Resolve ConfigKit paths from declaration origins
This commit is contained in:
@@ -356,6 +356,8 @@ Test rendering failure and caller mutation at these real local boundaries.
|
|||||||
|
|
||||||
## Stage 7 — Resolve Declaration-Relative Paths
|
## Stage 7 — Resolve Declaration-Relative Paths
|
||||||
|
|
||||||
|
**Status:** Completed 2026-09-13.
|
||||||
|
|
||||||
**Goal:** Normalize file paths using their effective source origins and retain
|
**Goal:** Normalize file paths using their effective source origins and retain
|
||||||
correct ConfigKit inspection history.
|
correct ConfigKit inspection history.
|
||||||
|
|
||||||
|
|||||||
165
internal/core/config/document_paths.go
Normal file
165
internal/core/config/document_paths.go
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
configkit "gitea.maximumdirect.net/eric/ConfigKit"
|
||||||
|
)
|
||||||
|
|
||||||
|
func normalizeDocumentPaths(document *Document, resolution *configkit.Resolution, state *documentLoadState) {
|
||||||
|
if document == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
initializeDocumentMainDirectory(resolution, state)
|
||||||
|
if document.PromptKit != nil {
|
||||||
|
normalizeDocumentPath(resolution, state, configkit.Keys("promptkit", "profile_dir"), &document.PromptKit.ProfileDir, false, "resolved PromptKit profile directory")
|
||||||
|
normalizeDocumentPath(resolution, state, configkit.Keys("promptkit", "profile_file"), &document.PromptKit.ProfileFile, false, "resolved PromptKit profile file")
|
||||||
|
}
|
||||||
|
if document.Output != nil {
|
||||||
|
normalizeDocumentPath(resolution, state, configkit.Keys("output", "directory"), &document.Output.Directory, false, "resolved output directory")
|
||||||
|
}
|
||||||
|
if document.Cache != nil {
|
||||||
|
if document.Cache.ChunkPlans != nil {
|
||||||
|
normalizeDocumentPath(resolution, state, configkit.Keys("cache", "chunk_plans", "directory"), &document.Cache.ChunkPlans.Directory, true, "resolved chunk-plan cache directory")
|
||||||
|
}
|
||||||
|
if document.Cache.Checkpoints != nil {
|
||||||
|
normalizeDocumentPath(resolution, state, configkit.Keys("cache", "checkpoints", "directory"), &document.Cache.Checkpoints.Directory, true, "resolved checkpoint cache directory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if document.Debug != nil {
|
||||||
|
normalizeDocumentPath(resolution, state, configkit.Keys("debug", "directory"), &document.Debug.Directory, false, "resolved debug directory")
|
||||||
|
}
|
||||||
|
for _, id := range sortedPipelineDocumentKeys(document.Pipelines) {
|
||||||
|
profile := document.Pipelines[id]
|
||||||
|
path := configkit.Keys("pipelines").Key(id)
|
||||||
|
normalizeDocumentReferencePaths(profile.References, path.Key("references"), resolution, state)
|
||||||
|
normalizeDocumentBindingReferencePaths(&profile.Input, path.Key("input"), resolution, state)
|
||||||
|
if profile.Chunk != nil {
|
||||||
|
normalizeDocumentBindingReferencePaths(profile.Chunk, path.Key("chunk"), resolution, state)
|
||||||
|
}
|
||||||
|
if profile.Output != nil {
|
||||||
|
normalizeDocumentBindingReferencePaths(profile.Output, path.Key("output"), resolution, state)
|
||||||
|
}
|
||||||
|
for laneID, lane := range profile.Artifacts {
|
||||||
|
normalizeDocumentLaneReferencePaths(&lane, path.Key("artifacts").Key(laneID), resolution, state)
|
||||||
|
profile.Artifacts[laneID] = lane
|
||||||
|
}
|
||||||
|
for index := range profile.Steps {
|
||||||
|
step := &profile.Steps[index]
|
||||||
|
stepPath := path.Key("steps").Index(index)
|
||||||
|
normalizeDocumentReferencePaths(step.References, stepPath.Key("references"), resolution, state)
|
||||||
|
for laneID, lane := range step.Artifacts {
|
||||||
|
normalizeDocumentLaneReferencePaths(&lane, stepPath.Key("artifacts").Key(laneID), resolution, state)
|
||||||
|
step.Artifacts[laneID] = lane
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.Pipelines[id] = profile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initializeDocumentMainDirectory(resolution *configkit.Resolution, state *documentLoadState) {
|
||||||
|
if state == nil || state.mainDirectory != "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info, ok := resolution.InputInfo(configkit.Keys("version"))
|
||||||
|
if ok && len(info.Origin.Locations) == 1 {
|
||||||
|
if source, sourceOK := resolution.Source(info.Origin.Locations[0].SourceID); sourceOK && source.Path != "" {
|
||||||
|
state.mainDirectory = filepath.Dir(source.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Byte and reader sources are test-oriented private entry points. They have
|
||||||
|
// no declaring file, so preserve their established invocation-directory
|
||||||
|
// semantics without extending that fallback to file-backed production loads.
|
||||||
|
state.mainDirectory = cleanInvocationDirectory(".")
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeDocumentBindingReferencePaths(binding *BindingDocument, path configkit.Path, resolution *configkit.Resolution, state *documentLoadState) {
|
||||||
|
if binding != nil {
|
||||||
|
normalizeDocumentReferencePaths(binding.References, path.Key("references"), resolution, state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeDocumentLaneReferencePaths(lane *ArtifactLaneDocument, path configkit.Path, resolution *configkit.Resolution, state *documentLoadState) {
|
||||||
|
if lane == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
normalizeDocumentBindingReferencePaths(&lane.Extract, path.Key("extract"), resolution, state)
|
||||||
|
normalizeDocumentBindingReferencePaths(lane.Merge, path.Key("merge"), resolution, state)
|
||||||
|
normalizeDocumentBindingReferencePaths(lane.Normalize, path.Key("normalize"), resolution, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeDocumentReferencePaths(references map[string]ReferenceDocument, path configkit.Path, resolution *configkit.Resolution, state *documentLoadState) {
|
||||||
|
for _, name := range sortedReferenceDocumentKeys(references) {
|
||||||
|
source := references[name]
|
||||||
|
sourcePath := path.Key(name).Key("path")
|
||||||
|
if source.Path != nil && *source.Path != "" && !filepath.IsAbs(*source.Path) {
|
||||||
|
base, ok := documentPathBase(resolution, state, sourcePath)
|
||||||
|
if !ok {
|
||||||
|
resolution.Error(sourcePath, "relative path has no unambiguous source base")
|
||||||
|
} else {
|
||||||
|
value := filepath.Clean(filepath.Join(base, *source.Path))
|
||||||
|
if value != *source.Path {
|
||||||
|
resolution.Record(sourcePath, configkit.ChangeNormalization, "resolved external reference path")
|
||||||
|
source.Path = documentValue(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
references[name] = source
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeDocumentPath(resolution *configkit.Resolution, state *documentLoadState, path configkit.Path, target **string, optional bool, reason string) {
|
||||||
|
if target == nil || *target == nil || **target == "" || filepath.IsAbs(**target) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
base, ok := documentPathBase(resolution, state, path)
|
||||||
|
if !ok {
|
||||||
|
resolution.Error(path, "relative path has no unambiguous source base")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
value := filepath.Clean(filepath.Join(base, **target))
|
||||||
|
if optional && **target == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if *target != nil && **target != value {
|
||||||
|
configkit.Normalize(resolution, path, target, documentValue(value), reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func documentPathBase(resolution *configkit.Resolution, state *documentLoadState, path configkit.Path) (string, bool) {
|
||||||
|
original := path
|
||||||
|
if state != nil {
|
||||||
|
original = state.originalPath(path)
|
||||||
|
}
|
||||||
|
info, ok := resolution.InputInfo(original)
|
||||||
|
if !ok {
|
||||||
|
if state != nil && state.mainDirectory != "" {
|
||||||
|
return state.mainDirectory, true
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
switch info.Origin.Layer {
|
||||||
|
case configkit.LayerCLI:
|
||||||
|
if state != nil && state.invocationDirectory != "" {
|
||||||
|
return state.invocationDirectory, true
|
||||||
|
}
|
||||||
|
case configkit.LayerDefault:
|
||||||
|
if state != nil && state.mainDirectory != "" {
|
||||||
|
return state.mainDirectory, true
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if len(info.Origin.Locations) != 1 {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
source, ok := resolution.Source(info.Origin.Locations[0].SourceID)
|
||||||
|
if !ok || source.Path == "" {
|
||||||
|
if state != nil && state.mainDirectory != "" {
|
||||||
|
return state.mainDirectory, true
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return filepath.Dir(source.Path), true
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
123
internal/core/config/document_paths_test.go
Normal file
123
internal/core/config/document_paths_test.go
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
configkit "gitea.maximumdirect.net/eric/ConfigKit"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDocumentPathsUseDeclaringFilesAcrossImports(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
root := t.TempDir()
|
||||||
|
main := filepath.Join(root, "notarius.yml")
|
||||||
|
fragmentDirectory := filepath.Join(root, "fragments")
|
||||||
|
if err := os.MkdirAll(fragmentDirectory, 0o700); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
fragment := filepath.Join(fragmentDirectory, "pipelines.yml")
|
||||||
|
if err := os.WriteFile(fragment, []byte(`pipelines:
|
||||||
|
imported:
|
||||||
|
input: {module: input}
|
||||||
|
references:
|
||||||
|
source: {path: ./from-fragment.txt}
|
||||||
|
`), 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(main, []byte(`version: 5
|
||||||
|
configkit:
|
||||||
|
imports:
|
||||||
|
- path: fragments/pipelines.yml
|
||||||
|
output: {directory: ./output}
|
||||||
|
debug: {directory: ./debug}
|
||||||
|
pipelines:
|
||||||
|
main:
|
||||||
|
input: {module: input}
|
||||||
|
references:
|
||||||
|
source: {path: ./from-main.txt}
|
||||||
|
`), 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
loaded, err := loadConfig(main, LoadOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("loadConfig() error = %v", err)
|
||||||
|
}
|
||||||
|
if got := loaded.Config.Pipelines["main"].References["source"].Path; got != filepath.Join(root, "from-main.txt") {
|
||||||
|
t.Fatalf("main reference = %q", got)
|
||||||
|
}
|
||||||
|
if got := loaded.Config.Pipelines["imported"].References["source"].Path; got != filepath.Join(fragmentDirectory, "from-fragment.txt") {
|
||||||
|
t.Fatalf("fragment reference = %q", got)
|
||||||
|
}
|
||||||
|
if loaded.Config.Output.Directory != filepath.Join(root, "output") || loaded.Config.Debug.Directory != filepath.Join(root, "debug") {
|
||||||
|
t.Fatalf("destinations = %#v %#v", loaded.Config.Output, loaded.Config.Debug)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDocumentPathsUseInvocationDirectoryForOverrides(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
root := t.TempDir()
|
||||||
|
configPath := filepath.Join(root, "notarius.yml")
|
||||||
|
if err := os.WriteFile(configPath, []byte("version: 5\n"), 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
invocation := t.TempDir()
|
||||||
|
loaded, err := loadConfig(configPath, LoadOptions{
|
||||||
|
InvocationDirectory: invocation,
|
||||||
|
Overrides: []configkit.Override{{Path: configkit.Keys("output", "directory"), Value: "generated", Flag: "--output"}},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("loadConfig() error = %v", err)
|
||||||
|
}
|
||||||
|
if got := loaded.Config.Output.Directory; got != filepath.Join(invocation, "generated") {
|
||||||
|
t.Fatalf("override directory = %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDocumentPathsUseProfileDeclarationDirectory(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
root := t.TempDir()
|
||||||
|
profiles := filepath.Join(root, "profiles")
|
||||||
|
if err := os.MkdirAll(profiles, 0o700); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
main := filepath.Join(root, "notarius.yml")
|
||||||
|
if err := os.WriteFile(main, []byte("version: 5\n"), 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(filepath.Join(profiles, "development.yml"), []byte("output: {directory: ./profile-output}\n"), 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
loaded, err := loadConfig(main, LoadOptions{Profile: "development"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("loadConfig() error = %v", err)
|
||||||
|
}
|
||||||
|
if got := loaded.Config.Output.Directory; got != filepath.Join(profiles, "profile-output") {
|
||||||
|
t.Fatalf("profile directory = %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDocumentPathsKeepEmptyCacheDirectoriesAndAbsolutePaths(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
root := t.TempDir()
|
||||||
|
configPath := filepath.Join(root, "notarius.yml")
|
||||||
|
abs := filepath.Join(t.TempDir(), "outside.txt")
|
||||||
|
if err := os.WriteFile(configPath, []byte("version: 5\ncache:\n chunk_plans: {directory: ''}\n checkpoints: {directory: ''}\npipelines:\n main:\n input: {module: input}\n references:\n outside: {path: "+abs+"}\n"), 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
loaded, err := loadConfig(configPath, LoadOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("loadConfig() error = %v", err)
|
||||||
|
}
|
||||||
|
if loaded.Config.Cache.ChunkPlans.Directory != "" || loaded.Config.Cache.Checkpoints.Directory != "" {
|
||||||
|
t.Fatalf("cache directories = %#v", loaded.Config.Cache)
|
||||||
|
}
|
||||||
|
if got := loaded.Config.Pipelines["main"].References["outside"].Path; got != abs {
|
||||||
|
t.Fatalf("absolute reference = %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
configkit "gitea.maximumdirect.net/eric/ConfigKit"
|
configkit "gitea.maximumdirect.net/eric/ConfigKit"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -8,26 +10,43 @@ import (
|
|||||||
// boundary. It is intentionally narrow: configuration discovery and CLI flag
|
// boundary. It is intentionally narrow: configuration discovery and CLI flag
|
||||||
// parsing remain outside this package.
|
// parsing remain outside this package.
|
||||||
type LoadOptions struct {
|
type LoadOptions struct {
|
||||||
Profile string
|
Profile string
|
||||||
Overrides []configkit.Override
|
Overrides []configkit.Override
|
||||||
|
InvocationDirectory string
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadDocument is the private ConfigKit load boundary under construction.
|
// loadDocument is the private ConfigKit load boundary under construction.
|
||||||
// Production commands continue to use the existing version 4 loader until the
|
// Production commands continue to use the existing version 4 loader until the
|
||||||
// runtime conversion and command wiring are complete.
|
// runtime conversion and command wiring are complete.
|
||||||
func loadDocument(path string, options LoadOptions) (*configkit.Result[Document], error) {
|
func loadDocument(path string, options LoadOptions) (*configkit.Result[Document], error) {
|
||||||
return loadDocumentSource(configkit.File(path), options)
|
return loadDocumentWithSource(configkit.File(path), options, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadDocumentSource(source configkit.Source, options LoadOptions) (*configkit.Result[Document], error) {
|
func loadDocumentSource(source configkit.Source, options LoadOptions) (*configkit.Result[Document], error) {
|
||||||
state := newDocumentLoadState()
|
return loadDocumentWithSource(source, options, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadDocumentWithSource(source configkit.Source, options LoadOptions, imports bool) (*configkit.Result[Document], error) {
|
||||||
|
state := newDocumentLoadState(options.InvocationDirectory)
|
||||||
return configkit.Load(source, configkit.Options[Document]{
|
return configkit.Load(source, configkit.Options[Document]{
|
||||||
Definition: documentDefinition(state),
|
Definition: documentDefinition(state),
|
||||||
|
Imports: imports,
|
||||||
Profile: options.Profile,
|
Profile: options.Profile,
|
||||||
Overrides: options.Overrides,
|
Overrides: options.Overrides,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cleanInvocationDirectory(value string) string {
|
||||||
|
if value == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
absolute, err := filepath.Abs(value)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return filepath.Clean(absolute)
|
||||||
|
}
|
||||||
|
|
||||||
func documentDefinition(state *documentLoadState) configkit.Definition[Document] {
|
func documentDefinition(state *documentLoadState) configkit.Definition[Document] {
|
||||||
return configkit.Definition[Document]{
|
return configkit.Definition[Document]{
|
||||||
Defaults: documentDefaults,
|
Defaults: documentDefaults,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func resolveDocumentOperations(document *Document, resolution *configkit.Resolut
|
|||||||
normalizeDocumentPromptKit(document.PromptKit, resolution)
|
normalizeDocumentPromptKit(document.PromptKit, resolution)
|
||||||
normalizeDocumentState(document, resolution)
|
normalizeDocumentState(document, resolution)
|
||||||
normalizeDocumentPipelines(document, resolution, state)
|
normalizeDocumentPipelines(document, resolution, state)
|
||||||
|
normalizeDocumentPaths(document, resolution, state)
|
||||||
deriveDocumentExtractWorkers(document, resolution)
|
deriveDocumentExtractWorkers(document, resolution)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,16 +36,20 @@ debug:
|
|||||||
if loaded.Config.Concurrency.TotalLLM == nil || *loaded.Config.Concurrency.TotalLLM != 4 || loaded.Config.Concurrency.StageWorkers["extract"] != 4 {
|
if loaded.Config.Concurrency.TotalLLM == nil || *loaded.Config.Concurrency.TotalLLM != 4 || loaded.Config.Concurrency.StageWorkers["extract"] != 4 {
|
||||||
t.Fatalf("concurrency = %#v", loaded.Config.Concurrency)
|
t.Fatalf("concurrency = %#v", loaded.Config.Concurrency)
|
||||||
}
|
}
|
||||||
if loaded.Config.PromptKit.ProfileDir == nil || *loaded.Config.PromptKit.ProfileDir != "./profiles" ||
|
workingDirectory, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if loaded.Config.PromptKit.ProfileDir == nil || *loaded.Config.PromptKit.ProfileDir != filepath.Join(workingDirectory, "profiles") ||
|
||||||
loaded.Config.PromptKit.LocalBackend == nil || loaded.Config.PromptKit.LocalBackend.Endpoint == nil || *loaded.Config.PromptKit.LocalBackend.Endpoint != "https://localhost:8080/v1" ||
|
loaded.Config.PromptKit.LocalBackend == nil || loaded.Config.PromptKit.LocalBackend.Endpoint == nil || *loaded.Config.PromptKit.LocalBackend.Endpoint != "https://localhost:8080/v1" ||
|
||||||
loaded.Config.PromptKit.LocalBackend.ConcurrencyLimit == nil || *loaded.Config.PromptKit.LocalBackend.ConcurrencyLimit != 0 {
|
loaded.Config.PromptKit.LocalBackend.ConcurrencyLimit == nil || *loaded.Config.PromptKit.LocalBackend.ConcurrencyLimit != 0 {
|
||||||
t.Fatalf("promptkit = %#v", loaded.Config.PromptKit)
|
t.Fatalf("promptkit = %#v", loaded.Config.PromptKit)
|
||||||
}
|
}
|
||||||
if loaded.Config.Output.Directory == nil || *loaded.Config.Output.Directory != "./output" ||
|
if loaded.Config.Output.Directory == nil || *loaded.Config.Output.Directory != filepath.Join(workingDirectory, "output") ||
|
||||||
loaded.Config.Cache.ChunkPlans.Mode == nil || *loaded.Config.Cache.ChunkPlans.Mode != "refresh" ||
|
loaded.Config.Cache.ChunkPlans.Mode == nil || *loaded.Config.Cache.ChunkPlans.Mode != "refresh" ||
|
||||||
loaded.Config.Cache.ChunkPlans.Directory == nil || *loaded.Config.Cache.ChunkPlans.Directory != "" ||
|
loaded.Config.Cache.ChunkPlans.Directory == nil || *loaded.Config.Cache.ChunkPlans.Directory != "" ||
|
||||||
loaded.Config.Cache.Checkpoints.Directory == nil || *loaded.Config.Cache.Checkpoints.Directory != "" ||
|
loaded.Config.Cache.Checkpoints.Directory == nil || *loaded.Config.Cache.Checkpoints.Directory != "" ||
|
||||||
loaded.Config.Debug.Directory == nil || *loaded.Config.Debug.Directory != "./debug" {
|
loaded.Config.Debug.Directory == nil || *loaded.Config.Debug.Directory != filepath.Join(workingDirectory, "debug") {
|
||||||
t.Fatalf("state = %#v, %#v, %#v", loaded.Config.Output, loaded.Config.Cache, loaded.Config.Debug)
|
t.Fatalf("state = %#v, %#v, %#v", loaded.Config.Output, loaded.Config.Cache, loaded.Config.Debug)
|
||||||
}
|
}
|
||||||
if diagnostics := loaded.Diagnostics(); len(diagnostics) != 0 {
|
if diagnostics := loaded.Diagnostics(); len(diagnostics) != 0 {
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ import (
|
|||||||
// load-local: source-location handling consumes it during a later resolver
|
// load-local: source-location handling consumes it during a later resolver
|
||||||
// pass and it never becomes runtime configuration state.
|
// pass and it never becomes runtime configuration state.
|
||||||
type documentLoadState struct {
|
type documentLoadState struct {
|
||||||
originalPaths map[string]configkit.Path
|
originalPaths map[string]configkit.Path
|
||||||
|
mainDirectory string
|
||||||
|
invocationDirectory string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDocumentLoadState() *documentLoadState {
|
func newDocumentLoadState(invocationDirectory string) *documentLoadState {
|
||||||
return &documentLoadState{originalPaths: make(map[string]configkit.Path)}
|
return &documentLoadState{originalPaths: make(map[string]configkit.Path), invocationDirectory: cleanInvocationDirectory(invocationDirectory)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *documentLoadState) rememberPath(normalized, original configkit.Path) {
|
func (state *documentLoadState) rememberPath(normalized, original configkit.Path) {
|
||||||
|
|||||||
Reference in New Issue
Block a user