fix: keep .rulesync/.aiignore exception effective in gitignore#1460
fix: keep .rulesync/.aiignore exception effective in gitignore#1460dyoshikawa merged 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes .gitignore generation so the negation rule for .rulesync/.aiignore remains effective by ensuring it appears after broad .aiignore ignore patterns, and adds a regression test to lock in the ordering.
Changes:
- Reordered
!.rulesync/.aiignorein the gitignore entry registry to come after**/.aiignore. - Added a unit test asserting
**/.aiignoreappears before!.rulesync/.aiignorein generated.gitignore.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/cli/commands/gitignore-entries.ts | Moves the .rulesync/.aiignore exception later in the registry to ensure Git ignore negation semantics work as intended. |
| src/cli/commands/gitignore.test.ts | Adds a regression test verifying the ordering of **/.aiignore and !.rulesync/.aiignore in generated output. |
| const writeCall = vi.mocked(writeFileContent).mock.calls[0]; | ||
| expect(writeCall).toBeDefined(); | ||
| const content = writeCall![1]; | ||
|
|
There was a problem hiding this comment.
The new ordering assertion relies on indexOf and will pass if **/.aiignore isn't present but the earlier test that checks toContain("**/.aiignore") is removed/changed later. Consider asserting content contains both patterns (or that both indexOf values are >= 0) before comparing indexes so failures are clearer and the test can’t become a false-positive over time.
| expect(content).toContain("**/.aiignore"); | |
| expect(content).toContain("!.rulesync/.aiignore"); |
| @@ -178,6 +177,8 @@ export const GITIGNORE_ENTRY_REGISTRY: ReadonlyArray<GitignoreEntryTag> = [ | |||
| { target: "kiro", feature: "subagents", entry: "**/.kiro/agents/" }, | |||
| { target: "kiro", feature: "mcp", entry: "**/.kiro/settings/mcp.json" }, | |||
| { target: "kiro", feature: "ignore", entry: "**/.aiignore" }, | |||
There was a problem hiding this comment.
**/.aiignore is currently tagged only for the kiro target, but Junie also generates a root .aiignore file (see JunieIgnore.getSettablePaths() and e2e ignore coverage). With rulesync gitignore --targets junie, this entry won’t be included, so the generated .aiignore won’t be gitignored. Consider changing this registry tag to apply to both kiro and junie (e.g., target: ["kiro","junie"]) so target-filtered output stays consistent.
| { target: "kiro", feature: "ignore", entry: "**/.aiignore" }, | |
| { target: ["kiro", "junie"], feature: "ignore", entry: "**/.aiignore" }, |
Motivation
!.rulesync/.aiignorewas placed before broad**/.aiignoreignore rules, causing the exception to be ineffective in generated.gitignore..rulesync/.aiignoreis not accidentally ignored.Description
!.rulesync/.aiignoreentry inGITIGNORE_ENTRY_REGISTRYso it appears after ignore entries such as**/.aiignoreand added an explanatory comment.src/cli/commands/gitignore.test.tsthat asserts the generated.gitignoreplaces**/.aiignorebefore!.rulesync/.aiignore.src/cli/commands/gitignore-entries.tsand the corresponding test to reflect the new ordering.Testing
pnpm vitest run src/cli/commands/gitignore.test.ts src/cli/commands/gitignore-entries.test.tsand the two test files passed (all assertions succeeded).pnpm cicheckwhich completed successfully including formatting, linting, typecheck, the full test suite (all tests passed), and content checks (cspellandsecretlint).Codex Task