nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: datreeio/datree
Pull request #152 (2021-08-30 09:39:53)

fix: brew versioning


Patch:
diff --git a/internal/release/internal_deploy.sh b/internal/release/internal_deploy.sh
index d320740..b209972 100644
--- a/internal/release/internal_deploy.sh
+++ b/internal/release/internal_deploy.sh
@@ -1,9 +1,11 @@
 set -ex
-touch temp
-git add -A
+
 export DATREE_INTERNAL=$SEMVER_NUMBER-internal
+sed -ie "s/homebrew-datree/homebrew-datree-internal/" .goreleaser.yml
+git add -A
 git commit -m "release $DATREE_INTERNAL"
 git tag $DATREE_INTERNAL -a -m "Generated internal tag from TravisCI for build $TRAVIS_BUILD_NUMBER"
 git push --tags
+
 export DATREE_BUILD_VERSION=$DATREE_INTERNAL
 curl -sL https://git.io/goreleaser | VERSION=v$GORELEASER_VERSION sh -s -- --rm-dist
diff --git a/pkg/cliClient/publish.go b/pkg/cliClient/publish.go
index 290da77..3ff11d0 100644
--- a/pkg/cliClient/publish.go
+++ b/pkg/cliClient/publish.go
@@ -6,7 +6,6 @@ import (
 )
 
 func (c *CliClient) PublishPolicies(policiesConfiguration files.UnknownStruct, cliId string) error {
-	headers := map[string]string{"x-cli-id": cliId}
-	_, err := c.httpClient.Request(http.MethodPut, "/cli/policy/publish", policiesConfiguration, headers)
+	_, err := c.httpClient.Request(http.MethodPut, "/cli/policy/publish/cliIds/"+cliId, policiesConfiguration, nil)
 	return err
 }


Test patch:
diff --git a/pkg/cliClient/cliClient_test.go b/pkg/cliClient/cliClient_test.go
index 0690f34..ab676c7 100644
--- a/pkg/cliClient/cliClient_test.go
+++ b/pkg/cliClient/cliClient_test.go
@@ -438,8 +438,6 @@ func test_createEvaluation_success() *CreateEvaluationTestCase {
 }
 
 func test_publishPolicies_success() *PublishPoliciesTestCase {
-	expectedPublishHeaders := map[string]string{"x-cli-id": "cli_id"}
-
 	requestPoliciesConfigurationArg := files.UnknownStruct{}
 	return &PublishPoliciesTestCase{
 		name: "success - publish policies",
@@ -481,9 +479,9 @@ func test_publishPolicies_success() *PublishPoliciesTestCase {
 				headers map[string]string
 			}{
 				method:  http.MethodPut,
-				uri:     "/cli/policy/publish",
+				uri:     "/cli/policy/publish/cliIds/cli_id",
 				body:    requestPoliciesConfigurationArg,
-				headers: expectedPublishHeaders,
+				headers: nil,
 			},
 			response: nil,
 		},
@@ -491,8 +489,6 @@ func test_publishPolicies_success() *PublishPoliciesTestCase {
 }
 
 func test_publishPolicies_schemaError() *PublishPoliciesTestCase {
-	expectedPublishHeaders := map[string]string{"x-cli-id": "cli_id"}
-
 	requestPoliciesConfigurationArg := files.UnknownStruct{}
 	return &PublishPoliciesTestCase{
 		name: "schema error - publish policies",
@@ -534,9 +530,9 @@ func test_publishPolicies_schemaError() *PublishPoliciesTestCase {
 				headers map[string]string
 			}{
 				method:  http.MethodPut,
-				uri:     "/cli/policy/publish",
+				uri:     "/cli/policy/publish/cliIds/cli_id",
 				body:    requestPoliciesConfigurationArg,
-				headers: expectedPublishHeaders,
+				headers: nil,
 			},
 			response: errors.New("error from cli-service"),
 		},
Repository: datreeio/datree
Pull request #462 (2022-03-03 09:34:27)

fix: add argo CRD support


Patch:
diff --git a/bl/validation/k8sValidator.go b/bl/validation/k8sValidator.go
index cae5706..77fe1af 100644
--- a/bl/validation/k8sValidator.go
+++ b/bl/validation/k8sValidator.go
@@ -23,7 +23,7 @@ func New() *K8sValidator {
 }
 
 func (val *K8sValidator) InitClient(k8sVersion string, ignoreMissingSchemas bool, schemaLocations []string) {
-	val.validationClient = newKubconformValidator(k8sVersion, ignoreMissingSchemas, schemaLocations)
+	val.validationClient = newKubconformValidator(k8sVersion, ignoreMissingSchemas, append(getDefaultSchemaLocation(), schemaLocations...))
 }
 
 func (val *K8sValidator) ValidateResources(filesConfigurationsChan chan *extractor.FileConfigurations, concurrency int) (chan *extractor.FileConfigurations, chan *extractor.InvalidFile) {
@@ -146,3 +146,16 @@ func isEveryResultStatusEmpty(results []kubeconformValidator.Result) bool {
 	}
 	return isEveryResultStatusEmpty
 }
+
+func getDefaultSchemaLocation() []string {
+	defaultSchemaLocations := [...]string{
+		"default",
+		getDatreeCRDSchemaByName("argo"),
+	}
+	return (defaultSchemaLocations[:])
+}
+
+func getDatreeCRDSchemaByName(crdCatalogName string) string {
+	crdCatalog := "https://raw.githubusercontent.com/datreeio/CRDs-catalog/master/" + crdCatalogName + "/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json"
+	return crdCatalog
+}


Test patch:
diff --git a/bl/validation/k8sValidator_test.go b/bl/validation/k8sValidator_test.go
index d263d37..676b001 100644
--- a/bl/validation/k8sValidator_test.go
+++ b/bl/validation/k8sValidator_test.go
@@ -24,6 +24,8 @@ func TestValidateResources(t *testing.T) {
 	test_valid_multiple_configurations(t)
 	test_valid_multiple_configurations_only_k8s_files(t)
 	test_invalid_file(t)
+	test_default_schema_location(t)
+	test_get_datree_crd_schema_by_name(t)
 	t.Run("test empty file", test_empty_file)
 }
 
@@ -122,3 +124,19 @@ func test_empty_file(t *testing.T) {
 		assert.Equal(t, path, p.Path)
 	}
 }
+
+func test_default_schema_location(t *testing.T) {
+	expectedOutput := []string{"default", "https://raw.githubusercontent.com/datreeio/CRDs-catalog/master/argo/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json"}
+	actual := getDefaultSchemaLocation()
+	assert.Equal(t, expectedOutput, actual)
+}
+
+func test_get_datree_crd_schema_by_name(t *testing.T) {
+	input := "argo"
+	expectedOutput := "https://raw.githubusercontent.com/datreeio/CRDs-catalog/master/argo/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json"
+	actual := getDatreeCRDSchemaByName(input)
+
+	if actual != expectedOutput {
+		t.Errorf("Expected: %s, Actual: %s", expectedOutput, actual)
+	}
+}
Repository: datreeio/datree
Pull request #511 (2022-03-20 18:39:22)

refactor: move argument logic to `Args` block
Fixes: #433 

**Changes proposed in the PR**
In this PR we need to move arguments validation logic in the `Args` block of cobra command. 

**Testing Instruction**
Since this is a refactor work make sure all test cases are passing, build is successful and functionality is working as expected.



Patch:
diff --git a/cmd/kustomize/main.go b/cmd/kustomize/main.go
index 60ef0a5..5ddbc9e 100644
--- a/cmd/kustomize/main.go
+++ b/cmd/kustomize/main.go
@@ -43,6 +43,9 @@ func New(testCtx *test.TestCommandContext, kustomizeCtx *KustomizeContext) *cobr
 		# Test the kustomize build from github
 		datree kustomize test https://github.com/kubernetes-sigs/kustomize.git/examples/helloWorld?ref=v1.0.6
 		`),
+		Args: func(cmd *cobra.Command, args []string) error {
+			return utils.ValidateStdinPathArgument(args)
+		},
 		PreRunE: func(cmd *cobra.Command, args []string) error {
 			return test.LoadVersionMessages(testCtx, args, cmd)
 		},
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index c498eac..19c69a7 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -1,6 +1,9 @@
 package utils
 
-import "strings"
+import (
+	"fmt"
+	"strings"
+)
 
 func Example(s string) string {
 	if len(s) == 0 {
@@ -30,3 +33,13 @@ func (s normalize) indent() normalize {
 	s.string = strings.Join(indentedLines, "\n")
 	return s
 }
+
+func ValidateStdinPathArgument(paths []string) error {
+	if paths[0] == "-" {
+		if len(paths) > 1 {
+			return fmt.Errorf(fmt.Sprintf("Unexpected args: [%s]", strings.Join(paths[1:], ",")))
+		}
+	}
+
+	return nil
+}


Test patch:
diff --git a/cmd/test/main.go b/cmd/test/main.go
index f0a99c9..5ed7481 100644
--- a/cmd/test/main.go
+++ b/cmd/test/main.go
@@ -171,11 +171,11 @@ func New(ctx *TestCommandContext) *cobra.Command {
 				errMessage := "Requires at least 1 arg\n"
 				return fmt.Errorf(errMessage)
 			}
-			err := testCommandFlags.Validate()
+			err := utils.ValidateStdinPathArgument(args)
 			if err != nil {
 				return err
 			}
-			return nil
+			return testCommandFlags.Validate()
 		},
 		PreRunE: func(cmd *cobra.Command, args []string) error {
 			return LoadVersionMessages(ctx, args, cmd)
@@ -189,11 +189,6 @@ func New(ctx *TestCommandContext) *cobra.Command {
 				}
 			}()
 
-			err = testCommandFlags.Validate()
-			if err != nil {
-				return err
-			}
-
 			localConfigContent, err := ctx.LocalConfig.GetLocalConfiguration()
 			if err != nil {
 				return err
@@ -301,9 +296,6 @@ func validateK8sVersionFormatIfProvided(k8sVersion string) error {
 
 func Test(ctx *TestCommandContext, paths []string, prerunData *TestCommandData) error {
 	if paths[0] == "-" {
-		if len(paths) > 1 {
-			return fmt.Errorf(fmt.Sprintf("Unexpected args: [%s]", strings.Join(paths[1:], ",")))
-		}
 		tempFile, err := os.CreateTemp("", "datree_temp_*.yaml")
 		if err != nil {
 			return err
Repository: datreeio/datree
Pull request #524 (2022-03-23 10:18:26)

fix: fail policy-config if no pac mode


Patch:
diff --git a/pkg/cliClient/evaluation.go b/pkg/cliClient/evaluation.go
index 2192bd2..bbbafe8 100644
--- a/pkg/cliClient/evaluation.go
+++ b/pkg/cliClient/evaluation.go
@@ -96,6 +96,7 @@ type EvaluationPrerunDataResponse struct {
 	AccountExists         bool                      `json:"accountExists"`
 	RegistrationURL       string                    `json:"registrationURL"`
 	PromptRegistrationURL string                    `json:"promptRegistrationURL"`
+	IsPolicyAsCodeMode    bool                      `json:"isPolicyAsCodeMode"`
 }
 
 const badRequestStatusCode = 400


Test patch:
diff --git a/cmd/test/main.go b/cmd/test/main.go
index 139f15c..0ee29f9 100644
--- a/cmd/test/main.go
+++ b/cmd/test/main.go
@@ -251,6 +251,10 @@ func GenerateTestCommandData(testCommandFlags *TestCommandFlags, localConfigCont
 	var err error
 
 	if testCommandFlags.PolicyConfig != "" {
+		if !evaluationPrerunDataResp.IsPolicyAsCodeMode {
+			return nil, fmt.Errorf("To use --policy-config flag you must first enable policy-as-code mode: https://hub.datree.io/policy-as-code")
+		}
+
 		policies, err = policy.GetPoliciesFileFromPath(testCommandFlags.PolicyConfig)
 		if err != nil {
 			return nil, err
Repository: datreeio/datree
Pull request #565 (2022-04-10 17:37:15)

fix: check for correct name


Patch:
diff --git a/pkg/policy/defaultRules.yaml b/pkg/policy/defaultRules.yaml
index c6d7e4d..4e6cc0f 100644
--- a/pkg/policy/defaultRules.yaml
+++ b/pkg/policy/defaultRules.yaml
@@ -962,7 +962,7 @@ rules:
                   - argocd-rbac-cm
                   - argocd-ssh-known-hosts-cm
                   - argocd-cmd-params-cm
-                  - argo-cm
+                  - argocd-cm
       then:
         properties:
           metadata:


Test patch:
diff --git a/pkg/policy/tests/37-fail.yaml b/pkg/policy/tests/37-fail.yaml
index 29af666..862de23 100644
--- a/pkg/policy/tests/37-fail.yaml
+++ b/pkg/policy/tests/37-fail.yaml
@@ -1,7 +1,7 @@
 apiVersion: v1
 kind: ConfigMap
 metadata:
-  name: argo-cm
+  name: argocd-cm
   labels:
     app.kubernetes.io/name: argocd-cm
     app.kubernetes.io/part-of: argoc
Repository: datreeio/datree
Pull request #572 (2022-04-13 08:57:05)

feat: support k8s validation for kind `CustomResourceDefinition`


Patch:
diff --git a/bl/validation/k8sValidator.go b/bl/validation/k8sValidator.go
index bb9c6fb..165d5ca 100644
--- a/bl/validation/k8sValidator.go
+++ b/bl/validation/k8sValidator.go
@@ -25,7 +25,7 @@ func New() *K8sValidator {
 }
 
 func (val *K8sValidator) InitClient(k8sVersion string, ignoreMissingSchemas bool, schemaLocations []string) {
-	val.validationClient = newKubconformValidator(k8sVersion, ignoreMissingSchemas, append(getDefaultSchemaLocation(), schemaLocations...))
+	val.validationClient = newKubeconformValidator(k8sVersion, ignoreMissingSchemas, append(getDefaultSchemaLocations(), schemaLocations...))
 }
 
 type FileWithWarning struct {
@@ -157,7 +157,7 @@ func (val *K8sValidator) isNetworkError(errorString string) bool {
 	return strings.Contains(errorString, "no such host") || strings.Contains(errorString, "connection refused")
 }
 
-func newKubconformValidator(k8sVersion string, ignoreMissingSchemas bool, schemaLocations []string) ValidationClient {
+func newKubeconformValidator(k8sVersion string, ignoreMissingSchemas bool, schemaLocations []string) ValidationClient {
 	v, _ := kubeconformValidator.New(schemaLocations, kubeconformValidator.Opts{Strict: true, KubernetesVersion: k8sVersion, IgnoreMissingSchemas: ignoreMissingSchemas})
 	return v
 }
@@ -172,12 +172,14 @@ func isEveryResultStatusEmpty(results []kubeconformValidator.Result) bool {
 	return isEveryResultStatusEmpty
 }
 
-func getDefaultSchemaLocation() []string {
-	defaultSchemaLocations := [...]string{
+func getDefaultSchemaLocations() []string {
+	return []string{
 		"default",
+		// this is a workaround for https://github.com/yannh/kubeconform/issues/100
+		// notice: order here is important because this fallback doesn't have strict mode enabled (in contrast to "default")
+		"https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/{{ .NormalizedKubernetesVersion }}/{{ .ResourceKind }}{{ .KindSuffix }}.json",
 		getDatreeCRDSchemaByName("argo"),
 	}
-	return (defaultSchemaLocations[:])
 }
 
 func getDatreeCRDSchemaByName(crdCatalogName string) string {


Test patch:
diff --git a/bl/validation/k8sValidator_test.go b/bl/validation/k8sValidator_test.go
index 4d95941..be9d01e 100644
--- a/bl/validation/k8sValidator_test.go
+++ b/bl/validation/k8sValidator_test.go
@@ -168,8 +168,12 @@ func test_no_connection(t *testing.T) {
 }
 
 func test_default_schema_location(t *testing.T) {
-	expectedOutput := []string{"default", "https://raw.githubusercontent.com/datreeio/CRDs-catalog/master/argo/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json"}
-	actual := getDefaultSchemaLocation()
+	expectedOutput := []string{
+		"default",
+		"https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/{{ .NormalizedKubernetesVersion }}/{{ .ResourceKind }}{{ .KindSuffix }}.json",
+		"https://raw.githubusercontent.com/datreeio/CRDs-catalog/master/argo/{{ .ResourceKind }}_{{ .ResourceAPIVersion }}.json",
+	}
+	actual := getDefaultSchemaLocations()
 	assert.Equal(t, expectedOutput, actual)
 }
Repository: datreeio/datree
Pull request #593 (2022-04-29 21:23:05)

feat: add output format test help cmd
Fixes: #586 

royhadad: @amustaque97 are you still working on this PR or can we close it?
amustaque97: > @amustaque97 are you still working on this PR or can we close it?

Thanks for the ping. Looks like I lost the track. Let me continue working on the PR. I will make the required changes. 

Patch:
diff --git a/bl/evaluation/output_flag.go b/bl/evaluation/output_flag.go
index 3f4d43c..8303499 100644
--- a/bl/evaluation/output_flag.go
+++ b/bl/evaluation/output_flag.go
@@ -1,9 +1,11 @@
 package evaluation
 
+import "strings"
+
 var FormattedOutputOptions = []string{"yaml", "json", "xml", "JUnit"}
 var InteractiveOutputOptions = []string{"", "simple"}
 var ValidOutputOptions = append(FormattedOutputOptions, InteractiveOutputOptions...)
-var ExplicitOptionOptions = []string{"simple", "yaml", "json", "xml", "JUnit"}
+var ExplicitOutputOptions = []string{"simple", "yaml", "json", "xml", "JUnit"}
 
 func IsValidOutputOption(option string) bool {
 	for _, validOption := range ValidOutputOptions {
@@ -22,3 +24,7 @@ func IsFormattedOutputOption(option string) bool {
 	}
 	return false
 }
+
+func OutputFormats() string {
+	return strings.Join(ExplicitOutputOptions, ", ")
+}


Test patch:
diff --git a/cmd/test/main.go b/cmd/test/main.go
index 06788ec..3fd0ad2 100644
--- a/cmd/test/main.go
+++ b/cmd/test/main.go
@@ -77,7 +77,7 @@ func (flags *TestCommandFlags) Validate() error {
 
 	if !evaluation.IsValidOutputOption(outputValue) {
 		return fmt.Errorf("invalid --output option - %q\n"+
-			"Valid output values are - "+strings.Join(evaluation.ExplicitOptionOptions, ", "), outputValue)
+			"Valid output values are - "+evaluation.OutputFormats(), outputValue)
 	}
 
 	err := validateK8sVersionFormatIfProvided(flags.K8sVersion)
@@ -239,11 +239,12 @@ func (flags *TestCommandFlags) ToMapping() map[string]interface{} {
 
 // AddFlags registers flags for a cli
 func (flags *TestCommandFlags) AddFlags(cmd *cobra.Command) {
+	defaultOutputValue := ""
 	if ciContext.Extract() != nil && ciContext.Extract().CIMetadata.ShouldHideEmojis {
-		cmd.Flags().StringVarP(&flags.Output, "output", "o", "simple", "Define output format")
-	} else {
-		cmd.Flags().StringVarP(&flags.Output, "output", "o", "", "Define output format")
+		defaultOutputValue = "simple"
 	}
+	cmd.Flags().StringVarP(&flags.Output, "output", "o", defaultOutputValue, "Define output format ("+evaluation.OutputFormats()+")")
+
 	cmd.Flags().StringVarP(&flags.K8sVersion, "schema-version", "s", "", "Set kubernetes version to validate against. Defaults to 1.19.0")
 	cmd.Flags().StringVarP(&flags.PolicyName, "policy", "p", "", "Policy name to run against")
Repository: chainguard-dev/apko
Pull request #1376 (2024-10-29 19:29:39)

MergeInto should include Volumes
We were dropping these :(


Patch:
diff --git a/pkg/build/types/image_configuration.go b/pkg/build/types/image_configuration.go
index a275330..089fcf3 100644
--- a/pkg/build/types/image_configuration.go
+++ b/pkg/build/types/image_configuration.go
@@ -145,6 +145,8 @@ func (ic *ImageConfiguration) MergeInto(target *ImageConfiguration) error {
 		}
 	}
 
+	target.Volumes = slices.Concat(ic.Volumes, target.Volumes)
+
 	// Update the contents.
 	return ic.Contents.MergeInto(&target.Contents)
 }


Test patch:
diff --git a/pkg/build/types/image_configuration_test.go b/pkg/build/types/image_configuration_test.go
index 36c22b4..5ea62d8 100644
--- a/pkg/build/types/image_configuration_test.go
+++ b/pkg/build/types/image_configuration_test.go
@@ -78,6 +78,9 @@ func TestMergeInto(t *testing.T) {
 				"org.extra": "foo",
 				"org.blah":  "foo",
 			},
+			Volumes: []string{
+				"volume1",
+			},
 		},
 		target: types.ImageConfiguration{
 			Contents: types.ImageContents{
@@ -102,6 +105,9 @@ func TestMergeInto(t *testing.T) {
 				"org.extra": "foo",
 				"org.blah":  "foo",
 			},
+			Volumes: []string{
+				"volume1",
+			},
 		},
 	}, {
 		name: "simple blend of contents",
Repository: chainguard-dev/apko
Pull request #1470 (2025-01-08 23:00:29)

Base32-encode etag values
These values need to be safe as filenames for --offline to work consistently.


Patch:
diff --git a/pkg/apk/apk/cache.go b/pkg/apk/apk/cache.go
index 01b82e2..ecbe4f6 100644
--- a/pkg/apk/apk/cache.go
+++ b/pkg/apk/apk/cache.go
@@ -16,6 +16,7 @@ package apk
 
 import (
 	"context"
+	"encoding/base32"
 	"fmt"
 	"io"
 	"net/http"
@@ -331,6 +332,11 @@ func etagFromResponse(resp *http.Response) (string, bool) {
 	}
 	// When we get etags, they appear to be quoted.
 	etag := strings.Trim(remoteEtag[0], `"`)
+
+	// To ensure these things are safe filenames, base32 encode them.
+	// (Avoiding base64 due to case sensitive filesystems.)
+	etag = base32.StdEncoding.EncodeToString([]byte(etag))
+
 	return etag, etag != ""
 }
 


Test patch:
diff --git a/pkg/apk/apk/repo_test.go b/pkg/apk/apk/repo_test.go
index b8a57ab..90a0988 100644
--- a/pkg/apk/apk/repo_test.go
+++ b/pkg/apk/apk/repo_test.go
@@ -16,6 +16,7 @@ package apk
 
 import (
 	"context"
+	"encoding/base32"
 	"fmt"
 	"io/fs"
 	"net/http"
@@ -192,7 +193,7 @@ func TestGetRepositoryIndexes(t *testing.T) {
 		require.NoErrorf(t, err, "unable to get indexes")
 		require.Greater(t, len(indexes), 0, "no indexes found")
 		// check that the contents are the same
-		index1, err := os.ReadFile(filepath.Join(repoDir, "APKINDEX", "an-etag.tar.gz"))
+		index1, err := os.ReadFile(filepath.Join(repoDir, "APKINDEX", base32.StdEncoding.EncodeToString([]byte("an-etag"))+".tar.gz"))
 		require.NoError(t, err, "unable to read cache index file")
 		index2, err := os.ReadFile(filepath.Join(testPrimaryPkgDir, indexFilename))
 		require.NoError(t, err, "unable to read previous index file")
Repository: chainguard-dev/apko
Pull request #1598 (2025-04-01 13:26:08)

paths: prefer to use relative paths
Using relative paths, makes the cache relocatable, which helps when
bind-mounting / moving it about.



Patch:
diff --git a/pkg/paths/paths.go b/pkg/paths/paths.go
index 7083ffa..4394915 100644
--- a/pkg/paths/paths.go
+++ b/pkg/paths/paths.go
@@ -18,6 +18,7 @@ import (
 	"fmt"
 	"os"
 	"path"
+	"path/filepath"
 )
 
 func ResolvePath(p string, includePaths []string) (string, error) {
@@ -41,6 +42,11 @@ func ResolvePath(p string, includePaths []string) (string, error) {
 // and we can safely move on. We will also perform a best-effort attempt to clean up the
 // unadvertised file at `src`.
 func AdvertiseCachedFile(src, dst string) error {
+	// Prefer relative symlinks
+	rel, err := filepath.Rel(filepath.Dir(dst), src)
+	if err != nil {
+		rel = src
+	}
 	// Check if the destination already exists.
 	if _, err := os.Stat(dst); err == nil {
 		// Since `src` is unadvertised, it is safe to remove it. Ideally we want this to succeeds,
@@ -50,14 +56,14 @@ func AdvertiseCachedFile(src, dst string) error {
 		return nil
 	}
 	// Create the symlink.
-	if err := os.Symlink(src, dst); err != nil {
+	if err := os.Symlink(rel, dst); err != nil {
 		// Ignore already exists errors. We don't even want to do clean up here even when
 		// the symlink is pointing somewhere elese, to avoid relying too much on file system
 		// remantics/eventual consistency, etc.
 		if errors.Is(err, os.ErrExist) {
 			return nil
 		}
-		return fmt.Errorf("linking (cached) %s to %s: %w", src, dst, err)
+		return fmt.Errorf("linking (cached) %s to %s: %w", rel, dst, err)
 	}
 	return nil
 }


Test patch:
diff --git a/pkg/paths/paths_test.go b/pkg/paths/paths_test.go
index cf64d23..c0ddd4f 100644
--- a/pkg/paths/paths_test.go
+++ b/pkg/paths/paths_test.go
@@ -15,6 +15,7 @@ package paths
 
 import (
 	"os"
+	"path/filepath"
 	"testing"
 )
 
@@ -48,9 +49,13 @@ func TestAdvertiseCachedFile(t *testing.T) {
 			t.Fatal(err)
 		}
 		// check the symlink
+		rel1, err := filepath.Rel(filepath.Dir(dst), src1)
+		if err != nil {
+			t.Fatal(err)
+		}
 		if l, err := os.Readlink(dst); err != nil {
 			t.Fatal(err)
-		} else if l != src1 {
+		} else if l != rel1 {
 			t.Fatalf("symlink should stay in tact: %s != %s", l, src2)
 		}
Repository: chainguard-dev/apko
Pull request #1668 (2025-05-08 20:06:46)

Guard against empty inputs list in unify()
This can panic if called incorrectly, return an empty list instead.


Patch:
diff --git a/pkg/build/lock.go b/pkg/build/lock.go
index 1754d38..29ed637 100644
--- a/pkg/build/lock.go
+++ b/pkg/build/lock.go
@@ -146,7 +146,7 @@ type resolved struct {
 
 // unify returns (locked packages (per arch), missing packages (per arch), error)
 func unify(originals []string, inputs []resolved) (map[string][]string, map[string][]string, error) {
-	if len(originals) == 0 {
+	if len(originals) == 0 || len(inputs) == 0 {
 		// If there are no original packages, then we can't really do anything.
 		// This used to return nil but multi-arch unification assumes we always
 		// have an "index" entry, even if it's empty, so we return this now.


Test patch:
diff --git a/pkg/build/lock_test.go b/pkg/build/lock_test.go
index 8aa6a20..376da65 100644
--- a/pkg/build/lock_test.go
+++ b/pkg/build/lock_test.go
@@ -33,6 +33,10 @@ func TestUnify(t *testing.T) {
 	}{{
 		name: "empty",
 		want: map[string][]string{"index": {}},
+	}, {
+		name:      "no inputs",
+		originals: []string{"foo", "bar", "baz"},
+		want:      map[string][]string{"index": {}},
 	}, {
 		name:      "simple single arch",
 		originals: []string{"foo", "bar", "baz"},