duty 1.3.0__py3-none-any.whl → 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- duty/callables/__init__.py +32 -24
- duty/callables/build.py +76 -0
- duty/callables/git_changelog.py +178 -0
- duty/callables/griffe.py +227 -0
- duty/callables/twine.py +284 -0
- duty/cli.py +2 -0
- duty/context.py +6 -1
- duty/tools/__init__.py +48 -0
- duty/tools/_autoflake.py +138 -0
- duty/tools/_base.py +66 -0
- duty/tools/_black.py +184 -0
- duty/tools/_blacken_docs.py +115 -0
- duty/tools/_build.py +84 -0
- duty/tools/_coverage.py +721 -0
- duty/tools/_flake8.py +230 -0
- duty/tools/_git_changelog.py +186 -0
- duty/tools/_griffe.py +226 -0
- duty/tools/_interrogate.py +160 -0
- duty/tools/_isort.py +579 -0
- duty/tools/_mkdocs.py +271 -0
- duty/tools/_mypy.py +502 -0
- duty/tools/_pytest.py +483 -0
- duty/tools/_ruff.py +451 -0
- duty/tools/_safety.py +97 -0
- duty/tools/_ssort.py +44 -0
- duty/tools/_twine.py +289 -0
- {duty-1.3.0.dist-info → duty-1.4.0.dist-info}/METADATA +2 -1
- duty-1.4.0.dist-info/RECORD +53 -0
- {duty-1.3.0.dist-info → duty-1.4.0.dist-info}/WHEEL +1 -1
- duty-1.3.0.dist-info/RECORD +0 -30
- {duty-1.3.0.dist-info → duty-1.4.0.dist-info}/entry_points.txt +0 -0
- {duty-1.3.0.dist-info → duty-1.4.0.dist-info}/licenses/LICENSE +0 -0
duty/callables/twine.py
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"""Callable for [Twine](https://github.com/pypa/twine)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from failprint.lazy import lazy
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def run(*args: str, version: bool = False, no_color: bool = False) -> None:
|
|
9
|
+
"""Run `twine`.
|
|
10
|
+
|
|
11
|
+
Parameters:
|
|
12
|
+
*args: CLI arguments.
|
|
13
|
+
version: Show program's version number and exit.
|
|
14
|
+
no_color: Disable colored output.
|
|
15
|
+
"""
|
|
16
|
+
from twine.cli import dispatch as twine
|
|
17
|
+
|
|
18
|
+
cli_args = []
|
|
19
|
+
|
|
20
|
+
# --version and --no-color must appear first.
|
|
21
|
+
if version:
|
|
22
|
+
cli_args.append("--version")
|
|
23
|
+
|
|
24
|
+
if no_color:
|
|
25
|
+
cli_args.append("--no-color")
|
|
26
|
+
|
|
27
|
+
cli_args.extend(args)
|
|
28
|
+
|
|
29
|
+
twine(cli_args)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@lazy(name="twine.check")
|
|
33
|
+
def check(
|
|
34
|
+
*dists: str,
|
|
35
|
+
strict: bool = False,
|
|
36
|
+
version: bool = False,
|
|
37
|
+
no_color: bool = False,
|
|
38
|
+
) -> None:
|
|
39
|
+
"""Checks whether your distribution's long description will render correctly on PyPI.
|
|
40
|
+
|
|
41
|
+
Parameters:
|
|
42
|
+
dists: The distribution files to check, usually `dist/*`.
|
|
43
|
+
strict: Fail on warnings.
|
|
44
|
+
version: Show program's version number and exit.
|
|
45
|
+
no_color: Disable colored output.
|
|
46
|
+
"""
|
|
47
|
+
cli_args = list(dists)
|
|
48
|
+
|
|
49
|
+
if strict is True:
|
|
50
|
+
cli_args.append("--strict")
|
|
51
|
+
|
|
52
|
+
run("check", *cli_args, version=version, no_color=no_color)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@lazy(name="twine.register")
|
|
56
|
+
def register(
|
|
57
|
+
package: str,
|
|
58
|
+
*,
|
|
59
|
+
repository: str = "pypi",
|
|
60
|
+
repository_url: str | None = None,
|
|
61
|
+
attestations: bool = False,
|
|
62
|
+
sign: bool = False,
|
|
63
|
+
sign_with: str | None = None,
|
|
64
|
+
identity: str | None = None,
|
|
65
|
+
username: str | None = None,
|
|
66
|
+
password: str | None = None,
|
|
67
|
+
non_interactive: bool = False,
|
|
68
|
+
comment: str | None = None,
|
|
69
|
+
config_file: str | None = None,
|
|
70
|
+
skip_existing: bool = False,
|
|
71
|
+
cert: str | None = None,
|
|
72
|
+
client_cert: str | None = None,
|
|
73
|
+
verbose: bool = False,
|
|
74
|
+
disable_progress_bar: bool = False,
|
|
75
|
+
version: bool = False,
|
|
76
|
+
no_color: bool = False,
|
|
77
|
+
) -> None:
|
|
78
|
+
"""Pre-register a name with a repository before uploading a distribution.
|
|
79
|
+
|
|
80
|
+
Pre-registration is not supported on PyPI, so the register command
|
|
81
|
+
is only necessary if you are using a different repository that requires it.
|
|
82
|
+
|
|
83
|
+
Parameters:
|
|
84
|
+
package: File from which we read the package metadata.
|
|
85
|
+
repository: The repository (package index) to upload the package to.
|
|
86
|
+
Should be a section in the config file (default: `pypi`).
|
|
87
|
+
Can also be set via `TWINE_REPOSITORY` environment variable.
|
|
88
|
+
repository_url: The repository (package index) URL to upload the package to. This overrides `--repository`.
|
|
89
|
+
Can also be set via `TWINE_REPOSITORY_URL` environment variable.
|
|
90
|
+
attestations: Upload each file's associated attestations.
|
|
91
|
+
sign: Sign files to upload using GPG.
|
|
92
|
+
sign_with: GPG program used to sign uploads (default: `gpg`).
|
|
93
|
+
identity: GPG identity used to sign files.
|
|
94
|
+
username: The username to authenticate to the repository (package index) as.
|
|
95
|
+
Can also be set via `TWINE_USERNAME` environment variable.
|
|
96
|
+
password: The password to authenticate to the repository (package index) with.
|
|
97
|
+
Can also be set via `TWINE_PASSWORD` environment variable.
|
|
98
|
+
non_interactive: Do not interactively prompt for username/password if the required credentials are missing.
|
|
99
|
+
Can also be set via `TWINE_NON_INTERACTIVE` environment variable.
|
|
100
|
+
comment: The comment to include with the distribution file.
|
|
101
|
+
config_file: The `.pypirc` config file to use.
|
|
102
|
+
skip_existing: Continue uploading files if one already exists.
|
|
103
|
+
Only valid when uploading to PyPI. Other implementations may not support this.
|
|
104
|
+
cert: Path to alternate CA bundle (can also be set via `TWINE_CERT` environment variable).
|
|
105
|
+
client_cert: Path to SSL client certificate, a single file containing the private key and the certificate in PEM format.
|
|
106
|
+
verbose: Show verbose output.
|
|
107
|
+
disable_progress_bar: Disable the progress bar.
|
|
108
|
+
version: Show program's version number and exit.
|
|
109
|
+
no_color: Disable colored output.
|
|
110
|
+
"""
|
|
111
|
+
cli_args = [package]
|
|
112
|
+
|
|
113
|
+
if repository:
|
|
114
|
+
cli_args.append("--repository")
|
|
115
|
+
cli_args.append(repository)
|
|
116
|
+
|
|
117
|
+
if repository_url:
|
|
118
|
+
cli_args.append("--repository-url")
|
|
119
|
+
cli_args.append(repository_url)
|
|
120
|
+
|
|
121
|
+
if attestations:
|
|
122
|
+
cli_args.append("--attestations")
|
|
123
|
+
|
|
124
|
+
if sign:
|
|
125
|
+
cli_args.append("--sign")
|
|
126
|
+
|
|
127
|
+
if sign_with:
|
|
128
|
+
cli_args.append("--sign-with")
|
|
129
|
+
cli_args.append(sign_with)
|
|
130
|
+
|
|
131
|
+
if identity:
|
|
132
|
+
cli_args.append("--identity")
|
|
133
|
+
cli_args.append(identity)
|
|
134
|
+
|
|
135
|
+
if username:
|
|
136
|
+
cli_args.append("--username")
|
|
137
|
+
cli_args.append(username)
|
|
138
|
+
|
|
139
|
+
if password:
|
|
140
|
+
cli_args.append("--password")
|
|
141
|
+
cli_args.append(password)
|
|
142
|
+
|
|
143
|
+
if non_interactive:
|
|
144
|
+
cli_args.append("--non-interactive")
|
|
145
|
+
|
|
146
|
+
if comment:
|
|
147
|
+
cli_args.append("--repository")
|
|
148
|
+
|
|
149
|
+
if config_file:
|
|
150
|
+
cli_args.append("--config-file")
|
|
151
|
+
cli_args.append(config_file)
|
|
152
|
+
|
|
153
|
+
if skip_existing:
|
|
154
|
+
cli_args.append("--skip-existing")
|
|
155
|
+
|
|
156
|
+
if cert:
|
|
157
|
+
cli_args.append("--cert")
|
|
158
|
+
cli_args.append(cert)
|
|
159
|
+
|
|
160
|
+
if client_cert:
|
|
161
|
+
cli_args.append("--client-cert")
|
|
162
|
+
cli_args.append(client_cert)
|
|
163
|
+
|
|
164
|
+
if verbose:
|
|
165
|
+
cli_args.append("--verbose")
|
|
166
|
+
|
|
167
|
+
if disable_progress_bar:
|
|
168
|
+
cli_args.append("--disable-progress-bar")
|
|
169
|
+
|
|
170
|
+
run("check", *cli_args, version=version, no_color=no_color)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@lazy(name="twine.upload")
|
|
174
|
+
def upload(
|
|
175
|
+
*dists: str,
|
|
176
|
+
repository: str = "pypi",
|
|
177
|
+
repository_url: str | None = None,
|
|
178
|
+
attestations: bool = False,
|
|
179
|
+
sign: bool = False,
|
|
180
|
+
sign_with: str | None = None,
|
|
181
|
+
identity: str | None = None,
|
|
182
|
+
username: str | None = None,
|
|
183
|
+
password: str | None = None,
|
|
184
|
+
non_interactive: bool = False,
|
|
185
|
+
comment: str | None = None,
|
|
186
|
+
config_file: str | None = None,
|
|
187
|
+
skip_existing: bool = False,
|
|
188
|
+
cert: str | None = None,
|
|
189
|
+
client_cert: str | None = None,
|
|
190
|
+
verbose: bool = False,
|
|
191
|
+
disable_progress_bar: bool = False,
|
|
192
|
+
version: bool = False,
|
|
193
|
+
no_color: bool = False,
|
|
194
|
+
) -> None:
|
|
195
|
+
"""Uploads one or more distributions to a repository.
|
|
196
|
+
|
|
197
|
+
Parameters:
|
|
198
|
+
dists: The distribution files to check, usually `dist/*`.
|
|
199
|
+
repository: The repository (package index) to upload the package to.
|
|
200
|
+
Should be a section in the config file (default: `pypi`).
|
|
201
|
+
Can also be set via `TWINE_REPOSITORY` environment variable.
|
|
202
|
+
repository_url: The repository (package index) URL to upload the package to. This overrides `--repository`.
|
|
203
|
+
Can also be set via `TWINE_REPOSITORY_URL` environment variable.
|
|
204
|
+
attestations: Upload each file's associated attestations.
|
|
205
|
+
sign: Sign files to upload using GPG.
|
|
206
|
+
sign_with: GPG program used to sign uploads (default: `gpg`).
|
|
207
|
+
identity: GPG identity used to sign files.
|
|
208
|
+
username: The username to authenticate to the repository (package index) as.
|
|
209
|
+
Can also be set via `TWINE_USERNAME` environment variable.
|
|
210
|
+
password: The password to authenticate to the repository (package index) with.
|
|
211
|
+
Can also be set via `TWINE_PASSWORD` environment variable.
|
|
212
|
+
non_interactive: Do not interactively prompt for username/password if the required credentials are missing.
|
|
213
|
+
Can also be set via `TWINE_NON_INTERACTIVE` environment variable.
|
|
214
|
+
comment: The comment to include with the distribution file.
|
|
215
|
+
config_file: The `.pypirc` config file to use.
|
|
216
|
+
skip_existing: Continue uploading files if one already exists.
|
|
217
|
+
Only valid when uploading to PyPI. Other implementations may not support this.
|
|
218
|
+
cert: Path to alternate CA bundle (can also be set via `TWINE_CERT` environment variable).
|
|
219
|
+
client_cert: Path to SSL client certificate, a single file containing the private key and the certificate in PEM format.
|
|
220
|
+
verbose: Show verbose output.
|
|
221
|
+
disable_progress_bar: Disable the progress bar.
|
|
222
|
+
version: Show program's version number and exit.
|
|
223
|
+
no_color: Disable colored output.
|
|
224
|
+
"""
|
|
225
|
+
cli_args = list(dists)
|
|
226
|
+
|
|
227
|
+
if repository:
|
|
228
|
+
cli_args.append("--repository")
|
|
229
|
+
cli_args.append(repository)
|
|
230
|
+
|
|
231
|
+
if repository_url:
|
|
232
|
+
cli_args.append("--repository-url")
|
|
233
|
+
cli_args.append(repository_url)
|
|
234
|
+
|
|
235
|
+
if attestations:
|
|
236
|
+
cli_args.append("--attestations")
|
|
237
|
+
|
|
238
|
+
if sign:
|
|
239
|
+
cli_args.append("--sign")
|
|
240
|
+
|
|
241
|
+
if sign_with:
|
|
242
|
+
cli_args.append("--sign-with")
|
|
243
|
+
cli_args.append(sign_with)
|
|
244
|
+
|
|
245
|
+
if identity:
|
|
246
|
+
cli_args.append("--identity")
|
|
247
|
+
cli_args.append(identity)
|
|
248
|
+
|
|
249
|
+
if username:
|
|
250
|
+
cli_args.append("--username")
|
|
251
|
+
cli_args.append(username)
|
|
252
|
+
|
|
253
|
+
if password:
|
|
254
|
+
cli_args.append("--password")
|
|
255
|
+
cli_args.append(password)
|
|
256
|
+
|
|
257
|
+
if non_interactive:
|
|
258
|
+
cli_args.append("--non-interactive")
|
|
259
|
+
|
|
260
|
+
if comment:
|
|
261
|
+
cli_args.append("--repository")
|
|
262
|
+
|
|
263
|
+
if config_file:
|
|
264
|
+
cli_args.append("--config-file")
|
|
265
|
+
cli_args.append(config_file)
|
|
266
|
+
|
|
267
|
+
if skip_existing:
|
|
268
|
+
cli_args.append("--skip-existing")
|
|
269
|
+
|
|
270
|
+
if cert:
|
|
271
|
+
cli_args.append("--cert")
|
|
272
|
+
cli_args.append(cert)
|
|
273
|
+
|
|
274
|
+
if client_cert:
|
|
275
|
+
cli_args.append("--client-cert")
|
|
276
|
+
cli_args.append(client_cert)
|
|
277
|
+
|
|
278
|
+
if verbose:
|
|
279
|
+
cli_args.append("--verbose")
|
|
280
|
+
|
|
281
|
+
if disable_progress_bar:
|
|
282
|
+
cli_args.append("--disable-progress-bar")
|
|
283
|
+
|
|
284
|
+
run("upload", *cli_args, version=version, no_color=no_color)
|
duty/cli.py
CHANGED
|
@@ -214,6 +214,8 @@ def parse_commands(arg_lists: list[list[str]], global_opts: dict[str, Any], coll
|
|
|
214
214
|
for arg_list in arg_lists:
|
|
215
215
|
duty = collection.get(arg_list[0])
|
|
216
216
|
opts, remainder = parse_options(duty, arg_list[1:])
|
|
217
|
+
if remainder and remainder[0] == "--":
|
|
218
|
+
remainder = remainder[1:]
|
|
217
219
|
duty.options_override = {**global_opts, **opts}
|
|
218
220
|
commands.append((duty, *parse_args(duty, remainder)))
|
|
219
221
|
return commands
|
duty/context.py
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import os
|
|
6
|
-
from contextlib import contextmanager
|
|
6
|
+
from contextlib import contextmanager, suppress
|
|
7
7
|
from typing import Any, Callable, Iterator, List, Union
|
|
8
8
|
|
|
9
9
|
from failprint.runners import run as failprint_run
|
|
10
10
|
|
|
11
11
|
from duty.exceptions import DutyFailure
|
|
12
|
+
from duty.tools import Tool
|
|
12
13
|
|
|
13
14
|
CmdType = Union[str, List[str], Callable]
|
|
14
15
|
|
|
@@ -67,6 +68,10 @@ class Context:
|
|
|
67
68
|
final_options = dict(self._options)
|
|
68
69
|
final_options.update(options)
|
|
69
70
|
|
|
71
|
+
if "command" not in final_options and isinstance(cmd, Tool):
|
|
72
|
+
with suppress(ValueError):
|
|
73
|
+
final_options["command"] = cmd.cli_command
|
|
74
|
+
|
|
70
75
|
allow_overrides = final_options.pop("allow_overrides", True)
|
|
71
76
|
workdir = final_options.pop("workdir", None)
|
|
72
77
|
|
duty/tools/__init__.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Module containing callables for many tools."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from failprint.lazy import lazy
|
|
6
|
+
|
|
7
|
+
from duty.tools._autoflake import autoflake
|
|
8
|
+
from duty.tools._base import LazyStderr, LazyStdout, Tool
|
|
9
|
+
from duty.tools._black import black
|
|
10
|
+
from duty.tools._blacken_docs import blacken_docs
|
|
11
|
+
from duty.tools._build import build
|
|
12
|
+
from duty.tools._coverage import coverage
|
|
13
|
+
from duty.tools._flake8 import flake8
|
|
14
|
+
from duty.tools._git_changelog import git_changelog
|
|
15
|
+
from duty.tools._griffe import griffe
|
|
16
|
+
from duty.tools._interrogate import interrogate
|
|
17
|
+
from duty.tools._isort import isort
|
|
18
|
+
from duty.tools._mkdocs import mkdocs
|
|
19
|
+
from duty.tools._mypy import mypy
|
|
20
|
+
from duty.tools._pytest import pytest
|
|
21
|
+
from duty.tools._ruff import ruff
|
|
22
|
+
from duty.tools._safety import safety
|
|
23
|
+
from duty.tools._ssort import ssort
|
|
24
|
+
from duty.tools._twine import twine
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"Tool",
|
|
28
|
+
"LazyStdout",
|
|
29
|
+
"LazyStderr",
|
|
30
|
+
"lazy",
|
|
31
|
+
"autoflake",
|
|
32
|
+
"black",
|
|
33
|
+
"blacken_docs",
|
|
34
|
+
"build",
|
|
35
|
+
"coverage",
|
|
36
|
+
"flake8",
|
|
37
|
+
"git_changelog",
|
|
38
|
+
"griffe",
|
|
39
|
+
"interrogate",
|
|
40
|
+
"isort",
|
|
41
|
+
"mkdocs",
|
|
42
|
+
"mypy",
|
|
43
|
+
"pytest",
|
|
44
|
+
"ruff",
|
|
45
|
+
"safety",
|
|
46
|
+
"ssort",
|
|
47
|
+
"twine",
|
|
48
|
+
]
|
duty/tools/_autoflake.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Callable for [autoflake](https://github.com/PyCQA/autoflake)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from duty.tools._base import LazyStderr, LazyStdout, Tool
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class autoflake(Tool): # noqa: N801
|
|
9
|
+
"""Call [autoflake](https://github.com/PyCQA/autoflake)."""
|
|
10
|
+
|
|
11
|
+
cli_name = "autoflake"
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*files: str,
|
|
16
|
+
config: str | None = None,
|
|
17
|
+
check: bool | None = None,
|
|
18
|
+
check_diff: bool | None = None,
|
|
19
|
+
imports: list[str] | None = None,
|
|
20
|
+
remove_all_unused_imports: bool | None = None,
|
|
21
|
+
recursive: bool | None = None,
|
|
22
|
+
jobs: int | None = None,
|
|
23
|
+
exclude: list[str] | None = None,
|
|
24
|
+
expand_star_imports: bool | None = None,
|
|
25
|
+
ignore_init_module_imports: bool | None = None,
|
|
26
|
+
remove_duplicate_keys: bool | None = None,
|
|
27
|
+
remove_unused_variables: bool | None = None,
|
|
28
|
+
remove_rhs_for_unused_variables: bool | None = None,
|
|
29
|
+
ignore_pass_statements: bool | None = None,
|
|
30
|
+
ignore_pass_after_docstring: bool | None = None,
|
|
31
|
+
quiet: bool | None = None,
|
|
32
|
+
verbose: bool | None = None,
|
|
33
|
+
stdin_display_name: str | None = None,
|
|
34
|
+
in_place: bool | None = None,
|
|
35
|
+
stdout: bool | None = None,
|
|
36
|
+
) -> None:
|
|
37
|
+
r"""Run `autoflake`.
|
|
38
|
+
|
|
39
|
+
Parameters:
|
|
40
|
+
*files: Files to format.
|
|
41
|
+
config: Explicitly set the config file instead of auto determining based on file location.
|
|
42
|
+
check: Return error code if changes are needed.
|
|
43
|
+
check_diff: Return error code if changes are needed, also display file diffs.
|
|
44
|
+
imports: By default, only unused standard library imports are removed; specify a comma-separated list of additional modules/packages.
|
|
45
|
+
remove_all_unused_imports: Remove all unused imports (not just those from the standard library).
|
|
46
|
+
recursive: Drill down directories recursively.
|
|
47
|
+
jobs: Number of parallel jobs; match CPU count if value is 0 (default: 0).
|
|
48
|
+
exclude: Exclude file/directory names that match these comma-separated globs.
|
|
49
|
+
expand_star_imports: Expand wildcard star imports with undefined names; this only triggers if there is only one star import in the file; this is skipped if there are any uses of `__all__` or `del` in the file.
|
|
50
|
+
ignore_init_module_imports: Exclude `__init__.py` when removing unused imports.
|
|
51
|
+
remove_duplicate_keys: Remove all duplicate keys in objects.
|
|
52
|
+
remove_unused_variables: Remove unused variables.
|
|
53
|
+
remove_rhs_for_unused_variables: Remove RHS of statements when removing unused variables (unsafe).
|
|
54
|
+
ignore_pass_statements: Ignore all pass statements.
|
|
55
|
+
ignore_pass_after_docstring: Ignore pass statements after a newline ending on `\"\"\"`.
|
|
56
|
+
quiet: Suppress output if there are no issues.
|
|
57
|
+
verbose: Print more verbose logs (you can repeat `-v` to make it more verbose).
|
|
58
|
+
stdin_display_name: The name used when processing input from stdin.
|
|
59
|
+
in_place: Make changes to files instead of printing diffs.
|
|
60
|
+
stdout: Print changed text to stdout. defaults to true when formatting stdin, or to false otherwise.
|
|
61
|
+
"""
|
|
62
|
+
cli_args = list(files)
|
|
63
|
+
|
|
64
|
+
if check:
|
|
65
|
+
cli_args.append("--check")
|
|
66
|
+
|
|
67
|
+
if check_diff:
|
|
68
|
+
cli_args.append("--check-diff")
|
|
69
|
+
|
|
70
|
+
if imports:
|
|
71
|
+
cli_args.append("--imports")
|
|
72
|
+
cli_args.append(",".join(imports))
|
|
73
|
+
|
|
74
|
+
if remove_all_unused_imports:
|
|
75
|
+
cli_args.append("--remove-all-unused-imports")
|
|
76
|
+
|
|
77
|
+
if recursive:
|
|
78
|
+
cli_args.append("--recursive")
|
|
79
|
+
|
|
80
|
+
if jobs:
|
|
81
|
+
cli_args.append("--jobs")
|
|
82
|
+
cli_args.append(str(jobs))
|
|
83
|
+
|
|
84
|
+
if exclude:
|
|
85
|
+
cli_args.append("--exclude")
|
|
86
|
+
cli_args.append(",".join(exclude))
|
|
87
|
+
|
|
88
|
+
if expand_star_imports:
|
|
89
|
+
cli_args.append("--expand-star-imports")
|
|
90
|
+
|
|
91
|
+
if ignore_init_module_imports:
|
|
92
|
+
cli_args.append("--ignore-init-module-imports")
|
|
93
|
+
|
|
94
|
+
if remove_duplicate_keys:
|
|
95
|
+
cli_args.append("--remove-duplicate-keys")
|
|
96
|
+
|
|
97
|
+
if remove_unused_variables:
|
|
98
|
+
cli_args.append("--remove-unused-variables")
|
|
99
|
+
|
|
100
|
+
if remove_rhs_for_unused_variables:
|
|
101
|
+
cli_args.append("remove-rhs-for-unused-variables")
|
|
102
|
+
|
|
103
|
+
if ignore_pass_statements:
|
|
104
|
+
cli_args.append("--ignore-pass-statements")
|
|
105
|
+
|
|
106
|
+
if ignore_pass_after_docstring:
|
|
107
|
+
cli_args.append("--ignore-pass-after-docstring")
|
|
108
|
+
|
|
109
|
+
if quiet:
|
|
110
|
+
cli_args.append("--quiet")
|
|
111
|
+
|
|
112
|
+
if verbose:
|
|
113
|
+
cli_args.append("--verbose")
|
|
114
|
+
|
|
115
|
+
if stdin_display_name:
|
|
116
|
+
cli_args.append("--stdin-display-name")
|
|
117
|
+
cli_args.append(stdin_display_name)
|
|
118
|
+
|
|
119
|
+
if config:
|
|
120
|
+
cli_args.append("--config")
|
|
121
|
+
cli_args.append(config)
|
|
122
|
+
|
|
123
|
+
if in_place:
|
|
124
|
+
cli_args.append("--in-place")
|
|
125
|
+
|
|
126
|
+
if stdout:
|
|
127
|
+
cli_args.append("--stdout")
|
|
128
|
+
|
|
129
|
+
super().__init__(cli_args)
|
|
130
|
+
|
|
131
|
+
def __call__(self) -> int:
|
|
132
|
+
from autoflake import _main as run_autoflake
|
|
133
|
+
|
|
134
|
+
return run_autoflake(
|
|
135
|
+
self.cli_args,
|
|
136
|
+
standard_out=LazyStdout(),
|
|
137
|
+
standard_error=LazyStderr(),
|
|
138
|
+
)
|
duty/tools/_base.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Utilities for creating tools."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import shlex
|
|
6
|
+
import sys
|
|
7
|
+
from io import StringIO
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
if sys.version_info >= (3, 11):
|
|
11
|
+
from typing import Self
|
|
12
|
+
else:
|
|
13
|
+
from typing_extensions import Self
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class LazyStdout(StringIO):
|
|
17
|
+
"""Lazy stdout buffer.
|
|
18
|
+
|
|
19
|
+
Can be used when tools' main entry-points
|
|
20
|
+
expect a file-like object for stdout.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def write(self, value: str) -> int:
|
|
24
|
+
return sys.stdout.write(value)
|
|
25
|
+
|
|
26
|
+
def __repr__(self) -> str:
|
|
27
|
+
return "stdout"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class LazyStderr(StringIO):
|
|
31
|
+
"""Lazy stderr buffer.
|
|
32
|
+
|
|
33
|
+
Can be used when tools' main entry-points
|
|
34
|
+
expect a file-like object for stderr.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def write(self, value: str) -> int:
|
|
38
|
+
return sys.stderr.write(value)
|
|
39
|
+
|
|
40
|
+
def __repr__(self) -> str:
|
|
41
|
+
return "stderr"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Tool:
|
|
45
|
+
"""Base class for tools."""
|
|
46
|
+
|
|
47
|
+
cli_name: str = ""
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
cli_args: list[str] | None = None,
|
|
52
|
+
py_args: dict[str, Any] | None = None,
|
|
53
|
+
) -> None:
|
|
54
|
+
self.cli_args: list[str] = cli_args or []
|
|
55
|
+
self.py_args: dict[str, Any] = py_args or {}
|
|
56
|
+
|
|
57
|
+
def add_args(self, *args: str) -> Self:
|
|
58
|
+
"""Add arguments."""
|
|
59
|
+
self.cli_args.extend(args)
|
|
60
|
+
return self
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def cli_command(self) -> str:
|
|
64
|
+
if not self.cli_name:
|
|
65
|
+
raise ValueError("This tool does not provide a CLI.")
|
|
66
|
+
return shlex.join([self.cli_name, *self.cli_args])
|