fast-dev-cli 0.11.0__tar.gz → 0.11.2__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.11.0 → fast_dev_cli-0.11.2}/PKG-INFO +20 -12
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/README.md +18 -10
- fast_dev_cli-0.11.2/fast_dev_cli/__init__.py +1 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/fast_dev_cli/cli.py +64 -36
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/pyproject.toml +2 -2
- fast_dev_cli-0.11.2/scripts/check.py +29 -0
- fast_dev_cli-0.11.2/scripts/format.py +13 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_bump.py +1 -1
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_lint.py +31 -1
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_poetry_version_plugin.py +1 -1
- fast_dev_cli-0.11.2/tests/test_upload.py +43 -0
- fast_dev_cli-0.11.0/fast_dev_cli/__init__.py +0 -1
- fast_dev_cli-0.11.0/scripts/check.py +0 -20
- fast_dev_cli-0.11.0/scripts/format.py +0 -15
- fast_dev_cli-0.11.0/tests/test_upload.py +0 -7
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/LICENSE +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/fast_dev_cli/__main__.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/fast_dev_cli/py.typed +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/pdm_build.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/scripts/test.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/__init__.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/conftest.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_fast_test.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_functions.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_runserver.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_sync.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_tag.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_upgrade.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/test_version.py +0 -0
- {fast_dev_cli-0.11.0 → fast_dev_cli-0.11.2}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fast-dev-cli
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.2
|
|
4
4
|
Summary: Python project development tool.
|
|
5
5
|
Author-Email: Waket Zheng <waketzheng@gmail.com>>
|
|
6
6
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -26,7 +26,7 @@ Requires-Dist: tomli<3,>=2.0.1; python_version < "3.11"
|
|
|
26
26
|
Requires-Dist: coverage<8,>=7.5.1
|
|
27
27
|
Requires-Dist: ruff<0.8,>=0.4.4
|
|
28
28
|
Requires-Dist: mypy<2,>=1.10.0
|
|
29
|
-
Requires-Dist: bumpversion2<2,>=1.4.
|
|
29
|
+
Requires-Dist: bumpversion2<2,>=1.4.3
|
|
30
30
|
Requires-Dist: pytest<9,>=8.2.0
|
|
31
31
|
Provides-Extra: all
|
|
32
32
|
Requires-Dist: ipython<9,>=8.24.0; extra == "all"
|
|
@@ -41,10 +41,10 @@ Description-Content-Type: text/markdown
|
|
|
41
41
|
</p>
|
|
42
42
|
<p align="center">
|
|
43
43
|
<a href="https://pypi.org/project/fast-dev-cli" target="_blank">
|
|
44
|
-
<img src="https://img.shields.io/pypi/
|
|
44
|
+
<img src="https://img.shields.io/pypi/pyversions/fast-dev-cli.svg" alt="Supported Python versions">
|
|
45
45
|
</a>
|
|
46
46
|
<a href="https://pypi.org/project/fast-dev-cli" target="_blank">
|
|
47
|
-
<img src="https://img.shields.io/pypi/
|
|
47
|
+
<img src="https://img.shields.io/pypi/v/fast-dev-cli?color=%2334D058&label=pypi%20package" alt="Package version">
|
|
48
48
|
</a>
|
|
49
49
|
<a href="https://github.com/waketzheng/fast-dev-cli/actions?query=workflow:ci" target="_blank">
|
|
50
50
|
<img src="https://github.com/waketzheng/fast-dev-cli/workflows/ci/badge.svg" alt="GithubActionResult">
|
|
@@ -52,14 +52,14 @@ Description-Content-Type: text/markdown
|
|
|
52
52
|
<a href="https://coveralls.io/github/waketzheng/fast-dev-cli?branch=main" target="_blank">
|
|
53
53
|
<img src="https://coveralls.io/repos/github/waketzheng/fast-dev-cli/badge.svg?branch=main" alt="Coverage Status">
|
|
54
54
|
</a>
|
|
55
|
-
<a href="https://github.com/astral-sh/ruff" target="_blank">
|
|
56
|
-
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
57
|
-
</a>
|
|
58
55
|
<a href="https://github.com/python/mypy" target="_blank">
|
|
59
|
-
<img src="https://img.shields.io/badge/mypy-100%25-
|
|
56
|
+
<img src="https://img.shields.io/badge/mypy-100%25-brightgreen.svg" alt="Mypy Coverage">
|
|
60
57
|
</a>
|
|
61
58
|
<a href="https://github.com/PyCQA/bandit" target="_blank">
|
|
62
|
-
<img src="https://img.shields.io/badge/security-bandit-
|
|
59
|
+
<img src="https://img.shields.io/badge/security-bandit-orange.svg" alt="security: bandit">
|
|
60
|
+
</a>
|
|
61
|
+
<a href="https://github.com/astral-sh/ruff" target="_blank">
|
|
62
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
63
63
|
</a>
|
|
64
64
|
</p>
|
|
65
65
|
|
|
@@ -88,7 +88,7 @@ pip install fast-dev-cli
|
|
|
88
88
|
|
|
89
89
|
- Lint py code:
|
|
90
90
|
```bash
|
|
91
|
-
fast lint /path/to/file-or-directory
|
|
91
|
+
fast lint [/path/to/file-or-directory]
|
|
92
92
|
```
|
|
93
93
|
- Check only
|
|
94
94
|
```bash
|
|
@@ -96,7 +96,10 @@ fast check
|
|
|
96
96
|
```
|
|
97
97
|
- Bump up version in pyproject.toml
|
|
98
98
|
```bash
|
|
99
|
-
fast bump
|
|
99
|
+
fast bump patch # 0.1.0 -> 0.1.1
|
|
100
|
+
fast bump minor # 0.1.0 -> 0.2.0
|
|
101
|
+
fast bump major # 0.1.0 -> 1.0.0
|
|
102
|
+
fast bump <part> --commit # bump version and run `git commit`
|
|
100
103
|
```
|
|
101
104
|
- Run unittest and report coverage
|
|
102
105
|
```bash
|
|
@@ -106,7 +109,7 @@ fast test
|
|
|
106
109
|
```bash
|
|
107
110
|
fast sync
|
|
108
111
|
```
|
|
109
|
-
- Upgrade main/dev dependencies to latest version
|
|
112
|
+
- Upgrade main/dev dependencies to latest version (only for poetry project)
|
|
110
113
|
```bash
|
|
111
114
|
fast upgrade
|
|
112
115
|
```
|
|
@@ -114,3 +117,8 @@ fast upgrade
|
|
|
114
117
|
```bash
|
|
115
118
|
fast dev
|
|
116
119
|
```
|
|
120
|
+
- Publish to pypi
|
|
121
|
+
```bash
|
|
122
|
+
fast upload
|
|
123
|
+
```
|
|
124
|
+
*Note: all command support the `--dry` option*
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
</p>
|
|
7
7
|
<p align="center">
|
|
8
8
|
<a href="https://pypi.org/project/fast-dev-cli" target="_blank">
|
|
9
|
-
<img src="https://img.shields.io/pypi/
|
|
9
|
+
<img src="https://img.shields.io/pypi/pyversions/fast-dev-cli.svg" alt="Supported Python versions">
|
|
10
10
|
</a>
|
|
11
11
|
<a href="https://pypi.org/project/fast-dev-cli" target="_blank">
|
|
12
|
-
<img src="https://img.shields.io/pypi/
|
|
12
|
+
<img src="https://img.shields.io/pypi/v/fast-dev-cli?color=%2334D058&label=pypi%20package" alt="Package version">
|
|
13
13
|
</a>
|
|
14
14
|
<a href="https://github.com/waketzheng/fast-dev-cli/actions?query=workflow:ci" target="_blank">
|
|
15
15
|
<img src="https://github.com/waketzheng/fast-dev-cli/workflows/ci/badge.svg" alt="GithubActionResult">
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
<a href="https://coveralls.io/github/waketzheng/fast-dev-cli?branch=main" target="_blank">
|
|
18
18
|
<img src="https://coveralls.io/repos/github/waketzheng/fast-dev-cli/badge.svg?branch=main" alt="Coverage Status">
|
|
19
19
|
</a>
|
|
20
|
-
<a href="https://github.com/astral-sh/ruff" target="_blank">
|
|
21
|
-
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
22
|
-
</a>
|
|
23
20
|
<a href="https://github.com/python/mypy" target="_blank">
|
|
24
|
-
<img src="https://img.shields.io/badge/mypy-100%25-
|
|
21
|
+
<img src="https://img.shields.io/badge/mypy-100%25-brightgreen.svg" alt="Mypy Coverage">
|
|
25
22
|
</a>
|
|
26
23
|
<a href="https://github.com/PyCQA/bandit" target="_blank">
|
|
27
|
-
<img src="https://img.shields.io/badge/security-bandit-
|
|
24
|
+
<img src="https://img.shields.io/badge/security-bandit-orange.svg" alt="security: bandit">
|
|
25
|
+
</a>
|
|
26
|
+
<a href="https://github.com/astral-sh/ruff" target="_blank">
|
|
27
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
28
28
|
</a>
|
|
29
29
|
</p>
|
|
30
30
|
|
|
@@ -53,7 +53,7 @@ pip install fast-dev-cli
|
|
|
53
53
|
|
|
54
54
|
- Lint py code:
|
|
55
55
|
```bash
|
|
56
|
-
fast lint /path/to/file-or-directory
|
|
56
|
+
fast lint [/path/to/file-or-directory]
|
|
57
57
|
```
|
|
58
58
|
- Check only
|
|
59
59
|
```bash
|
|
@@ -61,7 +61,10 @@ fast check
|
|
|
61
61
|
```
|
|
62
62
|
- Bump up version in pyproject.toml
|
|
63
63
|
```bash
|
|
64
|
-
fast bump
|
|
64
|
+
fast bump patch # 0.1.0 -> 0.1.1
|
|
65
|
+
fast bump minor # 0.1.0 -> 0.2.0
|
|
66
|
+
fast bump major # 0.1.0 -> 1.0.0
|
|
67
|
+
fast bump <part> --commit # bump version and run `git commit`
|
|
65
68
|
```
|
|
66
69
|
- Run unittest and report coverage
|
|
67
70
|
```bash
|
|
@@ -71,7 +74,7 @@ fast test
|
|
|
71
74
|
```bash
|
|
72
75
|
fast sync
|
|
73
76
|
```
|
|
74
|
-
- Upgrade main/dev dependencies to latest version
|
|
77
|
+
- Upgrade main/dev dependencies to latest version (only for poetry project)
|
|
75
78
|
```bash
|
|
76
79
|
fast upgrade
|
|
77
80
|
```
|
|
@@ -79,3 +82,8 @@ fast upgrade
|
|
|
79
82
|
```bash
|
|
80
83
|
fast dev
|
|
81
84
|
```
|
|
85
|
+
- Publish to pypi
|
|
86
|
+
```bash
|
|
87
|
+
fast upload
|
|
88
|
+
```
|
|
89
|
+
*Note: all command support the `--dry` option*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.11.2"
|
|
@@ -8,7 +8,7 @@ import subprocess # nosec:B404
|
|
|
8
8
|
import sys
|
|
9
9
|
from functools import cached_property
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Literal, Optional, Type, TypeAlias
|
|
11
|
+
from typing import Literal, Optional, Type, TypeAlias, get_args
|
|
12
12
|
|
|
13
13
|
import emoji
|
|
14
14
|
import typer
|
|
@@ -107,12 +107,13 @@ def read_version_from_file(
|
|
|
107
107
|
if work_dir is None:
|
|
108
108
|
work_dir = Project.get_work_dir()
|
|
109
109
|
package_dir = work_dir / package_name
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
init_file
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
if (
|
|
111
|
+
not (init_file := package_dir / "__init__.py").exists()
|
|
112
|
+
and not (init_file := work_dir / "src" / package_name / init_file.name).exists()
|
|
113
|
+
and not (init_file := work_dir / "app" / init_file.name).exists()
|
|
114
|
+
):
|
|
115
|
+
secho("WARNING: __init__.py file does not exist!")
|
|
116
|
+
return "0.0.0"
|
|
116
117
|
pattern = re.compile(r"__version__\s*=")
|
|
117
118
|
for line in init_file.read_text().splitlines():
|
|
118
119
|
if pattern.match(line):
|
|
@@ -230,7 +231,7 @@ class BumpUp(DryRun):
|
|
|
230
231
|
packages = []
|
|
231
232
|
else:
|
|
232
233
|
packages = [j for i in package_item if (j := i.get("include"))]
|
|
233
|
-
# In case of managed by `poetry-version
|
|
234
|
+
# In case of managed by `poetry-plugin-version`
|
|
234
235
|
cwd = Path.cwd()
|
|
235
236
|
pattern = re.compile(r"__version__\s*=\s*['\"]")
|
|
236
237
|
ds = [cwd / i for i in packages] + [cwd / cwd.name.replace("-", "_"), cwd]
|
|
@@ -369,7 +370,7 @@ class Project:
|
|
|
369
370
|
pass
|
|
370
371
|
else:
|
|
371
372
|
name: ToolName
|
|
372
|
-
for name in (
|
|
373
|
+
for name in get_args(ToolName):
|
|
373
374
|
if f"[tool.{name}]" in text:
|
|
374
375
|
return name
|
|
375
376
|
return ""
|
|
@@ -614,11 +615,18 @@ def tag(
|
|
|
614
615
|
|
|
615
616
|
class LintCode(DryRun):
|
|
616
617
|
def __init__(
|
|
617
|
-
self: Self,
|
|
618
|
+
self: Self,
|
|
619
|
+
args,
|
|
620
|
+
check_only=False,
|
|
621
|
+
_exit=False,
|
|
622
|
+
dry=False,
|
|
623
|
+
bandit=False,
|
|
624
|
+
skip_mypy=False,
|
|
618
625
|
) -> None:
|
|
619
626
|
self.args = args
|
|
620
627
|
self.check_only = check_only
|
|
621
628
|
self._bandit = bandit
|
|
629
|
+
self._skip_mypy = skip_mypy
|
|
622
630
|
super().__init__(_exit, dry)
|
|
623
631
|
|
|
624
632
|
@staticmethod
|
|
@@ -643,14 +651,16 @@ class LintCode(DryRun):
|
|
|
643
651
|
return "."
|
|
644
652
|
|
|
645
653
|
@classmethod
|
|
646
|
-
def to_cmd(
|
|
654
|
+
def to_cmd(
|
|
655
|
+
cls: Type[Self], paths=".", check_only=False, bandit=False, skip_mypy=False
|
|
656
|
+
) -> str:
|
|
647
657
|
cmd = ""
|
|
648
658
|
tools = ["ruff format", "ruff check --extend-select=I,B,SIM --fix", "mypy"]
|
|
649
659
|
if check_only:
|
|
650
660
|
tools[0] += " --check"
|
|
651
661
|
if check_only or load_bool("NO_FIX"):
|
|
652
662
|
tools[1] = tools[1].replace(" --fix", "")
|
|
653
|
-
if load_bool("SKIP_MYPY"):
|
|
663
|
+
if skip_mypy or load_bool("SKIP_MYPY"):
|
|
654
664
|
# Sometimes mypy is too slow
|
|
655
665
|
tools = tools[:-1]
|
|
656
666
|
elif load_bool("IGNORE_MISSING_IMPORTS"):
|
|
@@ -681,29 +691,32 @@ class LintCode(DryRun):
|
|
|
681
691
|
|
|
682
692
|
def gen(self: Self) -> str:
|
|
683
693
|
paths = " ".join(map(str, self.args)) if self.args else "."
|
|
684
|
-
return self.to_cmd(paths, self.check_only, self._bandit)
|
|
694
|
+
return self.to_cmd(paths, self.check_only, self._bandit, self._skip_mypy)
|
|
685
695
|
|
|
686
696
|
|
|
687
697
|
def parse_files(args: list[str] | tuple[str, ...]) -> list[str]:
|
|
688
698
|
return [i for i in args if not i.startswith("-")]
|
|
689
699
|
|
|
690
700
|
|
|
691
|
-
def lint(files=None, dry=False) -> None:
|
|
701
|
+
def lint(files=None, dry=False, skip_mypy=False) -> None:
|
|
692
702
|
if files is None:
|
|
693
703
|
files = parse_files(sys.argv[1:])
|
|
694
704
|
if files and files[0] == "lint":
|
|
695
705
|
files = files[1:]
|
|
696
|
-
LintCode(files, dry=dry).run()
|
|
706
|
+
LintCode(files, dry=dry, skip_mypy=skip_mypy).run()
|
|
697
707
|
|
|
698
708
|
|
|
699
|
-
def check(files=None, dry=False, bandit=False) -> None:
|
|
700
|
-
LintCode(
|
|
709
|
+
def check(files=None, dry=False, bandit=False, skip_mypy=False) -> None:
|
|
710
|
+
LintCode(
|
|
711
|
+
files, check_only=True, _exit=True, dry=dry, bandit=bandit, skip_mypy=skip_mypy
|
|
712
|
+
).run()
|
|
701
713
|
|
|
702
714
|
|
|
703
715
|
@cli.command(name="lint")
|
|
704
716
|
def make_style(
|
|
705
717
|
files: Annotated[Optional[list[Path]], typer.Argument()] = None,
|
|
706
718
|
check_only: bool = Option(False, "--check-only", "-c"),
|
|
719
|
+
skip_mypy: bool = Option(False, "--skip-mypy"),
|
|
707
720
|
dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
|
|
708
721
|
) -> None:
|
|
709
722
|
"""Run: ruff check/format to reformat code and then mypy to check"""
|
|
@@ -711,19 +724,21 @@ def make_style(
|
|
|
711
724
|
files = [Path(".")]
|
|
712
725
|
elif isinstance(files, str):
|
|
713
726
|
files = [files]
|
|
727
|
+
skip = _ensure_bool(skip_mypy)
|
|
714
728
|
if _ensure_bool(check_only):
|
|
715
|
-
check(files, dry=dry)
|
|
729
|
+
check(files, dry=dry, skip_mypy=skip)
|
|
716
730
|
else:
|
|
717
|
-
lint(files, dry=dry)
|
|
731
|
+
lint(files, dry=dry, skip_mypy=skip)
|
|
718
732
|
|
|
719
733
|
|
|
720
734
|
@cli.command(name="check")
|
|
721
735
|
def only_check(
|
|
722
736
|
bandit: bool = Option(False, "--bandit", help="Run `bandit -r <package_dir>`"),
|
|
737
|
+
skip_mypy: bool = Option(False, "--skip-mypy"),
|
|
723
738
|
dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
|
|
724
739
|
) -> None:
|
|
725
740
|
"""Check code style without reformat"""
|
|
726
|
-
check(dry=dry, bandit=bandit)
|
|
741
|
+
check(dry=dry, bandit=bandit, skip_mypy=_ensure_bool(skip_mypy))
|
|
727
742
|
|
|
728
743
|
|
|
729
744
|
class Sync(DryRun):
|
|
@@ -742,21 +757,20 @@ class Sync(DryRun):
|
|
|
742
757
|
return f"python -m pip install -r {self.filename}"
|
|
743
758
|
prefix = "" if is_venv() else f"{tool} run "
|
|
744
759
|
ensurepip = " {1}python -m ensurepip && {1}python -m pip install -U pip &&"
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
ensurepip = ""
|
|
760
|
+
if tool == "uv":
|
|
761
|
+
export_cmd = "uv export --no-hashes --all-extras --frozen"
|
|
762
|
+
if check_call(prefix + "python -m pip --version"):
|
|
763
|
+
ensurepip = ""
|
|
764
|
+
elif tool in ("poetry", "pdm"):
|
|
765
|
+
export_cmd = f"{tool} export --without-hashes --with=dev"
|
|
766
|
+
if tool == "poetry":
|
|
767
|
+
ensurepip = ""
|
|
768
|
+
if not UpgradeDependencies.should_with_dev():
|
|
769
|
+
export_cmd = export_cmd.replace(" --with=dev", "")
|
|
770
|
+
if extras and isinstance(extras, str | list):
|
|
771
|
+
export_cmd += f" --{extras=}".replace("'", '"')
|
|
772
|
+
elif check_call(prefix + "python -m pip --version"):
|
|
773
|
+
ensurepip = ""
|
|
760
774
|
install_cmd = "{2} -o {0} &&%s {1}python -m pip install -r {0}" % ensurepip
|
|
761
775
|
if should_remove and not save:
|
|
762
776
|
install_cmd += " && rm -f {0}"
|
|
@@ -811,12 +825,26 @@ def coverage_test(
|
|
|
811
825
|
return test(dry, ignore_script)
|
|
812
826
|
|
|
813
827
|
|
|
828
|
+
class Publish:
|
|
829
|
+
class CommandEnum(StrEnum):
|
|
830
|
+
poetry = "poetry publish --build"
|
|
831
|
+
pdm = "pdm publish"
|
|
832
|
+
uv = "uv build && uv publish"
|
|
833
|
+
twine = "python -m build && twine upload"
|
|
834
|
+
|
|
835
|
+
@classmethod
|
|
836
|
+
def gen(cls) -> str:
|
|
837
|
+
if (tool := Project.get_manage_tool()) and tool in get_args(ToolName):
|
|
838
|
+
return cls.CommandEnum[tool]
|
|
839
|
+
return cls.CommandEnum.twine
|
|
840
|
+
|
|
841
|
+
|
|
814
842
|
@cli.command()
|
|
815
843
|
def upload(
|
|
816
844
|
dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
|
|
817
845
|
) -> None:
|
|
818
846
|
"""Shortcut for package publish"""
|
|
819
|
-
cmd =
|
|
847
|
+
cmd = Publish.gen()
|
|
820
848
|
exit_if_run_failed(cmd, dry=dry)
|
|
821
849
|
|
|
822
850
|
|
|
@@ -37,10 +37,10 @@ dependencies = [
|
|
|
37
37
|
"coverage >=7.5.1,<8",
|
|
38
38
|
"ruff >=0.4.4,<0.8",
|
|
39
39
|
"mypy >=1.10.0,<2",
|
|
40
|
-
"bumpversion2 >=1.4.
|
|
40
|
+
"bumpversion2 >=1.4.3,<2",
|
|
41
41
|
"pytest >=8.2.0,<9",
|
|
42
42
|
]
|
|
43
|
-
version = "0.11.
|
|
43
|
+
version = "0.11.2"
|
|
44
44
|
|
|
45
45
|
[project.urls]
|
|
46
46
|
Homepage = "https://github.com/waketzheng/fast-dev-cli"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
TOOL = ("pdm", "poetry", "uv")[0]
|
|
7
|
+
parent = os.path.abspath(os.path.dirname(__file__))
|
|
8
|
+
work_dir = os.path.dirname(parent)
|
|
9
|
+
if os.getcwd() != work_dir:
|
|
10
|
+
os.chdir(work_dir)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def run_and_echo(cmd, tool=TOOL, verbose=True):
|
|
14
|
+
# type: (str, str, bool) -> int
|
|
15
|
+
if tool:
|
|
16
|
+
cmd = tool + " run " + cmd
|
|
17
|
+
if verbose:
|
|
18
|
+
print("--> " + cmd)
|
|
19
|
+
return os.system(cmd)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if run_and_echo("fast check", verbose=False) != 0:
|
|
23
|
+
print("\033[1m Please run './scripts/format.py' to auto-fix style issues \033[0m")
|
|
24
|
+
sys.exit(1)
|
|
25
|
+
|
|
26
|
+
package_name = os.path.basename(work_dir).replace("-", "_").replace(" ", "_")
|
|
27
|
+
if run_and_echo("bandit -r {}".format(package_name)) != 0:
|
|
28
|
+
sys.exit(1)
|
|
29
|
+
print("Done. ✨ 🍰 ✨")
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
parent = os.path.abspath(os.path.dirname(__file__))
|
|
7
|
+
work_dir = os.path.dirname(parent)
|
|
8
|
+
if os.getcwd() != work_dir:
|
|
9
|
+
os.chdir(work_dir)
|
|
10
|
+
|
|
11
|
+
cmd = "pdm run fast lint --skip-mypy"
|
|
12
|
+
if os.system(cmd) != 0:
|
|
13
|
+
sys.exit(1)
|
|
@@ -166,5 +166,5 @@ def test_bump_with_emoji(mocker, tmp_path, monkeypatch):
|
|
|
166
166
|
subprocess.run(["poetry", "run", "pip", "install", "bumpversion2"])
|
|
167
167
|
subprocess.run(["fast", "bump", "patch", "--commit"])
|
|
168
168
|
out = capture_cmd_output(["git", "log"])
|
|
169
|
-
new_commit = "⬆️
|
|
169
|
+
new_commit = "⬆️ Bump version: 0.1.0 → 0.1.1"
|
|
170
170
|
assert new_commit in out
|
|
@@ -75,6 +75,7 @@ def test_check(mock_no_dmypy, monkeypatch, mocker):
|
|
|
75
75
|
def test_check_bandit(tmp_path):
|
|
76
76
|
package_path = tmp_path / "foo"
|
|
77
77
|
with chdir(tmp_path):
|
|
78
|
+
assert LintCode.get_package_name() == "."
|
|
78
79
|
run_and_echo(f"poetry new {package_path.name}")
|
|
79
80
|
shutil.rmtree(package_path / package_path.name)
|
|
80
81
|
with chdir(package_path):
|
|
@@ -82,6 +83,18 @@ def test_check_bandit(tmp_path):
|
|
|
82
83
|
assert "bandit -r ." in command
|
|
83
84
|
|
|
84
85
|
|
|
86
|
+
def test_check_skip_mypy(mock_skip_mypy_0, mocker, capsys):
|
|
87
|
+
cmd = "fast check --skip-mypy --dry"
|
|
88
|
+
cmd2 = "fast lint --check-only --skip-mypy --dry"
|
|
89
|
+
mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
|
|
90
|
+
command = capture_cmd_output(cmd)
|
|
91
|
+
command2 = capture_cmd_output(cmd2)
|
|
92
|
+
expected = "--> " + SEP.join(
|
|
93
|
+
filter(lambda i: not i.startswith("mypy"), CHECK_CMD.split(SEP))
|
|
94
|
+
)
|
|
95
|
+
assert command == command2 == expected
|
|
96
|
+
|
|
97
|
+
|
|
85
98
|
def test_fast_check():
|
|
86
99
|
_fast_check()
|
|
87
100
|
|
|
@@ -128,7 +141,7 @@ def test_lint_with_prefix(mocker):
|
|
|
128
141
|
assert "pdm run" in stream.getvalue()
|
|
129
142
|
|
|
130
143
|
|
|
131
|
-
def test_make_style(mocker, mock_no_dmypy):
|
|
144
|
+
def test_make_style(mock_skip_mypy_0, mocker, mock_no_dmypy):
|
|
132
145
|
mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
|
|
133
146
|
with capture_stdout() as stream:
|
|
134
147
|
make_style(check_only=False, dry=True)
|
|
@@ -196,6 +209,23 @@ def test_skip_mypy(mock_skip_mypy, mocker):
|
|
|
196
209
|
assert LintCode(".").gen() == SEP.join(i for i in cmds if not i.startswith("mypy"))
|
|
197
210
|
|
|
198
211
|
|
|
212
|
+
def test_skip_mypy_option(mock_skip_mypy_0, mocker):
|
|
213
|
+
mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
|
|
214
|
+
cmds = LINT_CMD.split(SEP)
|
|
215
|
+
assert LintCode(".", skip_mypy=True).gen() == SEP.join(
|
|
216
|
+
i for i in cmds if not i.startswith("mypy")
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def test_skip_mypy_fast_lint(mock_skip_mypy_0, mocker, capsys):
|
|
221
|
+
mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
|
|
222
|
+
command = capture_cmd_output("fast lint --skip-mypy --dry")
|
|
223
|
+
cmds = LINT_CMD.split(SEP)
|
|
224
|
+
assert command.replace("--> ", "") == SEP.join(
|
|
225
|
+
i for i in cmds if not i.startswith("mypy")
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
|
|
199
229
|
def test_skip_mypy_0(mock_skip_mypy_0, mocker, mock_no_dmypy):
|
|
200
230
|
mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
|
|
201
231
|
assert LintCode(".").gen() == LINT_CMD
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from fast_dev_cli.cli import TOML_FILE, run_and_echo, upload
|
|
4
|
+
|
|
5
|
+
from .utils import chdir
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_upload(capsys):
|
|
9
|
+
upload(dry=True)
|
|
10
|
+
out = capsys.readouterr().out.strip()
|
|
11
|
+
assert out.replace("--> ", "") == "pdm publish"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_upload_poetry(tmp_path, capsys):
|
|
15
|
+
with chdir(tmp_path):
|
|
16
|
+
run_and_echo("poetry new foo", verbose=False)
|
|
17
|
+
with chdir(tmp_path / "foo"):
|
|
18
|
+
upload(dry=True)
|
|
19
|
+
out = capsys.readouterr().out.strip()
|
|
20
|
+
assert out.replace("--> ", "") == "poetry publish --build"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_upload_uv(tmp_path, capsys):
|
|
24
|
+
project_dir = tmp_path / "uv_proj"
|
|
25
|
+
project_dir.mkdir()
|
|
26
|
+
toml_file = project_dir / TOML_FILE
|
|
27
|
+
with chdir(project_dir):
|
|
28
|
+
run_and_echo("uv init", verbose=False)
|
|
29
|
+
if (s := "[tool.uv]") not in (text := toml_file.read_text()):
|
|
30
|
+
toml_file.write_text(text + os.linesep + s)
|
|
31
|
+
upload(dry=True)
|
|
32
|
+
out = capsys.readouterr().out.strip()
|
|
33
|
+
assert out.replace("--> ", "") == "uv build && uv publish"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_upload_other(tmp_path, capsys):
|
|
37
|
+
project_dir = tmp_path / "proj"
|
|
38
|
+
project_dir.mkdir()
|
|
39
|
+
with chdir(project_dir):
|
|
40
|
+
run_and_echo("uv init", verbose=False)
|
|
41
|
+
upload(dry=True)
|
|
42
|
+
out = capsys.readouterr().out.strip()
|
|
43
|
+
assert out.replace("--> ", "") == "python -m build && twine upload"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.11.0"
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding:utf-8 -*-
|
|
3
|
-
import os
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
parent = os.path.abspath(os.path.dirname(__file__))
|
|
7
|
-
work_dir = os.path.dirname(parent)
|
|
8
|
-
if os.getcwd() != work_dir:
|
|
9
|
-
os.chdir(work_dir)
|
|
10
|
-
|
|
11
|
-
if os.system("pdm run fast check") != 0:
|
|
12
|
-
print("\033[1m Please run './scripts/format.py' to auto-fix style issues \033[0m")
|
|
13
|
-
sys.exit(1)
|
|
14
|
-
|
|
15
|
-
package_name = os.path.basename(work_dir).replace("-", "_")
|
|
16
|
-
cmd = "pdm run bandit -r {}".format(package_name)
|
|
17
|
-
print("-->", cmd)
|
|
18
|
-
if os.system(cmd) != 0:
|
|
19
|
-
sys.exit(1)
|
|
20
|
-
print("Done. ✨ 🍰 ✨")
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding:utf-8 -*-
|
|
3
|
-
import os
|
|
4
|
-
import shlex
|
|
5
|
-
import subprocess
|
|
6
|
-
import sys
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
|
|
9
|
-
work_dir = Path(__file__).parent.resolve().parent
|
|
10
|
-
if Path.cwd() != work_dir:
|
|
11
|
-
os.chdir(str(work_dir))
|
|
12
|
-
|
|
13
|
-
cmd = "pdm run fast lint"
|
|
14
|
-
r = subprocess.run(shlex.split(cmd), env=dict(os.environ, SKIP_MYPY="1"))
|
|
15
|
-
sys.exit(None if r.returncode == 0 else 1)
|
|
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
|