diff --git a/cmd/helm/repo_add.go b/cmd/helm/repo_add.go index fd31e0d334efbf454795c3036809ab1e2bc1793d..414e962fa99325415523b9c3cd91aa44cd51f516 100644 --- a/cmd/helm/repo_add.go +++ b/cmd/helm/repo_add.go @@ -28,10 +28,11 @@ import ( ) type repoAddCmd struct { - name string - url string - home helmpath.Home - out io.Writer + name string + url string + home helmpath.Home + out io.Writer + noupdate bool } func newRepoAddCmd(out io.Writer) *cobra.Command { @@ -54,11 +55,19 @@ func newRepoAddCmd(out io.Writer) *cobra.Command { return add.run() }, } + f := cmd.Flags() + f.BoolVar(&add.noupdate, "no-update", false, "raise error if repo is already registered") return cmd } func (a *repoAddCmd) run() error { - if err := addRepository(a.name, a.url, a.home); err != nil { + var err error + if a.noupdate { + err = addRepository(a.name, a.url, a.home) + } else { + err = updateRepository(a.name, a.url, a.home) + } + if err != nil { return err } fmt.Fprintf(a.out, "%q has been added to your repositories\n", a.name) @@ -91,3 +100,28 @@ func insertRepoLine(name, url string, home helmpath.Home) error { }) return f.WriteFile(home.RepositoryFile(), 0644) } + +func updateRepository(name, url string, home helmpath.Home) error { + cif := home.CacheIndex(name) + if err := repo.DownloadIndexFile(name, url, cif); err != nil { + return err + } + + return updateRepoLine(name, url, home) +} + +func updateRepoLine(name, url string, home helmpath.Home) error { + cif := home.CacheIndex(name) + f, err := repo.LoadRepositoriesFile(home.RepositoryFile()) + if err != nil { + return err + } + + f.Update(&repo.Entry{ + Name: name, + URL: url, + Cache: filepath.Base(cif), + }) + + return f.WriteFile(home.RepositoryFile(), 0666) +} diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go index 055ee0bfd40a6d0cc859affe9e32371d4127a376..c9c2554331d79ce3a7596e4fffdb515047498908 100644 --- a/cmd/helm/repo_add_test.go +++ b/cmd/helm/repo_add_test.go @@ -92,4 +92,12 @@ func TestRepoAdd(t *testing.T) { if !f.Has(testName) { t.Errorf("%s was not successfully inserted into %s", testName, hh.RepositoryFile()) } + + if err := updateRepository(testName, ts.URL(), hh); err != nil { + t.Errorf("Repository was not updated: %s", err) + } + + if err := addRepository(testName, ts.URL(), hh); err == nil { + t.Errorf("Duplicate repository name was added") + } } diff --git a/pkg/repo/repo.go b/pkg/repo/repo.go index e1d9d4712457b0f5e969a6d3539da987a67bb9b6..d453f09da9a82e2629fb71e70cbcfb3b3853d27e 100644 --- a/pkg/repo/repo.go +++ b/pkg/repo/repo.go @@ -109,6 +109,20 @@ func (r *RepoFile) Add(re ...*Entry) { r.Repositories = append(r.Repositories, re...) } +// Update attempts to replace one or more repo entries in a repo file. If an +// entry with the same name doesn't exist in the repo file it will add it. +func (r *RepoFile) Update(re ...*Entry) { + for _, target := range re { + for j, repo := range r.Repositories { + if repo.Name == target.Name { + r.Repositories[j] = target + break + } + } + r.Add(target) + } +} + // Has returns true if the given name is already a repository name. func (r *RepoFile) Has(name string) bool { for _, rf := range r.Repositories {