Skip to content

CLI-614 Add hook markers migration#404

Open
georgii-borovinskikh-sonarsource wants to merge 9 commits into
masterfrom
gb/migrate-hook-scripts
Open

CLI-614 Add hook markers migration#404
georgii-borovinskikh-sonarsource wants to merge 9 commits into
masterfrom
gb/migrate-hook-scripts

Conversation

@georgii-borovinskikh-sonarsource

@georgii-borovinskikh-sonarsource georgii-borovinskikh-sonarsource commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Part of CLI-505


Summary by Gitar

  • Git Hook Migration:
    • Transitioned from a single legacy sonar-secrets ID to per-stage IDs (sonar-pre-commit, sonar-pre-push) to allow concurrent hook management.
    • Introduced declarative legacyCleanups to handle idempotency and migration of old hook artifacts.
  • Resource Management:
    • Added a formal RemovableResource interface to decouple and standardize the cleanup of legacy hooks and patches.
    • Refactored TextSnippet, WholeFile, and various patch resources to use dedicated remover classes for safer, idempotent cleanup.
  • Hook Identification:
    • Introduced markers.ts to manage distinct framework-aware markers for Git hooks, replacing a single global marker for improved detection and separation.
  • UX Improvements:
    • Standardized error messages for file overwrites to remove prescriptive --force advice, providing cleaner remediation hints instead.

This will update automatically on new commits.

@hashicorp-vault-sonar-prod hashicorp-vault-sonar-prod Bot changed the title Add hook markers migration CLI-614 Add hook markers migration Jun 5, 2026
@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Jun 5, 2026

Copy link
Copy Markdown

CLI-614

Comment thread tests/unit/cli/commands/integrate/git/git-native-resource.test.ts
Base automatically changed from gb/change-precommit-framework to master June 8, 2026 10:28
Comment thread src/cli/command-tree.ts
Comment thread src/cli/commands/integrate/git/tools/pre-commit/config.ts
Comment thread src/cli/commands/integrate/git/tools/pre-commit/index.ts
@netlify

netlify Bot commented Jun 9, 2026

Copy link
Copy Markdown

Deploy Preview for sonarqube-cli ready!

Name Link
🔨 Latest commit 960e258
🔍 Latest deploy log https://app.netlify.com/projects/sonarqube-cli/deploys/6a2a9f12bc661e0008138876
😎 Deploy Preview https://deploy-preview-404--sonarqube-cli.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread src/cli/commands/integrate/_common/registry/resources/text-snippet.ts Outdated
Comment thread src/cli/commands/integrate/git/tools/pre-commit/config.ts
Base automatically changed from gb/eol-preserve-line-endings to master June 10, 2026 09:45
After rebasing onto the EOL branch (which tracks current master), the
`install-integration.ts` file picked up an `onFeatureApplyStart` callback
call from master that the pre-rebase `installer.ts` didn't declare.

Restores the `<TOptions>` generic on `ApplyFeatureCallbacks`, adds
`onFeatureApplyStart`, and propagates the generic to all call-sites so
the feature-start text display works correctly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gitar-bot

gitar-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 6 resolved / 6 findings

Migration of legacy Git hooks to stage-specific IDs is implemented alongside a new declarative cleanup framework. All reported issues regarding incorrect error messaging, migration logic, and resource cleanup were addressed.

✅ 6 resolved
Bug: Native hook test asserts a message the code never throws

📄 tests/unit/cli/commands/integrate/git/git-native-resource.test.ts:92-102 📄 src/cli/commands/integrate/_common/registry/resources/whole-file.ts:126-129
The new test 'refuses to overwrite a foreign hook without --force' asserts error.message toContain 'was not created by Sonar'. But the native git hook now uses the generic wholeFile resource, whose assertOverwriteAllowed throws A different ${label} already exists at ${path}. (whole-file.ts:127). No code path produces the string 'was not created by Sonar'. Because the test uses expect.assertions(2), the second assertion (toContain('was not created by Sonar')) will fail, breaking this test.

Note the sibling tests updated in this same PR (installer.test.ts and registry.test.ts) were changed to expect A different pre-commit hook already exists at ..., confirming the intended message — this test was simply not updated to match.

Quality: git-pre-push argument help text references pre-commit

📄 src/cli/command-tree.ts:511
The new [files...] argument on the git-pre-push command uses the description 'Changed files passed by pre-commit (pass_filenames: true)', copied verbatim from the git-pre-commit command. On a pre-push hook this is misleading — the files are passed by the pre-push hook, not pre-commit. Consider updating the help text to reference pre-push for accuracy.

Edge Case: inferStage can throw on a sonar entry missing 'entry'

📄 src/cli/commands/integrate/git/tools/pre-commit/config.ts:97-111 📄 src/cli/commands/integrate/git/tools/pre-commit/config.ts:168-182
inferStage unconditionally reads entry.entry.includes(...) after the stages checks fall through. It is invoked from upsertSonarHook and removeSonarHook on any hook whose id === 'sonar-secrets' (the legacy id). The config comes from arbitrary user-authored YAML (normalizePreCommitConfig only validates repos is an array — individual hook entries are not validated). A user-edited or malformed sonar-secrets entry that has no entry field (or a non-string entry) would make entry.entry.includes throw a TypeError, aborting integrate git install/uninstall with an unhandled crash rather than a graceful CliError. Guard the access, e.g. typeof entry.entry === 'string' && entry.entry.includes('git-pre-push').

Bug: Uninstall no longer cleans legacy repo / empty local repo

📄 src/cli/commands/integrate/git/tools/pre-commit/index.ts:64-69 📄 src/cli/commands/integrate/git/tools/pre-commit/config.ts:181-191
The removePatch previously called removeSonarHooksFromPreCommitConfig, which (per its doc) also dropped the legacy remote repo (sonar-secrets-pre-commit) and removed an empty local repo entry after stripping sonar hooks. The new removeSonarHook only filters the per-stage/legacy hook out of the local repo. As a result, uninstalling git integration that was originally installed by an older version (which added the legacy remote repo: sonar-secrets-pre-commit) leaves that legacy repo entry behind, and a local repo emptied of all sonar hooks remains as { repo: 'local', hooks: [] }. If leaving these is intentional, ignore; otherwise consider calling removeLegacyHook and pruning an empty local repo in the remove path as before.

Edge Case: Legacy sonar-secrets entry without stages is never migrated

📄 src/cli/commands/integrate/git/tools/pre-commit/config.ts:96-105 📄 src/cli/commands/integrate/git/tools/pre-commit/config.ts:155-169
upsertSonarHook only migrates a legacy sonar-secrets entry when inferStage(h) === stage, and inferStage returns undefined for an entry that has no stages array. Likewise removeLegacySonarHook filters on inferStage(h) === stage. So a stage-less legacy sonar-secrets hook is neither replaced in place nor cleaned up: on migration the CLI appends a new per-stage entry (sonar-pre-commit) while leaving the stage-less sonar-secrets entry in the config. Since pre-commit treats an entry without stages as applying to the default stages, the same scan can then run twice (legacy + new per-stage) on pre-commit.

Entries written by prior CLI versions always set stages, so this only affects hand-edited configs and is low-likelihood — hence minor. Consider treating a stage-less legacy entry as matching the pre-commit stage (or both stages) during migration/cleanup so it is replaced rather than duplicated.

...and 1 more resolved from earlier reviews

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@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