feat(marketplace): index root directories
Some checks failed
Security Scan / security (push) Failing after 12s
Test / test (push) Successful in 2m14s

Include the directories passed to BuildFromDirs before scanning children so scm index . handles a manifest at the root of the scanned directory.

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 06:59:57 +00:00
parent 2e188e346a
commit ec8149efbe
2 changed files with 46 additions and 21 deletions

View file

@ -31,15 +31,19 @@ type Builder struct {
Org string
}
// BuildFromDirs scans each directory for subdirectories containing either
// core.json (preferred) or .core/manifest.yaml. Each valid manifest is
// added to the resulting Index as a Module.
// BuildFromDirs scans each directory, then its immediate subdirectories, for
// core.json (preferred) or .core/manifest.yaml. Each valid manifest is added
// to the resulting Index as a Module.
// Usage: BuildFromDirs(...)
func (b *Builder) BuildFromDirs(dirs ...string) (*Index, error) {
var modules []Module
seen := make(map[string]bool)
for _, dir := range dirs {
if err := b.loadInto(&modules, seen, dir); err != nil {
core.Warn(core.Sprintf("marketplace: skipping %s: %v", filepath.Base(dir), err))
}
entries, err := os.ReadDir(dir)
if err != nil {
if os.IsNotExist(err) {
@ -53,26 +57,10 @@ func (b *Builder) BuildFromDirs(dirs ...string) (*Index, error) {
continue
}
m, err := b.loadFromDir(filepath.Join(dir, e.Name()))
if err != nil {
child := filepath.Join(dir, e.Name())
if err := b.loadInto(&modules, seen, child); err != nil {
core.Warn(core.Sprintf("marketplace: skipping %s: %v", e.Name(), err))
continue
}
if m == nil {
continue
}
if seen[m.Code] {
continue
}
seen[m.Code] = true
mod := Module{
Code: m.Code,
Name: m.Name,
Repo: b.repoURL(m.Code),
SignKey: m.Sign,
}
modules = append(modules, mod)
}
}
@ -86,6 +74,29 @@ func (b *Builder) BuildFromDirs(dirs ...string) (*Index, error) {
}, nil
}
func (b *Builder) loadInto(modules *[]Module, seen map[string]bool, dir string) error {
m, err := b.loadFromDir(dir)
if err != nil {
return err
}
if m == nil {
return nil
}
if seen[m.Code] {
return nil
}
seen[m.Code] = true
mod := Module{
Code: m.Code,
Name: m.Name,
Repo: b.repoURL(m.Code),
SignKey: m.Sign,
}
*modules = append(*modules, mod)
return nil
}
// BuildFromManifests constructs an Index from pre-loaded manifests.
// This is useful when manifests have already been collected (e.g. from
// a Forge API crawl).

View file

@ -65,6 +65,20 @@ func TestBuildFromDirs_Good_ManifestYAML_Good(t *testing.T) {
assert.Equal(t, IndexVersion, idx.Version)
}
func TestBuildFromDirs_Good_IndexesRootDirectory_Good(t *testing.T) {
root := t.TempDir()
writeManifestYAML(t, root, "root-mod", "Root Module", "1.0.0")
b := &Builder{BaseURL: "https://forge.lthn.ai", Org: "core"}
idx, err := b.BuildFromDirs(root)
require.NoError(t, err)
require.Len(t, idx.Modules, 1)
assert.Equal(t, "root-mod", idx.Modules[0].Code)
assert.Equal(t, "Root Module", idx.Modules[0].Name)
assert.Equal(t, "https://forge.lthn.ai/core/root-mod.git", idx.Modules[0].Repo)
}
func TestBuildFromDirs_Good_CarriesSignKey_Good(t *testing.T) {
root := t.TempDir()
modDir := filepath.Join(root, "signed-mod")