From b27137da29a63e2c7c062d4dec1fe83da8323342 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Wed, 16 Apr 2025 20:13:22 +0300 Subject: [PATCH] Allow sync and update subcommands when local database files are corrupt --- src/bpm/main.go | 46 ++++++++++++++++++++++++++++++++++++++ src/bpmlib/config.go | 9 -------- src/bpmlib/repositories.go | 41 ++++++++++++++++++++++++++++----- 3 files changed, 82 insertions(+), 14 deletions(-) diff --git a/src/bpm/main.go b/src/bpm/main.go index 7265eb9..9ff4a10 100644 --- a/src/bpm/main.go +++ b/src/bpm/main.go @@ -102,6 +102,13 @@ func resolveCommand() { fmt.Println("No packages were given") return } + + // Read local databases + err := bpmlib.ReadLocalDatabases() + if err != nil { + log.Fatalf("Error: could not read local databases: %s", err) + } + for n, pkg := range packages { var info *bpmlib.PackageInfo isFile := false @@ -145,6 +152,12 @@ func resolveCommand() { fmt.Println(bpmlib.CreateReadableInfo(true, true, true, info, rootDir)) } case list: + // Read local databases + err := bpmlib.ReadLocalDatabases() + if err != nil { + log.Fatalf("Error: could not read local databases: %s", err) + } + packages, err := bpmlib.GetInstalledPackages(rootDir) if err != nil { log.Fatalf("Error: could not get installed packages: %s", err.Error()) @@ -178,6 +191,13 @@ func resolveCommand() { if len(searchTerms) == 0 { log.Fatalf("Error: no search terms given") } + + // Read local databases + err := bpmlib.ReadLocalDatabases() + if err != nil { + log.Fatalf("Error: could not read local databases: %s", err) + } + for i, term := range searchTerms { nameResults := make([]*bpmlib.PackageInfo, 0) descResults := make([]*bpmlib.PackageInfo, 0) @@ -236,6 +256,12 @@ func resolveCommand() { reinstallMethod = bpmlib.ReinstallMethodNone } + // Read local databases + err := bpmlib.ReadLocalDatabases() + if err != nil { + log.Fatalf("Error: could not read local databases: %s", err) + } + // Create installation operation operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallMethod, !noOptional, force, verbose, subcommandArgs...) if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) { @@ -287,6 +313,14 @@ func resolveCommand() { log.Fatalf("Error: this subcommand needs to be run with superuser permissions") } + // Read local databases if no sync + if nosync { + err := bpmlib.ReadLocalDatabases() + if err != nil { + log.Fatalf("Error: could not read local databases: %s", err) + } + } + // Create update operation operation, err := bpmlib.UpdatePackages(rootDir, !nosync, !noOptional, force, verbose) if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) { @@ -362,6 +396,12 @@ func resolveCommand() { return } + // Read local databases + err := bpmlib.ReadLocalDatabases() + if err != nil { + log.Fatalf("Error: could not read local databases: %s", err) + } + // Create remove operation operation, err := bpmlib.RemovePackages(rootDir, removeUnused, doCleanup, verbose, subcommandArgs...) if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) { @@ -408,6 +448,12 @@ func resolveCommand() { log.Fatalf("Error: this subcommand needs to be run with superuser permissions") } + // Read local databases + err := bpmlib.ReadLocalDatabases() + if err != nil { + log.Fatalf("Error: could not read local databases: %s", err) + } + // Create cleanup operation operation, err := bpmlib.CleanupPackages(rootDir, verbose) if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) { diff --git a/src/bpmlib/config.go b/src/bpmlib/config.go index fdbf246..eee5d57 100644 --- a/src/bpmlib/config.go +++ b/src/bpmlib/config.go @@ -34,14 +34,5 @@ func ReadConfig() (err error) { } } - for _, repo := range BPMConfig.Repositories { - repo.Entries = make(map[string]*RepositoryEntry) - repo.VirtualPackages = make(map[string][]string) - err := repo.ReadLocalDatabase() - if err != nil { - return err - } - } - return nil } diff --git a/src/bpmlib/repositories.go b/src/bpmlib/repositories.go index ffe64b2..c74e440 100644 --- a/src/bpmlib/repositories.go +++ b/src/bpmlib/repositories.go @@ -2,6 +2,7 @@ package bpmlib import ( "errors" + "fmt" "gopkg.in/yaml.v3" "io" "net/http" @@ -83,29 +84,59 @@ func (repo *Repository) ReadLocalDatabase() error { func (repo *Repository) SyncLocalDatabase() error { repoFile := "/var/lib/bpm/repositories/" + repo.Name + ".bpmdb" - err := os.MkdirAll(path.Dir(repoFile), 0755) - if err != nil { - return err - } + // Get URL to database u, err := url.JoinPath(repo.Source, "database.bpmdb") if err != nil { return err } + // Retrieve data from URL resp, err := http.Get(u) if err != nil { return err } defer resp.Body.Close() + // Load data into byte buffer + buffer, err := io.ReadAll(resp.Body) + + // Unmarshal data to ensure it is a valid BPM repository + err = yaml.Unmarshal(buffer, &Repository{}) + if err != nil { + return fmt.Errorf("could not decode repository: %s", err) + } + + // Create parent directories to repository file + err = os.MkdirAll(path.Dir(repoFile), 0755) + if err != nil { + return err + } + + // Create file and save repository data out, err := os.Create(repoFile) if err != nil { return err } defer out.Close() - _, err = io.Copy(out, resp.Body) + _, err = out.Write(buffer) + + return nil +} + +func ReadLocalDatabases() (err error) { + for _, repo := range BPMConfig.Repositories { + // Initialize struct values + repo.Entries = make(map[string]*RepositoryEntry) + repo.VirtualPackages = make(map[string][]string) + + // Read database + err = repo.ReadLocalDatabase() + if err != nil { + return err + } + } return nil }