fast-dev-cli 0.15.1__tar.gz → 0.16.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.15.1 → fast_dev_cli-0.16.0}/PKG-INFO +3 -2
- fast_dev_cli-0.16.0/fast_dev_cli/__init__.py +1 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/fast_dev_cli/cli.py +58 -19
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/pyproject.toml +13 -4
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_bump.py +73 -1
- fast_dev_cli-0.15.1/fast_dev_cli/__init__.py +0 -1
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/LICENSE +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/README.md +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/fast_dev_cli/__main__.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/fast_dev_cli/py.typed +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/pdm_build.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/scripts/check.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/scripts/format.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/scripts/test.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/__init__.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/conftest.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_fast_test.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_functions.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_lint.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_poetry_version_plugin.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_runserver.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_sync.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_tag.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_upgrade.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_upload.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_version.py +0 -0
- {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.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.16.0
|
|
4
4
|
Summary: Python project development tool.
|
|
5
5
|
Author-Email: Waket Zheng <waketzheng@gmail.com>>
|
|
6
6
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
18
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
19
|
Classifier: Topic :: Software Development :: Libraries
|
|
19
20
|
Classifier: Topic :: Software Development
|
|
@@ -22,9 +23,9 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
22
23
|
Project-URL: Homepage, https://github.com/waketzheng/fast-dev-cli
|
|
23
24
|
Requires-Python: >=3.9
|
|
24
25
|
Requires-Dist: typer<1,>=0.12.3
|
|
26
|
+
Requires-Dist: tomli<3,>=2.0.1; python_version < "3.11"
|
|
25
27
|
Requires-Dist: emoji<3,>=2.12.1
|
|
26
28
|
Requires-Dist: packaging>=20.5
|
|
27
|
-
Requires-Dist: tomli<3,>=2.0.1; python_version < "3.11"
|
|
28
29
|
Requires-Dist: coverage<8,>=7.5.1
|
|
29
30
|
Requires-Dist: mypy<2,>=1.15.0
|
|
30
31
|
Requires-Dist: bumpversion2<2,>=1.4.3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.16.0"
|
|
@@ -18,11 +18,21 @@ from typing import (
|
|
|
18
18
|
get_args,
|
|
19
19
|
)
|
|
20
20
|
|
|
21
|
-
import emoji
|
|
22
21
|
import typer
|
|
23
22
|
from typer import Exit, Option, echo, secho
|
|
24
23
|
from typer.models import ArgumentInfo, OptionInfo
|
|
25
24
|
|
|
25
|
+
try:
|
|
26
|
+
from emoji import is_emoji
|
|
27
|
+
except ImportError:
|
|
28
|
+
|
|
29
|
+
def is_emoji(char: str) -> bool: # type:ignore[misc]
|
|
30
|
+
return (
|
|
31
|
+
not re.match(r"[\w\d\s]", char)
|
|
32
|
+
and not "\u4e00" <= char <= "\u9fff" # Chinese
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
26
36
|
try:
|
|
27
37
|
from . import __version__
|
|
28
38
|
except ImportError: # pragma: no cover
|
|
@@ -59,7 +69,12 @@ class ShellCommandError(Exception): ...
|
|
|
59
69
|
|
|
60
70
|
def poetry_module_name(name: str) -> str:
|
|
61
71
|
"""Get module name that generated by `poetry new`"""
|
|
62
|
-
|
|
72
|
+
try:
|
|
73
|
+
from packaging.utils import canonicalize_name
|
|
74
|
+
except ImportError:
|
|
75
|
+
|
|
76
|
+
def canonicalize_name(s: str) -> str: # type:ignore[misc]
|
|
77
|
+
return re.sub(r"[-_.]+", "-", s)
|
|
63
78
|
|
|
64
79
|
return canonicalize_name(name).replace("-", "_").replace(" ", "_")
|
|
65
80
|
|
|
@@ -122,16 +137,27 @@ def _parse_version(line: str, pattern: re.Pattern[str]) -> str:
|
|
|
122
137
|
def read_version_from_file(
|
|
123
138
|
package_name: str, work_dir: Path | None = None, toml_text: str | None = None
|
|
124
139
|
) -> str:
|
|
125
|
-
if
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
140
|
+
if not package_name and toml_text:
|
|
141
|
+
pattern = re.compile(r"version\s*=")
|
|
142
|
+
for line in toml_text.splitlines():
|
|
143
|
+
if pattern.match(line):
|
|
144
|
+
return _parse_version(line, pattern)
|
|
145
|
+
version_file = BumpUp.parse_filename(toml_text, work_dir, package_name)
|
|
146
|
+
if version_file == TOML_FILE:
|
|
147
|
+
if toml_text is None:
|
|
148
|
+
toml_text = Project.load_toml_text()
|
|
149
|
+
context = tomllib.loads(toml_text)
|
|
150
|
+
with contextlib.suppress(KeyError):
|
|
151
|
+
return context["project"]["version"]
|
|
152
|
+
with contextlib.suppress(KeyError): # Poetry V1
|
|
153
|
+
return context["tool"]["poetry"]["version"]
|
|
154
|
+
secho(f"WARNING: can not find 'version' item in {version_file}!")
|
|
155
|
+
return "0.0.0"
|
|
156
|
+
pattern = re.compile(r"__version__\s*=")
|
|
157
|
+
for line in Path(version_file).read_text("utf-8").splitlines():
|
|
130
158
|
if pattern.match(line):
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
break
|
|
134
|
-
return lib_version
|
|
159
|
+
return _parse_version(line, pattern)
|
|
160
|
+
# TODO: remove or refactor the following lines.
|
|
135
161
|
if work_dir is None:
|
|
136
162
|
work_dir = Project.get_work_dir()
|
|
137
163
|
package_dir = work_dir / package_name
|
|
@@ -142,6 +168,7 @@ def read_version_from_file(
|
|
|
142
168
|
):
|
|
143
169
|
secho("WARNING: __init__.py file does not exist!")
|
|
144
170
|
return "0.0.0"
|
|
171
|
+
|
|
145
172
|
pattern = re.compile(r"__version__\s*=")
|
|
146
173
|
for line in init_file.read_text("utf-8").splitlines():
|
|
147
174
|
if pattern.match(line):
|
|
@@ -255,11 +282,16 @@ class BumpUp(DryRun):
|
|
|
255
282
|
except (IndexError, ShellCommandError):
|
|
256
283
|
return False
|
|
257
284
|
else:
|
|
258
|
-
return
|
|
285
|
+
return is_emoji(first_char)
|
|
259
286
|
|
|
260
287
|
@staticmethod
|
|
261
|
-
def parse_filename(
|
|
262
|
-
toml_text =
|
|
288
|
+
def parse_filename(
|
|
289
|
+
toml_text: str | None = None,
|
|
290
|
+
work_dir: Path | None = None,
|
|
291
|
+
package_name: str | None = None,
|
|
292
|
+
) -> str:
|
|
293
|
+
if toml_text is None:
|
|
294
|
+
toml_text = Project.load_toml_text()
|
|
263
295
|
context = tomllib.loads(toml_text)
|
|
264
296
|
by_version_plugin = False
|
|
265
297
|
try:
|
|
@@ -277,14 +309,14 @@ class BumpUp(DryRun):
|
|
|
277
309
|
version_value = context["tool"]["poetry"]["version"]
|
|
278
310
|
except KeyError:
|
|
279
311
|
if not Project.manage_by_poetry():
|
|
312
|
+
if work_dir is None:
|
|
313
|
+
work_dir = Project.get_work_dir()
|
|
280
314
|
for tool in ("pdm", "hatch"):
|
|
281
315
|
with contextlib.suppress(KeyError):
|
|
282
316
|
version_path = context["tool"][tool]["version"]["path"]
|
|
283
317
|
if (
|
|
284
318
|
Path(version_path).exists()
|
|
285
|
-
or
|
|
286
|
-
.joinpath(version_path)
|
|
287
|
-
.exists()
|
|
319
|
+
or work_dir.joinpath(version_path).exists()
|
|
288
320
|
):
|
|
289
321
|
return version_path
|
|
290
322
|
# version = { source = "file", path = "fast_dev_cli/__init__.py" }
|
|
@@ -295,7 +327,7 @@ class BumpUp(DryRun):
|
|
|
295
327
|
continue
|
|
296
328
|
if p_key in (value := line.split(v_key, 1)[-1].split("#")[0]):
|
|
297
329
|
filename = value.split(p_key, 1)[-1].split('"')[0]
|
|
298
|
-
if
|
|
330
|
+
if work_dir.joinpath(filename).exists():
|
|
299
331
|
return filename
|
|
300
332
|
else:
|
|
301
333
|
by_version_plugin = version_value in ("0", "0.0.0", "init")
|
|
@@ -319,6 +351,8 @@ class BumpUp(DryRun):
|
|
|
319
351
|
cwd = Path.cwd()
|
|
320
352
|
pattern = re.compile(r"__version__\s*=\s*['\"]")
|
|
321
353
|
ds: list[Path] = []
|
|
354
|
+
if package_name is not None:
|
|
355
|
+
packages.insert(0, (package_name, ""))
|
|
322
356
|
for package_name, source_dir in packages:
|
|
323
357
|
ds.append(cwd / package_name)
|
|
324
358
|
ds.append(cwd / "src" / package_name)
|
|
@@ -328,7 +362,12 @@ class BumpUp(DryRun):
|
|
|
328
362
|
ds.extend([cwd / module_name, cwd / "src" / module_name, cwd])
|
|
329
363
|
for d in ds:
|
|
330
364
|
init_file = d / "__init__.py"
|
|
331
|
-
if
|
|
365
|
+
if (
|
|
366
|
+
init_file.exists() and pattern.search(init_file.read_text("utf8"))
|
|
367
|
+
) or (
|
|
368
|
+
(init_file := init_file.with_name("__version__.py")).exists()
|
|
369
|
+
and pattern.search(init_file.read_text("utf8"))
|
|
370
|
+
):
|
|
332
371
|
break
|
|
333
372
|
else:
|
|
334
373
|
raise ParseError("Version file not found! Where are you now?")
|
|
@@ -25,6 +25,7 @@ classifiers = [
|
|
|
25
25
|
"Programming Language :: Python :: 3.11",
|
|
26
26
|
"Programming Language :: Python :: 3.12",
|
|
27
27
|
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Programming Language :: Python :: 3.14",
|
|
28
29
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
29
30
|
"Topic :: Software Development :: Libraries",
|
|
30
31
|
"Topic :: Software Development",
|
|
@@ -32,16 +33,16 @@ classifiers = [
|
|
|
32
33
|
"License :: OSI Approved :: MIT License",
|
|
33
34
|
]
|
|
34
35
|
dependencies = [
|
|
35
|
-
"typer>=0.12.3,<1",
|
|
36
|
+
"typer >=0.12.3,<1",
|
|
37
|
+
"tomli >=2.0.1,<3; python_version < '3.11'",
|
|
36
38
|
"emoji >=2.12.1,<3",
|
|
37
|
-
"packaging>=20.5",
|
|
38
|
-
"tomli>=2.0.1,<3; python_version < '3.11'",
|
|
39
|
+
"packaging >=20.5",
|
|
39
40
|
"coverage >=7.5.1,<8",
|
|
40
41
|
"mypy >=1.15.0,<2",
|
|
41
42
|
"bumpversion2 >=1.4.3,<2",
|
|
42
43
|
"pytest >=8.2.0,<9",
|
|
43
44
|
]
|
|
44
|
-
version = "0.
|
|
45
|
+
version = "0.16.0"
|
|
45
46
|
|
|
46
47
|
[project.urls]
|
|
47
48
|
Homepage = "https://github.com/waketzheng/fast-dev-cli"
|
|
@@ -163,3 +164,11 @@ exclude_dirs = [
|
|
|
163
164
|
"examples",
|
|
164
165
|
".venv",
|
|
165
166
|
]
|
|
167
|
+
|
|
168
|
+
[dependency-groups]
|
|
169
|
+
ci = [
|
|
170
|
+
"coveralls @ git+https://github.com/waketzheng/coveralls-python@4.1.1",
|
|
171
|
+
]
|
|
172
|
+
dev = [
|
|
173
|
+
"twine>=6.1.0",
|
|
174
|
+
]
|
|
@@ -288,8 +288,80 @@ dynamic = ["readme", "version"]
|
|
|
288
288
|
path = "httpx/__version__.py"
|
|
289
289
|
""")
|
|
290
290
|
Path(project_name).mkdir()
|
|
291
|
-
Path("httpx/__version__.py")
|
|
291
|
+
version_file = Path("httpx/__version__.py")
|
|
292
|
+
version_file.write_text("""
|
|
292
293
|
__title__ = "httpx"
|
|
293
294
|
__description__ = "A next generation HTTP client, for Python 3."
|
|
294
295
|
__version__ = "0.28.1"
|
|
295
296
|
""")
|
|
297
|
+
out = capture_cmd_output("fast bump patch")
|
|
298
|
+
assert str(version_file) in out
|
|
299
|
+
assert "0.28.2" in version_file.read_text()
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def test_package_project_diff(tmp_work_dir):
|
|
303
|
+
project_name = "tortoise-database-url"
|
|
304
|
+
package_name = "database_url"
|
|
305
|
+
Path(project_name).mkdir()
|
|
306
|
+
with chdir(project_name):
|
|
307
|
+
Path(package_name).mkdir()
|
|
308
|
+
version_file = Path(package_name, "__init__.py")
|
|
309
|
+
version_file.write_text('__version__ = "0.3.0"')
|
|
310
|
+
toml_file = Path("pyproject.toml")
|
|
311
|
+
toml_file.write_text("""
|
|
312
|
+
[project]
|
|
313
|
+
name = "tortoise-database-url"
|
|
314
|
+
description = "Make it easy to generate database url."
|
|
315
|
+
authors = [{name="Waket Zheng", email="waketzheng@gmail.com"}]
|
|
316
|
+
readme = "README.md"
|
|
317
|
+
dynamic = ["version"]
|
|
318
|
+
keywords = ["database_url", "tortoise-orm"]
|
|
319
|
+
requires-python = ">=3.9"
|
|
320
|
+
dependencies = []
|
|
321
|
+
|
|
322
|
+
[tool.pdm.version]
|
|
323
|
+
source = "file"
|
|
324
|
+
path = "database_url/__init__.py"
|
|
325
|
+
|
|
326
|
+
[build-system]
|
|
327
|
+
requires = ["pdm-backend"]
|
|
328
|
+
build-backend = "pdm.backend"
|
|
329
|
+
""")
|
|
330
|
+
out = capture_cmd_output("fast bump patch")
|
|
331
|
+
assert str(version_file) in out
|
|
332
|
+
assert "0.3.1" in version_file.read_text()
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def test_version_file_in_work_dir(tmp_work_dir):
|
|
336
|
+
project_name = package_name = "bigmodels"
|
|
337
|
+
Path(project_name).mkdir()
|
|
338
|
+
with chdir(project_name):
|
|
339
|
+
Path(package_name).mkdir()
|
|
340
|
+
version_file = Path("__version__.py")
|
|
341
|
+
version_file.write_text('__version__ = "0.3.0"')
|
|
342
|
+
toml_file = Path("pyproject.toml")
|
|
343
|
+
toml_file.write_text("""
|
|
344
|
+
[project]
|
|
345
|
+
name = "bigmodels"
|
|
346
|
+
description = ""
|
|
347
|
+
authors = [{name="Waket Zheng", email="waketzheng@gmail.com"}]
|
|
348
|
+
readme = "README.md"
|
|
349
|
+
dynamic = ["version"]
|
|
350
|
+
keywords = []
|
|
351
|
+
requires-python = ">=3.9"
|
|
352
|
+
dependencies = []
|
|
353
|
+
|
|
354
|
+
[tool.pdm]
|
|
355
|
+
distribution = false
|
|
356
|
+
|
|
357
|
+
[tool.pdm.version]
|
|
358
|
+
source = "file"
|
|
359
|
+
path = "__version__.py"
|
|
360
|
+
|
|
361
|
+
[build-system]
|
|
362
|
+
requires = ["pdm-backend"]
|
|
363
|
+
build-backend = "pdm.backend"
|
|
364
|
+
""")
|
|
365
|
+
out = capture_cmd_output("fast bump patch")
|
|
366
|
+
assert str(version_file) in out
|
|
367
|
+
assert "0.3.1" in version_file.read_text()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.15.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|