Skip to content

Commit

Permalink
feat: root files for other programming languages (andreoliwa#321)
Browse files Browse the repository at this point in the history
* feat: add .pre-commit-config.yaml as a root file
* test: run raises QuitComplainingError when no root dir found
* feat: add Rust, Golang and JavaScript root files
  • Loading branch information
andreoliwa authored Mar 21, 2021
1 parent 928c043 commit 09a0e83
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 15 deletions.
23 changes: 14 additions & 9 deletions docs/auto_detection.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@ Root dir of the project

Nitpick_ tries to find the root dir of the project using some hardcoded assumptions.

#. Starting from the current working directory, it will search for files that are usually in the root of a Python project:

- ``pyproject.toml``
- ``setup.py``
- ``setup.cfg``
- ``requirements*.txt``
- ``Pipfile`` (Pipenv_)
- ``app.py`` and ``wsgi.py`` (`Flask CLI`_)
- ``autoapp.py``
#. Starting from the current working directory, it will search for files that are usually in the root of a project:

- ``.pre-commit-config.yaml`` (pre-commit_)
- ``pyproject.toml``
- ``setup.py``
- ``setup.cfg``
- ``requirements*.txt``
- ``Pipfile`` (Pipenv_)
- ``tox.ini`` (tox_)
- ``package.json`` (JavaScript, NodeJS)
- ``Cargo.*`` (Rust)
- ``go.mod``, ``go.sum`` (Golang)
- ``app.py`` and ``wsgi.py`` (`Flask CLI`_)
- ``autoapp.py`` (Flask_)

#. If none of these root files were found, search for ``manage.py``.
On Django_ projects, it can be in another dir inside the root dir (:issue:`21`).
Expand Down
1 change: 1 addition & 0 deletions docs/targets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
.. _Django: https://github.com/django/django
.. _EditorConfig: https://editorconfig.org
.. _flake8: https://gitlab.com/pycqa/flake8
.. _Flask: https://github.com/pallets/flask/
.. _Flask CLI: https://flask.palletsprojects.com/en/1.1.x/cli/
.. _Invoke: https://github.com/pyinvoke/invoke
.. _IPython: https://github.com/ipython/ipython
Expand Down
33 changes: 29 additions & 4 deletions src/nitpick/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,40 @@
READ_THE_DOCS_URL = "https://nitpick.rtfd.io/en/latest/"

# Special files
# Python
PYPROJECT_TOML = "pyproject.toml"
SETUP_PY = "setup.py"
SETUP_CFG = "setup.cfg"
ROOT_PYTHON_FILES = ("setup.py", "app.py", "wsgi.py", "autoapp.py")
ROOT_FILES = (PYPROJECT_TOML, SETUP_CFG, "requirements*.txt", "Pipfile") + ROOT_PYTHON_FILES
REQUIREMENTS_STAR_TXT = "requirements*.txt"
PIPFILE_STAR = "Pipfile.*"
ROOT_PYTHON_FILES = ("app.py", "wsgi.py", "autoapp.py")
MANAGE_PY = "manage.py"
PRE_COMMIT_CONFIG_YAML = ".pre-commit-config.yaml"
EDITOR_CONFIG = ".editorconfig"
TOX_INI = "tox.ini"
PYLINTRC = ".pylintrc"
# Tools
PRE_COMMIT_CONFIG_YAML = ".pre-commit-config.yaml"
EDITOR_CONFIG = ".editorconfig"
# JavaScript
PACKAGE_JSON = "package.json"
# Rust
CARGO_STAR = "Cargo.*"
# Golang
GO_MOD = "go.mod"
GO_SUM = "go.sum"
# All root files
ROOT_FILES = (
PRE_COMMIT_CONFIG_YAML,
PYPROJECT_TOML,
SETUP_PY,
SETUP_CFG,
REQUIREMENTS_STAR_TXT,
PIPFILE_STAR,
TOX_INI,
PACKAGE_JSON,
CARGO_STAR,
GO_MOD,
GO_SUM,
) + ROOT_PYTHON_FILES

SINGLE_QUOTE = "'"
DOUBLE_QUOTE = '"'
Expand Down
6 changes: 5 additions & 1 deletion tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,14 @@ def _simulate_cli(self, command: str, str_or_lines: StrOrList = None, *args: str
expected = list(always_iterable(str_or_lines))
return result, actual, expected

def cli_run(self, str_or_lines: StrOrList = None, apply=False, violations=0) -> "ProjectMock":
def cli_run(self, str_or_lines: StrOrList = None, apply=False, violations=0, exception_class=None) -> "ProjectMock":
"""Assert the expected CLI output for the chosen command."""
cli_args = [] if apply else ["--check"]
result, actual, expected = self._simulate_cli("run", str_or_lines, *cli_args)
if exception_class:
assert isinstance(result.exception, exception_class)
return self

if violations:
expected.append(f"Violations: ❌ {violations} to change manually.")
elif str_or_lines:
Expand Down
7 changes: 6 additions & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from nitpick.constants import PYPROJECT_TOML, SETUP_CFG
from nitpick.core import Nitpick
from nitpick.exceptions import QuitComplainingError
from tests.helpers import ProjectMock


Expand All @@ -19,10 +20,14 @@ def test_singleton():

def test_no_root_dir(tmp_path):
"""No root dir."""
ProjectMock(tmp_path, pyproject_toml=False, setup_py=False).create_symlink("hello.py").flake8().assert_single_error(
project = ProjectMock(tmp_path, pyproject_toml=False, setup_py=False)
project.create_symlink("hello.py").flake8().assert_single_error(
"NIP101 No root dir found (is this a Python project?)"
)

# TODO: don't abort with QuitComplainingError when root files are missing
project.cli_run(exception_class=QuitComplainingError)


def test_multiple_root_dirs(tmp_path):
"""Multiple possible "root dirs" found (e.g.: a requirements.txt file inside a docs dir)."""
Expand Down

0 comments on commit 09a0e83

Please sign in to comment.