Skip to content

feat(scan): platform profile JSON loader and ScanConfig merge (#362) - #682

Merged
fernandotonon merged 5 commits into
masterfrom
feat/platform-profile-362
May 28, 2026
Merged

feat(scan): platform profile JSON loader and ScanConfig merge (#362)#682
fernandotonon merged 5 commits into
masterfrom
feat/platform-profile-362

Conversation

@fernandotonon

@fernandotonon fernandotonon commented May 27, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds bundled platform validation presets under profiles/ with a PlatformProfileLoader that resolves built-in ids, file paths, and extends inheritance.
  • Merges profiles into ScanConfig in order: defaults → profile → project config → CLI flags.
  • Wires qtmesh scan --profile <id>, profile: in qtmesh.yml, and --list-profiles.

Test plan

  • UnitTests --gtest_filter="PlatformProfile*:ApplyPlatformProfile*" (9 tests)
  • UnitTests --gtest_filter="ScanConfig*" (37 tests)
  • ./qtmesh scan --list-profiles lists example-base and example-minimal
  • CI green on Linux / Windows / macOS

Closes #362

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Added platform profiles for reusable validation rule bundles.
    • New CLI options to select a profile and to list available profiles.
    • Configuration precedence updated: defaults → platform profile → project config → CLI flags.
    • Included example profiles (base and minimal) for inheritance and presets.
  • Documentation

    • Example configuration and docs updated to show profile usage.
  • Tests

    • Added tests covering profile loading, inheritance, warnings, and application.

Review Change Stack

Introduce bundled JSON validation presets with inheritance, merge into
ScanConfig after defaults, and wire qtmesh scan --profile / profile: in
project config ahead of local rules and CLI overrides.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented May 27, 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: 9449af4a-d4d4-4c0e-a81b-8484b4d94f81

📥 Commits

Reviewing files that changed from the base of the PR and between 780077b and 64fdec5.

📒 Files selected for processing (7)
  • CMakeLists.txt
  • profiles/CMakeLists.txt
  • src/CLIPipeline.cpp
  • src/PlatformProfile.cpp
  • src/PlatformProfile_test.cpp
  • src/ScanConfig.cpp
  • tests/CMakeLists.txt
✅ Files skipped from review due to trivial changes (1)
  • profiles/CMakeLists.txt
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/PlatformProfile_test.cpp
  • src/PlatformProfile.cpp
  • src/ScanConfig.cpp

📝 Walkthrough

Walkthrough

Introduces platform profiles: JSON profile files, a loader API, applyPlatformProfile, ScanConfig refactor for project-file application, CLI flags --profile/--list-profiles, CMake staging of profiles/, example profiles, and tests; config precedence is defaults → platform profile → project config → CLI flags.

Changes

Platform Profile Foundation

Layer / File(s) Summary
Platform Profile Data Model & Loader API
src/PlatformProfile.h
PlatformProfile struct and PlatformProfileLoadResult; PlatformProfileLoader API to load by ID/path, list builtin IDs, resolve builtin directory, and expose known rule keys; applyPlatformProfile declaration and docs.
Profile Loader Implementation - Parsing, Inheritance & Discovery
src/PlatformProfile.cpp
Implements known-rule allowlist, builtin profiles directory probing, JSON parsing with top-level whitelist, file I/O error reporting, recursive extends resolution with cycle detection, merging overlay semantics, and listing builtin IDs.
Profile Application to ScanConfig
src/PlatformProfile.cpp
applyPlatformProfile() applies profile rules and scopes into an existing ScanConfig, filters unknown rule keys with warnings, and respects scope _order.
ScanConfig Config Layering API
src/ScanConfig.h, src/ScanConfig.cpp
Adds loadProjectMapFromFile() (JSON/YAML → QVariantMap) and applyProjectConfig() to merge scan, rules, scopes, fix, and report onto an existing ScanConfig; fromVariantMap()/loadFromFile() now delegate to these helpers.
CLI Integration - Profile Flag Support & Config Flow Refactoring
src/CLIPipeline.cpp
Adds --profile <id> and --list-profiles to qtmesh scan; updates help text to show precedence (defaults → platform profile → project config → CLI flags); refactors cmdScan to initialize from defaults, load/apply platform profile, apply project config, then CLI overrides.
Build Configuration & Asset Deployment
CMakeLists.txt, src/CMakeLists.txt, profiles/CMakeLists.txt, tests/CMakeLists.txt
Adds PlatformProfile.cpp/.h to source lists, includes profiles subdirectory, bundles profiles/*.json into runtime output, stages profiles/ alongside media/ in post-build copy for main and UnitTests, and compiles PlatformProfile into tests.
Example Profiles & Documentation
profiles/example-base.json, profiles/example-minimal.json, qtmesh.example.yml, CLAUDE.md
Adds two example profiles (base + minimal inheriting base), comments in example config for profile: example-minimal, and CLI example lines for --profile and --list-profiles.
Comprehensive Test Coverage for Profiles
src/PlatformProfile_test.cpp
GTest suite covering loading by ID and file, inheritance, missing/invalid/circular errors, unknown-key warnings/filtering, listBuiltinIds, id-mismatch rejection, and applyPlatformProfile merge behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • #362: Implements the platform-profile JSON schema, loader, apply API, CLI flag support, merge-order behavior, example profiles, and tests described by the issue.

Possibly related PRs

Poem

🐰 I bundled rules in JSON nests,
so scans can pick their cozy vests.
Defaults first, then profiles sing,
projects tweak—the CLI is king! 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(scan): platform profile JSON loader and ScanConfig merge (#362)' clearly and concisely summarizes the main change: introducing platform profile loading and configuration merging for the scan CLI.
Description check ✅ Passed The PR description includes a clear summary of the solution, technical details of what was implemented, and a comprehensive test plan with specific test command examples. It links to the related issue #362.
Linked Issues check ✅ Passed All major requirements from issue #362 are met: JSON profile schema defined and implemented [profiles/example-base.json, profiles/example-minimal.json], PlatformProfile type and loader implemented [src/PlatformProfile.h/cpp], merge order (defaults → profile → project config → CLI) implemented [src/CLIPipeline.cpp, src/ScanConfig.cpp], config integration wired [--profile, --list-profiles, profile: in qtmesh.yml], comprehensive unit tests added [src/PlatformProfile_test.cpp], and unknown keys handled with warnings.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #362 objectives: profile JSON files, loader implementation, ScanConfig merge API, CLI/config integration, build configuration updates, and unit tests. No extraneous changes detected.

✏️ 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 feat/platform-profile-362

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: 780077b94b

ℹ️ 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/CMakeLists.txt
Comment on lines +446 to +448
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/profiles
$<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>/profiles

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Install bundled profiles with packaged binaries

This post-build copy makes --profile/--list-profiles work from the build tree, but I checked the install/package rules: the top-level install(TARGETS ...) only installs the binary to bin, and there is no matching install(DIRECTORY profiles ...) like media/CMakeLists.txt has for media. In installed DEB/CPack builds, QCoreApplication::applicationDirPath() will be the installed binary directory and none of the searched profiles locations will exist, so qtmesh scan --list-profiles returns “No built-in platform profiles found” and built-in profile ids cannot be used unless users manually provide QTMESH_PROFILES_DIR.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Installed bundled profiles by adding \ + , so packaged installs get \ like the build tree.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Installed bundled profiles by adding profiles/CMakeLists.txt + ADD_SUBDIRECTORY(profiles), so packaged installs get <bin>/profiles/*.json like the build tree.

@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: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/CLIPipeline.cpp`:
- Around line 3989-3999: The list-profiles early-exit and the config/profile
source selection paths lack Sentry breadcrumbs; add
SentryReporter::addBreadcrumb calls: when handling the listProfiles branch
(before printing and before returning) call
SentryReporter::addBreadcrumb("ui.action", "cli: list-profiles (found N
profiles)") and include the directory via
PlatformProfileLoader::builtinProfilesDirectory(); for each config/profile
selection branch (the config flag branch, the local auto-config branch, and the
profile load branch referenced around the other config/profile branches) add
breadcrumbs like SentryReporter::addBreadcrumb("file.import", "config: loaded
from --config <path>"), SentryReporter::addBreadcrumb("file.import", "config:
loaded from local auto-config"), and
SentryReporter::addBreadcrumb("ai.tool_call", "profile: loaded <profileId>")
respectively; place these calls near the existing cliWrite/return points and
where PlatformProfileLoader::listBuiltinIds() or the config/profile resolution
occurs so Sentry has a clear trace of user-visible actions.

In `@src/PlatformProfile.cpp`:
- Around line 152-174: The profile discovery functions lack Sentry
breadcrumbs—add SentryReporter::addBreadcrumb(...) calls to record key
user-facing actions and failures: in
PlatformProfileLoader::builtinProfilesDirectory() add a breadcrumb when a
candidate directory is checked (category "file.import" or "ui.action" with
message indicating the candidate path) and another breadcrumb when a directory
is found (e.g., "builtin profiles directory found: <path>"); in
PlatformProfileLoader::listBuiltinIds() add a breadcrumb at function entry
(category "file.import" message "listBuiltinIds called"), a breadcrumb when
dirPath is empty/failure (category "file.import" message "no builtin profiles
directory"), and a breadcrumb after collecting ids (category "file.import"
message "found N builtin profiles"), using the actual values (dirPath, count) in
the message to aid diagnostics and ensure calls reference
SentryReporter::addBreadcrumb directly.
- Around line 61-67: warnUnknownRuleKeys is being called and then
filterKnownRuleKeys emits the same warnings again, producing duplicates for
scope.pathPattern; fix by ensuring unknown-rule warnings are emitted only once:
call warnUnknownRuleKeys(rawRules, QStringLiteral("profile scope
'%1'").arg(scope.pathPattern), warnings) once, then make
filterKnownRuleKeys(rawRules, QStringLiteral("profile scope
'%1'").arg(scope.pathPattern), warnings) skip emitting warnings (either add a
suppressWarnings/skipWarnings parameter or remove its internal warning logic)
and return the filtered rules to assign to scope.rules to avoid double-reporting
the same keys.
- Around line 263-271: The code currently only assigns result.profile.id from
displayIdHint when id is missing, allowing a built-in profile to declare a
conflicting id; update the logic to detect and reject mismatched ids early:
after parsing (where result.profile.id is available) add a check that if
displayIdHint is non-empty and result.profile.id is non-empty and
result.profile.id != displayIdHint then set result.error (include absolutePath,
result.profile.id and displayIdHint in the message) and return result so
conflicting built-in ids are refused rather than silently accepted.

In `@src/ScanConfig.cpp`:
- Around line 392-412: In ScanConfig::loadProjectMapFromFile add Sentry
breadcrumbs around the file import/parse flow: call
SentryReporter::addBreadcrumb("file.import",
QString("open_attempt:%1").arg(path)) before attempting QFile::open,
addBreadcrumb("file.import", QString("open_failed:%1").arg(path)) on the open
failure branch, addBreadcrumb("file.import",
QString("parse_attempt:%1").arg(path)) before parsing, then on parse success
call addBreadcrumb("file.import", QString("parse_success:%1").arg(path)) and on
parse failure (both JSON invalid branch and any parse error from
parseSimpleYaml) call addBreadcrumb("file.import",
QString("parse_failed:%1").arg(path)) so open/parse attempts and outcomes for
ScanConfig::loadProjectMapFromFile are recorded.
🪄 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: 51c30dab-de68-4a5a-a36e-ba5149b6dbc7

📥 Commits

Reviewing files that changed from the base of the PR and between fb1299f and 780077b.

📒 Files selected for processing (11)
  • CLAUDE.md
  • profiles/example-base.json
  • profiles/example-minimal.json
  • qtmesh.example.yml
  • src/CLIPipeline.cpp
  • src/CMakeLists.txt
  • src/PlatformProfile.cpp
  • src/PlatformProfile.h
  • src/PlatformProfile_test.cpp
  • src/ScanConfig.cpp
  • src/ScanConfig.h

Comment thread src/CLIPipeline.cpp
Comment thread src/PlatformProfile.cpp Outdated
Comment thread src/PlatformProfile.cpp
Comment thread src/PlatformProfile.cpp
Comment thread src/ScanConfig.cpp
fernandotonon and others added 4 commits May 27, 2026 18:59
- Add PlatformProfile.cpp to tests/CMakeLists TEST_SRC_FILES (fixes CI link).
- Install bundled profiles/ with packaged binaries.
- Reject built-in profile id mismatches; dedupe scope rule warnings.
- Add Sentry breadcrumbs for scan profile/config paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use QTMESH_PROFILES_DIR so the loader resolves by id and exercises
the displayIdHint mismatch guard.

Co-authored-by: Cursor <cursoragent@cursor.com>
QVERIFY is a Qt Test macro; PlatformProfile_test uses Google Test.

Co-authored-by: Cursor <cursoragent@cursor.com>
Emit breadcrumbs for scan config open/parse outcomes and platform profile
load/list/apply steps to improve diagnosability.

Co-authored-by: Cursor <cursoragent@cursor.com>
@fernandotonon
fernandotonon merged commit 6407313 into master May 28, 2026
13 of 14 checks passed
@fernandotonon
fernandotonon deleted the feat/platform-profile-362 branch May 28, 2026 03:35
@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.

Platform profile: JSON schema, loader, and ScanConfig application API

1 participant