nitpick

repository·master·Indexed 19 days ago

https://github.com/andreoliwa/nitpick

A cross-language configuration linter and fixer (version 0.38.1) that enforces consistent settings across multiple configuration files using a centralized TOML style file. It supports checking and fixing INI, JSON, TOML, YAML, .editorconfig, and .pylintrc files. Nitpick can be used as a command-line tool, a flake8 plugin, a pre-commit hook, or a Python library via the nitpick.core.Nitpick class.

Tokens
17.2K
Snippets
74
Records
94
Agent score
64%

What's inside nitpick

  1. What is Nitpick?

    master
    Nitpick is a command-line tool and flake8 plugin designed to enforce consistent configuration settings across multiple language-independent projects. It prevents the need to manually copy and paste configuration keys (like INI, TOML, YAML, or JSON) across different repositories by using a centralized "style file."
  2. How Nitpick style files work

    master

    A Nitpick style file is a TOML file that defines the expected settings for various configuration files in your projects. Each entry in the style file uses a key representing the target file path and its internal configuration structure.

    For example, a style file can assert that black and isort must have a line-length of 120 in pyproject.toml, and that flake8 must have specific settings in setup.cfg.

    ["pyproject.toml".tool.black]
    line-length = 120
    
    ["pyproject.toml".tool.poetry.group.dev.dependencies]
    pylint = "*"
    
    ["setup.cfg".flake8]
    ignore = "D107,D202,D203,D401"
    max-line-length = 120
    inline-quotes = "double"
    
    ["setup.cfg".isort]
    line_length = 120
    multi_line_output = 3
    include_trailing_comma = true
    force_grid_wrap = 0
    combine_as_imports = true
  3. Extend Nitpick with custom plugins

    master

    Nitpick uses a plugin system to handle different file types and formatting logic. To create a custom plugin, you should implement the nitpick.plugins.base.BasePlugin interface. The base plugin provides standard configuration options for how members and headings are displayed in the output.

    # Conceptual implementation based on BasePlugin options
    # Options available to plugins:
    # - show_root_heading: bool (default: true)
    # - show_source: bool (default: true)
    # - members_order: str (e.g., 'source')
    # - heading_level: int
  4. How Nitpick searches for style files

    master

    Nitpick follows a specific search order to locate a style file:

    1. Explicit Configuration: A file or URL specified in your pyproject.toml under the [tool.nitpick] section using the style key.
    2. Local Style File: A nitpick-style.toml file found in the current directory (where Nitpick is running) or any parent directory.
    3. Default Style: If no other style is found, Nitpick uses its own default style file hosted on GitHub.
  5. How the Flake8 plugin works

    master

    Nitpick is not a native Flake8 plugin; instead, it piggybacks on Flake8's messaging system to report configuration linting errors. While Flake8 lints Python files, Nitpick lints configuration and text files.

    To function as a plugin, Nitpick follows this logic:

    1. It finds the first available Python file in your project.
    2. It ignores all other Python files.
    3. It compares your configuration/text files against the style file.
    4. It reports violations using the path of that first Python file rather than the actual configuration file that contains the error.

    Requirement: Your project must contain at least one Python file for the Flake8 plugin to work. If you are using Nitpick in a non-Python project, create a dummy.py file in the project root.

    Example violation report:
    ./tasks.py:0:1: NIP323 File setup.cfg: [flake8]max-line-length is 80 but it should be like this:
    [flake8]
    max-line-length = 120
  6. Use multiple styles and overrides

    master

    You can provide a list of styles to the style option. This allows you to mix local files and remote URLs.

    Important: The order of the list matters. Styles are applied sequentially, and each subsequent style overrides any keys defined by previous ones. If a key is defined in multiple files, the value from the last file in the list will prevail.

    To use a local file as an override for a remote style, use the ./ prefix. This convention works on Windows as well.

    [tool.nitpick]
    style = [
        "https://example.com/on/the/web/remote-style.toml",
        "./my-local-style.toml",
    ]
  7. How Nitpick plugins work

    master
    Nitpick uses a plugin-based architecture to handle and enforce configurations in various file formats. Plugins are responsible for enforcing specific configurations and, where supported, performing autofixes on the files. Currently, Nitpick includes specialized plugins for INI, JSON, Text, TOML, and YAML files.
  8. Install Nitpick

    master

    You can install Nitpick using several package managers depending on your environment and project setup.

    Global Installation

    Use pipx for an isolated global environment:

    pipx install nitpick

    On macOS/Linux, use Homebrew:

    brew install andreoliwa/formulae/nitpick

    On Arch Linux, use yay:

    yay -Syu nitpick

    Project-specific Installation

    Add Nitpick as a development dependency to your project using uv or Poetry:

    uv add --dev nitpick
    # or
    poetry add --dev nitpick

    Alternatively, use standard pip:

    pip install -U nitpick
    pipx install nitpick
  9. Use remote GitHub styles

    master

    You can point the style option to a remote file hosted on GitHub.

    GitHub URL Schemes

    You can use github:// or gh:// schemes. You can pin the style to a specific Git reference (commit, tag, or branch) using the @ syntax. If no reference is provided, Nitpick defaults to the develop branch.

    Authentication for Private Repositories

    For private repositories, you can include a token directly in the URL or use an environment variable.

    Note: A literal token cannot start with $ and must not contain @ or : characters. When using an environment variable, use the $VARIABLE_NAME syntax.

    # Pinned to a version
    [tool.nitpick]
    style = "github://andreoliwa/nitpick@v0.38.1/nitpick-style.toml"
    
    # Using the default branch (develop)
    style = "gh://andreoliwa/nitpick/nitpick-style.toml"
    
    # Using a regular GitHub URL (uses the raw URL)
    style = "https://github.com/andreoliwa/nitpick/blob/v0.38.1/nitpick-style.toml"
    
    # Private repo with environment variable
    style = "github://$MY_AUTH_KEY@some-user/a-private-repo@some-branch/nitpick-style.toml"
  10. Configure Nitpick in pre-commit

    master

    The default nitpick pre-commit hook calls Flake8 directly using flake8 --select=NIP. This is an unconventional setup because Flake8 only triggers when Python files are modified, meaning changes to configuration files alone might not trigger the linting.

    To ensure configuration files are always verified regardless of whether a Python file changed, do not use the Flake8-based hook. Instead, use the pre-commit hooks that call the Nitpick CLI directly.

    # The current (not recommended) placeholder hook command:
    flake8 --select=NIP
  11. Use Nitpick as a Python library

    master

    You can integrate Nitpick directly into your Python applications by using the Nitpick class from nitpick.core. The standard workflow involves initializing a singleton instance and then calling the run() method to execute checks and retrieve violations.

    from nitpick.core import Nitpick
    
    # Initialize Nitpick
    nit = Nitpick.singleton().init()
    
    # Run checks
    violations = nit.run()