Browse Source

Merge pull request #1779 from Jguer/jguer/migrate-provides

Config: Add migration service and migrate provides default value
Jo 2 years atrás
parent
commit
e2f61255cb

+ 1 - 1
.github/workflows/builder-image.yml

@@ -29,7 +29,7 @@ jobs:
           DOCKER_BUILDKIT: 0
           COMPOSE_DOCKER_CLI_BUILD: 0
         with:
-          platforms: linux/amd64, linux/arm/v6,linux/arm/v7,linux/arm64
+          platforms: linux/amd64,linux/arm/v7,linux/arm64
           file: ci.Dockerfile
           push: true
           tags: jguer/yay-builder:latest

+ 0 - 14
.github/workflows/multiarch-build.yml

@@ -11,7 +11,6 @@ jobs:
         arch:
           [
             "linux/amd64 x86_64",
-            "linux/arm/v6 armv6h",
             "linux/arm/v7 armv7h",
             "linux/arm64 aarch64",
           ]
@@ -75,9 +74,6 @@ jobs:
           name: yay_armv7h
       - uses: actions/download-artifact@v2
         with:
-          name: yay_armv6h
-      - uses: actions/download-artifact@v2
-        with:
           name: yay_aarch64
       - name: Create Release
         id: create_release
@@ -109,16 +105,6 @@ jobs:
           asset_path: ./yay_${{ steps.tags.outputs.version }}_armv7h.tar.gz
           asset_name: yay_${{ steps.tags.outputs.version }}_armv7h.tar.gz
           asset_content_type: application/tar+gzip
-      - name: Upload armv6h asset
-        id: upload-release-asset-armv6h
-        uses: actions/upload-release-asset@v1
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          upload_url: ${{ steps.create_release.outputs.upload_url }}
-          asset_path: ./yay_${{ steps.tags.outputs.version }}_armv6h.tar.gz
-          asset_name: yay_${{ steps.tags.outputs.version }}_armv6h.tar.gz
-          asset_content_type: application/tar+gzip
       - name: Upload aarch64 asset
         id: upload-release-asset-aarch64
         uses: actions/upload-release-asset@v1

+ 1 - 1
Makefile

@@ -12,7 +12,7 @@ PREFIX := /usr/local
 
 MAJORVERSION := 11
 MINORVERSION := 2
-PATCHVERSION := 0
+PATCHVERSION := 1
 VERSION ?= ${MAJORVERSION}.${MINORVERSION}.${PATCHVERSION}
 
 LOCALEDIR := po

+ 3 - 3
ci.Dockerfile

@@ -1,11 +1,11 @@
-FROM docker.io/lopsided/archlinux:devel
+FROM docker.io/jguer/yay-builder:latest
 
 ENV GO111MODULE=on
 WORKDIR /app
 
 COPY go.mod .
 
-RUN pacman -Syu --overwrite=* --needed --noconfirm go git && \
+RUN pacman -Sy && pacman -S --overwrite=* --noconfirm archlinux-keyring && pacman -Su --overwrite=* --needed --noconfirm go git && \
     rm -rfv /var/cache/pacman/* /var/lib/pacman/sync/* && \
-    curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.44.2 && \
+    curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.48.0 && \
     go mod download

+ 3 - 2
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 {

+ 5 - 0
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 {

+ 2 - 2
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
 }
 

+ 4 - 2
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 {

+ 2 - 1
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()

+ 2 - 2
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
 }
 

+ 1 - 1
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,

+ 10 - 5
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"))
 }

+ 67 - 0
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
+}

+ 151 - 0
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)
+			}
+		})
+	}
+}

+ 10 - 8
pkg/vcs/vcs.go

@@ -30,13 +30,14 @@ type OriginInfoByURL map[string]OriginInfo
 
 // OriginInfo contains the last commit sha of a repo
 // Example:
-// "github.com/Jguer/yay.git": {
-// 	"protocols": [
-// 		"https"
-// 	],
-// 	"branch": "next",
-// 	"sha": "c1171d41467c68ffd3c46748182a16366aaaf87b"
-// }.
+//
+//	"github.com/Jguer/yay.git": {
+//		"protocols": [
+//			"https"
+//		],
+//		"branch": "next",
+//		"sha": "c1171d41467c68ffd3c46748182a16366aaaf87b"
+//	}.
 type OriginInfo struct {
 	Protocols []string `json:"protocols"`
 	Branch    string   `json:"branch"`
@@ -90,7 +91,8 @@ func (v *InfoStore) getCommit(ctx context.Context, url, branch string, protocols
 }
 
 func (v *InfoStore) Update(ctx context.Context, pkgName string,
-	sources []gosrc.ArchString, mux sync.Locker, wg *sync.WaitGroup) {
+	sources []gosrc.ArchString, mux sync.Locker, wg *sync.WaitGroup,
+) {
 	defer wg.Done()
 
 	info := make(OriginInfoByURL)

+ 13 - 8
pkg/vcs/vcs_test.go

@@ -13,6 +13,7 @@ import (
 	gosrc "github.com/Morganamilo/go-srcinfo"
 	"github.com/bradleyjkemp/cupaloy"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	"github.com/Jguer/yay/v11/pkg/settings/exe"
 )
@@ -261,9 +262,9 @@ func TestInfoStore_Update(t *testing.T) {
 		},
 	}
 
-	file, err := os.CreateTemp("/tmp", "yay-vcs-test")
-	assert.NoError(t, err)
-	defer os.Remove(file.Name())
+	file, err := os.CreateTemp("/tmp", "yay-infostore-*-test")
+	filePath := file.Name()
+	require.NoError(t, err)
 
 	for _, tt := range tests {
 		tt := tt
@@ -271,7 +272,7 @@ func TestInfoStore_Update(t *testing.T) {
 			t.Parallel()
 			v := &InfoStore{
 				OriginsByPackage: tt.fields.OriginsByPackage,
-				FilePath:         file.Name(),
+				FilePath:         filePath,
 				CmdBuilder:       tt.fields.CmdBuilder,
 			}
 			var mux sync.Mutex
@@ -296,6 +297,8 @@ func TestInfoStore_Update(t *testing.T) {
 			cupaloy.SnapshotT(t, marshalledinfo)
 		})
 	}
+
+	require.NoError(t, os.Remove(filePath))
 }
 
 func TestInfoStore_Remove(t *testing.T) {
@@ -325,9 +328,9 @@ func TestInfoStore_Remove(t *testing.T) {
 		},
 	}
 
-	file, err := os.CreateTemp("/tmp", "yay-vcs-test")
-	assert.NoError(t, err)
-	defer os.Remove(file.Name())
+	file, err := os.CreateTemp("/tmp", "yay-vcs-*-test")
+	filePath := file.Name()
+	require.NoError(t, err)
 
 	for _, tt := range tests {
 		tt := tt
@@ -335,10 +338,12 @@ func TestInfoStore_Remove(t *testing.T) {
 			t.Parallel()
 			v := &InfoStore{
 				OriginsByPackage: tt.fields.OriginsByPackage,
-				FilePath:         file.Name(),
+				FilePath:         filePath,
 			}
 			v.RemovePackage(tt.args.pkgs)
 			assert.Len(t, tt.fields.OriginsByPackage, 2)
 		})
 	}
+
+	require.NoError(t, os.Remove(filePath))
 }

+ 7 - 4
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,