fast-dev-cli 0.21.0__tar.gz → 0.21.1__tar.gz
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.
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/PKG-INFO +7 -1
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/README.md +6 -0
- fast_dev_cli-0.21.1/fast_dev_cli/__init__.py +1 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/fast_dev_cli/cli.py +85 -28
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/pyproject.toml +1 -1
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_bump.py +20 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_upgrade.py +1 -1
- fast_dev_cli-0.21.0/fast_dev_cli/__init__.py +0 -1
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/LICENSE +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/fast_dev_cli/__main__.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/fast_dev_cli/py.typed +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/pdm_build.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/scripts/check.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/scripts/deps.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/scripts/format.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/scripts/test.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/__init__.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/assets/uv-tx.lock +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/assets/uv-upload-time.lock +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/assets/uv.lock +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/conftest.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_deps.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_exec.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_fast_test.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_functions.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_help.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_lint.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_poetry_version_plugin.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_pypi.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_runserver.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_sync.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_tag.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_upload.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/test_version.py +0 -0
- {fast_dev_cli-0.21.0 → fast_dev_cli-0.21.1}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fast-dev-cli
|
|
3
|
-
Version: 0.21.
|
|
3
|
+
Version: 0.21.1
|
|
4
4
|
Summary: Python project development tool.
|
|
5
5
|
Author-Email: Waket Zheng <waketzheng@gmail.com>>
|
|
6
6
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -51,6 +51,12 @@ Description-Content-Type: text/markdown
|
|
|
51
51
|
<a href="https://github.com/python/mypy" target="_blank">
|
|
52
52
|
<img src="https://img.shields.io/badge/mypy-100%25-brightgreen.svg" alt="Mypy Coverage">
|
|
53
53
|
</a>
|
|
54
|
+
<a href="https://github.com/microsoft/pyright" target="_blank">
|
|
55
|
+
<img src="https://img.shields.io/badge/pyright-checked-brightgreen.svg" alt="Pyright Checked">
|
|
56
|
+
</a>
|
|
57
|
+
<a href="https://github.com/astral-sh/ty" target="_blank">
|
|
58
|
+
<img src="https://img.shields.io/badge/ty-checked-brightgreen.svg" alt="ty Checked">
|
|
59
|
+
</a>
|
|
54
60
|
<a href="https://github.com/astral-sh/ruff" target="_blank">
|
|
55
61
|
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
56
62
|
</a>
|
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
<a href="https://github.com/python/mypy" target="_blank">
|
|
21
21
|
<img src="https://img.shields.io/badge/mypy-100%25-brightgreen.svg" alt="Mypy Coverage">
|
|
22
22
|
</a>
|
|
23
|
+
<a href="https://github.com/microsoft/pyright" target="_blank">
|
|
24
|
+
<img src="https://img.shields.io/badge/pyright-checked-brightgreen.svg" alt="Pyright Checked">
|
|
25
|
+
</a>
|
|
26
|
+
<a href="https://github.com/astral-sh/ty" target="_blank">
|
|
27
|
+
<img src="https://img.shields.io/badge/ty-checked-brightgreen.svg" alt="ty Checked">
|
|
28
|
+
</a>
|
|
23
29
|
<a href="https://github.com/astral-sh/ruff" target="_blank">
|
|
24
30
|
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
25
31
|
</a>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.21.1"
|
|
@@ -75,11 +75,10 @@ def poetry_module_name(name: str) -> str:
|
|
|
75
75
|
try:
|
|
76
76
|
from packaging.utils import canonicalize_name
|
|
77
77
|
except ImportError:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return canonicalize_name(name).replace("-", "_").replace(" ", "_")
|
|
78
|
+
module_name = re.sub(r"[-_.]+", "-", name)
|
|
79
|
+
else:
|
|
80
|
+
module_name = canonicalize_name(name)
|
|
81
|
+
return module_name.replace("-", "_").replace(" ", "_")
|
|
83
82
|
|
|
84
83
|
|
|
85
84
|
def is_emoji(char: str) -> bool:
|
|
@@ -272,6 +271,26 @@ def read_version_from_file(
|
|
|
272
271
|
return "0.0.0"
|
|
273
272
|
|
|
274
273
|
|
|
274
|
+
def _get_frontend_version() -> tuple[Path, str] | None:
|
|
275
|
+
try:
|
|
276
|
+
frontend_version_file = Project.get_work_dir("package.json", be_file=True)
|
|
277
|
+
except EnvError:
|
|
278
|
+
return None
|
|
279
|
+
try:
|
|
280
|
+
from asynctor.jsons import json_loads
|
|
281
|
+
except ImportError:
|
|
282
|
+
from json import loads as json_loads # type:ignore[assignment]
|
|
283
|
+
content = frontend_version_file.read_bytes()
|
|
284
|
+
metadata: dict[str, str] = json_loads(content) # type:ignore[assignment]
|
|
285
|
+
try:
|
|
286
|
+
current_version = metadata["version"]
|
|
287
|
+
except (KeyError, TypeError):
|
|
288
|
+
return None
|
|
289
|
+
with contextlib.suppress(ValueError):
|
|
290
|
+
frontend_version_file = frontend_version_file.relative_to(Path.cwd())
|
|
291
|
+
return frontend_version_file, current_version
|
|
292
|
+
|
|
293
|
+
|
|
275
294
|
@overload
|
|
276
295
|
def get_current_version(
|
|
277
296
|
verbose: bool = False,
|
|
@@ -288,7 +307,7 @@ def get_current_version(
|
|
|
288
307
|
is_poetry: bool | None = None,
|
|
289
308
|
package_name: str | None = None,
|
|
290
309
|
*,
|
|
291
|
-
check_version: Literal[True]
|
|
310
|
+
check_version: Literal[True],
|
|
292
311
|
) -> tuple[bool, str]: ...
|
|
293
312
|
|
|
294
313
|
|
|
@@ -310,11 +329,20 @@ def get_current_version(
|
|
|
310
329
|
return out
|
|
311
330
|
toml_text = work_dir = None
|
|
312
331
|
if package_name is None:
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
332
|
+
try:
|
|
333
|
+
work_dir = Project.get_work_dir()
|
|
334
|
+
except EnvError as e:
|
|
335
|
+
if (res := _get_frontend_version()) is None:
|
|
336
|
+
raise e
|
|
337
|
+
current_version = res[1]
|
|
338
|
+
if check_version:
|
|
339
|
+
return False, current_version
|
|
340
|
+
return current_version
|
|
341
|
+
else:
|
|
342
|
+
toml_text = Project.load_toml_text()
|
|
343
|
+
doc = tomllib.loads(toml_text)
|
|
344
|
+
project_name = doc.get("project", {}).get("name", work_dir.name)
|
|
345
|
+
package_name = re.sub(r"[- ]", "_", project_name)
|
|
318
346
|
local_version = read_version_from_file(package_name, work_dir, toml_text)
|
|
319
347
|
try:
|
|
320
348
|
installed_version = importlib_metadata.version(package_name)
|
|
@@ -330,15 +358,15 @@ def get_current_version(
|
|
|
330
358
|
|
|
331
359
|
|
|
332
360
|
def _ensure_bool(value: bool | OptionInfo) -> bool:
|
|
333
|
-
if
|
|
334
|
-
|
|
335
|
-
return value
|
|
361
|
+
if isinstance(value, bool):
|
|
362
|
+
return value
|
|
363
|
+
return bool(getattr(value, "default", False))
|
|
336
364
|
|
|
337
365
|
|
|
338
|
-
def _ensure_str(value: str | OptionInfo | None) -> str:
|
|
339
|
-
if
|
|
340
|
-
|
|
341
|
-
return value
|
|
366
|
+
def _ensure_str(value: str | OptionInfo | None) -> str | None:
|
|
367
|
+
if isinstance(value, str) or value is None:
|
|
368
|
+
return value
|
|
369
|
+
return getattr(value, "default", "")
|
|
342
370
|
|
|
343
371
|
|
|
344
372
|
class DryRun:
|
|
@@ -371,7 +399,13 @@ class BumpUp(DryRun):
|
|
|
371
399
|
self.commit = commit
|
|
372
400
|
self.part = part
|
|
373
401
|
if filename is None:
|
|
374
|
-
|
|
402
|
+
try:
|
|
403
|
+
filename = self.parse_filename()
|
|
404
|
+
except EnvError:
|
|
405
|
+
if (res := _get_frontend_version()) is not None:
|
|
406
|
+
filename = res[0].name
|
|
407
|
+
else:
|
|
408
|
+
raise
|
|
375
409
|
self.filename = filename
|
|
376
410
|
self._no_sync = no_sync
|
|
377
411
|
self._emoji = emoji
|
|
@@ -467,7 +501,7 @@ class BumpUp(DryRun):
|
|
|
467
501
|
try:
|
|
468
502
|
project_name = context["project"]["name"]
|
|
469
503
|
except KeyError:
|
|
470
|
-
packages = []
|
|
504
|
+
packages: list[tuple[str, str]] = []
|
|
471
505
|
else:
|
|
472
506
|
packages = [(poetry_module_name(project_name), "")]
|
|
473
507
|
else:
|
|
@@ -549,12 +583,23 @@ class BumpUp(DryRun):
|
|
|
549
583
|
echo("You may want to pin tag by `fast tag`")
|
|
550
584
|
|
|
551
585
|
|
|
586
|
+
def _echo_version(version_file: Any, value: str) -> None:
|
|
587
|
+
styled = typer.style(value, bold=True)
|
|
588
|
+
echo(f"Version value in {version_file}: " + styled)
|
|
589
|
+
|
|
590
|
+
|
|
552
591
|
@cli.command()
|
|
553
592
|
def version() -> None:
|
|
554
593
|
"""Show the version of this tool"""
|
|
555
594
|
echo("Fast Dev Cli Version: " + typer.style(__version__, fg=typer.colors.BLUE))
|
|
556
595
|
with contextlib.suppress(FileNotFoundError, KeyError):
|
|
557
|
-
|
|
596
|
+
try:
|
|
597
|
+
toml_text = Project.load_toml_text()
|
|
598
|
+
except EnvError:
|
|
599
|
+
if (res := _get_frontend_version()) is not None:
|
|
600
|
+
_echo_version(*res)
|
|
601
|
+
return
|
|
602
|
+
raise
|
|
558
603
|
doc = tomllib.loads(toml_text)
|
|
559
604
|
if value := doc.get("project", {}).get("version", ""):
|
|
560
605
|
styled = typer.style(value, bold=True, fg=typer.colors.CYAN)
|
|
@@ -569,8 +614,7 @@ def version() -> None:
|
|
|
569
614
|
for line in text.splitlines():
|
|
570
615
|
if line.strip().startswith(varname):
|
|
571
616
|
value = line.split("=", 1)[-1].strip().strip('"').strip("'")
|
|
572
|
-
|
|
573
|
-
echo(f"Version value in {version_file}: " + styled)
|
|
617
|
+
_echo_version(version_file, value)
|
|
574
618
|
break
|
|
575
619
|
|
|
576
620
|
|
|
@@ -985,7 +1029,7 @@ def upgrade(
|
|
|
985
1029
|
dry: bool = DryOption,
|
|
986
1030
|
) -> None:
|
|
987
1031
|
"""Upgrade dependencies in pyproject.toml to latest versions"""
|
|
988
|
-
if not (tool := _ensure_str(tool)) or tool == ToolOption.default:
|
|
1032
|
+
if not (tool := _ensure_str(tool) or "") or tool == ToolOption.default:
|
|
989
1033
|
tool = Project.get_manage_tool() or "uv"
|
|
990
1034
|
if tool in get_args(ToolName):
|
|
991
1035
|
UpgradeDependencies(dry=dry, tool=cast(ToolName, tool)).run()
|
|
@@ -1065,6 +1109,7 @@ class LintCode(DryRun):
|
|
|
1065
1109
|
sim: bool = True,
|
|
1066
1110
|
strict: bool = False,
|
|
1067
1111
|
ty: bool = False,
|
|
1112
|
+
fix: bool = True,
|
|
1068
1113
|
) -> None:
|
|
1069
1114
|
self.args = args
|
|
1070
1115
|
self.check_only = check_only
|
|
@@ -1077,6 +1122,7 @@ class LintCode(DryRun):
|
|
|
1077
1122
|
self._sim = sim
|
|
1078
1123
|
self._strict = strict
|
|
1079
1124
|
self._ty = _ensure_bool(ty)
|
|
1125
|
+
self._fix = _ensure_bool(fix)
|
|
1080
1126
|
super().__init__(_exit, dry)
|
|
1081
1127
|
|
|
1082
1128
|
@staticmethod
|
|
@@ -1123,11 +1169,13 @@ class LintCode(DryRun):
|
|
|
1123
1169
|
ruff_check_sim: bool = True,
|
|
1124
1170
|
mypy_strict: bool = False,
|
|
1125
1171
|
prefer_ty: bool = False,
|
|
1172
|
+
ruff_check_fix: bool = True,
|
|
1126
1173
|
) -> str:
|
|
1127
1174
|
if paths != "." and all(i.endswith(".html") for i in paths.split()):
|
|
1128
1175
|
return f"prettier -w {paths}"
|
|
1129
1176
|
cmd = ""
|
|
1130
|
-
|
|
1177
|
+
ruff_check = "ruff check --extend-select=I,B,SIM" + " --fix" * ruff_check_fix
|
|
1178
|
+
tools = ["ruff format", ruff_check, "mypy"]
|
|
1131
1179
|
if check_only:
|
|
1132
1180
|
tools[0] += " --check"
|
|
1133
1181
|
if check_only or load_bool("NO_FIX"):
|
|
@@ -1256,6 +1304,7 @@ class LintCode(DryRun):
|
|
|
1256
1304
|
ruff_check_sim=self._sim,
|
|
1257
1305
|
mypy_strict=self._strict,
|
|
1258
1306
|
prefer_ty=self._ty,
|
|
1307
|
+
ruff_check_fix=self._fix,
|
|
1259
1308
|
)
|
|
1260
1309
|
|
|
1261
1310
|
|
|
@@ -1275,6 +1324,7 @@ def lint(
|
|
|
1275
1324
|
sim: bool = True,
|
|
1276
1325
|
strict: bool = False,
|
|
1277
1326
|
ty: bool = False,
|
|
1327
|
+
fix: bool = True,
|
|
1278
1328
|
) -> None:
|
|
1279
1329
|
if files is None:
|
|
1280
1330
|
files = parse_files(sys.argv[1:])
|
|
@@ -1292,6 +1342,7 @@ def lint(
|
|
|
1292
1342
|
sim=sim,
|
|
1293
1343
|
strict=strict,
|
|
1294
1344
|
ty=ty,
|
|
1345
|
+
fix=fix,
|
|
1295
1346
|
).run()
|
|
1296
1347
|
|
|
1297
1348
|
|
|
@@ -1343,6 +1394,7 @@ def make_style(
|
|
|
1343
1394
|
sim: bool = Option(True, help="Whether ruff check with --extend-select=SIM"),
|
|
1344
1395
|
strict: bool = Option(False, help="Whether run mypy with --strict"),
|
|
1345
1396
|
ty: bool = Option(False, help="Whether use ty instead of mypy"),
|
|
1397
|
+
fix: bool | None = Option(None, help="Whether ruff check with --fix"),
|
|
1346
1398
|
) -> None:
|
|
1347
1399
|
"""Run: ruff check/format to reformat code and then mypy to check"""
|
|
1348
1400
|
if getattr(files, "default", files) is None:
|
|
@@ -1352,13 +1404,18 @@ def make_style(
|
|
|
1352
1404
|
skip = _ensure_bool(skip_mypy)
|
|
1353
1405
|
dmypy = _ensure_bool(use_dmypy)
|
|
1354
1406
|
bandit = _ensure_bool(bandit)
|
|
1355
|
-
|
|
1356
|
-
tool = _ensure_str(tool)
|
|
1407
|
+
tool = _ensure_str(tool) or ""
|
|
1357
1408
|
up = _ensure_bool(up)
|
|
1358
1409
|
sim = _ensure_bool(sim)
|
|
1359
1410
|
strict = _ensure_bool(strict)
|
|
1360
1411
|
kwargs = {"dry": dry, "skip_mypy": skip, "dmypy": dmypy, "bandit": bandit}
|
|
1361
|
-
|
|
1412
|
+
if _ensure_bool(check_only):
|
|
1413
|
+
run = check
|
|
1414
|
+
else:
|
|
1415
|
+
prefix = _ensure_bool(prefix)
|
|
1416
|
+
if fix is None or not isinstance(fix, bool):
|
|
1417
|
+
fix = load_bool("FASTDEVCLI_FIX", True)
|
|
1418
|
+
run = functools.partial(lint, prefix=prefix, fix=fix)
|
|
1362
1419
|
run(files, tool=tool, up=up, sim=sim, strict=strict, ty=ty, **kwargs)
|
|
1363
1420
|
|
|
1364
1421
|
|
|
@@ -402,3 +402,23 @@ build-backend = "pdm.backend"
|
|
|
402
402
|
out = capture_cmd_output("fast bump patch")
|
|
403
403
|
assert version_file.as_posix() in out
|
|
404
404
|
assert "0.3.1" in version_file.read_text()
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def test_package_dot_json(tmp_work_dir):
|
|
408
|
+
p = Path("package.json")
|
|
409
|
+
p.write_text('{"version":"0.1.0"}', encoding="utf-8")
|
|
410
|
+
out = capture_cmd_output("fast bump patch")
|
|
411
|
+
assert p.name in out
|
|
412
|
+
assert "0.1.1" in p.read_text()
|
|
413
|
+
out = capture_cmd_output("fast bump patch --commit --dry")
|
|
414
|
+
assert (
|
|
415
|
+
'bumpversion --parse "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)" --current-version="0.1.1" patch package.json --commit'
|
|
416
|
+
in out
|
|
417
|
+
)
|
|
418
|
+
run_and_echo("git init")
|
|
419
|
+
run_and_echo("git add .")
|
|
420
|
+
run_and_echo("git config user.name xxx")
|
|
421
|
+
run_and_echo("git config user.email xxx@a.com")
|
|
422
|
+
run_and_echo('git commit -m "xxx"')
|
|
423
|
+
out = capture_cmd_output("fast tag --dry")
|
|
424
|
+
assert "git tag -a 0.1.1 -m '' && git push --tags" in out
|
|
@@ -58,7 +58,7 @@ anyio = {version = ">=3.7.1", optional = true}
|
|
|
58
58
|
typer = {extras = ["all"], version = "^0.9.0", optional = true}
|
|
59
59
|
uvicorn = {version = "^0.23.2", platform = "linux", optional = true}
|
|
60
60
|
"""
|
|
61
|
-
lines = [str(i) for i in segment.splitlines()]
|
|
61
|
+
lines: list[str] = [str(i) for i in segment.splitlines()]
|
|
62
62
|
assert UpgradeDependencies.build_args(lines) == (
|
|
63
63
|
[
|
|
64
64
|
'"ipython@latest"',
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.21.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|