Skip to content

Commit 050dd26

Browse files
authored
Merge pull request #80 from FSoft-AI4Code/feat/gitignore
automatically apply gitignore rules
2 parents 4c18fac + 403eb7d commit 050dd26

16 files changed

Lines changed: 531 additions & 36 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ MANIFEST
3838
htmlcov/
3939
.tox/
4040
.hypothesis/
41-
tests/
41+
tests/*
42+
!tests/test_gitignore_filtering.py
4243

4344
# Jupyter
4445
*.ipynb

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ codewiki generate --focus "src/core,src/api" --doc-type architecture
221221

222222
# Add custom instructions for the AI agent
223223
codewiki generate --instructions "Focus on public APIs and include usage examples"
224+
225+
# Analyze files ignored by Git (Git ignore filtering is enabled by default)
226+
codewiki generate --no-gitignore
224227
```
225228

226229
#### Pattern Behavior (Important!)
@@ -238,6 +241,12 @@ codewiki generate --instructions "Focus on public APIs and include usage example
238241
- Glob patterns: `*.test.js`, `*_test.py`, `*.min.*`
239242
- Directory patterns: `build/`, `dist/`, `coverage/`
240243

244+
- **`--use-gitignore/--no-gitignore`**: Git ignore rules are applied by default
245+
- Root and nested `.gitignore` files are respected before call-graph analysis
246+
- Tracked files remain included, matching Git behavior
247+
- Built-in and explicit `--exclude` patterns still apply when Git includes a path
248+
- Use `codewiki config set --no-gitignore` to persistently disable this behavior
249+
241250
#### Setting Persistent Defaults
242251

243252
Save your preferred settings as defaults:
@@ -266,6 +275,7 @@ codewiki config agent --clear
266275
|--------|-------------|----------|---------|
267276
| `--include` | File patterns to include | **Replaces** defaults | `*.cs`, `*.py`, `src/**/*.ts` |
268277
| `--exclude` | Patterns to exclude | **Merges** with defaults | `Tests,Specs`, `*.test.js`, `build/` |
278+
| `--use-gitignore/--no-gitignore` | Apply Git ignore rules | Enabled by default | `--no-gitignore` |
269279
| `--focus` | Modules to document in detail | Standalone option | `src/core,src/api` |
270280
| `--doc-type` | Documentation style | Standalone option | `api`, `architecture`, `user-guide`, `developer` |
271281
| `--instructions` | Custom agent instructions | Standalone option | Free-form text |

codewiki/cli/adapters/doc_generator.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ def generate(self) -> DocumentationJob:
146146
max_token_per_module=self.config.get('max_token_per_module', 36369),
147147
max_token_per_leaf_module=self.config.get('max_token_per_leaf_module', 16000),
148148
max_depth=self.config.get('max_depth', 2),
149-
agent_instructions=self.config.get('agent_instructions')
149+
agent_instructions=self.config.get('agent_instructions'),
150+
use_gitignore=self.config.get('use_gitignore', True),
150151
)
151152

152153
# Run backend documentation generation

codewiki/cli/commands/config.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ def config_group():
111111
type=str,
112112
help="Azure OpenAI deployment name"
113113
)
114+
@click.option(
115+
"--use-gitignore/--no-gitignore",
116+
default=None,
117+
help="Apply Git ignore rules during repository analysis (default: enabled)",
118+
)
114119
def config_set(
115120
api_key: Optional[str],
116121
base_url: Optional[str],
@@ -124,7 +129,8 @@ def config_set(
124129
provider: Optional[str] = None,
125130
aws_region: Optional[str] = None,
126131
api_version: Optional[str] = None,
127-
azure_deployment: Optional[str] = None
132+
azure_deployment: Optional[str] = None,
133+
use_gitignore: Optional[bool] = None,
128134
):
129135
"""
130136
Set configuration values for CodeWiki.
@@ -170,10 +176,14 @@ def config_set(
170176
\b
171177
# Set max depth for hierarchical decomposition
172178
$ codewiki config set --max-depth 3
179+
180+
\b
181+
# Persistently disable Git ignore filtering
182+
$ codewiki config set --no-gitignore
173183
"""
174184
try:
175185
# Check if at least one option is provided
176-
if not any([api_key, base_url, main_model, cluster_model, fallback_model, max_tokens, max_token_per_module, max_token_per_leaf_module, max_depth, provider, aws_region, api_version, azure_deployment]):
186+
if not any([api_key, base_url, main_model, cluster_model, fallback_model, max_tokens, max_token_per_module, max_token_per_leaf_module, max_depth, provider, aws_region, api_version, azure_deployment, use_gitignore is not None]):
177187
click.echo("No options provided. Use --help for usage information.")
178188
sys.exit(EXIT_CONFIG_ERROR)
179189

@@ -237,6 +247,9 @@ def config_set(
237247
if azure_deployment is not None:
238248
validated_data['azure_deployment'] = azure_deployment
239249

250+
if use_gitignore is not None:
251+
validated_data['use_gitignore'] = use_gitignore
252+
240253
# Create config manager and save
241254
manager = ConfigManager()
242255
manager.load() # Load existing config if present
@@ -254,7 +267,8 @@ def config_set(
254267
provider=validated_data.get('provider'),
255268
aws_region=validated_data.get('aws_region'),
256269
api_version=validated_data.get('api_version'),
257-
azure_deployment=validated_data.get('azure_deployment')
270+
azure_deployment=validated_data.get('azure_deployment'),
271+
use_gitignore=validated_data.get('use_gitignore'),
258272
)
259273

260274
# Display success messages
@@ -315,6 +329,9 @@ def config_set(
315329
if azure_deployment:
316330
click.secho(f"✓ Azure Deployment: {azure_deployment}", fg="green")
317331

332+
if use_gitignore is not None:
333+
click.secho(f"✓ Use gitignore: {use_gitignore}", fg="green")
334+
318335
click.echo("\n" + click.style("Configuration updated successfully.", fg="green", bold=True))
319336

320337
except ConfigurationError as e:
@@ -375,6 +392,7 @@ def config_show(output_json: bool):
375392
"max_token_per_module": config.max_token_per_module if config else 36369,
376393
"max_token_per_leaf_module": config.max_token_per_leaf_module if config else 16000,
377394
"max_depth": config.max_depth if config else 2,
395+
"use_gitignore": config.use_gitignore if config else True,
378396
"agent_instructions": config.agent_instructions.to_dict() if config and config.agent_instructions else {},
379397
"config_file": str(manager.config_file_path)
380398
}
@@ -435,6 +453,7 @@ def config_show(output_json: bool):
435453
click.secho("Decomposition Settings", fg="cyan", bold=True)
436454
if config:
437455
click.echo(f" Max Depth: {config.max_depth}")
456+
click.echo(f" Use Gitignore: {config.use_gitignore}")
438457

439458
click.echo()
440459
click.secho("Agent Instructions", fg="cyan", bold=True)
@@ -859,4 +878,3 @@ def config_agent(
859878
sys.exit(e.exit_code)
860879
except Exception as e:
861880
sys.exit(handle_error(e))
862-

codewiki/cli/commands/generate.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@ def _find_affected(tree, parent_names=None):
266266
default=None,
267267
help="Custom instructions for the documentation agent",
268268
)
269+
@click.option(
270+
"--use-gitignore/--no-gitignore",
271+
default=None,
272+
help="Apply Git ignore rules during analysis (default: enabled)",
273+
)
269274
@click.option(
270275
"--verbose",
271276
"-v",
@@ -319,6 +324,7 @@ def generate_command(
319324
focus: Optional[str],
320325
doc_type: Optional[str],
321326
instructions: Optional[str],
327+
use_gitignore: Optional[bool],
322328
verbose: bool,
323329
max_tokens: Optional[int],
324330
max_token_per_module: Optional[int],
@@ -346,6 +352,10 @@ def generate_command(
346352
\b
347353
# Force full regeneration
348354
$ codewiki generate --no-cache
355+
356+
\b
357+
# Analyze ignored files as well
358+
$ codewiki generate --no-gitignore
349359
350360
\b
351361
# C# project: only .cs files, exclude tests
@@ -521,10 +531,12 @@ def generate_command(
521531
effective_max_token_per_module = max_token_per_module if max_token_per_module is not None else config.max_token_per_module
522532
effective_max_token_per_leaf = max_token_per_leaf_module if max_token_per_leaf_module is not None else config.max_token_per_leaf_module
523533
effective_max_depth = max_depth if max_depth is not None else config.max_depth
534+
effective_use_gitignore = use_gitignore if use_gitignore is not None else config.use_gitignore
524535
logger.debug(f"Max tokens: {effective_max_tokens}")
525536
logger.debug(f"Max token/module: {effective_max_token_per_module}")
526537
logger.debug(f"Max token/leaf module: {effective_max_token_per_leaf}")
527538
logger.debug(f"Max depth: {effective_max_depth}")
539+
logger.debug(f"Use gitignore: {effective_use_gitignore}")
528540

529541
# Get agent instructions (merge runtime with persistent)
530542
agent_instructions_dict = None
@@ -562,6 +574,8 @@ def generate_command(
562574
'max_token_per_leaf_module': max_token_per_leaf_module if max_token_per_leaf_module is not None else config.max_token_per_leaf_module,
563575
# Max depth setting (runtime override takes precedence)
564576
'max_depth': max_depth if max_depth is not None else config.max_depth,
577+
# Gitignore setting (runtime override takes precedence)
578+
'use_gitignore': use_gitignore if use_gitignore is not None else config.use_gitignore,
565579
},
566580
verbose=verbose,
567581
generate_html=github_pages,
@@ -629,4 +643,3 @@ def generate_command(
629643
sys.exit(130)
630644
except Exception as e:
631645
sys.exit(handle_error(e, verbose=verbose))
632-

codewiki/cli/config_manager.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ def save(
135135
provider: Optional[str] = None,
136136
aws_region: Optional[str] = None,
137137
api_version: Optional[str] = None,
138-
azure_deployment: Optional[str] = None
138+
azure_deployment: Optional[str] = None,
139+
use_gitignore: Optional[bool] = None,
139140
):
140141
"""
141142
Save configuration to file and keyring.
@@ -155,6 +156,7 @@ def save(
155156
aws_region: AWS region for Bedrock provider
156157
api_version: Azure OpenAI API version
157158
azure_deployment: Azure OpenAI deployment name
159+
use_gitignore: Apply Git ignore rules during repository analysis
158160
"""
159161
# Ensure config directory exists
160162
try:
@@ -204,6 +206,8 @@ def save(
204206
self._config.api_version = api_version
205207
if azure_deployment is not None:
206208
self._config.azure_deployment = azure_deployment
209+
if use_gitignore is not None:
210+
self._config.use_gitignore = use_gitignore
207211

208212
# Validate configuration whenever the minimum required fields are set.
209213
# Caw providers only need main_model; API providers need base_url +
@@ -330,4 +334,3 @@ def keyring_available(self) -> bool:
330334
def config_file_path(self) -> Path:
331335
"""Get configuration file path."""
332336
return CONFIG_FILE
333-

codewiki/cli/models/config.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class Configuration:
121121
max_token_per_module: Maximum tokens per module for clustering (default: 36369)
122122
max_token_per_leaf_module: Maximum tokens per leaf module (default: 16000)
123123
max_depth: Maximum depth for hierarchical decomposition (default: 2)
124+
use_gitignore: Apply Git ignore rules during repository analysis
124125
agent_instructions: Custom agent instructions for documentation generation
125126
"""
126127
base_url: str
@@ -136,6 +137,7 @@ class Configuration:
136137
max_token_per_module: int = 36369
137138
max_token_per_leaf_module: int = 16000
138139
max_depth: int = 2
140+
use_gitignore: bool = True
139141
agent_instructions: AgentInstructions = field(default_factory=AgentInstructions)
140142

141143
def validate(self):
@@ -172,6 +174,7 @@ def to_dict(self) -> dict:
172174
'max_token_per_module': self.max_token_per_module,
173175
'max_token_per_leaf_module': self.max_token_per_leaf_module,
174176
'max_depth': self.max_depth,
177+
'use_gitignore': self.use_gitignore,
175178
'fallback_model': self.fallback_model,
176179
}
177180
if self.agent_instructions and not self.agent_instructions.is_empty():
@@ -207,6 +210,7 @@ def from_dict(cls, data: dict) -> 'Configuration':
207210
max_token_per_module=data.get('max_token_per_module', 36369),
208211
max_token_per_leaf_module=data.get('max_token_per_leaf_module', 16000),
209212
max_depth=data.get('max_depth', 2),
213+
use_gitignore=data.get('use_gitignore', True),
210214
agent_instructions=agent_instructions,
211215
)
212216

@@ -273,6 +277,6 @@ def to_backend_config(self, repo_path: str, output_dir: str, api_key: str, runti
273277
max_token_per_module=self.max_token_per_module,
274278
max_token_per_leaf_module=self.max_token_per_leaf_module,
275279
max_depth=self.max_depth,
276-
agent_instructions=final_instructions.to_dict() if final_instructions else None
280+
agent_instructions=final_instructions.to_dict() if final_instructions else None,
281+
use_gitignore=self.use_gitignore,
277282
)
278-

codewiki/mcp/server.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ def _fine_grained_tools() -> list[Tool]:
102102
"type": "string",
103103
"description": "Comma-separated patterns to exclude (e.g., '*test*,*spec*')",
104104
},
105+
"use_gitignore": {
106+
"type": "boolean",
107+
"description": "Apply Git ignore rules before analysis (default: true)",
108+
"default": True,
109+
},
105110
},
106111
"required": ["repo_path"],
107112
},
@@ -320,6 +325,11 @@ def _legacy_tools() -> list[Tool]:
320325
"type": "string",
321326
"description": "Comma-separated patterns to exclude",
322327
},
328+
"use_gitignore": {
329+
"type": "boolean",
330+
"description": "Apply Git ignore rules before analysis (default: true)",
331+
"default": True,
332+
},
323333
},
324334
"required": ["repo_path"],
325335
},
@@ -489,6 +499,7 @@ async def _legacy_generate_docs(arguments: dict[str, Any]) -> list[TextContent]:
489499
aws_region=getattr(config, "aws_region", "us-east-1"),
490500
max_tokens=config.max_tokens,
491501
agent_instructions=agent_instructions or None,
502+
use_gitignore=arguments.get("use_gitignore", True),
492503
)
493504

494505
from codewiki.cli.utils.repo_validator import get_git_commit_hash

codewiki/mcp/tools/analysis.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ def handle_analyze_repo(
304304
llm_api_key="not-needed",
305305
main_model="unused",
306306
cluster_model="unused",
307+
use_gitignore=arguments.get("use_gitignore", True),
307308
)
308309

309310
# Apply optional include/exclude patterns

0 commit comments

Comments
 (0)