Clarify search and secret bootstrap names
This commit is contained in:
@@ -52,8 +52,8 @@ func SearchDirectory(directory string, supplied ...DirectorySearchOptions) Searc
|
||||
return Search{value: engine.SearchDirectory(directory, options...)}
|
||||
}
|
||||
|
||||
// Paths describes literal host-file candidates in the supplied order.
|
||||
func Paths(paths ...string) Search { return Search{value: engine.Paths(paths...)} }
|
||||
// SearchPaths describes literal host-file candidates in the supplied order.
|
||||
func SearchPaths(paths ...string) Search { return Search{value: engine.Paths(paths...)} }
|
||||
|
||||
// Searches concatenates descriptions in order and snapshots their entries.
|
||||
func Searches(searches ...Search) Search {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Pre-v1 Public API Cleanup Implementation Plan
|
||||
|
||||
Status: in progress; Stages 1–4 are complete and Stages 5–11 are pending.
|
||||
Status: in progress; Stages 1–5 are complete and Stages 6–11 are pending.
|
||||
Baseline: `07e4ae5d9236935389e81b207d4a8f00543fafce`.
|
||||
Audience: a Luna coding agent executing the stages sequentially.
|
||||
|
||||
@@ -225,7 +225,7 @@ ordinary/layered loading.
|
||||
|
||||
## Stage 5 — Clarify Discovery And Environment Bootstrap Names
|
||||
|
||||
Status: pending. Implements N1 and D7.
|
||||
Status: complete. Implements N1 and D7.
|
||||
|
||||
1. In root [discovery.go](../../discovery.go), rename `Paths` to `SearchPaths`.
|
||||
Forward the same literal candidates to existing engine machinery. Migrate
|
||||
|
||||
@@ -82,7 +82,7 @@ func Example_weatherStartup() {
|
||||
defer os.RemoveAll(directory)
|
||||
_ = os.WriteFile(filepath.Join(directory, blockedName), []byte("unused-example-value\n"), 0o600)
|
||||
_ = os.WriteFile(filepath.Join(directory, tokenName), []byte("disposable-example-credential\n"), 0o600)
|
||||
report, bootstrapErr := configkit.LoadSecretsDir(directory)
|
||||
report, bootstrapErr := configkit.LoadSecretsIntoEnvironment(directory)
|
||||
var reportOutput bytes.Buffer
|
||||
_, reportWriteErr := report.WriteTo(&reportOutput)
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ func LoadSequenceCatalog(mainPath, overlayName, runLabel string) (*configkit.Res
|
||||
filesystem := configkit.NewFilesystem("sequence catalog", os.DirFS(root))
|
||||
filesystemContext := &configkit.FilesystemContext{BaseDir: ".", Root: ".", FS: &filesystem}
|
||||
mainSearch := configkit.SearchConfig("", configkit.Searches(
|
||||
configkit.Paths(absoluteMain),
|
||||
configkit.SearchPaths(absoluteMain),
|
||||
configkit.SearchDirectory(filepath.Join(root, "fallback"), configkit.DirectorySearchOptions{
|
||||
Filenames: []configkit.FilenameGroup{configkit.CustomFilenames(filepath.Base(absoluteMain))},
|
||||
}),
|
||||
|
||||
@@ -140,7 +140,7 @@ func TestFacadeSecretsBootstrapUsesFacadeRecords(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
report, err := configkit.LoadSecretsDir(directory)
|
||||
report, err := configkit.LoadSecretsIntoEnvironment(directory)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -164,7 +164,7 @@ func TestFacadeSecretsBootstrapUsesFacadeRecords(t *testing.T) {
|
||||
t.Fatalf("report rendering = %q, %v", rendered.String(), err)
|
||||
}
|
||||
|
||||
failedReport, err := configkit.LoadSecretsDir("")
|
||||
failedReport, err := configkit.LoadSecretsIntoEnvironment("")
|
||||
var secretsError *configkit.SecretsError
|
||||
if failedReport == nil || !errors.As(err, &secretsError) || len(secretsError.Diagnostics()) != 1 || secretsError.Diagnostics()[0].Code != configkit.CodeSecretsInvalidPath {
|
||||
t.Fatalf("bootstrap failure = %#v / %#v", failedReport, err)
|
||||
|
||||
@@ -93,14 +93,14 @@ func TestFacadeSearchOrderingRequirednessAndSnapshots(t *testing.T) {
|
||||
names := []string{"config.yml"}
|
||||
groups := []FilenameGroup{CustomFilenames(names...)}
|
||||
directoryOptions := []DirectorySearchOptions{{Filenames: groups}}
|
||||
search := Searches(Paths(paths...), SearchDirectory(root, directoryOptions...), Paths(laterPath))
|
||||
search := Searches(SearchPaths(paths...), SearchDirectory(root, directoryOptions...), SearchPaths(laterPath))
|
||||
source := SearchConfig("", search, SearchOptions{Required: true})
|
||||
|
||||
paths[0] = laterPath
|
||||
names[0] = "later.yml"
|
||||
groups[0] = CustomFilenames("later.yml")
|
||||
directoryOptions[0].Filenames[0] = CustomFilenames("later.yml")
|
||||
search = Paths(laterPath)
|
||||
search = SearchPaths(laterPath)
|
||||
|
||||
result, err := Load[facadeDiscoveryConfig](source)
|
||||
if err != nil || result.Config.Value != "selected" {
|
||||
@@ -110,7 +110,7 @@ func TestFacadeSearchOrderingRequirednessAndSnapshots(t *testing.T) {
|
||||
t.Fatalf("ordered search sources = %#v", sources)
|
||||
}
|
||||
|
||||
_, err = Load[facadeDiscoveryConfig](SearchConfig("", Paths(filepath.Join(root, "missing.yml")), SearchOptions{Required: true}))
|
||||
_, err = Load[facadeDiscoveryConfig](SearchConfig("", SearchPaths(filepath.Join(root, "missing.yml")), SearchOptions{Required: true}))
|
||||
var loadErr *LoadError
|
||||
if !errors.As(err, &loadErr) {
|
||||
t.Fatalf("required exhausted search error = %v, want *LoadError", err)
|
||||
@@ -131,7 +131,7 @@ func TestFacadeSearchWorksForLayeredMainAndUnderlay(t *testing.T) {
|
||||
mainPath := writeFacadeImportFile(t, root, "main.yml", "settings: {main: value}\n")
|
||||
underlayPath := writeFacadeImportFile(t, root, "underlay/base.yml", "settings: {underlay: value}\n")
|
||||
result, err := LoadLayered(
|
||||
Input{Source: SearchConfig("", Paths(mainPath))},
|
||||
Input{Source: SearchConfig("", SearchPaths(mainPath))},
|
||||
LayeredOptions[facadeDiscoveryConfig]{Underlays: []Underlay{{Inputs: []Input{{
|
||||
Source: SearchConfig("", SearchDirectory(filepath.Dir(underlayPath), DirectorySearchOptions{
|
||||
Filenames: []FilenameGroup{CustomFilenames("base.yml")},
|
||||
@@ -157,7 +157,7 @@ func TestFacadeSearchSelectedAndAbsentUseRootOnlyContext(t *testing.T) {
|
||||
filesystem := &FilesystemContext{Root: root}
|
||||
options := Options[facadeDiscoveryConfig]{Overlay: "testing", Filesystem: filesystem}
|
||||
|
||||
selected, err := Load(SearchConfig("", Paths(mainPath)), options)
|
||||
selected, err := Load(SearchConfig("", SearchPaths(mainPath)), options)
|
||||
if err != nil || selected.Config.Value != "overlay" {
|
||||
t.Fatalf("selected search with root-only context = %#v, %v", selected, err)
|
||||
}
|
||||
@@ -171,7 +171,7 @@ func TestFacadeSearchSelectedAndAbsentUseRootOnlyContext(t *testing.T) {
|
||||
t.Fatalf("selected file base context = %#v, %v", mainContext, ok)
|
||||
}
|
||||
|
||||
missing := SearchConfig("", Paths(filepath.Join(root, "missing.yml")))
|
||||
missing := SearchConfig("", SearchPaths(filepath.Join(root, "missing.yml")))
|
||||
searchedAbsent, err := Load(missing, options)
|
||||
if err != nil {
|
||||
t.Fatalf("exhausted search with root-only overlay context: %v", err)
|
||||
@@ -201,7 +201,7 @@ func TestFacadeSearchRejectsSelectedContextWithoutFallback(t *testing.T) {
|
||||
inside := writeFacadeImportFile(t, root, "inside.yml", "value: fallback\n")
|
||||
outsideRoot := t.TempDir()
|
||||
outside := writeFacadeImportFile(t, outsideRoot, "outside.yml", "value: selected\n")
|
||||
search := SearchConfig("", Paths(outside, inside))
|
||||
search := SearchConfig("", SearchPaths(outside, inside))
|
||||
|
||||
_, err := Load(search, Options[facadeDiscoveryConfig]{Filesystem: &FilesystemContext{Root: root}})
|
||||
var loadErr *LoadError
|
||||
@@ -228,7 +228,7 @@ func TestFacadeSearchRunsCallbacksOnceAndKeepsInspectionWithSelectedFile(t *test
|
||||
selectedPath := writeFacadeImportFile(t, root, "selected.yml", "value: selected\n")
|
||||
writeFacadeImportFile(t, root, "later.yml", "value: later\n")
|
||||
defaultsCalls, resolveCalls, validateCalls := 0, 0, 0
|
||||
result, err := Load(SearchConfig("", Paths(selectedPath, filepath.Join(root, "later.yml"))), Options[facadeDiscoveryLifecycleConfig]{
|
||||
result, err := Load(SearchConfig("", SearchPaths(selectedPath, filepath.Join(root, "later.yml"))), Options[facadeDiscoveryLifecycleConfig]{
|
||||
Definition: Definition[facadeDiscoveryLifecycleConfig]{
|
||||
Defaults: func() facadeDiscoveryLifecycleConfig {
|
||||
defaultsCalls++
|
||||
@@ -272,7 +272,7 @@ func TestFacadeSearchSequenceItemAndAbsentInputPlacement(t *testing.T) {
|
||||
Destination: Keys("items"),
|
||||
PlacementMode: PlacementModeSequenceItem,
|
||||
}
|
||||
selected, err := Load(SearchConfig("", Paths(selectedPath)), options)
|
||||
selected, err := Load(SearchConfig("", SearchPaths(selectedPath)), options)
|
||||
if err != nil || len(selected.Config.Items) != 1 || selected.Config.Items[0].Name != "selected" {
|
||||
t.Fatalf("selected sequence item = %#v, %v", selected, err)
|
||||
}
|
||||
@@ -283,7 +283,7 @@ func TestFacadeSearchSequenceItemAndAbsentInputPlacement(t *testing.T) {
|
||||
defaults := func() facadeDiscoveryPlacementConfig {
|
||||
return facadeDiscoveryPlacementConfig{Items: []facadeDiscoveryPlacementItem{}}
|
||||
}
|
||||
absent, err := Load(SearchConfig("", Paths(filepath.Join(root, "missing.yml"))), Options[facadeDiscoveryPlacementConfig]{
|
||||
absent, err := Load(SearchConfig("", SearchPaths(filepath.Join(root, "missing.yml"))), Options[facadeDiscoveryPlacementConfig]{
|
||||
Definition: Definition[facadeDiscoveryPlacementConfig]{Defaults: defaults},
|
||||
Destination: options.Destination,
|
||||
PlacementMode: options.PlacementMode,
|
||||
|
||||
13
secrets.go
13
secrets.go
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
// SecretFileStatus describes the outcome for one file considered by
|
||||
// LoadSecretsDir.
|
||||
// LoadSecretsIntoEnvironment.
|
||||
type SecretFileStatus string
|
||||
|
||||
const (
|
||||
@@ -85,11 +85,12 @@ func (e *SecretsError) Diagnostics() []Diagnostic {
|
||||
return result
|
||||
}
|
||||
|
||||
// LoadSecretsDir explicitly loads immediate regular files from directory into
|
||||
// previously unset process environment variables. Applications should call it
|
||||
// once during startup, before concurrent work; Load never calls it.
|
||||
// Dot-prefixed entries are ignored and omitted from the report.
|
||||
func LoadSecretsDir(directory string) (*SecretsReport, error) {
|
||||
// LoadSecretsIntoEnvironment explicitly loads immediate regular files into the
|
||||
// process environment, preserving variables that are already set, including
|
||||
// empty values. Dot-prefixed entries are ignored and omitted from the report.
|
||||
// Load never calls it. The report accompanies any error, and an error does not
|
||||
// roll back values already applied.
|
||||
func LoadSecretsIntoEnvironment(directory string) (*SecretsReport, error) {
|
||||
report, err := engine.LoadSecretsDir(directory)
|
||||
result := &SecretsReport{value: report}
|
||||
if err == nil {
|
||||
|
||||
Reference in New Issue
Block a user