fast-dev-cli 0.9.10__tar.gz → 0.10.0__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.9.10 → fast_dev_cli-0.10.0}/PKG-INFO +3 -3
- fast_dev_cli-0.10.0/fast_dev_cli/__init__.py +1 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/fast_dev_cli/cli.py +33 -9
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/pyproject.toml +2 -2
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/scripts/check.sh +1 -1
- fast_dev_cli-0.10.0/scripts/format.sh +6 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_fast_test.py +7 -1
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_functions.py +6 -1
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_lint.py +19 -1
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_runserver.py +14 -1
- fast_dev_cli-0.9.10/fast_dev_cli/__init__.py +0 -1
- fast_dev_cli-0.9.10/scripts/format.sh +0 -6
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/LICENSE +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/README.md +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/fast_dev_cli/__main__.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/fast_dev_cli/py.typed +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/pdm_build.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/scripts/test.sh +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/__init__.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/conftest.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_bump.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_poetry_version_plugin.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_sync.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_tag.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_upgrade.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_upload.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/test_version.py +0 -0
- {fast_dev_cli-0.9.10 → fast_dev_cli-0.10.0}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fast-dev-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary: Python project development tool.
|
|
5
5
|
Author-Email: Waket Zheng <waketzheng@gmail.com>>
|
|
6
6
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -24,13 +24,13 @@ Requires-Dist: typer<0.13,>=0.12.3
|
|
|
24
24
|
Requires-Dist: emoji<3,>=2.12.1
|
|
25
25
|
Requires-Dist: tomli<3,>=2.0.1; python_version < "3.11"
|
|
26
26
|
Requires-Dist: coverage<8,>=7.5.1
|
|
27
|
-
Requires-Dist: ruff<0.
|
|
27
|
+
Requires-Dist: ruff<0.8,>=0.4.4
|
|
28
28
|
Requires-Dist: mypy<2,>=1.10.0
|
|
29
29
|
Requires-Dist: bumpversion2<2,>=1.4.2
|
|
30
30
|
Requires-Dist: pytest<9,>=8.2.0
|
|
31
|
+
Provides-Extra: all
|
|
31
32
|
Requires-Dist: ipython<9,>=8.24.0; extra == "all"
|
|
32
33
|
Requires-Dist: pytest-mock<4,>=3.14.0; extra == "all"
|
|
33
|
-
Provides-Extra: all
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
35
|
|
|
36
36
|
<p align="center">
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.10.0"
|
|
@@ -44,7 +44,12 @@ cli = typer.Typer()
|
|
|
44
44
|
def load_bool(name: str, default=False) -> bool:
|
|
45
45
|
if not (v := os.getenv(name)):
|
|
46
46
|
return default
|
|
47
|
-
|
|
47
|
+
if (lower := v.lower()) in ("0", "false", "f", "off", "no", "n"):
|
|
48
|
+
return False
|
|
49
|
+
elif lower in ("1", "true", "t", "on", "yes", "y"):
|
|
50
|
+
return True
|
|
51
|
+
secho(f"WARNING: can not convert value({v!r}) of {name} to bool!")
|
|
52
|
+
return default
|
|
48
53
|
|
|
49
54
|
|
|
50
55
|
def is_venv() -> bool:
|
|
@@ -567,9 +572,12 @@ def tag(
|
|
|
567
572
|
|
|
568
573
|
|
|
569
574
|
class LintCode(DryRun):
|
|
570
|
-
def __init__(
|
|
575
|
+
def __init__(
|
|
576
|
+
self: Self, args, check_only=False, _exit=False, dry=False, bandit=False
|
|
577
|
+
) -> None:
|
|
571
578
|
self.args = args
|
|
572
579
|
self.check_only = check_only
|
|
580
|
+
self._bandit = bandit
|
|
573
581
|
super().__init__(_exit, dry)
|
|
574
582
|
|
|
575
583
|
@staticmethod
|
|
@@ -579,11 +587,13 @@ class LintCode(DryRun):
|
|
|
579
587
|
@staticmethod
|
|
580
588
|
def prefer_dmypy(paths: str, tools: list[str]) -> bool:
|
|
581
589
|
return (
|
|
582
|
-
paths == "."
|
|
590
|
+
paths == "."
|
|
591
|
+
and any(t.startswith("mypy") for t in tools)
|
|
592
|
+
and not load_bool("NO_DMYPY")
|
|
583
593
|
)
|
|
584
594
|
|
|
585
595
|
@classmethod
|
|
586
|
-
def to_cmd(cls: Type[Self], paths=".", check_only=False) -> str:
|
|
596
|
+
def to_cmd(cls: Type[Self], paths=".", check_only=False, bandit=False) -> str:
|
|
587
597
|
cmd = ""
|
|
588
598
|
tools = ["ruff format", "ruff check --extend-select=I,B,SIM --fix", "mypy"]
|
|
589
599
|
if check_only:
|
|
@@ -612,11 +622,24 @@ class LintCode(DryRun):
|
|
|
612
622
|
if cls.prefer_dmypy(paths, tools):
|
|
613
623
|
tools[-1] = "dmypy run"
|
|
614
624
|
cmd += lint_them.format(prefix, paths, *tools)
|
|
625
|
+
if bandit or load_bool("FASTDEVCLI_BANDIT"):
|
|
626
|
+
command = prefix + "bandit"
|
|
627
|
+
if paths == ".": # fast check --bandit
|
|
628
|
+
command += " -r"
|
|
629
|
+
root = Project.get_work_dir(allow_cwd=True)
|
|
630
|
+
package_maybe = (root.name.replace("-", "_"), "src")
|
|
631
|
+
for name in package_maybe:
|
|
632
|
+
if root.joinpath(name).is_dir():
|
|
633
|
+
command += " " + name
|
|
634
|
+
break
|
|
635
|
+
else:
|
|
636
|
+
command += " ."
|
|
637
|
+
cmd += " && " + command
|
|
615
638
|
return cmd
|
|
616
639
|
|
|
617
640
|
def gen(self: Self) -> str:
|
|
618
641
|
paths = " ".join(map(str, self.args)) if self.args else "."
|
|
619
|
-
return self.to_cmd(paths, self.check_only)
|
|
642
|
+
return self.to_cmd(paths, self.check_only, self._bandit)
|
|
620
643
|
|
|
621
644
|
|
|
622
645
|
def parse_files(args: list[str] | tuple[str, ...]) -> list[str]:
|
|
@@ -631,8 +654,8 @@ def lint(files=None, dry=False) -> None:
|
|
|
631
654
|
LintCode(files, dry=dry).run()
|
|
632
655
|
|
|
633
656
|
|
|
634
|
-
def check(files=None, dry=False) -> None:
|
|
635
|
-
LintCode(files, check_only=True, _exit=True, dry=dry).run()
|
|
657
|
+
def check(files=None, dry=False, bandit=False) -> None:
|
|
658
|
+
LintCode(files, check_only=True, _exit=True, dry=dry, bandit=bandit).run()
|
|
636
659
|
|
|
637
660
|
|
|
638
661
|
@cli.command(name="lint")
|
|
@@ -654,10 +677,11 @@ def make_style(
|
|
|
654
677
|
|
|
655
678
|
@cli.command(name="check")
|
|
656
679
|
def only_check(
|
|
680
|
+
bandit: bool = Option(False, "--bandit", help="Run `bandit -r <package_dir>`"),
|
|
657
681
|
dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
|
|
658
682
|
) -> None:
|
|
659
683
|
"""Check code style without reformat"""
|
|
660
|
-
check(dry=dry)
|
|
684
|
+
check(dry=dry, bandit=bandit)
|
|
661
685
|
|
|
662
686
|
|
|
663
687
|
class Sync(DryRun):
|
|
@@ -697,7 +721,7 @@ def sync(
|
|
|
697
721
|
Sync(filename, extras, save, dry=dry).run()
|
|
698
722
|
|
|
699
723
|
|
|
700
|
-
def _should_run_test_script(path: Path) -> bool:
|
|
724
|
+
def _should_run_test_script(path: Path = Path("scripts/test.sh")) -> bool:
|
|
701
725
|
return path.exists()
|
|
702
726
|
|
|
703
727
|
|
|
@@ -35,12 +35,12 @@ dependencies = [
|
|
|
35
35
|
"emoji >=2.12.1,<3",
|
|
36
36
|
"tomli>=2.0.1,<3; python_version < '3.11'",
|
|
37
37
|
"coverage >=7.5.1,<8",
|
|
38
|
-
"ruff >=0.4.4,<0.
|
|
38
|
+
"ruff >=0.4.4,<0.8",
|
|
39
39
|
"mypy >=1.10.0,<2",
|
|
40
40
|
"bumpversion2 >=1.4.2,<2",
|
|
41
41
|
"pytest >=8.2.0,<9",
|
|
42
42
|
]
|
|
43
|
-
version = "0.
|
|
43
|
+
version = "0.10.0"
|
|
44
44
|
|
|
45
45
|
[project.urls]
|
|
46
46
|
Homepage = "https://github.com/waketzheng/fast-dev-cli"
|
|
@@ -2,7 +2,12 @@ import pathlib
|
|
|
2
2
|
|
|
3
3
|
from pytest_mock import MockerFixture
|
|
4
4
|
|
|
5
|
-
from fast_dev_cli.cli import
|
|
5
|
+
from fast_dev_cli.cli import (
|
|
6
|
+
Project,
|
|
7
|
+
_should_run_test_script,
|
|
8
|
+
capture_cmd_output,
|
|
9
|
+
coverage_test,
|
|
10
|
+
)
|
|
6
11
|
from fast_dev_cli.cli import test as unitcase
|
|
7
12
|
|
|
8
13
|
|
|
@@ -60,6 +65,7 @@ def test_test_not_in_venv(mocker: MockerFixture, capsys):
|
|
|
60
65
|
|
|
61
66
|
|
|
62
67
|
def test_run_script(mocker: MockerFixture, capsys):
|
|
68
|
+
assert _should_run_test_script()
|
|
63
69
|
mocker.patch("fast_dev_cli.cli._should_run_test_script", return_value=True)
|
|
64
70
|
unitcase(dry=True)
|
|
65
71
|
assert "sh scripts/test.sh" in capsys.readouterr().out
|
|
@@ -16,7 +16,7 @@ from fast_dev_cli.cli import (
|
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def test_utils():
|
|
19
|
+
def test_utils(capsys):
|
|
20
20
|
# parse files
|
|
21
21
|
assert parse_files([]) == []
|
|
22
22
|
assert parse_files(["-a", "--a"]) == []
|
|
@@ -52,6 +52,11 @@ def test_utils():
|
|
|
52
52
|
assert load_bool(name) is True
|
|
53
53
|
os.environ.pop(name)
|
|
54
54
|
assert load_bool(name) is False
|
|
55
|
+
os.environ[name] = "yeah"
|
|
56
|
+
assert load_bool(name) is False
|
|
57
|
+
assert load_bool(name, True) is True
|
|
58
|
+
out = capsys.readouterr().out.strip()
|
|
59
|
+
assert "WARNING" in out
|
|
55
60
|
|
|
56
61
|
|
|
57
62
|
def test_run_shell():
|
|
@@ -56,10 +56,18 @@ LINT_CMD = _CMD.format("", " --fix")
|
|
|
56
56
|
CHECK_CMD = _CMD.format(" --check", "")
|
|
57
57
|
|
|
58
58
|
|
|
59
|
-
def test_check(mock_no_dmypy):
|
|
59
|
+
def test_check(mock_no_dmypy, monkeypatch):
|
|
60
60
|
command = capture_cmd_output("fast check --dry")
|
|
61
61
|
for cmd in CHECK_CMD.split(SEP):
|
|
62
62
|
assert cmd in command
|
|
63
|
+
command2 = capture_cmd_output("fast check --bandit --dry")
|
|
64
|
+
assert command2 == command + " && bandit -r fast_dev_cli"
|
|
65
|
+
monkeypatch.setenv("FASTDEVCLI_BANDIT", "1")
|
|
66
|
+
command3 = capture_cmd_output("fast check --dry")
|
|
67
|
+
assert command3 == command2
|
|
68
|
+
monkeypatch.setenv("FASTDEVCLI_BANDIT", "0")
|
|
69
|
+
command4 = capture_cmd_output("fast check --dry")
|
|
70
|
+
assert command4 == command
|
|
63
71
|
|
|
64
72
|
|
|
65
73
|
def test_fast_check():
|
|
@@ -110,9 +118,15 @@ def test_lint_with_prefix(mocker):
|
|
|
110
118
|
|
|
111
119
|
def test_make_style(mocker, mock_no_dmypy):
|
|
112
120
|
mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
|
|
121
|
+
with capture_stdout() as stream:
|
|
122
|
+
make_style(check_only=False, dry=True)
|
|
123
|
+
assert LINT_CMD in stream.getvalue()
|
|
113
124
|
with capture_stdout() as stream:
|
|
114
125
|
make_style([Path(".")], check_only=False, dry=True)
|
|
115
126
|
assert LINT_CMD in stream.getvalue()
|
|
127
|
+
with capture_stdout() as stream:
|
|
128
|
+
make_style(".", check_only=False, dry=True) # type:ignore[arg-type]
|
|
129
|
+
assert LINT_CMD in stream.getvalue()
|
|
116
130
|
with capture_stdout() as stream:
|
|
117
131
|
make_style([Path(".")], check_only=True, dry=True)
|
|
118
132
|
assert CHECK_CMD in stream.getvalue()
|
|
@@ -138,6 +152,10 @@ def test_lint_func(mocker, mock_no_dmypy):
|
|
|
138
152
|
with mock_sys_argv(["tests"]), capture_stdout() as stream:
|
|
139
153
|
lint(dry=True)
|
|
140
154
|
assert LINT_CMD.replace(" .", " tests") in stream.getvalue()
|
|
155
|
+
with capture_stdout() as stream:
|
|
156
|
+
lint(["lint"], dry=True)
|
|
157
|
+
assert LINT_CMD in stream.getvalue()
|
|
158
|
+
assert LINT_CMD in capture_cmd_output("python -m fast_dev_cli lint --dry")
|
|
141
159
|
|
|
142
160
|
|
|
143
161
|
def test_lint_without_ruff_installed(mocker, mock_no_dmypy):
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import fast_dev_cli
|
|
2
|
+
from fast_dev_cli.cli import dev, main, run_and_echo, runserver
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def test_runserver(capsys):
|
|
@@ -17,6 +18,12 @@ def test_runserver(capsys):
|
|
|
17
18
|
runserver(port=9000, host="0.0.0.0", dry=True)
|
|
18
19
|
out = capsys.readouterr().out.strip()
|
|
19
20
|
assert out.replace("--> ", "") == "fastapi dev --port=9000 --host=0.0.0.0"
|
|
21
|
+
runserver("9000", host="0.0.0.0", dry=True)
|
|
22
|
+
out = capsys.readouterr().out.strip()
|
|
23
|
+
assert out.replace("--> ", "") == "fastapi dev --port=9000 --host=0.0.0.0"
|
|
24
|
+
runserver("app.py", host="0.0.0.0", dry=True)
|
|
25
|
+
out = capsys.readouterr().out.strip()
|
|
26
|
+
assert out.replace("--> ", "") == "fastapi dev app.py --host=0.0.0.0"
|
|
20
27
|
|
|
21
28
|
|
|
22
29
|
def test_dev(capsys):
|
|
@@ -80,3 +87,9 @@ def test_run_by_module(tmp_path):
|
|
|
80
87
|
assert "fastapi dev main.py --port=9000 --host=0.0.0.0" in out.read_text()
|
|
81
88
|
run_and_echo(f"{fast} dev 9000 --host=0.0.0.0 --dry > {out}", verbose=False)
|
|
82
89
|
assert "fastapi dev --port=9000 --host=0.0.0.0" in out.read_text()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_main(mocker):
|
|
93
|
+
mocker.patch("fast_dev_cli.cli.cli")
|
|
94
|
+
main()
|
|
95
|
+
fast_dev_cli.cli.cli.assert_called_once() # type:ignore[attr-defined]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.9.10"
|
|
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
|