# Docs Linting

Documentation problems tend to be invisible until someone encounters them: a function with no docstring, a cross-reference pointing to a symbol that was renamed, or a directive that's misspelled. These issues don't produce build errors, so they can persist across many releases.

Great Docs includes a built-in linter that analyzes your package's public API for documentation quality issues. It catches missing docstrings, broken cross-references, inconsistent formatting, and malformed directives before your users ever see them.


# Basic Usage

Run the linter from your project directory:


    Terminal


``` bash
great-docs lint
```


This produces a report like:

    ════════════════════════════════════════════════════════════
    📋 Documentation Lint Results
    ════════════════════════════════════════════════════════════

    Package: my_package
    Exports checked: 42

    ✅ All documentation checks passed!

When issues are found, they are grouped by check type with clear indicators:

    ────────────────────────────────────────────────────────────
      missing-docstring  [2 error(s), 3 warning(s)]
    ────────────────────────────────────────────────────────────
      ❌  calculate_total: Public export 'calculate_total'
                           has no docstring.
      ❌  DataProcessor: Public export 'DataProcessor' has
                         no docstring.
      ⚠️   Widget.render: Public method 'Widget.render'
                           has no docstring.
      ⚠️   Widget.update: Public method 'Widget.update'
                           has no docstring.
      ⚠️   Widget.__repr__: Public method 'Widget.__repr__'
                             has no docstring.

    ────────────────────────────────────────────────────────────
      style-mismatch  [1 warning(s)]
    ────────────────────────────────────────────────────────────
      ⚠️   parse_config: Docstring appears to use 'google'
                          style but project is configured
                          for 'numpy'.

    ────────────────────────────────────────────────────────────
    ❌ 2 error(s), 4 warning(s)

Errors represent problems that will produce gaps or broken content on the rendered site. Warnings flag inconsistencies that are worth investigating but won't break anything.


# Checks Performed

The linter runs four categories of checks, each targeting a different class of documentation problem. All four run by default, and each can be run individually using `--check` (described below).


## Missing Docstrings

Finds public exports and class methods that lack docstrings.

| Finding | Severity | Description |
|----|----|----|
| `missing-docstring` | Error | A public export in `__all__` has no docstring |
| `missing-docstring` | Warning | A public method on a documented class has no docstring |

Private methods (names starting with `_`) and constructor dunders (`__init__`, `__new__`) are skipped automatically. The linter only flags symbols that would appear (or be expected to appear) in the rendered documentation.


## Broken Cross-References

Cross-references that point to nonexistent symbols produce dead links on the rendered site. The linter validates that `%seealso` directives reference symbols that actually exist in your public API.

| Finding | Severity | Description |
|----|----|----|
| `broken-xref` | Error | `%seealso` references a name that is not a known public export |

For example, this would flag an error:

``` python
def process(data):
    """
    Process the input data.

    %seealso validate_input, transform_data
    """
    ...
```

If `validate_input` exists in your public API but `transform_data` does not, the linter reports `transform_data` as a broken cross-reference. This is especially useful after renaming or removing functions.


## Style Consistency

Detects docstrings that don't match your project's configured parser style. The `parser` setting in `great-docs.yml` determines which style is expected:


    great-docs.yml


``` yaml
parser: numpy    # or "google" or "sphinx"
```


| Finding          | Severity | Description                                      |
|------------------|----------|--------------------------------------------------|
| `style-mismatch` | Warning  | Docstring uses a different style than configured |

The linter detects style by looking for characteristic patterns:

- **NumPy**: Section headers with dashed underlines (`Parameters\n----------`)
- **Google**: Section headers with colons (`Args:`, `Returns:`)
- **Sphinx**: Field markers (`:param x:`, `:returns:`)

Short docstrings without structured sections are not flagged, since they don't contain enough signal to determine a style.


## Directive Consistency

Great Docs uses `%`-prefixed directives in docstrings for features like cross-references and documentation exclusion. This check catches misspelled or unrecognized directives that would otherwise be silently ignored.

| Finding             | Severity | Description                                |
|---------------------|----------|--------------------------------------------|
| `unknown-directive` | Warning  | A `%`-prefixed directive is not recognized |

Great Docs recognizes these directives:

- `%seealso`: cross-reference related items (see [Cross-Referencing](cross-referencing.md))
- `%nodoc`: exclude an item from documentation (see [Writing Docstrings](writing-docstrings.md#nodoc-exclude-an-item-from-documentation))

Any other `%`-prefixed token (e.g., `%deprecated`, `%internal`) is flagged as unknown. If you see a false positive, check for typos in the directive name.


# Running Specific Checks

When diagnosing a particular class of issue, you can run a subset of checks instead of the full suite. Use `--check` to select only the checks you need (this option can be repeated):


    Terminal


``` bash
# Only check for missing docstrings
great-docs lint --check docstrings

# Check cross-references and style together
great-docs lint --check cross-refs --check style

# Only check directive usage
great-docs lint --check directives
```


Available check names:

| Name         | What it checks                                     |
|--------------|----------------------------------------------------|
| `docstrings` | Missing docstrings on public exports and methods   |
| `cross-refs` | Broken `%seealso` references                       |
| `style`      | Docstring style consistency with configured parser |
| `directives` | Unknown or malformed `%` directives                |

When no `--check` flags are given, all four categories run.


# JSON Output

For CI/CD integration or programmatic analysis, use `--json` to get machine-readable output:


    Terminal


``` bash
great-docs lint --json
```


This produces structured JSON:

``` json
{
  "status": "fail",
  "package": "my_package",
  "exports_checked": 42,
  "summary": {
    "errors": 2,
    "warnings": 4,
    "info": 0
  },
  "issues": [
    {
      "check": "missing-docstring",
      "severity": "error",
      "symbol": "calculate_total",
      "message": "Public export 'calculate_total' has no docstring."
    },
    {
      "check": "style-mismatch",
      "severity": "warning",
      "symbol": "parse_config",
      "message": "Docstring appears to use 'google' style but project is configured for 'numpy'."
    }
  ]
}
```

The `status` field is one of:

| Status | Meaning                          |
|--------|----------------------------------|
| `pass` | No errors or warnings            |
| `warn` | Warnings only (exit code 0)      |
| `fail` | At least one error (exit code 1) |

You can filter the JSON output with `jq`:


    Terminal


``` bash
# Show only errors
great-docs lint --json | jq '.issues[] | select(.severity == "error")'

# Count issues by check type
great-docs lint --json | jq '.issues | group_by(.check) | map({check: .[0].check, count: length})'
```


The JSON format is stable across releases, so you can build tooling around it.


# Exit Codes

The linter uses exit codes to indicate whether action is needed:

| Code | Meaning                          |
|------|----------------------------------|
| `0`  | No errors (warnings are allowed) |
| `1`  | At least one error was found     |

This means you can use `great-docs lint` directly in CI pipelines and it will fail the build only when there are errors. Warnings appear in the output but do not block the pipeline.


# CI/CD Integration

Running the linter in CI ensures that documentation quality is enforced on every pull request, not just when someone remembers to check.


## GitHub Actions

Add documentation linting to your CI workflow:


    .github/workflows/docs.yml


``` yaml
name: Documentation

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint-docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: |
          pip install -e .
          pip install great-docs

      - name: Lint documentation
        run: great-docs lint
```


## Pre-commit Hook

Add linting as a pre-commit hook:


    .pre-commit-config.yaml


``` yaml
repos:
  - repo: local
    hooks:
      - id: lint-docs
        name: Lint Documentation
        entry: great-docs lint
        language: system
        pass_filenames: false
        always_run: true
```


## Combining with Other Quality Checks

Run linting alongside other Great Docs quality tools in CI:


    .github/workflows/docs.yml


``` yaml
      - name: Lint documentation
        run: great-docs lint

      - name: Check links
        run: great-docs check-links

      - name: Proofread
        run: great-docs proofread

      - name: Audit SEO
        run: great-docs seo
```


Running all four together gives you a comprehensive pre-deployment quality gate.


# Next Steps

The linter catches structural problems early: missing docstrings, malformed directives, broken cross-references, and style inconsistencies that would otherwise surface as confusing gaps in the rendered site. Run it in CI to enforce documentation quality alongside code quality.

- [Link Checker](link-checker.md) validates that all links in the built site resolve correctly
- [Proofreading](proofreading.md) checks spelling, grammar, and style in your prose
- [Writing Docstrings](writing-docstrings.md) covers the docstring format and directives that the linter validates
- [SEO Optimization](seo.md) audits generated metadata that complements documentation quality
