From 2e416b9e6f96f485e40b3b9688f36b2131346175 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Fri, 2 May 2025 20:43:24 +0300 Subject: [PATCH] Allow direct split source package installation through repository entries --- src/bpmlib/general.go | 4 --- src/bpmlib/operations.go | 64 ++++++++++++++++++++++++++++++-------- src/bpmlib/repositories.go | 52 +++++++++++++++++++++++++++++-- 3 files changed, 100 insertions(+), 20 deletions(-) diff --git a/src/bpmlib/general.go b/src/bpmlib/general.go index c9cc1bd..1d8b05a 100644 --- a/src/bpmlib/general.go +++ b/src/bpmlib/general.go @@ -83,10 +83,6 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein continue } - if entry.Info.IsSplitPackage() { - return nil, fmt.Errorf("direct split source package installation has not been implemented") - } - operation.AppendAction(&FetchPackageAction{ IsDependency: false, RepositoryEntry: entry, diff --git a/src/bpmlib/operations.go b/src/bpmlib/operations.go index efb5a04..1736545 100644 --- a/src/bpmlib/operations.go +++ b/src/bpmlib/operations.go @@ -413,30 +413,68 @@ func (operation *BPMOperation) RunHooks(verbose bool) error { return nil } -func (operation *BPMOperation) Execute(verbose, force bool) error { +func (operation *BPMOperation) Execute(verbose, force bool) (err error) { // Fetch packages from repositories if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool { return action.GetActionType() == "fetch" }) { fmt.Println("Fetching packages from available repositories...") + + // Create map for fetched packages + fetchedPackages := make(map[string]string) + for i, action := range operation.Actions { if action.GetActionType() != "fetch" { continue } + + // Get repository entry entry := action.(*FetchPackageAction).RepositoryEntry - fetchedPackage, err := entry.Repository.FetchPackage(entry.Info.Name) - if err != nil { - return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err)) + + // Create bpmpkg variable + var bpmpkg *BPMPackage + + // Check if package has already been fetched from download link + if _, ok := fetchedPackages[entry.Download]; !ok { + // Fetch package from repository + fetchedPackage, err := entry.Repository.FetchPackage(entry.Info.Name) + if err != nil { + return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err)) + } + + // Read fetched package + bpmpkg, err = ReadPackage(fetchedPackage) + if err != nil { + return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err)) + } + + // Add fetched package to map + fetchedPackages[entry.Download] = fetchedPackage + + fmt.Printf("Package (%s) was successfully fetched!\n", entry.Info.Name) + } else { + // Read fetched package + bpmpkg, err = ReadPackage(fetchedPackages[entry.Download]) + if err != nil { + return errors.New(fmt.Sprintf("could not read package (%s): %s\n", entry.Info.Name, err)) + } + + fmt.Printf("Package (%s) was successfully fetched!\n", entry.Info.Name) } - bpmpkg, err := ReadPackage(fetchedPackage) - if err != nil { - return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err)) - } - fmt.Printf("Package (%s) was successfully fetched!\n", bpmpkg.PkgInfo.Name) - operation.Actions[i] = &InstallPackageAction{ - File: fetchedPackage, - IsDependency: action.(*FetchPackageAction).IsDependency, - BpmPackage: bpmpkg, + + if bpmpkg.PkgInfo.IsSplitPackage() { + operation.Actions[i] = &InstallPackageAction{ + File: fetchedPackages[entry.Download], + IsDependency: action.(*FetchPackageAction).IsDependency, + BpmPackage: bpmpkg, + SplitPackageToInstall: entry.Info.Name, + } + } else { + operation.Actions[i] = &InstallPackageAction{ + File: fetchedPackages[entry.Download], + IsDependency: action.(*FetchPackageAction).IsDependency, + BpmPackage: bpmpkg, + } } } } diff --git a/src/bpmlib/repositories.go b/src/bpmlib/repositories.go index c74e440..c168f79 100644 --- a/src/bpmlib/repositories.go +++ b/src/bpmlib/repositories.go @@ -73,10 +73,56 @@ func (repo *Repository) ReadLocalDatabase() error { return err } - for _, p := range entry.Info.Provides { - repo.VirtualPackages[p] = append(repo.VirtualPackages[p], entry.Info.Name) + // Create repository entries + if entry.Info.IsSplitPackage() { + for _, splitPkg := range entry.Info.SplitPackages { + // Turn split package into json data + splitPkgJson, err := yaml.Marshal(splitPkg) + if err != nil { + return err + } + + // Clone all main package fields onto split package + splitPkgClone := *entry.Info + + // Set split package field of split package to nil + splitPkgClone.SplitPackages = nil + + // Unmarshal json data back to struct + err = yaml.Unmarshal(splitPkgJson, &splitPkgClone) + if err != nil { + return err + } + + // Force set split package version, revision and URL + splitPkgClone.Version = entry.Info.Version + splitPkgClone.Revision = entry.Info.Revision + splitPkgClone.Url = entry.Info.Url + + // Create entry for split package + repo.Entries[splitPkg.Name] = &RepositoryEntry{ + Info: &splitPkgClone, + Download: entry.Download, + DownloadSize: entry.DownloadSize, + InstalledSize: 0, + Repository: repo, + } + + // Add virtual packages to repository + for _, p := range splitPkg.Provides { + repo.VirtualPackages[p] = append(repo.VirtualPackages[p], splitPkg.Name) + } + } + } else { + // Create entry for package + repo.Entries[entry.Info.Name] = &entry + + // Add virtual packages to repository + for _, p := range entry.Info.Provides { + repo.VirtualPackages[p] = append(repo.VirtualPackages[p], entry.Info.Name) + } } - repo.Entries[entry.Info.Name] = &entry + } return nil