From e9cfefbf44117741718d9b62d62cfd0ec90a699f Mon Sep 17 00:00:00 2001 From: Benoit Tigeot Date: Fri, 29 Aug 2025 16:34:29 +0200 Subject: [PATCH] Output should be closer to the one for OCI registry Plus handling of p.Version if we are not able to extract the version... not sure is what we want.. Plus handling of tar.gz Plus a little refactoring Signed-off-by: Benoit Tigeot --- pkg/action/pull.go | 47 +++++++++++++++++++++++++++++++++++++---- pkg/action/pull_test.go | 10 ++++----- pkg/cmd/pull_test.go | 2 +- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/pkg/action/pull.go b/pkg/action/pull.go index dc1e33e3a..8619e50e4 100644 --- a/pkg/action/pull.go +++ b/pkg/action/pull.go @@ -19,6 +19,7 @@ package action import ( "crypto/sha256" "fmt" + "io" "os" "path/filepath" "strings" @@ -144,17 +145,25 @@ func (p *Pull) Run(chartRef string) (string, error) { // path does not go through the registry client's summary printer, so we emit // a consistent summary here. We mirror the OCI output format: // - // Pulled: : + // Pulled: : // Digest: sha256: // // For HTTP/repo pulls, the digest is the SHA-256 of the downloaded .tgz archive. // For direct OCI pulls, the registry client already prints "Pulled:" and // "Digest:" (manifest digest), so we do not print here to avoid duplicates. if p.RepoURL != "" || !registry.IsOCI(downloadSourceRef) { - fmt.Fprintf(&out, "Pulled: %s\n", downloadSourceRef) + base := trimAnySuffix(downloadSourceRef, ".tar.gz", ".tgz") + chart, ver := splitChartNameVersion(base) + + tag := chart + if ver != "" { + tag += ":" + ver + } else if p.Version != "" { + tag += ":" + p.Version + } + fmt.Fprintf(&out, "Pulled: %s\n", tag) - if f, err := os.ReadFile(saved); err == nil { - sum := sha256.Sum256(f) + if sum, err := sha256File(saved); err == nil { fmt.Fprintf(&out, "Digest: sha256:%x\n", sum) } } @@ -194,3 +203,33 @@ func (p *Pull) Run(chartRef string) (string, error) { } return out.String(), nil } + +func trimAnySuffix(s string, suffixes ...string) string { + for _, suf := range suffixes { + if strings.HasSuffix(s, suf) { + return strings.TrimSuffix(s, suf) + } + } + return s +} + +func splitChartNameVersion(s string) (name, version string) { + if i := strings.LastIndex(s, "-"); i > 0 { + return s[:i], s[i+1:] + } + return s, "" +} + +func sha256File(path string) ([]byte, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + + h := sha256.New() + if _, err := io.Copy(h, f); err != nil { + return nil, err + } + return h.Sum(nil), nil +} diff --git a/pkg/action/pull_test.go b/pkg/action/pull_test.go index 7d06ff9dd..5c6f488e9 100644 --- a/pkg/action/pull_test.go +++ b/pkg/action/pull_test.go @@ -77,7 +77,7 @@ entries: out, err := p.Run("testchart") require.NoError(t, err, "Pull.Run() should succeed. Output:\n%s", out) - expectedURL := srv.URL + "/testchart-1.2.3.tgz" + expectedURL := srv.URL + "/testchart:1.2.3" assert.Contains(t, out, "Pulled: "+expectedURL, "expected Pulled summary in output") assert.Contains(t, out, "Digest: "+wantDigest, "expected archive digest in output") @@ -95,7 +95,7 @@ func TestPull_PrintsSummary_ForDirectHTTPURL(t *testing.T) { wantDigest := fmt.Sprintf("sha256:%x", sum) mux := http.NewServeMux() - mux.HandleFunc("/directchart-9.9.9.tgz", func(w http.ResponseWriter, _ *http.Request) { + mux.HandleFunc("/directchart-9.9.9.tar.gz", func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/gzip") _, _ = w.Write(chartBytes) }) @@ -114,17 +114,17 @@ func TestPull_PrintsSummary_ForDirectHTTPURL(t *testing.T) { p.DestDir = t.TempDir() // Direct HTTP URL (absolute URL). Version is ignored for absolute URLs. - chartURL := srv.URL + "/directchart-9.9.9.tgz" + chartURL := srv.URL + "/directchart-9.9.9.tar.gz" out, err := p.Run(chartURL) require.NoError(t, err, "Pull.Run() should succeed. Output:\n%s", out) // Output should reflect name-version.tgz from the URL. - expectedURL := srv.URL + "/directchart-9.9.9.tgz" + expectedURL := srv.URL + "/directchart:9.9.9" assert.Contains(t, out, "Pulled: "+expectedURL, "expected Pulled summary in output") assert.Contains(t, out, "Digest: "+wantDigest, "expected archive digest in output") // Ensure the chart file was saved. - _, statErr := os.Stat(filepath.Join(p.DestDir, "directchart-9.9.9.tgz")) + _, statErr := os.Stat(filepath.Join(p.DestDir, "directchart-9.9.9.tar.gz")) require.NoError(t, statErr, "expected chart archive to be saved") } diff --git a/pkg/cmd/pull_test.go b/pkg/cmd/pull_test.go index 8a7a223cd..34bf2860b 100644 --- a/pkg/cmd/pull_test.go +++ b/pkg/cmd/pull_test.go @@ -44,7 +44,7 @@ func TestPullCmd(t *testing.T) { t.Fatal(err) } - helmTestKeyOut := "Pulled: signtest:0.1.0\n" + + helmTestKeyOut := "Pulled: test/signtest\n" + "Digest: sha256:e5ef611620fb97704d8751c16bab17fedb68883bfb0edc76f78a70e9173f9b55\n" + "Signed by: Helm Testing (This key should only be used for testing. DO NOT TRUST.) \n" + "Using Key With Fingerprint: 5E615389B53CA37F0EE60BD3843BBF981FC18762\n" +