Skip to content

Commit 80ea42d

Browse files
committed
fix path normalization for RooIgnoreController and tests
1 parent 1ea63af commit 80ea42d

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

src/core/ignore/GitIgnoreController.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,28 +123,38 @@ export class GitIgnoreController extends BaseIgnoreController {
123123

124124
if (relativeDir) {
125125
// For nested .gitignore files, we need to create patterns that match files within that directory
126-
const lines = content.split("\n").filter((line) => line.trim() && !line.startsWith("#"))
127-
const adjustedPatterns = lines.map((pattern) => {
126+
const lines = content.split(/\r?\n/).filter((line) => line.trim() && !line.startsWith("#"))
127+
// Convert Windows paths to POSIX for consistent pattern matching
128+
const normalizedRelativeDir = relativeDir.split(path.sep).join("/")
129+
130+
const adjustedPatterns = lines.flatMap((pattern) => {
128131
const trimmed = pattern.trim()
129-
// Convert Windows paths to POSIX for consistent pattern matching
130-
const normalizedRelativeDir = relativeDir.split(path.sep).join("/")
131132

132133
if (trimmed.startsWith("/")) {
133134
// Absolute patterns (starting with /) are relative to the .gitignore location
134-
return normalizedRelativeDir + trimmed
135+
return [normalizedRelativeDir + trimmed]
135136
} else if (trimmed.startsWith("!")) {
136137
// Negation patterns
137138
const negatedPattern = trimmed.slice(1)
138139
if (negatedPattern.startsWith("/")) {
139-
return "!" + normalizedRelativeDir + negatedPattern
140+
return ["!" + normalizedRelativeDir + negatedPattern]
140141
} else {
141142
// For relative negation patterns, match in the directory and subdirectories
142-
return "!" + normalizedRelativeDir + "/" + negatedPattern
143+
return [
144+
"!" + normalizedRelativeDir + "/" + negatedPattern,
145+
"!" + normalizedRelativeDir + "/**/" + negatedPattern,
146+
]
143147
}
144148
} else {
145-
// Relative patterns - match files directly in the directory
146-
// This handles cases like "*.tmp" in src/.gitignore matching "src/temp.tmp"
147-
return normalizedRelativeDir + "/" + trimmed
149+
// Relative patterns - match files in the directory and all subdirectories
150+
// For "*.tmp" in src/.gitignore, we need TWO patterns:
151+
// - src/*.tmp (matches direct children like src/temp.tmp)
152+
// - src/**/*.tmp (matches descendants like src/subdir/temp.tmp)
153+
const patterns = [
154+
normalizedRelativeDir + "/" + trimmed,
155+
normalizedRelativeDir + "/**/" + trimmed,
156+
]
157+
return patterns
148158
}
149159
})
150160

src/core/ignore/__tests__/GitIgnoreController.security.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,9 @@ build/
175175

176176
// Mock different content for each file
177177
mockReadFile.mockImplementation((filePath: any) => {
178-
if (filePath.toString().endsWith("src/.gitignore")) {
178+
// Normalize path separators for cross-platform compatibility
179+
const normalizedPath = filePath.toString().replace(/\\/g, "/")
180+
if (normalizedPath.endsWith("src/.gitignore")) {
179181
return Promise.resolve("*.tmp\n*.cache\n")
180182
}
181183
return Promise.resolve("node_modules/\n*.log\n")

src/core/ignore/__tests__/GitIgnoreController.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ describe("GitIgnoreController", () => {
153153

154154
// Mock different content for each file
155155
mockReadFile.mockImplementation((filePath: any) => {
156-
if (filePath.toString().endsWith("src/.gitignore")) {
156+
// Normalize path separators for cross-platform compatibility
157+
const normalizedPath = filePath.toString().replace(/\\/g, "/")
158+
if (normalizedPath.endsWith("src/.gitignore")) {
157159
return Promise.resolve("*.tmp\n")
158160
}
159161
return Promise.resolve("node_modules/\n*.log\n")

0 commit comments

Comments
 (0)