feat(cli): exit 0 with valid empty output when no source files found#691
Merged
Conversation
Today `pathfinder scan` errors out with exit 1 and "no source files
found in project" the moment the file walk returns zero supported
files. That misclassifies "we don't analyze this language yet" as a
scanner failure: cpf-executor flags the job as failed, the dashboard
shows a red error, and CI runs against docs-only PRs go red for no
reason. `pathfinder ci` already handled this case gracefully; this
brings scan in line and upgrades the message on both.
What changes:
- `getFiles` now returns a ProjectStats summary alongside the file
list: TotalFiles, ScannedFiles, and a language-name -> count map
covering everything the walk saw (supported and unsupported). The
always-skipped dirs (vendor, node_modules, .git, build, ...) are
still excluded from counts so the "Detected:" line stays honest.
- CodeGraph carries the stats so scan/ci can render a multi-line
empty-project explanation when the graph ends up with zero nodes:
Scanned 0 of 91 files (71 unsupported).
Detected: TypeScript (37), SQL (15), JavaScript (6), JSON (5), Markdown (4)
Supported: Java, Python, Go, C/C++, Dockerfile, docker-compose
No files to analyze. (Pathfinder doesn't analyze these languages yet.)
- scan.go no longer returns an error in this case. It logs the block
above and falls through to the formatter step so a valid empty
JSON/CSV/SARIF document is still written to --output-file. Exit
code stays 0.
- ci.go uses the same helper for consistency (previously it printed a
single verbose-only line).
- New `Logger.Info` method for always-shown, prefix-free status
messages (the existing Progress is gated to --verbose, Warning
prepends "Warning:", neither fit this case).
Verified end-to-end against getpathfinder/pathfinder-api (a TypeScript
worker repo that triggered this bug in prod): the binary now exits 0,
prints the explanation above, and emits a parseable empty document in
all three machine formats.
Test coverage:
- graph/project_stats_test.go: 100% on every new function (languageOf,
SupportedLanguages, recordFile, UnsupportedFileCount,
UnsupportedSummary). Covers happy paths, tied counts, topN cap,
unsupported-language exclusion, defensive-copy behavior.
- graph/utils_test.go: three new tests for ProjectStats output of
getFiles (only-unsupported, mixed, skip-dirs-not-counted).
- cmd/empty_project_test.go: covers all three branches of the message
builder plus the Info-at-default-verbosity guarantee.
- output/logger_test.go: direct test of Info at every verbosity level.
go vet clean, golangci-lint clean (0 issues).
SafeDep Report SummaryNo dependency changes detected. Nothing to scan. This report is generated by SafeDep Github App |
Code Pathfinder Security ScanNo security issues detected.
Powered by Code Pathfinder |
Pathfinder Report✅ No security findings on the changed files. This pull request is clean. Powered by Code Pathfinder. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #691 +/- ##
==========================================
+ Coverage 85.44% 85.53% +0.08%
==========================================
Files 188 190 +2
Lines 27333 27467 +134
==========================================
+ Hits 23355 23494 +139
+ Misses 3086 3082 -4
+ Partials 892 891 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.



Summary
Today
pathfinder scanexits 1 withno source files found in projectas soon as the file walk finds zero supported files. That misclassifies "we don't analyze this language yet" as a scanner failure: cpf-executor flags the job as failed, the dashboard shows a red error card, and CI runs against docs-only PRs go red for no reason.pathfinder cialready handled this case (logged a single line and continued); this PR brings scan in line and upgrades the message on both commands.What the user now sees
Run against
getpathfinder/pathfinder-api(TypeScript Cloudflare Worker, the repo that triggered this in prod):CSV and SARIF outputs also emit complete, parseable empty documents.
What changed
getFilesreturns aProjectStats(TotalFiles, ScannedFiles, ByLanguage map) alongside the file list. Files inside always-skipped dirs (vendor/,node_modules/,.git/, build artifact dirs, ...) and--excludeprefixes are intentionally not counted, so the "Detected:" line reflects what the user expected pathfinder to look at.CodeGraphcarries the stats so scan/ci can render the multi-line empty-project message.scan.gono longer returns an error whenlen(codeGraph.Nodes) == 0. It logs the explanation and falls through to the formatter step so a valid empty JSON/CSV/SARIF document is still written. Exit 0.ci.gouses the same helper for consistency (previously printed a single verbose-only line).Logger.Infomethod for always-shown, prefix-free messages. The existingProgressis gated to--verbose,WarningprependsWarning:, neither fit this case.Test plan
go test ./...passes (all packages green).go vet ./...clean.golangci-lint run ./graph/ ./cmd/ ./output/reports 0 issues.languageOf,SupportedLanguages,recordFile,UnsupportedFileCount,UnsupportedSummary,reportEmptyProject,emptyProjectMessage,Logger.Info).cpf-api(TypeScript) verifies exit 0, valid JSON/CSV/SARIF output, and the exact message format above.cpf-apiviapathfinder ci --output json --output-file ci.jsonverifies the ci path uses the same message + valid empty output.getFilescallers (8 ingraph_test.go, 5 inutils_test.go) updated for the new 3-value return signature, all still pass.