Skip to content

Commit 96d3e43

Browse files
thegdsksKaranG08Copilot
committed
fix: normalize ignore patterns cross-platform and use config for diff index path
Address Copilot review feedback: - Normalize user-provided ignore patterns to forward slashes in ScanIgnore - Read index from cfg.Output.JSON in diff command instead of hardcoded path - Handle backslash normalization on non-Windows OSes where filepath.ToSlash is a no-op - Update tests to cover backslash ignore patterns Co-Authored-By: KaranG08 <KaranG08@users.noreply.github.com> Co-Authored-By: Copilot <copilot@github.com>
1 parent 7eb4382 commit 96d3e43

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

internal/cli/diff.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,29 @@ func newDiffCmd() *cobra.Command {
1717
Use: "diff",
1818
Short: "Show changes since last index generation",
1919
RunE: func(cmd *cobra.Command, args []string) error {
20-
// 1. Read stacklit.json
21-
data, err := os.ReadFile("stacklit.json")
20+
// 1. Load config and read the index file.
21+
cfg := config.Load(".")
22+
indexPath := cfg.Output.JSON
23+
if indexPath == "" {
24+
indexPath = "stacklit.json"
25+
}
26+
27+
data, err := os.ReadFile(indexPath)
2228
if err != nil {
23-
return fmt.Errorf("could not read stacklit.json: %w (run 'stacklit generate' first)", err)
29+
return fmt.Errorf("could not read %s: %w (run 'stacklit generate' first)", indexPath, err)
2430
}
2531

2632
var index schema.Index
2733
if err := json.Unmarshal(data, &index); err != nil {
28-
return fmt.Errorf("could not parse stacklit.json: %w", err)
34+
return fmt.Errorf("could not parse %s: %w", indexPath, err)
2935
}
3036

3137
storedHash := index.MerkleHash
3238
if storedHash == "" {
33-
return fmt.Errorf("stacklit.json has no merkle_hash; run 'stacklit generate' to rebuild")
39+
return fmt.Errorf("%s has no merkle_hash; run 'stacklit generate' to rebuild", indexPath)
3440
}
3541

3642
// 2. Walk current source files, excluding Stacklit's own generated outputs.
37-
cfg := config.Load(".")
3843
files, err := walker.Walk(".", cfg.ScanIgnore())
3944
if err != nil {
4045
return fmt.Errorf("failed to walk source files: %w", err)

internal/config/config.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"os"
66
"path/filepath"
7+
"strings"
78
)
89

910
// Config holds the settings loaded from a .stacklitrc.json file.
@@ -74,14 +75,26 @@ func Load(root string) *Config {
7475
}
7576

7677
// ScanIgnore returns ignore patterns plus Stacklit output files so generated artifacts
77-
// never feed back into the next scan.
78+
// never feed back into the next scan. All patterns are normalized to forward slashes
79+
// so they match the walker's normalized paths on every OS.
7880
func (c *Config) ScanIgnore() []string {
79-
ignore := append([]string{}, c.Ignore...)
81+
ignore := make([]string, 0, len(c.Ignore)+3)
82+
for _, pat := range c.Ignore {
83+
ignore = append(ignore, toSlash(pat))
84+
}
8085
for _, out := range []string{c.Output.JSON, c.Output.Mermaid, c.Output.HTML} {
8186
if out == "" {
8287
continue
8388
}
84-
ignore = append(ignore, filepath.ToSlash(out))
89+
ignore = append(ignore, toSlash(out))
8590
}
8691
return ignore
8792
}
93+
94+
// toSlash normalizes both OS path separators and literal backslashes to forward
95+
// slashes. filepath.ToSlash only converts os.PathSeparator which is '/' on
96+
// Unix, leaving Windows-style backslashes untouched on non-Windows builds.
97+
func toSlash(p string) string {
98+
p = filepath.ToSlash(p)
99+
return strings.ReplaceAll(p, "\\", "/")
100+
}

internal/config/config_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ func TestLoadMalformed(t *testing.T) {
5757

5858
func TestScanIgnoreIncludesOutputs(t *testing.T) {
5959
cfg := DefaultConfig()
60-
cfg.Ignore = []string{"custom/"}
60+
cfg.Ignore = []string{"custom/", "vendor\\libs"}
6161
cfg.Output.JSON = "out\\stacklit.json"
6262
cfg.Output.Mermaid = "docs\\DEPENDENCIES.md"
6363
cfg.Output.HTML = "stacklit.html"
6464

6565
got := cfg.ScanIgnore()
66-
want := []string{"custom/", "out/stacklit.json", "docs/DEPENDENCIES.md", "stacklit.html"}
66+
want := []string{"custom/", "vendor/libs", "out/stacklit.json", "docs/DEPENDENCIES.md", "stacklit.html"}
6767
if len(got) != len(want) {
6868
t.Fatalf("expected %d ignore patterns, got %d: %v", len(want), len(got), got)
6969
}

0 commit comments

Comments
 (0)