• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

andreoliwa / nitpick / 9594924093

20 Jun 2024 09:21AM UTC coverage: 96.746%. Remained the same
9594924093

push

github

andreoliwa
build(deps): bump urllib3 from 2.0.7 to 2.2.2

Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.0.7 to 2.2.2.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.0.7...2.2.2)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

788 of 827 branches covered (95.28%)

Branch coverage included in aggregate %.

2096 of 2154 relevant lines covered (97.31%)

4.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.19
/src/nitpick/cli.py
1
"""Module that contains the command line app.
2

3
Why does this file exist, and why not put this in __main__?
4

5
You might be tempted to import things from __main__ later, but that will cause
6
problems: the code will get executed twice:
7

8
- When you run `python -mnitpick` python will execute ``__main__.py`` as a script.
9
    That means there won't be any ``nitpick.__main__`` in ``sys.modules``.
10
- When you import __main__ it will get executed again (as a module) because
11
    there's no ``nitpick.__main__`` in ``sys.modules``.
12

13
Also see (1) from https://click.palletsprojects.com/en/5.x/setuptools/#setuptools-integration
14
"""
15

16
from __future__ import annotations
5✔
17

18
import logging
5✔
19
import sys
5✔
20
from pathlib import Path
5✔
21

22
import click
5✔
23
import tomlkit
5✔
24
from click.exceptions import Exit
5✔
25
from loguru import logger
5✔
26

27
from nitpick import tomlkit_ext
5✔
28
from nitpick.constants import (
5✔
29
    CONFIG_KEY_IGNORE_STYLES,
30
    CONFIG_KEY_STYLE,
31
    CONFIG_TOOL_NITPICK_KEY,
32
    PROJECT_NAME,
33
    EmojiEnum,
34
    Flake8OptionEnum,
35
)
36
from nitpick.core import Nitpick
5✔
37
from nitpick.exceptions import QuitComplainingError
5✔
38
from nitpick.generic import relative_to_current_dir
5✔
39
from nitpick.violations import Reporter
5✔
40

41
VERBOSE_OPTION = click.option(
5✔
42
    "--verbose", "-v", count=True, default=False, help="Increase logging verbosity (-v = INFO, -vv = DEBUG)"
43
)
44
FILES_ARGUMENT = click.argument("files", nargs=-1)
5✔
45

46

47
@click.group()
5✔
48
@click.option(
5✔
49
    "--project",
50
    "-p",
51
    type=click.Path(exists=True, dir_okay=True, file_okay=False, resolve_path=True),
52
    help="Path to project root",
53
)
54
@click.option(
5✔
55
    f"--{Flake8OptionEnum.OFFLINE.name.lower()}",  # pylint: disable=no-member
56
    is_flag=True,
57
    default=False,
58
    help=Flake8OptionEnum.OFFLINE.value,
59
)
60
@click.version_option()
5✔
61
def nitpick_cli(project: Path | None = None, offline=False):  # pylint: disable=unused-argument # noqa: ARG001
5✔
62
    """Enforce the same settings across multiple language-independent projects."""
63

64

65
def get_nitpick(context: click.Context) -> Nitpick:
5✔
66
    """Create a Nitpick instance from the click context parameters."""
67
    project = None
5✔
68
    offline = False
5✔
69
    if context.parent:
5!
70
        project = context.parent.params["project"]
5✔
71
        offline = context.parent.params["offline"]
5✔
72
    project_root: Path | None = Path(project) if project else None
5✔
73
    return Nitpick.singleton().init(project_root, offline)
5✔
74

75

76
def common_fix_or_check(context, verbose: int, files, check_only: bool) -> None:
5✔
77
    """Common CLI code for both "fix" and "check" commands."""
78
    if verbose:
5!
79
        level = logging.INFO if verbose == 1 else logging.DEBUG
×
80

81
        # https://loguru.readthedocs.io/en/stable/resources/recipes.html#changing-the-level-of-an-existing-handler
82
        # https://github.com/Delgan/loguru/issues/138#issuecomment-525594566
83
        logger.remove()
×
84
        logger.add(sys.stderr, level=logging.getLevelName(level))
×
85

86
        logger.enable(PROJECT_NAME)
×
87

88
    nit = get_nitpick(context)
5✔
89
    try:
5✔
90
        for fuss in nit.run(*files, autofix=not check_only):
5✔
91
            nit.echo(fuss.pretty)
5✔
92
    except QuitComplainingError as err:
5✔
93
        for fuss in err.violations:
5✔
94
            click.echo(fuss.pretty)
5✔
95
        raise Exit(2) from err
5✔
96

97
    click.secho(Reporter.get_counts())
5✔
98
    if Reporter.manual or Reporter.fixed:
5✔
99
        raise Exit(1)
5✔
100

101

102
@nitpick_cli.command()
5✔
103
@click.pass_context
5✔
104
@VERBOSE_OPTION
5✔
105
@FILES_ARGUMENT
5✔
106
def fix(context, verbose, files):
5✔
107
    """Fix files, modifying them directly.
108

109
    You can use partial and multiple file names in the FILES argument.
110
    """
111
    common_fix_or_check(context, verbose, files, False)
×
112

113

114
@nitpick_cli.command()
5✔
115
@click.pass_context
5✔
116
@VERBOSE_OPTION
5✔
117
@FILES_ARGUMENT
5✔
118
def check(context, verbose, files):
5✔
119
    """Don't modify files, just print the differences.
120

121
    Return code 0 means nothing would change. Return code 1 means some files would be modified.
122
    You can use partial and multiple file names in the FILES argument.
123
    """
124
    common_fix_or_check(context, verbose, files, True)
5✔
125

126

127
@nitpick_cli.command()
5✔
128
@click.pass_context
5✔
129
@FILES_ARGUMENT
5✔
130
def ls(context, files):  # pylint: disable=invalid-name
5✔
131
    """List of files configured in the Nitpick style.
132

133
    Display existing files in green and absent files in red.
134
    You can use partial and multiple file names in the FILES argument.
135
    """
136
    nit = get_nitpick(context)
5✔
137
    try:
5✔
138
        violations = list(nit.project.merge_styles(nit.offline))
5✔
139
        error_exit_code = 1
5✔
140
    except QuitComplainingError as err:
5✔
141
        violations = err.violations
5✔
142
        error_exit_code = 2
5✔
143
    if violations:
5✔
144
        for fuss in violations:
5✔
145
            click.echo(fuss.pretty)
5✔
146
        raise Exit(error_exit_code)  # TODO: test: ls with invalid style
5✔
147

148
    # TODO: test: configured_files() API
149
    for file in nit.configured_files(*files):
5✔
150
        click.secho(relative_to_current_dir(file), fg="green" if file.exists() else "red")
5✔
151

152

153
@nitpick_cli.command()
5✔
154
@click.pass_context
5✔
155
@click.option(
5✔
156
    "--fix",
157
    "-f",
158
    is_flag=True,
159
    default=False,
160
    help="Autofix the files changed by the command; otherwise, just print what would be done",
161
)
162
@click.option(
5✔
163
    "--suggest",
164
    "-s",
165
    is_flag=True,
166
    default=False,
167
    help="Suggest styles based on the extension of project files (skipping Git ignored files)",
168
)
169
@click.option(
5✔
170
    "--library",
171
    "-l",
172
    type=click.Path(exists=True, dir_okay=True, file_okay=False, resolve_path=True),
173
    help="Library dir to scan for style files (implies --suggest); if not provided, uses the built-in style library",
174
)
175
@click.argument("style_urls", nargs=-1)
5✔
176
def init(
5✔
177
    context,
178
    fix: bool,  # pylint: disable=redefined-outer-name
179
    suggest: bool,
180
    library: str | None,
181
    style_urls: list[str],
182
) -> None:
183
    """Create or update the [tool.nitpick] table in the configuration file."""
184
    # If a library is provided, it implies --suggest
185
    if library:
5✔
186
        suggest = True
5✔
187

188
    if not style_urls and not suggest:
5✔
189
        click.secho(
5✔
190
            f"Nothing to do. {EmojiEnum.SLEEPY_FACE.value} Either pass at least one style URL"
191
            " or use --suggest to add styles based on the files in the project root"
192
            " (you can do both at the same time).",
193
            fg="yellow",
194
        )
195
        return
5✔
196

197
    nit = get_nitpick(context)
5✔
198
    config = nit.project.read_configuration()
5✔
199

200
    # Convert tuple to list, so we can add styles to it
201
    style_urls = list(style_urls)
5✔
202
    if suggest:
5✔
203
        from nitpick import __version__  # pylint: disable=import-outside-toplevel
5✔
204

205
        # Create the ignored styles array only when suggesting styles
206
        if CONFIG_KEY_IGNORE_STYLES not in config.table:
5!
207
            config.table.add(CONFIG_KEY_IGNORE_STYLES, config.dont_suggest)
5✔
208

209
        style_urls.extend(nit.project.suggest_styles(library))
5✔
210
        tomlkit_ext.update_comment_before(
5✔
211
            config.table,
212
            CONFIG_KEY_STYLE,
213
            PROJECT_NAME,
214
            f"""
215
            (auto-generated by "nitpick init --suggest" {__version__})
216
            Styles added to the Nitpick Style Library will be appended to the end of the {CONFIG_KEY_STYLE!r} key.
217
            If you don't want a style, move it to the {CONFIG_KEY_IGNORE_STYLES!r} key.
218
            """,
219
        )
220

221
    new_styles = []
5✔
222
    for style_url in style_urls:
5✔
223
        if style_url in config.styles or style_url in config.dont_suggest:
5✔
224
            continue
5✔
225
        new_styles.append(style_url)
5✔
226
        config.styles.add_line(style_url, indent="  ")
5✔
227
    if not new_styles:
5✔
228
        click.echo(
5✔
229
            f"All done! {EmojiEnum.STAR_CAKE.value} [{CONFIG_TOOL_NITPICK_KEY}] table left unchanged in {config.file.name!r}"
230
        )
231
        return
5✔
232

233
    click.echo("New styles:")
5✔
234
    for style in new_styles:
5✔
235
        click.echo(f"- {style}")
5✔
236
    count = len(new_styles)
5✔
237
    message = f"{count} style{'s' if count > 1 else ''}"
5✔
238

239
    if not fix:
5✔
240
        click.secho(
5✔
241
            f"Use --fix to append {message} to the [{CONFIG_TOOL_NITPICK_KEY}]"
242
            f" table in the config file {config.file.name!r}.",
243
            fg="yellow",
244
        )
245
        return
5✔
246

247
    config.file.write_text(tomlkit.dumps(config.doc), encoding="UTF-8")
5✔
248
    click.echo(
5✔
249
        f"The [{CONFIG_TOOL_NITPICK_KEY}] table was updated in {config.file.name!r}:"
250
        f" {message} appended. {EmojiEnum.STAR_CAKE.value}"
251
    )
252
    raise Exit(1)  # A non-zero exit code is needed when executed as a pre-commit hook
5✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc