Skip to content

Commit 8f86866

Browse files
feat(repo): expose fileCount in --output json (#16)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 157fe90 commit 8f86866

6 files changed

Lines changed: 45 additions & 5 deletions

File tree

.changeset/repo-json-file-count.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@codacy/codacy-cloud-cli": minor
3+
---
4+
5+
`codacy repo --output json` now includes a `fileCount` field on the repository object, plucked from `coverage.numberTotalFiles` on the existing `getRepositoryWithAnalysis` response. The field is present even on repos without coverage data, so no extra API call is needed. Lets consumers (e.g. the `configure-codacy-cloud` skill) read repo size without a separate roundtrip.

SPECS/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,4 @@ _No pending tasks._ All commands implemented.
6868
| 2026-06-02 | `--reanalyze-and-wait` (`-w`) blocking variant for `repository` and `pull-request`: triggers reanalysis, polls to completion (10s interval, 20min cap), then prints issue deltas by pattern/severity/category. New `src/utils/reanalyze-wait.ts` + `formatDuration`/`isBeingAnalyzed` helpers (26 new tests, 356 total) |
6969
| 2026-06-02 | `issues --overview` improvements: relabel False Positives buckets (`belowThreshold`/`equalOrAboveThreshold` → "Not a False Positive"/"Potential False Positive"), and a "Suggested actions to reduce noise" section that flags noisy patterns (≥10% of issues or ≥3× the average) with a runnable `codacy pattern … --disable` command, resolving the tool via its `prefix` (3 new tests, 360 total) |
7070
| 2026-06-02 | Pattern config-file & coding-standard awareness: new `pattern <tool> <id>` **info mode** (same card as `patterns`); `pattern`/`patterns` skip listing and refuse updates when a tool uses a local config file; `pattern` refuses to modify coding-standard-enforced patterns; `issues --overview` noise suggestions now render a manual "update your config file / coding standard" step instead of a command when a pattern can't be disabled via CLI. `printPatternCard`/`PATTERN_JSON_FIELDS` moved to `utils/formatting.ts` (11 new tests, 371 total) |
71+
| 2026-06-18 | `repo --output json` now includes `repository.fileCount`, plucked from `coverage.numberTotalFiles` on the existing `getRepositoryWithAnalysis` response (present even without coverage data — no extra API call). Unlocks repo-size visibility for downstream consumers like the `configure-codacy-cloud` skill (1 new test, 373 total) |

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/commands/AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ Instead of a dedicated "Visibility" column (wastes horizontal space), public rep
105105
- Green if gate passes, red if gate fails; no coloring if no matching gate exists
106106
- **Issues Overview**: three count tables — by category, severity level, and language — sorted descending by count within each group
107107
- Shows pagination warning for pull requests if more exist
108-
- JSON output bundles all three API responses into a single object
108+
- JSON output bundles all three API responses into a single object, plus a `repository.fileCount` field plucked from `data.coverage.numberTotalFiles` (present on the existing `getRepositoryWithAnalysis` response even when the repo has no coverage data — no extra API call). Omitted when that field is absent
109109
- **`--reanalyze` mode** (`-R`): fetches HEAD commit SHA, calls `RepositoryService.reanalyzeCommitById`; early return
110110
- **`--reanalyze-and-wait` mode** (`-w`): blocking variant — see "Reanalyze and wait" below. Baseline comes from `issuesOverview`; polling reads the repo's first commit via `listRepositoryCommits(limit=1)` analysis timestamps
111111

src/commands/repository.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const mockRepoData = {
8686
addedState: "Added",
8787
gatePolicyName: "Codacy recommended",
8888
},
89-
coverage: { coveragePercentage: 78 },
89+
coverage: { coveragePercentage: 78, numberTotalFiles: 83 },
9090
goals: {
9191
maxComplexFilesPercentage: 25,
9292
maxDuplicatedFilesPercentage: 10,
@@ -250,6 +250,36 @@ describe("repository command", () => {
250250
expect(console.log).toHaveBeenCalledWith(
251251
expect.stringContaining('"name": "test-repo"'),
252252
);
253+
254+
const jsonCall = (console.log as ReturnType<typeof vi.fn>).mock.calls.find(
255+
(c) => typeof c[0] === "string" && c[0].startsWith("{"),
256+
);
257+
const parsed = JSON.parse(jsonCall![0]);
258+
expect(parsed.repository.fileCount).toBe(83);
259+
});
260+
261+
it("omits fileCount from JSON when coverage.numberTotalFiles is absent", async () => {
262+
vi.mocked(AnalysisService.getRepositoryWithAnalysis).mockResolvedValue({
263+
data: { ...mockRepoData, coverage: {} } as any,
264+
});
265+
vi.mocked(AnalysisService.listRepositoryPullRequests).mockResolvedValue({
266+
data: [],
267+
});
268+
vi.mocked(AnalysisService.issuesOverview).mockResolvedValue({
269+
data: { counts: mockIssuesCounts },
270+
});
271+
272+
const program = createProgram();
273+
await program.parseAsync([
274+
"node", "test", "--output", "json",
275+
"repository", "gh", "test-org", "test-repo",
276+
]);
277+
278+
const jsonCall = (console.log as ReturnType<typeof vi.fn>).mock.calls.find(
279+
(c) => typeof c[0] === "string" && c[0].startsWith("{"),
280+
);
281+
const parsed = JSON.parse(jsonCall![0]);
282+
expect(parsed.repository.fileCount).toBeUndefined();
253283
});
254284

255285
it("should handle repository with no PRs and no issues", async () => {

src/commands/repository.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,10 @@ Examples:
527527

528528
if (format === "json") {
529529
printJson(pickDeep({
530-
repository: data,
530+
repository: {
531+
...data,
532+
fileCount: data.coverage?.numberTotalFiles,
533+
},
531534
pullRequests,
532535
issuesOverview: issuesCounts,
533536
}, [
@@ -549,6 +552,7 @@ Examples:
549552
// Metrics
550553
"repository.issuesCount",
551554
"repository.loc",
555+
"repository.fileCount",
552556
"repository.coverage.coveragePercentage",
553557
"repository.complexFilesPercentage",
554558
"repository.duplicationPercentage",

0 commit comments

Comments
 (0)