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.
Files changed (27) hide show
  1. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/PKG-INFO +3 -2
  2. fast_dev_cli-0.16.0/fast_dev_cli/__init__.py +1 -0
  3. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/fast_dev_cli/cli.py +58 -19
  4. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/pyproject.toml +13 -4
  5. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_bump.py +73 -1
  6. fast_dev_cli-0.15.1/fast_dev_cli/__init__.py +0 -1
  7. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/LICENSE +0 -0
  8. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/README.md +0 -0
  9. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/fast_dev_cli/__main__.py +0 -0
  10. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/fast_dev_cli/py.typed +0 -0
  11. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/pdm_build.py +0 -0
  12. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/scripts/check.py +0 -0
  13. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/scripts/format.py +0 -0
  14. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/scripts/test.py +0 -0
  15. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/__init__.py +0 -0
  16. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/conftest.py +0 -0
  17. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_fast_test.py +0 -0
  18. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_functions.py +0 -0
  19. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_lint.py +0 -0
  20. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_poetry_version_plugin.py +0 -0
  21. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_runserver.py +0 -0
  22. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_sync.py +0 -0
  23. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_tag.py +0 -0
  24. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_upgrade.py +0 -0
  25. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_upload.py +0 -0
  26. {fast_dev_cli-0.15.1 → fast_dev_cli-0.16.0}/tests/test_version.py +0 -0
  27. {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.15.1
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
- from packaging.utils import canonicalize_name
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 toml_text is None:
126
- toml_text = Project.load_toml_text()
127
- pattern = re.compile(r"version\s*=")
128
- invalid = ("0", "0.0.0")
129
- for line in toml_text.splitlines():
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
- lib_version = _parse_version(line, pattern)
132
- if lib_version.startswith("{") or lib_version in invalid:
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 emoji.is_emoji(first_char)
285
+ return is_emoji(first_char)
259
286
 
260
287
  @staticmethod
261
- def parse_filename() -> str:
262
- toml_text = Project.load_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 Project.get_work_dir()
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 Project.get_work_dir().joinpath(filename).exists():
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 init_file.exists() and pattern.search(init_file.read_text("utf8")):
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.15.1"
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").write_text("""
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