CLI-541 Add dependency risk analysis git push hook#339
CLI-541 Add dependency risk analysis git push hook#339georgii-borovinskikh-sonarsource wants to merge 1 commit into
Conversation
8a21400 to
43ca3d5
Compare
43ca3d5 to
a970261
Compare
a970261 to
ce6cf45
Compare
ce6cf45 to
1dcced3
Compare
1dcced3 to
7ac9ddd
Compare
ff371ad to
c23392d
Compare
43a14e5 to
52d2bb8
Compare
9b9ee42 to
ea91a8f
Compare
2da84f8 to
725d42f
Compare
| for (const legacyMarker of this.options.legacyStartMarkers ?? []) { | ||
| const legacyIndex = existing.indexOf(legacyMarker); | ||
| if (legacyIndex >= 0) { | ||
| return `${existing.slice(0, legacyIndex)}${managedBlock}\n`; | ||
| } | ||
| } |
There was a problem hiding this comment.
⚠️ Bug: Legacy marker upgrade discards user content after managed block
When renderContent encounters a legacy start marker (line 90-94), it truncates the file at that position and appends the new managed block. If the user has appended their own scripts after the old end marker (e.g. npm test after # sonar:end husky-pre-push), that content is silently lost.
This is a realistic scenario because husky hook files commonly contain multiple tool invocations. The existing regex-based replacement on line 81-82 correctly does in-place replacement preserving surrounding content, but the legacy fallback doesn't attempt to find the old end marker.
A fix would be to also try matching a regex with legacy start marker + current end marker before falling back to the slice approach.
Try regex replacement with legacy start + current end markers first (preserves content after block), fall back to slice only when no end marker is found.:
for (const legacyMarker of this.options.legacyStartMarkers ?? []) {
const legacyPattern = new RegExp(
String.raw`${escapeRegExp(legacyMarker)}[\s\S]*?${escapeRegExp(this.endMarker)}`,
);
if (legacyPattern.test(existing)) {
return existing.replace(legacyPattern, managedBlock);
}
const legacyIndex = existing.indexOf(legacyMarker);
if (legacyIndex >= 0) {
return `${existing.slice(0, legacyIndex)}${managedBlock}
`;
}
}
Was this helpful? React with 👍 / 👎
| if (options.nonInteractive) validateProjectKeyOption('--project', options.project); | ||
| validateDependencyRisksOption(options); | ||
| if (options.withDependencyRisks) { | ||
| throw new InvalidOptionError( | ||
| '--with-dependency-risks is not supported with --global; install per project instead', | ||
| ); | ||
| } |
There was a problem hiding this comment.
💡 Bug: Global validation order gives misleading error message
In integrateGitGlobal, validateDependencyRisksOption(options) is called before the --global incompatibility check. When a user passes --global --with-dependency-risks --non-interactive without --project, they get "--with-dependency-risks requires -p " instead of the more helpful "--with-dependency-risks is not supported with --global".
Swap the order so the global-specific check runs first.
Move the --global incompatibility check before the generic dependency-risks validation.:
validateHookOption(options.hook);
if (options.withDependencyRisks) {
throw new InvalidOptionError(
'--with-dependency-risks is not supported with --global; install per project instead',
);
}
if (options.nonInteractive) validateProjectKeyOption('--project', options.project);
validateDependencyRisksOption(options);
Was this helpful? React with 👍 / 👎
4635cff to
7df438c
Compare
|
Code Review
|
| Auto-apply | Compact | Unblock |
|
|
|
Was this helpful? React with 👍 / 👎 | Gitar



Summary by Gitar
--with-dependency-risksflag tointegrate gitto enable automated pre-push analysis, blocking pushes with detected risks.ScaScanOrchestratorandScaWatchPatternsRunnerusingpicomatchto manage project scanning, version verification, and targeted manifest analysis.sonarScaScannerBinaryDependencyand integratedupdateScaScannerBinaryIfNeededinto thepost-updateworkflow for automated updates.pre-pushhandlers.This will update automatically on new commits.