Skip to content

Commit cb116b8

Browse files
authored
feat: Make project option available globally (#37)
1 parent 1c41efb commit cb116b8

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

docs/cli.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ At the end of execution, this command displays:
9393
You can use partial and multiple file names in the FILES argument.
9494
9595
Options:
96-
-v, --verbose Increase logging verbosity (-v = INFO, -vv = DEBUG)
97-
--help Show this message and exit.
96+
-p, --project DIRECTORY Path to project root
97+
-v, --verbose Increase logging verbosity (-v = INFO, -vv = DEBUG)
98+
--help Show this message and exit.
9899
99100
.. _cli_cmd_check:
100101

@@ -113,8 +114,9 @@ At the end of execution, this command displays:
113114
argument.
114115
115116
Options:
116-
-v, --verbose Increase logging verbosity (-v = INFO, -vv = DEBUG)
117-
--help Show this message and exit.
117+
-p, --project DIRECTORY Path to project root
118+
-v, --verbose Increase logging verbosity (-v = INFO, -vv = DEBUG)
119+
--help Show this message and exit.
118120
119121
.. _cli_cmd_ls:
120122

@@ -132,7 +134,8 @@ At the end of execution, this command displays:
132134
and multiple file names in the FILES argument.
133135
134136
Options:
135-
--help Show this message and exit.
137+
-p, --project DIRECTORY Path to project root
138+
--help Show this message and exit.
136139
137140
.. _cli_cmd_init:
138141

@@ -147,6 +150,7 @@ At the end of execution, this command displays:
147150
Create or update the [tool.nitpick] table in the configuration file.
148151
149152
Options:
153+
-p, --project DIRECTORY Path to project root
150154
-f, --fix Autofix the files changed by the command;
151155
otherwise, just print what would be done
152156
-s, --suggest Suggest styles based on the extension of project

src/nitpick/cli.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,17 @@
4242
"--verbose", "-v", count=True, default=False, help="Increase logging verbosity (-v = INFO, -vv = DEBUG)"
4343
)
4444
FILES_ARGUMENT = click.argument("files", nargs=-1)
45-
46-
47-
@click.group()
48-
@click.option(
45+
# TODO(phuongfi91): Project option is made available globally in an ugly way. Refactor it.
46+
PROJECT_OPTION = click.option(
4947
"--project",
5048
"-p",
5149
type=click.Path(exists=True, dir_okay=True, file_okay=False, resolve_path=True),
5250
help="Path to project root",
5351
)
52+
53+
54+
@click.group()
55+
@PROJECT_OPTION
5456
@click.option(
5557
f"--{Flake8OptionEnum.OFFLINE.name.lower()}", # pylint: disable=no-member
5658
is_flag=True,
@@ -62,18 +64,19 @@ def nitpick_cli(project: Path | None = None, offline=False): # pylint: disable=
6264
"""Enforce the same settings across multiple language-independent projects."""
6365

6466

65-
def get_nitpick(context: click.Context) -> Nitpick:
67+
def get_nitpick(context: click.Context, project: Path | None = None) -> Nitpick:
6668
"""Create a Nitpick instance from the click context parameters."""
67-
project = None
6869
offline = False
6970
if context.parent:
70-
project = context.parent.params["project"]
71+
project = (
72+
project or context.parent.params["project"]
73+
) # prioritize 'project' from the current command over the one from context
7174
offline = context.parent.params["offline"]
7275
project_root: Path | None = Path(project) if project else None
7376
return Nitpick.singleton().init(project_root, offline)
7477

7578

76-
def common_fix_or_check(context, verbose: int, files, check_only: bool) -> None:
79+
def common_fix_or_check(context, project: Path | None, verbose: int, files, check_only: bool) -> None:
7780
"""Common CLI code for both "fix" and "check" commands."""
7881
if verbose:
7982
level = logging.INFO if verbose == 1 else logging.DEBUG
@@ -85,7 +88,7 @@ def common_fix_or_check(context, verbose: int, files, check_only: bool) -> None:
8588

8689
logger.enable(PROJECT_NAME)
8790

88-
nit = get_nitpick(context)
91+
nit = get_nitpick(context, project)
8992
try:
9093
for fuss in nit.run(*files, autofix=not check_only):
9194
nit.echo(fuss.pretty)
@@ -101,39 +104,42 @@ def common_fix_or_check(context, verbose: int, files, check_only: bool) -> None:
101104

102105
@nitpick_cli.command()
103106
@click.pass_context
107+
@PROJECT_OPTION
104108
@VERBOSE_OPTION
105109
@FILES_ARGUMENT
106-
def fix(context, verbose, files):
110+
def fix(context, project: Path | None, verbose, files):
107111
"""Fix files, modifying them directly.
108112
109113
You can use partial and multiple file names in the FILES argument.
110114
"""
111-
common_fix_or_check(context, verbose, files, False)
115+
common_fix_or_check(context, project, verbose, files, False)
112116

113117

114118
@nitpick_cli.command()
115119
@click.pass_context
120+
@PROJECT_OPTION
116121
@VERBOSE_OPTION
117122
@FILES_ARGUMENT
118-
def check(context, verbose, files):
123+
def check(context, project: Path | None, verbose, files):
119124
"""Don't modify files, just print the differences.
120125
121126
Return code 0 means nothing would change. Return code 1 means some files would be modified.
122127
You can use partial and multiple file names in the FILES argument.
123128
"""
124-
common_fix_or_check(context, verbose, files, True)
129+
common_fix_or_check(context, project, verbose, files, True)
125130

126131

127132
@nitpick_cli.command()
128133
@click.pass_context
134+
@PROJECT_OPTION
129135
@FILES_ARGUMENT
130-
def ls(context, files): # pylint: disable=invalid-name
136+
def ls(context, project: Path | None, files): # pylint: disable=invalid-name
131137
"""List of files configured in the Nitpick style.
132138
133139
Display existing files in green and absent files in red.
134140
You can use partial and multiple file names in the FILES argument.
135141
"""
136-
nit = get_nitpick(context)
142+
nit = get_nitpick(context, project)
137143
try:
138144
violations = list(nit.project.merge_styles(nit.offline))
139145
error_exit_code = 1
@@ -152,6 +158,7 @@ def ls(context, files): # pylint: disable=invalid-name
152158

153159
@nitpick_cli.command()
154160
@click.pass_context
161+
@PROJECT_OPTION
155162
@click.option(
156163
"--fix",
157164
"-f",
@@ -173,8 +180,9 @@ def ls(context, files): # pylint: disable=invalid-name
173180
help="Library dir to scan for style files (implies --suggest); if not provided, uses the built-in style library",
174181
)
175182
@click.argument("style_urls", nargs=-1)
176-
def init(
183+
def init( # noqa: PLR0913, pylint: disable=too-many-arguments
177184
context,
185+
project: Path | None,
178186
fix: bool, # pylint: disable=redefined-outer-name
179187
suggest: bool,
180188
library: str | None,
@@ -194,7 +202,7 @@ def init(
194202
)
195203
return
196204

197-
nit = get_nitpick(context)
205+
nit = get_nitpick(context, project)
198206
config = nit.project.read_configuration()
199207

200208
# Convert tuple to list, so we can add styles to it

0 commit comments

Comments
 (0)