diff --git a/AGENTS.md b/AGENTS.md index 39bd146..cd2cb2c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ Compare AUTOSAR MATLAB/Simulink codegen folders while filtering proven generator noise. Package: compare_tool. Read docs/architecture.md for module ownership and contracts. -## Invariants +## Constraints - An unproven difference is a real change. Scan/read/parse/compare failures are errors, never empty or clean results. - Verdicts: identical, comment-only, ignorable-only, real-change, added, deleted, error. Only noise may be hidden; filtering must not change verdicts, counts or raw report results. - New noise rules must prove both noise-only handling and preservation of a nearby real change. @@ -11,7 +11,15 @@ Package: compare_tool. Read docs/architecture.md for module ownership and contra - HTML reports contain local/inline assets and work offline. - Exit codes: 0 clean, 1 real changes or configured consistency failures, 2 incomplete/error. --exit-zero must never suppress errors. - Graceful UI fallback must not disguise comparison failures. -- Update task-oriented English docs and corresponding docs/vi/ with documented behavior changes. + +## Documentation + +- Write short, direct sentences. Lead with the task or result, avoid marketing language, and link to existing guidance instead of repeating it. +- Keep user guides focused on user tasks, options, constraints, and interpreting results. +- Do not describe transient GUI status text, progress-bar timing or visibility, widget layout, implementation details, or bug-fix history in user guides. +- Put implementation details in maintainer documentation and user-visible fixes in CHANGELOG.md. Update a user guide only when usage, options, constraints, or result interpretation changes. +- Keep architecture documentation focused on the current design, contracts, constraints, and verification entry points. Exclude update history, completed-work lists, validation snapshots, TODOs, and roadmaps. +- Keep English docs and corresponding docs/vi/ synchronized. ## Verification For code changes: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cdafb59..fea2299 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,44 +1,30 @@ # Contributing -Thanks for helping improve the CodeGen Compare Tool. This file is the short -version of what CI enforces; [`docs/architecture.md`](docs/architecture.md) is -the map of how the pieces fit and why. +Read [AGENTS.md](AGENTS.md) for constraints and [Architecture](docs/architecture.md) for module ownership. ## Setup -No install is needed to run the tool or the tests — the core is standard -library only. +From the repository folder: ```bash -git clone https://github.com/longvo92/codegen-compare-tool.git -cd codegen-compare-tool +python -m pip install ruff mypy python -m compare_tool --help ``` -The viewer and its tests need PySide6: +The CLI and core tests need no runtime dependencies. Install the optional viewer for GUI work: ```bash -pip install "PySide6>=6.5" +python -m pip install -e ".[viewer]" ``` -## Two hard constraints +## Change requirements -These are checked automatically ([`tests/test_stdlib_only.py`](tests/test_stdlib_only.py)), -not left to reviewers to remember: +- Support Python 3.8+ and keep the core/zipapp standard-library only. +- Keep Qt imports in `compare_tool/qtviewer/`; shared models must work without Qt. +- Test new noise rules with both a noise-only case and a nearby real change. +- Keep CLI, viewer and report decisions consistent. +- Update task-oriented English/Vietnamese guides when usage changes. Put release notes in [CHANGELOG.md](CHANGELOG.md). -1. **The compare core is standard library only.** Everything under - `compare_tool/` except `compare_tool/qtviewer/` ships inside - `compare_tool.pyz`, the documented fallback for machines where antivirus - blocks the `.exe`. One third-party import there and the zipapp stops running - on exactly those machines. If you genuinely need a library in the core, say - so in the PR — it is a real trade-off (it costs the `.pyz` and the "zero - dependencies" line), not something to slip in. -2. **PySide6 lives only under `compare_tool/qtviewer/`,** imported lazily when - the viewer opens. `tree.py` and `summary_model.py` stay Qt-free so the suite - runs headless. +## Verification -Python 3.8 is a shipped promise: no `match`, no `X | Y` at runtime, and -`list[str]` in an annotation needs `from __future__ import annotations`. - - -Issues and pull requests are welcome. +Run the [checks and relevant smoke tests](docs/architecture.md#verification) before opening a PR. Documentation-only changes need link, example and diff checks. diff --git a/README.md b/README.md index 52906d1..407343b 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,68 @@ -

- CodeGen Compare Tool -

- -

-Test -Python 3.8+ -License: MIT -Release -

- -

🇻🇳 Tiếng Việt

- # CodeGen Compare Tool -Compare two AUTOSAR MATLAB/Simulink code-generation snapshots and focus on the changes that need review. - -The tool filters generator noise that it can prove is harmless, then summarizes changes to generated C/C++, ARXML, RTE access and A2L objects. +[Tiếng Việt](docs/vi/README.md) -> If a difference cannot be proven to be noise, it remains a real change. +Compare AUTOSAR MATLAB/Simulink codegen folders or ZIPs and review C/C++, ARXML, RTE and A2L changes. Only proven generator noise is filtered; unexplained differences remain real changes. ## Quick start -Download `compare-tool.exe` or `compare_tool.pyz` from the [latest release](https://github.com/longvo92/codegen-compare-tool/releases/latest). Both accept the options shown below. +1. Download `compare-tool.exe` from [Releases](https://github.com/longvo92/codegen-compare-tool/releases/latest) and open it. No Python installation is needed. +2. Select BASELINE and CURRENT, then run the comparison. +3. Review changes in the viewer or export an offline HTML report. -To run from source: +For CLI use, download `compare_tool.pyz` and run it with Python 3.8+, or use the source commands below. Replace `python -m compare_tool` with `compare-tool.exe` or `python compare_tool.pyz` for downloaded builds. + +## Run from source ```bash git clone https://github.com/longvo92/codegen-compare-tool.git cd codegen-compare-tool -``` - -For downloaded builds, replace `python -m compare_tool` with `compare-tool.exe` or `python compare_tool.pyz`. - -Check consistency before delivery using one folder or ZIP (new in source; not released yet): - -```bash -python -m compare_tool --check-current current -``` - -This mode runs no diff and writes no HTML. The `delivery` policy gates missing input and unchecked items; existing comparison commands and YAML remain supported. See [usage](docs/usage.md#consistency-check) for mappings and exceptions. - -Create a self-contained HTML report: - -```bash python -m compare_tool baseline current --report report.html ``` -Print only a terminal summary: +The CLI uses only the Python standard library. For the desktop viewer: ```bash -python -m compare_tool baseline current --no-report +python -m pip install -e ".[viewer]" +python -m compare_tool ``` -The terminal mode shows a per-model Overview, AUTOSAR/A2L changes, consistency warnings, effective compare settings, hunk-classification totals and one summary for each non-identical file. Add `--check-consistency` to validate CURRENT generated RTE calls against CURRENT ARXML declarations. It does not print individual hunks, source diffs or create HTML. +Sample inputs: [tests/fixtures/demo](tests/fixtures/demo). -Open the desktop viewer: +## Usage ```bash -python -m compare_tool +python -m compare_tool baseline current --no-report +python -m compare_tool --check-current current ``` -The viewer requires PySide6. The CLI and `compare_tool.pyz` use only the Python standard library. - -Folders and ZIP archives are accepted as inputs. - -## Outputs - -| Output | Use it for | +| Output | Use it to | |---|---| -| Desktop viewer | Interactive side-by-side review | -| HTML report | Sharing or publishing as a CI artifact | -| `--check-current PATH` | CURRENT consistency and coverage before delivery | -| `--no-report` | Detailed terminal review and diagnostics without generated files | -| `--json` | Structured pipeline processing | -| `--sarif` | Code-scanning annotations | - -The comparison engine also reports: - -- model/SWC ownership; -- ports, port interfaces, runnables and events; -- `Rte_*` access points; -- A2L `CHARACTERISTIC` and `MEASUREMENT` objects; -- possible incomplete regeneration across ARXML, A2L and generated C; -- generated RTE calls that disagree with CURRENT ARXML access declarations when `--check-consistency` is enabled. - -Old/new regeneration warnings remain advisory. The optional CURRENT-tree check is disabled by default; when enabled, a `fail` finding exits `1`, an incomplete consistency scan exits `2`, and a `warn` finding does not change the exit code. No consistency result changes a file verdict. - -## Verdicts - -| Verdict | Meaning | -|---|---| -| Modified | A real change needs review | -| Comment | Only comments changed | -| Unimportant | Only proven generator noise changed | -| Added / Deleted | The file exists on one side only | -| Identical | No difference | -| Not compared | The file could not be read or compared | - -## CI exit codes - -| Code | Meaning | -|---:|---| -| `0` | No real changes | -| `1` | Real changes found | -| `2` | Comparison incomplete or failed | +| Desktop viewer | Review changes side by side | +| HTML report | Share results offline or as a CI artifact | +| `--no-report` | Review summaries and diagnostics in the terminal | +| `--check-current PATH` | Check CURRENT RTE/ARXML consistency before delivery | +| `--json` / `--sarif` | Export comparison results for pipelines | -`--exit-zero` suppresses only file-difference failures, never consistency failures or incomplete scans. `--check-current` returns `0` for a policy pass, `1` for failed rules and `2` for incomplete input/scanning or unchecked items under delivery policy. +CURRENT consistency findings are terminal-only; JSON/SARIF exports contain comparison results and old/new advisories. -## Requirements +## Review the results -- Python 3.8 or newer -- No server, database or network access at runtime -- PySide6 only for the desktop viewer -- Self-contained HTML reports with no CDN or external assets +- **Modified**, **Added** and **Deleted** need review. **Comment** and **Unimportant** contain only comments or proven noise. **Not compared** indicates an error. +- Overview groups changes by model/SWC, including ports, runnables, events, RTE access and A2L objects. +- Old/new regeneration warnings are advisory; unchanged output does not prove regeneration history. +- `--check-current` uses delivery policy: failed rules exit `1`; missing input, scan errors or unchecked items exit `2`. See the [User Guide](docs/usage.md#consistency-check) for scope and exceptions. +- Comparisons exit `0` when clean, `1` for real changes or enabled consistency failures, and `2` for errors/incomplete scans. `--exit-zero` suppresses only file-difference failures. ## Documentation -- [Usage Guide](docs/usage.md) — commands, viewer controls, noise rules and CI -- [Vietnamese documentation](docs/vi/README.md) +- [User Guide](docs/usage.md) — viewer, CLI, noise rules and CI +- [Architecture](docs/architecture.md) — components, contracts, verification and builds +- [Contributing](CONTRIBUTING.md) — setup and change requirements +- [Changelog](CHANGELOG.md) — release notes -Run `python -m compare_tool --help` for the complete CLI reference. +See [CLI flags](docs/usage.md#cli-flags) for defaults and supported combinations, or run `python -m compare_tool --help`. HTML reports work offline without a server or external assets. ## License -[MIT](LICENSE) © 2026 Long Vo Thien +[MIT](LICENSE) · Long Vo Thien diff --git a/docs/architecture.md b/docs/architecture.md index 93e4685..67cdde3 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,188 +1,110 @@ # Architecture -This is the implementation map for maintainers and code agents. Read [AGENTS.md](../AGENTS.md) first; it contains the project invariants and required checks. This file explains where behavior lives and which contracts must remain stable. +[Tiếng Việt](vi/architecture.md) · [AGENTS.md](../AGENTS.md) · [Contributing](../CONTRIBUTING.md) -The English document is authoritative. +The CLI, HTML report and Qt viewer share one scan result. The core and zipapp support Python 3.8+ using only the standard library; Qt is optional and loaded lazily. -## Non-negotiable contracts +## Components -1. If a difference cannot be proven to be noise, it is a real change. -2. A scan, read or comparison failure produces `error`; it never looks identical. -3. File verdicts are `identical`, `comment-only`, `ignorable-only`, `real-change`, `added`, `deleted` or `error`. -4. Only `comment-only` and `ignorable-only` may be folded or muted. -5. CLI, report and viewer consume the same raw scan result. -6. The comparison core and zipapp use only the Python standard library and support Python 3.8. -7. Qt imports stay inside `compare_tool/qtviewer/` and are loaded lazily. -8. HTML reports are self-contained and make no network requests. -9. Exit codes are `0` for no real changes, `1` for real changes and `2` for incomplete comparison. `--exit-zero` never suppresses `2`. - -## Data flow - -```mermaid -flowchart LR - A[Folder, ZIP or Git commit] --> B[Source adapter] - B --> C[scanner.scan] - C --> D[diff_engine.compare_pair] - D --> E[Raw result dict] - C --> F[Semantic extractors] - F --> E - E --> G[CLI summary] - E --> H[HTML report] - E --> I[Qt viewer] - E --> J[JSON / SARIF] -``` - -Source adapters materialize inputs as directories. Everything after that uses the same scanner and result contract. - -## Module map +Paths are relative to `compare_tool/`. | Module | Responsibility | |---|---| -| `main.py` | CLI parsing, front-end selection, exit codes and terminal output | -| `scanner.py` | Tree walk, file comparison, move pairing and semantic rollups | -| `diff_engine.py` | Two-pass comparison, hunk classification and the single verdict decision | -| `linediff.py` | Patience-based line matching | -| `c_rules.py` | C/C++ comments, generated renames and safe reorder checks | -| `arxml_rules.py` | ARXML/XML noise rules and semantic extraction | -| `a2l_rules.py` | A2L noise rules and semantic extraction | -| `langspec.py` | Shared comment/string grammar and whitespace-safe shadows | -| `filepair.py` | Conservative Added/Deleted move pairing | -| `consistency.py` | Cross-file regeneration advisories | -| `view_model.py` | Renderer-neutral labels, row alignment and visual modes | -| `report.py` | Self-contained HTML and shared Overview data | -| `serialize.py` | JSON and SARIF output | -| `review.py` | Stable review IDs, notes and sign-offs | -| `gitsource.py` | Read-only Git snapshot materialization | -| `zipsource.py` | Safe ZIP extraction and wrapper-folder handling | -| `theme.py` | Named color roles for HTML and Qt | -| `resources.py` | Optional packaged UI resources | -| `qtviewer/` | The only Qt-dependent package | - -## Comparison contract - -`scanner.scan` returns a dict keyed by relative path. Each value has at least a verdict and comparison metadata: - -```python -{ - "status": "real-change", - "hunks": [ - { - "kind": "real", - "old_range": [12, 15], - "new_range": [12, 14], - } - ], - "renames": {}, - "notes": [], - "binary": False, -} -``` - -Semantic keys such as `ifaces`, `swc`, `rte` and `a2l` are added only when applicable. Move pairs add `moved_from` or `moved_to`, `move_status` and `move_similarity`. - -Ranges are zero-based and end-exclusive indexes into raw file lines. Do not convert the stored coordinates to shadow lines or rendered rows. - -Hunk kinds currently include `real`, `moved`, `comment`, `rename`, `assumed-rename`, `reorder`, `uuid`, `timestamp`, `sw-version`, `description`, `whitespace` and `mixed`. - -### Verdict ownership - -`diff_engine._status_of` is the only place that decides a file verdict. `scanner.FOLDABLE` names the only foldable verdicts. - -A UI filter may change paint, navigation or visibility. It must not rewrite `status`, counts or exported data. Reports and summaries must always use the raw result. - -## Two-pass diff +| `main.py` | Arguments, front-end selection, terminal output and exit codes | +| `scanner.py` | File discovery/comparison, move pairing and semantic rollups | +| `diff_engine.py`, `linediff.py` | Two-pass diff, patience matching, hunk classification and verdicts | +| `c_rules.py`, `arxml_rules.py`, `a2l_rules.py` | Language noise rules and semantic extraction | +| `langspec.py`, `userrules.py` | Comment/string grammar, safe whitespace shadows and custom rules | +| `filepair.py` | Conservative Added/Deleted file pairing | +| `consistency.py` | Old/new advisories and opt-in CURRENT RTE/ARXML checks | +| `view_model.py`, `funcname.py` | Shared labels, aligned rows, muting and object captions | +| `report.py`, `serialize.py` | Offline HTML, shared model Overview, JSON and SARIF | +| `review.py` | Review identity, notes and sign-offs | +| `gitsource.py`, `zipsource.py` | Read-only Git snapshots and safe temporary ZIP extraction | +| `theme.py`, `resources.py` | Shared color roles and optional packaged assets | +| `qtviewer/` | Qt UI, worker, models and rendering; the only Qt-dependent package | -`diff_engine.compare_pair` uses `linediff.hunks` for both passes so coordinates stay aligned. +## Data flow -1. **Truth pass:** compare normalized shadows. Comments and supported generator noise are removed while literal contents and significant Python/YAML indentation are preserved. Anything left is real. -2. **Display pass:** diff raw lines and label each hunk. A raw hunk that does not overlap a real hunk is classified by the one-rule variants. If several rules are needed, its kind is `mixed`. +1. Source adapters materialize folders, ZIPs or Git snapshots as directories. +2. `scanner.scan` compares file pairs through `diff_engine.compare_pair` and attaches semantic data. +3. Move pairing and semantic rollups enrich the raw result. +4. CLI, HTML, JSON/SARIF and viewer consume that result. -The matcher uses patience anchors, then an exact matcher for remaining gaps. This avoids poor alignment in generated files with many repeated structural lines. +Git uses `git archive` without changing HEAD, index or working files. ZIP extraction rejects unreadable/empty archives and path traversal, then cleans temporary directories. -### Rename and reorder safety +## Comparison contracts -A generated rename is applied only after a one-to-one mapping is inferred and rechecked against the shadow. Function callees require matching generated checksum roots. Literal contents are never rewritten. +- Unexplained differences remain real; scan/read/compare failures produce errors. +- Verdicts: `identical`, `comment-only`, `ignorable-only`, `real-change`, `added`, `deleted`, `error`. +- `diff_engine._status_of` owns verdict decisions; `scanner.FOLDABLE` permits only comment/noise folding. Filters never change raw verdicts, counts or exports. +- `scanner.scan` returns a dict keyed by relative path. Records contain `status`, `hunks`, `renames`, `notes` and `binary`; applicable records add `ifaces`, `swc`, `rte` or `a2l`. +- Hunk `old_range` / `new_range` coordinates are zero-based, end-exclusive indexes into raw file lines, never shadow or rendered rows. +- File moves add `moved_from` / `moved_to`, `move_status` and `move_similarity`. Original Added/Deleted verdicts remain. -A reorder is noise only when every line is a side-effect-free scalar assignment, both sides contain the same statements and all data dependencies keep their order. Calls, increments, nested assignments, control flow, declarations and indirect writes disqualify the block. +## Diff and noise safety -`--skip-var-renames` is the only intentionally unsafe comparison mode. Its hunks use `assumed-rename`, and every output surface must disclose that the option was used. +Both passes use `linediff.hunks`, with patience anchors and exact gap matching: -## Semantic extraction +1. **Truth:** compare normalized shadows while preserving literals and significant Python/YAML indentation. Remaining differences are real. +2. **Display:** diff raw lines. Non-real hunks receive a single-rule kind, or `mixed` when several rules are needed. -`scanner.compare_file` attaches semantic data for real changes and one-sided files. The `summarize_*` functions aggregate interfaces, SWCs, RTE access and A2L objects. +Hunk kinds include `real`, `moved`, `comment`, `rename`, `assumed-rename`, `reorder`, `uuid`, `timestamp`, `sw-version`, `description`, `whitespace` and `mixed`. -`consistency.py` derives old/new regeneration advisories from the complete result. When CLI callers opt in with `--check-consistency`, it also performs a standard-library-only check of CURRENT generated RTE calls against CURRENT ARXML access-point declarations. Current-tree `fail` findings set exit code `1`; read, listing and parse failures set `2`; `warn` findings do not gate. Consistency never rewrites file verdicts. The viewer and HTML renderer do not run or render this optional check. +Generated renames require a verified one-to-one mapping; function callees need matching generated checksum roots. Reorders require identical side-effect-free scalar assignments with dependency order preserved. Calls, increments, nested assignments, declarations, control flow and indirect writes disqualify reorder folding. -`--check-current` invokes the same checker directly on one source, bypassing diff scanning and HTML. `CurrentTreeCheck` owns status and consistency exit codes; `main._exit_code` combines them with comparison errors/differences. Standard policy leaves unchecked items non-gating; delivery returns 2. Missing input always returns 2. Existing YAML stays supported; JSON adds scoped mappings and exceptions with reasons. Parsing retains full runnable paths, SWC, SYMBOL/prefix and full access references; orphan matching is runnable-specific. CURRENT finding exports remain a [P2 TODO](todo.md). +`--skip-var-renames` deliberately relaxes rename proof. Its hunks use `assumed-rename`; every output surface must disclose the option. -File move pairing runs after verdicts are settled. A pair is presentation metadata: Added and Deleted verdicts remain in the result and counts. +## Consistency -## Shared presentation seams +`consistency.py` derives advisory regeneration findings from the raw comparison. CURRENT checking runs only when requested by CLI; HTML/viewer do not run or render that check. -Keep facts shared by two front ends outside their renderers: +`--check-current` bypasses diff/HTML and checks one source. `CurrentTreeCheck` owns consistency status/exit codes; `main._exit_code` combines them with comparison results: -| Shared decision | Owner | +| Result | Exit | |---|---| -| Hunk kind to display mode | `view_model.mode_of` | -| Intra-line highlight span | `view_model.char_span` | -| Side-by-side row alignment and muting | `view_model.aligned_rows`, `mute_rows` | -| AUTOSAR display vocabulary | `view_model.SWC_DISPLAY` | -| Model Overview grouping and counts | `report.model_overview` | -| Function/object caption per line | `funcname.enclosing` | -| Color roles | `theme.py` | -| Review identity | `review.py` | - -Do not copy mappings or rollup logic into CLI, HTML or Qt code. - -## Front ends - -### CLI and report - -`main.viewer_requested` decides whether the process opens Qt or runs a terminal comparison. - -`run_compare` removes a stale target report before scanning. A report-write failure preserves the scan for terminal output and exits `2`. - -With `--no-report`, `run_compare` skips HTML rendering. `summary_lines(..., terminal=True)` prints the Overview, semantic details and warnings without source hunks. `diagnostic_lines` adds effective settings, aggregate hunk-kind totals and one summary per non-identical file. Both consume the raw result and never change verdicts, counts or exit codes. `report.model_overview` supplies the same structured rows to HTML and terminal renderers. +| Clean | 0 | +| Real changes or enabled consistency failures | 1 | +| Input/scan/parse/output error or missing required input | 2 | +| Unchecked coverage | Non-gating under standard; 2 under delivery | -### Viewer +`--exit-zero` suppresses file-difference failures only. Checks preserve full runnable/SWC identity, SYMBOL/prefix and access references; orphan matching is per runnable. YAML supports the existing settings; JSON adds scoped mappings/exceptions. See [User Guide](usage.md#consistency-check) for policy and coverage boundaries. -The scanner runs in `qtviewer/worker.py` on a `QThread`. Results cross into widgets through signals. Renderer-independent Qt models must remain importable without PySide6 so headless tests still run. +## Shared presentation -Report export uses the raw scan, not the filtered tree. Muted noise remains part of the verdict and exported counts. - -### Input adapters - -`gitsource.py` uses `git archive` and never changes HEAD, the index or the working tree. - -`zipsource.py` rejects unreadable/empty archives, prevents path traversal and removes temporary extraction directories after use. +| Decision | Owner | +|---|---| +| Hunk display mode and character spans | `view_model.mode_of`, `char_span` | +| Alignment and muting | `view_model.aligned_rows`, `mute_rows` | +| AUTOSAR labels | `view_model.SWC_DISPLAY` | +| Model grouping and counts | `report.model_overview` | +| Function/object captions | `funcname.enclosing` | +| Color roles / review identity | `theme.py` / `review.py` | -## Change map +Keep these decisions outside renderers. Viewer scans run in `qtviewer/worker.py` on a `QThread`; Qt-free models remain importable without PySide6. Exports use the raw scan. -| Change | Start here | Required proof | -|---|---|---| -| Noise rule | Relevant `*_rules.py`, then `diff_engine.py` | Rule alone becomes noise; adjacent real change stays real | -| Generic comment language | `langspec.py`, `diff_engine.RULES`, `syntax.py` | String/comment boundaries agree in diff and highlighting | -| File verdict | `diff_engine._status_of` | Every renderer/count/exit path handles it; folding is explicit | -| Semantic object | Extractor, `scanner.compare_file`, `summarize_*` | Added, removed and modified cases | -| Shared label or rollup | `view_model.py` or a renderer-neutral report helper | HTML, terminal and Qt stay consistent | -| Color | `theme.py` | Role exists in both themes | -| CLI behavior | `main.py` | Exit codes, stale-output behavior and docs | -| Viewer behavior | `qtviewer/` | Headless model test plus a rendered check | -| JSON/SARIF schema | `serialize.py` | Schema/version compatibility and error representation | +`main.viewer_requested` selects the front end. `run_compare` removes stale target HTML before scanning; write failures preserve terminal results and exit 2. `--no-report` skips HTML and leaves existing reports untouched. `summary_lines` and `diagnostic_lines` consume the raw scan without changing results. ## Verification -Run before commit: +For code changes: -```bash +```powershell python -m unittest discover -s tests -v python -m ruff check . +python -m mypy compare_tool +python -m compare_tool tests/fixtures/demo/old tests/fixtures/demo/new --report "$env:TEMP\codegen-smoke.html" ``` -For a release: +The demo contains real changes, so its comparison exits 1. Verify affected viewer behavior with a rendered check; skipped Qt tests do not prove execution. Noise-rule tests must prove noise-only classification and preservation of a nearby real change. Semantic changes need added/removed/modified cases; schema changes need compatibility/error coverage. + +## Build and release -```bash -python packaging/release_check.py X.Y.Z +```powershell +.\build.ps1 -Pyz +.\build.ps1 -PyzOnly ``` -Qt tests may skip without PySide6. A green run in that environment does not verify the viewer. +The first builds the Windows executable and CLI zipapp; the second builds only the zipapp. See [GUI resources](../resources/README.md) for packaged assets. + +For an authorized release, bump `compare_tool.__version__`, date the changelog section and empty `[Unreleased]`. Run `python packaging/release_check.py X.Y.Z`, merge the version change, then run `release.yml` from `main`. The workflow verifies tests/builds and refuses existing tags; publishing requires `publish=true`. diff --git a/docs/usage.md b/docs/usage.md index b175d0b..189ee3e 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -1,221 +1,211 @@ -# Usage Guide +# User Guide -🇻🇳 [Bản tiếng Việt](vi/usage.md) - -This guide is for people running CodeGen Compare Tool. Run `python -m compare_tool --help` for the complete option reference. - -- [Command line](#command-line) -- [Side-by-side viewer](#side-by-side-viewer) -- [What counts as noise](#what-counts-as-noise) -- [Custom noise rules](#custom-noise-rules) -- [AUTOSAR semantic summary](#autosar-semantic-summary) -- [Consistency check](#consistency-check) -- [HTML report](#html-report) -- [CI integration](#ci-integration) -- [Single-file build](#single-file-build) +[Tiếng Việt](vi/usage.md) · [Quick start](../README.md) ## Command line -Both inputs can be folders or ZIP archives. - -CLI comparisons and `--check-current` print `codegen-compare-tool ` before processing inputs. Use `--version` to print only the tool version. - -### HTML report +Inputs may be folders or ZIP archives. Put BASELINE first and CURRENT second: ```bash python -m compare_tool baseline current --report report.html +python -m compare_tool baseline current --no-report ``` -If `--report` is omitted, the default is `compare_report.html`. With `--arxml-only`, the default is `arxml_update.html`. - -### Terminal summary +Two input paths select CLI comparison; without both paths, the tool opens the viewer. Use `--qt` / `--viewer` to open supplied inputs in the viewer, or `--check-current PATH` to check one input in the terminal. Quote paths, labels, globs and regexes that contain spaces or shell characters. -```bash -python -m compare_tool baseline current --no-report -``` +### CLI flags -This mode creates no HTML and prints no source-code hunks. It prints: +#### Mode and input scope -1. total verdict counts; -2. a per-model Overview with file counts and AUTOSAR changes; -3. detailed AUTOSAR/A2L changes; -4. consistency and quick-check warnings; -5. tool/Python/platform versions and effective compare options; -6. totals for each hunk classification; -7. one summary per non-identical file with its verdict, ruleset, hunk-kind counts, rename/move totals and error notes. +| Argument / flag | Use and defaults | +|---|---| +| `old_dir new_dir` | BASELINE and CURRENT paths; required for CLI comparison. Each may be a folder or ZIP. | +| `--qt`, `--viewer` | Aliases: open the desktop viewer instead of CLI comparison. Requires PySide6; input paths are optional. | +| `--arxml-only` | Restrict comparison to ARXML/XML/A2L and produce a compact update report. Off by default. | +| `--exclude PATTERN` | Skip matching relative paths or bare file names on both sides. Repeat for multiple globs, e.g. `--exclude "*.tmp" --exclude "cache/*"`. No exclusions by default. | -An existing report is left untouched. `--json` and `--sarif` still write their requested files. +#### Reports and results -The diagnostics do not print source content and do not change verdicts or exit codes. +| Flag | Use and defaults | +|---|---| +| `--report OUT.html` | HTML output path. Default: `compare_report.html`, or `arxml_update.html` with `--arxml-only`. Reports open offline. | +| `--no-report` | Print model/SWC summaries, semantic changes, warnings, effective settings and per-file diagnostics without source hunks or HTML. Requires both input paths; leaves existing HTML untouched. | +| `--json OUT.json` | Also write the versioned comparison result, including file verdicts, hunks, semantic data, old/new advisories and exit code. No JSON by default. | +| `--sarif OUT.sarif` | Also write SARIF 2.1.0 findings for Modified, Added, Deleted and error files. No SARIF by default. | +| `--baseline-name NAME` | Set the BASELINE display label, e.g. `"build 4821"`; does not change the input path. Default: label derived from the input. | +| `--current-name NAME` | Set the CURRENT display label; same behavior as `--baseline-name`. | +| `--theme dark\|light` | Initial viewer/HTML theme. Default: `dark`; both themes remain available in HTML. Does not affect terminal output. | +| `--max-diff-lines N` | Cap the embedded full HTML diff at about N lines per file. Default: `0` (unlimited). Truncation is marked; comparison, verdicts, counts and machine exports remain complete. | +| `--review REVIEW.json` | Load viewer review notes/sign-offs into the full HTML report. Never loaded automatically; no effect with `--no-report` or the compact `--arxml-only` report. | +| `--exit-zero` | Return `0` for file differences so CI can collect reports without failing on changes. Off by default; never suppresses enabled consistency failures (`1`), input/scan/output errors or delivery coverage gaps (`2`). | + +#### CURRENT consistency + +These checks are CLI-only. See [Consistency check](#consistency-check) for policy, rules, configuration and coverage limits. + +| Flag | Use and defaults | +|---|---| +| `--check-consistency` | Check generated RTE calls against ARXML in CURRENT during a two-input comparison. Off by default; findings appear in the terminal. | +| `--check-current PATH` | Check one CURRENT folder/ZIP without a baseline, diff or HTML. Uses `delivery` policy by default. | +| `--consistency-policy standard\|delivery` | Select coverage enforcement. Default: `standard` for comparison checks, `delivery` for `--check-current`. Delivery gates unchecked items with exit `2`; standard reports them without gating. | +| `--consistency-config FILE` | Load the supported YAML subset or JSON policy. Controls forbidden prefixes, ignored ports and rule severities; JSON also supports mappings/exceptions. Omitted settings keep built-in defaults. | +| `--ignore-access-port-regex REGEX` | Add one temporary ignored-port regex, OR-ed with configured patterns. Matches the payload after `Rte__`; does not disable forbidden-API checks. No extra regex by default. | -### Common options +#### Noise rules and help -| Option | Purpose | +| Flag | Use and defaults | |---|---| -| `--report OUT.html` | Write a self-contained HTML report | -| `--no-report` | Print the terminal-only summary | -| `--arxml-only` | Compare only ARXML, XML and A2L files | -| `--exclude PATTERN` | Skip a matching path or file name; repeatable | -| `--baseline-name NAME` | Change the BASELINE label | -| `--current-name NAME` | Change the CURRENT label | -| `--theme dark\|light` | Select the initial report/viewer theme | -| `--rules RULES.json` | Add project-specific noise rules | -| `--skip-var-renames` | Run the unsafe variable-rename quick check | -| `--max-diff-lines N` | Limit embedded diff lines per report file | -| `--json OUT.json` | Also write the complete structured result | -| `--sarif OUT.sarif` | Also write actionable findings as SARIF 2.1.0 | -| `--exit-zero` | Convert real-change exit code `1` to `0` | -| `--version` | Print the installed version | - -`--report` and `--no-report` are mutually exclusive. Both input paths are required for terminal comparison. +| `--rules RULES.json` | Add project noise patterns to built-in rules for CLI/viewer. No custom rules by default; see [Custom noise rules](#custom-noise-rules) for the file format. | +| `--skip-var-renames` | Unsafe C/C++ rename quick check; off by default. Can hide real rewiring and labels folded hunks as Assumed rename. Do not use it to sign off a review; see [noise limits](#what-counts-as-noise). | +| `-h`, `--help` | Print CLI syntax/options and exit; no inputs needed. | +| `--version` | Print only the tool version and exit; no inputs needed. | -## Side-by-side viewer +### Flag combinations + +- `--report` and `--no-report` are mutually exclusive. JSON/SARIF are additional outputs; add `--no-report` to avoid default HTML. Their contents exclude CURRENT findings. +- `--no-report` requires both inputs and cannot run with `--qt` / `--viewer`. Use report/export flags in CLI comparisons; the viewer exports HTML through its own Export action. +- `--consistency-policy`, `--consistency-config` and `--ignore-access-port-regex` require `--check-consistency` or `--check-current`. Consistency checks cannot run with the viewer or `--arxml-only`. +- `--check-current` takes its input from PATH, not positional arguments. It accepts `--exclude`, `--current-name` and consistency options; `--no-report` / `--check-consistency` are redundant. Comparison/report options and JSON/SARIF are rejected. `--exit-zero` does not suppress its failures. -PySide6 6.12.0 is excluded because Qt highlighting/teardown crashes with Python 3.11; the CLI does not depend on Qt. +### Examples -Install PySide6, then start the viewer: +Name the input builds and select a light report theme: ```bash -pip install "PySide6>=6.5,!=6.12.0" -python -m compare_tool +python -m compare_tool baseline current --report report.html --baseline-name "build 4821" --current-name "working tree" --theme light ``` -To open a comparison directly: +Export machine results without HTML, excluding temporary files: ```bash -python -m compare_tool --viewer baseline current +python -m compare_tool baseline current --no-report --exclude "*.tmp" --exclude "cache/*" --json result.json --sarif result.sarif --exit-zero ``` -The viewer accepts folders and ZIP archives. **Git compare** compares a selected commit with the current checkout without changing the working tree. +Review only the AUTOSAR/calibration surface: -The Files, Quick changes and Consistency panes can be folded or resized. Hiding or muting a category changes only the view; it never changes verdicts, counts or exported reports. +```bash +python -m compare_tool baseline current --arxml-only --report autosar.html +``` -### Verdict marks +After saving a rules file and viewer review notes, include them in a capped HTML report: -| Mark | Verdict | Meaning | -|---|---|---| -| `≠` | Modified | Real changes | -| `≈` | Comment | Comments only | -| `≈` | Unimportant | Proven generator noise only | -| `+` | Added | Only in CURRENT | -| `−` | Deleted | Only in BASELINE | -| `=` | Identical | No difference | -| `‼` | Not compared | Read or comparison error | +```bash +python -m compare_tool baseline current --report report.html --rules rules.json --review codegen-review.json --max-diff-lines 4000 +``` -### Shortcuts +Gate CURRENT consistency and coverage while allowing ordinary file differences: -| Shortcut | Action | -|---|---| -| `F7` / `F8` | Previous / next change across files | -| `Ctrl+Home` / `Ctrl+End` | First / last change in the current file | -| `Ctrl+F` | Find in the current file | -| `F3` / `Shift+F3` | Next / previous match | -| `Ctrl+R` | Mark the current change reviewed | -| `Ctrl+Shift+R` | Mark the current file reviewed | -| `Ctrl+E` | Export an HTML report | -| `F1` | Open the offline user guide | - -Review notes are stored in `codegen-review.json` beside the CURRENT folder. The CLI loads them only when `--review FILE` is specified. +```bash +python -m compare_tool baseline current --no-report --check-consistency --consistency-policy delivery --exit-zero +``` -### Renamed and moved files +## Side-by-side viewer -A confident Added/Deleted file pair is shown as a move and rendered as one diff. Pairing requires the same extension, a mutual best match and enough distance from the next candidate. Uncertain pairs remain Added and Deleted. +Install the [optional viewer](../README.md#run-from-source), then run: -The original verdicts and exit code remain unchanged. +```bash +python -m compare_tool +python -m compare_tool --viewer baseline current +``` -## What counts as noise +Select folders or ZIPs, or use **Git compare** to compare a commit with the current checkout. Git compare leaves the working tree unchanged. Filters and muting affect the view only; verdicts, counts and exported reports retain all results. -A difference is noise only when a rule fully explains it. +| Verdict | Meaning | +|---|---| +| Modified | Real changes | +| Comment / Unimportant | Comments only / proven generator noise only | +| Added / Deleted | Only in CURRENT / BASELINE | +| Identical | No difference | +| Not compared | Read or comparison error | -| Kind | What can be folded | +| Shortcut | Action | |---|---| -| Comment | Supported C/C++, A2L, XML, Python and YAML comments | -| Rename | A verified one-to-one rename of generated identifiers | -| Reorder | Side-effect-free scalar assignments reordered without changing dependencies | -| UUID | ARXML/XML `UUID` attributes | -| Timestamp | ARXML/XML `ADMIN-DATA` and `DATE` | -| Version | ARXML/XML `SW-VERSION` | -| Description | ARXML/XML `DESC`, `LONG-NAME` and `INTRODUCTION` | -| Whitespace | Layout outside literals; Python/YAML indentation remains significant | -| Line ending | CRLF/LF and BOM differences | +| `F7` / `F8` | Previous / next change across files | +| `Ctrl+Home` / `Ctrl+End` | First / last change in the file | +| `Ctrl+F`, `F3` / `Shift+F3` | Find, next / previous match | +| `Ctrl+R` / `Ctrl+Shift+R` | Mark change / file reviewed | +| `Ctrl+E` | Export HTML | +| `F1` | Open the offline guide | -Function calls, literal contents, control flow, pointer/array/field writes and uncertain rename mappings remain real changes. +Review notes are saved in `codegen-review.json` beside CURRENT. The CLI loads them only with `--review FILE`. -### Quick check: skipping variable renames +## What counts as noise + +A rule must explain the whole difference; anything left remains real. -`--skip-var-renames` folds C/C++ bindings that differ only by variable names without proving that the change is harmless. It can hide a real rewiring such as `output = speed` becoming `output = torque`. +| Kind | Supported noise | +|---|---| +| Comment | C/C++, A2L, XML, Python and YAML comments | +| Rename | Verified one-to-one generated identifier renames | +| Reorder | Side-effect-free scalar assignments with dependencies preserved | +| XML metadata | `UUID`, `ADMIN-DATA`, `DATE`, `SW-VERSION`, `DESC`, `LONG-NAME`, `INTRODUCTION` | +| Whitespace | Layout outside literals, line endings and BOM; Python/YAML indentation stays significant | -Use it only to sweep a regenerate for changes that are not rename-shaped. The terminal, report, JSON and viewer identify runs that used this option. +Literal contents, control flow, calls, indirect writes and uncertain renames remain real changes. Matching C functions, ARXML objects and A2L blocks may be shown as moved. Confident Added/Deleted file pairs may share one diff; their original verdicts and exit codes remain. + +`--skip-var-renames` can hide real rewiring such as `output = speed` becoming `output = torque`. Use it only for a quick sweep; outputs identify when it was enabled. ## Custom noise rules -A rules file adds anchored text substitutions on top of the built-in rules: +Pass `--rules RULES.json` to add project-specific substitutions: ```json { - "rules": [ - { - "name": "generator-checksum", - "pattern": "Checksum: [0-9A-F]{8}", - "replacement": "Checksum: ", - "extensions": [".c", ".h"] - } - ] + "rules": [{ + "name": "generator-checksum", + "pattern": "Checksum: [0-9A-F]{8}", + "replacement": "Checksum: ", + "extensions": [".c", ".h"] + }] } ``` -Each rule needs `name` and `pattern`. `replacement` defaults to an empty string; `extensions` is optional. - -Invalid rules and rules that change line count are skipped with a warning. A custom rule cannot replace built-in safety checks or hide a remaining real change. - -## Moved block detection - -Reordered C functions, ARXML objects and A2L blocks are shown as moved when their content matches after supported generator noise is removed. Modified blocks remain real changes. +`name` and `pattern` are required; `replacement` defaults to empty and `extensions` is optional. Limit patterns to known generator noise. Invalid rules or substitutions that change line count are skipped; unexplained differences remain real. An unreadable or invalid JSON file stops the run. ## AUTOSAR semantic summary -For changed and one-sided files, the tool extracts: - -- SWCs; -- ports and port interfaces; -- runnables and events; -- `Rte_*` access points; -- A2L `CHARACTERISTIC` and `MEASUREMENT` objects. +Overview groups artifacts by model/SWC; unassigned files appear under **Shared / other**. Changed and one-sided files contribute ports/interfaces, runnables/events, RTE access and A2L `CHARACTERISTIC` / `MEASUREMENT` changes. Timing-event period changes are shown directly. -Timing-event period changes are reported directly, for example `0.01 s → 0.02 s`. - -## Grouping by model / SWC - -The Overview groups generated artifacts by model/SWC when ownership can be determined from their paths and extracted content. Unassigned files appear under **Shared / other**. - -The HTML report and `--no-report` use the same grouping and rollup data. +Old/new consistency advisories suggest reviewing dependencies and generation records when ARXML/A2L changes without C changes, or a model gains RTE access while peers stay identical. They never gate delivery: unchanged output cannot prove regeneration history. ## Consistency check -The tool warns about combinations that may indicate incomplete regeneration, including: +Check one CURRENT folder or ZIP without a baseline, HTML or viewer: -- ARXML interface changes without corresponding generated C changes; -- A2L changes without corresponding generated C changes; -- a model gaining RTE access while another model remains identical. +```bash +python -m compare_tool --check-current current +python -m compare_tool --check-current delivery.zip --consistency-config project.json +``` -The CURRENT-tree check is disabled by default, so existing CLI, viewer and HTML-report workflows are unchanged. Enable it for a CLI comparison with: +Or enable the same checker during a CLI comparison: ```bash python -m compare_tool baseline current --no-report --check-consistency ``` -The check validates generated C and ARXML inside the CURRENT folder: - -| Rule | Default | Finding | +| Condition | `standard` (comparison default) | `delivery` (`--check-current` default) | |---|---|---| -| `forbidden_rte_api` | `fail` | An RTE call starts with a configured forbidden prefix. | -| `no_matching_port_dataelement` | `fail` | A generated RTE read/write cannot be matched to an ARXML Port/DataElement pair. | -| `missing_access_point_in_arxml` | `fail` | A duplicate ARXML runnable definition omits an access used by generated C. | -| `inconsistent_arxml_access_mode` | `fail` | Duplicate ARXML definitions disagree on direction or access mode. | -| `access_mode_mismatch` | `fail` | The generated API and ARXML disagree on read/write or explicit/implicit access. | -| `orphan_access` | `warn` | A resolved ARXML access point has no matching generated RTE access. | +| Complete check, no failed rule | 0 | 0 | +| Rule set to `fail` | 1 | 1 | +| Read/list/parse error or missing required input | 2 | 2 | +| Unsupported API, ambiguous reference or unresolved call/runnable | INCOMPLETE, non-gating | 2 | + +Use `--consistency-policy delivery` to enforce coverage on comparison checks. The terminal shows PASS, PASS WITH EXCEPTIONS, FAIL or INCOMPLETE, findings and coverage. Comparison differences also affect exit status; `--exit-zero` suppresses only those differences, never consistency failures or errors. + +`--check-current` accepts `--exclude`, `--current-name`, consistency options and the redundant `--no-report` / `--check-consistency` flags. Comparison-only options and JSON/SARIF are rejected. CURRENT findings are terminal-only, including during comparisons; capture terminal output for a delivery record. -Use `--consistency-config CONFIG.yaml` to override the built-in CURRENT-tree policy without adding PyYAML. Every section is optional; omitted values keep their defaults: +### Policy configuration + +Use `--consistency-config CONFIG.yaml` or JSON. Both are standard-library only; omitted settings keep defaults. + +| Rule | Default | Detects | +|---|---|---| +| `forbidden_rte_api` | fail | Configured forbidden API prefix | +| `no_matching_port_dataelement` | fail | RTE access without a matching ARXML Port/DataElement | +| `missing_access_point_in_arxml` | fail | Duplicate runnable definition missing a used access | +| `inconsistent_arxml_access_mode` | fail | Duplicate definitions disagree on direction/mode | +| `access_mode_mismatch` | fail | C/ARXML disagree on direction or explicit/implicit access | +| `orphan_access` | warn | Resolved ARXML access without matching C access | ```yaml forbidden_rte_prefixes: @@ -224,142 +214,73 @@ forbidden_rte_prefixes: ignore_access_port_regex: - ^Bsw_ rules: - forbidden_rte_api: fail - no_matching_port_dataelement: fail - missing_access_point_in_arxml: fail - inconsistent_arxml_access_mode: fail - access_mode_mismatch: fail - orphan_access: warn + orphan_access: fail ``` -Rule severities are: - -- `fail`: print the finding and set exit code `1`; -- `warn`: print the finding without changing the exit code; -- `skip`: omit the finding and report how many configured findings were skipped; -- `off`: disable the rule without a skipped count. - -The ignore regex is matched against the API payload after `Rte__`, for example `Bsw_Port_Data`. It affects Port/DataElement matching but does not disable `forbidden_rte_api`. `--ignore-access-port-regex REGEX` adds one temporary pattern to the file configuration. - -`--consistency-config` and `--ignore-access-port-regex` require `--check-consistency` or `--check-current`. The check is not available with `--arxml-only`, and its findings are not embedded in the HTML report or viewer. +Severities: `fail` gates, `warn` reports only, `skip` omits and counts configured findings, `off` disables the rule. WARN never gates under either policy. -Old/new regeneration warnings remain advisory. A CURRENT-tree `fail` finding sets exit code `1`, even with `--exit-zero`; `warn` does not change the exit code. A file read, folder listing or ARXML parse failure makes the consistency scan incomplete and sets exit code `2`. Consistency results never rewrite file verdicts. +The default implicit-API prohibition is a project policy, not a universal AUTOSAR restriction. Set `forbidden_rte_prefixes: []` to allow implicit APIs. Ignore regexes match the payload after `Rte__`, affect port/data matching and do not disable forbidden-API checks. `--ignore-access-port-regex REGEX` adds a temporary pattern. -### Delivery check without a baseline +After saving the YAML above as `project.yaml`, add a temporary ignore alongside `^Bsw_`: ```bash -python -m compare_tool --check-current current -python -m compare_tool --check-current delivery.zip --consistency-config project.json +python -m compare_tool --check-current current --consistency-config project.yaml --ignore-access-port-regex "^Diag_" ``` -`--check-current PATH` checks one folder or ZIP, without comparison, HTML or a viewer. It accepts `--exclude`, `--current-name`, `--consistency-config`, `--ignore-access-port-regex`, `--consistency-policy`, and the redundant `--no-report` / `--check-consistency` flags. `--exit-zero` never suppresses its failures. Comparison-only options and `--json` / `--sarif` are rejected; CURRENT finding exports are tracked in [TODO](todo.md). +Consistency options require `--check-consistency` or `--check-current`. Checks cannot run with `--arxml-only` or the viewer. -Existing two-folder commands and the YAML subset above remain valid. Comparison without `--check-consistency` is unchanged. Select stricter completeness checking on the old command explicitly: +### Mappings and exceptions -```bash -python -m compare_tool baseline current --no-report --check-consistency --consistency-policy delivery --exit-zero -``` - -| Condition | `standard` (comparison default) | `delivery` (`--check-current` default) | -|---|---:|---:| -| Complete check, no failed rule | 0 | 0 | -| Rule configured `fail` | 1 | 1 | -| Read/list/parse error, missing required input | 2 | 2 | -| Unsupported API, ambiguous reference, unresolved call/runnable | Non-gating; shown as INCOMPLETE | 2 | - -The terminal shows PASS, PASS WITH EXCEPTIONS, FAIL or INCOMPLETE, FAIL/WARN totals and coverage. In a comparison, file differences still affect the final process exit unless `--exit-zero` is used. Under standard policy INCOMPLETE coverage may be non-gating, so use delivery policy for completeness enforcement. WARN rules remain non-gating in both policies; set `orphan_access: fail` if your project requires it. - -Required input includes C files and ARXML runnable definitions. Empty folders, filters that remove all required input, or a tree with neither calls nor access declarations cannot silently pass. A documented `no_rte_expected` JSON reason permits a C-only utility with no detected RTE calls or access declarations; it cannot waive read/parse errors, absent C files, or real RTE usage. - -### Project policy and scoped exceptions - -The default prohibition on `Rte_IRead_` / `Rte_IWrite_` is an inherited **project policy**, not a universal AUTOSAR restriction. Keep existing YAML files, or use JSON for structured mappings and exceptions; both use only the standard library. Omitted settings retain existing defaults. This example allows implicit APIs, gates orphan accesses, and records two narrowly scoped decisions: +JSON supports helper mappings and scoped exceptions with reasons: ```json { - "forbidden_rte_prefixes": [], - "rules": {"orphan_access": "fail"}, - "function_mappings": [ - { - "file": "Ctrl_autosar_rtw/Ctrl.c", - "function": "read_inputs", - "runnable": "/Pkg/Ctrl/IB/Step", - "reason": "Generated helper called only by Step; reviewed against generated C" - } - ], - "exceptions": [ - { - "rule": "unsupported_rte_api", - "file": "Ctrl_autosar_rtw/Ctrl.c", - "runnable": "/Pkg/Ctrl/IB/Step", - "reason": "Client/server contract verified separately by integration" - } - ] + "function_mappings": [{ + "file": "Ctrl_autosar_rtw/Ctrl.c", + "function": "read_inputs", + "runnable": "/Pkg/Ctrl/IB/Step", + "reason": "Generated helper called only by Step; reviewed against generated C" + }], + "exceptions": [{ + "rule": "unsupported_rte_api", + "file": "Ctrl_autosar_rtw/Ctrl.c", + "runnable": "/Pkg/Ctrl/IB/Step", + "reason": "Client/server contract verified separately by integration" + }] } ``` -Mappings require an exact function name, a file glob, an existing full runnable path and a reason. They are explicit project assertions, not inferred call-graph proof. Multiple matching targets remain unresolved. Mappings that refer to nonexistent runnables make the check incomplete. Applied mappings are printed in the terminal. - -Exceptions require a rule, a nonempty reason and at least one scope: `file` (glob), `swc` (exact full path), `runnable` (exact full path), or `port` (exact short name). All supplied scopes must match; unresolved fields cannot match a scope. Exceptions can waive the six configurable findings above, plus `unsupported_rte_api`, `runnable_not_resolved`, `runnable_not_implemented` and `ambiguous_port_dataelement`. They cannot waive scan errors or missing input. Each applied exception and reason is printed. Legacy ignore regexes, excluded files and disabled rules remain accepted and visible; scoped exceptions are preferable when the decision needs a reason. +- Mappings need a file glob, exact function name, existing full runnable path and reason. They are project assertions; multiple targets or nonexistent runnables leave the check incomplete. +- Exceptions need a rule, reason and at least one scope: `file` (glob), `swc` / `runnable` (full path), or `port` (short name). Every supplied scope must match; unresolved fields cannot match. +- Exceptions cover the six rules above plus `unsupported_rte_api`, `runnable_not_resolved`, `runnable_not_implemented` and `ambiguous_port_dataelement`. They cannot waive scan errors or missing input. +- Applied mappings, exceptions, legacy ignores, excludes and disabled rules are visible in the terminal. -For a utility with no RTE contract: +Required inputs include C files and ARXML runnable definitions. Empty input or filters removing required input cannot pass. For a C-only utility with no RTE calls or access declarations: ```json {"no_rte_expected": "Standalone math utility, reviewed to have no RTE contract"} ``` -### Matching and coverage boundaries - -Runnable identity includes its package, SWC and internal behavior. Explicit `SYMBOL` plus the component symbol prefix determines the C entry point. When no symbol is supplied, only unambiguous short-name/component-name candidates are used; suffix guesses cannot establish ownership. Duplicate definitions are compared within the same full runnable path. Full port/data references are retained, and ambiguous short-name or underscore combinations are UNCHECKED. Orphan matching includes runnable, reference, direction and access mode. - -The checker reads `.c` files and validates `Rte_Read`, `Rte_Write`, `Rte_IRead` and `Rte_IWrite` against Sender/Receiver access declarations. Other detected `Rte_*` calls, including `Rte_Call`, `Rte_Send` and `Rte_Receive`, are explicitly UNCHECKED. Declared runnables without resolved C functions are also UNCHECKED. Helper calls require a documented mapping when ownership cannot be resolved. - -This is a source consistency check, not a full AUTOSAR schema validator or C compiler: it does not preprocess conditional compilation, expand macros, scan inline header implementations or infer helper call graphs. Select the intended generated sources and record applicable policy decisions. A policy pass applies only to this declared scope. +This reason cannot waive read/parse errors, missing C files or real RTE usage. -Old/new unchanged-peer advisories ask for dependency and generation-record review. Byte-identical output does not prove whether regeneration occurred or was required; these advisories never gate delivery and use the same wording in CLI, HTML and viewer. +### Coverage boundaries -## HTML report +The checker reads `.c` files and matches `Rte_Read`, `Rte_Write`, `Rte_IRead` and `Rte_IWrite` to Sender/Receiver declarations. Other detected APIs, including `Rte_Call`, `Rte_Send` and `Rte_Receive`, are UNCHECKED. Unresolved C implementations and ambiguous references are also UNCHECKED. -The report includes the Overview, verdict filters, focused diffs, semantic changes and consistency warnings. Long unchanged regions and generator noise are collapsed so real changes remain visible. +Matching uses full package/SWC/runnable identity and declared SYMBOL/component prefixes, with only unambiguous name fallbacks. Orphan matching includes runnable, reference, direction and access mode. Helpers may need an explicit mapping. -The file is self-contained: CSS and JavaScript are inline, and opening it requires no server or network connection. - -Use `--max-diff-lines N` when a very large regenerate would otherwise create an impractical report. Truncation is shown clearly and does not change verdicts or exit codes. +This source check does not preprocess C, expand macros, scan inline header implementations, infer call graphs or perform full AUTOSAR schema validation. A policy pass applies only to this scope. ## CI integration ```bash -python -m compare_tool baseline.zip current.zip \ - --report compare_report.html \ - --check-consistency \ - --consistency-config codegen_checker.yaml \ - --json compare_result.json \ - --sarif compare_result.sarif +python -m compare_tool baseline.zip current.zip --report report.html --json result.json --sarif result.sarif ``` | Exit code | Meaning | -|---:|---| -| `0` | No real changes and no enabled consistency rule failed | -| `1` | Real changes found, or an enabled CURRENT-tree consistency rule failed | -| `2` | Comparison or enabled consistency scan incomplete/failed | - -`--exit-zero` suppresses exit code `1` only when it came from file differences. It never suppresses a CURRENT-tree consistency `fail`. A read, scan, comparison, consistency-scan or report-write failure always exits `2`. - -Publish the HTML report and any JSON/SARIF outputs as CI artifacts. - -CURRENT findings currently remain terminal-only. JSON/SARIF comparison exports contain the comparison results and old/new advisories, not CURRENT findings; see [TODO](todo.md). - -## Single-file build - -The release page provides: - -- `compare-tool.exe`: Windows executable with the viewer; -- `compare_tool.pyz`: standard-library CLI zipapp. - -Build them locally from PowerShell: - -```powershell -.\build.ps1 -Pyz -``` +|---|---| +| 0 | No real changes or enabled consistency failures | +| 1 | Real changes or enabled consistency rule failures | +| 2 | Comparison/check incomplete or an input/output error | -Use `.\build.ps1 -PyzOnly` to build only the zipapp. +Publish the requested files as CI artifacts. Add `--check-consistency` and a policy/config when needed. JSON/SARIF contain comparison results and old/new advisories, not CURRENT findings. diff --git a/docs/vi/README.md b/docs/vi/README.md index dd5aec2..fe3b745 100644 --- a/docs/vi/README.md +++ b/docs/vi/README.md @@ -1,126 +1,68 @@ -

- CodeGen Compare Tool -

- -

-Test -Python 3.8+ -License: MIT -Release -

- -

🇬🇧 English

- # CodeGen Compare Tool -So sánh hai snapshot AUTOSAR MATLAB/Simulink code generation và tập trung vào các thay đổi cần review. +[English](../../README.md) -Tool lọc những generator noise có thể chứng minh là không ảnh hưởng chức năng, sau đó tóm tắt thay đổi trong generated C/C++, ARXML, RTE access và A2L objects. +So sánh folder hoặc ZIP codegen AUTOSAR MATLAB/Simulink và review thay đổi C/C++, ARXML, RTE, A2L. Tool chỉ lọc generator noise đã chứng minh; khác biệt chưa giải thích được vẫn là real change. -> Nếu không chứng minh được một khác biệt là noise, tool giữ nó lại như real change. +## Bắt đầu -## Quick start +1. Tải `compare-tool.exe` từ [Releases](https://github.com/longvo92/codegen-compare-tool/releases/latest) và mở. Không cần cài Python. +2. Chọn BASELINE và CURRENT, rồi chạy compare. +3. Review trong viewer hoặc export HTML report để mở offline. -Tải `compare-tool.exe` hoặc `compare_tool.pyz` từ [release mới nhất](https://github.com/longvo92/codegen-compare-tool/releases/latest). Cả hai hỗ trợ các options bên dưới. +Để dùng CLI, tải `compare_tool.pyz` và chạy bằng Python 3.8+, hoặc dùng source như bên dưới. Với bản tải về, thay `python -m compare_tool` bằng `compare-tool.exe` hoặc `python compare_tool.pyz`. -Để chạy từ source: +## Chạy từ source ```bash git clone https://github.com/longvo92/codegen-compare-tool.git cd codegen-compare-tool -``` - -Với single-file build, thay `python -m compare_tool` bằng `compare-tool.exe` hoặc `python compare_tool.pyz`. - -Kiểm tra consistency trước delivery, chỉ cần một folder hoặc ZIP (tính năng mới trên source, chưa phát hành): - -```bash -python -m compare_tool --check-current current -``` - -Mode này không chạy diff hoặc tạo HTML. Policy `delivery` chặn khi thiếu dữ liệu hoặc còn mục chưa kiểm tra được; YAML và lệnh compare cũ vẫn được hỗ trợ. Xem [usage](usage.md#consistency-check) để cấu hình mapping và ngoại lệ. - -Tạo HTML report độc lập: - -```bash python -m compare_tool baseline current --report report.html ``` -Chỉ in summary trên terminal: +CLI chỉ dùng Python standard library. Để mở desktop viewer: ```bash -python -m compare_tool baseline current --no-report +python -m pip install -e ".[viewer]" +python -m compare_tool ``` -Terminal mode hiển thị Overview theo model, toàn bộ file cùng verdict, AUTOSAR/A2L changes và consistency warnings. Thêm `--check-consistency` để kiểm tra generated RTE call của CURRENT với ARXML declaration trong CURRENT. Mode này không in source diff và không tạo HTML. +Input mẫu: [tests/fixtures/demo](../../tests/fixtures/demo). -Mở desktop viewer: +## Sử dụng ```bash -python -m compare_tool +python -m compare_tool baseline current --no-report +python -m compare_tool --check-current current ``` -Viewer cần PySide6. CLI và `compare_tool.pyz` chỉ dùng Python standard library. - -Input có thể là folder hoặc ZIP archive. - -## Output - -| Output | Dùng khi | +| Output | Dùng để | |---|---| | Desktop viewer | Review side-by-side | -| HTML report | Chia sẻ hoặc publish thành CI artifact | -| `--check-current PATH` | Kiểm tra consistency CURRENT trước delivery | -| `--no-report` | Review nhanh trên terminal, không tạo file | -| `--json` | Xử lý dữ liệu trong pipeline | -| `--sarif` | Tạo code-scanning annotations | - -Comparison engine còn báo cáo: - -- model/SWC ownership; -- port, port interface, runnable và event; -- `Rte_*` access point; -- A2L `CHARACTERISTIC` và `MEASUREMENT`; -- dấu hiệu regenerate chưa đầy đủ giữa ARXML, A2L và generated C; -- generated RTE call không khớp với access declaration trong ARXML của CURRENT khi bật `--check-consistency`. - -Old/new regeneration warning vẫn là advisory. CURRENT-tree check mặc định tắt; khi được bật, finding mức `fail` trả exit code `1`, consistency scan không hoàn tất trả `2`, còn `warn` không đổi exit code. Consistency result không thay đổi file verdict. - -## Verdict - -| Verdict | Ý nghĩa | -|---|---| -| Modified | Có real change cần review | -| Comment | Chỉ comment thay đổi | -| Unimportant | Chỉ có generator noise đã được chứng minh | -| Added / Deleted | File chỉ tồn tại ở một phía | -| Identical | Không có khác biệt | -| Not compared | Không thể đọc hoặc compare file | - -## CI exit code - -| Code | Ý nghĩa | -|---:|---| -| `0` | Không có real change | -| `1` | Có real change | -| `2` | Comparison không đầy đủ hoặc thất bại | +| HTML report | Chia sẻ offline hoặc làm CI artifact | +| `--no-report` | Xem summary và diagnostics trên terminal | +| `--check-current PATH` | Kiểm tra RTE/ARXML trong CURRENT trước delivery | +| `--json` / `--sarif` | Export comparison result cho pipeline | -`--exit-zero` chỉ bỏ qua real-change từ diff; không bỏ qua consistency failure hoặc incomplete. `--check-current` trả `0` khi policy pass, `1` khi rule fail và `2` khi scan thiếu dữ liệu hoặc còn mục UNCHECKED theo policy delivery. +CURRENT consistency finding chỉ có trên terminal; JSON/SARIF chứa comparison result và old/new advisory. -## Yêu cầu +## Đọc kết quả -- Python 3.8 trở lên -- Không cần server, database hoặc network khi chạy -- Chỉ cần PySide6 cho desktop viewer -- HTML report độc lập, không dùng CDN hoặc external asset +- **Modified**, **Added**, **Deleted** cần review. **Comment**, **Unimportant** chỉ có comment hoặc noise đã chứng minh. **Not compared** báo lỗi. +- Overview nhóm thay đổi theo model/SWC, gồm port, runnable, event, RTE access và A2L object. +- Old/new regeneration warning là advisory; output giữ nguyên không chứng minh lịch sử regenerate. +- `--check-current` dùng policy delivery: rule fail trả `1`; thiếu input, scan error hoặc mục chưa kiểm tra được trả `2`. Xem [Hướng dẫn sử dụng](usage.md#consistency-check) để biết scope và ngoại lệ. +- Compare trả `0` khi sạch, `1` khi có real change hoặc consistency failure đã bật, `2` khi lỗi/scan không đầy đủ. `--exit-zero` chỉ bỏ qua failure do file difference. ## Tài liệu -- [Hướng dẫn sử dụng](usage.md) — command, viewer, noise rules và CI -- [English documentation](../../README.md) +- [Hướng dẫn sử dụng](usage.md) — viewer, CLI, noise rules và CI +- [Kiến trúc](architecture.md) — module, contract, verification và build +- [Contributing](../../CONTRIBUTING.md) — setup và yêu cầu khi sửa tool +- [Changelog](../../CHANGELOG.md) — release notes -Chạy `python -m compare_tool --help` để xem đầy đủ CLI options. +Xem [CLI flags](usage.md#cli-flags) về mặc định và cách kết hợp, hoặc chạy `python -m compare_tool --help`. HTML report mở offline, không cần server hoặc external asset. ## License -[MIT](../../LICENSE) © 2026 Long Vo Thien +[MIT](../../LICENSE) · Long Vo Thien diff --git a/docs/vi/architecture.md b/docs/vi/architecture.md index d714aae..766aa2d 100644 --- a/docs/vi/architecture.md +++ b/docs/vi/architecture.md @@ -1,163 +1,110 @@ # Kiến trúc -Đây là bản đồ implementation dành cho maintainer. AI/code agent phải dùng [bản tiếng Anh](../architecture.md) làm nguồn chuẩn và đọc [AGENTS.md](../../AGENTS.md) trước khi sửa code. +[English](../architecture.md) · [AGENTS.md](../../AGENTS.md) · [Contributing](../../CONTRIBUTING.md) -## Contract bắt buộc +CLI, HTML report và Qt viewer dùng chung một scan result. Core và zipapp hỗ trợ Python 3.8+, chỉ dùng standard library; Qt là tùy chọn và load lazy. Bản tiếng Anh là nguồn chuẩn cho maintainer và code agent. -1. Nếu không chứng minh được khác biệt là noise, đó là real change. -2. Lỗi scan, đọc hoặc compare tạo verdict `error`; không được trông giống identical. -3. File verdict gồm `identical`, `comment-only`, `ignorable-only`, `real-change`, `added`, `deleted` và `error`. -4. Chỉ `comment-only` và `ignorable-only` được fold hoặc mute. -5. CLI, report và viewer dùng cùng raw scan result. -6. Comparison core và zipapp chỉ dùng Python standard library, hỗ trợ Python 3.8. -7. Qt import chỉ nằm trong `compare_tool/qtviewer/` và được load lazy. -8. HTML report độc lập, không gọi network. -9. Exit code: `0` không có real change, `1` có real change, `2` comparison không đầy đủ. `--exit-zero` không được bỏ qua `2`. +## Module -## Data flow - -```mermaid -flowchart LR - A[Folder, ZIP hoặc Git commit] --> B[Source adapter] - B --> C[scanner.scan] - C --> D[diff_engine.compare_pair] - D --> E[Raw result dict] - C --> F[Semantic extractor] - F --> E - E --> G[CLI summary] - E --> H[HTML report] - E --> I[Qt viewer] - E --> J[JSON / SARIF] -``` - -Source adapter đưa input về dạng directory. Từ scanner trở đi, mọi front end dùng chung result contract. - -## Bản đồ module +Path tương đối với `compare_tool/`. | Module | Trách nhiệm | |---|---| -| `main.py` | CLI parsing, chọn front end, exit code và terminal output | -| `scanner.py` | Scan tree, compare file, ghép file move và semantic rollup | -| `diff_engine.py` | Two-pass diff, phân loại hunk và quyết định verdict | -| `linediff.py` | Patience-based line matching | -| `c_rules.py` | C/C++ comment, generated rename và safe reorder | -| `arxml_rules.py` | ARXML/XML noise rules và semantic extraction | -| `a2l_rules.py` | A2L noise rules và semantic extraction | -| `langspec.py` | Comment/string grammar và whitespace-safe shadow | -| `filepair.py` | Ghép Added/Deleted thành file move một cách bảo thủ | -| `consistency.py` | Cross-file regeneration advisory | -| `view_model.py` | Label, aligned row và visual mode dùng chung | -| `report.py` | HTML độc lập và dữ liệu Overview dùng chung | -| `serialize.py` | JSON và SARIF | -| `review.py` | Stable review ID, note và sign-off | -| `gitsource.py` | Tạo Git snapshot read-only | -| `zipsource.py` | Giải nén ZIP an toàn | -| `theme.py` | Named color role cho HTML và Qt | -| `qtviewer/` | Package duy nhất phụ thuộc Qt | - -## Result contract - -`scanner.scan` trả về dict theo relative path: - -```python -{ - "status": "real-change", - "hunks": [ - { - "kind": "real", - "old_range": [12, 15], - "new_range": [12, 14], - } - ], - "renames": {}, - "notes": [], - "binary": False, -} -``` +| `main.py` | Argument, chọn front end, terminal output và exit code | +| `scanner.py` | Tìm/compare file, ghép file move và semantic rollup | +| `diff_engine.py`, `linediff.py` | Two-pass diff, patience matching, phân loại hunk và verdict | +| `c_rules.py`, `arxml_rules.py`, `a2l_rules.py` | Noise rule theo ngôn ngữ và semantic extraction | +| `langspec.py`, `userrules.py` | Comment/string grammar, whitespace shadow an toàn và custom rule | +| `filepair.py` | Ghép Added/Deleted file một cách bảo thủ | +| `consistency.py` | Old/new advisory và CURRENT RTE/ARXML check tùy chọn | +| `view_model.py`, `funcname.py` | Label, aligned row, mute và object caption dùng chung | +| `report.py`, `serialize.py` | HTML offline, model Overview dùng chung, JSON và SARIF | +| `review.py` | Review identity, note và sign-off | +| `gitsource.py`, `zipsource.py` | Git snapshot read-only và giải nén ZIP an toàn vào temp | +| `theme.py`, `resources.py` | Color role dùng chung và packaged asset tùy chọn | +| `qtviewer/` | Qt UI, worker, model và rendering; package duy nhất phụ thuộc Qt | -Các key `ifaces`, `swc`, `rte` và `a2l` chỉ xuất hiện khi phù hợp. File move có thêm `moved_from` hoặc `moved_to`, `move_status` và `move_similarity`. +## Data flow -Range dùng index zero-based, end-exclusive trên raw line. Không đổi chúng sang shadow line hoặc rendered row. +1. Source adapter đưa folder, ZIP hoặc Git snapshot về directory. +2. `scanner.scan` compare từng cặp file qua `diff_engine.compare_pair` và gắn semantic data. +3. Move pairing và semantic rollup bổ sung raw result. +4. CLI, HTML, JSON/SARIF và viewer dùng result này. -`diff_engine._status_of` là nơi duy nhất quyết định file verdict. `scanner.FOLDABLE` khai báo hai verdict được phép fold. +Git dùng `git archive`, không đổi HEAD, index hoặc working file. ZIP extraction từ chối archive không đọc được/rỗng và path traversal, rồi dọn temp directory. -UI filter chỉ được thay đổi paint, navigation hoặc visibility. Không được sửa `status`, count hoặc exported data. +## Comparison contract -## Two-pass diff +- Khác biệt chưa giải thích vẫn là real; lỗi scan/đọc/compare tạo error. +- Verdict: `identical`, `comment-only`, `ignorable-only`, `real-change`, `added`, `deleted`, `error`. +- `diff_engine._status_of` quyết định verdict; `scanner.FOLDABLE` chỉ cho fold comment/noise. Filter không đổi raw verdict, count hoặc export. +- `scanner.scan` trả dict theo relative path. Record có `status`, `hunks`, `renames`, `notes`, `binary`; thêm `ifaces`, `swc`, `rte`, `a2l` khi phù hợp. +- `old_range` / `new_range` của hunk là index zero-based, end-exclusive trên raw line; không dùng shadow hay rendered row. +- File move thêm `moved_from` / `moved_to`, `move_status`, `move_similarity`. Verdict Added/Deleted gốc giữ nguyên. -`diff_engine.compare_pair` gọi `linediff.hunks` cho cả hai pass để giữ alignment: +## Diff và noise safety -1. **Truth pass:** compare normalized shadow. Phần còn khác sau khi bỏ supported generator noise là real. -2. **Display pass:** diff raw line và gắn kind cho từng hunk. Hunk không overlap real hunk được phân loại bằng single-rule variant; nếu cần nhiều rule thì dùng `mixed`. +Hai pass đều dùng `linediff.hunks`, với patience anchor và exact gap matching: -Shadow phải giữ nguyên literal content và indentation có ý nghĩa trong Python/YAML. +1. **Truth:** compare normalized shadow, giữ literal và indentation có ý nghĩa của Python/YAML. Khác biệt còn lại là real. +2. **Display:** diff raw line. Hunk không real nhận single-rule kind, hoặc `mixed` khi cần nhiều rule. -Generated rename chỉ được áp dụng sau khi mapping một-một được suy ra và verify lại. Function callee cần cùng generated checksum root. Literal không được rewrite. +Hunk kind gồm `real`, `moved`, `comment`, `rename`, `assumed-rename`, `reorder`, `uuid`, `timestamp`, `sw-version`, `description`, `whitespace`, `mixed`. -Reorder chỉ là noise khi toàn bộ line là scalar assignment không side effect, hai phía có cùng statement và mọi data dependency giữ nguyên thứ tự. +Generated rename cần mapping một-một đã verify; function callee cần cùng generated checksum root. Reorder cần cùng scalar assignment không side effect và giữ dependency order. Call, increment, nested assignment, declaration, control flow, indirect write không được fold như reorder. -`--skip-var-renames` là mode cố ý không an toàn duy nhất. Hunk của nó dùng `assumed-rename`, và mọi output phải báo option này đã được bật. +`--skip-var-renames` chủ động nới điều kiện chứng minh rename. Hunk dùng `assumed-rename`; mọi output phải ghi rõ đã bật option. -## Semantic và file move +## Consistency -`scanner.compare_file` gắn semantic data cho real change và one-sided file. Các hàm `summarize_*` tổng hợp interface, SWC, RTE access và A2L object. +`consistency.py` tạo regeneration advisory từ raw comparison. CURRENT check chỉ chạy khi CLI yêu cầu; HTML/viewer không chạy hoặc render check này. -`consistency.py` tạo old/new regeneration advisory từ toàn bộ result. Khi CLI caller opt in bằng `--check-consistency`, module này còn kiểm tra generated RTE call của CURRENT với access-point declaration trong ARXML của CURRENT mà chỉ dùng Python standard library. Current-tree finding mức `fail` trả exit code `1`; lỗi đọc, list hoặc parse trả `2`; finding mức `warn` không gate. Consistency không đổi file verdict. Viewer và HTML renderer không chạy hoặc render optional check này. +`--check-current` bỏ qua diff/HTML và check một source. `CurrentTreeCheck` sở hữu consistency status/exit code; `main._exit_code` kết hợp với comparison result: -`--check-current` gọi trực tiếp cùng checker trên một source, bỏ qua scanner diff và HTML. `CurrentTreeCheck` sở hữu status và consistency exit code; `main._exit_code` kết hợp với comparison errors/differences. Policy standard giữ unchecked item không gate; delivery trả 2. Thiếu đầu vào luôn trả 2. YAML cũ giữ nguyên; JSON thêm mapping và ngoại lệ có scope/lý do. Parser giữ full runnable path, SWC, SYMBOL/prefix và full access references; orphan được xét theo runnable. CURRENT finding export vẫn là [P2 TODO](todo.md). +| Kết quả | Exit | +|---|---| +| Sạch | 0 | +| Real change hoặc consistency failure đã bật | 1 | +| Lỗi input/scan/parse/output hoặc thiếu input bắt buộc | 2 | +| Coverage chưa kiểm tra được | Không gate với standard; 2 với delivery | -File move được ghép sau khi verdict đã chốt. Pairing chỉ là presentation metadata; Added và Deleted vẫn giữ nguyên trong count và exit code. +`--exit-zero` chỉ bỏ qua failure do file difference. Check giữ full runnable/SWC identity, SYMBOL/prefix và access reference; orphan match theo runnable. YAML hỗ trợ setting cũ; JSON thêm mapping/ngoại lệ có scope. Xem [Hướng dẫn sử dụng](usage.md#consistency-check) về policy và giới hạn coverage. -## Seam dùng chung +## Presentation dùng chung -| Quyết định dùng chung | Owner | +| Quyết định | Owner | |---|---| -| Hunk kind → display mode | `view_model.mode_of` | -| Intra-line highlight | `view_model.char_span` | -| Aligned row và muting | `view_model.aligned_rows`, `mute_rows` | -| AUTOSAR display vocabulary | `view_model.SWC_DISPLAY` | -| Model Overview | `report.model_overview` | +| Hunk display mode và character span | `view_model.mode_of`, `char_span` | +| Alignment và mute | `view_model.aligned_rows`, `mute_rows` | +| AUTOSAR label | `view_model.SWC_DISPLAY` | +| Model grouping và count | `report.model_overview` | | Function/object caption | `funcname.enclosing` | -| Color role | `theme.py` | -| Review identity | `review.py` | +| Color role / review identity | `theme.py` / `review.py` | -Không copy mapping hoặc rollup logic vào CLI, HTML hay Qt renderer. +Giữ các quyết định này ngoài renderer. Viewer scan trong `qtviewer/worker.py` bằng `QThread`; model không phụ thuộc Qt phải import được khi thiếu PySide6. Export dùng raw scan. -## Front end và input +`main.viewer_requested` chọn front end. `run_compare` xóa target HTML cũ trước scan; lỗi ghi vẫn giữ terminal result và trả 2. `--no-report` bỏ qua HTML, không đụng report cũ. `summary_lines` và `diagnostic_lines` dùng raw scan, không đổi kết quả. -`main.viewer_requested` chọn Qt hoặc terminal comparison. `run_compare` xóa stale report trước khi scan; lỗi ghi report vẫn in được scan result và trả exit code `2`. +## Verification -Với `--no-report`, tool bỏ qua HTML rendering. `summary_lines(..., terminal=True)` in Overview, semantic details và warnings mà không in source hunk. `diagnostic_lines` bổ sung effective settings, tổng số hunk theo kind và một summary cho mỗi file không identical. Cả hai đều dùng raw result và không thay đổi verdict, count hoặc exit code. `report.model_overview` cấp cùng structured rows cho HTML và terminal. +Với code change: -Viewer chạy scanner trong `qtviewer/worker.py` bằng `QThread`. Export report luôn dùng raw scan, không dùng filtered tree. - -`gitsource.py` dùng `git archive`, không đổi HEAD, index hoặc working tree. `zipsource.py` chặn path traversal, báo lỗi archive hỏng/rỗng và xóa temp directory sau khi chạy. - -## Sửa gì, bắt đầu ở đâu - -| Change | Bắt đầu | Bằng chứng cần có | -|---|---|---| -| Noise rule | `*_rules.py`, rồi `diff_engine.py` | Rule đứng một mình là noise; cạnh real change vẫn là real | -| Generic comment language | `langspec.py`, `RULES`, `syntax.py` | Diff và highlighting hiểu comment/string giống nhau | -| File verdict | `diff_engine._status_of` | Mọi renderer, count và exit path xử lý rõ ràng | -| Semantic object | Extractor, `scanner.compare_file`, `summarize_*` | Added, removed và modified cases | -| Shared label/rollup | `view_model.py` hoặc renderer-neutral helper | HTML, terminal và Qt cho cùng kết quả | -| Color | `theme.py` | Role có trong cả hai theme | -| CLI behavior | `main.py` | Exit code, stale output và docs | -| Viewer behavior | `qtviewer/` | Headless model test và rendered check | -| JSON/SARIF schema | `serialize.py` | Schema compatibility và error representation | - -## Verify - -```bash +```powershell python -m unittest discover -s tests -v python -m ruff check . +python -m mypy compare_tool +python -m compare_tool tests/fixtures/demo/old tests/fixtures/demo/new --report "$env:TEMP\codegen-smoke.html" ``` -Trước release: +Demo có real change nên compare trả 1. Verify viewer bị ảnh hưởng bằng rendered check; Qt test skip không chứng minh execution. Noise-rule test cần case chỉ noise và case giữ real change ở gần. Semantic change cần case added/removed/modified; schema change cần kiểm tra compatibility/error. + +## Build và release -```bash -python packaging/release_check.py X.Y.Z +```powershell +.\build.ps1 -Pyz +.\build.ps1 -PyzOnly ``` -Qt tests có thể skip nếu thiếu PySide6. +Lệnh đầu build Windows executable và CLI zipapp; lệnh sau chỉ build zipapp. Xem [GUI resources](../../resources/README.md) về packaged asset. + +Khi được yêu cầu release, tăng `compare_tool.__version__`, ghi ngày cho changelog section và để trống `[Unreleased]`. Chạy `python packaging/release_check.py X.Y.Z`, merge version change, rồi chạy `release.yml` từ `main`. Workflow kiểm tra test/build và từ chối tag đã có; publish cần `publish=true`. diff --git a/docs/vi/usage.md b/docs/vi/usage.md index 8ec1f1c..ffbbfc6 100644 --- a/docs/vi/usage.md +++ b/docs/vi/usage.md @@ -1,221 +1,211 @@ # Hướng dẫn sử dụng -🇬🇧 [English](../usage.md) - -Tài liệu này dành cho người sử dụng CodeGen Compare Tool. Chạy `python -m compare_tool --help` để xem đầy đủ CLI options. - -- [Command line](#command-line) -- [Viewer side-by-side](#viewer-side-by-side) -- [Cái gì được tính là noise](#cái-gì-được-tính-là-noise) -- [Custom noise rules](#custom-noise-rules) -- [AUTOSAR semantic summary](#autosar-semantic-summary) -- [Consistency check](#consistency-check) -- [HTML report](#html-report) -- [Tích hợp CI](#tích-hợp-ci) -- [Single-file build](#single-file-build) +[English](../usage.md) · [Bắt đầu](README.md) ## Command line -Cả hai input đều có thể là folder hoặc ZIP archive. - -CLI compare và `--check-current` in `codegen-compare-tool ` trước khi xử lý input. Dùng `--version` để chỉ in version của tool. - -### HTML report +Input có thể là folder hoặc ZIP. Đặt BASELINE trước, CURRENT sau: ```bash python -m compare_tool baseline current --report report.html +python -m compare_tool baseline current --no-report ``` -Nếu bỏ qua `--report`, output mặc định là `compare_report.html`. Khi dùng `--arxml-only`, output mặc định là `arxml_update.html`. +Có đủ hai path thì chạy CLI comparison; thiếu path thì mở viewer. Dùng `--qt` / `--viewer` để mở input đã truyền trong viewer, hoặc `--check-current PATH` để check một input trên terminal. Đặt path, label, glob và regex trong dấu nháy nếu có khoảng trắng hoặc ký tự shell. -### Terminal summary +### CLI flags -```bash -python -m compare_tool baseline current --no-report -``` - -Mode này không tạo HTML và không in source-code hunk. Terminal hiển thị: +#### Mode và phạm vi input -1. tổng số file theo verdict; -2. Overview theo model với file count và AUTOSAR changes; -3. AUTOSAR/A2L changes chi tiết; -4. consistency và quick-check warnings; -5. version của tool/Python/platform và các compare option thực tế; -6. tổng số theo từng hunk classification; -7. một summary cho mỗi file không identical gồm verdict, ruleset, số hunk theo kind, tổng rename/move và error note. +| Argument / flag | Công dụng và mặc định | +|---|---| +| `old_dir new_dir` | Path BASELINE và CURRENT; bắt buộc khi CLI comparison. Mỗi input có thể là folder hoặc ZIP. | +| `--qt`, `--viewer` | Hai tên cho cùng flag: mở desktop viewer thay CLI comparison. Cần PySide6; input path không bắt buộc. | +| `--arxml-only` | Chỉ compare ARXML/XML/A2L và tạo compact update report. Mặc định tắt. | +| `--exclude PATTERN` | Bỏ qua relative path hoặc file name khớp glob ở cả hai phía. Lặp để thêm glob, ví dụ `--exclude "*.tmp" --exclude "cache/*"`. Mặc định không exclude. | -Report đã có từ trước không bị thay đổi. `--json` và `--sarif` vẫn tạo file khi được chỉ định. +#### Report và kết quả -Diagnostics không in source content và không thay đổi verdict hoặc exit code. +| Flag | Công dụng và mặc định | +|---|---| +| `--report OUT.html` | Path HTML output. Mặc định: `compare_report.html`, hoặc `arxml_update.html` khi dùng `--arxml-only`. Report mở offline. | +| `--no-report` | In summary model/SWC, semantic changes, warning, cấu hình thực tế và diagnostics từng file; không in source hunk hay tạo HTML. Cần đủ hai input; giữ nguyên HTML đã có. | +| `--json OUT.json` | Xuất thêm comparison result có schema version, gồm file verdict, hunk, semantic data, old/new advisory và exit code. Mặc định không tạo JSON. | +| `--sarif OUT.sarif` | Xuất thêm SARIF 2.1.0 finding cho file Modified, Added, Deleted và error. Mặc định không tạo SARIF. | +| `--baseline-name NAME` | Đặt label hiển thị BASELINE, ví dụ `"build 4821"`; không đổi input path. Mặc định: label lấy từ input. | +| `--current-name NAME` | Đặt label hiển thị CURRENT; cùng cách hoạt động với `--baseline-name`. | +| `--theme dark\|light` | Theme ban đầu của viewer/HTML. Mặc định: `dark`; HTML vẫn chứa cả hai theme. Không ảnh hưởng terminal output. | +| `--max-diff-lines N` | Giới hạn full HTML diff nhúng khoảng N dòng mỗi file. Mặc định: `0` (không giới hạn). Có đánh dấu phần bị cắt; comparison, verdict, count và machine export vẫn đầy đủ. | +| `--review REVIEW.json` | Đọc review note/sign-off từ viewer vào full HTML report. Không tự đọc; không có tác dụng với `--no-report` hoặc compact report `--arxml-only`. | +| `--exit-zero` | Trả `0` khi có file difference để CI thu report mà không fail vì thay đổi. Mặc định tắt; không bỏ qua consistency failure đã bật (`1`), lỗi input/scan/output hoặc thiếu coverage theo delivery (`2`). | + +#### CURRENT consistency + +Các check này chỉ dùng trên CLI. Xem [Consistency check](#consistency-check) về policy, rule, cấu hình và giới hạn coverage. + +| Flag | Công dụng và mặc định | +|---|---| +| `--check-consistency` | Check generated RTE call với ARXML trong CURRENT khi compare hai input. Mặc định tắt; finding hiện trên terminal. | +| `--check-current PATH` | Check một folder/ZIP CURRENT, không cần baseline, diff hay HTML. Mặc định dùng policy `delivery`. | +| `--consistency-policy standard\|delivery` | Chọn cách gate coverage. Mặc định: `standard` cho comparison check, `delivery` cho `--check-current`. Delivery trả `2` khi còn mục chưa check được; standard chỉ báo, không gate. | +| `--consistency-config FILE` | Đọc policy từ YAML subset được hỗ trợ hoặc JSON. Cấu hình forbidden prefix, ignored port và rule severity; JSON thêm mapping/ngoại lệ. Setting bỏ qua giữ default có sẵn. | +| `--ignore-access-port-regex REGEX` | Thêm một regex ignored-port tạm thời, kết hợp OR với pattern trong config. Match payload sau `Rte__`; không tắt forbidden-API check. Mặc định không thêm regex. | -### Options thường dùng +#### Noise rule và trợ giúp -| Option | Công dụng | +| Flag | Công dụng và mặc định | |---|---| -| `--report OUT.html` | Tạo HTML report độc lập | -| `--no-report` | Chỉ in terminal summary | -| `--arxml-only` | Chỉ compare ARXML, XML và A2L | -| `--exclude PATTERN` | Bỏ qua path hoặc file name khớp pattern; có thể lặp | -| `--baseline-name NAME` | Đổi label BASELINE | -| `--current-name NAME` | Đổi label CURRENT | -| `--theme dark\|light` | Chọn theme ban đầu của report/viewer | -| `--rules RULES.json` | Thêm noise rules của project | -| `--skip-var-renames` | Chạy quick check đổi tên biến không an toàn | -| `--max-diff-lines N` | Giới hạn số diff line nhúng cho mỗi file | -| `--json OUT.json` | Tạo thêm kết quả có cấu trúc | -| `--sarif OUT.sarif` | Tạo thêm SARIF 2.1.0 cho actionable findings | -| `--exit-zero` | Chuyển exit code `1` thành `0` | -| `--version` | In version đang dùng | - -`--report` và `--no-report` không thể dùng cùng nhau. Terminal comparison cần đủ hai input path. +| `--rules RULES.json` | Thêm noise pattern của dự án vào built-in rule cho CLI/viewer. Mặc định không có custom rule; xem format tại [Custom noise rules](#custom-noise-rules). | +| `--skip-var-renames` | Quick check rename C/C++ không an toàn; mặc định tắt. Có thể ẩn rewiring thật, gắn nhãn Assumed rename cho hunk bị fold. Không dùng để sign off review; xem [giới hạn noise](#cái-gì-được-tính-là-noise). | +| `-h`, `--help` | In cú pháp/options CLI rồi thoát; không cần input. | +| `--version` | Chỉ in version của tool rồi thoát; không cần input. | -## Viewer side-by-side +### Kết hợp flag + +- `--report` và `--no-report` không dùng cùng nhau. JSON/SARIF là output bổ sung; thêm `--no-report` để tránh tạo HTML mặc định. Nội dung chưa chứa CURRENT finding. +- `--no-report` cần đủ hai input, không dùng cùng `--qt` / `--viewer`. Dùng report/export flag trong CLI comparison; viewer xuất HTML qua thao tác Export riêng. +- `--consistency-policy`, `--consistency-config` và `--ignore-access-port-regex` cần `--check-consistency` hoặc `--check-current`. Consistency check không dùng cùng viewer hoặc `--arxml-only`. +- `--check-current` lấy input từ PATH, không nhận positional argument. Chấp nhận `--exclude`, `--current-name` và consistency options; `--no-report` / `--check-consistency` không bắt buộc. Option compare/report và JSON/SARIF bị từ chối. `--exit-zero` không bỏ qua failure của mode này. -PySide6 6.12.0 bị loại khỏi dependency do crash trong Qt highlighting/teardown với Python 3.11; CLI không phụ thuộc Qt. +### Ví dụ -Cài PySide6 rồi mở viewer: +Đặt tên build input và chọn report theme sáng: ```bash -pip install "PySide6>=6.5,!=6.12.0" -python -m compare_tool +python -m compare_tool baseline current --report report.html --baseline-name "build 4821" --current-name "working tree" --theme light ``` -Mở trực tiếp một comparison: +Xuất machine result không tạo HTML, bỏ qua file tạm: ```bash -python -m compare_tool --viewer baseline current +python -m compare_tool baseline current --no-report --exclude "*.tmp" --exclude "cache/*" --json result.json --sarif result.sarif --exit-zero ``` -Viewer nhận folder và ZIP archive. **Git compare** so sánh commit được chọn với current checkout mà không thay đổi working tree. +Chỉ review AUTOSAR/calibration surface: -Các pane Files, Quick changes và Consistency có thể fold hoặc resize. Hide hoặc mute một category chỉ thay đổi cách hiển thị; verdict, count và report export không đổi. +```bash +python -m compare_tool baseline current --arxml-only --report autosar.html +``` -### Verdict mark +Sau khi lưu rules file và review note từ viewer, đưa chúng vào HTML report có giới hạn diff: -| Mark | Verdict | Ý nghĩa | -|---|---|---| -| `≠` | Modified | Có real change | -| `≈` | Comment | Chỉ comment thay đổi | -| `≈` | Unimportant | Chỉ có generator noise đã được chứng minh | -| `+` | Added | Chỉ có trong CURRENT | -| `−` | Deleted | Chỉ có trong BASELINE | -| `=` | Identical | Không có khác biệt | -| `‼` | Not compared | Lỗi đọc hoặc compare | +```bash +python -m compare_tool baseline current --report report.html --rules rules.json --review codegen-review.json --max-diff-lines 4000 +``` -### Shortcut +Gate consistency và coverage của CURRENT, cho phép file difference thông thường: -| Shortcut | Thao tác | -|---|---| -| `F7` / `F8` | Change trước / sau, đi qua các file | -| `Ctrl+Home` / `Ctrl+End` | Change đầu / cuối trong file hiện tại | -| `Ctrl+F` | Tìm trong file hiện tại | -| `F3` / `Shift+F3` | Kết quả tìm kiếm tiếp theo / trước đó | -| `Ctrl+R` | Đánh dấu change hiện tại đã review | -| `Ctrl+Shift+R` | Đánh dấu file hiện tại đã review | -| `Ctrl+E` | Export HTML report | -| `F1` | Mở offline user guide | +```bash +python -m compare_tool baseline current --no-report --check-consistency --consistency-policy delivery --exit-zero +``` -Review note được lưu trong `codegen-review.json` cạnh CURRENT folder. CLI chỉ đọc file này khi truyền `--review FILE`. +## Viewer side-by-side -### File rename hoặc move +Cài [viewer tùy chọn](README.md#chạy-từ-source), rồi chạy: -Một cặp Added/Deleted đủ chắc chắn được hiển thị như file move và chỉ render một diff. Hai file phải cùng extension, chọn nhau là best match và đủ khác biệt so với candidate kế tiếp. Trường hợp không chắc chắn vẫn giữ Added và Deleted. +```bash +python -m compare_tool +python -m compare_tool --viewer baseline current +``` -Verdict ban đầu và exit code không thay đổi. +Chọn folder hoặc ZIP, hoặc dùng **Git compare** để so sánh commit với checkout hiện tại. Git compare không thay đổi working tree. Filter và mute chỉ ảnh hưởng hiển thị; verdict, count và report export giữ đủ kết quả. + +| Verdict | Ý nghĩa | +|---|---| +| Modified | Real change | +| Comment / Unimportant | Chỉ comment / generator noise đã chứng minh | +| Added / Deleted | Chỉ có trong CURRENT / BASELINE | +| Identical | Không khác biệt | +| Not compared | Lỗi đọc hoặc compare | + +| Shortcut | Thao tác | +|---|---| +| `F7` / `F8` | Change trước / sau qua các file | +| `Ctrl+Home` / `Ctrl+End` | Change đầu / cuối trong file | +| `Ctrl+F`, `F3` / `Shift+F3` | Tìm, kết quả sau / trước | +| `Ctrl+R` / `Ctrl+Shift+R` | Đánh dấu change / file đã review | +| `Ctrl+E` | Export HTML | +| `F1` | Mở hướng dẫn offline | + +Review note lưu trong `codegen-review.json` cạnh CURRENT. CLI chỉ đọc khi truyền `--review FILE`. ## Cái gì được tính là noise -Một khác biệt chỉ là noise khi rule giải thích được toàn bộ khác biệt đó. +Rule phải giải thích toàn bộ khác biệt; phần còn lại vẫn là real change. -| Kind | Có thể fold | +| Kind | Noise được hỗ trợ | |---|---| -| Comment | Comment được hỗ trợ trong C/C++, A2L, XML, Python và YAML | +| Comment | Comment C/C++, A2L, XML, Python và YAML | | Rename | Generated identifier đổi tên theo mapping một-một đã verify | -| Reorder | Scalar assignment không có side effect đổi thứ tự nhưng giữ nguyên dependency | -| UUID | Attribute `UUID` trong ARXML/XML | -| Timestamp | `ADMIN-DATA` và `DATE` trong ARXML/XML | -| Version | `SW-VERSION` trong ARXML/XML | -| Description | `DESC`, `LONG-NAME` và `INTRODUCTION` trong ARXML/XML | -| Whitespace | Layout ngoài literal; indentation của Python/YAML vẫn có ý nghĩa | -| Line ending | Khác biệt CRLF/LF và BOM | - -Function call, nội dung literal, control flow, pointer/array/field write và rename mapping không chắc chắn vẫn là real change. +| Reorder | Scalar assignment không side effect, giữ nguyên dependency | +| XML metadata | `UUID`, `ADMIN-DATA`, `DATE`, `SW-VERSION`, `DESC`, `LONG-NAME`, `INTRODUCTION` | +| Whitespace | Layout ngoài literal, line ending và BOM; indentation Python/YAML vẫn có ý nghĩa | -### Quick check: bỏ qua variable rename +Nội dung literal, control flow, call, indirect write và rename chưa chắc chắn vẫn là real change. C function, ARXML object và A2L block khớp nội dung có thể hiện là moved. Cặp Added/Deleted đủ chắc chắn có thể dùng chung một diff; verdict và exit code gốc vẫn giữ nguyên. -`--skip-var-renames` fold C/C++ binding chỉ khác variable name mà không chứng minh thay đổi đó là noise. Cờ này có thể ẩn một rewiring thật như `output = speed` đổi thành `output = torque`. - -Chỉ dùng để quét nhanh một lần regenerate nhằm tìm những thay đổi không có hình dạng rename. Terminal, report, JSON và viewer đều ghi rõ khi option này được bật. +`--skip-var-renames` có thể ẩn rewiring thật như `output = speed` đổi thành `output = torque`. Chỉ dùng để quét nhanh; output ghi rõ khi bật cờ này. ## Custom noise rules -Rules file thêm anchored text substitution bên trên built-in rules: +Truyền `--rules RULES.json` để thêm substitution của dự án: ```json { - "rules": [ - { - "name": "generator-checksum", - "pattern": "Checksum: [0-9A-F]{8}", - "replacement": "Checksum: ", - "extensions": [".c", ".h"] - } - ] + "rules": [{ + "name": "generator-checksum", + "pattern": "Checksum: [0-9A-F]{8}", + "replacement": "Checksum: ", + "extensions": [".c", ".h"] + }] } ``` -Mỗi rule cần `name` và `pattern`. `replacement` mặc định là chuỗi rỗng; `extensions` là optional. - -Rule không hợp lệ hoặc làm thay đổi số dòng sẽ bị bỏ qua kèm warning. Custom rule không thể thay thế built-in safety check hoặc ẩn phần real change còn lại. - -## Phát hiện block bị di chuyển - -C function, ARXML object và A2L block đổi vị trí được hiển thị là moved khi nội dung của chúng khớp sau khi loại bỏ generator noise được hỗ trợ. Block bị sửa vẫn là real change. +Bắt buộc có `name` và `pattern`; `replacement` mặc định rỗng, `extensions` tùy chọn. Chỉ dùng pattern cho generator noise đã biết. Rule sai hoặc substitution đổi số dòng bị bỏ qua; khác biệt chưa giải thích vẫn là real change. File không đọc được hoặc JSON sai làm dừng lệnh. ## AUTOSAR semantic summary -Với file thay đổi hoặc chỉ có ở một phía, tool trích xuất: - -- SWC; -- port và port interface; -- runnable và event; -- `Rte_*` access point; -- A2L `CHARACTERISTIC` và `MEASUREMENT`. +Overview nhóm artifact theo model/SWC; file chưa xác định ownership nằm trong **Shared / other**. File thay đổi hoặc chỉ có một phía đóng góp thay đổi port/interface, runnable/event, RTE access và A2L `CHARACTERISTIC` / `MEASUREMENT`. Timing-event period change được hiển thị trực tiếp. -Timing-event period change được báo trực tiếp, ví dụ `0.01 s → 0.02 s`. - -## Nhóm theo model / SWC - -Overview nhóm generated artifact theo model/SWC khi có thể xác định ownership từ path và nội dung đã trích xuất. File không xác định được model nằm trong **Shared / other**. - -HTML report và `--no-report` dùng chung grouping và rollup data. +Old/new consistency advisory đề nghị xem dependency và generation record khi ARXML/A2L đổi nhưng C không đổi, hoặc model thêm RTE access trong khi peer giữ nguyên. Advisory không gate delivery: output giữ nguyên không chứng minh lịch sử regenerate. ## Consistency check -Tool cảnh báo các trường hợp có thể cho thấy regenerate chưa đầy đủ: +Kiểm tra một folder hoặc ZIP CURRENT, không cần baseline, HTML hay viewer: -- ARXML interface thay đổi nhưng generated C tương ứng không đổi; -- A2L thay đổi nhưng generated C tương ứng không đổi; -- một model có thêm RTE access trong khi model liên quan vẫn identical. +```bash +python -m compare_tool --check-current current +python -m compare_tool --check-current delivery.zip --consistency-config project.json +``` -CURRENT-tree check mặc định tắt nên CLI, viewer và HTML-report workflow hiện có không đổi. Bật check cho CLI comparison bằng: +Hoặc bật cùng checker trong CLI comparison: ```bash python -m compare_tool baseline current --no-report --check-consistency ``` -Check đối chiếu generated C và ARXML bên trong folder CURRENT: - -| Rule | Default | Finding | +| Điều kiện | `standard` (mặc định comparison) | `delivery` (mặc định `--check-current`) | |---|---|---| -| `forbidden_rte_api` | `fail` | RTE call bắt đầu bằng forbidden prefix đã cấu hình. | -| `no_matching_port_dataelement` | `fail` | Generated RTE read/write không match được với cặp Port/DataElement trong ARXML. | -| `missing_access_point_in_arxml` | `fail` | Một duplicate ARXML runnable definition thiếu access mà generated C đang dùng. | -| `inconsistent_arxml_access_mode` | `fail` | Các duplicate ARXML definition không thống nhất direction hoặc access mode. | -| `access_mode_mismatch` | `fail` | Generated API và ARXML không khớp read/write hoặc explicit/implicit access. | -| `orphan_access` | `warn` | ARXML access point thuộc runnable đã resolve không có generated RTE access tương ứng. | +| Check đầy đủ, không rule fail | 0 | 0 | +| Rule đặt `fail` | 1 | 1 | +| Lỗi đọc/list/parse hoặc thiếu input bắt buộc | 2 | 2 | +| API chưa hỗ trợ, reference mơ hồ hoặc call/runnable chưa resolve | INCOMPLETE, không gate | 2 | + +Dùng `--consistency-policy delivery` để bắt buộc coverage trong comparison check. Terminal hiện PASS, PASS WITH EXCEPTIONS, FAIL hoặc INCOMPLETE, finding và coverage. File difference cũng ảnh hưởng exit status của comparison; `--exit-zero` chỉ bỏ qua phần difference đó, không bỏ qua consistency failure hoặc lỗi. + +`--check-current` nhận `--exclude`, `--current-name`, consistency options và các cờ không bắt buộc `--no-report` / `--check-consistency`. Option chỉ dành cho comparison và JSON/SARIF bị từ chối. CURRENT finding chỉ có trên terminal, kể cả khi compare; lưu terminal output nếu cần delivery record. -Dùng `--consistency-config CONFIG.yaml` để override policy mặc định của CURRENT-tree mà không cần thêm PyYAML. Mọi section đều optional; giá trị bị bỏ qua sẽ giữ default: +### Cấu hình policy + +Dùng `--consistency-config CONFIG.yaml` hoặc JSON. Cả hai chỉ dùng standard library; setting bỏ qua giữ default. + +| Rule | Default | Phát hiện | +|---|---|---| +| `forbidden_rte_api` | fail | API có forbidden prefix đã cấu hình | +| `no_matching_port_dataelement` | fail | RTE access không khớp ARXML Port/DataElement | +| `missing_access_point_in_arxml` | fail | Duplicate runnable definition thiếu access đang dùng | +| `inconsistent_arxml_access_mode` | fail | Duplicate definition không thống nhất direction/mode | +| `access_mode_mismatch` | fail | C/ARXML không khớp direction hoặc explicit/implicit access | +| `orphan_access` | warn | ARXML access đã resolve không có C access tương ứng | ```yaml forbidden_rte_prefixes: @@ -224,142 +214,73 @@ forbidden_rte_prefixes: ignore_access_port_regex: - ^Bsw_ rules: - forbidden_rte_api: fail - no_matching_port_dataelement: fail - missing_access_point_in_arxml: fail - inconsistent_arxml_access_mode: fail - access_mode_mismatch: fail - orphan_access: warn + orphan_access: fail ``` -Rule severity gồm: - -- `fail`: in finding và trả exit code `1`; -- `warn`: in finding nhưng không đổi exit code; -- `skip`: bỏ finding và báo số finding đã skip theo config; -- `off`: tắt rule mà không tăng skipped count. - -Ignore regex match với API payload phía sau `Rte__`, ví dụ `Bsw_Port_Data`. Regex này ảnh hưởng Port/DataElement matching nhưng không tắt `forbidden_rte_api`. `--ignore-access-port-regex REGEX` thêm một pattern tạm thời vào cấu hình trong file. - -`--consistency-config` và `--ignore-access-port-regex` yêu cầu `--check-consistency` hoặc `--check-current`. Check không dùng được cùng `--arxml-only`, và finding chưa được đưa vào HTML report hoặc viewer. +Severity: `fail` gate, `warn` chỉ báo, `skip` bỏ qua và đếm finding theo cấu hình, `off` tắt rule. WARN không gate trong cả hai policy. -Old/new regeneration warning vẫn là advisory. CURRENT-tree finding mức `fail` trả exit code `1`, kể cả khi dùng `--exit-zero`; `warn` không đổi exit code. Lỗi đọc file, list folder hoặc parse ARXML làm consistency scan không hoàn tất và trả exit code `2`. Consistency result không thay đổi file verdict. +Mặc định cấm implicit API là policy dự án, không phải hạn chế chung của AUTOSAR. Đặt `forbidden_rte_prefixes: []` để cho phép implicit API. Ignore regex match payload sau `Rte__`, ảnh hưởng port/data matching và không tắt forbidden-API check. `--ignore-access-port-regex REGEX` thêm pattern tạm thời. -### Kiểm tra delivery không cần baseline +Sau khi lưu YAML trên thành `project.yaml`, thêm ignore tạm thời bên cạnh `^Bsw_`: ```bash -python -m compare_tool --check-current current -python -m compare_tool --check-current delivery.zip --consistency-config project.json +python -m compare_tool --check-current current --consistency-config project.yaml --ignore-access-port-regex "^Diag_" ``` -`--check-current PATH` kiểm tra một folder hoặc ZIP, không chạy comparison, HTML hay viewer. Mode hỗ trợ `--exclude`, `--current-name`, `--consistency-config`, `--ignore-access-port-regex`, `--consistency-policy` và chấp nhận thêm `--no-report` / `--check-consistency` dù không bắt buộc. `--exit-zero` không bỏ qua lỗi. Các option chỉ dành cho comparison và `--json` / `--sarif` bị từ chối; export CURRENT finding được ghi trong [TODO](todo.md). +Consistency options yêu cầu `--check-consistency` hoặc `--check-current`. Không dùng check cùng `--arxml-only` hoặc viewer. -Lệnh hai folder và YAML subset cũ vẫn hợp lệ. Comparison không bật `--check-consistency` giữ nguyên hành vi. Có thể bật kiểm tra completeness nghiêm ngặt trên lệnh cũ: +### Mapping và ngoại lệ -```bash -python -m compare_tool baseline current --no-report --check-consistency --consistency-policy delivery --exit-zero -``` - -| Điều kiện | `standard` (mặc định comparison) | `delivery` (mặc định `--check-current`) | -|---|---:|---:| -| Kiểm tra đầy đủ, không có rule fail | 0 | 0 | -| Rule cấu hình `fail` | 1 | 1 | -| Lỗi đọc/list/parse hoặc thiếu đầu vào bắt buộc | 2 | 2 | -| API chưa hỗ trợ, reference mơ hồ, call/runnable chưa resolve | Không gate; hiện INCOMPLETE | 2 | - -Terminal hiển thị PASS, PASS WITH EXCEPTIONS, FAIL hoặc INCOMPLETE, tổng FAIL/WARN và coverage. Trong comparison, file difference vẫn ảnh hưởng process exit trừ khi dùng `--exit-zero`. Policy standard có thể không gate coverage INCOMPLETE; dùng delivery để bắt buộc kiểm tra đầy đủ. Rule WARN không gate trong cả hai policy; đặt `orphan_access: fail` nếu dự án yêu cầu. - -Đầu vào bắt buộc gồm C file và ARXML runnable definition. Folder rỗng, filter loại hết đầu vào cần thiết, hoặc cây không có cả call lẫn access declaration không thể âm thầm pass. Lý do JSON `no_rte_expected` cho phép utility chỉ có C, không phát hiện RTE call hoặc access declaration; không bỏ qua lỗi đọc/parse, thiếu C hay RTE usage thực tế. - -### Policy dự án và ngoại lệ có phạm vi - -Mặc định cấm `Rte_IRead_` / `Rte_IWrite_` là **policy dự án** được giữ từ trước, không phải hạn chế chung của AUTOSAR. Có thể giữ YAML cũ hoặc dùng JSON cho mapping và ngoại lệ có cấu trúc; cả hai chỉ dùng standard library. Setting không khai báo giữ default cũ. Ví dụ sau cho phép implicit API, gate orphan access và ghi hai quyết định có phạm vi cụ thể: +JSON hỗ trợ helper mapping và ngoại lệ có scope, lý do: ```json { - "forbidden_rte_prefixes": [], - "rules": {"orphan_access": "fail"}, - "function_mappings": [ - { - "file": "Ctrl_autosar_rtw/Ctrl.c", - "function": "read_inputs", - "runnable": "/Pkg/Ctrl/IB/Step", - "reason": "Generated helper called only by Step; reviewed against generated C" - } - ], - "exceptions": [ - { - "rule": "unsupported_rte_api", - "file": "Ctrl_autosar_rtw/Ctrl.c", - "runnable": "/Pkg/Ctrl/IB/Step", - "reason": "Client/server contract verified separately by integration" - } - ] + "function_mappings": [{ + "file": "Ctrl_autosar_rtw/Ctrl.c", + "function": "read_inputs", + "runnable": "/Pkg/Ctrl/IB/Step", + "reason": "Generated helper called only by Step; reviewed against generated C" + }], + "exceptions": [{ + "rule": "unsupported_rte_api", + "file": "Ctrl_autosar_rtw/Ctrl.c", + "runnable": "/Pkg/Ctrl/IB/Step", + "reason": "Client/server contract verified separately by integration" + }] } ``` -Mapping cần tên function chính xác, file glob, full runnable path đang tồn tại và lý do. Đây là xác nhận của dự án, không phải bằng chứng call graph do tool tự suy luận. Nhiều target cùng match vẫn là unresolved. Target không tồn tại làm check incomplete. Mapping được áp dụng sẽ được in trên terminal. +- Mapping cần file glob, tên function chính xác, full runnable path tồn tại và lý do. Đây là xác nhận của dự án; nhiều target hoặc runnable không tồn tại khiến check incomplete. +- Ngoại lệ cần rule, lý do và ít nhất một scope: `file` (glob), `swc` / `runnable` (full path), hoặc `port` (short name). Mọi scope khai báo phải match; field chưa resolve không match. +- Ngoại lệ áp dụng cho sáu rule trên và `unsupported_rte_api`, `runnable_not_resolved`, `runnable_not_implemented`, `ambiguous_port_dataelement`. Không bỏ qua scan error hoặc thiếu input. +- Mapping, ngoại lệ, legacy ignore, exclude và disabled rule được áp dụng đều hiện trên terminal. -Ngoại lệ cần rule, lý do không rỗng và ít nhất một scope: `file` (glob), `swc` (full path chính xác), `runnable` (full path chính xác) hoặc `port` (short name chính xác). Tất cả scope khai báo phải match; field chưa resolve không match scope. Ngoại lệ áp dụng cho sáu finding có cấu hình ở trên và `unsupported_rte_api`, `runnable_not_resolved`, `runnable_not_implemented`, `ambiguous_port_dataelement`. Không được bỏ qua scan error hay thiếu đầu vào. Mỗi ngoại lệ được áp dụng cùng lý do đều được in. Ignore regex cũ, file exclude và rule bị tắt vẫn được hỗ trợ và hiển thị; nên dùng ngoại lệ có scope khi cần lưu lý do. - -Với utility không có RTE contract: +Input bắt buộc gồm C file và ARXML runnable definition. Input rỗng hoặc filter loại hết input cần thiết không thể pass. Với utility chỉ có C, không có RTE call hoặc access declaration: ```json {"no_rte_expected": "Standalone math utility, reviewed to have no RTE contract"} ``` -### Matching và giới hạn coverage - -Runnable identity gồm package, SWC và internal behavior. `SYMBOL` khai báo cùng component symbol prefix xác định C entry point. Khi thiếu symbol, chỉ dùng candidate short-name/component-name không mơ hồ; không dùng suffix để đoán ownership. Duplicate definition chỉ được so trong cùng full runnable path. Tool giữ đầy đủ port/data reference; short name hoặc tổ hợp dấu gạch dưới mơ hồ được đánh dấu UNCHECKED. Orphan matching xét runnable, reference, direction và access mode. - -Checker đọc `.c` và đối chiếu `Rte_Read`, `Rte_Write`, `Rte_IRead`, `Rte_IWrite` với Sender/Receiver access declaration. Các `Rte_*` khác phát hiện được, gồm `Rte_Call`, `Rte_Send`, `Rte_Receive`, được ghi rõ UNCHECKED. Runnable đã khai báo nhưng không resolve được C function cũng là UNCHECKED. Helper cần mapping có lý do khi chưa resolve được ownership. - -Đây là source consistency check, không phải AUTOSAR schema validator đầy đủ hay C compiler: không preprocess conditional compilation, expand macro, scan inline implementation trong header hay suy luận helper call graph. Chọn đúng generated source và ghi policy phù hợp. Kết quả pass chỉ áp dụng cho phạm vi đã khai báo này. - -Old/new advisory về peer giữ nguyên chỉ đề nghị xem dependency và generation record. Output byte-identical không chứng minh đã hoặc cần regenerate; advisory không gate delivery và dùng chung wording trên CLI, HTML, viewer. +Lý do này không bỏ qua lỗi đọc/parse, thiếu C file hoặc RTE usage thực tế. -## HTML report +### Giới hạn coverage -Report gồm Overview, verdict filter, focused diff, semantic changes và consistency warnings. Các vùng unchanged dài và generator noise được collapse để real change dễ thấy. +Checker đọc `.c` và match `Rte_Read`, `Rte_Write`, `Rte_IRead`, `Rte_IWrite` với Sender/Receiver declaration. API khác phát hiện được, gồm `Rte_Call`, `Rte_Send`, `Rte_Receive`, là UNCHECKED. C implementation chưa resolve và reference mơ hồ cũng là UNCHECKED. -HTML hoàn toàn độc lập: CSS và JavaScript nằm trong file, không cần server hoặc network khi mở. +Matching dùng đầy đủ package/SWC/runnable identity và SYMBOL/component prefix đã khai báo, chỉ fallback tên khi không mơ hồ. Orphan matching xét runnable, reference, direction và access mode. Helper có thể cần mapping tường minh. -Dùng `--max-diff-lines N` nếu một lần regenerate lớn có thể tạo report quá nặng. Report hiển thị rõ phần bị cắt và vẫn giữ nguyên verdict cùng exit code. +Source check không preprocess C, expand macro, scan inline implementation trong header, suy luận call graph hoặc validate đầy đủ AUTOSAR schema. Policy pass chỉ áp dụng trong scope này. ## Tích hợp CI ```bash -python -m compare_tool baseline.zip current.zip \ - --report compare_report.html \ - --check-consistency \ - --consistency-config codegen_checker.yaml \ - --json compare_result.json \ - --sarif compare_result.sarif +python -m compare_tool baseline.zip current.zip --report report.html --json result.json --sarif result.sarif ``` | Exit code | Ý nghĩa | -|---:|---| -| `0` | Không có real change và không có consistency rule đã bật bị fail | -| `1` | Có real change hoặc CURRENT-tree consistency rule đã bật bị fail | -| `2` | Comparison hoặc consistency scan đã bật không đầy đủ/thất bại | - -`--exit-zero` chỉ bỏ qua exit code `1` khi code đó đến từ file difference. Cờ này không bỏ qua CURRENT-tree consistency `fail`. Lỗi đọc, scan, compare, consistency scan hoặc ghi report luôn trả về `2`. - -Nên publish HTML report và JSON/SARIF output thành CI artifact. - -CURRENT finding hiện chỉ có trên terminal. JSON/SARIF comparison export chứa comparison result và old/new advisory, chưa chứa CURRENT finding; xem [TODO](todo.md). - -## Single-file build - -Release page cung cấp: - -- `compare-tool.exe`: Windows executable có viewer; -- `compare_tool.pyz`: CLI zipapp chỉ dùng standard library. - -Build local từ PowerShell: - -```powershell -.\build.ps1 -Pyz -``` +|---|---| +| 0 | Không có real change hoặc consistency failure đã bật | +| 1 | Có real change hoặc consistency rule đã bật bị fail | +| 2 | Comparison/check không đầy đủ hoặc lỗi input/output | -Dùng `.\build.ps1 -PyzOnly` nếu chỉ cần zipapp. +Publish các file đã yêu cầu thành CI artifact. Thêm `--check-consistency` và policy/config khi cần. JSON/SARIF chứa comparison result và old/new advisory, chưa chứa CURRENT finding. diff --git a/resources/README.md b/resources/README.md index 06e9393..3e39ccf 100644 --- a/resources/README.md +++ b/resources/README.md @@ -1,35 +1,22 @@ # GUI resources -Maintainer reference for the icons and logos shipped with the desktop viewer. +Icons and logos bundled with the desktop viewer. -## Layout +| Path | Content | +|---|---| +| `icons/svg/` | Source toolbar icons | +| `icons/png/24/`, `icons/png/48/` | Raster fallbacks | +| `logo/` | Viewer, report and Windows assets | +| `gen/` | Asset definitions and generator | +| `resources.qrc` | Qt resource manifest | -```text -resources/ -├── icons/svg/ source toolbar icons -├── icons/png/24/ raster fallback -├── icons/png/48/ HiDPI raster fallback -├── logo/ viewer, report and Windows assets -├── gen/ asset definitions and generator -└── resources.qrc Qt resource manifest -``` +`compare_tool/resources.py` resolves source/frozen assets; `compare_tool/qtviewer/icons.py` loads and tints them. Missing assets fall back to text or empty icons without preventing startup or comparison. -## Runtime behavior +## Editing -`compare_tool/resources.py` resolves assets in both a source checkout and a frozen executable. `compare_tool/qtviewer/icons.py` loads and tints them for the active theme. +- Use a 24×24 SVG grid with `stroke="currentColor"`; define app colors in `compare_tool/theme.py`. +- Keep PNG/ICO fallbacks synchronized with SVG sources. +- Update `resources.qrc` and the PyInstaller spec when adding packaged assets. +- Commit generated assets so runtime needs no generator dependencies or network. -Missing assets must degrade to text labels or an empty icon; they must not prevent comparison or viewer startup. - -## Editing rules - -- Keep SVG icons on a 24×24 grid with `stroke="currentColor"`. -- Put application colors in `compare_tool/theme.py`; do not add viewer color literals here. -- Keep PNG and ICO fallbacks in sync with their SVG sources. -- Add new packaged assets to `resources.qrc` and the PyInstaller spec when required. -- Generated assets are committed so runtime use never needs CairoSVG, Pillow or network access. - -Verify resource lookup with: - -```bash -python -m unittest tests.test_resources -v -``` +Verify lookup with `python -m unittest tests.test_resources -v`. diff --git a/tests/fixtures/demo/README.md b/tests/fixtures/demo/README.md index d261fd8..5d5dfe2 100644 --- a/tests/fixtures/demo/README.md +++ b/tests/fixtures/demo/README.md @@ -1,69 +1,39 @@ -# Demo tree +# Demo inputs -One before/after pair that shows the whole tool in a single compare, laid out -the way an Embedded Coder AUTOSAR export actually lands on disk: each model owns -a `_autosar_rtw/` folder of generated C, the ARXML export sits under -`arxml/`, and the calibration files under `a2l/`. - -This is also the suite's only fixture pair — every test scans this tree, so a -path in an assertion is a path a reviewer would really see. +Compare the synthetic before/after AUTOSAR export: ```bash -python -m compare_tool tests/fixtures/demo/old tests/fixtures/demo/new \ - --report demo.html --json demo.json --sarif demo.sarif -``` - -``` -old/ - Ctrl_autosar_rtw/ Ctrl.c Ctrl.h Ctrl_private.h Ctrl_types.h - Rte_Ctrl.h rtwtypes.h - NoiseDemo_autosar_rtw/ NoiseDemo.c NoiseDemo_data.c ert_main.c … - PedalMap_autosar_rtw/ - SpeedCtrl_autosar_rtw/ - StaleGen_autosar_rtw/ - TorqueLimiter_autosar_rtw/ - arxml/ one _component.arxml per model, plus NoiseDemo's - modular _interface / _datatype / _implementation - a2l/ Ctrl.a2l NoiseDemo.a2l PedalMap.a2l StaleGen.a2l +python -m compare_tool tests/fixtures/demo/old tests/fixtures/demo/new --report demo.html --json demo.json --sarif demo.sarif ``` -Grouping keys off the **file stem**, not the folder, so a model's C, its ARXML -under `arxml/` and its A2L under `a2l/` still land in one group in the Overview. +Expected exit: `1` because the inputs contain real changes. C files live under `_autosar_rtw/`, ARXML under `arxml/`, and calibration data under `a2l/`. -## Six models, each making one point +## Cases -| Model | What it shows | +| Model | Review focus | |---|---| -| **SpeedCtrl** | **Reordered statements are noise.** `SpeedCtrl.c` emits the same three independent gains in a different order (and a new timestamp), so it is filed under **Unimportant**, not Modified — the values are identical, and the tool proves it before hiding it. Its `SpeedCtrl_data.c` is **Added**: a file the regenerate started emitting. | -| **StaleGen** | **Cross-artifact consistency.** The ARXML gained a port and the A2L gained a characteristic, but `StaleGen.c` is byte-for-byte unchanged — the interface and calibration moved without the code. The report and the terminal flag *"ARXML and A2L changed but the generated C did not"*, the usual sign of a stale regenerate. | -| **TorqueLimiter** | **A code-only change is normal.** `TorqueLimiter.c` changed (a gain went 1.25 → 1.45) while its ARXML did not, so it is **not** flagged — the check only fires when a surface changed without the code following. Its `TorqueLimiter_data.c` carries a rename the mapping cannot fully explain, which therefore stays **Modified**. | -| **PedalMap** | **The healthy case, plus machine output.** The C, the ARXML (a new `Scaled` port) and the A2L (a new `K_PedalOffset`) all changed together, so no flag — and the AUTOSAR summary lists the new port and characteristic. | -| **Ctrl** | **The +RTE quick-regen advisory.** `Ctrl.c` gains an `Rte_Write_Out2_Diag` while StaleGen's C stays identical, and its `TIMING-EVENT` period goes `0.01s → 0.02s`. Flagged *"gained an RTE access while a peer model stayed identical"*. | -| **NoiseDemo** | **Every ignorable kind in one model**, so the noise rules can be read side by side with what is real. | +| SpeedCtrl | Independent assignments reordered as noise; a generated data file added | +| StaleGen | ARXML/A2L changes with identical C; advisory to review dependencies and generation records | +| TorqueLimiter | A real gain change and an unproven rename; both remain Modified | +| PedalMap | C, ARXML and A2L changes together, including a port and calibration object | +| Ctrl | Added RTE access and a timing-event period change from 0.01 s to 0.02 s | +| NoiseDemo | Comments, generated renames, UUIDs and timestamps beside real changes | -## Where each noise rule lives +Identical C output does not establish whether regeneration occurred or was required. Old/new advisories never gate delivery. + +## Representative verdicts | Path | Verdict | |---|---| -| `NoiseDemo_autosar_rtw/ert_main.c` | **Comment** — banner churn only | -| `NoiseDemo_autosar_rtw/NoiseDemo_data.c` | **Unimportant** — a consistent 1-to-1 identifier rename | -| `NoiseDemo_autosar_rtw/NoiseDemo.c` | **Modified** — a real change beside a comment change | -| `NoiseDemo_autosar_rtw/NoiseDemo_types.h` | **Deleted** | -| `SpeedCtrl_autosar_rtw/SpeedCtrl_data.c` | **Added** | -| `TorqueLimiter_autosar_rtw/TorqueLimiter_data.c` | **Modified** — a rename the mapping cannot explain stays real | -| `arxml/NoiseDemo_component.arxml` | **Unimportant** — `UUID="…"` churn only | -| `arxml/NoiseDemo_implementation.arxml` | **Unimportant** — `` timestamp churn | -| `arxml/NoiseDemo_interface.arxml` | **Modified** — a port-interface change, alongside a UUID bump | -| `arxml/NoiseDemo_datatype.arxml` | **Modified** — a data type renamed | -| `a2l/Ctrl.a2l` | **Comment** | -| `a2l/NoiseDemo.a2l` | **Modified** — a calibration object change | -| every `rtwtypes.h`, `*_private.h`, `Rte_*.h` | **Identical** — the bulk a real compare is made of | - -## What the outputs carry - -- **`demo.html`** — the human report: a *Consistency check* section (below the AUTOSAR changes) names StaleGen (surfaces changed, C did not) and Ctrl (+RTE while a peer stayed identical), `SpeedCtrl.c` sits under Unimportant with its rows greyed until you click, and the folder tree / Overview show every verdict at once. -- **`demo.json`** — the whole scan under a versioned schema, including the same exit code the process returns. -- **`demo.sarif`** — only the files that need action. Unimportant, Comment and identical files are *not* findings. - -`test_demo.py` asserts every one of these claims, so the demo cannot drift out of -step with what it says it does. +| `NoiseDemo_autosar_rtw/ert_main.c` | Comment | +| `NoiseDemo_autosar_rtw/NoiseDemo_data.c` | Unimportant | +| `NoiseDemo_autosar_rtw/NoiseDemo.c` | Modified | +| `NoiseDemo_autosar_rtw/NoiseDemo_types.h` | Deleted | +| `SpeedCtrl_autosar_rtw/SpeedCtrl_data.c` | Added | +| `arxml/NoiseDemo_component.arxml` | Unimportant | +| `arxml/NoiseDemo_interface.arxml` | Modified | +| `a2l/NoiseDemo.a2l` | Modified | + +HTML contains the review view and old/new advisories. JSON carries the versioned comparison result; SARIF contains actionable file findings. CURRENT RTE/ARXML checking is separate and terminal-only; see the [User Guide](../../../docs/usage.md#consistency-check). + +[Demo tests](../../test_demo.py) verify verdicts, semantic summaries, advisories and exports.