feat: decorator for duplicated commands detection - #1300
feat: decorator for duplicated commands detection#1300André Jordan (andjordan) wants to merge 4 commits into
Conversation
Dependency ReviewThe following issues were found:
Snapshot WarningsConsider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. License Issuesinfra/syntax/CMakeLists.txt
external/crypto/mbedtls/CMakeLists.txt
external/crypto/micro-ecc/CMakeLists.txt
osal/freertos/CMakeLists.txt
external/crypto/tiny-aes128/CMakeLists.txt
cmake/emil_test_helpers.cmake
osal/threadx/CMakeLists.txt
external/segger_rtt/CMakeLists.txt
lwip/lwip/CMakeLists.txt
external/protobuf/CMakeLists.txt
external/args/CMakeLists.txt
OpenSSF ScorecardScorecard details
Scanned Files
|
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|
| ✅ ACTION | actionlint | 11 | 0 | 0 | 0.28s | |
| ✅ ACTION | zizmor | 11 | 0 | 0 | 0 | 4.41s |
| ✅ CPP | clang-format | 1098 | 8 | 0 | 0 | 9.24s |
| ✅ DOCKERFILE | hadolint | 2 | 0 | 0 | 0.05s | |
| ✅ JSON | jsonlint | 7 | 0 | 0 | 0.35s | |
| ✅ JSON | prettier | 7 | 0 | 0 | 0 | 0.54s |
| markdownlint | 8 | 0 | 5 | 0 | 1.21s | |
| ✅ MARKDOWN | markdown-table-formatter | 8 | 0 | 0 | 0 | 0.25s |
| betterleaks | yes | 1 | 5 | 1.35s | ||
| ✅ REPOSITORY | checkov | yes | no | no | 33.53s | |
| ✅ REPOSITORY | git_diff | yes | no | no | 0.09s | |
| ✅ REPOSITORY | grype | yes | no | no | 71.36s | |
| ✅ REPOSITORY | ls-lint | yes | no | no | 0.01s | |
| ✅ REPOSITORY | osv-scanner | yes | no | no | 0.65s | |
| ✅ REPOSITORY | secretlint | yes | no | no | 16.27s | |
| ✅ REPOSITORY | syft | yes | no | no | 1.9s | |
| ✅ REPOSITORY | trivy | yes | no | no | 20.16s | |
| ✅ REPOSITORY | trivy-sbom | yes | no | no | 0.28s | |
| ✅ REPOSITORY | trufflehog | yes | no | no | 4.55s | |
| lychee | 140 | 1 | 0 | 117.0s | ||
| prettier | 21 | 1 | 1 | 0 | 0.62s | |
| ✅ YAML | v8r | 21 | 0 | 0 | 9.0s | |
| ✅ YAML | yamllint | 21 | 0 | 0 | 0.79s |
Detailed Issues
⚠️ REPOSITORY / betterleaks - 1 error
warning: generic-api-key has detected secret for file external/crypto/tiny-aes128/TinyAes.c.
┌─ external/crypto/tiny-aes128/TinyAes.c:17:4
│
17 │ key:
│ ╭────^
18 │ │ 2b7e151628aed2a6abf7158809cf4f3c
│ ╰────────────────────────────────────^
warning: generic-api-key has detected secret for file services/network/WebSocket.cpp.
┌─ services/network/WebSocket.cpp:81:50
│
81 │ headers.push_back(services::HttpHeader("Sec-Websocket-Key", "AQIDBAUGBbgJCgsMDQ4PEC=="));
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: private-key has detected secret for file services/network/CertificatesMbedTls.cpp.
┌─ services/network/CertificatesMbedTls.cpp:125:21
│
125 │ stream << "HIDDEN_BY_MEGALINTER\r\n";
│ ╰────────────────────────────────────────────────^
warning: private-key has detected secret for file services/network/test_doubles/Certificates.cpp.
┌─ services/network/test_doubles/Certificates.cpp:56:15
│
56 │ "HIDDEN_BY_MEGALINTER\r\n";
│ ╰──────────────────────────────────────────^
warning: private-key has detected secret for file services/network/test_doubles/Certificates.cpp.
┌─ services/network/test_doubles/Certificates.cpp:108:15
│
108 │ "HIDDEN_BY_MEGALINTER\r\n";
│ ╰──────────────────────────────────────────^
warning: 5 warnings emitted
⚠️ SPELL / lychee - 1 error
📝 Summary
---------------------
🔍 Total..........697
🔗 Unique.........661
✅ Successful.....691
⏳ Timeouts.........0
🔀 Redirected.....310
👻 Excluded.........5
❓ Unknown..........0
🚫 Errors...........1
⛔ Unsupported......1
Errors in external/protoc/CMakeLists.txt
[404] https://github.com/protocolbuffers/protobuf/releases/download/v$%7Bprotobuf_tag%7D/protoc-$%7Bprotobuf_version%7D-$%7Bos_postfix%7D.zip (at 18:13) | Rejected status code: 404 Not Found
Hint: Followed 310 redirects. You might want to consider replacing redirecting URLs with the resolved URLs. Use verbose mode (`-v`/`-vv`) to see redirection details.
Hint: You can configure accepted/rejected response codes with `-a` or `--accept`
⚠️ MARKDOWN / markdownlint - 5 errors
.github/instructions/microtest.instructions.md:7 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "## Google Test Suite Coding Ru..."]
external/crypto/tiny-aes128/README.md:1 error MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "### Tiny AES128 in C"]
external/crypto/tiny-aes128/README.md:29 error MD046/code-block-style Code block style [Expected: fenced; Actual: indented]
external/crypto/tiny-aes128/README.md:39 error MD046/code-block-style Code block style [Expected: fenced; Actual: indented]
external/crypto/tiny-aes128/README.md:49 error MD046/code-block-style Code block style [Expected: fenced; Actual: indented]
⚠️ YAML / prettier - 1 error
[error] Explicitly specified pattern "documents/modules/ROOT/examples/clangformat.yaml" is a symbolic link.
.clusterfuzzlite/project.yaml 46ms (unchanged)
.github/dependabot.yml 16ms (unchanged)
.github/workflows/ci.yml 64ms (unchanged)
.github/workflows/dependency-scanner.yml 12ms (unchanged)
.github/workflows/documentation.yml 10ms (unchanged)
.github/workflows/fuzzing-batch.yml 5ms (unchanged)
.github/workflows/fuzzing-cron.yml 7ms (unchanged)
.github/workflows/fuzzing-pr.yml 8ms (unchanged)
.github/workflows/linting-formatting.yml 12ms (unchanged)
.github/workflows/release-please.yml 7ms (unchanged)
.github/workflows/security.yml 4ms (unchanged)
.github/workflows/static-analysis.yml 10ms (unchanged)
.github/workflows/validate-pr.yml 14ms (unchanged)
.ls-lint.yml 2ms
.mega-linter.yml 2ms (unchanged)
antora-playbook-branch.yml 2ms (unchanged)
antora-playbook-site.yml 3ms (unchanged)
documents/antora.yml 2ms (unchanged)
documents/supplemental-ui/ui.yml 1ms (unchanged)
mull.yml 1ms (unchanged)
Notices
📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)
See detailed reports in MegaLinter artifacts
Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)
- Documentation: Custom Flavors
- Command:
npx mega-linter-runner@9.6.0 --custom-flavor-setup --custom-flavor-linters ACTION_ACTIONLINT,ACTION_ZIZMOR,CPP_CLANG_FORMAT,DOCKERFILE_HADOLINT,JSON_JSONLINT,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_BETTERLEAKS,REPOSITORY_GRYPE,REPOSITORY_LS_LINT,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,SPELL_LYCHEE,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

Show us your support by starring ⭐ the repository
There was a problem hiding this comment.
Pull request overview
This PR adds a TerminalWithCommands decorator that detects conflicting (duplicate) terminal command names across registered TerminalCommands observers, aborting at runtime when a conflict is found. It also adds unit tests validating forwarding behavior and duplicate-detection behavior.
Changes:
- Introduces
services::TerminalWithCommandsDuplicateDetectorto validate uniqueness of command long/short names across observers. - Implements deferred (event-dispatched) evaluation after observer registration to catch duplicates introduced during registration bursts.
- Adds tests covering forwarding of observers to the delegate terminal and aborting on various conflict scenarios.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| services/util/test/TestTerminal.cpp | Adds a new test fixture and test cases for duplicate command detection, including death tests for conflicts. |
| services/util/Terminal.hpp | Declares the new TerminalWithCommandsDuplicateDetector decorator type. |
| services/util/Terminal.cpp | Implements duplicate detection logic and deferred evaluation scheduling on observer registration. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (1)
services/util/test/TestTerminal.cpp:518
- The new death tests should be disabled under EMIL_MUTATION_TESTING, consistent with the rest of the test suite (death tests are slow and can crash the mutation test runner). Wrap this block in
#ifndef EMIL_MUTATION_TESTING/#endif.
TEST_F(TerminalWithCommandsDuplicateDetectorTest, aborts_when_new_long_name_matches_existing_long_name)
{
EXPECT_DEATH(RegisterConflictingObserversAndDispatch("alpha", "a", "alpha", "b"), "Duplicate terminal command 'alpha'.*existing command 'alpha'");
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
services/util/test/TestTerminal.cpp:496
- Death tests should be guarded with
#ifndef EMIL_MUTATION_TESTINGto avoid running during mutation testing (per test guidelines).
#ifndef EMIL_MUTATION_TESTING
TEST_F(TerminalWithCommandsDuplicateDetectorTest, aborts_when_new_long_name_matches_existing_long_name)
{
EXPECT_DEATH(RegisterConflictingObserversAndDispatch("alpha", "a", "alpha", "b"), "");
| if (!evaluationScheduled) | ||
| { | ||
| evaluationScheduled = true; | ||
| infra::EventDispatcher::Instance().Schedule([this]() | ||
| { | ||
| evaluationScheduled = false; | ||
| EvaluateDuplicateCommands(); | ||
| }); | ||
| } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (2)
services/util/Terminal.cpp:69
- EvaluateDuplicateCommands() skips comparisons when &existingObserver == &newObserver, which means duplicate command names within a single TerminalCommands implementation are never detected (only duplicates across observers are). This can still lead to ambiguous command resolution (ProcessCommand will pick the first match). Consider adding an intra-observer duplicate check before comparing against other observers.
delegate.NotifyObservers([&newObserver, &newCommand](TerminalCommands& existingObserver)
{
if (&existingObserver != &newObserver)
for (const auto& existingCommand : existingObserver.Commands())
services/util/Terminal.cpp:44
- The duplicate evaluation is only triggered from RegisterObserver(). If the delegate already has TerminalCommands observers attached before this decorator is constructed, those existing registrations will never be evaluated (unless another observer is registered later). If the intent is to enforce uniqueness across all currently registered observers, consider performing an initial evaluation in the constructor.
This issue also appears on line 66 of the same file.
TerminalWithCommandsDuplicateDetector::TerminalWithCommandsDuplicateDetector(TerminalWithCommands& delegate)
: delegate(delegate)
{}
|



Pull request overview
This PR adds a
TerminalWithCommandsdecorator that detects conflicting (duplicate) terminal command names across registeredTerminalCommandsobservers, aborting at runtime when a conflict is found. It also adds unit tests validating forwarding behavior and duplicate-detection behavior.Changes:
services::TerminalWithCommandsDuplicateDetectorto validate uniqueness of command long/short names across observers.