Skip to content

Improve scan CLI UX, add scan rule override flags, and update docs - #280

Merged
fernandotonon merged 24 commits into
masterfrom
codex/coverage-over-80-again
Apr 11, 2026
Merged

Improve scan CLI UX, add scan rule override flags, and update docs#280
fernandotonon merged 24 commits into
masterfrom
codex/coverage-over-80-again

Conversation

@fernandotonon

@fernandotonon fernandotonon commented Apr 11, 2026

Copy link
Copy Markdown
Owner

Summary

This PR bundles the requested cleanup, coverage improvements, and scan CLI UX/documentation updates.

Core code improvements

  • Reduced duplication in primitives/gizmo/MCP areas:
    • PrimitivesWidget cleanup
    • shared gizmo-axis helpers and translation/scale gizmo deduplication
    • MCPServer deduplication/refactor
  • Expanded test coverage in command and scan flows:
    • increased TransformCommands tests
    • added/updated coverage around gizmo helper behavior, MCP server behavior, and scan CLI behavior

Scan CLI UX improvements

  • Plain-text scan output now streams per-asset while scanning (instead of waiting until the end).
  • Status labels are colorized in terminal output:
    • OK green
    • WARN yellow
    • ERROR red
  • Summary now uses icons and color cues.
  • Added --max-vertices CLI override (both --max-vertices 1000 and --max-vertices=1000).
  • Added broad scan rule overrides via CLI for quick one-off verification:
    • --allowed-formats, --forbidden-extensions
    • --max-file-size-mb, --min-file-size-mb
    • --max-meshes, --min-meshes
    • --max-materials, --min-materials
    • --max-vertices, --min-vertices
    • --require-skeleton / --no-require-skeleton
    • --require-animations / --no-require-animations
    • --allow-embedded-textures / --disallow-embedded-textures
    • --require-textures-exist / --no-require-textures-exist
    • --allow-missing-materials / --disallow-missing-materials
    • --file-name-case
    • --max-anim-keyframes, --min-anim-keyframes
    • --max-anim-duration, --min-anim-duration
    • --require-animation-names, --require-bone-names

Website/docs updates

  • Updated website docs (website/src/DocsApp.jsx) to include the new scan override flags and examples.
  • Updated docs scan example output to reflect current summary/icon format.

Validation

  • QT_QPA_PLATFORM=offscreen build_cov_local/debug/UnitTests --gtest_filter='CLIPipelineCmdScan*'
  • QT_QPA_PLATFORM=offscreen build_cov_local/debug/UnitTests --gtest_filter='ScanEngineTest.Run_*:CLIPipelineCmdScan*'
  • cd website && npm run build
  • Manual CLI checks using build_test/bin/qtmesh scan ... for streaming output and CLI override behavior.

Notes

  • skipped currently tracks load/parse failures (loadError) and those also contribute to errors via load_error findings.

Summary by CodeRabbit

  • New Features

    • Per-run CLI overrides for scan (allowed/forbidden formats, file-size, mesh/material/vertex min/max, skeleton/animation/texture/material toggles, filename-case, required animation/bone name lists); supports --flag value and --flag=value, boolean negation, and empty flags to clear scoped rules; CLI overrides take precedence.
    • Optional colorized glyphs in terminal scan summary (non-JSON output).
  • Documentation

    • Expanded scan docs and examples covering new flags, forms, and example outputs.
  • Tests

    • Added CLI validation, override, precedence, and exit-code tests.
  • Bug Fixes

    • Stabilized exit code behavior for the animation list command.

@coderabbitai

coderabbitai Bot commented Apr 11, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 34a9a377-689b-413e-8f7f-e1b6d06d31c3

📥 Commits

Reviewing files that changed from the base of the PR and between ee045a7 and 4aab76a.

📒 Files selected for processing (1)
  • src/CLIPipeline_test.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/CLIPipeline_test.cpp

📝 Walkthrough

Walkthrough

The scan CLI gained many per-run override flags, improved flag parsing (supports --flag value and --flag=value, boolean negation, validation), applies overrides via a final CLI-precedence ScanScope, and made status icon colorization optional; tests and docs updated accordingly.

Changes

Cohort / File(s) Summary
CLI Implementation & Colorization
src/CLIPipeline.cpp
Added helper to optionally colorize icon glyphs; extended scan usage with numerous override flags (allowed/forbidden formats, file-size, mesh/material/vertex/skeleton/animation/texture/material constraints, required name lists, file-name-case); refactored cmdScan to parse both --opt value and --opt=value, added numeric/enum validation and boolean negation forms, applied parsed overrides into a final "catch-all" ScanScope to enforce CLI precedence, and used the colorize flag for non-JSON terminal summaries.
CLI Tests
src/CLIPipeline_test.cpp
Updated tests to use .fbx source and format helper; tightened exit-code expectations; added invalid-argument tests (non-numeric, bad enum); added constraint-violation tests for --max-vertices, --max-file-size-mb, --allowed-formats; added override/precedence tests (--no-require-*, empty overrides that clear scoped rules) and ensured CLI takes precedence over YAML scopes.
Documentation / Website
website/src/DocsApp.jsx
Expanded scan command docs with the new flags and examples, documented acceptance of --flag value and --flag=value, clarified that CLI overrides apply after config and take precedence, and updated example output to a glyph-based status summary.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant CLI as CLI
    participant Config as ConfigLoader
    participant Engine as ScanEngine
    participant Reporter as Reporter

    User->>CLI: run `qtmesh scan` with flags
    CLI->>Config: load qtmesh.yml / qtmesh.json (if present)
    CLI->>CLI: parse flags (accept --opt value & --opt=value, booleans/negations, validate)
    CLI->>Config: inject CLI overrides as final ScanScope (CLI precedence)
    Config->>Engine: invoke scan with effective ScanConfig
    Engine->>Reporter: produce structured scan results
    Reporter->>CLI: format output (apply icon colors only if colorize enabled)
    CLI->>User: print terminal summary / write JSON/SARIF reports
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇 I hop through flags with gentle care,

I read your YAML, then CLI takes chair.
Glyphs may color when counts are bright,
CLI rules leap in, pushing scopes to night.
Thump—your scan reports sparkle in the light. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main changes: improved scan CLI UX, new scan rule override flags, and documentation updates.
Description check ✅ Passed The description covers all required template sections with comprehensive details of features, technical changes, validation steps, and notes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/coverage-over-80-again

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 64e0311d92

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/CLIPipeline.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/CLIPipeline_test.cpp (2)

1179-1184: This regression check is too permissive now.

Accepting 1 here means the test no longer protects the intended zero-animation success path. Please switch to a deterministic fixture/import path and keep asserting the success case explicitly.

Based on learnings, CLIPipeline::cmdAnim list mode should return success and emit No animations found. / [] when a skeleton exists but has zero animations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/CLIPipeline_test.cpp` around lines 1179 - 1184, The test currently allows
textRc == 1 which masks failures; change the test to use a deterministic
fixture/import path that guarantees the file is loaded (a model with a skeleton
but zero animations) and assert success explicitly: replace the loose
EXPECT_TRUE(textRc == 0 || textRc == 1) with an ASSERT_EQ(textRc, 0) (and keep
ASSERT_EQ(textRc, jsonRc)); additionally verify CLIPipeline::cmdAnim list mode
output contains the expected no-animation indicators (e.g. "No animations
found." and "[]") so the test fails if the loader or list-mode handling
regresses.

2134-2187: These scan override tests should isolate auto-loaded config.

cmdScan() auto-detects qtmesh.yml/qtmesh.yaml/qtmesh.json when --config is omitted, so these cases can pick up unrelated repo-local rules and change the expected exit code. Wrap them in ScopedCurrentDir(tmpDir.path()) or pass a minimal temp config so the failure comes only from the override under test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/CLIPipeline_test.cpp` around lines 2134 - 2187, The tests calling
CLIPipeline::cmdScan are inheriting repo-local
qtmesh.yml/qtmesh.yaml/qtmesh.json because they omit --config, causing flaky
exit codes; fix each test (e.g., the tests using TestArgv and invoking
CLIPipeline::cmdScan) by isolating auto-loaded config either by wrapping the
test body with ScopedCurrentDir(tmpDir.path()) or by creating a minimal temp
config file in tmpDir and passing its path via "--config" in TestArgv so only
the specific override under test (e.g., --max-vertices, --max-file-size-mb,
--allowed-formats) drives the failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/CLIPipeline.cpp`:
- Around line 1986-2061: The CLI currently treats empty string/list flags as
"not provided" by checking QString::isEmpty(), so you must adopt the same
sentinel approach used for other overrides (like maxFileSizeMbOverride checks)
for forbiddenExtensionsArg, fileNameCaseOverride, requiredAnimationNamesArg, and
requiredBoneNamesArg: when parsing the CLI set a distinct sentinel value (or a
parallel boolean "provided" flag) when the flag is present even if empty, then
change the checks in the block that applies overrides to test that sentinel/flag
instead of isEmpty(), apply the empty value to config.forbiddenExtensions,
config.fileNameCase, config.requireAnimationNames, and config.requireBoneNames
when the sentinel indicates an explicit empty override, and ensure those entries
are added to cliRuleOverrides (keys "forbidden_extensions", "file_name_case",
"require_animation_names", "require_bone_names") when the sentinel/flag is set
so scoped rules can be cleared from the CLI.

In `@website/src/DocsApp.jsx`:
- Around line 406-409: The paragraph in DocsApp.jsx that mentions loading
qtmesh.yml/qtmesh.json underspecifies supported filenames; update the string
inside the <p className={s.para}> (the paragraph that currently references
<Code>qtmesh.yml</Code>/<Code>qtmesh.json</Code>) to also include
<Code>qtmesh.yaml</Code> so the note reads that CLI overrides are applied after
loading qtmesh.yml/qtmesh.yaml/qtmesh.json (or similar wording) to reflect the
runtime auto-detection.

---

Nitpick comments:
In `@src/CLIPipeline_test.cpp`:
- Around line 1179-1184: The test currently allows textRc == 1 which masks
failures; change the test to use a deterministic fixture/import path that
guarantees the file is loaded (a model with a skeleton but zero animations) and
assert success explicitly: replace the loose EXPECT_TRUE(textRc == 0 || textRc
== 1) with an ASSERT_EQ(textRc, 0) (and keep ASSERT_EQ(textRc, jsonRc));
additionally verify CLIPipeline::cmdAnim list mode output contains the expected
no-animation indicators (e.g. "No animations found." and "[]") so the test fails
if the loader or list-mode handling regresses.
- Around line 2134-2187: The tests calling CLIPipeline::cmdScan are inheriting
repo-local qtmesh.yml/qtmesh.yaml/qtmesh.json because they omit --config,
causing flaky exit codes; fix each test (e.g., the tests using TestArgv and
invoking CLIPipeline::cmdScan) by isolating auto-loaded config either by
wrapping the test body with ScopedCurrentDir(tmpDir.path()) or by creating a
minimal temp config file in tmpDir and passing its path via "--config" in
TestArgv so only the specific override under test (e.g., --max-vertices,
--max-file-size-mb, --allowed-formats) drives the failure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ab8d8f7a-86b9-4048-abe6-502f1a5f8ddb

📥 Commits

Reviewing files that changed from the base of the PR and between 7abe553 and ca6c23b.

📒 Files selected for processing (3)
  • src/CLIPipeline.cpp
  • src/CLIPipeline_test.cpp
  • website/src/DocsApp.jsx

Comment thread src/CLIPipeline.cpp Outdated
Comment thread website/src/DocsApp.jsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/CLIPipeline_test.cpp (1)

2134-2289: Optional: extract shared scan-fixture setup helper to reduce duplication.

The repeated temp-dir + assets + minimal OBJ setup across these tests could be wrapped in a small helper for maintainability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/CLIPipeline_test.cpp` around lines 2134 - 2289, Many tests (e.g., TESTs
MaxVerticesOverrideReturnsFailure, MaxVerticesOverrideWithEqualsReturnsFailure,
MaxFileSizeOverrideReturnsFailure, AllowedFormatsOverrideReturnsFailure,
RequireSkeletonAndAnimationsCanBeDisabledFromCli,
CliOverridesTakePrecedenceOverScopedRules, EmptyCliOverridesCanClearScopedRules)
repeat the same temp-dir + assets creation + writeMinimalObj setup; extract that
into a small helper (e.g., SetupScanTestAssets or a test fixture class like
CLIPipelineScanTest with a method setupAssets) that returns the rootPath (and
optionally config path and ScopedCurrentDir) so each TEST calls the helper and
then only prepares args and assertions, replacing the duplicated QTemporaryDir,
ScopedCurrentDir, mkdir, and writeMinimalObj blocks with a single call to the
helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@website/src/DocsApp.jsx`:
- Around line 421-425: The hardcoded summary line in DocsApp.jsx is inconsistent
with the sample findings (shows "✗ Errors: 4" while actual errors are 3); update
the rendering in the DocsApp component so the summary numbers are computed from
the same data source used for the example findings (e.g., derive
scanned/passed/warnings/errors from the findings array or the findingsSummary
object rather than hardcoding "4"), or change the hardcoded "Errors" value to
match the sample (3) so the CodeBlock output (the string that currently contains
"• Scanned: 4 ✓ Passed: 1 ▲ Warnings: 1 ✗ Errors: 4 ⏱ Time: 0.3s") is consistent
with the example details.

---

Nitpick comments:
In `@src/CLIPipeline_test.cpp`:
- Around line 2134-2289: Many tests (e.g., TESTs
MaxVerticesOverrideReturnsFailure, MaxVerticesOverrideWithEqualsReturnsFailure,
MaxFileSizeOverrideReturnsFailure, AllowedFormatsOverrideReturnsFailure,
RequireSkeletonAndAnimationsCanBeDisabledFromCli,
CliOverridesTakePrecedenceOverScopedRules, EmptyCliOverridesCanClearScopedRules)
repeat the same temp-dir + assets creation + writeMinimalObj setup; extract that
into a small helper (e.g., SetupScanTestAssets or a test fixture class like
CLIPipelineScanTest with a method setupAssets) that returns the rootPath (and
optionally config path and ScopedCurrentDir) so each TEST calls the helper and
then only prepares args and assertions, replacing the duplicated QTemporaryDir,
ScopedCurrentDir, mkdir, and writeMinimalObj blocks with a single call to the
helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1bf9bf67-fc5e-4872-a2b2-e2a21e1b57f1

📥 Commits

Reviewing files that changed from the base of the PR and between ca6c23b and 52ad93b.

📒 Files selected for processing (3)
  • src/CLIPipeline.cpp
  • src/CLIPipeline_test.cpp
  • website/src/DocsApp.jsx
✅ Files skipped from review due to trivial changes (1)
  • src/CLIPipeline.cpp

Comment thread website/src/DocsApp.jsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/CLIPipeline_test.cpp`:
- Line 1180: The test assertion expecting failure is inverted for skeletons with
zero animations: update the CLIPipeline_test.cpp assertion(s) that check
CLIPipeline::cmdAnim in list mode (the ASSERT_EQ(textRc, 1) line) to expect
success (0) instead of error (1); ensure any corresponding json-mode
assertion(s) are also changed to ASSERT_EQ(..., 0) so the test matches
CLIPipeline::cmdAnim behavior (returns 0 and emits "No animations found." or
"[]").
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e415b873-2b8c-46eb-9db5-98aca3522cff

📥 Commits

Reviewing files that changed from the base of the PR and between 52ad93b and ee045a7.

📒 Files selected for processing (2)
  • src/CLIPipeline_test.cpp
  • website/src/DocsApp.jsx
✅ Files skipped from review due to trivial changes (1)
  • website/src/DocsApp.jsx

Comment thread src/CLIPipeline_test.cpp Outdated
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant