Skip to content

Commit

Permalink
Merge 8610873 into 6c84f19
Browse files Browse the repository at this point in the history
  • Loading branch information
andreoliwa committed Apr 6, 2021
2 parents 6c84f19 + 8610873 commit 75a80d3
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 6 deletions.
26 changes: 24 additions & 2 deletions docs/cli.rst
Expand Up @@ -27,6 +27,8 @@ The available commands are described below.

.. auto-generated-from-here
.. _cli_cmd:

Main options
------------

Expand All @@ -45,8 +47,11 @@ Main options
--help Show this message and exit.
Commands:
ls List of files configured in the Nitpick style.
run Apply suggestions to configuration files.
init Create a configuration file if it doesn't exist already.
ls List of files configured in the Nitpick style.
run Apply suggestions to configuration files.
.. _cli_cmd_run:

``run``: Apply style to files
-----------------------------
Expand All @@ -73,6 +78,8 @@ At the end of execution, this command displays:
-v, --verbose Verbose logging
--help Show this message and exit.
.. _cli_cmd_ls:

``ls``: List configures files
-----------------------------

Expand All @@ -88,3 +95,18 @@ At the end of execution, this command displays:
Options:
--help Show this message and exit.
.. _cli_cmd_init:

``init``: Initialise a configuration file
-----------------------------------------


.. code-block::
Usage: nitpick init [OPTIONS]
Create a configuration file if it doesn't exist already.
Options:
--help Show this message and exit.
4 changes: 3 additions & 1 deletion docs/configuration.rst
Expand Up @@ -16,7 +16,9 @@ Possible configuration files (in order of precedence):
The first file found will be used; the other files will be ignored.

You can configure your own style like this:
Run the ``nipick init`` CLI command to create a config file (:ref:`cli_cmd_init`).

To configure your own style:

.. code-block:: toml
Expand Down
6 changes: 5 additions & 1 deletion docs/generate_rst.py
Expand Up @@ -64,6 +64,7 @@
""",
),
("ls", "List configures files", ""),
("init", "Initialise a configuration file", ""),
]

nit = Nitpick.singleton().init()
Expand Down Expand Up @@ -197,6 +198,8 @@ def generate_plugins(filename: str) -> int:
def generate_cli(filename: str) -> int:
"""Generate CLI docs."""
template = """
.. _cli_cmd{anchor}:
{header}
{dashes}
{long}
Expand All @@ -209,6 +212,7 @@ def generate_cli(filename: str) -> int:
blocks = []

for command, short, long in CLI_MAPPING:
anchor = f"_{command}" if command else ""
header = f"``{command}``: {short}" if command else short
blocks.append("")
parts = ["nitpick"]
Expand All @@ -219,7 +223,7 @@ def generate_cli(filename: str) -> int:
output = check_output(parts).decode().strip() # nosec
blocks.append(
clean_template.format(
header=header, dashes="-" * len(header), long=dedent(long), help=indent(output, " ")
anchor=anchor, header=header, dashes="-" * len(header), long=dedent(long), help=indent(output, " ")
)
)

Expand Down
16 changes: 15 additions & 1 deletion src/nitpick/cli.py
Expand Up @@ -19,7 +19,7 @@
from click.exceptions import Exit
from loguru import logger

from nitpick.constants import PROJECT_NAME
from nitpick.constants import DOT_NITPICK_TOML, PROJECT_NAME
from nitpick.core import Nitpick
from nitpick.enums import OptionEnum
from nitpick.exceptions import QuitComplainingError
Expand Down Expand Up @@ -114,3 +114,17 @@ def ls(context, files): # pylint: disable=invalid-name
# TODO: test API .configured_files
for file in nit.configured_files(*files):
click.secho(relative_to_current_dir(file), fg="green" if file.exists() else "red")


@nitpick_cli.command()
@click.pass_context
def init(context):
"""Create a configuration file if it doesn't exist already."""
nit = get_nitpick(context)
config = nit.project.read_configuration()
if config.file:
click.secho(f"A config file already exists: {config.file.name}", fg="yellow")
raise Exit(1)

nit.project.create_configuration()
click.secho(f"Config file created: {DOT_NITPICK_TOML}", fg="green")
16 changes: 16 additions & 0 deletions src/nitpick/project.py
Expand Up @@ -10,14 +10,18 @@
from loguru import logger
from marshmallow_polyfield import PolyField
from pluggy import PluginManager
from tomlkit import comment, document, dumps, table
from tomlkit.items import Key, KeyType

from nitpick import fields, plugins
from nitpick.constants import (
CONFIG_FILES,
DOT_NITPICK_TOML,
MANAGE_PY,
NITPICK_MINIMUM_VERSION_JMEX,
PROJECT_NAME,
PYPROJECT_TOML,
READ_THE_DOCS_URL,
ROOT_FILES,
ROOT_PYTHON_FILES,
TOOL_NITPICK,
Expand Down Expand Up @@ -233,3 +237,15 @@ def merge_styles(self, offline: bool) -> Iterator[Fuss]:

self.nitpick_section = self.style_dict.get("nitpick", {})
self.nitpick_files_section = self.nitpick_section.get("files", {})

def create_configuration(self) -> None:
"""Create a configuration file."""
from nitpick.style import Style # pylint: disable=import-outside-toplevel

doc = document()
doc.add(comment("This file was generated by the `nitpick init` command"))
doc.add(comment(f"More info at {READ_THE_DOCS_URL}configuration.html"))
doc.add(Key(TOOL_NITPICK, KeyType.Bare), table().add("style", [Style.get_default_style_url()]))

path: Path = self.root / DOT_NITPICK_TOML
path.write_text(dumps(doc, sort_keys=True))
9 changes: 8 additions & 1 deletion tests/helpers.py
Expand Up @@ -353,10 +353,17 @@ def cli_run(
compare(actual=actual, expected=expected)
return self

def cli_ls(self, str_or_lines: StrOrList, exit_code: int = None):
def cli_ls(self, str_or_lines: StrOrList, *, exit_code: int = None) -> "ProjectMock":
"""Run the ls command and assert the output."""
result, actual, expected = self._simulate_cli("ls", str_or_lines, exit_code=exit_code)
compare(actual=actual, expected=expected, prefix=f"Result: {result}")
return self

def cli_init(self, str_or_lines: StrOrList, *, exit_code: int = None) -> "ProjectMock":
"""Run the init command and assert the output."""
result, actual, expected = self._simulate_cli("init", str_or_lines, exit_code=exit_code)
compare(actual=actual, expected=expected, prefix=f"Result: {result}")
return self

def assert_file_contents(self, *name_contents: Union[PathOrStr, str]):
"""Assert the file has the expected contents."""
Expand Down
26 changes: 26 additions & 0 deletions tests/test_cli.py
@@ -1,4 +1,8 @@
"""CLI tests."""
import pytest

from nitpick.constants import DOT_NITPICK_TOML, PYPROJECT_TOML, READ_THE_DOCS_URL, TOOL_NITPICK
from nitpick.style import Style
from tests.helpers import XFAIL_ON_WINDOWS, ProjectMock


Expand Down Expand Up @@ -28,3 +32,25 @@ def test_simple_error(tmp_path):
line-length = 100
"""
)


@pytest.mark.parametrize("config_file", [DOT_NITPICK_TOML, PYPROJECT_TOML])
def test_config_file_already_exists(tmp_path, config_file):
"""Test if .nitpick.toml already exists."""
project = ProjectMock(tmp_path, pyproject_toml=False, setup_py=True).save_file(config_file, "")
project.cli_init(f"A config file already exists: {config_file}", exit_code=1)


def test_create_basic_dot_nitpick_toml(tmp_path):
"""If no config file is found, create a basic .nitpick.toml."""
project = ProjectMock(tmp_path, pyproject_toml=False, setup_py=True)
project.cli_init(f"Config file created: {DOT_NITPICK_TOML}").assert_file_contents(
DOT_NITPICK_TOML,
f"""
# This file was generated by the `nitpick init` command
# More info at {READ_THE_DOCS_URL}configuration.html
[{TOOL_NITPICK}]
style = ["{Style.get_default_style_url()}"]
""",
)

0 comments on commit 75a80d3

Please sign in to comment.