feat: add multi-folder indexing with dynamic add/remove capabilities - #60
Merged
bartolli merged 1 commit intoOct 29, 2025
Conversation
Enables indexing multiple directories simultaneously with persistent configuration and automatic cleanup of removed folders. New CLI commands: - codanna add-folder <PATH> - Add folder to indexed paths - codanna remove-folder <PATH> - Remove folder from indexed paths - codanna list-folders - List all indexed folders - codanna clean - Clean up symbols from removed folders Enhanced commands: - codanna index [PATHS...] - Now accepts multiple paths, uses config when no paths provided, and automatically cleans removed folders Core implementation: - Added indexed_paths configuration field - Path canonicalization prevents duplicates - Automatic cleanup when folders removed - Backward compatible (requires explicit paths when not configured) Testing: - 10 new integration tests for multi-folder scenarios - 8 new unit tests for configuration management - Windows path compatibility fixed in tests - All clippy checks passing Documentation: - Updated CLI reference with all new commands - Added multi-folder indexing guide to configuration docs - Included usage examples for common workflows 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Owner
|
This looks good. I’ll review and merge both of your PRs today. I’m finishing testing a profile system that allows easily applying reusable, project-specific files and utilities. |
bartolli
added a commit
that referenced
this pull request
Oct 29, 2025
- added ConfigFileWatcher for settings.toml monitoring in HTTP/HTTPS modes - added sync_with_config to compare settings with index metadata on every command - settings.toml is source of truth, index metadata is derived state - sync automatically indexes new directories and removes symbols from removed directories - removed clean command (now redundant with automatic sync) - removed clean_removed_paths method from SimpleIndexer - deleted test_multi_folder_indexing.rs (tested manual cleanup, now automatic) - FileWatcher now tracks config file changes in addition to source files - fixed batch management in remove_file to be self-contained Related to PR #60
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Multi-Folder Indexing Support
Description
This PR implements multi-folder indexing support for codanna, allowing users to index multiple directories simultaneously and dynamically manage which folders are indexed through persistent configuration.
Overview
Previously, codanna could only index a single directory at a time. This feature enables:
This is particularly useful for:
Changes
Core Implementation
1. Configuration Management (src/config.rs)
Added:
indexed_paths: Vec<PathBuf>field toIndexingConfigstructSettings:add_indexed_path()- Adds folder with duplicate detection via canonicalizationremove_indexed_path()- Removes folder by canonical pathget_indexed_paths()- Returns configured paths (empty if not configured)Implementation Details:
PathBuf::canonicalize()to resolve symlinks and prevent duplicate entriesTests Added:
test_add_indexed_path_success- Basic add functionalitytest_add_indexed_path_prevents_duplicates- Duplicate preventiontest_add_indexed_path_canonicalizes- Symlink handlingtest_add_indexed_path_rejects_nonexistent- Error handlingtest_remove_indexed_path_success- Basic remove functionalitytest_remove_indexed_path_not_found- Error handlingtest_get_indexed_paths_defaults_to_current- Default behaviortest_get_indexed_paths_returns_configured- Configured paths retrieval2. CLI Commands (src/main.rs)
Modified
IndexCommand:New Commands:
Enhanced Index Logic:
indexed_pathsfrom config when no arguments providedCommand Handlers:
AddFolder- Validates path, adds to config, saves settingsRemoveFolder- Validates path exists in config, removes, saves settingsListFolders- Displays current indexed paths or "(none configured)" messageClean- Manually triggers cleanup of removed foldersExample Usage:
3. Cleanup Implementation (src/indexing/simple.rs)
Added Fields:
New Methods:
add_indexed_folder(path)- Tracks folders being indexedget_indexed_folders()- Returns set of indexed foldersclean_removed_folders(current_folders)- Removes symbols from folders not in current listCleanup Algorithm:
starts_with()remove_file_documents(file_path)Key Features:
src/utils/whensrc/is configured)4. Document Deletion Enhancement (src/storage/tantivy.rs)
Modified
remove_file_documents():Previously this method existed but wasn't being used effectively for cleanup. Enhanced to:
file_pathtermCritical Fix:
The initial implementation had an issue where deleted symbols still appeared in searches. This was resolved by ensuring
remove_file_documents()creates a temporary writer, commits, and reloads the reader when called outside of a batch context (which is the case during cleanup).Test Coverage
Unit Tests (8 tests in src/config.rs)
All configuration helper methods have unit tests covering:
Integration Tests (10 tests in tests/integration/test_multi_folder_indexing.rs)
Basic Functionality:
test_index_multiple_folders- Indexes 2 folders, verifies symbols from both are searchabletest_add_and_remove_folders_from_config- Tests add/remove commands and config persistencetest_add_folder_indexes_new_symbols- Verifies new symbols appear when folder addedtest_remove_folder_cleans_symbols- Critical test - Verifies symbols disappear when folder removedEdge Cases:
5.
test_nested_folders_no_duplicate_symbols- Tests indexing bothsrc/andsrc/utils/6.
test_overlapping_paths_cleanup_protection- Ensures cleanup doesn't remove from overlapping paths7.
test_symlinks_are_canonicalized- Verifies symlink handling prevents duplicates8.
test_symlink_removal_works_correctly- Tests removal of symlinked foldersConfiguration:
9.
test_index_prevents_duplicate_paths- Verifies duplicate prevention in config10.
test_index_with_no_configured_paths_uses_default- Tests backward compatible behaviorTest Methodology:
Production Testing
Real-World Validation
Testing was performed using open-source .NET repositories:
Test Scenarios Executed
✅ Test 1: Single Folder Baseline
✅ Test 2: Add Second Folder
✅ Test 3: Large Repository
✅ Test 4: Configuration Persistence
list-foldersshows all 3 folderssettings.tomlcontains correct paths✅ Test 5: Folder Removal & Cleanup
✅ Test 6: Clean Command Edge Cases
✅ Test 7: Cross-Folder Search
✅ Test 8: Fourth Folder
✅ Test 9: Index Integrity
indexwithout arguments (uses config)✅ Test 10: Documentation
Performance Results
Issues Found & Resolved
Issue: Symbols Not Being Deleted
remove_file_documents()which deletes by file_path and commits immediatelyBreaking Changes
None - Fully Backward Compatible
indexcommand with single path still works (now accepts multiple paths)indexcommand without arguments requiresindexed_pathsconfiguration (prevents accidental behavior change)Backward Compatibility Fix:
During development, we ensured that
codanna index(without arguments and without configuration) maintains the original behavior of requiring an explicit path argument. This prevents breaking existing scripts that may depend on the error message when no path is provided.Migration Path
Users can adopt multi-folder indexing gradually:
Current workflow (still works):
New multi-folder workflow (opt-in):
codanna add-folder /path/to/project1 codanna add-folder /path/to/project2 codanna index # Uses configured pathsDocumentation Updates
New Quick Start Example
Configuration File
New section in
settings.toml:Code Quality
Static Analysis
cargo fmt --all- No formatting issuescargo clippy --all-targets -- -D warnings- Zero warningsTest Results
Files Changed
Core Implementation (4 files)
src/config.rs- Configuration helpers and storage (+120 lines, +8 tests)src/main.rs- CLI commands and index orchestration (+180 lines)src/indexing/simple.rs- Cleanup algorithm (+95 lines)src/storage/tantivy.rs- Document deletion fix (+5 lines)Tests (2 files)
tests/integration_tests.rs- Module registration (+1 line)tests/integration/test_multi_folder_indexing.rs- New file (+600 lines, 10 tests)Documentation (2 files)
docs/user-guide/cli-reference.md- Updated with new commandsdocs/user-guide/configuration.md- Added multi-folder indexing guideTotal Changes:
User Experience Improvements
Clear Command Output
All commands provide clear feedback:
Error Handling
Descriptive errors for common issues:
$ codanna add-folder /nonexistent Error: Invalid path: No such file or directory (os error 2) $ codanna add-folder /path/to/project Error: Path already indexed: /path/to/project $ codanna remove-folder /not/indexed Error: Path not found in indexed paths: /not/indexedTesting Instructions
For Reviewers
Quick Validation (5 minutes)
Testing
Run the full integration test suite:
cargo test test_multi_folder --test integration_tests -- --nocaptureChecklist
cargo fmtReady for Review ✅