diff --git a/cli/install/install.go b/cli/install/install.go index 513a338..3abd3ed 100644 --- a/cli/install/install.go +++ b/cli/install/install.go @@ -174,7 +174,7 @@ func (i *installer) installFromFile(path string) error { func (i *installer) installFromRepo(ctx context.Context, name string, archs []string) error { pi := goolib.PkgNameSplit(name) if i.shouldReinstall { - ps, err := i.db.FetchPkg(pi.Name) + ps, err := i.db.FetchPkg(pi) if err != nil { return fmt.Errorf("unable to fetch %v: %v", pi.Name, err) } diff --git a/cli/remove/remove.go b/cli/remove/remove.go index 89e5614..18e1c32 100644 --- a/cli/remove/remove.go +++ b/cli/remove/remove.go @@ -84,7 +84,7 @@ func (cmd *removeCmd) Execute(ctx context.Context, flags *flag.FlagSet, _ ...int func (cmd *removeCmd) removeOne(ctx context.Context, pkgName string, downloader *client.Downloader, db *googetdb.GooDB) error { pi := goolib.PkgNameSplit(pkgName) - ps, err := db.FetchPkg(pi.Name) + ps, err := db.FetchPkg(pi) if err != nil { return err } diff --git a/cli/verify/verify.go b/cli/verify/verify.go index b3be9ee..5364b05 100644 --- a/cli/verify/verify.go +++ b/cli/verify/verify.go @@ -71,7 +71,7 @@ func (cmd *verifyCmd) Execute(ctx context.Context, flags *flag.FlagSet, _ ...int for _, arg := range flags.Args() { pi := goolib.PkgNameSplit(arg) - ps, err := db.FetchPkg(pi.Name) + ps, err := db.FetchPkg(pi) if err != nil { logger.Errorf("Package %q not installed, cannot verify.", arg) continue diff --git a/googet.goospec b/googet.goospec index fa262a4..8fbf3ba 100644 --- a/googet.goospec +++ b/googet.goospec @@ -1,4 +1,4 @@ -{{$version := "3.2.0@0" -}} +{{$version := "3.2.1@0" -}} { "name": "googet", "version": "{{$version}}", @@ -15,6 +15,7 @@ "path": "install.ps1" }, "releaseNotes": [ + "3.2.1 - Refactor: Update GooDB.FetchPkg to accept goolib.PackageInfo.", "3.2.0 - Add Provides functionality and field to the GooGet PkgSpec.", "3.1.0 - Introduce a dry_run flag for update, install, and remove subcommands.", "3.0.0 - Replace googet state file with sqlite database. Add json output for installed command.", diff --git a/googetdb/googetdb.go b/googetdb/googetdb.go index 3e2ce8d..e74b1b2 100644 --- a/googetdb/googetdb.go +++ b/googetdb/googetdb.go @@ -24,6 +24,7 @@ import ( "time" "github.com/google/googet/v2/client" + "github.com/google/googet/v2/goolib" "github.com/google/googet/v2/settings" "github.com/google/googet/v2/system" "github.com/google/logger" @@ -152,45 +153,46 @@ func (g *GooDB) RemovePkg(pkgName, arch string) error { } // FetchPkg exports a single package from the googet database -func (g *GooDB) FetchPkg(pkgName string) (client.PackageState, error) { - var pkgState client.PackageState - +func (g *GooDB) FetchPkg(pi goolib.PackageInfo) (client.PackageState, error) { selectSpecQuery := `SELECT pkg_json FROM InstalledPackages WHERE pkg_name = ? - ORDER BY pkg_name + ORDER BY pkg_arch, pkg_ver ` - spec, err := g.db.Query(selectSpecQuery, pkgName) + spec, err := g.db.Query(selectSpecQuery, pi.Name) if err != nil { - return client.PackageState{}, nil + return client.PackageState{}, err } defer spec.Close() + + var lastPkgState client.PackageState for spec.Next() { var jsonState string - err = spec.Scan( - &jsonState, - ) - if err != nil { - return pkgState, err + if err := spec.Scan(&jsonState); err != nil { + return client.PackageState{}, err } - err = json.Unmarshal([]byte(jsonState), &pkgState) - if err != nil { - return pkgState, err + var pkgState client.PackageState + if err := json.Unmarshal([]byte(jsonState), &pkgState); err != nil { + return client.PackageState{}, err + } + if pkgState.Match(pi) { + return pkgState, nil } + lastPkgState = pkgState } - return pkgState, nil + return lastPkgState, nil } // FetchPkgs exports all of the current packages in the googet database func (g *GooDB) FetchPkgs(pkgName string) (client.GooGetState, error) { var state client.GooGetState - query := `SELECT pkg_json FROM InstalledPackages ORDER BY pkg_name` + query := `SELECT pkg_json FROM InstalledPackages ORDER BY pkg_name, pkg_arch` var args []any if pkgName != "" { - query = `SELECT pkg_json FROM InstalledPackages WHERE pkg_name LIKE ? ORDER BY pkg_name` + query = `SELECT pkg_json FROM InstalledPackages WHERE pkg_name LIKE ? ORDER BY pkg_name, pkg_arch` args = []any{pkgName} } rows, err := g.db.Query(query, args...) diff --git a/googetdb/googetdb_test.go b/googetdb/googetdb_test.go index 1dc71b2..750f210 100644 --- a/googetdb/googetdb_test.go +++ b/googetdb/googetdb_test.go @@ -128,8 +128,9 @@ func TestFetchPkgsReturnsDistinctEntriesForDifferentArches(t *testing.T) { defer db.Close() want := client.GooGetState{ - client.PackageState{PackageSpec: &goolib.PkgSpec{Name: "test-pkg", Arch: "amd64", Version: "1"}, InstallDate: 123456789}, - client.PackageState{PackageSpec: &goolib.PkgSpec{Name: "test-pkg", Arch: "i386", Version: "1"}, InstallDate: 123456789}, + client.PackageState{PackageSpec: &goolib.PkgSpec{Name: "test-pkg", Arch: "arm64", Version: "1"}, InstallDate: 123456789}, + client.PackageState{PackageSpec: &goolib.PkgSpec{Name: "test-pkg", Arch: "x86_32", Version: "1"}, InstallDate: 123456789}, + client.PackageState{PackageSpec: &goolib.PkgSpec{Name: "test-pkg", Arch: "x86_64", Version: "1"}, InstallDate: 123456789}, } if err := db.WriteStateToDB(want); err != nil { t.Fatalf("db.WriteStateToDB(%v): %v", want, err) @@ -143,6 +144,32 @@ func TestFetchPkgsReturnsDistinctEntriesForDifferentArches(t *testing.T) { if diff := cmp.Diff(want, got, cmpopts.EquateEmpty()); diff != "" { t.Fatalf("FetchPkgs got unexpected diff (-want +got):\n%v", diff) } + + gotPkg, err := db.FetchPkg(goolib.PackageInfo{Name: "test-pkg", Arch: "x86_32"}) + if err != nil { + t.Fatalf("db.FetchPkg: %v", err) + } + if diff := cmp.Diff(want[1], gotPkg, cmpopts.EquateEmpty()); diff != "" { + t.Fatalf("FetchPkg got unexpected diff (-want +got):\n%v", diff) + } + + // If only name is provided, arm64 should be matched first based on sort order. + gotPkg, err = db.FetchPkg(goolib.PackageInfo{Name: "test-pkg"}) + if err != nil { + t.Fatalf("db.FetchPkg: %v", err) + } + if diff := cmp.Diff(want[0], gotPkg, cmpopts.EquateEmpty()); diff != "" { + t.Fatalf("FetchPkg got unexpected diff (-want +got):\n%v", diff) + } + + // If no arch matches, the last processed package (x86_64) should be returned. + gotPkg, err = db.FetchPkg(goolib.PackageInfo{Name: "test-pkg", Arch: "none"}) + if err != nil { + t.Fatalf("db.FetchPkg: %v", err) + } + if diff := cmp.Diff(want[2], gotPkg, cmpopts.EquateEmpty()); diff != "" { + t.Fatalf("FetchPkg got unexpected diff (-want +got):\n%v", diff) + } } func TestCreateIfMissing(t *testing.T) { diff --git a/install/install.go b/install/install.go index 598abba..04e9133 100644 --- a/install/install.go +++ b/install/install.go @@ -39,7 +39,7 @@ var toRemove []string // minInstalled reports whether the package is installed at the given version or greater. func minInstalled(pi goolib.PackageInfo, db *googetdb.GooDB) (bool, error) { - p, err := db.FetchPkg(pi.Name) + p, err := db.FetchPkg(pi) if err != nil { return false, err } @@ -199,7 +199,7 @@ func FromRepo(ctx context.Context, pi goolib.PackageInfo, repo, cache string, rm logger.Infof("Installation of %s.%s.%s completed", pi.Name, pi.Arch, pi.Ver) fmt.Printf("Installation of %s.%s.%s and all dependencies completed\n", pi.Name, pi.Arch, pi.Ver) // Clean up old version, if applicable. - ps, err := db.FetchPkg(pi.Name) + ps, err := db.FetchPkg(pi) if err != nil { return err } @@ -360,7 +360,7 @@ func copyPkg(src, dst string) (retErr error) { // NeedsInstallation checks if a package version needs installation. func NeedsInstallation(pi goolib.PackageInfo, db *googetdb.GooDB) (bool, error) { - p, err := db.FetchPkg(pi.Name) + p, err := db.FetchPkg(pi) if err != nil { return true, err } @@ -481,7 +481,6 @@ func cleanOld(st client.PackageState, insFiles map[string]string, dbOnly bool) { if st.UnpackDir != "" && oswrap.RemoveAll(st.UnpackDir) != nil { logger.Error("Unable to remove old unpack dir") } - return } func cleanOldFiles(oldState client.PackageState, insFiles map[string]string) { diff --git a/remove/remove.go b/remove/remove.go index 008fccd..6b120b1 100644 --- a/remove/remove.go +++ b/remove/remove.go @@ -31,7 +31,7 @@ import ( func uninstallPkg(ctx context.Context, pi goolib.PackageInfo, dbOnly bool, downloader *client.Downloader, db *googetdb.GooDB) error { logger.Infof("Executing removal of package %q", pi.Name) - ps, err := db.FetchPkg(pi.Name) + ps, err := db.FetchPkg(pi) if err != nil { return fmt.Errorf("package not found in state file: %v", err) }