From ec40a824e15ddb4f8a2f0a0bb61bd779927770ce Mon Sep 17 00:00:00 2001 From: Pascal Pothmann Date: Mon, 22 Jun 2026 13:44:14 +0200 Subject: [PATCH] feat(cli): add --compare-to option to override stored commit hash for incremental updates --- README.md | 4 +++ codewiki/cli/commands/generate.py | 48 ++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index f70c925e..5ac094d6 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,10 @@ codewiki generate --create-branch --github-pages --verbose # Incremental update (only regenerate changed modules since last run) codewiki generate --update + +# Incremental update using a specific commit hash to compare against (useful in CI/CD or squashed PRs) +# This overrides the stored commit hash in metadata.json and implicitly enables --update +codewiki generate --compare-to ``` ### Customization Options diff --git a/codewiki/cli/commands/generate.py b/codewiki/cli/commands/generate.py index 1c370cb8..48445ab1 100644 --- a/codewiki/cli/commands/generate.py +++ b/codewiki/cli/commands/generate.py @@ -43,7 +43,8 @@ def _detect_changed_files( repo_path: Path, output_dir: Path, logger, - verbose: bool + verbose: bool, + compare_to: Optional[str] = None ) -> Optional[List[str]]: """ Detect files changed since the last documentation generation. @@ -57,21 +58,25 @@ def _detect_changed_files( """ import json - metadata_path = output_dir / "metadata.json" - if not metadata_path.exists(): - if verbose: - logger.debug("No metadata.json found — cannot detect changes, running full generation.") - return None - - try: - metadata = json.loads(metadata_path.read_text()) - prev_commit = metadata.get("generation_info", {}).get("commit_id") - if not prev_commit: + prev_commit = None + if compare_to: + prev_commit = compare_to + else: + metadata_path = output_dir / "metadata.json" + if not metadata_path.exists(): if verbose: - logger.debug("No commit_id in metadata — running full generation.") + logger.debug("No metadata.json found — cannot detect changes, running full generation.") + return None + + try: + metadata = json.loads(metadata_path.read_text()) + prev_commit = metadata.get("generation_info", {}).get("commit_id") + if not prev_commit: + if verbose: + logger.debug("No commit_id in metadata — running full generation.") + return None + except (json.JSONDecodeError, OSError): return None - except (json.JSONDecodeError, OSError): - return None # Get current HEAD commit try: @@ -295,6 +300,12 @@ def _find_affected(tree, parent_names=None): is_flag=True, help="Incremental update: only regenerate modules affected by changes since last generation", ) +@click.option( + "--compare-to", + type=str, + default=None, + help="Commit hash to compare against for incremental updates (overrides stored commit in metadata.json)", +) @click.pass_context def generate_command( ctx, @@ -312,7 +323,8 @@ def generate_command( max_token_per_module: Optional[int], max_token_per_leaf_module: Optional[int], max_depth: Optional[int], - update: bool = False + update: bool = False, + compare_to: Optional[str] = None ): """ Generate comprehensive documentation for a code repository. @@ -416,10 +428,14 @@ def generate_command( logger.success(f"Output directory: {output_dir}") + # If a base commit is specified to compare against, implicitly enable update + if compare_to: + update = True + # Incremental update: detect changed files and selectively regenerate changed_files = None if update and output_dir.exists(): - changed_files = _detect_changed_files(repo_path, output_dir, logger, verbose) + changed_files = _detect_changed_files(repo_path, output_dir, logger, verbose, compare_to=compare_to) if changed_files is not None and len(changed_files) == 0: logger.success("No changes detected since last generation. Documentation is up to date.") sys.exit(EXIT_SUCCESS)