Skip to content

Commit

Permalink
ingest config files with ResourceLoader
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Humphreys <[email protected]>
  • Loading branch information
Mjaethers authored and glours committed Oct 17, 2024
1 parent 35c9659 commit 8948716
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 28 deletions.
57 changes: 29 additions & 28 deletions cli/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,22 +403,24 @@ func (o *ProjectOptions) GetWorkingDir() (string, error) {
return os.Getwd()
}

func (o *ProjectOptions) GetConfigFiles() ([]types.ConfigFile, error) {
configPaths, err := o.getConfigPaths()
// ReadConfigFiles reads ConfigFiles and populates the content field
func (o ProjectOptions) ReadConfigFiles(ctx context.Context, options *ProjectOptions) (*types.ConfigDetails, error) {
config, err := loader.LoadConfigFiles(ctx, options.ConfigPaths, options.loadOptions...)
if err != nil {
return nil, err
}
configs := make([][]byte, len(config.ConfigFiles))

var configs []types.ConfigFile
for _, f := range configPaths {
for i, c := range config.ConfigFiles {
var err error
var b []byte
if f == "-" {
if c.Filename == "-" {
b, err = io.ReadAll(os.Stdin)
if err != nil {
return nil, err
}
} else {
f, err := filepath.Abs(f)
f, err := filepath.Abs(c.Filename)
if err != nil {
return nil, err
}
Expand All @@ -427,27 +429,31 @@ func (o *ProjectOptions) GetConfigFiles() ([]types.ConfigFile, error) {
return nil, err
}
}
configs = append(configs, types.ConfigFile{
Filename: f,
Content: b,
})
configs[i] = b
}
return configs, err
for i, c := range configs {
config.ConfigFiles[i].Content = c
}
return config, nil
}

// LoadProject loads compose file according to options and bind to types.Project go structs
func (o *ProjectOptions) LoadProject(ctx context.Context) (*types.Project, error) {
configDetails, err := o.prepare()
config, err := o.prepare(ctx)
if err != nil {
return nil, err
}

project, err := loader.LoadWithContext(ctx, configDetails, o.loadOptions...)
project, err := loader.LoadWithContext(ctx, types.ConfigDetails{
ConfigFiles: config.ConfigFiles,
WorkingDir: config.WorkingDir,
Environment: o.Environment,
}, o.loadOptions...)
if err != nil {
return nil, err
}

for _, config := range configDetails.ConfigFiles {
for _, config := range config.ConfigFiles {
project.ComposeFiles = append(project.ComposeFiles, config.Filename)
}

Expand All @@ -456,36 +462,31 @@ func (o *ProjectOptions) LoadProject(ctx context.Context) (*types.Project, error

// LoadModel loads compose file according to options and returns a raw (yaml tree) model
func (o *ProjectOptions) LoadModel(ctx context.Context) (map[string]any, error) {
configDetails, err := o.prepare()
configDetails, err := o.prepare(ctx)
if err != nil {
return nil, err
}

return loader.LoadModelWithContext(ctx, configDetails, o.loadOptions...)
return loader.LoadModelWithContext(ctx, *configDetails, o.loadOptions...)
}

// prepare converts ProjectOptions into loader's types.ConfigDetails and configures default load options
func (o *ProjectOptions) prepare() (types.ConfigDetails, error) {
configs, err := o.GetConfigFiles()
func (o *ProjectOptions) prepare(ctx context.Context) (*types.ConfigDetails, error) {
defaultDir, err := o.GetWorkingDir()
if err != nil {
return types.ConfigDetails{}, err
return &types.ConfigDetails{}, err
}

workingDir, err := o.GetWorkingDir()
configDetails, err := o.ReadConfigFiles(ctx, o)
if err != nil {
return types.ConfigDetails{}, err
}

configDetails := types.ConfigDetails{
ConfigFiles: configs,
WorkingDir: workingDir,
Environment: o.Environment,
return configDetails, err
}

o.loadOptions = append(o.loadOptions,
withNamePrecedenceLoad(workingDir, o),
withNamePrecedenceLoad(defaultDir, o),
withConvertWindowsPaths(o),
withListeners(o))

return configDetails, nil
}

Expand Down
42 changes: 42 additions & 0 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,48 @@ func parseYAML(decoder *yaml.Decoder) (map[string]interface{}, PostProcessor, er
return converted.(map[string]interface{}), &processor, nil
}

// LoadConfigFiles ingests config files with ResourceLoader and returns config details with paths to local copies
func LoadConfigFiles(ctx context.Context, configFiles []string, options ...func(*Options)) (*types.ConfigDetails, error) {
if len(configFiles) < 1 {
return &types.ConfigDetails{}, errors.New("no files specified")
}

opts := &Options{}
config := &types.ConfigDetails{
ConfigFiles: make([]types.ConfigFile, len(configFiles)),
}

for _, op := range options {
op(opts)
}
opts.ResourceLoaders = append(opts.ResourceLoaders, localResourceLoader{})

for i, p := range configFiles {
for _, loader := range opts.ResourceLoaders {
if !loader.Accept(p) {
continue
}
local, err := loader.Load(ctx, p)
if err != nil {
continue
}
if config.WorkingDir == "" {
config.WorkingDir = filepath.Dir(local)

}
abs, err := filepath.Abs(local)
if err != nil {
abs = local
}
config.ConfigFiles[i] = types.ConfigFile{
Filename: abs,
}
break
}
}
return config, nil
}

// Load reads a ConfigDetails and returns a fully loaded configuration.
// Deprecated: use LoadWithContext.
func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.Project, error) {
Expand Down

0 comments on commit 8948716

Please sign in to comment.