feat: integrate ruff for code quality and formatting#2
feat: integrate ruff for code quality and formatting#2
Conversation
Add modern Python packaging with uv tool installation support: - Add pyproject.toml with console script entry points (ccusage-monitor, claude-monitor) - Update README.md to prioritize uv installation over legacy methods - Add CLAUDE.md development documentation - Add comprehensive .gitignore for Python project Users can now install with: uv tool install claude-usage-monitor Maintains full backwards compatibility with existing installation methods
Update installation docs to use local directory instead of PyPI: - Change from 'uv tool install claude-usage-monitor' to 'uv tool install .' - Add git clone step since package not yet published to PyPI - Clarify platform-specific uv installation commands Fixes installation errors for users trying to install from PyPI
WalkthroughThis pull request introduces Ruff as the primary tool for linting and formatting Python code. It adds configuration files for Ruff, pre-commit hooks, and VS Code integration, updates documentation to guide contributors on using these tools, and implements a GitHub Actions workflow to automate linting and pre-commit checks in CI. Minor code style changes are also applied to the main Python script. Changes
Sequence Diagram(s)sequenceDiagram
participant Developer
participant Pre-commit
participant Ruff
participant GitHub Actions
Developer->>Pre-commit: git commit
Pre-commit->>Ruff: Lint, format, sort imports, check files
Ruff-->>Pre-commit: Results (fixes/issues)
Pre-commit-->>Developer: Pass/fail hooks
Developer->>GitHub Actions: Push/PR to main
GitHub Actions->>Ruff: Run lint/format jobs
GitHub Actions->>Pre-commit: Run hooks
Ruff-->>GitHub Actions: Lint/format results
Pre-commit-->>GitHub Actions: Hook results
GitHub Actions-->>Developer: CI status
Assessment against linked issues
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
dd993e9 to
f997ffb
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
ccusage_monitor.py (3)
178-185: Improved timezone fallback with warning.Catching
UnknownTimeZoneErrorspecifically and defaulting to Warsaw is sensible; consider using a logger instead of
229-239: Comprehensive CLI argument definitions.Added plan and timezone options cover all use cases; you might add range validation for
--reset-hour(0–23) to prevent invalid input.
252-267: Simplify max-token detection.You can replace the manual loop for
custom_maxwith:if plan == "custom_max" and blocks: max_tokens = max( (b.get("totalTokens", 0) for b in blocks if not b.get("isGap") and not b.get("isActive")), default=7000, ) return max_tokensto reduce verbosity.
.pre-commit-config.yaml (1)
5-14: Specify file patterns for Ruff hooksConsider explicitly adding a
files:pattern (e.g.,"\.py$") to both theruffandruff-formathooks so they only run on Python files, reducing unnecessary executions on other file types.- id: ruff args: [--fix] + files: ["\\.py$"] - id: ruff-format + files: ["\\.py$"].github/workflows/lint.yml (1)
16-25: Cache dependencies to speed up CIConsider adding an
actions/cachestep to persist pip/uv or Ruff caches across runs. This will significantly reduce install times on subsequent workflows:- name: Cache Python dependencies uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}DEVELOPMENT.md (1)
317-326: Document code quality tool installation clearlyThe new “🛠️ Code Quality Tools” section is useful. You may want to call out installing the VS Code Ruff extension (e.g.,
astral-sh.ruff) to streamline IDE setup.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
__pycache__/ccusage_monitor.cpython-311.pycis excluded by!**/*.pyc
📒 Files selected for processing (8)
.github/workflows/lint.yml(1 hunks).pre-commit-config.yaml(1 hunks).ruff.toml(1 hunks).vscode/settings.json(1 hunks)CONTRIBUTING.md(9 hunks)DEVELOPMENT.md(5 hunks)README.md(6 hunks)ccusage_monitor.py(5 hunks)
🧰 Additional context used
🪛 Pylint (3.3.7)
ccusage_monitor.py
[refactor] 260-261: Consider using 'max_tokens = max(max_tokens, tokens)' instead of unnecessary if block
(R1731)
[refactor] 269-269: Too many local variables (37/15)
(R0914)
[refactor] 315-316: Consider using 'token_limit = max(token_limit, new_limit)' instead of unnecessary if block
(R1731)
[refactor] 269-269: Too many branches (22/12)
(R0912)
[refactor] 269-269: Too many statements (103/50)
(R0915)
🔇 Additional comments (24)
ccusage_monitor.py (7)
3-9: Nicely grouped imports and bumped Python requirements.Imports are now correctly ordered (stdlib, third-party) and
argparse,os, andsubprocessare explicitly imported, aligning with Python 3.7+ usage (e.g.,capture_output) ensured by the bumped version.
17-20: Clean subprocess invocation with explicit output handling.Using
capture_output=True,text=True, andcheck=Trueimproves clarity and error handling for theccusagecall.
43-53: Consistent and clear progress-bar formatting.The update to use double quotes and refined string construction enhances readability without altering behavior.
61-75: Refined time-progress bar with clear color styling.Stylistic updates align with the new Ruff configuration and maintain the same functionality.
80-86: Stylized header formatting standardized.Consistent use of escape codes and double quotes improves code style in the header output.
94-101: Velocity indicator logic remains unchanged.Emoji thresholds are intact and the refactoring is strictly stylistic.
112-162: Hourly burn-rate calculation unchanged.Loop logic and time overlap computation are correct; only whitespace and string literal styles were adjusted.
README.md (3)
3-3: Updated Python version badge.The badge now correctly reflects the minimum Python 3.7 requirement for Ruff compatibility.
71-71: Prerequisites updated to Python 3.7+.Consistent with the bumped version requirement in
.ruff.toml.
298-298: Cleaned up example whitespace.The session timeline example has been fine-tuned for consistency without altering meaning.
.ruff.toml (1)
1-12: Ruff configuration looks solid.Targeting Python 3.7, setting line-length to 88, and selecting core lint and import rules aligns perfectly with the new tooling strategy.
CONTRIBUTING.md (2)
47-47: Switched dev dependency toruff.Updated installation command now installs
pytestandruffinstead of Black and Flake8, aligning with the new linting toolchain.
362-364: Extended Python version support.The supported Python versions list has been updated to remove 3.6 and include 3.12, matching other docs.
.vscode/settings.json (1)
1-17: VS Code Ruff integration configured.Settings enable format-on-save, auto-fix, and import organization with Ruff—perfectly aligned with the CI and pre-commit hooks.
.pre-commit-config.yaml (1)
15-25: Pre-commit hygiene hooks look goodThe hooks from
pre-commit/pre-commit-hookscover common cleanup tasks (trailing whitespace, EOF fixer, YAML/TOML validation, etc.) with automatic fixes where supported..github/workflows/lint.yml (3)
1-8: Workflow triggers are correctly scopedThe workflow is set to run on both
pushandpull_requestevents formain, ensuring lint checks run consistently on all incoming changes.
27-32: Verify Ruff subcommand flagsPlease confirm that
uv run ruff check --output-format=github .anduv run ruff format --check .use valid flags in the pinned Ruff version.
33-52: Pre-commit job setup is solidThe
pre-commitjob installs and runs all hooks across the repository, enforcing local and CI-level code hygiene.DEVELOPMENT.md (6)
9-9: Unrelated ML status change detectedThe update to the ML-Powered Auto Mode status appears outside the Ruff integration scope. Please verify if this change was intentional.
136-136: Unrelated Docker status change detectedThe modification in the Docker Image status is not related to tooling/formatting. Confirm whether this update should be part of this PR.
328-332: Manual Ruff commands are accurateExamples for
ruff check .,ruff format ., andruff check --fix .align with the configured hooks and CLI usage.
341-345: VS Code integration details are comprehensiveListing auto-format on save, real-time linting, import organization, and style consistency matches the
.vscode/settings.json. No changes needed.
355-355: Workflow step updated appropriatelyNoting that code is auto-formatted and linted via pre-commit hooks enhances clarity in the Development Workflow.
397-399: Contact information changes are out of scopeUpdates to the developer contact details don’t relate to Ruff integration.
| session_duration = 300 # 5 hours in minutes | ||
| remaining_minutes = max(0, session_duration - elapsed_minutes) | ||
| max(0, session_duration - elapsed_minutes) | ||
|
|
There was a problem hiding this comment.
Remove no-op max() call.
The expression max(0, session_duration - elapsed_minutes) is evaluated but not assigned; either assign its result or remove the redundant call.
🤖 Prompt for AI Agents
In ccusage_monitor.py around lines 335 to 337, the max() function call is used
without assigning its result, making it a no-op. Fix this by assigning the
result of max(0, session_duration - elapsed_minutes) to a variable or directly
use it where needed, or remove the call if it serves no purpose.
feat: add uv package manager support
- Add comprehensive .ruff.toml configuration with essential linting rules - Set up pre-commit hooks for automated code quality checks - Create GitHub Actions CI workflow for ruff validation - Configure VS Code settings for real-time ruff integration - Format existing codebase to comply with ruff standards - Update documentation with ruff usage instructions - Update Python requirement from 3.6+ to 3.7+ (ruff minimum) - Replace outdated tools (black, flake8) with modern ruff tooling Resolves Maciek-roboblog#15
f997ffb to
4386d1c
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
ccusage_monitor.py (1)
335-337: Fix the no-op max() call (duplicate of previous review).This issue was previously identified and remains unresolved. The expression
max(0, session_duration - elapsed_minutes)is calculated but not assigned or used.Either assign the result to a variable or remove the redundant call:
- session_duration = 300 # 5 hours in minutes - max(0, session_duration - elapsed_minutes) + session_duration = 300 # 5 hours in minutes + remaining_minutes = max(0, session_duration - elapsed_minutes)Or if this calculation isn't needed, simply remove the line.
🧹 Nitpick comments (7)
ccusage_monitor.py (2)
260-261: Simplify conditional logic using max() function.The current if-block can be simplified for better readability.
- if tokens > max_tokens: - max_tokens = tokens + max_tokens = max(max_tokens, tokens)
315-316: Simplify conditional logic using max() function.Similar to the previous suggestion, this if-block can be simplified.
- if new_limit > token_limit: - token_limit = new_limit + token_limit = max(token_limit, new_limit)README.md (2)
387-389: Minor formatting inconsistency with session timeline.The session timeline example has inconsistent spacing that could be cleaned up for better readability.
**Example Session Timeline:**10:30 AM - First message (Session A starts)
03:30 PM - Session A expires (5 hours later)-12:15 PM - First message (Session B starts)
+12:15 PM - First message (Session B starts)
05:15 PM - Session B expires (5 hours later)
564-578: Clarify legacy setup context for shell alias.The shell alias section should be more clearly marked as applicable only to legacy/development setup to avoid confusion with the recommended uv installation.
The heading and content could be adjusted to make it clearer this is for development setup only:
-3. **Custom Shell Alias (Legacy Setup)** +3. **Custom Shell Alias (Development Setup Only)** ```bash - # Add to ~/.bashrc or ~/.zshrc (only for development setup) + # Add to ~/.bashrc or ~/.zshrc (only needed for development setup) alias claude-monitor='cd ~/Claude-Code-Usage-Monitor && source venv/bin/activate && ./ccusage_monitor.py' ```CLAUDE.md (3)
164-164: Minor grammar improvement: add missing article.-- Sessions start with first message and last exactly 5 hours +- Sessions start with the first message and last exactly 5 hours
171-171: Minor grammar improvement: add missing article.-- Automatically switches to custom_max when Pro limit exceeded +- Automatically switches to custom_max when the Pro limit is exceeded
192-192: Minor grammar improvement: add missing article.-See DEVELOPMENT.md for roadmap including: +See DEVELOPMENT.md for a roadmap including:
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
__pycache__/ccusage_monitor.cpython-311.pycis excluded by!**/*.pyc
📒 Files selected for processing (11)
.github/workflows/lint.yml(1 hunks).gitignore(1 hunks).pre-commit-config.yaml(1 hunks).ruff.toml(1 hunks).vscode/settings.json(1 hunks)CLAUDE.md(1 hunks)CONTRIBUTING.md(9 hunks)DEVELOPMENT.md(5 hunks)README.md(20 hunks)ccusage_monitor.py(5 hunks)pyproject.toml(1 hunks)
✅ Files skipped from review due to trivial changes (4)
- CONTRIBUTING.md
- .pre-commit-config.yaml
- .gitignore
- pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (4)
- .ruff.toml
- .vscode/settings.json
- DEVELOPMENT.md
- .github/workflows/lint.yml
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
README.md
542-542: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
650-650: Emphasis used instead of a heading
null
(MD036, no-emphasis-as-heading)
🪛 GitHub Actions: Lint
README.md
[error] 1-1: Pre-commit hook 'trim trailing whitespace' failed. Trailing whitespace was found and automatically fixed.
CLAUDE.md
[error] 1-1: Pre-commit hook 'trim trailing whitespace' failed. Trailing whitespace was found and automatically fixed.
[error] 1-1: Pre-commit hook 'fix end of files' failed. Missing or incorrect end of file newline was found and automatically fixed.
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~164-~164: You might be missing the article “the” here.
Context: ...g session system: - Sessions start with first message and last exactly 5 hours - Mult...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~171-~171: You might be missing the article “the” here.
Context: ...tomatically switches to custom_max when Pro limit exceeded - custom_max scans previ...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~192-~192: You might be missing the article “a” here.
Context: ...ture Development See DEVELOPMENT.md for roadmap including: - ML-powered auto-detection ...
(AI_EN_LECTOR_MISSING_DETERMINER_A)
🪛 Pylint (3.3.7)
ccusage_monitor.py
[refactor] 260-261: Consider using 'max_tokens = max(max_tokens, tokens)' instead of unnecessary if block
(R1731)
[refactor] 269-269: Too many local variables (37/15)
(R0914)
[refactor] 315-316: Consider using 'token_limit = max(token_limit, new_limit)' instead of unnecessary if block
(R1731)
[refactor] 269-269: Too many branches (22/12)
(R0912)
[refactor] 269-269: Too many statements (103/50)
(R0915)
🔇 Additional comments (10)
ccusage_monitor.py (4)
3-10: LGTM: Import reorganization improves code clarity.The import statements have been properly reorganized and formatted for better readability, which aligns well with the Ruff integration objectives.
17-19: LGTM: Subprocess call formatting enhances readability.The multiline formatting of the subprocess.run call makes the parameters more readable and maintainable.
43-52: LGTM: String literal standardization to double quotes.Standardizing string literals to double quotes improves consistency throughout the codebase.
175-180: LGTM: Exception handling improvement for timezone errors.The more specific exception handling for
pytz.exceptions.UnknownTimeZoneErroris a good improvement over generic exception catching.README.md (4)
52-86: Excellent addition of modern uv installation method.The new "Modern Installation with uv" section provides clear, step-by-step instructions and positions this as the recommended approach. The inclusion of platform-specific installation commands and the global command availability is very user-friendly.
3-3: LGTM: Python version requirement updated to 3.7+.The badge correctly reflects the updated minimum Python version requirement, which aligns with the project's modernization goals.
220-257: Well-structured dual command examples.Providing both uv tool installation and traditional/development mode examples ensures all users can follow appropriate instructions for their setup. The clear section headings make this easy to navigate.
1-694: Note: Trailing whitespace automatically fixed by pipeline.The pipeline successfully detected and fixed trailing whitespace issues. This demonstrates the effectiveness of the new pre-commit hooks introduced in this PR.
CLAUDE.md (2)
1-196: Excellent comprehensive documentation for Claude Code integration.This new file provides outstanding guidance for Claude Code when working with this repository. The structure covers all essential aspects including project overview, architecture, development commands, dependencies, and package structure. This will significantly improve the development experience and project understanding.
1-196: Note: Pipeline automatically fixed formatting issues.The pipeline successfully detected and fixed trailing whitespace and missing end of file newline. This demonstrates the effectiveness of the new pre-commit hooks and Ruff integration.
| return limits.get(plan, 7000) | ||
|
|
||
|
|
||
| def main(): |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Consider refactoring main() function to reduce complexity.
The main() function has high complexity metrics (37 local variables, 22 branches, 103 statements). Consider extracting logical sections into separate functions.
Potential extractions:
- Display/UI logic into separate functions
- Token calculation logic
- Time/timezone handling logic
- Notification logic
This would improve maintainability and testability while reducing cognitive load.
🧰 Tools
🪛 Pylint (3.3.7)
[refactor] 269-269: Too many local variables (37/15)
(R0914)
[refactor] 269-269: Too many branches (22/12)
(R0912)
[refactor] 269-269: Too many statements (103/50)
(R0915)
🤖 Prompt for AI Agents
In ccusage_monitor.py at line 269, the main() function is overly complex with
many local variables, branches, and statements. Refactor by extracting distinct
logical sections into separate functions, such as display/UI logic, token
calculation, time/timezone handling, and notification logic. This modularization
will reduce complexity, improve maintainability, and make the code easier to
test.
|
|
||
| ### Build Configuration | ||
| - **Build backend**: hatchling (modern Python build system) | ||
| - **Python requirement**: >=3.6 for broad compatibility |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Update Python version requirement for consistency.
The document mentions Python >=3.6, but other files in this PR have been updated to require Python 3.7+. This should be consistent.
-- **Python requirement**: >=3.6 for broad compatibility
+- **Python requirement**: >=3.7 for broad compatibility📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - **Python requirement**: >=3.6 for broad compatibility | |
| - **Python requirement**: >=3.7 for broad compatibility |
🤖 Prompt for AI Agents
In CLAUDE.md at line 188, update the Python version requirement from ">=3.6" to
">=3.7" to ensure consistency with other files in the PR that specify Python
3.7+ as the minimum version.
Resolves Maciek-roboblog#15
Summary by CodeRabbit
.gitignoreto exclude common development and environment files.