fast-dev-cli 0.9.9__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.9 → 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.9 → fast_dev_cli-0.10.0}/fast_dev_cli/cli.py +39 -12
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/pyproject.toml +2 -2
- {fast_dev_cli-0.9.9 → 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.9 → fast_dev_cli-0.10.0}/tests/test_bump.py +24 -5
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_fast_test.py +7 -1
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_functions.py +6 -1
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_lint.py +19 -1
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_runserver.py +14 -1
- fast_dev_cli-0.9.9/fast_dev_cli/__init__.py +0 -1
- fast_dev_cli-0.9.9/scripts/format.sh +0 -6
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/LICENSE +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/README.md +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/fast_dev_cli/__main__.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/fast_dev_cli/py.typed +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/pdm_build.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/scripts/test.sh +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/__init__.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/conftest.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_poetry_version_plugin.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_sync.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_tag.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_upgrade.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_upload.py +0 -0
- {fast_dev_cli-0.9.9 → fast_dev_cli-0.10.0}/tests/test_version.py +0 -0
- {fast_dev_cli-0.9.9 → 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:
|
|
@@ -228,8 +233,9 @@ class BumpUp(DryRun):
|
|
|
228
233
|
cmd += " --tag"
|
|
229
234
|
cmd += " --commit"
|
|
230
235
|
if self.should_add_emoji():
|
|
231
|
-
cmd += " --
|
|
232
|
-
|
|
236
|
+
cmd += " --message-emoji=1"
|
|
237
|
+
if not load_bool("DONT_GIT_PUSH"):
|
|
238
|
+
cmd += " && git push && git push --tags && git log -1"
|
|
233
239
|
else:
|
|
234
240
|
cmd += " --allow-dirty"
|
|
235
241
|
return cmd
|
|
@@ -543,7 +549,9 @@ class GitTag(DryRun):
|
|
|
543
549
|
return capture_cmd_output("git status")
|
|
544
550
|
|
|
545
551
|
def mark_tag(self: Self) -> bool:
|
|
546
|
-
if not re.search(r"working (tree|directory) clean", self.git_status)
|
|
552
|
+
if not re.search(r"working (tree|directory) clean", self.git_status) and (
|
|
553
|
+
"无文件要提交,干净的工作区" not in self.git_status
|
|
554
|
+
):
|
|
547
555
|
run_and_echo("git status")
|
|
548
556
|
echo("ERROR: Please run git commit to make sure working tree is clean!")
|
|
549
557
|
return False
|
|
@@ -564,9 +572,12 @@ def tag(
|
|
|
564
572
|
|
|
565
573
|
|
|
566
574
|
class LintCode(DryRun):
|
|
567
|
-
def __init__(
|
|
575
|
+
def __init__(
|
|
576
|
+
self: Self, args, check_only=False, _exit=False, dry=False, bandit=False
|
|
577
|
+
) -> None:
|
|
568
578
|
self.args = args
|
|
569
579
|
self.check_only = check_only
|
|
580
|
+
self._bandit = bandit
|
|
570
581
|
super().__init__(_exit, dry)
|
|
571
582
|
|
|
572
583
|
@staticmethod
|
|
@@ -576,11 +587,13 @@ class LintCode(DryRun):
|
|
|
576
587
|
@staticmethod
|
|
577
588
|
def prefer_dmypy(paths: str, tools: list[str]) -> bool:
|
|
578
589
|
return (
|
|
579
|
-
paths == "."
|
|
590
|
+
paths == "."
|
|
591
|
+
and any(t.startswith("mypy") for t in tools)
|
|
592
|
+
and not load_bool("NO_DMYPY")
|
|
580
593
|
)
|
|
581
594
|
|
|
582
595
|
@classmethod
|
|
583
|
-
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:
|
|
584
597
|
cmd = ""
|
|
585
598
|
tools = ["ruff format", "ruff check --extend-select=I,B,SIM --fix", "mypy"]
|
|
586
599
|
if check_only:
|
|
@@ -609,11 +622,24 @@ class LintCode(DryRun):
|
|
|
609
622
|
if cls.prefer_dmypy(paths, tools):
|
|
610
623
|
tools[-1] = "dmypy run"
|
|
611
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
|
|
612
638
|
return cmd
|
|
613
639
|
|
|
614
640
|
def gen(self: Self) -> str:
|
|
615
641
|
paths = " ".join(map(str, self.args)) if self.args else "."
|
|
616
|
-
return self.to_cmd(paths, self.check_only)
|
|
642
|
+
return self.to_cmd(paths, self.check_only, self._bandit)
|
|
617
643
|
|
|
618
644
|
|
|
619
645
|
def parse_files(args: list[str] | tuple[str, ...]) -> list[str]:
|
|
@@ -628,8 +654,8 @@ def lint(files=None, dry=False) -> None:
|
|
|
628
654
|
LintCode(files, dry=dry).run()
|
|
629
655
|
|
|
630
656
|
|
|
631
|
-
def check(files=None, dry=False) -> None:
|
|
632
|
-
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()
|
|
633
659
|
|
|
634
660
|
|
|
635
661
|
@cli.command(name="lint")
|
|
@@ -651,10 +677,11 @@ def make_style(
|
|
|
651
677
|
|
|
652
678
|
@cli.command(name="check")
|
|
653
679
|
def only_check(
|
|
680
|
+
bandit: bool = Option(False, "--bandit", help="Run `bandit -r <package_dir>`"),
|
|
654
681
|
dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
|
|
655
682
|
) -> None:
|
|
656
683
|
"""Check code style without reformat"""
|
|
657
|
-
check(dry=dry)
|
|
684
|
+
check(dry=dry, bandit=bandit)
|
|
658
685
|
|
|
659
686
|
|
|
660
687
|
class Sync(DryRun):
|
|
@@ -694,7 +721,7 @@ def sync(
|
|
|
694
721
|
Sync(filename, extras, save, dry=dry).run()
|
|
695
722
|
|
|
696
723
|
|
|
697
|
-
def _should_run_test_script(path: Path) -> bool:
|
|
724
|
+
def _should_run_test_script(path: Path = Path("scripts/test.sh")) -> bool:
|
|
698
725
|
return path.exists()
|
|
699
726
|
|
|
700
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"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import subprocess
|
|
1
2
|
from contextlib import redirect_stdout
|
|
2
3
|
from io import StringIO
|
|
3
4
|
from pathlib import Path
|
|
@@ -14,11 +15,11 @@ from fast_dev_cli.cli import (
|
|
|
14
15
|
StrEnum,
|
|
15
16
|
bump,
|
|
16
17
|
bump_version,
|
|
18
|
+
capture_cmd_output,
|
|
17
19
|
get_current_version,
|
|
18
20
|
)
|
|
19
|
-
from tests.utils import mock_sys_argv
|
|
20
21
|
|
|
21
|
-
from .utils import chdir
|
|
22
|
+
from .utils import chdir, mock_sys_argv
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
def test_enum():
|
|
@@ -40,7 +41,7 @@ def _bump_commands(
|
|
|
40
41
|
cmd = rf'bumpversion --parse "(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)" --current-version="{version}"'
|
|
41
42
|
suffix = " --commit && git push && git push --tags && git log -1"
|
|
42
43
|
if emoji:
|
|
43
|
-
suffix = suffix.replace("--commit", "--commit --
|
|
44
|
+
suffix = suffix.replace("--commit", "--commit --message-emoji=1")
|
|
44
45
|
patch_without_commit = cmd + f" patch {filename} --allow-dirty"
|
|
45
46
|
patch_with_commit = cmd + f" patch {filename}" + suffix
|
|
46
47
|
minor_with_commit = cmd + f" minor {filename} --tag" + suffix
|
|
@@ -136,16 +137,34 @@ def test_bump_with_poetry(mocker, tmp_poetry_project, tmp_path):
|
|
|
136
137
|
assert work_dir == work_dir2 == tmp_path
|
|
137
138
|
|
|
138
139
|
|
|
139
|
-
def test_bump_with_emoji(mocker):
|
|
140
|
+
def test_bump_with_emoji(mocker, tmp_path, monkeypatch):
|
|
140
141
|
mocker.patch("fast_dev_cli.cli.Project.manage_by_poetry", return_value=True)
|
|
141
142
|
version = get_current_version()
|
|
142
143
|
patch_without_commit, patch_with_commit, minor_with_commit = _bump_commands(
|
|
143
144
|
version, emoji=True
|
|
144
145
|
)
|
|
146
|
+
last_commit = "📝 Update release notes"
|
|
145
147
|
mocker.patch(
|
|
146
148
|
"fast_dev_cli.cli.BumpUp.get_last_commit_message",
|
|
147
|
-
return_value=
|
|
149
|
+
return_value=last_commit,
|
|
148
150
|
)
|
|
149
151
|
assert BumpUp(part="patch", commit=False, dry=True).gen() == patch_without_commit
|
|
150
152
|
assert BumpUp(part="patch", commit=True, dry=True).gen() == patch_with_commit
|
|
151
153
|
assert BumpUp(part="minor", commit=True, dry=True).gen() == minor_with_commit
|
|
154
|
+
# real bump
|
|
155
|
+
with chdir(tmp_path):
|
|
156
|
+
project = "foo"
|
|
157
|
+
subprocess.run(["poetry", "new", project])
|
|
158
|
+
with chdir(tmp_path / project):
|
|
159
|
+
subprocess.run(["git", "init"])
|
|
160
|
+
subprocess.run(["git", "add", "."])
|
|
161
|
+
subprocess.run(["git", "commit", "-m", last_commit])
|
|
162
|
+
monkeypatch.setenv("DONT_GIT_PUSH", "1")
|
|
163
|
+
command = BumpUp(part="patch", commit=True).gen()
|
|
164
|
+
expected = patch_with_commit.split("&&")[0].strip().replace('""', '"0.1.0"')
|
|
165
|
+
assert expected == command
|
|
166
|
+
subprocess.run(["poetry", "run", "pip", "install", "bumpversion2"])
|
|
167
|
+
subprocess.run(["fast", "bump", "patch", "--commit"])
|
|
168
|
+
out = capture_cmd_output(["git", "log"])
|
|
169
|
+
new_commit = "⬆️ Bump version: 0.1.0 → 0.1.1"
|
|
170
|
+
assert new_commit in out
|
|
@@ -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.9"
|
|
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
|