Skip to content

feat(cli): exit 0 with valid empty output when no source files found#691

Merged
shivasurya merged 1 commit into
mainfrom
shiva/empty-project-graceful-exit
May 22, 2026
Merged

feat(cli): exit 0 with valid empty output when no source files found#691
shivasurya merged 1 commit into
mainfrom
shiva/empty-project-graceful-exit

Conversation

@shivasurya

Copy link
Copy Markdown
Owner

Summary

Today pathfinder scan exits 1 with no source files found in project as 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 ci already 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):

$ pathfinder scan --project ~/src/shivasurya/cpf-api --rules ./rules --output json --output-file out.json
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.)
$ echo $?
0
$ jq '.results, .summary.total' out.json
[]
0

CSV and SARIF outputs also emit complete, parseable empty documents.

What changed

  • getFiles returns a ProjectStats (TotalFiles, ScannedFiles, ByLanguage map) alongside the file list. Files inside always-skipped dirs (vendor/, node_modules/, .git/, build artifact dirs, ...) and --exclude prefixes are intentionally not counted, so the "Detected:" line reflects what the user expected pathfinder to look at.
  • CodeGraph carries the stats so scan/ci can render the multi-line empty-project message.
  • scan.go no longer returns an error when len(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.go uses the same helper for consistency (previously printed a single verbose-only line).
  • New Logger.Info method for always-shown, prefix-free messages. The existing Progress is gated to --verbose, Warning prepends Warning:, neither fit this case.

Test plan

  • go test ./... passes (all packages green).
  • go vet ./... clean.
  • golangci-lint run ./graph/ ./cmd/ ./output/ reports 0 issues.
  • New code coverage: 100% on every new function (languageOf, SupportedLanguages, recordFile, UnsupportedFileCount, UnsupportedSummary, reportEmptyProject, emptyProjectMessage, Logger.Info).
  • End-to-end run on cpf-api (TypeScript) verifies exit 0, valid JSON/CSV/SARIF output, and the exact message format above.
  • End-to-end run on cpf-api via pathfinder ci --output json --output-file ci.json verifies the ci path uses the same message + valid empty output.
  • Existing getFiles callers (8 in graph_test.go, 5 in utils_test.go) updated for the new 3-value return signature, all still pass.

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).
@shivasurya shivasurya added enhancement New feature or request go Pull requests that update go code labels May 22, 2026
@shivasurya shivasurya self-assigned this May 22, 2026
@shivasurya shivasurya added the go Pull requests that update go code label May 22, 2026
@safedep

safedep Bot commented May 22, 2026

Copy link
Copy Markdown

SafeDep Report Summary

Green Malicious Packages Badge Green Vulnerable Packages Badge Green Risky License Badge

No dependency changes detected. Nothing to scan.

View complete scan results →

This report is generated by SafeDep Github App

@github-actions

Copy link
Copy Markdown

Code Pathfinder Security Scan

Pass Critical High Medium Low Info

No security issues detected.

Metric Value
Files Scanned 13
Rules 205

Powered by Code Pathfinder

@code-pathfinder

Copy link
Copy Markdown

Pathfinder Report

No security findings on the changed files. This pull request is clean.

View report on the dashboard


Powered by Code Pathfinder.

@codecov

codecov Bot commented May 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.22222% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.53%. Comparing base (1faca6c) to head (9b3dd7e).

Files with missing lines Patch % Lines
sast-engine/cmd/scan.go 0.00% 3 Missing ⚠️
sast-engine/cmd/ci.go 0.00% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@shivasurya shivasurya merged commit 9e00502 into main May 22, 2026
9 checks passed
@shivasurya shivasurya deleted the shiva/empty-project-graceful-exit branch May 22, 2026 00:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request go Pull requests that update go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant