From 33fbcda4cc82aa5b1c22b52dfdae7a4e9adc71c4 Mon Sep 17 00:00:00 2001 From: Gergo Huszty Date: Thu, 20 Apr 2017 07:02:48 +0000 Subject: [PATCH] Recursive dependency build added Loop prevention added with wired threshold. Docs updated. --- cmd/helm/dependency_build.go | 7 +++- docs/helm/helm_dependency_build.md | 1 + docs/man/man1/helm_dependency_build.1 | 4 +++ pkg/downloader/manager.go | 51 +++++++++++++++++++++------ scripts/completions.bash | 2 ++ 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/cmd/helm/dependency_build.go b/cmd/helm/dependency_build.go index 3a92edd07..9dd548db3 100644 --- a/cmd/helm/dependency_build.go +++ b/cmd/helm/dependency_build.go @@ -42,6 +42,7 @@ type dependencyBuildCmd struct { verify bool keyring string helmhome helmpath.Home + recursive bool } func newDependencyBuildCmd(out io.Writer) *cobra.Command { @@ -67,6 +68,7 @@ func newDependencyBuildCmd(out io.Writer) *cobra.Command { f := cmd.Flags() f.BoolVar(&dbc.verify, "verify", false, "verify the packages against signatures") f.StringVar(&dbc.keyring, "keyring", defaultKeyring(), "keyring containing public keys") + f.BoolVar(&dbc.recursive, "recursive", false, "recursive mode") return cmd } @@ -78,10 +80,13 @@ func (d *dependencyBuildCmd) run() error { HelmHome: d.helmhome, Keyring: d.keyring, Getters: defaultgetters.Get(settings), + Recursive: d.recursive, + Debug: settings.FlagDebug, } if d.verify { man.Verify = downloader.VerifyIfPossible } - return man.Build() + _, err := man.Build() + return err } diff --git a/docs/helm/helm_dependency_build.md b/docs/helm/helm_dependency_build.md index 4cd149444..99bbd9110 100644 --- a/docs/helm/helm_dependency_build.md +++ b/docs/helm/helm_dependency_build.md @@ -24,6 +24,7 @@ helm dependency build [flags] CHART ``` --keyring string keyring containing public keys (default "~/.gnupg/pubring.gpg") + --recursive recursive mode --verify verify the packages against signatures ``` diff --git a/docs/man/man1/helm_dependency_build.1 b/docs/man/man1/helm_dependency_build.1 index a42f44a58..6d5fa762e 100644 --- a/docs/man/man1/helm_dependency_build.1 +++ b/docs/man/man1/helm_dependency_build.1 @@ -32,6 +32,10 @@ of 'helm dependency update'. \fB\-\-keyring\fP="~/.gnupg/pubring.gpg" keyring containing public keys +.PP +\fB\-\-recursive\fP[=false] + recursive mode + .PP \fB\-\-verify\fP[=false] verify the packages against signatures diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index 4f881591a..76eb7d5cc 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -57,6 +57,8 @@ type Manager struct { SkipUpdate bool // Getter collection for the operation Getters []getter.Prop + // Recursive mode collects the dependencies to the lowest level + Recursive bool } // Build rebuilds a local charts directory from a lockfile. @@ -64,46 +66,66 @@ type Manager struct { // If the lockfile is not present, this will run a Manager.Update() // // If SkipUpdate is set, this will not update the repository. -func (m *Manager) Build() error { +func (m *Manager) Build() (int, error) { c, err := m.loadChartDir() if err != nil { - return err + return 0, err } // If a lock file is found, run a build from that. Otherwise, just do // an update. lock, err := chartutil.LoadRequirementsLock(c) if err != nil { - return m.Update() + return 0, m.Update() } // A lock must accompany a requirements.yaml file. - req, err := chartutil.LoadRequirements(c) + reqs, err := chartutil.LoadRequirements(c) if err != nil { - return fmt.Errorf("requirements.yaml cannot be opened: %s", err) + return 0, fmt.Errorf("requirements.yaml cannot be opened: %s", err) } - if sum, err := resolver.HashReq(req); err != nil || sum != lock.Digest { - return fmt.Errorf("requirements.lock is out of sync with requirements.yaml") + if sum, err := resolver.HashReq(reqs); err != nil || sum != lock.Digest { + return 0, fmt.Errorf("requirements.lock is out of sync with requirements.yaml") } // Check that all of the repos we're dependent on actually exist. if err := m.hasAllRepos(lock.Dependencies); err != nil { - return err + return 0, err } if !m.SkipUpdate { // For each repo in the file, update the cached copy of that repo if err := m.UpdateRepositories(); err != nil { - return err + return 0, err } } // Now we need to fetch every package here into charts/ if err := m.downloadAll(lock.Dependencies); err != nil { - return err + return 0, err } - return nil + myDeps := len(reqs.Dependencies) + if m.Recursive { + depM := *m + for _, dep := range reqs.Dependencies { + depM.ChartPath = filepath.Join(m.ChartPath, "charts", dep.Name) + depM.SkipUpdate = true + fmt.Fprintln(m.Out, "Getting requirements recursively for:", depM.ChartPath) + depOfDeps, err := depM.Build() + if err != nil { + return 0, err + } + myDeps += depOfDeps + if myDeps > 100 { + return 0, fmt.Errorf("Loop prevention kicked in.") + } + } + } + if m.Debug { + fmt.Fprintln(m.Out, "Done with", m.ChartPath, ", deps:", myDeps) + } + return myDeps, nil } // Update updates a local charts directory. @@ -246,6 +268,13 @@ func (m *Manager) downloadAll(deps []*chartutil.Dependency) error { if _, _, err := dl.DownloadTo(churl, "", destPath); err != nil { return fmt.Errorf("could not download %s: %s", churl, err) } + if m.Recursive == true { + tarPath := filepath.Join(destPath, filepath.Base(churl)) + fmt.Fprintln(m.Out, "Unpacking:", tarPath) + if err = chartutil.ExpandFile(destPath, tarPath); err != nil { + return fmt.Errorf("Error while unpacking: %s", err) + } + } } return nil } diff --git a/scripts/completions.bash b/scripts/completions.bash index f928ae502..4459aaf1b 100644 --- a/scripts/completions.bash +++ b/scripts/completions.bash @@ -323,6 +323,8 @@ _helm_dependency_build() flags+=("--keyring=") local_nonpersistent_flags+=("--keyring=") + flags+=("--recursive") + local_nonpersistent_flags+=("--recursive") flags+=("--verify") local_nonpersistent_flags+=("--verify") flags+=("--debug")