Files
Auditor/theauditor/commands/full.py
TheAuditorTool c7a59e420b Fix: Critical Windows ProcessPoolExecutor hang and documentation drift
Fixed critical Windows compatibility issues and updated outdated documentation.

  CRITICAL WINDOWS HANG FIXES:
  1. ProcessPoolExecutor → ThreadPoolExecutor
     - Fixes PowerShell/terminal hang where Ctrl+C wouldn't work
     - Prevents .pf directory lock requiring Task Manager kill
     - Root cause: Nested ProcessPool + ThreadPool on Windows creates kernel deadlock

  2. Ctrl+C Interruption Support
     - Replaced subprocess.run with Popen+poll pattern (industry standard)
     - Poll subprocess every 100ms for interruption checking
     - Added global stop_event and signal handlers for graceful shutdown
     - Root cause: subprocess.run blocks threads with no signal propagation

  DOCUMENTATION DRIFT FIX:
  - Removed hardcoded "14 phases" references (actual is 19+ commands)
  - Updated to "multiple analysis phases" throughout all docs
  - Fixed CLI help text to be version-agnostic
  - Added missing "Summary generation" step in HOWTOUSE.md

  Changes:
  - pipelines.py: ProcessPoolExecutor → ThreadPoolExecutor, added Popen+poll pattern
  - Added signal handling and run_subprocess_with_interrupt() function
  - commands/full.py: Updated docstring to remove specific phase count
  - README.md: Changed "14 distinct phases" to "multiple analysis phases"
  - HOWTOUSE.md: Updated phase references, added missing summary step
  - CLAUDE.md & ARCHITECTURE.md: Removed hardcoded phase counts

  Impact: Critical UX fixes - Windows compatibility restored, pipeline interruptible
  Testing: Ctrl+C works, no PowerShell hangs, .pf directory deletable
2025-09-09 14:26:18 +07:00

90 lines
3.6 KiB
Python

"""Run complete audit pipeline."""
import sys
import click
from theauditor.utils.error_handler import handle_exceptions
from theauditor.utils.exit_codes import ExitCodes
@click.command()
@handle_exceptions
@click.option("--root", default=".", help="Root directory to analyze")
@click.option("--quiet", is_flag=True, help="Minimal output")
@click.option("--exclude-self", is_flag=True, help="Exclude TheAuditor's own files (for self-testing)")
@click.option("--offline", is_flag=True, help="Skip network operations (deps, docs)")
def full(root, quiet, exclude_self, offline):
"""Run complete audit pipeline with multiple analysis phases organized in parallel stages."""
from theauditor.pipelines import run_full_pipeline
# Define log callback for console output
def log_callback(message, is_error=False):
if is_error:
click.echo(message, err=True)
else:
click.echo(message)
# Run the pipeline
result = run_full_pipeline(
root=root,
quiet=quiet,
exclude_self=exclude_self,
offline=offline,
log_callback=log_callback if not quiet else None
)
# Display clear status message based on results
findings = result.get("findings", {})
critical = findings.get("critical", 0)
high = findings.get("high", 0)
medium = findings.get("medium", 0)
low = findings.get("low", 0)
click.echo("\n" + "=" * 60)
click.echo("AUDIT FINAL STATUS")
click.echo("=" * 60)
# Determine overall status and exit code
exit_code = ExitCodes.SUCCESS
# Check for pipeline failures first
if result["failed_phases"] > 0:
click.echo(f"[WARNING] Pipeline completed with {result['failed_phases']} phase failures")
click.echo("Some analysis phases could not complete successfully.")
exit_code = ExitCodes.TASK_INCOMPLETE # Exit code for pipeline failures
# Then check for security findings
if critical > 0:
click.echo(f"\nSTATUS: [CRITICAL] - Audit complete. Found {critical} critical vulnerabilities.")
click.echo("Immediate action required - deployment should be blocked.")
exit_code = ExitCodes.CRITICAL_SEVERITY # Exit code for critical findings
elif high > 0:
click.echo(f"\nSTATUS: [HIGH] - Audit complete. Found {high} high-severity issues.")
click.echo("Priority remediation needed before next release.")
if exit_code == ExitCodes.SUCCESS:
exit_code = ExitCodes.HIGH_SEVERITY # Exit code for high findings (unless already set for failures)
elif medium > 0 or low > 0:
click.echo(f"\nSTATUS: [MODERATE] - Audit complete. Found {medium} medium and {low} low issues.")
click.echo("Schedule fixes for upcoming sprints.")
else:
click.echo("\nSTATUS: [CLEAN] - No critical or high-severity issues found.")
click.echo("Codebase meets security and quality standards.")
# Show findings breakdown if any exist
if critical + high + medium + low > 0:
click.echo("\nFindings breakdown:")
if critical > 0:
click.echo(f" - Critical: {critical}")
if high > 0:
click.echo(f" - High: {high}")
if medium > 0:
click.echo(f" - Medium: {medium}")
if low > 0:
click.echo(f" - Low: {low}")
click.echo("\nReview the chunked data in .pf/readthis/ for complete findings.")
click.echo("=" * 60)
# Exit with appropriate code for CI/CD automation
# Using standardized exit codes from ExitCodes class
if exit_code != ExitCodes.SUCCESS:
sys.exit(exit_code)