diff --git a/go.mod b/go.mod index 3e0de02..6e1ce74 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module miro go 1.25.5 + +require github.com/BurntSushi/toml v1.5.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ff7fd09 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..5ae971a --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,40 @@ +package config + +import ( + "errors" + "fmt" + "os" + + "github.com/BurntSushi/toml" +) + +type Config struct { + TestDir string + HasTestDir bool +} + +type tomlConfig struct { + Miro tomlMiroConfig `toml:"miro"` +} + +type tomlMiroConfig struct { + TestDir string `toml:"test_dir"` +} + +// ReadConfig reads miro.toml and reports whether [miro].test_dir was explicitly set. +func ReadConfig(path string) (Config, error) { + var raw tomlConfig + + meta, err := toml.DecodeFile(path, &raw) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return Config{}, err + } + return Config{}, fmt.Errorf("failed to read %s: %v", path, err) + } + + return Config{ + TestDir: raw.Miro.TestDir, + HasTestDir: meta.IsDefined("miro", "test_dir"), + }, nil +} diff --git a/internal/config/config_test.go b/internal/config/config_test.go new file mode 100644 index 0000000..5541009 --- /dev/null +++ b/internal/config/config_test.go @@ -0,0 +1,60 @@ +package config + +import ( + "os" + "path/filepath" + "testing" +) + +func TestReadConfig(t *testing.T) { + tests := []struct { + name string + content string + wantDir string + wantHasDir bool + wantReadErr bool + }{ + { + name: "with test dir", + content: "[miro]\ntest_dir = \"custom/suite\"\n", + wantDir: "custom/suite", + wantHasDir: true, + }, + { + name: "without test dir", + content: "[miro]\n", + wantHasDir: false, + }, + { + name: "invalid toml", + content: "[miro]\ntest_dir = [\n", + wantReadErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + path := filepath.Join(t.TempDir(), "miro.toml") + if err := os.WriteFile(path, []byte(tt.content), 0o644); err != nil { + t.Fatalf("WriteFile() error = %v", err) + } + + got, err := ReadConfig(path) + if tt.wantReadErr { + if err == nil { + t.Fatal("ReadConfig() error = nil, want error") + } + return + } + if err != nil { + t.Fatalf("ReadConfig() error = %v", err) + } + if got.TestDir != tt.wantDir { + t.Fatalf("ReadConfig() TestDir = %q, want %q", got.TestDir, tt.wantDir) + } + if got.HasTestDir != tt.wantHasDir { + t.Fatalf("ReadConfig() HasTestDir = %v, want %v", got.HasTestDir, tt.wantHasDir) + } + }) + } +}