Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions pr_description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Fixes #4647

## Problem

The .rooignore file was not properly excluding files in nested project folders. For example, when a user had:

```
Root Folder/
├── .rooignore (contains "example-nextjs/.next/")
└── example-nextjs/
└── .next/ (should be ignored but wasn't)
```

The .next folder was still being indexed despite being listed in the .rooignore file.

## Root Cause

The DirectoryScanner was creating a new RooIgnoreController with the directory being scanned as the working directory, instead of using the workspace root. This meant the .rooignore file was being looked for in the wrong location.

## Solution

- Modified DirectoryScanner to accept an optional workspaceRoot parameter
- Updated the scanner to use the workspace root (instead of scan directory) for the RooIgnoreController
- Updated CodeIndexServiceFactory to pass the workspace path to the scanner
- Added fallback behavior for backward compatibility

## Changes

- src/services/code-index/processors/scanner.ts: Added workspaceRoot parameter and updated RooIgnoreController initialization
- src/services/code-index/service-factory.ts: Pass workspacePath to DirectoryScanner constructor
- src/services/code-index/processors/**tests**/scanner.spec.ts: Updated test to include new parameter

## Testing

- Existing tests continue to pass
- The fix ensures .rooignore files in the workspace root properly filter files in nested directories
- Backward compatibility maintained with fallback to scan directory if no workspace root provided
760 changes: 760 additions & 0 deletions roo-code-messages.log

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ describe("DirectoryScanner", () => {
mockCodeParser,
mockCacheManager,
mockIgnoreInstance,
"/mock/workspace", // Add workspace root parameter
)

// Mock default implementations - create proper Stats object
Expand Down
7 changes: 5 additions & 2 deletions src/services/code-index/processors/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class DirectoryScanner implements IDirectoryScanner {
private readonly codeParser: ICodeParser,
private readonly cacheManager: CacheManager,
private readonly ignoreInstance: Ignore,
private readonly workspaceRoot?: string,
) {}

/**
Expand All @@ -53,8 +54,10 @@ export class DirectoryScanner implements IDirectoryScanner {
// Filter out directories (marked with trailing '/')
const filePaths = allPaths.filter((p) => !p.endsWith("/"))

// Initialize RooIgnoreController if not provided
const ignoreController = new RooIgnoreController(directoryPath)
// Initialize RooIgnoreController with workspace root (not the directory being scanned)
// This ensures .rooignore files are always looked for in the workspace root
const rooIgnoreWorkingDirectory = this.workspaceRoot || directoryPath
const ignoreController = new RooIgnoreController(rooIgnoreWorkingDirectory)

await ignoreController.initialize()

Expand Down
9 changes: 8 additions & 1 deletion src/services/code-index/service-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,14 @@ export class CodeIndexServiceFactory {
parser: ICodeParser,
ignoreInstance: Ignore,
): DirectoryScanner {
return new DirectoryScanner(embedder, vectorStore, parser, this.cacheManager, ignoreInstance)
return new DirectoryScanner(
embedder,
vectorStore,
parser,
this.cacheManager,
ignoreInstance,
this.workspacePath,
)
}

/**
Expand Down
53 changes: 53 additions & 0 deletions test-rooignore-issue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Test script to reproduce the .rooignore issue with nested project folders
const path = require("path")

// Simulate the issue scenario
const rootFolder = "/Users/test/Root Folder"
const nextjsProject = "/Users/test/Root Folder/example-nextjs"
const nextFolder = "/Users/test/Root Folder/example-nextjs/.next"

// Test the path normalization logic from RooIgnoreController
function testPathNormalization(cwd, filePath) {
console.log(`\nTesting path normalization:`)
console.log(`CWD: ${cwd}`)
console.log(`File path: ${filePath}`)

// This is the logic from RooIgnoreController.validateAccess()
const absolutePath = path.resolve(cwd, filePath)
console.log(`Absolute path: ${absolutePath}`)

const relativePath = path.relative(cwd, absolutePath)
console.log(`Relative path: ${relativePath}`)

// Convert to POSIX (forward slashes)
const posixPath = relativePath.replace(/\\/g, "/")
console.log(`POSIX path: ${posixPath}`)

return posixPath
}

// Test case 1: .rooignore in root folder, trying to ignore nested .next folder
console.log("=== Test Case 1: .rooignore in Root Folder ===")
const rooignorePattern = "example-nextjs/.next/"
const fileToCheck = "example-nextjs/.next/server/pages/index.js"

const normalizedPath = testPathNormalization(rootFolder, fileToCheck)
console.log(`\nPattern in .rooignore: ${rooignorePattern}`)
console.log(`Normalized file path: ${normalizedPath}`)
console.log(`Should match pattern: ${normalizedPath.startsWith(rooignorePattern.replace(/\/$/, ""))}`)

// Test case 2: What if the file path is already absolute?
console.log("\n=== Test Case 2: Absolute file path ===")
const absoluteFileToCheck = path.join(nextjsProject, ".next/server/pages/index.js")
const normalizedPath2 = testPathNormalization(rootFolder, absoluteFileToCheck)
console.log(`\nPattern in .rooignore: ${rooignorePattern}`)
console.log(`Normalized file path: ${normalizedPath2}`)
console.log(`Should match pattern: ${normalizedPath2.startsWith(rooignorePattern.replace(/\/$/, ""))}`)

// Test case 3: What if we're scanning from the nextjs project directory?
console.log("\n=== Test Case 3: Scanning from nextjs project directory ===")
const fileInNext = ".next/server/pages/index.js"
const normalizedPath3 = testPathNormalization(nextjsProject, fileInNext)
console.log(`\nIf .rooignore was in nextjs project with pattern: .next/`)
console.log(`Normalized file path: ${normalizedPath3}`)
console.log(`Should match pattern: ${normalizedPath3.startsWith(".next/")}`)
Loading