Skip to content

Commit 9c14265

Browse files
committed
refactor: introduce a struct for git repository URL encapsulation
This will make it easier to extend the functionality to be able to use subdirectories for charts Signed-off-by: Dominykas Blyžė <[email protected]>
1 parent f180a95 commit 9c14265

File tree

7 files changed

+61
-27
lines changed

7 files changed

+61
-27
lines changed

internal/gitutil/gitutil.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,24 @@ limitations under the License.
1717
package gitutil
1818

1919
import (
20+
"net/url"
2021
"os"
2122
"regexp"
2223
"strings"
2324

25+
"github.com/pkg/errors"
26+
giturls "github.com/whilp/git-urls"
27+
2428
"github.com/Masterminds/vcs"
2529
)
2630

2731
var gitRepositoryURLRe = regexp.MustCompile(`^git(\+\w+)?://`)
2832

33+
type GitRepositoryURL struct {
34+
RepositoryURL string
35+
GitRemoteURL *url.URL
36+
}
37+
2938
// HasGitReference returns true if a git repository contains a specified ref (branch/tag)
3039
func HasGitReference(gitRepo, ref string) (bool, error) {
3140
local, err := os.MkdirTemp("", "helm-git-")
@@ -50,7 +59,20 @@ func IsGitRepository(url string) bool {
5059
return gitRepositoryURLRe.MatchString(url)
5160
}
5261

53-
// RepositoryURLToGitURL converts a repository URL into a URL that `git clone` could consume
54-
func RepositoryURLToGitURL(url string) string {
55-
return strings.TrimPrefix(url, "git+")
62+
// ParseGitRepositoryURL creates a new GitRepositoryURL from a string
63+
func ParseGitRepositoryURL(repositoryURL string) (GitRepositoryURL, error) {
64+
gitRemoteURL, err := giturls.Parse(strings.TrimPrefix(repositoryURL, "git+"))
65+
66+
if err != nil {
67+
return GitRepositoryURL{}, err
68+
}
69+
70+
if gitRemoteURL.User != nil {
71+
return GitRepositoryURL{}, errors.Errorf("git repository URL should not contain credentials - please use git credential helpers")
72+
}
73+
74+
return GitRepositoryURL{
75+
RepositoryURL: repositoryURL,
76+
GitRemoteURL: gitRemoteURL,
77+
}, err
5678
}

internal/gitutil/gitutil_test.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,32 @@ func TestIsGitUrl(t *testing.T) {
3838
}
3939
}
4040

41-
func TestRepositoryURLToGitURL(t *testing.T) {
42-
// Test table: Given url, RepositoryURLToGitURL should return expect.
41+
func TestParseGitRepositoryURL(t *testing.T) {
42+
// Test table: Given url, ParseGitRepositoryURL should return expect.
4343
tests := []struct {
44-
url string
45-
expect string
44+
url string
45+
expectRepositoryURL string
46+
expectGitRepositoryURL string
4647
}{
47-
{"git://example.com/example/chart", "git://example.com/example/chart"},
48-
{"git+https://example.com/example/chart", "https://example.com/example/chart"},
48+
{
49+
url: "git://example.com/example/chart",
50+
expectRepositoryURL: "git://example.com/example/chart",
51+
expectGitRepositoryURL: "git://example.com/example/chart",
52+
},
53+
{
54+
url: "git+https://example.com/example/chart",
55+
expectRepositoryURL: "git+https://example.com/example/chart",
56+
expectGitRepositoryURL: "https://example.com/example/chart",
57+
},
4958
}
5059

5160
for _, test := range tests {
52-
if RepositoryURLToGitURL(test.url) != test.expect {
53-
t.Errorf("Expected %s for %s", test.expect, test.url)
61+
parsed, _ := ParseGitRepositoryURL(test.url)
62+
if parsed.RepositoryURL != test.expectRepositoryURL {
63+
t.Errorf("Expected RepositoryURL %s for %s, but got %s", test.expectRepositoryURL, test.url, parsed)
64+
}
65+
if parsed.GitRemoteURL.String() != test.expectGitRepositoryURL {
66+
t.Errorf("Expected GitRemoteURL %s for %s, but got %s", test.expectGitRepositoryURL, test.url, parsed)
5467
}
5568
}
5669
}

internal/resolver/resolver.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,12 @@ func (r *Resolver) Resolve(reqs []*chart.Dependency, repoNames map[string]string
117117

118118
if gitutil.IsGitRepository(d.Repository) {
119119

120-
found, err := hasGitReference(gitutil.RepositoryURLToGitURL(d.Repository), d.Version)
120+
gitURL, err := gitutil.ParseGitRepositoryURL(d.Repository)
121+
if err != nil {
122+
return nil, err
123+
}
121124

125+
found, err := hasGitReference(gitURL.GitRemoteURL.String(), d.Version)
122126
if err != nil {
123127
return nil, err
124128
}

pkg/downloader/chart_downloader.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ import (
2626
"github.com/Masterminds/semver/v3"
2727
"github.com/pkg/errors"
2828

29-
giturls "github.com/whilp/git-urls"
30-
3129
"helm.sh/helm/v3/internal/fileutil"
3230
"helm.sh/helm/v3/internal/gitutil"
3331
"helm.sh/helm/v3/internal/urlutil"
@@ -210,14 +208,11 @@ func (c *ChartDownloader) ResolveChartVersion(ref, version string) (*url.URL, er
210208
}
211209

212210
if gitutil.IsGitRepository(ref) {
213-
gitURL, gitURLErr := giturls.Parse(gitutil.RepositoryURLToGitURL(ref))
214-
if gitURLErr != nil {
215-
return nil, errors.Errorf("invalid git URL format: %s", ref)
216-
}
217-
if gitURL.User != nil {
218-
return nil, errors.Errorf("git repository URL should not contain credentials - please use git credential helpers")
211+
_, err := gitutil.ParseGitRepositoryURL(ref)
212+
if err != nil {
213+
return nil, errors.Wrapf(err, "invalid git URL format: %s", ref)
219214
}
220-
return u, nil
215+
return u, err
221216
}
222217

223218
rf, err := loadRepoConfig(c.RepositoryConfig)

pkg/downloader/chart_downloader_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestResolveChartRef(t *testing.T) {
4343
{name: "full URL, with authentication", ref: "http://username:[email protected]/foo-1.2.3.tgz", expect: "http://username:[email protected]/foo-1.2.3.tgz"},
4444
{name: "helmchart", ref: "git+https://github.com/helmchart/helmchart.git", expect: "git+https://github.com/helmchart/helmchart.git"},
4545
{name: "helmchart", ref: "git://github.com/helmchart/helmchart.git", expect: "git://github.com/helmchart/helmchart.git"},
46-
{name: "helmchart", ref: "git+https://username:[email protected]/helmchart/helmchart.git", expectError: "git repository URL should not contain credentials - please use git credential helpers"},
46+
{name: "helmchart", ref: "git+https://username:[email protected]/helmchart/helmchart.git", expectError: "invalid git URL format: git+https://username:[email protected]/helmchart/helmchart.git: git repository URL should not contain credentials - please use git credential helpers"},
4747
{name: "reference, testing repo", ref: "testing/alpine", expect: "http://example.com/alpine-1.2.3.tgz"},
4848
{name: "reference, version, testing repo", ref: "testing/alpine", version: "0.2.0", expect: "http://example.com/alpine-0.2.0.tgz"},
4949
{name: "reference, version, malformed repo", ref: "malformed/alpine", version: "1.2.3", expect: "http://dl.example.com/alpine-1.2.3.tgz"},

pkg/downloader/manager.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,6 @@ func (m *Manager) resolveRepoNames(deps []*chart.Dependency) (map[string]string,
610610
// if the repo does not exist then it will later error when we try to fetch branches and tags.
611611
// we could check for the repo existence here, but trying to avoid another git request.
612612
if gitutil.IsGitRepository(dd.Repository) {
613-
if m.Debug {
614-
fmt.Fprintf(m.Out, "Repository from git url: %s\n", strings.TrimPrefix(dd.Repository, "git:"))
615-
}
616613
reposMap[dd.Name] = dd.Repository
617614
continue
618615
}

pkg/getter/gitgetter.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ func (g *GitGetter) Get(href string, options ...Option) (*bytes.Buffer, error) {
4747
}
4848

4949
func (g *GitGetter) get(href string) (*bytes.Buffer, error) {
50-
gitURL := gitutil.RepositoryURLToGitURL(href)
50+
gitURL, err := gitutil.ParseGitRepositoryURL(href)
51+
if err != nil {
52+
return nil, err
53+
}
5154
version := g.opts.version
5255
chartName := g.opts.chartName
5356
if version == "" {
@@ -64,7 +67,7 @@ func (g *GitGetter) get(href string) (*bytes.Buffer, error) {
6467
}
6568
defer os.RemoveAll(tmpDir)
6669

67-
repo, err := vcs.NewRepo(gitURL, chartTmpDir)
70+
repo, err := vcs.NewRepo(gitURL.GitRemoteURL.String(), chartTmpDir)
6871
if err != nil {
6972
return nil, err
7073
}

0 commit comments

Comments
 (0)