Files
ConfigKit/internal/engine/source_context.go

80 lines
2.1 KiB
Go

package engine
import (
"io/fs"
"path"
"path/filepath"
"strings"
)
func contextsForResolvedSources(resolved *resolvedFilesystemContext, sources []SourceInfo) (map[string]ResourceContext, *Diagnostic) {
if len(sources) == 0 {
return nil, nil
}
if resolved == nil {
return nil, nil
}
rootPath, basePath := resolved.rootPath, resolved.basePath
var filesystem fs.FS
if resolved.native != nil {
filesystem = resolved.native.filesystem
}
var rooted fs.FS
if filesystem != nil {
rooted = rootedNativeFS{filesystem: filesystem, root: rootPath}
} else {
rooted = rootedHostFS{root: rootPath}
}
result := make(map[string]ResourceContext, len(sources))
for _, acquired := range sources {
base := basePath
if acquired.Path != "" {
if filesystem != nil {
base = path.Dir(acquired.Path)
} else {
base = filepath.Dir(acquired.Path)
}
}
var relative string
if filesystem != nil {
if !containsNativePath(rootPath, base) {
value := importDiagnostic(CodeImportOutsideRoot, "source base is outside the configuration root", nil)
return nil, &value
}
relative = base
if rootPath != "." {
relative = strings.TrimPrefix(strings.TrimPrefix(base, rootPath), "/")
if relative == "" {
relative = "."
}
}
} else {
if !containedPath(rootPath, base) {
value := importDiagnostic(CodeImportOutsideRoot, "source base is outside the configuration root", nil)
return nil, &value
}
var err error
relative, err = filepath.Rel(rootPath, base)
if err != nil {
value := importDiagnostic(CodeImportInvalid, "source base could not be addressed in the configuration root", nil)
return nil, &value
}
relative = filepath.ToSlash(relative)
}
result[acquired.ID] = ResourceContext{FS: rooted, BaseDir: relative}
}
return result, nil
}
func mergeResourceContexts(target *map[string]ResourceContext, incoming map[string]ResourceContext) {
if len(incoming) == 0 {
return
}
if *target == nil {
*target = make(map[string]ResourceContext, len(incoming))
}
for id, context := range incoming {
(*target)[id] = context
}
}