mirror of
https://github.com/holos-run/holos.git
synced 2026-03-20 17:25:01 +00:00
Previously there isn't a good way to unify json and yaml files with the cue configuration. This is a problem for use cases where data can be generated idempotentialy prior to rendering the platform configuration. The first use case is to explore unifying configuration with decrypted sops values, which isn't typical since Holos is designed to handle secrets with ExternalSecret resources, but does fit into the use case of executing a command to produce data idempotently, then make the data available to the platform configuration. Other use cases this feature is intended to support are the prior experiment where we fetch top level platform configuration from an rpc service, and the future goal of integrating with data provided by Terraform.
72 lines
1.8 KiB
Go
72 lines
1.8 KiB
Go
package util
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/holos-run/holos/internal/errors"
|
|
)
|
|
|
|
// EnsureNewline adds a trailing newline if not already there.
|
|
func EnsureNewline(b []byte) []byte {
|
|
if len(b) > 0 && b[len(b)-1] != '\n' {
|
|
b = append(b, '\n')
|
|
}
|
|
return b
|
|
}
|
|
|
|
// FindCueMod returns the root module location containing the cue.mod.
|
|
func FindCueMod(path string) (root string, err error) {
|
|
origPath := path
|
|
if path, err = filepath.Abs(path); err != nil {
|
|
return "", errors.Wrap(err)
|
|
}
|
|
for {
|
|
if _, err := os.Stat(filepath.Join(path, "cue.mod")); err == nil {
|
|
if root != "" && root != path {
|
|
return "", fmt.Errorf("multiple modules not supported: %v is not %v", root, path)
|
|
}
|
|
root = path
|
|
break
|
|
} else if !os.IsNotExist(err) {
|
|
return "", errors.Wrap(err)
|
|
}
|
|
parent := filepath.Dir(path)
|
|
if parent == path {
|
|
return "", fmt.Errorf("no cue.mod from root to leaf: %v", origPath)
|
|
}
|
|
path = parent
|
|
}
|
|
return root, nil
|
|
}
|
|
|
|
// FindRootLeaf returns the root path containing the cue.mod and the leaf path
|
|
// relative to the root for the given target path. FindRootLeaf calls
|
|
// [filepath.Clean] on the returned paths.
|
|
func FindRootLeaf(target string) (root string, leaf string, err error) {
|
|
if root, err = FindCueMod(target); err != nil {
|
|
return "", "", err
|
|
}
|
|
absPath, err := filepath.Abs(target)
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
if leaf, err = filepath.Rel(root, absPath); err != nil {
|
|
return "", "", err
|
|
}
|
|
// Needed for CUE to load the path properly.
|
|
leaf = DotSlash(leaf)
|
|
return
|
|
}
|
|
|
|
// DotSlash ensures a relative path has a leading ./ needed for CUE loading.
|
|
func DotSlash(path string) string {
|
|
clean := filepath.Clean(path)
|
|
if filepath.IsAbs(clean) || strings.HasPrefix(clean, ".") || strings.HasPrefix(clean, string(filepath.Separator)) {
|
|
return clean
|
|
}
|
|
return "." + string(filepath.Separator) + clean
|
|
}
|