Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package apko for openSUSE:Factory checked in at 2025-11-17 12:19:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apko (Old) and /work/SRC/openSUSE:Factory/.apko.new.2061 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "apko" Mon Nov 17 12:19:24 2025 rev:75 rq:1318139 version:0.30.22 Changes: -------- --- /work/SRC/openSUSE:Factory/apko/apko.changes 2025-11-04 18:44:27.110715961 +0100 +++ /work/SRC/openSUSE:Factory/.apko.new.2061/apko.changes 2025-11-17 12:24:55.777694812 +0100 @@ -1,0 +2,36 @@ +Mon Nov 17 06:18:09 UTC 2025 - Johannes Kastl <[email protected]> + +- Update to version 0.30.22: + * build(deps): bump github/codeql-action from 4.31.2 to 4.31.3 + (#1936) + * Add support for tagged repositories (#1868) + * build(deps): bump github/codeql-action from + 8a06050a8c0348fb4738f28e0cfbb6727cf054ce to + 04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 (#1927) + * build(deps): bump google.golang.org/api from 0.254.0 to 0.255.0 + (#1917) + * build(deps): bump go.step.sm/crypto from 0.73.0 to 0.74.0 + (#1914) + * build(deps): bump docker/setup-qemu-action from 3.6.0 to 3.7.0 + (#1921) + * build(deps): bump golang.org/x/oauth2 from 0.32.0 to 0.33.0 + (#1924) + * build(deps): bump chainguard-dev/actions from 1.5.7 to 1.5.8 + (#1928) + * build(deps): bump golangci/golangci-lint-action from 8.0.0 to + 9.0.0 (#1929) + * build(deps): bump golang.org/x/sys from 0.37.0 to 0.38.0 + (#1925) + * build(deps): bump golang.org/x/sync from 0.17.0 to 0.18.0 + (#1926) + +------------------------------------------------------------------- +Mon Nov 10 13:03:00 UTC 2025 - Johannes Kastl <[email protected]> + +- Update to version 0.30.21: + * Upgrade golangci-lint to 2.6.1 and enable modernize linter + (#1916) + * build(deps): bump step-security/harden-runner from 2.13.1 to + 2.13.2 (#1919) + +------------------------------------------------------------------- Old: ---- apko-0.30.20.obscpio New: ---- apko-0.30.22.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apko.spec ++++++ --- /var/tmp/diff_new_pack.KhtLd1/_old 2025-11-17 12:24:56.825739008 +0100 +++ /var/tmp/diff_new_pack.KhtLd1/_new 2025-11-17 12:24:56.833739346 +0100 @@ -17,7 +17,7 @@ Name: apko -Version: 0.30.20 +Version: 0.30.22 Release: 0 Summary: Build OCI images from APK packages directly without Dockerfile License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.KhtLd1/_old 2025-11-17 12:24:56.893741876 +0100 +++ /var/tmp/diff_new_pack.KhtLd1/_new 2025-11-17 12:24:56.901742213 +0100 @@ -3,7 +3,7 @@ <param name="url">https://github.com/chainguard-dev/apko</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v0.30.20</param> + <param name="revision">v0.30.22</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.KhtLd1/_old 2025-11-17 12:24:56.933743563 +0100 +++ /var/tmp/diff_new_pack.KhtLd1/_new 2025-11-17 12:24:56.941743900 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/chainguard-dev/apko</param> - <param name="changesrevision">60404f94c61fefb78291c4c5091c62c610da05e7</param></service></servicedata> + <param name="changesrevision">1767a213ad33b3965235118732d3bafc06a8de27</param></service></servicedata> (No newline at EOF) ++++++ apko-0.30.20.obscpio -> apko-0.30.22.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/.golangci.yml new/apko-0.30.22/.golangci.yml --- old/apko-0.30.20/.golangci.yml 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/.golangci.yml 2025-11-15 14:34:17.000000000 +0100 @@ -11,6 +11,7 @@ - gosec - importas - misspell + - modernize - prealloc - staticcheck - tparallel @@ -29,6 +30,10 @@ gosec: excludes: - G115 + modernize: + disable: + # Suggest replacing omitempty with omitzero for struct fields. + - omitzero exclusions: generated: lax presets: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/go.mod new/apko-0.30.22/go.mod --- old/apko-0.30.20/go.mod 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/go.mod 2025-11-15 14:34:17.000000000 +0100 @@ -24,12 +24,12 @@ go.lsp.dev/uri v0.3.0 go.opentelemetry.io/otel v1.38.0 go.opentelemetry.io/otel/trace v1.38.0 - go.step.sm/crypto v0.73.0 - golang.org/x/oauth2 v0.32.0 - golang.org/x/sync v0.17.0 - golang.org/x/sys v0.37.0 + go.step.sm/crypto v0.74.0 + golang.org/x/oauth2 v0.33.0 + golang.org/x/sync v0.18.0 + golang.org/x/sys v0.38.0 golang.org/x/time v0.14.0 - google.golang.org/api v0.254.0 + google.golang.org/api v0.255.0 gopkg.in/ini.v1 v1.67.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/apimachinery v0.34.1 @@ -130,7 +130,7 @@ golang.org/x/net v0.46.0 // indirect golang.org/x/text v0.30.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect google.golang.org/grpc v1.76.0 // indirect google.golang.org/protobuf v1.36.10 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/go.sum new/apko-0.30.22/go.sum --- old/apko-0.30.20/go.sum 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/go.sum 2025-11-15 14:34:17.000000000 +0100 @@ -288,8 +288,8 @@ go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= -go.step.sm/crypto v0.73.0 h1:SNFpslZJa+kTNADpWYJJeMsQqzwDiuxFq0ei5OPLIUg= -go.step.sm/crypto v0.73.0/go.mod h1:pw2MKw7aPgx3bVjVwYrKbpMIawLRwth/5cyhZf6QnBM= +go.step.sm/crypto v0.74.0 h1:/APBEv45yYR4qQFg47HA8w1nesIGcxh44pGyQNw6JRA= +go.step.sm/crypto v0.74.0/go.mod h1:UoXqCAJjjRgzPte0Llaqen7O9P7XjPmgjgTHQGkKCDk= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= @@ -321,15 +321,15 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -346,8 +346,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -380,12 +380,12 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.254.0 h1:jl3XrGj7lRjnlUvZAbAdhINTLbsg5dbjmR90+pTQvt4= -google.golang.org/api v0.254.0/go.mod h1:5BkSURm3D9kAqjGvBNgf0EcbX6Rnrf6UArKkwBzAyqQ= +google.golang.org/api v0.255.0 h1:OaF+IbRwOottVCYV2wZan7KUq7UeNUQn1BcPc4K7lE4= +google.golang.org/api v0.255.0/go.mod h1:d1/EtvCLdtiWEV4rAEHDHGh2bCnqsWhw+M8y2ECN4a8= google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/internal/cli/build_test.go new/apko-0.30.22/internal/cli/build_test.go --- old/apko-0.30.20/internal/cli/build_test.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/internal/cli/build_test.go 2025-11-15 14:34:17.000000000 +0100 @@ -99,7 +99,7 @@ // https://github.com/google/go-cmp/issues/224#issuecomment-650429859 transformJSON := cmp.FilterValues(func(x, y []byte) bool { return json.Valid(x) && json.Valid(y) - }, cmp.Transformer("ParseJSON", func(in []byte) (out interface{}) { + }, cmp.Transformer("ParseJSON", func(in []byte) (out any) { if err := json.Unmarshal(in, &out); err != nil { panic(err) // should never occur given previous filter to ensure valid JSON } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/internal/cli/lock.go new/apko-0.30.22/internal/cli/lock.go --- old/apko-0.30.20/internal/cli/lock.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/internal/cli/lock.go 2025-11-15 14:34:17.000000000 +0100 @@ -171,8 +171,6 @@ // TODO: If the archs can't agree on package versions (e.g., arm builds are ahead of x86) then we should fail instead of producing inconsistent locks. for _, arch := range archs { - arch := arch - log := log.With("arch", arch.ToAPK()) ctx := clog.WithLogger(ctx, log) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/internal/ldso-cache/ldsocache.go new/apko-0.30.22/internal/ldso-cache/ldsocache.go --- old/apko-0.30.20/internal/ldso-cache/ldsocache.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/internal/ldso-cache/ldsocache.go 2025-11-15 14:34:17.000000000 +0100 @@ -240,8 +240,8 @@ if !strings.HasPrefix(realname, "lib") && !strings.HasPrefix(realname, "ld-") { return "", "", fmt.Errorf("filename does not start with 'lib' or 'ld-': %s", realname) } - if strings.HasSuffix(realname, ".so") { - name = strings.TrimSuffix(realname, ".so") + if before, ok := strings.CutSuffix(realname, ".so"); ok { + name = before ver = "" return name, ver, nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/internal/tarfs/tarfs.go new/apko-0.30.22/internal/tarfs/tarfs.go --- old/apko-0.30.20/internal/tarfs/tarfs.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/internal/tarfs/tarfs.go 2025-11-15 14:34:17.000000000 +0100 @@ -29,7 +29,7 @@ ) var readerPool = sync.Pool{ - New: func() interface{} { + New: func() any { return bufio.NewReaderSize(nil, 1<<20) }, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/apkindex.go new/apko-0.30.22/pkg/apk/apk/apkindex.go --- old/apko-0.30.20/pkg/apk/apk/apkindex.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/apkindex.go 2025-11-15 14:34:17.000000000 +0100 @@ -303,6 +303,6 @@ func (info *tarballItemFileInfo) Mode() os.FileMode { return 0644 } func (info *tarballItemFileInfo) ModTime() time.Time { return time.Time{} } func (info *tarballItemFileInfo) IsDir() bool { return false } -func (info *tarballItemFileInfo) Sys() interface{} { return nil } +func (info *tarballItemFileInfo) Sys() any { return nil } var _ os.FileInfo = (*tarballItemFileInfo)(nil) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/cache.go new/apko-0.30.22/pkg/apk/apk/cache.go --- old/apko-0.30.20/pkg/apk/apk/cache.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/cache.go 2025-11-15 14:34:17.000000000 +0100 @@ -59,7 +59,7 @@ } } - v, err, _ := f.flight.Do(key, func() (interface{}, error) { + v, err, _ := f.flight.Do(key, func() (any, error) { if v, ok := f.cache.Load(key); ok { return v, nil } @@ -214,7 +214,7 @@ return resp, nil } - v, err, _ := t.cache.headFlight.Do(cacheFile, func() (interface{}, error) { + v, err, _ := t.cache.headFlight.Do(cacheFile, func() (any, error) { req := request.Clone(request.Context()) req.Method = http.MethodHead resp, err := t.wrapped.Do(req) @@ -237,7 +237,7 @@ } func (t *cacheTransport) get(ctx context.Context, request *http.Request, cacheFile, initialEtag string) (string, error) { - v, err, _ := t.cache.getFlight.Do(cacheFile, func() (interface{}, error) { + v, err, _ := t.cache.getFlight.Do(cacheFile, func() (any, error) { // We simulate content-based addressing with the etag values using an .etag file extension. etagFile, err := cacheFileFromEtag(cacheFile, initialEtag) if err != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/common_test_nonunix.go new/apko-0.30.22/pkg/apk/apk/common_test_nonunix.go --- old/apko-0.30.20/pkg/apk/apk/common_test_nonunix.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/common_test_nonunix.go 2025-11-15 14:34:17.000000000 +0100 @@ -13,7 +13,6 @@ // limitations under the License. //go:build windows || darwin || js || wasm -// +build windows darwin js wasm package apk diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/common_test_unix.go new/apko-0.30.22/pkg/apk/apk/common_test_unix.go --- old/apko-0.30.20/pkg/apk/apk/common_test_unix.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/common_test_unix.go 2025-11-15 14:34:17.000000000 +0100 @@ -13,7 +13,6 @@ // limitations under the License. //go:build linux -// +build linux package apk diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/implementation.go new/apko-0.30.22/pkg/apk/apk/implementation.go --- old/apko-0.30.20/pkg/apk/apk/implementation.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/implementation.go 2025-11-15 14:34:17.000000000 +0100 @@ -352,10 +352,8 @@ } for _, pkg := range installedPkgs { - for _, prov := range pkg.Provides { - if prov == "merged-lib" { - return true - } + if slices.Contains(pkg.Provides, "merged-lib") { + return true } } return false @@ -520,7 +518,6 @@ var eg errgroup.Group for _, element := range keyFiles { - element := element eg.Go(func() error { log.Debugf("installing key %v", element) @@ -641,8 +638,6 @@ // concurrently fetch and expand all our APKs. for i, pkg := range allpkgs { - i, pkg := i, pkg - g.Go(func() error { expanded, err := a.expandPackage(ctx, pkg) @@ -809,8 +804,6 @@ // Meanwhile, concurrently fetch and expand all our APKs. // We signal they are ready to be installed by closing done[i]. for i, pkg := range allpkgs { - i, pkg := i, pkg - g.Go(func() error { defer func() { close(done[i]) }() exp, err := a.expandPackage(ctx, pkg) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/index.go new/apko-0.30.22/pkg/apk/apk/index.go --- old/apko-0.30.20/pkg/apk/apk/index.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/index.go 2025-11-15 14:34:17.000000000 +0100 @@ -241,8 +241,6 @@ var eg errgroup.Group for i, repo := range repos { - i, repo := i, repo - eg.Go(func() error { // does it start with a pin? var ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/install.go new/apko-0.30.22/pkg/apk/apk/install.go --- old/apko-0.30.20/pkg/apk/apk/install.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/install.go 2025-11-15 14:34:17.000000000 +0100 @@ -25,6 +25,7 @@ "fmt" "io" "os" + "slices" "strings" "go.opentelemetry.io/otel" @@ -132,10 +133,8 @@ return false, fmt.Errorf("found existing file we did not install (this should never happen): %s", header.Name) } - for _, rep := range pk.Replaces { - if pkg.Name == rep { - return false, nil - } + if slices.Contains(pk.Replaces, pkg.Name) { + return false, nil } // Otherwise, we can only overwrite the file if it's in the same origin or if it replaces the existing package. @@ -289,11 +288,9 @@ return nil, nil } - if strings.HasPrefix(hexsum, "Q1") { + if b64, ok := strings.CutPrefix(hexsum, "Q1"); ok { // This is nonstandard but something we did at one point, handle it. // In other contexts, this Q1 prefix means "this is sha1 not md5". - b64 := strings.TrimPrefix(hexsum, "Q1") - checksum, err := base64.StdEncoding.DecodeString(b64) if err != nil { return nil, fmt.Errorf("decoding base64 checksum from header for %q: %w", header.Name, err) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/installed.go new/apko-0.30.22/pkg/apk/apk/installed.go --- old/apko-0.30.20/pkg/apk/apk/installed.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/installed.go 2025-11-15 14:34:17.000000000 +0100 @@ -432,7 +432,7 @@ // Build a set of all directory paths (with and without trailing slashes) dirPaths := make(map[string]bool) - for i := 0; i < len(headers); i++ { + for i := range headers { if headers[i].Typeflag == tar.TypeDir { // Add both versions of the path (with and without trailing slash) cleanPath := strings.TrimSuffix(headers[i].Name, "/") @@ -446,7 +446,7 @@ dirPaths["."] = true writeIndex := 0 - for readIndex := 0; readIndex < len(headers); readIndex++ { + for readIndex := range headers { keep := true header := headers[readIndex] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/repo_test.go new/apko-0.30.22/pkg/apk/apk/repo_test.go --- old/apko-0.30.20/pkg/apk/apk/repo_test.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/repo_test.go 2025-11-15 14:34:17.000000000 +0100 @@ -286,8 +286,7 @@ tmpDir := t.TempDir() eg := errgroup.Group{} - for i := 0; i < 100; i++ { - i := i + for i := range 100 { eg.Go(func() error { a := prepLayout(t, tmpDir, nil) a.SetClient(&http.Client{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/apk/util.go new/apko-0.30.22/pkg/apk/apk/util.go --- old/apko-0.30.20/pkg/apk/apk/util.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/apk/util.go 2025-11-15 14:34:17.000000000 +0100 @@ -59,8 +59,8 @@ return nil, fmt.Errorf("unable to read .PKGINFO from control tar.gz file: %w", err) } mapping := map[string][]string{} - lines := strings.Split(string(b), "\n") - for _, line := range lines { + lines := strings.SplitSeq(string(b), "\n") + for line := range lines { parts := strings.Split(line, "=") if len(parts) != 2 { continue diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/expandapk/utility.go new/apko-0.30.22/pkg/apk/expandapk/utility.go --- old/apko-0.30.20/pkg/apk/expandapk/utility.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/expandapk/utility.go 2025-11-15 14:34:17.000000000 +0100 @@ -19,11 +19,9 @@ return nil, nil } - if strings.HasPrefix(hexsum, "Q1") { + if b64, ok := strings.CutPrefix(hexsum, "Q1"); ok { // This is nonstandard but something we did at one point, handle it. // In other contexts, this Q1 prefix means "this is sha1 not md5". - b64 := strings.TrimPrefix(hexsum, "Q1") - checksum, err := base64.StdEncoding.DecodeString(b64) if err != nil { return nil, fmt.Errorf("decoding base64 checksum from header for %q: %w", header.Name, err) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/fs/memfs_test.go new/apko-0.30.22/pkg/apk/fs/memfs_test.go --- old/apko-0.30.20/pkg/apk/fs/memfs_test.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/fs/memfs_test.go 2025-11-15 14:34:17.000000000 +0100 @@ -434,7 +434,7 @@ } // now walk the tree, we should get consistent results each time var results []string - for i := 0; i < 10; i++ { + for i := range 10 { var result []string err := fs.WalkDir(m, "/", func(path string, _ fs.DirEntry, err error) error { require.NoError(t, err) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/fs/rwosfs.go new/apko-0.30.22/pkg/apk/fs/rwosfs.go --- old/apko-0.30.20/pkg/apk/fs/rwosfs.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/fs/rwosfs.go 2025-11-15 14:34:17.000000000 +0100 @@ -656,7 +656,7 @@ func (f *fileInfo) IsDir() bool { return f.file.IsDir() } -func (f *fileInfo) Sys() interface{} { +func (f *fileInfo) Sys() any { return f.mem.Sys() } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/apk/fs/rwosfs_test.go new/apko-0.30.22/pkg/apk/fs/rwosfs_test.go --- old/apko-0.30.20/pkg/apk/fs/rwosfs_test.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/apk/fs/rwosfs_test.go 2025-11-15 14:34:17.000000000 +0100 @@ -238,7 +238,7 @@ } // now walk the tree, we should get consistent results each time var results []string - for i := 0; i < 10; i++ { + for i := range 10 { var result []string err := fs.WalkDir(fsys, "/", func(path string, _ fs.DirEntry, err error) error { require.NoError(t, err) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/build/build_implementation.go new/apko-0.30.22/pkg/build/build_implementation.go --- old/apko-0.30.20/pkg/build/build_implementation.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/build/build_implementation.go 2025-11-15 14:34:17.000000000 +0100 @@ -51,7 +51,7 @@ var pgzipThreads = min(runtime.GOMAXPROCS(0), 8) var pgzipPool = sync.Pool{ - New: func() interface{} { + New: func() any { zw := gzip.NewWriter(nil) if err := zw.SetConcurrency(1<<20, pgzipThreads); err != nil { // This should never happen. @@ -68,7 +68,7 @@ } var bufioPool = sync.Pool{ - New: func() interface{} { + New: func() any { return bufio.NewWriterSize(nil, 1<<22) }, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/build/multi.go new/apko-0.30.22/pkg/build/multi.go --- old/apko-0.30.20/pkg/build/multi.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/build/multi.go 2025-11-15 14:34:17.000000000 +0100 @@ -72,8 +72,6 @@ layers := map[types.Architecture]v1.Layer{} errs := []error{} for arch, bc := range m.Contexts { - arch, bc := arch, bc - g.Go(func() error { _, layer, err := bc.BuildLayer(ctx) @@ -110,8 +108,6 @@ toInstalls := map[types.Architecture][]*apk.RepositoryPackage{} errs := []error{} for arch, bc := range m.Contexts { - arch, bc := arch, bc - g.Go(func() error { toInstall, _, err := bc.apk.ResolveWorld(ctx) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/build/oci/index.go new/apko-0.30.22/pkg/build/oci/index.go --- old/apko-0.30.20/pkg/build/oci/index.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/build/oci/index.go 2025-11-15 14:34:17.000000000 +0100 @@ -20,6 +20,7 @@ "errors" "fmt" "io" + "maps" "os" "sort" "strings" @@ -59,9 +60,7 @@ // If annotations are set and we're using the OCI mediaType, set annotations on the index. annCopy := make(map[string]string, len(ic.Annotations)) if mediaType == ggcrtypes.OCIImageIndex { - for k, v := range ic.Annotations { - annCopy[k] = v - } + maps.Copy(annCopy, ic.Annotations) if ic.VCSUrl != "" { if url, hash, ok := strings.Cut(ic.VCSUrl, "@"); ok { annCopy["org.opencontainers.image.source"] = url diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/build/oci/publish.go new/apko-0.30.22/pkg/build/oci/publish.go --- old/apko-0.30.20/pkg/build/oci/publish.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/build/oci/publish.go 2025-11-15 14:34:17.000000000 +0100 @@ -162,8 +162,6 @@ var g errgroup.Group for i, m := range manifest.Manifests { - i, m := i, m - dig := repo.Digest(m.Digest.String()) digests[i] = dig diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/build/options.go new/apko-0.30.22/pkg/build/options.go --- old/apko-0.30.20/pkg/build/options.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/build/options.go 2025-11-15 14:34:17.000000000 +0100 @@ -19,6 +19,7 @@ sha2562 "crypto/sha256" "encoding/base64" "fmt" + "maps" "net/http" "time" @@ -35,7 +36,6 @@ // WithConfig sets the image configuration for the build context. // The image configuration is parsed from given config file. // TODO(jason): Remove this. -// Deprecated: Use WithImageConfiguration instead. func WithConfig(configFile string, includePaths []string) Option { return func(bc *Context) error { ctx := context.Background() @@ -184,9 +184,7 @@ if bc.ic.Annotations == nil { bc.ic.Annotations = make(map[string]string) } - for k, v := range annotations { - bc.ic.Annotations[k] = v - } + maps.Copy(bc.ic.Annotations, annotations) return nil } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/build/types/types.go new/apko-0.30.22/pkg/build/types/types.go --- old/apko-0.30.20/pkg/build/types/types.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/build/types/types.go 2025-11-15 14:34:17.000000000 +0100 @@ -18,11 +18,41 @@ "fmt" "net/url" "runtime" - "sort" + "slices" + "strings" v1 "github.com/google/go-containerregistry/pkg/v1" ) +func processRepositoryURLs(repositories []string) error { + for idx, repo := range repositories { + parts := strings.Split(repo, " ") + switch len(parts) { + case 2: + tag := parts[0] + rawURL := parts[1] + if !strings.HasPrefix(tag, "@") || len(tag) <= 1 { + return fmt.Errorf("invalid tag format in repository: %s (expected @tag format)", tag) + } + parsed, err := url.Parse(rawURL) + if err != nil { + return fmt.Errorf("parsing repository URL: %w", err) + } + repositories[idx] = tag + " " + parsed.Redacted() + case 1: + rawURL := repo + parsed, err := url.Parse(rawURL) + if err != nil { + return fmt.Errorf("parsing repository URL: %w", err) + } + repositories[idx] = parsed.Redacted() + default: + return fmt.Errorf("invalid repository format: %s (expected either 'url' or '@tag url')", repo) + } + } + return nil +} + type User struct { // Required: The name of the user UserName string `json:"username,omitempty"` @@ -96,26 +126,16 @@ // MarshalYAML implements yaml.Marshaler for ImageContents, redacting URLs in // the ImageContents struct fields. -func (i ImageContents) MarshalYAML() (interface{}, error) { +func (i ImageContents) MarshalYAML() (any, error) { type redactedImageContents ImageContents ri := redactedImageContents(i) - for idx, repo := range ri.BuildRepositories { - rawURL := repo - parsed, err := url.Parse(rawURL) - if err != nil { - return nil, fmt.Errorf("parsing repository URL: %w", err) - } - ri.BuildRepositories[idx] = parsed.Redacted() + if err := processRepositoryURLs(ri.BuildRepositories); err != nil { + return nil, err } - for idx, repo := range ri.Repositories { - rawURL := repo - parsed, err := url.Parse(rawURL) - if err != nil { - return nil, fmt.Errorf("parsing repository URL: %w", err) - } - ri.Repositories[idx] = parsed.Redacted() + if err := processRepositoryURLs(ri.Repositories); err != nil { + return nil, err } for idx, key := range ri.Keyring { @@ -207,7 +227,7 @@ func (a Architecture) String() string { return string(a) } -func (a *Architecture) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (a *Architecture) UnmarshalYAML(unmarshal func(any) error) error { var buf string if err := unmarshal(&buf); err != nil { return err @@ -401,9 +421,7 @@ for k := range uniq { archs = append(archs, k) } - sort.Slice(archs, func(i, j int) bool { - return archs[i] < archs[j] - }) + slices.Sort(archs) return archs } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/build/types/types_test.go new/apko-0.30.22/pkg/build/types/types_test.go --- old/apko-0.30.20/pkg/build/types/types_test.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/build/types/types_test.go 2025-11-15 14:34:17.000000000 +0100 @@ -15,6 +15,7 @@ package types import ( + "fmt" "strings" "testing" @@ -23,6 +24,84 @@ "gopkg.in/yaml.v3" ) +func TestYamlMarshallingRepositories(t *testing.T) { + const alpineMain = "https://dl-cdn.alpinelinux.org/alpine/v3.22/main" + const alpineCommunity = "https://dl-cdn.alpinelinux.org/alpine/v3.22/community" + const alpineEdgeTesting = "https://dl-cdn.alpinelinux.org/alpine/edge/testing" + const alpineEdgeCommunity = "https://dl-cdn.alpinelinux.org/alpine/edge/community" + const alpineWithCreds = "https://user:[email protected]/alpine/v3.22/main" + + for _, c := range []struct { + desc string + in ImageContents + want string + }{{ + desc: "empty", + in: ImageContents{}, + want: "{}\n", + }, { + desc: "simple", + in: ImageContents{ + Repositories: []string{alpineMain, alpineCommunity}, + BuildRepositories: []string{alpineMain, alpineCommunity}, + }, + want: fmt.Sprintf("build_repositories:\n - %s\n - %s\nrepositories:\n - %s\n - %s\n", alpineMain, alpineCommunity, alpineMain, alpineCommunity), + }, { + desc: "tagged", + in: ImageContents{ + Repositories: []string{"@testing " + alpineEdgeTesting}, + BuildRepositories: []string{"@community " + alpineEdgeCommunity}, + }, + want: fmt.Sprintf("build_repositories:\n - '@community %s'\nrepositories:\n - '@testing %s'\n", alpineEdgeCommunity, alpineEdgeTesting), + }, { + desc: "tagged with creds", + in: ImageContents{ + Repositories: []string{"@myorg " + alpineWithCreds}, + }, + want: fmt.Sprintf("repositories:\n - '@myorg %s'\n", "https://user:[email protected]/alpine/v3.22/main"), + }, { + desc: "invalid tag format - missing @", + in: ImageContents{ + Repositories: []string{"testing https://dl-cdn.alpinelinux.org/alpine/edge/testing"}, + }, + want: "error", // This will cause an error during marshalling + }, { + desc: "invalid tag format - empty tag", + in: ImageContents{ + Repositories: []string{"@ https://dl-cdn.alpinelinux.org/alpine/edge/testing"}, + }, + want: "error", // This will cause an error during marshalling + }, { + desc: "invalid URL in tagged repository", + in: ImageContents{ + Repositories: []string{"@testing ://invalid-url"}, + }, + want: "error", // This will cause an error during marshalling + }, { + desc: "invalid URL in untagged repository", + in: ImageContents{ + Repositories: []string{"://invalid-url"}, + }, + want: "error", // This will cause an error during marshalling + }, { + desc: "too many parts in repository", + in: ImageContents{ + Repositories: []string{"@testing https://example.com extra-part"}, + }, + want: "error", // This will cause an error during marshalling + }} { + t.Run(c.desc, func(t *testing.T) { + b, err := yaml.Marshal(c.in) + if c.want == "error" { + require.Error(t, err, "expected error for invalid repository format") + } else { + require.NoError(t, err) + require.Equal(t, c.want, string(b)) + } + }) + } +} + func TestParseArchitectures(t *testing.T) { for _, c := range []struct { desc string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/s6/supervision_tree.go new/apko-0.30.22/pkg/s6/supervision_tree.go --- old/apko-0.30.20/pkg/s6/supervision_tree.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/s6/supervision_tree.go 2025-11-15 14:34:17.000000000 +0100 @@ -33,7 +33,7 @@ return fmt.Errorf("could not make supervision directory: %w", err) } - if err := sc.fs.WriteFile(filepath.Join(svcdir, "run"), []byte(fmt.Sprintf("#!/bin/execlineb\n%s\n", svccmd)), 0755); err != nil { + if err := sc.fs.WriteFile(filepath.Join(svcdir, "run"), fmt.Appendf(nil, "#!/bin/execlineb\n%s\n", svccmd), 0755); err != nil { return fmt.Errorf("could not write runfile: %w", err) } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/sbom/generator/spdx/spdx.go new/apko-0.30.22/pkg/sbom/generator/spdx/spdx.go --- old/apko-0.30.20/pkg/sbom/generator/spdx/spdx.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/sbom/generator/spdx/spdx.go 2025-11-15 14:34:17.000000000 +0100 @@ -683,8 +683,8 @@ } // If this is a github package, add a purl to it: - if strings.HasPrefix(packageName, "github.com/") { - slug := strings.TrimPrefix(packageName, "github.com/") + if after, ok := strings.CutPrefix(packageName, "github.com/"); ok { + slug := after org, user, ok := strings.Cut(slug, "/") if ok { sourcePackage.ExternalRefs = []ExternalRef{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/sbom/generator/spdx/spdx_test.go new/apko-0.30.22/pkg/sbom/generator/spdx/spdx_test.go --- old/apko-0.30.20/pkg/sbom/generator/spdx/spdx_test.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/sbom/generator/spdx/spdx_test.go 2025-11-15 14:34:17.000000000 +0100 @@ -250,7 +250,7 @@ fsys := apkfs.NewMemFS() sx := New(fsys) d := [][]byte{} - for i := 0; i < 2; i++ { + for i := range 2 { path := filepath.Join(dir, fmt.Sprintf("sbom%d.%s", i, sx.Ext())) require.NoError(t, sx.Generate(t.Context(), testOpts, path)) require.FileExists(t, path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/tarfs/fs.go new/apko-0.30.22/pkg/tarfs/fs.go --- old/apko-0.30.20/pkg/tarfs/fs.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/tarfs/fs.go 2025-11-15 14:34:17.000000000 +0100 @@ -27,6 +27,7 @@ "os" "path" "path/filepath" + "slices" "sort" "strings" "sync" @@ -84,11 +85,9 @@ return nil, nil } - if strings.HasPrefix(hexsum, "Q1") { + if b64, ok := strings.CutPrefix(hexsum, "Q1"); ok { // This is nonstandard but something we did at one point, handle it. // In other contexts, this Q1 prefix means "this is sha1 not md5". - b64 := strings.TrimPrefix(hexsum, "Q1") - checksum, err := base64.StdEncoding.DecodeString(b64) if err != nil { return nil, fmt.Errorf("decoding base64 checksum from header for %q: %w", header.Name, err) @@ -495,20 +494,12 @@ } // If the existing file's package replaces the package we want to install, we don't need to write this file. - for _, replace := range got.pkg.Replaces { - if want.pkg.Name == replace { - return false, nil - } + if slices.Contains(got.pkg.Replaces, want.pkg.Name) { + return false, nil } // Otherwise, determine if the package we are installing replaces the existing package. - replaces := false - for _, replace := range want.pkg.Replaces { - if got.pkg.Name == replace { - replaces = true - break - } - } + replaces := slices.Contains(want.pkg.Replaces, got.pkg.Name) // Or if they're from the same origin. sameOrigin := got.pkg.Origin == want.pkg.Origin diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/vfs/fsmode.go new/apko-0.30.22/pkg/vfs/fsmode.go --- old/apko-0.30.20/pkg/vfs/fsmode.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/vfs/fsmode.go 2025-11-15 14:34:17.000000000 +0100 @@ -13,7 +13,6 @@ // limitations under the License. //go:build !darwin && !linux -// +build !darwin,!linux package vfs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/vfs/fsmode_darwin.go new/apko-0.30.22/pkg/vfs/fsmode_darwin.go --- old/apko-0.30.20/pkg/vfs/fsmode_darwin.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/vfs/fsmode_darwin.go 2025-11-15 14:34:17.000000000 +0100 @@ -13,7 +13,6 @@ // limitations under the License. //go:build darwin -// +build darwin package vfs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/apko-0.30.20/pkg/vfs/fsmode_linux.go new/apko-0.30.22/pkg/vfs/fsmode_linux.go --- old/apko-0.30.20/pkg/vfs/fsmode_linux.go 2025-11-04 04:30:38.000000000 +0100 +++ new/apko-0.30.22/pkg/vfs/fsmode_linux.go 2025-11-15 14:34:17.000000000 +0100 @@ -13,7 +13,6 @@ // limitations under the License. //go:build linux -// +build linux package vfs ++++++ apko.obsinfo ++++++ --- /var/tmp/diff_new_pack.KhtLd1/_old 2025-11-17 12:24:58.045790458 +0100 +++ /var/tmp/diff_new_pack.KhtLd1/_new 2025-11-17 12:24:58.057790964 +0100 @@ -1,5 +1,5 @@ name: apko -version: 0.30.20 -mtime: 1762227038 -commit: 60404f94c61fefb78291c4c5091c62c610da05e7 +version: 0.30.22 +mtime: 1763213657 +commit: 1767a213ad33b3965235118732d3bafc06a8de27 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/apko/vendor.tar.gz /work/SRC/openSUSE:Factory/.apko.new.2061/vendor.tar.gz differ: char 13, line 1
