Skip to content

Code Quality Checks

doctk maintains high code quality through comprehensive automated checks. This guide explains the quality tools, how to run them, and how to fix issues.

Overview

Quality checks are organized into several categories:

  1. Python Code Quality: Linting and formatting with ruff
  2. Shell Script Quality: Linting with shellcheck, formatting with shfmt
  3. TOML Quality: Formatting with taplo
  4. Documentation Quality: Linting with markdownlint, link checking with lychee
  5. Configuration Consistency: Meta tests for config drift
  6. Test Quality: Comprehensive test coverage

Running Quality Checks

All Checks

Run all quality checks with tox:

tox

This runs all environments in sequence and reports pass/fail for each.

Specific Checks

Run individual quality checks:

# Python
tox -e ruff

# Shell scripts
tox -e shellcheck
tox -e shfmt

# TOML
tox -e taplo

# Documentation
tox -e docs

# Tests
tox -e pytest

Auto-fix

Many issues can be automatically fixed:

# Fix Python formatting
tox -e ruff-fix

# Fix shell script formatting
tox -e shfmt-fix

# Fix TOML formatting
tox -e taplo-fix

# Fix documentation formatting
tox -e docs-fix

Python Code Quality

Ruff

Ruff is an extremely fast Python linter and formatter that replaces multiple tools (flake8, isort, black, etc.).

Configuration

Configured in pyproject.toml:

[tool.ruff]
line-length = 100
target-version = "py310"

[tool.ruff.lint]
select = [
    "E",   # pycodestyle errors
    "W",   # pycodestyle warnings
    "F",   # pyflakes
    "I",   # isort
    "N",   # pep8-naming
    "UP",  # pyupgrade
    "B",   # flake8-bugbear
    "C4",  # flake8-comprehensions
    "SIM", # flake8-simplify
]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

Running

# Check for issues
tox -e ruff

# Auto-fix issues
tox -e ruff-fix

# Or use ruff directly
uv run ruff check .
uv run ruff format .

Common Issues

  • E501: Line too long (> 100 characters)
  • Fix: Break line into multiple lines
  • F401: Unused import
  • Fix: Remove the import
  • I001: Import block is un-sorted
  • Fix: Run tox -e ruff-fix
  • N802: Function name should be lowercase
  • Fix: Rename function

Shell Script Quality

Shellcheck

Shellcheck is a static analysis tool for shell scripts that catches common errors.

Running

# Check all shell scripts
tox -e shellcheck

# Or use shellcheck directly
shellcheck scripts/*.sh

Common Issues

  • SC2086: Double quote to prevent globbing
  • Fix: "$variable" instead of $variable
  • SC2155: Declare and assign separately
  • Fix: Split into two lines
  • SC2164: Use cd ... || exit in case cd fails
  • Fix: Add error handling

Shfmt

Shfmt formats shell scripts according to Google Shell Style Guide.

Configuration

  • Indent: 2 spaces
  • Binary operators at start of line
  • Redirect operators followed by space
  • Keep column alignment

Running

# Check formatting
tox -e shfmt

# Auto-fix formatting
tox -e shfmt-fix

# Or use shfmt directly
shfmt -d scripts/*.sh
shfmt -w scripts/*.sh

TOML Quality

Taplo

Taplo formats TOML files consistently.

Running

# Check formatting
tox -e taplo

# Auto-fix formatting
tox -e taplo-fix

# Or use taplo directly
taplo format --check pyproject.toml
taplo format pyproject.toml

Documentation Quality

Markdownlint

Markdownlint enforces consistent Markdown style.

Configuration

Configured in .markdownlint.yaml:

# Heading style
MD003:
  style: atx

# Unordered list style
MD004:
  style: dash

# Line length (disabled for flexibility)
MD013: false

# Code block style
MD046:
  style: fenced

Running

# Check all markdown files
tox -e docs

# Auto-fix issues
tox -e docs-fix

# Or use markdownlint directly
markdownlint-cli2 "**/*.md"

Common Issues

  • MD001: Heading levels should increment by one
  • Fix: Don't skip heading levels (h1 → h3)
  • MD022: Headings should be surrounded by blank lines
  • Fix: Add blank lines before/after headings
  • MD032: Lists should be surrounded by blank lines
  • Fix: Add blank lines before/after lists

MkDocs Site Build

CRITICAL: Always build the documentation site in strict mode before committing changes to docs/.

MkDocs strict mode catches broken links, missing files, and other documentation issues that would cause the GitHub Pages deployment to fail.

Running

# Build docs in strict mode (catches all issues)
tox -e docs-build

# Serve docs locally for preview
tox -e docs-serve
# Then open http://127.0.0.1:8000 in your browser

Why This Matters

  • Broken links fail the build: Any reference to a non-existent file will cause a build failure
  • Excluded files: Files in exclude_docs (like archive/, design/) cannot be linked from published docs
  • Missing nav entries: Files not in the nav configuration won't be published
  • GitHub Pages deployment: The CI/CD pipeline runs mkdocs build --strict and will fail if there are issues

Common Issues

  • Link to excluded file: Doc file 'index.md' contains a link to 'design/file.md' which is excluded
  • Fix: Either remove the link or change it to reference the repository path
  • Broken relative link: contains a link '../file.md', but the target 'file.md' is not found
  • Fix: Correct the relative path or move the file into the docs structure
  • Unrecognized link: contains an unrecognized relative link 'folder/'
  • Fix: Link to a specific file like folder/README.md instead of the directory

Workflow

Before committing any changes to docs/:

# 1. Make your documentation changes
vim docs/index.md

# 2. Build in strict mode to check for issues
tox -e docs-build

# 3. If build succeeds, commit
git add docs/
git commit -m "docs: update documentation"

# 4. If build fails, fix the issues and repeat

Mdformat

Mdformat auto-formats Markdown files.

Running

# Format all markdown files
tox -e docs-fix

# Or use mdformat directly
uv run mdformat docs/ README.md CONTRIBUTING.md

Lychee

Lychee checks for broken links in documentation.

Configuration

Configured in .lychee.toml:

# Exclude patterns
exclude = [
    "localhost",
    "127.0.0.1",
    "mailto:",
]

# Retry failed requests
max_retries = 2
retry_wait_time = 2

# Timeout
timeout = 20

Running

# Check all links
tox -e docs

# Or use lychee directly
lychee docs/ README.md CONTRIBUTING.md

Common Issues

  • 404 Not Found: Link is broken
  • Fix: Update or remove the link
  • Timeout: Server didn't respond
  • Fix: Check if URL is correct, may need to exclude
  • SSL Error: Certificate issue
  • Fix: May need to exclude or update URL

Configuration Consistency

Meta Tests

Meta tests verify project configuration is consistent.

Location

tests/quality/meta/test_config_consistency.py

Tests

  1. Tool versions match: Versions in pyproject.toml match .pre-commit-config.yaml
  2. Tox environments documented: All tox environments have descriptions
  3. Dependency groups complete: All required dependencies are listed
  4. External tools have plugins: All tools in pyproject.toml have plugin files

Running

# Run meta tests
uv run pytest tests/quality/meta/ -v

# Or via tox
tox -e quality

Fixing Issues

If meta tests fail:

  1. Check the error message for specific mismatch
  2. Update the relevant configuration file
  3. Run python3 scripts/sync-precommit-versions.py to sync versions
  4. Re-run tests to verify

Pre-commit Hooks

Pre-commit hooks run automatically on git commit to catch issues early.

Installed Hooks

  1. File quality: trailing whitespace, end-of-file, YAML syntax
  2. Shell scripts: shellcheck, shfmt
  3. Python: ruff
  4. Markdown: mdformat
  5. TOML: taplo
  6. Tool plugins: validate plugin format

Running Manually

# Run all hooks on all files
uv run pre-commit run --all-files

# Run specific hook
uv run pre-commit run ruff --all-files

# Run on staged files only
uv run pre-commit run

Skipping Hooks

In rare cases, you may need to skip hooks:

# Skip all hooks
git commit --no-verify

# Skip specific hook (not recommended)
SKIP=ruff git commit

Note: Only skip hooks if absolutely necessary. CI will still run all checks.

Updating Hooks

Update hook versions:

# Update to latest versions
uv run pre-commit autoupdate

# Sync versions from pyproject.toml
python3 scripts/sync-precommit-versions.py

Test Quality

Coverage

Aim for high test coverage:

# Run tests with coverage
uv run pytest --cov=doctk --cov-report=html

# View HTML report
open reports/coverage/html/index.html

Test Categories

  • Unit tests: Fast, isolated tests
  • E2E tests: End-to-end CLI tests
  • Quality tests: Meta tests for config
  • Docs tests: Documentation quality tests

See Testing Guide for details.

CI/CD Integration

GitHub Actions

All quality checks run in CI on every push and pull request.

Workflow

name: Quality Checks

on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install tools
        run: python3 scripts/setup-external-tools.py
      - name: Run quality checks
        run: tox

Required Checks

Pull requests must pass:

  1. All tox environments
  2. All tests
  3. All pre-commit hooks
  4. Coverage threshold (if configured)

Troubleshooting

Ruff Errors

If ruff reports errors:

  1. Try auto-fix: tox -e ruff-fix
  2. If still failing, read error message carefully
  3. Fix manually if auto-fix doesn't work
  4. Check ruff documentation: https://docs.astral.sh/ruff/

Shellcheck Errors

If shellcheck reports errors:

  1. Read the error code (e.g., SC2086)
  2. Check shellcheck wiki: https://www.shellcheck.net/wiki/SC2086
  3. Fix the issue manually
  4. Re-run: tox -e shellcheck

Pre-commit Hook Failures

If pre-commit hooks fail:

  1. Read the error message
  2. Run the specific hook manually: uv run pre-commit run <hook-name> --all-files
  3. Fix the issues
  4. Try committing again

Version Mismatches

If tool versions don't match:

  1. Run: python3 scripts/sync-precommit-versions.py
  2. Verify: python3 scripts/check-tools.py
  3. Reinstall if needed: python3 scripts/setup-external-tools.py

Best Practices

Before Committing

  1. Run tests: uv run pytest
  2. Run quality checks: tox
  3. If you modified docs/: Build docs in strict mode: tox -e docs-build
  4. Fix any issues
  5. Commit changes

During Development

  1. Run relevant checks frequently
  2. Use auto-fix tools when available
  3. Don't accumulate quality debt
  4. Fix issues as they arise

Code Review

  1. Verify all CI checks pass
  2. Review code quality manually
  3. Check test coverage
  4. Ensure documentation is updated

Quality Metrics

Current Status

  • Python: 100% ruff compliant
  • Shell: 100% shellcheck compliant
  • TOML: 100% taplo compliant
  • Markdown: 100% markdownlint compliant
  • Links: 0 broken links
  • Tests: All passing
  • Coverage: >80% (target)

Goals

  • Maintain 100% compliance with all linters
  • Increase test coverage to >90%
  • Zero broken links in documentation
  • All tox environments passing

References