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 TestDocumentPathsUseOverlayDeclarationDirectory(t *testing.T) { t.Parallel() root := t.TempDir() overlays := filepath.Join(root, "overlays") if err := os.MkdirAll(overlays, 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(overlays, "development.yml"), []byte("output: {directory: ./overlay-output}\n"), 0o600); err != nil { t.Fatal(err) } loaded, err := loadConfig(main, LoadOptions{Overlay: "development"}) if err != nil { t.Fatalf("loadConfig() error = %v", err) } if got := loaded.Config.Output.Directory; got != filepath.Join(overlays, "overlay-output") { t.Fatalf("overlay directory = %q", got) } } func TestDocumentLoadDoesNotFallBackToLegacyProfileDirectory(t *testing.T) { t.Parallel() root := t.TempDir() main := filepath.Join(root, "notarius.yml") if err := os.WriteFile(main, []byte("version: 5\n"), 0o600); err != nil { t.Fatal(err) } legacy := filepath.Join(root, "profiles", "development.yml") if err := os.MkdirAll(filepath.Dir(legacy), 0o700); err != nil { t.Fatal(err) } if err := os.WriteFile(legacy, []byte("output: {directory: ./legacy-output}\n"), 0o600); err != nil { t.Fatal(err) } if _, err := loadConfig(main, LoadOptions{Overlay: "development"}); err == nil { t.Fatal("loadConfig() error = nil, want missing overlay") } } 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) } }