This document explains the internal processing workflow of Path Header Scanner.
It describes:
- execution stages
- path resolution
- language strategy resolution
- header validation
- file updates
- result aggregation
- logging flow
parse CLI arguments
↓
resolve target path
↓
scan source files
↓
resolve language strategy
↓
extract existing header
↓
generate expected header
↓
validate header
↓
insert/update if needed
↓
collect processing results
↓
display summary
CLI Command
↓
Typer Argument Parsing
↓
Path Resolution
↓
File Scanning
↓
Language Strategy Resolution
↓
File Processing
↓
Header Validation
↓
File Update (optional)
↓
Result Aggregation
↓
Summary Reporting
The workflow begins from:
app/cli/main.pyThe CLI is implemented using:
- Typer
- pathlib
- structured logging
Main command:
path-header-scanner scan TARGET_DIRECTORYThe CLI layer is responsible for:
- parsing arguments
- parsing options
- initializing strategies
- resolving paths
- creating scanner and processor instances
- displaying summaries
| Option | Purpose |
|---|---|
--apply |
Write file changes |
--debug |
Enable debug logging |
--workdir |
Custom working directory |
--include-target-directory |
Include scan target in headers |
--exclude-target-directory |
Exclude scan target from headers |
The target directory is resolved using:
resolve_target_path()Responsibilities:
- normalize paths
- support Docker workspaces
- support custom workdirs
- resolve relative paths safely
Resolution priority:
absolute path
↓
working directory
↓
current working directory
↓
Docker workspace
↓
direct relative path
Input:
scan appDocker runtime:
-w /workspaceResolved path:
/workspace/app
The CLI initializes:
FileScannerwith:
- resolved root directory
- language strategies
- ignored directories
The scanner:
- recursively walks directories
- skips ignored directories
- filters supported extensions
- returns matching source files
Ignored by default:
.git
.venv
venv
__pycache__
node_modules
dist
build
Scanning uses:
Path.rglob("*")Workflow:
walk directories
↓
skip ignored paths
↓
check supported extensions
↓
collect matching files
↓
sort files
↓
return file list
Each file is matched against a language strategy.
Example:
main.py
↓
PythonLanguageStrategy
| Strategy | Extensions |
|---|---|
| PythonLanguageStrategy | .py |
| JavaScriptLanguageStrategy | .js, .jsx, .ts, .tsx |
| ShellLanguageStrategy | .sh, .bash, .zsh |
| PhpLanguageStrategy | .php |
| HtmlLanguageStrategy | .html, .htm |
| MarkdownLanguageStrategy | .md, .markdown |
Strategies define:
- supported extensions
- comment syntax
- header extraction
- insertion handling
- special-line preservation
Each discovered file is processed individually.
Workflow:
read file
↓
split into lines
↓
extract current header
↓
generate expected header
↓
compare headers
↓
insert/update if needed
↓
return processing result
Each strategy determines whether a file already contains a header.
Examples:
Python:
# app/main.pyJavaScript:
// app/main.jsHTML:
<!-- app/index.html -->Some languages require preserving special lines.
Preserved:
- shebang lines
- encoding declarations
Example:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# app/main.pyPreserved:
- shebangs
<?php
Example:
<?php
// app/index.phpPreserved:
- shebang lines
Example:
#!/bin/bash
# scripts/build.shExpected headers are generated using:
build_header()based on relative file paths.
Default behavior:
# app/cli/main.pyEnabled using:
--include-target-directoryAlternative behavior:
# cli/main.pyEnabled using:
--exclude-target-directoryresolve relative path
↓
apply include/exclude logic
↓
convert to POSIX path
↓
prepend comment syntax
↓
return formatted header
The current header is compared against the expected header.
Possible outcomes:
| State | Meaning |
|---|---|
| VALID | Header already correct |
| UPDATED | Existing header replaced |
| INSERTED | Missing header inserted |
| FAILED | Processing error occurred |
extract current header
↓
compare with expected header
↓
determine result state
Example:
# app/main.pyalready matches expected output.
No update required.
Example:
Before:
# old/path.pyAfter:
# app/main.pyExample:
Before:
print("hello")After:
# app/main.py
print("hello")Failures may occur due to:
- encoding issues
- permissions
- invalid filesystem state
- unexpected exceptions
Failures are captured safely using:
try/exceptUpdates are only written when:
--applyis enabled.
Default behavior:
path-header-scanner scan appNo files modified.
path-header-scanner scan app --applyFiles updated on disk.
The updater safely rebuilds file content:
preserve special lines
↓
insert/replace header
↓
preserve remaining content
↓
normalize trailing newline
Each processed file returns:
FileProcessResultcontaining:
- file path
- status
- expected header
- current header
- messages
The processor aggregates results:
VALID
UPDATED
INSERTED
FAILED
and generates final statistics.
SUMMARY
Valid: 22
Updated: 1
Inserted: 1
Failed: 0
The project uses structured logging.
| Level | Purpose |
|---|---|
| DEBUG | detailed processing |
| INFO | summaries and updates |
| WARNING | recoverable issues |
| ERROR | failures |
| Status | Logging Level |
|---|---|
| VALID | DEBUG |
| UPDATED | INFO |
| INSERTED | INFO |
| FAILED | ERROR |
Typical Docker execution:
build image
↓
mount workspace
↓
set working directory
↓
run scanner
↓
modify mounted files
↓
remove container
Example:
docker run -it --rm \
-w /workspace \
-v "${PWD}:/workspace" \
path-header-scanner \
scan appPath resolution:
host project
↓
mounted to /workspace
↓
scan app
↓
resolved to /workspace/app
Example:
make docker-debugexpands internally to:
docker run -it --rm \
-w /workspace \
-v "$(CURDIR):/workspace" \
path-header-scanner \
scan app --debugErrors are isolated per file.
Workflow:
process file
↓
exception raised
↓
log exception
↓
return FAILED result
↓
continue processing remaining files
This prevents a single failure from stopping the full scan.
Recommended practices for large repositories:
- use INFO summaries only
- log VALID files in DEBUG mode
- avoid excessive console output
- use mounted workspaces
- prefer dry-run before apply
Potential future improvements:
- parallel processing
- progress bars
- configuration files
- incremental scanning
- cache support
- Git integration
- pre-commit hooks
- plugin system
- File processing is deterministic.
- Relative paths use POSIX separators.
- File updates preserve trailing newlines.
- Language strategies remain isolated and reusable.
- Docker workflows are optimized for mounted workspace development.