Home  >  Article  >  Backend Development  >  Setting Up Tools for Code Quality

Setting Up Tools for Code Quality

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-01 05:47:02364browse

Setting Up Tools for Code Quality

When developing ReadmeGenie, I aimed to ensure consistent code quality with an automated setup for linting and formatting. After considering several tools, I selected Ruff as the linter and Black as the code formatter. Although Ruff can also handle both linting and formatting, I decided to set up Black as a separate formatter to gain experience with the configuration of both tools. Below, I’ll share why I chose these tools, how I configured them for my project, the challenges I faced, and the lessons I learned along the way.


1. Tool Selection

Why Ruff?

Ruff is a fast linter for Python that supports various linting rules from other linters (like Flake8 and Pyflakes) and offers significant performance improvements. It’s highly customizable, which allowed me to specify a mix of rules while ensuring compatibility with Black for formatting. Ruff’s design for speed and extensibility is ideal for projects that prioritize efficiency without sacrificing quality.

  • Ruff Documentation: https://github.com/charliermarsh/ruff

Why Black?

Black is a Python formatter that strictly enforces one formatting style, helping reduce discussions and inconsistencies over code styling. While Ruff offers basic formatting capabilities, Black’s dedicated approach provides a few advantages:

  • Consistency: Black enforces a strict, standard style that minimizes debates over code formatting.
  • Broad Adoption: Black is widely used, making it easier to integrate into most development workflows, especially in collaborative projects.

  • Black Documentation: https://github.com/psf/black

2. Project Setup

To ensure that Ruff and Black worked seamlessly in ReadmeGenie, I configured them in both pyproject.toml and
.pre-commit-config.yaml, allowing developers to automatically format and lint code when making commits.

Configuration for Ruff and Black in pyproject.toml

This setup ensures Ruff is used solely for linting and Black for formatting:

# pyproject.toml
# Set up black as formatter
[tool.black]
line-length = 88
target-version = ["py311"]

# Set up ruff as linter only
[tool.ruff]
# Exclude directories that don’t need linting (e.g., virtual environments)
exclude = [
    "venv/",
    "__pycache__/"
]
fix = true


# Enable specific linting rules
select = ["F", "E", "W", "B", "I", "S"]  # Example codes: F=flake8, E=errors, W=warnings, B=bugbear, I=import, S=safety
# Exclude Black-compatible rules to avoid conflicts with Black's formatting.
ignore = ["E501", "E203", "E231"]  # Exclude Black-incompatible style issues
  • ignore: Black handles specific styling, so we excluded these rules in Ruff.
  • fix: Enables Ruff to fix issues where possible, leaving formatting to Black.

Adding Pre-commit Hook for Ruff and Black

Using pre-commit hooks, I configured .pre-commit-config.yaml to enforce linting and formatting on every commit:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/psf/black
    rev: 23.1.0
    hooks:
      - id: black
  - repo: https://github.com/charliermarsh/ruff-pre-commit
    rev: v0.7.1
    hooks:
      - id: ruff

3. Running Ruff and Black from the Command Line

With the above setup, you can use the following commands:

  • Run Ruff:
# pyproject.toml
# Set up black as formatter
[tool.black]
line-length = 88
target-version = ["py311"]

# Set up ruff as linter only
[tool.ruff]
# Exclude directories that don’t need linting (e.g., virtual environments)
exclude = [
    "venv/",
    "__pycache__/"
]
fix = true


# Enable specific linting rules
select = ["F", "E", "W", "B", "I", "S"]  # Example codes: F=flake8, E=errors, W=warnings, B=bugbear, I=import, S=safety
# Exclude Black-compatible rules to avoid conflicts with Black's formatting.
ignore = ["E501", "E203", "E231"]  # Exclude Black-incompatible style issues
  • Run Black:
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/psf/black
    rev: 23.1.0
    hooks:
      - id: black
  - repo: https://github.com/charliermarsh/ruff-pre-commit
    rev: v0.7.1
    hooks:
      - id: ruff

These commands apply fixes to all Python files, ensuring consistent styling and quality checks.

4. VS Code Integration

To automate Ruff and Black on save, I added the following configuration in .vscode/settings.json:

  ruff check . --fix

This setup makes Black the default formatter and Ruff the only active linter in VS Code, allowing both to run
automatically upon saving.

5. Findings and Fixes

Once configured, Ruff and Black identified several issues:

  • Line Length (E501): Ruff initially flagged long lines, which Black auto-formatted.
  • Unused Imports and Variables: Ruff caught several unused imports and variables.
  • Indentation and Styling Consistency: Black applied consistent spacing and indentation, enhancing readability.

6. Challenges

One notable challenge was understanding that some styles are incompatible between Ruff and Black. For example:

  • Line Length (E501): Ruff initially flagged long lines exceeding 88 characters, which Black handles by wrapping lines. To prevent conflicts, I added E501 to Ruff’s ignore list. Despite this, Ruff sometimes flagged E501 errors if Black didn’t apply the expected breakpoints. These discrepancies underscored the importance of adjusting each tool’s configuration and understanding where they may overlap.

7. Lessons Learned

Using Ruff and Black together has been a great way to improve code quality. Here’s what I learned:

  • Consistency: Black’s opinionated style reduces ambiguity in code styling.
  • Automation: Pre-commit hooks save time and ensure consistent formatting.
  • Editor Integration: Configuring Ruff and Black to run on save within VS Code streamlined development.
  • Compatibility: Learning how to resolve conflicts like E501 taught me about tool configurations and helped fine-tune project workflows.

The above is the detailed content of Setting Up Tools for Code Quality. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn