diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index fd3ce694f..27474f583 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -27,6 +27,7 @@ import ( "os" "path/filepath" "regexp" + "slices" "strings" "sync" @@ -275,6 +276,7 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error { fmt.Fprintf(m.Out, "Saving %d charts\n", len(deps)) var saveError error churls := make(map[string]struct{}) + skippedCharts := make([]string, 0) for _, dep := range deps { // No repository means the chart is in charts directory if dep.Repository == "" { @@ -373,6 +375,8 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error { name := dl.getChartName(u.String()) if _, err = os.Stat(filepath.Join(destPath, name)); err == nil { fmt.Fprintf(m.Out, "Already exists locally %s from repo %s\n", dep.Name, dep.Repository) + + skippedCharts = append(skippedCharts, name) continue } } @@ -389,7 +393,7 @@ func (m *Manager) downloadAll(deps []*chart.Dependency) error { // TODO: this should probably be refactored to be a []error, so we can capture and provide more information rather than "last error wins". if saveError == nil { // now we can move all downloaded charts to destPath and delete outdated dependencies - if err := m.safeMoveDeps(deps, tmpPath, destPath); err != nil { + if err := m.safeMoveDeps(deps, tmpPath, destPath, skippedCharts); err != nil { return err } } else { @@ -416,13 +420,14 @@ func parseOCIRef(chartRef string) (string, string, error) { // It does this by first matching the file name to an expected pattern, then loading // the file to verify that it is a chart. // -// Any charts in dest that do not exist in source are removed (barring local dependencies) +// Any charts in dest that do not exist in source and not in skippedCharts are removed (barring local dependencies) +// skippedCharts is a list of charts that were skipped during the download process. // // Because it requires tar file introspection, it is more intensive than a basic move. // // This will only return errors that should stop processing entirely. Other errors // will emit log messages or be ignored. -func (m *Manager) safeMoveDeps(deps []*chart.Dependency, source, dest string) error { +func (m *Manager) safeMoveDeps(deps []*chart.Dependency, source, dest string, skippedCharts []string) error { existsInSourceDirectory := map[string]bool{} isLocalDependency := map[string]bool{} sourceFiles, err := os.ReadDir(source) @@ -463,7 +468,7 @@ func (m *Manager) safeMoveDeps(deps []*chart.Dependency, source, dest string) er fmt.Fprintln(m.Out, "Deleting outdated charts") // find all files that exist in dest that do not exist in source; delete them (outdated dependencies) for _, file := range destFiles { - if !file.IsDir() && !existsInSourceDirectory[file.Name()] { + if !file.IsDir() && !existsInSourceDirectory[file.Name()] && !slices.Contains(skippedCharts, file.Name()) { fname := filepath.Join(dest, file.Name()) ch, err := loader.LoadFile(fname) if err != nil {