From 1a52da58912a142b74aadf0c64011eaaf03e304b Mon Sep 17 00:00:00 2001 From: jguer Date: Fri, 5 Aug 2022 22:55:54 +0200 Subject: [PATCH] Make provides disabled by default. Add Migration to set provides to disabled --- Makefile | 2 +- install.go | 5 +- main.go | 5 + pkg/completion/completion_test.go | 4 +- pkg/db/executor.go | 6 +- pkg/pgp/keys_test.go | 3 +- pkg/query/source_test.go | 4 +- pkg/settings/config.go | 2 +- pkg/settings/dirs_test.go | 15 ++- pkg/settings/migrations.go | 67 +++++++++++++ pkg/settings/migrations_test.go | 151 ++++++++++++++++++++++++++++++ upgrade.go | 11 ++- 12 files changed, 255 insertions(+), 20 deletions(-) create mode 100644 pkg/settings/migrations.go create mode 100644 pkg/settings/migrations_test.go diff --git a/Makefile b/Makefile index 680a1cbd..af2ff2c6 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ PREFIX := /usr/local MAJORVERSION := 11 MINORVERSION := 2 -PATCHVERSION := 0 +PATCHVERSION := 1 VERSION ?= ${MAJORVERSION}.${MINORVERSION}.${PATCHVERSION} LOCALEDIR := po diff --git a/install.go b/install.go index 2c643b06..795a2d86 100644 --- a/install.go +++ b/install.go @@ -550,7 +550,7 @@ func pkgbuildsToSkip(bases []dep.Base, targets stringset.StringSet) stringset.St pkgbuild, err := gosrc.ParseFile(dir) if err == nil { - if alpm.VerCmp(pkgbuild.Version(), base.Version()) >= 0 { + if db.VerCmp(pkgbuild.Version(), base.Version()) >= 0 { toSkip.Set(base.Pkgbase()) } } @@ -812,7 +812,8 @@ func doInstall(ctx context.Context, arguments, cmdArgs *parser.Arguments, pkgDep func doAddTarget(dp *dep.Pool, localNamesCache, remoteNamesCache stringset.StringSet, arguments, cmdArgs *parser.Arguments, pkgdests map[string]string, - deps, exp []string, name string, optional bool) (newDeps, newExp []string, err error) { + deps, exp []string, name string, optional bool, +) (newDeps, newExp []string, err error) { pkgdest, ok := pkgdests[name] if !ok { if optional { diff --git a/main.go b/main.go index 5e425e19..247ccc88 100644 --- a/main.go +++ b/main.go @@ -114,6 +114,11 @@ func main() { return } + if errS := config.RunMigrations( + settings.DefaultMigrations(), config.Runtime.ConfigPath); errS != nil { + text.Errorln(errS) + } + cmdArgs := parser.MakeArguments() if err = config.ParseCommandLine(cmdArgs); err != nil { diff --git a/pkg/completion/completion_test.go b/pkg/completion/completion_test.go index 7c46aef0..191deca9 100644 --- a/pkg/completion/completion_test.go +++ b/pkg/completion/completion_test.go @@ -4,7 +4,7 @@ import ( "bytes" "context" "errors" - "io/ioutil" + "io" "net/http" "testing" @@ -45,7 +45,7 @@ func (m *mockDoer) Do(req *http.Request) (*http.Response, error) { assert.Equal(m.t, m.wantUrl, req.URL.String()) return &http.Response{ StatusCode: m.returnStatusCode, - Body: ioutil.NopCloser(bytes.NewBufferString(m.returnBody)), + Body: io.NopCloser(bytes.NewBufferString(m.returnBody)), }, m.returnErr } diff --git a/pkg/db/executor.go b/pkg/db/executor.go index 6d69d4d8..e957f5b1 100644 --- a/pkg/db/executor.go +++ b/pkg/db/executor.go @@ -11,8 +11,10 @@ type ( Depend = alpm.Depend ) -func VerCmp(a, b string) int { - return alpm.VerCmp(a, b) +// VerCmp performs version comparison according to Pacman conventions. Return +// value is <0 if and only if v1 is older than v2. +func VerCmp(v1, v2 string) int { + return alpm.VerCmp(v1, v2) } type Upgrade struct { diff --git a/pkg/pgp/keys_test.go b/pkg/pgp/keys_test.go index fc587550..c8e87868 100644 --- a/pkg/pgp/keys_test.go +++ b/pkg/pgp/keys_test.go @@ -12,6 +12,7 @@ import ( "sort" "strings" "testing" + "time" aur "github.com/Jguer/aur" gosrc "github.com/Morganamilo/go-srcinfo" @@ -59,7 +60,7 @@ func getPgpKey(key string) string { } func startPgpKeyServer() *http.Server { - srv := &http.Server{Addr: fmt.Sprintf("127.0.0.1:%d", gpgServerPort)} + srv := &http.Server{Addr: fmt.Sprintf("127.0.0.1:%d", gpgServerPort), ReadHeaderTimeout: 1 * time.Second} go func() { err := srv.ListenAndServe() diff --git a/pkg/query/source_test.go b/pkg/query/source_test.go index cffbe034..152a9c72 100644 --- a/pkg/query/source_test.go +++ b/pkg/query/source_test.go @@ -3,7 +3,7 @@ package query import ( "bytes" "context" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -83,7 +83,7 @@ type mockDoer struct{} func (m *mockDoer) Do(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: 200, - Body: ioutil.NopCloser(bytes.NewBufferString(validPayload)), + Body: io.NopCloser(bytes.NewBufferString(validPayload)), }, nil } diff --git a/pkg/settings/config.go b/pkg/settings/config.go index 600b85c9..bf39cabc 100644 --- a/pkg/settings/config.go +++ b/pkg/settings/config.go @@ -213,7 +213,7 @@ func DefaultConfig(version string) *Configuration { AnswerEdit: "", AnswerUpgrade: "", RemoveMake: "ask", - Provides: true, + Provides: false, UpgradeMenu: true, CleanMenu: true, DiffMenu: true, diff --git a/pkg/settings/dirs_test.go b/pkg/settings/dirs_test.go index 94b166b7..f9acd7a7 100644 --- a/pkg/settings/dirs_test.go +++ b/pkg/settings/dirs_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // GIVEN no user directories and sudo user @@ -13,11 +14,15 @@ import ( // THEN the selected cache home should be in the tmp dir func Test_getCacheHome(t *testing.T) { dir := t.TempDir() - os.Unsetenv("XDG_CACHE_HOME") - os.Unsetenv("HOME") - os.Setenv("SUDO_USER", "test") - os.Setenv("TMPDIR", dir) + require.NoError(t, os.Unsetenv("XDG_CACHE_HOME")) + require.NoError(t, os.Unsetenv("HOME")) + require.NoError(t, os.Setenv("SUDO_USER", "test")) + require.NoError(t, os.Setenv("TMPDIR", dir)) + got, err := getCacheHome() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, filepath.Join(dir, "yay"), got) + + require.NoError(t, os.Unsetenv("TMPDIR")) + require.NoError(t, os.Unsetenv("SUDO_USER")) } diff --git a/pkg/settings/migrations.go b/pkg/settings/migrations.go new file mode 100644 index 00000000..e40aaf9e --- /dev/null +++ b/pkg/settings/migrations.go @@ -0,0 +1,67 @@ +package settings + +import ( + "fmt" + + "github.com/Jguer/yay/v11/pkg/db" + "github.com/Jguer/yay/v11/pkg/text" + + "github.com/leonelquinteros/gotext" +) + +type configMigration interface { + // Description of what the migration does + fmt.Stringer + // return true if migration was done + Do(config *Configuration) bool + // Target version of the migration (e.g. "11.2.1") + // Should match the version of yay releasing this migration + TargetVersion() string +} + +type configProviderMigration struct{} + +func (migration *configProviderMigration) String() string { + return gotext.Get("Disable 'provides' setting by default") +} + +func (migration *configProviderMigration) Do(config *Configuration) bool { + if config.Provides { + config.Provides = false + + return true + } + + return false +} + +func (migration *configProviderMigration) TargetVersion() string { + return "11.2.1" +} + +func DefaultMigrations() []configMigration { + return []configMigration{ + &configProviderMigration{}, + } +} + +func (c *Configuration) RunMigrations(migrations []configMigration, configPath string) error { + saveConfig := false + + for _, migration := range migrations { + if db.VerCmp(migration.TargetVersion(), c.Version) > 0 { + if migration.Do(c) { + text.Infoln("Config migration executed (", + migration.TargetVersion(), "):", migration) + + saveConfig = true + } + } + } + + if saveConfig { + return c.Save(configPath) + } + + return nil +} diff --git a/pkg/settings/migrations_test.go b/pkg/settings/migrations_test.go new file mode 100644 index 00000000..4b868834 --- /dev/null +++ b/pkg/settings/migrations_test.go @@ -0,0 +1,151 @@ +package settings + +import ( + "encoding/json" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMigrationNothingToDo(t *testing.T) { + t.Parallel() + // Create temporary file for config + configFile, err := os.CreateTemp("/tmp", "yay-*-config.json") + require.NoError(t, err) + + testFilePath := configFile.Name() + defer os.Remove(testFilePath) + // Create config with configVersion + config := Configuration{ + Version: "99.0.0", + // Create runtime with runtimeVersion + Runtime: &Runtime{Version: "20.0.0"}, + } + + // Run Migration + err = config.RunMigrations(DefaultMigrations(), testFilePath) + require.NoError(t, err) + + // Check file contents if wantSave otherwise check file empty + cfile, err := os.Open(testFilePath) + require.NoError(t, err) + defer cfile.Close() + + decoder := json.NewDecoder(cfile) + newConfig := Configuration{} + err = decoder.Decode(&newConfig) + require.Error(t, err) + assert.Empty(t, newConfig.Version) +} + +func TestProvidesMigrationDo(t *testing.T) { + migration := &configProviderMigration{} + config := Configuration{Provides: true} + + assert.True(t, migration.Do(&config)) + + falseConfig := Configuration{Provides: false} + + assert.False(t, migration.Do(&falseConfig)) +} + +func TestProvidesMigration(t *testing.T) { + t.Parallel() + type testCase struct { + desc string + testConfig *Configuration + wantSave bool + } + + testCases := []testCase{ + { + desc: "to upgrade", + testConfig: &Configuration{ + Version: "11.0.1", + Runtime: &Runtime{Version: "11.2.1"}, + Provides: true, + }, + wantSave: true, + }, + { + desc: "to upgrade-git", + testConfig: &Configuration{ + Version: "11.2.0.r7.g6f60892", + Runtime: &Runtime{Version: "11.2.1"}, + Provides: true, + }, + wantSave: true, + }, + { + desc: "to not upgrade", + testConfig: &Configuration{ + Version: "11.2.0", + Runtime: &Runtime{Version: "11.2.1"}, + Provides: false, + }, + wantSave: false, + }, + { + desc: "to not upgrade - target version", + testConfig: &Configuration{ + Version: "11.2.1", + Runtime: &Runtime{Version: "11.2.1"}, + Provides: true, + }, + wantSave: false, + }, + { + desc: "to not upgrade - new version", + testConfig: &Configuration{ + Version: "11.3.0", + Runtime: &Runtime{Version: "11.3.0"}, + Provides: true, + }, + wantSave: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + // Create temporary file for config + configFile, err := os.CreateTemp("/tmp", "yay-*-config.json") + require.NoError(t, err) + + testFilePath := configFile.Name() + defer os.Remove(testFilePath) + // Create config with configVersion and provides + tcConfig := Configuration{ + Version: tc.testConfig.Version, + Provides: tc.testConfig.Provides, + // Create runtime with runtimeVersion + Runtime: &Runtime{Version: tc.testConfig.Runtime.Version}, + } + + // Run Migration + err = tcConfig.RunMigrations( + []configMigration{&configProviderMigration{}}, + testFilePath) + + require.NoError(t, err) + + // Check file contents if wantSave otherwise check file empty + cfile, err := os.Open(testFilePath) + require.NoError(t, err) + defer cfile.Close() + + decoder := json.NewDecoder(cfile) + newConfig := Configuration{} + err = decoder.Decode(&newConfig) + if tc.wantSave { + require.NoError(t, err) + assert.Equal(t, tc.testConfig.Runtime.Version, newConfig.Version) + assert.Equal(t, false, newConfig.Provides) + } else { + require.Error(t, err) + assert.Empty(t, newConfig.Version) + } + }) + } +} diff --git a/upgrade.go b/upgrade.go index f3770ab2..f7043bbf 100644 --- a/upgrade.go +++ b/upgrade.go @@ -35,7 +35,8 @@ func filterUpdateList(list []db.Upgrade, filter upgrade.Filter) []db.Upgrade { // upList returns lists of packages to upgrade from each source. func upList(ctx context.Context, warnings *query.AURWarnings, dbExecutor db.Executor, enableDowngrade bool, - filter upgrade.Filter) (aurUp, repoUp upgrade.UpSlice, err error) { + filter upgrade.Filter, +) (aurUp, repoUp upgrade.UpSlice, err error) { remote, remoteNames := query.GetRemotePackages(dbExecutor) var ( @@ -125,7 +126,8 @@ func upList(ctx context.Context, warnings *query.AURWarnings, dbExecutor db.Exec } func printLocalNewerThanAUR( - remote []alpm.IPackage, aurdata map[string]*aur.Pkg) { + remote []alpm.IPackage, aurdata map[string]*aur.Pkg, +) { for _, pkg := range remote { aurPkg, ok := aurdata[pkg.Name()] if !ok { @@ -134,7 +136,7 @@ func printLocalNewerThanAUR( left, right := upgrade.GetVersionDiff(pkg.Version(), aurPkg.Version) - if !isDevelPackage(pkg) && alpm.VerCmp(pkg.Version(), aurPkg.Version) > 0 { + if !isDevelPackage(pkg) && db.VerCmp(pkg.Version(), aurPkg.Version) > 0 { text.Warnln(gotext.Get("%s: local (%s) is newer than AUR (%s)", text.Cyan(pkg.Name()), left, right, @@ -233,7 +235,8 @@ func upgradePkgsMenu(aurUp, repoUp upgrade.UpSlice) (stringset.StringSet, []stri // Targets for sys upgrade. func sysupgradeTargets(ctx context.Context, dbExecutor db.Executor, - enableDowngrade bool) (stringset.StringSet, []string, error) { + enableDowngrade bool, +) (stringset.StringSet, []string, error) { warnings := query.NewWarnings() aurUp, repoUp, err := upList(ctx, warnings, dbExecutor, enableDowngrade,