Skip to content

Commit

Permalink
feat: suggest styles based on the file types in the project (#629)
Browse files Browse the repository at this point in the history
* --suggest to scan files by type
* --fix to autofix the config
* --library dir to scan for style files
* pre-commit hook

Signed-off-by: W. Augusto Andreoli <andreoliwa@sent.com>
  • Loading branch information
andreoliwa committed Nov 20, 2023
1 parent f6cfe01 commit e2bca24
Show file tree
Hide file tree
Showing 32 changed files with 1,258 additions and 205 deletions.
10 changes: 10 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
entry: nitpick fix
language: python

- id: nitpick-suggest
name: "nitpick init --suggest (auto fixing files)"
description: "Suggest new Nitpick styles based on the files in the project root (skipping Git ignored files)"
entry: nitpick init --fix --suggest
language: python
# This hook should NOT be run for changed Git files, otherwise they will be considered style URLS
# and will be added to [tool.nitpick]style in pyproject.toml
pass_filenames: false
always_run: true

# This hook is kept for compatibility (or if one wants to be explicit): "nitpick" does the same as "nitpick-fix" now
- id: nitpick-fix
name: "nitpick fix (auto fixing files)"
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
poetry 1.6.1
poetry 1.7.1
pre-commit 3.3.2
12 changes: 6 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@

- default pre-commit hook now runs "nitpick fix" ([cb4c242](https://github.com/andreoliwa/nitpick/commit/cb4c242607c6810c629dc7f5604920c1b64a070e))
- **json:** autofix JSON files ([#429](https://github.com/andreoliwa/nitpick/issues/429)) ([4b58a03](https://github.com/andreoliwa/nitpick/commit/4b58a0380f88b01c99945817e7ff9b595ea362aa))
- nitpick init adds a [tool.nitpick] section ([36f4065](https://github.com/andreoliwa/nitpick/commit/36f4065483b1ec4308bc28b815c82aa0abac104c))
- nitpick init adds a [tool.nitpick] table ([36f4065](https://github.com/andreoliwa/nitpick/commit/36f4065483b1ec4308bc28b815c82aa0abac104c))
- **yaml:** autofix .pre-commit-config.yaml (note: style changed!) ([#434](https://github.com/andreoliwa/nitpick/issues/434)) ([352b53d](https://github.com/andreoliwa/nitpick/commit/352b53d574e49ca683666fd40de3462d1396e575))
- **yaml:** autofix GitHub Workflow files ([#437](https://github.com/andreoliwa/nitpick/issues/437)) ([6af77c4](https://github.com/andreoliwa/nitpick/commit/6af77c4293d8f964ccd249626d47c82440e6412f))
- **yaml:** autofix YAML files ([#431](https://github.com/andreoliwa/nitpick/issues/431)) ([d8cc4b1](https://github.com/andreoliwa/nitpick/commit/d8cc4b1e80366d475c08316c54dc35393b4430dd))
Expand Down Expand Up @@ -289,7 +289,7 @@

### Features

- **style:** validate the [nitpick.files] section ([96c1c31](https://github.com/andreoliwa/nitpick/commit/96c1c31))
- **style:** validate the [nitpick.files] table ([96c1c31](https://github.com/andreoliwa/nitpick/commit/96c1c31))
- show help with the documentation URL on validation errors ([83a8f89](https://github.com/andreoliwa/nitpick/commit/83a8f89))
- validate [nitpick.files.present] and [nitpick.files.absent] ([ab068b5](https://github.com/andreoliwa/nitpick/commit/ab068b5))
- validate configuration of JSON files ([e1192a4](https://github.com/andreoliwa/nitpick/commit/e1192a4))
Expand Down Expand Up @@ -324,7 +324,7 @@

### Features

- **pyproject.toml:** validate [tool.nitpick] section ([765562a](https://github.com/andreoliwa/nitpick/commit/765562a))
- **pyproject.toml:** validate [tool.nitpick] table ([765562a](https://github.com/andreoliwa/nitpick/commit/765562a))

# [0.17.0](https://github.com/andreoliwa/nitpick/compare/v0.16.1...v0.17.0) (2019-08-08)

Expand Down Expand Up @@ -451,7 +451,7 @@
### Bug Fixes

- keep showing other errors when pyproject.toml doesn't exist ([dc7f02f](https://github.com/andreoliwa/nitpick/commit/dc7f02f))
- move nitpick config to an exclusive section on the style file ([cd64361](https://github.com/andreoliwa/nitpick/commit/cd64361))
- move nitpick config to an exclusive table on the style file ([cd64361](https://github.com/andreoliwa/nitpick/commit/cd64361))
- use only yield to return values ([af7d8d2](https://github.com/andreoliwa/nitpick/commit/af7d8d2))
- use yaml.safe_load() ([b1df589](https://github.com/andreoliwa/nitpick/commit/b1df589))

Expand All @@ -467,7 +467,7 @@

### BREAKING CHANGES

- Comma separated values was moved to a different section in the TOML file:
- Comma separated values was moved to a different table in the TOML file:

Before:
["setup.cfg".nitpick]
Expand Down Expand Up @@ -567,7 +567,7 @@ Now:
- First warning, only on the main Python file ([0b30506](https://github.com/andreoliwa/nitpick/commit/0b30506))
- Read config from pyproject.toml, cache data, run only on one Python ([265daa5](https://github.com/andreoliwa/nitpick/commit/265daa5))
- Read style from TOML file/URL (or climb directory tree) ([84f19d6](https://github.com/andreoliwa/nitpick/commit/84f19d6))
- Respect the files section on nitpick.toml ([9e36a02](https://github.com/andreoliwa/nitpick/commit/9e36a02))
- Respect the files table on nitpick.toml ([9e36a02](https://github.com/andreoliwa/nitpick/commit/9e36a02))
- Use nitpick's own default style file if none is provided ([4701b86](https://github.com/andreoliwa/nitpick/commit/4701b86))

<a name="0.1.1"></a>
Expand Down
7 changes: 4 additions & 3 deletions docs/autofix_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
EmojiEnum,
)
from nitpick.core import Nitpick
from nitpick.style import BuiltinStyle, builtin_styles
from nitpick.style import BuiltinStyle, builtin_styles, repo_root

RST_DIVIDER_FROM_HERE = ".. auto-generated-from-here"
RST_DIVIDER_START = ".. auto-generated-start-{}"
Expand Down Expand Up @@ -296,10 +296,11 @@ def _build_library(gitref: bool = True) -> list[str]:
style = BuiltinStyle.from_path(path)

# When run with tox (invoke ci-build), the path starts with "site-packages"
clean_root = style.path_from_repo_root.replace("site-packages/", "src/")
path_from_repo_root = path.relative_to(repo_root()).as_posix()
clean_root = path_from_repo_root.replace("site-packages/", "src/")

row = StyleLibraryRow(
style=f"{pre}`{style.py_url_without_ext} <{clean_root}>`{post}",
style=f"{pre}`{style.formatted} <{clean_root}>`{post}",
name=f"`{style.name} <{style.url}>`_" if style.url else style.name,
)
library[style.identify_tag].append(attr.astuple(row))
Expand Down
37 changes: 33 additions & 4 deletions docs/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,29 @@ If you use Git, you can review the files before committing.

The available commands are described below.

Suggest styles based on project files
-------------------------------------

You can use the ``nitpick init --suggest`` command to suggest styles based on the files in your project.

Nitpick will scan the files starting from the project root, skipping the ones ignored by Git, and suggest the styles that match the file types.

By default, it will suggest the styles from the built-in library. You can use the ``--library`` option to scan a custom directory with styles.

The directory structure of your custom library should be the same as the built-in library: ``<root_library_dir>/<file_type>/<your_style_name>.toml``.

- ``file_type`` can be any tag reported by the `pre-commit/identify library <https://github.com/pre-commit/identify>`_ (e.g. ``python``, ``yaml``, ``markdown``, etc.);
- use the special type ``any`` for styles that apply to all file types (e.g. trim trailing whitespace).

The ``--suggest` command will display what would be changed. To apply these changes and autofix the config, run with the ``--fix`` option.

To ignore styles, add them to the ``[tool.nitpick] ignore_styles`` key on the config file.

Nitpick will consider the following Git ignore files:

- ``.gitignore`` on the project root;
- a global ignore file configured by ``git config --get core.excludesFile``.

.. auto-generated-from-here
.. _cli_cmd:
Expand All @@ -47,7 +70,7 @@ Main options
Commands:
check Don't modify files, just print the differences.
fix Fix files, modifying them directly.
init Create a [tool.nitpick] section in the configuration file if it...
init Create or update the [tool.nitpick] table in the configuration...
ls List of files configured in the Nitpick style.
.. _cli_cmd_fix:
Expand Down Expand Up @@ -121,8 +144,14 @@ At the end of execution, this command displays:
Usage: nitpick init [OPTIONS] [STYLE_URLS]...
Create a [tool.nitpick] section in the configuration file if it doesn't
exist already.
Create or update the [tool.nitpick] table in the configuration file.
Options:
--help Show this message and exit.
-f, --fix Autofix the files changed by the command;
otherwise, just print what would be done
-s, --suggest Suggest styles based on the extension of project
files (skipping Git ignored files)
-l, --library DIRECTORY Library dir to scan for style files (implies
--suggest); if not provided, uses the built-in
style library
--help Show this message and exit.
2 changes: 1 addition & 1 deletion docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Configuration
=============

:ref:`the-style-file` for your project should be configured in the ``[tool.nitpick]`` section of the configuration file.
:ref:`the-style-file` for your project should be configured in the ``[tool.nitpick]`` table of the configuration file.

Possible configuration files (in order of precedence):

Expand Down
6 changes: 3 additions & 3 deletions docs/nitpick_section.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
.. _nitpick_section:

The [nitpick] section
=====================
The [nitpick] table
===================

The [nitpick] section in :ref:`the style file <the-style-file>` contains global settings for the style.
The [nitpick] table in :ref:`the style file <the-style-file>` contains global settings for the style.

Those are settings that either don't belong to any specific config file, or can be applied to all config files.

Expand Down
10 changes: 7 additions & 3 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,18 @@ If you use pre-commit_ on your project, add this to the ``.pre-commit-config.yam
- repo: https://github.com/andreoliwa/nitpick
rev: v0.34.0
hooks:
- id: nitpick-suggest
- id: nitpick
There are 3 available hook IDs:
There are 4 available hook IDs:

- ``nitpick`` and ``nitpick-fix`` both run the ``nitpick fix`` command;
- ``nitpick-check`` runs ``nitpick check``.
- ``nitpick-check`` runs ``nitpick check``;
- ``nitpick-suggest`` runs ``nitpick init --fix --suggest``;

If you want to run Nitpick_ as a flake8_ plugin instead::
If you want to run Nitpick_ as a flake8_ plugin instead:

.. code-block:: yaml
repos:
- repo: https://github.com/PyCQA/flake8
Expand Down
11 changes: 6 additions & 5 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
alabaster==0.7.13 ; python_version >= "3.8" and python_version < "4.0"
attrs==23.1.0 ; python_version >= "3.8" and python_version < "4.0"
autorepr==0.3.0 ; python_version >= "3.8" and python_version < "4.0"
babel==2.13.1 ; python_version >= "3.8" and python_version < "4.0"
babel==2.13.0 ; python_version >= "3.8" and python_version < "4.0"
cattrs==23.1.2 ; python_version >= "3.8" and python_version < "4.0"
certifi==2023.7.22 ; python_version >= "3.8" and python_version < "4.0"
charset-normalizer==3.3.2 ; python_version >= "3.8" and python_version < "4.0"
charset-normalizer==3.3.0 ; python_version >= "3.8" and python_version < "4.0"
click==8.1.7 ; python_version >= "3.8" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.8" and python_version < "4.0" and (platform_system == "Windows" or sys_platform == "win32")
configupdater==3.1.1 ; python_version >= "3.8" and python_version < "4.0"
Expand All @@ -15,7 +15,8 @@ exceptiongroup==1.1.3 ; python_version >= "3.8" and python_version < "3.11"
flake8==5.0.4 ; python_version >= "3.8" and python_version < "4.0"
flatten-dict==0.4.2 ; python_version >= "3.8" and python_version < "4.0"
furl==2.1.3 ; python_version >= "3.8" and python_version < "4.0"
identify==2.5.31 ; python_version >= "3.8" and python_version < "4.0"
gitignore-parser==0.1.9 ; python_version >= "3.8" and python_version < "4.0"
identify==2.5.30 ; python_version >= "3.8" and python_version < "4.0"
idna==3.4 ; python_version >= "3.8" and python_version < "4.0"
imagesize==1.4.1 ; python_version >= "3.8" and python_version < "4.0"
importlib-metadata==6.8.0 ; python_version >= "3.8" and python_version < "3.10"
Expand All @@ -24,7 +25,7 @@ iniconfig==2.0.0 ; python_version >= "3.8" and python_version < "4.0"
jinja2==3.1.2 ; python_version >= "3.8" and python_version < "4.0"
jmespath==1.0.1 ; python_version >= "3.8" and python_version < "4.0"
jsonschema-specifications==2023.7.1 ; python_version >= "3.8" and python_version < "4.0"
jsonschema==4.19.2 ; python_version >= "3.8" and python_version < "4.0"
jsonschema==4.19.1 ; python_version >= "3.8" and python_version < "4.0"
loguru==0.7.2 ; python_version >= "3.8" and python_version < "4.0"
markupsafe==2.1.3 ; python_version >= "3.8" and python_version < "4.0"
marshmallow-polyfield==5.11 ; python_version >= "3.8" and python_version < "4.0"
Expand All @@ -40,7 +41,7 @@ pycodestyle==2.9.1 ; python_version >= "3.8" and python_version < "4.0"
pyflakes==2.5.0 ; python_version >= "3.8" and python_version < "4.0"
pygments==2.16.1 ; python_version >= "3.8" and python_version < "4.0"
pytest-socket==0.6.0 ; python_version >= "3.8" and python_version < "4.0"
pytest==7.4.3 ; python_version >= "3.8" and python_version < "4.0"
pytest==7.4.2 ; python_version >= "3.8" and python_version < "4.0"
python-slugify==8.0.1 ; python_version >= "3.8" and python_version < "4.0"
pytz==2023.3.post1 ; python_version >= "3.8" and python_version < "3.9"
referencing==0.30.2 ; python_version >= "3.8" and python_version < "4.0"
Expand Down
1 change: 1 addition & 0 deletions docs/source/nitpick.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ Submodules
nitpick.generic
nitpick.schemas
nitpick.style
nitpick.tomlkit_ext
nitpick.typedefs
nitpick.violations
7 changes: 7 additions & 0 deletions docs/source/nitpick.tomlkit_ext.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
nitpick.tomlkit\_ext module
===========================

.. automodule:: nitpick.tomlkit_ext
:members:
:undoc-members:
:show-inheritance:
4 changes: 2 additions & 2 deletions docs/styles.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ On YAML files, a list (called a "sequence" in the YAML spec) can contain differe
- Other lists (sequences).

The default behaviour for all lists: when applying a style, Nitpick_ searches
if the element already exists in the list; if not found, the element is appended at the end of list.
if the element already exists in the list; if not found, the element is appended to the end of list.

1. With scalar values, Nitpick_ compares the elements by their exact value.
Strings are compared in a case-sensitive manner, and spaces are considered.
Expand All @@ -124,7 +124,7 @@ On lists containing dicts, it is possible to define a custom "list key" used to
overriding the default compare mechanism above.

If an element is found by its key, the other key/values are compared and Nitpick_ applies the difference.
If the key doesn't exist, the new dict is appended at the end of the list.
If the key doesn't exist, the new dict is appended to the end of the list.

Some files have a predefined configuration:

Expand Down
Loading

0 comments on commit e2bca24

Please sign in to comment.