b21ef5c0bb
- Add --changes PATH and --changes-from REF flags to glint check and glint graph
for rules:changes: evaluation. --changes marks files explicitly; --changes-from
runs git diff --name-only <REF> automatically. Both flags can be combined.
- Implement doublestar glob matching (*, ** across path segments) in EvalJob and
EvalWorkflow; extended {paths, compare_to} map form supported.
- Without --changes/--changes-from the condition stays permissive (existing behaviour).
- Context summary line now shows changed-file count when file data is provided.
- Achieve 100% statement coverage: comprehensive tests added across all packages;
removed provably dead code; added testability seams (exit, userHomeDirFn,
execCommandOutput variables) to cover previously unreachable paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
128 lines
3.1 KiB
Go
128 lines
3.1 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestLoad_NotFound(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
cfg, err := Load(tmp)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if len(cfg.Ignore) != 0 || cfg.Token != "" || cfg.URL != "" {
|
|
t.Errorf("expected empty config, got %+v", cfg)
|
|
}
|
|
}
|
|
|
|
func TestLoad_Found(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
content := `
|
|
ignore:
|
|
- GL007
|
|
- GL032
|
|
severity:
|
|
GL004: warning
|
|
stages:
|
|
- quality
|
|
token: glpat-test
|
|
url: https://gitlab.example.com
|
|
cache_dir: /tmp/glint-cache
|
|
`
|
|
if err := os.WriteFile(filepath.Join(tmp, Filename), []byte(content), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg, err := Load(tmp)
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
if len(cfg.Ignore) != 2 || cfg.Ignore[0] != "GL007" {
|
|
t.Errorf("ignore = %v", cfg.Ignore)
|
|
}
|
|
if cfg.Severity["GL004"] != "warning" {
|
|
t.Errorf("severity = %v", cfg.Severity)
|
|
}
|
|
if len(cfg.Stages) != 1 || cfg.Stages[0] != "quality" {
|
|
t.Errorf("stages = %v", cfg.Stages)
|
|
}
|
|
if cfg.Token != "glpat-test" {
|
|
t.Errorf("token = %q", cfg.Token)
|
|
}
|
|
if cfg.URL != "https://gitlab.example.com" {
|
|
t.Errorf("url = %q", cfg.URL)
|
|
}
|
|
if cfg.CacheDir != "/tmp/glint-cache" {
|
|
t.Errorf("cache_dir = %q", cfg.CacheDir)
|
|
}
|
|
}
|
|
|
|
func TestLoad_WalksUp(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
sub := filepath.Join(tmp, "subdir", "pipeline")
|
|
if err := os.MkdirAll(sub, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Config at the top-level (no .git, so walk continues to tmp).
|
|
if err := os.WriteFile(filepath.Join(tmp, Filename), []byte("token: walked-up\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg, err := Load(sub)
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
if cfg.Token != "walked-up" {
|
|
t.Errorf("token = %q, want walked-up", cfg.Token)
|
|
}
|
|
}
|
|
|
|
func TestLoad_StopsAtGitRoot(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
sub := filepath.Join(tmp, "repo", "src")
|
|
if err := os.MkdirAll(sub, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// .git marks the repo root — walk must stop here.
|
|
if err := os.Mkdir(filepath.Join(tmp, "repo", ".git"), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Config placed ABOVE the .git root should not be found.
|
|
if err := os.WriteFile(filepath.Join(tmp, Filename), []byte("token: should-not-load\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg, err := Load(sub)
|
|
if err != nil {
|
|
t.Fatalf("Load: %v", err)
|
|
}
|
|
if cfg.Token != "" {
|
|
t.Errorf("token = %q, should not have crossed .git boundary", cfg.Token)
|
|
}
|
|
}
|
|
|
|
// TestLoad_ReadError covers the !os.IsNotExist(err) branch (config.go:59-61)
|
|
// when the file exists but is not readable.
|
|
func TestLoad_ReadError(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
cfgPath := filepath.Join(tmp, Filename)
|
|
if err := os.WriteFile(cfgPath, []byte("ignore: []"), 0o000); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { os.Chmod(cfgPath, 0o644) })
|
|
_, err := Load(tmp)
|
|
if err == nil {
|
|
t.Error("expected error for unreadable config file")
|
|
}
|
|
}
|
|
|
|
func TestLoad_InvalidYAML(t *testing.T) {
|
|
tmp := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(tmp, Filename), []byte("ignore: [unclosed\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err := Load(tmp)
|
|
if err == nil {
|
|
t.Error("expected error for invalid YAML")
|
|
}
|
|
}
|