Skip to content

Commit

Permalink
refactor: loader only loads project and root blueprints
Browse files Browse the repository at this point in the history
  • Loading branch information
jmgilman committed Sep 12, 2024
1 parent afbd1c8 commit 28a8c99
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 274 deletions.
8 changes: 1 addition & 7 deletions blueprint/pkg/blueprint/blueprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (b BlueprintFiles) Unify(ctx *cue.Context) (cue.Value, error) {
v = v.Unify(bp.Value)
}

if err := cuetools.Validate(v, cue.Concrete(true)); err != nil {
if err := cuetools.Validate(v); err != nil {
return cue.Value{}, err
}

Expand Down Expand Up @@ -93,12 +93,6 @@ func NewBlueprintFile(ctx *cue.Context, path string, contents []byte, inj inject
return BlueprintFile{}, fmt.Errorf("failed to delete version from blueprint file: %w", err)
}

v = inj.InjectEnv(v)

if err := cuetools.Validate(v, cue.Concrete(true)); err != nil {
return BlueprintFile{}, err
}

return BlueprintFile{
Path: path,
Value: v,
Expand Down
88 changes: 43 additions & 45 deletions blueprint/pkg/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"io"
"log/slog"
"os"
"path/filepath"

"cuelang.org/go/cue"
Expand All @@ -15,7 +16,7 @@ import (
"github.com/input-output-hk/catalyst-forge/blueprint/pkg/version"
"github.com/input-output-hk/catalyst-forge/blueprint/schema"
cuetools "github.com/input-output-hk/catalyst-forge/tools/pkg/cue"
"github.com/input-output-hk/catalyst-forge/tools/pkg/walker"
"github.com/spf13/afero"
)

//go:generate go run github.com/matryer/moq@latest --pkg mocks --out ./mocks/loader.go . BlueprintLoader
Expand All @@ -34,16 +35,40 @@ type BlueprintLoader interface {

// DefaultBlueprintLoader is the default implementation of the BlueprintLoader
type DefaultBlueprintLoader struct {
fs afero.Fs
injector injector.Injector
logger *slog.Logger
walker walker.ReverseWalker
}

func (b *DefaultBlueprintLoader) Load(projectPath, gitRootPath string) (blueprint.RawBlueprint, error) {
files, err := b.findBlueprints(projectPath, gitRootPath)
files := make(map[string][]byte)

pbPath := filepath.Join(projectPath, BlueprintFileName)
pb, err := afero.ReadFile(b.fs, pbPath)
if err != nil {
b.logger.Error("Failed to find blueprint files", "error", err)
return blueprint.RawBlueprint{}, fmt.Errorf("failed to find blueprint files: %w", err)
if os.IsNotExist(err) {
b.logger.Warn("No project blueprint file found", "path", pbPath)
} else {
b.logger.Error("Failed to read blueprint file", "path", pbPath, "error", err)
return blueprint.RawBlueprint{}, fmt.Errorf("failed to read blueprint file: %w", err)
}
} else {
files[pbPath] = pb
}

if projectPath != gitRootPath {
rootPath := filepath.Join(gitRootPath, BlueprintFileName)
rb, err := afero.ReadFile(b.fs, rootPath)
if err != nil {
if os.IsNotExist(err) {
b.logger.Warn("No root blueprint file found", "path", rootPath)
} else {
b.logger.Error("Failed to read blueprint file", "path", rootPath, "error", err)
return blueprint.RawBlueprint{}, fmt.Errorf("failed to read blueprint file: %w", err)
}
} else {
files[rootPath] = rb
}
}

ctx := cuecontext.New()
Expand Down Expand Up @@ -81,6 +106,7 @@ func (b *DefaultBlueprintLoader) Load(projectPath, gitRootPath string) (blueprin

finalVersion = bps.Version()
userBlueprint = userBlueprint.FillPath(cue.ParsePath("version"), finalVersion.String())
userBlueprint = b.injector.InjectEnv(userBlueprint)
finalBlueprint = schema.Unify(userBlueprint)
} else {
b.logger.Warn("No blueprint files found, using default values")
Expand All @@ -105,55 +131,27 @@ func (b *DefaultBlueprintLoader) Load(projectPath, gitRootPath string) (blueprin
return blueprint.NewRawBlueprint(finalBlueprint), nil
}

// findBlueprints searches for blueprint files starting from the startPath and
// ending at the endPath. It returns a map of blueprint file paths to their
// contents or an error if the search fails.
func (b *DefaultBlueprintLoader) findBlueprints(startPath, endPath string) (map[string][]byte, error) {
bps := make(map[string][]byte)

err := b.walker.Walk(
startPath,
endPath,
func(path string, fileType walker.FileType, openFile func() (walker.FileSeeker, error)) error {
if fileType == walker.FileTypeFile {
if filepath.Base(path) == BlueprintFileName {
reader, err := openFile()
if err != nil {
return err
}

defer reader.Close()

data, err := io.ReadAll(reader)
if err != nil {
return err
}

bps[path] = data
}
}

return nil
},
)

if err != nil {
return nil, err
// NewDefaultBlueprintLoader creates a new DefaultBlueprintLoader.
func NewDefaultBlueprintLoader(logger *slog.Logger) DefaultBlueprintLoader {
if logger == nil {
logger = slog.New(slog.NewTextHandler(io.Discard, nil))
}

return bps, nil
return DefaultBlueprintLoader{
fs: afero.NewOsFs(),
injector: injector.NewDefaultInjector(logger),
logger: logger,
}
}

// NewDefaultBlueprintLoader creates a new DefaultBlueprintLoader.
func NewDefaultBlueprintLoader(logger *slog.Logger) DefaultBlueprintLoader {
func NewCustomBlueprintLoader(fs afero.Fs, injector injector.Injector, logger *slog.Logger) DefaultBlueprintLoader {
if logger == nil {
logger = slog.New(slog.NewTextHandler(io.Discard, nil))
}

walker := walker.NewDefaultFSReverseWalker(logger)
return DefaultBlueprintLoader{
injector: injector.NewDefaultInjector(logger),
fs: fs,
injector: injector,
logger: logger,
walker: &walker,
}
}
Loading

0 comments on commit 28a8c99

Please sign in to comment.