feat(repo): add LoadIndexFileForEntries to filter index on load

Fixes #32159

- Refactor LoadIndexFile to delegate to LoadIndexFileForEntries(path, nil)
- Accept []string instead of map[string]struct{} for idiomatic public API
- Remove extra blank line before doc comment
- Add unit tests covering nil names, single match, no match, partial match

Co-authored-by: rajarshipal-lab <rajarshipal-lab@users.noreply.github.com>
Co-authored-by: Cloud-Architect-Emma <Cloud-Architect-Emma@users.noreply.github.com>
Signed-off-by: Cloud-Architect-Emma <your@email.com>
Cloud-Architect-Emma 2 months ago
parent 38a2a83ea6
commit cb1f76395c

@ -104,6 +104,21 @@ func NewIndexFile() *IndexFile {
// LoadIndexFile takes a file at the given path and returns an IndexFile object
func LoadIndexFile(path string) (*IndexFile, error) {
return LoadIndexFileForEntries(path, nil)
}
// LoadIndexFileForEntries loads an index file but only validates and retains
// entries matching the provided chart names. Unmatched entries are discarded
// after unmarshal without validation, reducing memory and CPU overhead.
// If names is nil, all entries are loaded (equivalent to LoadIndexFile).
func LoadIndexFileForEntries(path string, names []string) (*IndexFile, error) {
var entries map[string]struct{}
if names != nil {
entries = make(map[string]struct{}, len(names))
for _, n := range names {
entries[n] = struct{}{}
}
}
b, err := os.ReadFile(path)
if err != nil {
return nil, err
@ -112,6 +127,14 @@ func LoadIndexFile(path string) (*IndexFile, error) {
if err != nil {
return nil, fmt.Errorf("error loading %s: %w", path, err)
}
if entries != nil {
for name := range i.Entries {
if _, ok := entries[name]; !ok {
delete(i.Entries, name)
}
}
}
i.SortEntries()
return i, nil
}

@ -718,3 +718,59 @@ func TestLoadIndex_DuplicateChartDeps(t *testing.T) {
})
}
}
func TestLoadIndexFileForEntries(t *testing.T) {
// nil names loads all entries
t.Run("nil names loads all", func(t *testing.T) {
i, err := LoadIndexFileForEntries("testdata/local-index.yaml", nil)
if err != nil {
t.Fatal(err)
}
if len(i.Entries) == 0 {
t.Fatal("expected entries, got none")
}
})
// filter to a specific chart
t.Run("filter to one entry", func(t *testing.T) {
i, err := LoadIndexFileForEntries("testdata/local-index.yaml", []string{"alpine"})
if err != nil {
t.Fatal(err)
}
if len(i.Entries) != 1 {
t.Fatalf("expected 1 entry, got %d", len(i.Entries))
}
if _, ok := i.Entries["alpine"]; !ok {
t.Fatal("expected 'alpine' entry")
}
})
// no matches returns empty entries
t.Run("no matches returns empty", func(t *testing.T) {
i, err := LoadIndexFileForEntries("testdata/local-index.yaml", []string{"nonexistent-chart"})
if err != nil {
t.Fatal(err)
}
if len(i.Entries) != 0 {
t.Fatalf("expected 0 entries, got %d", len(i.Entries))
}
})
// partial match retains only matched entries
t.Run("partial match", func(t *testing.T) {
full, _ := LoadIndexFile("testdata/local-index.yaml")
var firstName string
for k := range full.Entries {
firstName = k
break
}
i, err := LoadIndexFileForEntries("testdata/local-index.yaml", []string{firstName, "nonexistent-chart"})
if err != nil {
t.Fatal(err)
}
if len(i.Entries) != 1 {
t.Fatalf("expected 1 entry, got %d", len(i.Entries))
}
})
}
Loading…
Cancel
Save