feat(cli): Add scan defaults and compilation model caching#89
Merged
misonijnik merged 61 commits intomainfrom Apr 16, 2026
Merged
feat(cli): Add scan defaults and compilation model caching#89misonijnik merged 61 commits intomainfrom
misonijnik merged 61 commits intomainfrom
Conversation
- Remove MarkFlagRequired("output"), default SARIF to project-model/sources/
- Replace temp dir with staging dir inside model cache
- Promote staging to cache via symlink swap after successful scan
- Clean up staging dir on compilation failure
- Update printScanInfo to show "Project model (staging)"
- Add DefaultSarifReportPath and StableProjectModelPath to model_cache.go - Replace hardcoded "project-model"/"sources"/"opentaint.sarif" in scan.go - Extract cleanupStaging closure to deduplicate two identical cleanup blocks - Extract setupPruneTestGlobals helper to deduplicate test boilerplate
…er cache dir names
- Scan with default output (no --output flag) → SARIF in cache - Verify cached model directory structure (symlink, SARIF location) - Scan with no arguments (defaults to current directory) - Scan pre-compiled model without --output → SARIF in model/sources/ - Prune --dry-run lists cached models - Prune --yes removes cached models
EnsureParentDir(sarifPath) for the default path <staging>/project-model/sources/opentaint.sarif was creating project-model/ inside the staging dir before compile ran. ValidateCompileInputs then failed with "output directory already exists". Move EnsureParentDir to after compilation in CompileAndScan mode.
…output - Move symlink promotion from post-analysis to post-compilation - Analysis now runs against the stable cached model path - printScanInfo shows the final cache path, not the staging path - Recompute SARIF path after promotion to use stable model path
…al retention - Skip compilation when a valid cached model exists (project.yaml present) - Add --recompile flag to force recompilation - Implement generational retention (N=1): keep current + previous model version during promotion to protect concurrent readers - Third promotion removes the oldest generation automatically
…terference After promotion or cache reuse, resolve the project-model symlink to the actual timestamped directory (e.g. project-model-1234567890/). This pins each scan process to its own model generation so that a concurrent scan promoting a new version does not redirect the symlink out from under an in-progress analysis.
…oncurrently When no cached model exists and a .staging-* directory is present, another scan process is already compiling. Instead of starting a redundant compilation, stop with a clear message asking the user to wait or use --project-model.
… value ScanMode's zero value is Scan, so when cache reuse check fails, scanMode remained 0 (Scan) and the CompileAndScan branch was never entered, leaving absProjectModelPath empty. Use a dedicated cachedModelReused bool to guard the CompileAndScan fallthrough.
…-model/ dir Concurrent compilations are prevented by HasStagingDir, so the symlink-swap and timestamped directories are unnecessary complexity. Now PromoteStagingToCache simply replaces <cache>/project-model/ directly. Removes ~50 lines of symlink/generation management code.
The positional argument now exclusively accepts a path to project sources. A new --project-model flag allows passing a pre-compiled project model directly, replacing the previous auto-detection logic.
…rentDir Extract the three-way scan mode resolution (explicit model, dry-run, cache/staging) into a scanConfig struct and resolveScanConfig function. Replace scattered mutable variables (tempProjectModel, tempLogsDir, scanMode, projectCachePath, tempProjectModelPath) with a single cfg value. Consolidate the two EnsureParentDir calls into one placed after the compilation block, covering both scan-only and compile-and-scan modes.
Reflect the new scan behavior: source path defaults to current directory, --output is optional (defaults to cached model dir), compiled models are cached and reused, --recompile forces recompilation, --project-model replaces positional arg for pre-compiled models, and prune removes cached models.
…defaults Simplify scan command in all translation READMEs to just `opentaint scan`. Update classes-and-jars-analysis to use --project-model flag.
- Extract activateLoggingForProject() to eliminate repeated cache-path-resolution pattern across compile, project, and scan commands - Merge duplicate GetModelCacheDirPath() calls in prune into single pass that scans both models and logs in one loop - Use sync.Once for LogWriter() init to prevent check-then-assign race - Skip zero-size model entries in prune scanning (matching log behavior) - Scope logCachePath inside DryRunScan guard in scan command
Skip printing "Log file" in debug config fields and "Log" in scan summary when globals.LogPath is empty (e.g. dry-run or no logging).
Reject conflicting flag combinations early: - source-path argument with --project-model - --recompile with --project-model
Add build-system marker detection that recursively searches for Java/Kotlin build files (pom.xml, build.gradle, gradlew, etc.) up to depth 3, skipping known non-project directories. - Scan command detects project.yaml and suggests --project-model - Compile command validates markers without project.yaml check - Extensible LanguageMarkers registry for future language support - Cross-platform: includes gradlew.bat and mvnw.cmd for Windows
Return all detected languages instead of stopping at first match. Uses marker-to-language lookup map for O(1) resolution and preserves registration order from supportedLanguages.
Previously, passing a non-existent path to scan or compile produced a misleading "No supported build files found" error. Now both validators check that the directory exists first, giving a clear error message.
Print the error message first, then the actionable suggestion below it, so the user sees the problem before the remediation.
a6757ba to
f8c1389
Compare
Capitalizes the first letter of Go error strings when displaying them to users. Errors follow Go lowercase convention internally but should read as sentences in CLI output.
These errors are now capitalized at the display layer by Humanize/ErrorErr, so the source strings should follow Go convention (lowercase).
…ag factories Replace hardcoded command strings in suggestions with OpentaintCommandBuilder. Add currentScanBuilder, currentCompileBuilder, currentSummaryBuilder factories so adding a new flag requires updating only one place per command. Add CopyFlagsFrom to propagate flags to Docker builder variants automatically. - Add NewSummaryCommand, WithShowFindings, WithVerboseFlow, WithShowCodeSnippets - Add CopyFlagsFrom for creating builder variants that inherit all flags - Refactor BuildScanCommandWithDocker and BuildCompileCommandWithDocker to accept a base builder instead of individual flag parameters - Render true boolFlags as --flag instead of --flag=true
Fix typo in WithRuleset that prevented default-ruleset skip from firing, extract shared validation into validateSourceDir, simplify scan logging activation to use activateLoggingForProject consistently.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.