Skip to content

Refactor reporting functions to cut cognitive complexity (S3776, batch 1/4) - #15

Merged
kgrizz-git merged 9 commits into
mainfrom
refactor/s3776-reporting
Aug 7, 2026
Merged

Refactor reporting functions to cut cognitive complexity (S3776, batch 1/4)#15
kgrizz-git merged 9 commits into
mainfrom
refactor/s3776-reporting

Conversation

@kgrizz-git

@kgrizz-git kgrizz-git commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

First themed batch of SonarCloud S3776 (cognitive complexity) refactors — the reporting area. All are pure extract-method: behavior and output are unchanged, verified by the existing suite (many reporting tests assert exact printed output byte-for-byte).

Function Before Approach
report_summary._print_top_consumers 54 Split into 5 section helpers (actions minutes/cost, repo-consumer breakdowns, copilot, LFS)
export_csv._write_sections 44 Extract each CSV section into its own _write_*_section helper
report_products.show_base_costs 32 Share 4 block helpers with render_base_costs (dedup)
report_products.render_base_costs 32 Same shared helpers — removes ~80 lines of duplication (567→513 lines)
report_account.render_rate_limits 22 Split standard vs premium rate-limit printers; drop a dead used var
report_actions.show_actions_os_breakdown 21 Extract per-repo OS breakdown + totals printers
report_data._fetch_sections 20 Extract the repeated try/except→errors[key] into _try_section

Each parent is now a flat sequence of calls, well under the 15 threshold.

Verification

  • 732 tests OK (unittest discover)
  • typecheck: 0 errors
  • ruff + ruff-format: clean

Follow-up batches (not in this PR)

Setup/wizard (8), GUI (2), Core/CLI (8) — separate PRs.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor

    • Improved the internal structure of reporting and CSV export generation while preserving existing output and behavior.
    • Standardized handling of report data, pricing details, usage breakdowns, and error conditions.
    • Simplified rate-limit, cost, and top-consumer reporting logic for improved maintainability.
  • Bug Fixes

    • Improved resilience when billing data is incomplete or unavailable.
    • Ensured base-cost reports still display correctly when pricing details are empty.
  • Tests

    • Added coverage for base-cost reporting with missing pricing data.

kgrizz-git and others added 3 commits August 6, 2026 11:38
report_summary.py:_print_top_consumers had cognitive complexity 54 (limit
15). Extract each output section into a focused helper —
_print_actions_minutes_top, _print_actions_cost_top,
_print_repo_consumer_breakdowns, _print_copilot_by_model, _print_lfs_storage
— leaving the parent as a flat sequence of calls. Pure extract-method; output
is byte-for-byte unchanged (33 report-summary tests assert exact output).

Also gitignore the local .sonar_cloud_token helper file.

732 tests OK, ruff clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- export_csv._write_sections (complexity 44 -> ~2): extract each CSV section
  into its own _write_*_section helper; parent is now a flat call sequence.
- report_products.show_base_costs and render_base_costs (32 each): these were
  near-duplicate per-product pricing printers. Extract four shared block
  helpers (_print_actions_compute_costs, _print_actions_storage_costs,
  _print_copilot_base_costs, _print_lfs_base_costs) that both call, removing
  ~80 lines of duplication (567 -> 513 lines) and dropping both parents well
  under the threshold.

Pure extract-method; output byte-for-byte unchanged. 732 tests OK, ruff clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- report_data._fetch_sections (20): extract the repeated
  try/except-RuntimeError->errors[key] pattern into a _try_section helper so
  each section fetch is a single call.
- report_actions.show_actions_os_breakdown (21): extract per-repo OS
  breakdown printing (_print_repo_os_breakdown) and the totals block
  (_print_os_totals).
- report_account.render_rate_limits (22): split into
  _print_standard_rate_limits and _print_premium_rate_limits; drop a dead
  `used` assignment in the standard loop.

Pure extract-method; output unchanged. 732 tests OK, typecheck clean, ruff clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5711ec59-7fb0-4f3e-93b8-679bf3a12368

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The pull request extracts reporting, data-fetching, pricing, summary, and CSV export logic into smaller private helpers. It preserves existing output and error behavior and adds coverage for missing billing item data.

Changes

Reporting refactor

Layer / File(s) Summary
Centralized report section fetching
src/github_usage/report_data.py
_try_section now handles section getter execution and RuntimeError capture for multiple report sections.
Extracted report rendering helpers
src/github_usage/report_account.py, src/github_usage/report_actions.py, src/github_usage/report_products.py, tests/test_report_products.py
Rate limits, Actions OS usage, and product pricing use focused helpers. Pricing handles missing item maps, and tests cover that case.
Simplified consumer summary orchestration
src/github_usage/report_summary.py, CHANGELOG.md
Top-consumer output delegates Actions, repository, Copilot, and Git LFS rendering to separate helpers. The changelog records the refactoring.
Dedicated CSV section writers
src/github_usage/export_csv.py
CSV section dispatch, consumer rows, storage data, insights, unavailable data, and sources use dedicated writers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: cursoragent

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: refactoring reporting functions to reduce SonarCloud S3776 cognitive complexity.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/s3776-reporting

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread src/github_usage/report_products.py Fixed
Comment thread src/github_usage/report_products.py Fixed
Comment thread src/github_usage/report_products.py Fixed
Comment thread src/github_usage/report_products.py Fixed
@kgrizz-git

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/github_usage/report_products.py`:
- Line 230: Resolve the Ruff RUF001 warnings in the four output strings near the
product-report formatting prints by replacing the ambiguous “×” character with
ASCII “x” (or adding a targeted RUF001 suppression if the symbol is
intentionally required), while preserving the existing output formatting.
- Around line 506-509: Add unit-test coverage for render_base_costs in the
relevant test module, exercising both billing data containing the "items" key
and the missing-"items" path, while preserving existing show_base_costs coverage
and following the established src/github_usage test patterns.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 68153c7e-3c4f-41cc-900d-c1fafd7c552a

📥 Commits

Reviewing files that changed from the base of the PR and between 033ad2a and 0d8b13a.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • src/github_usage/export_csv.py
  • src/github_usage/report_account.py
  • src/github_usage/report_actions.py
  • src/github_usage/report_data.py
  • src/github_usage/report_products.py
  • src/github_usage/report_summary.py
  • tests/test_report_products.py

Comment thread src/github_usage/report_products.py Outdated
price = item.get("pricePerUnit", 0)
qty = item.get("grossQuantity", 0)
net = item.get("netAmount", 0)
print(f" {sku:<40} {fmt_price(price)}/min × {qty:.1f} min = {fmt_price(net)}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Resolve the Ruff RUF001 warnings.

Ruff flags the × character in these four output strings as ambiguous. If the character is intentional, add a narrow # noqa: RUF001 suppression. Otherwise, replace it with ASCII x.

Also applies to: 252-252, 274-274, 295-295

🧰 Tools
🪛 Ruff (0.16.1)

[warning] 230-230: String contains ambiguous × (MULTIPLICATION SIGN). Did you mean x (LATIN SMALL LETTER X)?

(RUF001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/github_usage/report_products.py` at line 230, Resolve the Ruff RUF001
warnings in the four output strings near the product-report formatting prints by
replacing the ambiguous “×” character with ASCII “x” (or adding a targeted
RUF001 suppression if the symbol is intentionally required), while preserving
the existing output formatting.

Source: Linters/SAST tools

Comment on lines +506 to +509
_print_actions_compute_costs(actions_sku)
_print_actions_storage_costs(actions_sku)
_print_copilot_base_costs(copilot_billing.get("items") if copilot_billing else None)
_print_lfs_base_costs(lfs_billing.get("items") if lfs_billing else None)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Expect: a test that calls render_base_costs.
rg -n -C 4 '\brender_base_costs\b' tests src/github_usage

Repository: kgrizz-git/github-usage

Length of output: 1962


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate tests related to products/show_base_costs/render_base_costs =="
rg -n -C 3 'show_base_costs|render_base_costs|base_costs|missing.*items|items.*missing' tests || true

echo
echo "== report_products outline / relevant source =="
ast-grep outline src/github_usage/report_products.py --match render_base_costs --view expanded || true
sed -n '480,515p' src/github_usage/report_products.py

echo
echo "== find public exports for report_products =="
rg -n 'from \.report_products import|import report_products|show_base_costs|render_base_costs|__all__' src/github_usage tests || true

Repository: kgrizz-git/github-usage

Length of output: 3907


Add coverage for render_base_costs.

render_base_costs is defined in src/github_usage/report_products.py, but the regression test only covers show_base_costs. Add a unit test for render_base_costs, including the missing "items" path, per the coverage guideline for src/github_usage/**/*.py.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/github_usage/report_products.py` around lines 506 - 509, Add unit-test
coverage for render_base_costs in the relevant test module, exercising both
billing data containing the "items" key and the missing-"items" path, while
preserving existing show_base_costs coverage and following the established
src/github_usage test patterns.

Source: Coding guidelines

@sonarqubecloud

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

Comment thread src/github_usage/report_products.py Dismissed
Comment thread src/github_usage/report_products.py Dismissed
@kgrizz-git
kgrizz-git merged commit f64c8bf into main Aug 7, 2026
11 checks passed
@kgrizz-git
kgrizz-git deleted the refactor/s3776-reporting branch August 7, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants