fast-dev-cli 0.7.2__tar.gz → 0.8.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.
@@ -1,24 +1,34 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fast-dev-cli
3
- Version: 0.7.2
4
- Summary:
5
- Author: Waket Zheng
6
- Author-email: waketzheng@gmail.com
7
- Requires-Python: >=3.10,<4.0
8
- Classifier: Programming Language :: Python :: 3
3
+ Version: 0.8.0
4
+ Summary: Python project development tool.
5
+ Author-Email: Waket Zheng <waketzheng@gmail.com>>
6
+ Classifier: Development Status :: 4 - Beta
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: Intended Audience :: Science/Research
9
+ Classifier: Intended Audience :: System Administrators
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3 :: Only
9
12
  Classifier: Programming Language :: Python :: 3.10
10
13
  Classifier: Programming Language :: Python :: 3.11
11
14
  Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Classifier: Topic :: Software Development
18
+ Classifier: Typing :: Typed
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Project-URL: Homepage, https://github.com/waketzheng/fast-dev-cli
21
+ Requires-Python: <3.13,>=3.10
22
+ Requires-Dist: typer<0.13,>=0.12.3
23
+ Requires-Dist: typing-extensions>=4.8.0
24
+ Requires-Dist: coverage<8,>=7.5.1
25
+ Requires-Dist: ruff<0.5,>=0.4.4
26
+ Requires-Dist: mypy<2,>=1.10.0
27
+ Requires-Dist: bumpversion<0.7,>=0.6.0
28
+ Requires-Dist: pytest<9,>=8.2.0
29
+ Requires-Dist: ipython<9,>=8.24.0; extra == "all"
30
+ Requires-Dist: pytest-mock<4,>=3.14.0; extra == "all"
12
31
  Provides-Extra: all
13
- Requires-Dist: bumpversion (>=0.6.0,<0.7.0) ; extra == "all"
14
- Requires-Dist: click (>=7.1.1)
15
- Requires-Dist: coverage (>=6.5.0) ; extra == "all"
16
- Requires-Dist: mypy (>=1.10.0,<2.0.0) ; extra == "all"
17
- Requires-Dist: pytest (>=8.2.0,<9.0.0) ; extra == "all"
18
- Requires-Dist: ruff (>=0.4.2,<0.5.0) ; extra == "all"
19
- Requires-Dist: strenum (>=0.4.15) ; python_version < "3.11"
20
- Requires-Dist: type-extensions (>=0.1.2) ; python_version < "3.11"
21
- Requires-Dist: typer (>=0.12.3,<0.13.0) ; extra == "all"
22
32
  Description-Content-Type: text/markdown
23
33
 
24
34
  <p align="center">
@@ -54,17 +64,16 @@ Description-Content-Type: text/markdown
54
64
 
55
65
  ## Requirements
56
66
 
57
- Python 3.11+
67
+ Python 3.10+
58
68
 
59
69
  ## Installation
60
70
 
61
71
  <div class="termy">
62
72
 
63
- ```console
64
- $ pip install "fast-dev-cli[all]"
65
- ---> 100%
66
- Successfully installed fast-dev-cli isort black ruff mypy typer bumpversion pytest coverage
73
+ ```bash
74
+ pip install "fast-dev-cli"
67
75
  ```
76
+ *Will install: fast-dev-cli typer ruff mypy bumpversion pytest coverage*
68
77
 
69
78
  </div>
70
79
 
@@ -94,4 +103,7 @@ fast sync
94
103
  ```bash
95
104
  fast upgrade
96
105
  ```
97
-
106
+ - Start a fastapi server in development mode
107
+ ```bash
108
+ fast dev
109
+ ```
@@ -31,17 +31,16 @@
31
31
 
32
32
  ## Requirements
33
33
 
34
- Python 3.11+
34
+ Python 3.10+
35
35
 
36
36
  ## Installation
37
37
 
38
38
  <div class="termy">
39
39
 
40
- ```console
41
- $ pip install "fast-dev-cli[all]"
42
- ---> 100%
43
- Successfully installed fast-dev-cli isort black ruff mypy typer bumpversion pytest coverage
40
+ ```bash
41
+ pip install "fast-dev-cli"
44
42
  ```
43
+ *Will install: fast-dev-cli typer ruff mypy bumpversion pytest coverage*
45
44
 
46
45
  </div>
47
46
 
@@ -71,3 +70,7 @@ fast sync
71
70
  ```bash
72
71
  fast upgrade
73
72
  ```
73
+ - Start a fastapi server in development mode
74
+ ```bash
75
+ fast dev
76
+ ```
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- import importlib.metadata
3
+ import importlib.metadata as importlib_metadata
4
4
  import os
5
5
  import re
6
6
  import subprocess
@@ -8,75 +8,40 @@ import sys
8
8
  from functools import cached_property
9
9
  from pathlib import Path
10
10
  from subprocess import CompletedProcess
11
- from typing import TYPE_CHECKING, Optional, Type
11
+ from typing import TYPE_CHECKING, Literal, Optional, Type
12
+
13
+ import typer
14
+ from typer import Exit, Option, echo, secho
12
15
 
13
16
  if sys.version_info >= (3, 11):
14
17
  from enum import StrEnum
15
18
  from typing import Self
16
19
  else: # pragma: no cover
17
- from strenum import StrEnum # type:ignore[no-redef,assignment]
20
+ from enum import Enum
21
+
18
22
  from typing_extensions import Self
19
23
 
20
- if TYPE_CHECKING:
24
+ class StrEnum(str, Enum):
25
+ __str__ = str.__str__
26
+
27
+
28
+ if TYPE_CHECKING: # pragma: no cover
21
29
  from typer.models import OptionInfo
22
30
 
23
31
 
24
- __version__ = importlib.metadata.version(Path(__file__).parent.name)
32
+ __version__ = "0.8.0"
25
33
 
26
34
 
27
35
  def parse_files(args: list[str] | tuple[str, ...]) -> list[str]:
28
36
  return [i for i in args if not i.startswith("-")]
29
37
 
30
38
 
31
- try:
32
- import typer
33
- from typer import Exit, Option, echo, secho
34
-
35
- cli = typer.Typer()
36
- if len(sys.argv) >= 2 and sys.argv[1] == "lint":
37
- if not parse_files(sys.argv[2:]):
38
- sys.argv.append(".")
39
- except ModuleNotFoundError:
40
- import click
41
- from click import echo, secho
42
- from click.core import Group as _Group
43
- from click.exceptions import Exit
44
-
45
- def Option(default, *shortcuts, help=None): # type:ignore[no-redef]
46
- return default
47
-
48
- def _command(self, *args, **kwargs):
49
- from click.decorators import command
50
-
51
- def decorator(f):
52
- if kwargs.get("name") == "lint":
53
- import functools
54
-
55
- def auto_fill_args(func):
56
- @functools.wraps(func)
57
- def runner(*arguments: str, **kw):
58
- if "files" not in kw and not parse_files(arguments):
59
- arguments = (".",)
60
- return func(*arguments, **kw)
61
-
62
- return runner
63
-
64
- f = auto_fill_args(f)
65
- if sys.argv[2:]:
66
- f = click.argument("files", nargs=-1)(f)
67
- cmd = command(*args, **kwargs)(f)
68
- self.add_command(cmd)
69
- return cmd
70
-
71
- return decorator
72
-
73
- _Group.command = _command # type:ignore
74
-
75
- @click.group()
76
- def cli() -> None: ... # pragma: no cover
77
-
39
+ if len(sys.argv) >= 2 and sys.argv[1] == "lint":
40
+ if not parse_files(sys.argv[2:]):
41
+ sys.argv.append(".")
78
42
 
79
43
  TOML_FILE = "pyproject.toml"
44
+ cli = typer.Typer()
80
45
 
81
46
 
82
47
  def load_bool(name: str, default=False) -> bool:
@@ -98,6 +63,7 @@ def _run_shell(cmd: str, **kw) -> CompletedProcess:
98
63
 
99
64
 
100
65
  def run_and_echo(cmd: str, *, dry=False, verbose=True, **kw) -> int:
66
+ """Run shell command with subprocess and print it"""
101
67
  if verbose:
102
68
  echo(f"--> {cmd}")
103
69
  if dry:
@@ -117,11 +83,18 @@ def capture_cmd_output(command: list[str] | str, **kw) -> str:
117
83
  return r.stdout.strip().decode()
118
84
 
119
85
 
120
- def get_current_version(verbose=False) -> str:
86
+ def get_current_version(
87
+ verbose=False,
88
+ is_poetry: bool | None = None,
89
+ package_name=Path(__file__).parent.name,
90
+ ) -> str:
91
+ if is_poetry is None:
92
+ is_poetry = Project.manage_by_poetry()
93
+ if not is_poetry:
94
+ return importlib_metadata.version(package_name)
121
95
  cmd = ["poetry", "version", "-s"]
122
96
  if verbose:
123
- command = " ".join(cmd)
124
- echo(f"--> {command}")
97
+ echo(f"--> {' '.join(cmd)}")
125
98
  return capture_cmd_output(cmd)
126
99
 
127
100
 
@@ -166,13 +139,25 @@ class BumpUp(DryRun):
166
139
  major = "major"
167
140
 
168
141
  def __init__(
169
- self: Self, commit: bool, part: str, filename=TOML_FILE, dry=False
142
+ self: Self, commit: bool, part: str, filename: str | None = None, dry=False
170
143
  ) -> None:
171
144
  self.commit = commit
172
145
  self.part = part
146
+ if filename is None:
147
+ filename = self.parse_filename()
173
148
  self.filename = filename
174
149
  super().__init__(dry=dry)
175
150
 
151
+ @staticmethod
152
+ def parse_filename() -> str:
153
+ if not Project.manage_by_poetry():
154
+ # version = { source = "file", path = "fast_dev_cli/cli.py" }
155
+ for line in Project.load_toml_text().splitlines():
156
+ if not line.startswith("version = "):
157
+ continue
158
+ return line.split('path = "', 1)[-1].split('"')[0]
159
+ return TOML_FILE
160
+
176
161
  def get_part(self, s: str) -> str:
177
162
  choices: dict[str, str] = {}
178
163
  for i, p in enumerate(self.PartChoices, 1):
@@ -231,7 +216,7 @@ def bump_version(
231
216
  dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
232
217
  ) -> None:
233
218
  """Bump up version string in pyproject.toml"""
234
- return BumpUp(_ensure_bool(commit), part.value, dry=dry).run()
219
+ return BumpUp(_ensure_bool(commit), getattr(part, "value", part), dry=dry).run()
235
220
 
236
221
 
237
222
  def bump() -> None:
@@ -246,7 +231,8 @@ def bump() -> None:
246
231
  return BumpUp(commit, part, dry="--dry" in args).run()
247
232
 
248
233
 
249
- class EnvError(Exception): ...
234
+ class EnvError(Exception):
235
+ """Raise when expected to be managed by poetry, but toml file not found."""
250
236
 
251
237
 
252
238
  class Project:
@@ -276,6 +262,23 @@ class Project:
276
262
  toml_file = cls.get_work_dir().resolve() / TOML_FILE # to be optimize
277
263
  return toml_file.read_text("utf8")
278
264
 
265
+ @classmethod
266
+ def manage_by_poetry(cls: Type[Self]) -> bool:
267
+ return "[tool.poetry]" in cls.load_toml_text()
268
+
269
+ @classmethod
270
+ def get_manage_tool(cls: Type[Self]) -> Literal["poetry", "pdm", ""]:
271
+ try:
272
+ text = cls.load_toml_text()
273
+ except EnvError:
274
+ pass
275
+ else:
276
+ if "[tool.poetry]" in text:
277
+ return "poetry"
278
+ elif "[tool.pdm]" in text:
279
+ return "pdm"
280
+ return ""
281
+
279
282
  @staticmethod
280
283
  def python_exec_dir() -> Path:
281
284
  return Path(sys.executable).parent
@@ -396,6 +399,10 @@ class UpgradeDependencies(Project, DryRun):
396
399
  if toml_text is None:
397
400
  toml_text = cls.load_toml_text()
398
401
  main_title = "[tool.poetry.dependencies]"
402
+ if main_title not in toml_text:
403
+ raise EnvError(
404
+ f"{main_title} not found! Make sure this is a poetry project."
405
+ )
399
406
  text = toml_text.split(main_title)[-1]
400
407
  dev_flag = "--group dev"
401
408
  new_flag, old_flag = cls.DevFlag.new, cls.DevFlag.old
@@ -458,7 +465,8 @@ class GitTag(DryRun):
458
465
  self.message = message
459
466
  super().__init__(dry=dry)
460
467
 
461
- def has_v_prefix(self: Self) -> bool:
468
+ @staticmethod
469
+ def has_v_prefix() -> bool:
462
470
  return "v" in capture_cmd_output("git tag")
463
471
 
464
472
  def should_push(self: Self) -> bool:
@@ -512,24 +520,28 @@ class LintCode(DryRun):
512
520
  @classmethod
513
521
  def to_cmd(cls: Type[Self], paths=".", check_only=False) -> str:
514
522
  cmd = ""
515
- tools = ["ruff check --extend-select=I --fix", "ruff format", "mypy"]
523
+ tools = ["ruff format", "ruff check --extend-select=I --fix", "mypy"]
516
524
  if check_only:
517
- tools[1] += " --check"
525
+ tools[0] += " --check"
518
526
  if check_only or load_bool("NO_FIX"):
519
- tools[0] = tools[0].replace(" --fix", "")
527
+ tools[1] = tools[1].replace(" --fix", "")
520
528
  if load_bool("SKIP_MYPY"):
521
529
  # Sometimes mypy is too slow
522
530
  tools = tools[:-1]
523
531
  lint_them = " && ".join("{0}{%d} {1}" % i for i in range(2, len(tools) + 2))
524
- prefix = "poetry run "
532
+ prefix = ""
533
+ should_run_by_tool = False
525
534
  if is_venv():
526
- if cls.check_lint_tool_installed():
527
- prefix = ""
528
- else:
535
+ if not cls.check_lint_tool_installed():
536
+ should_run_by_tool = True
529
537
  if check_call("python -c 'import fast_dev_cli'"):
530
- command = 'python -m pip install -U "fast_dev_cli[all]"'
531
- tip = "You may need to run the following command to install lint tools"
538
+ command = 'python -m pip install -U "fast_dev_cli"'
539
+ tip = "You may need to run following command to install lint tools"
532
540
  secho(f"{tip}:\n\n {command}\n", fg="yellow")
541
+ else:
542
+ should_run_by_tool = True
543
+ if should_run_by_tool:
544
+ prefix = Project.get_manage_tool() + " run "
533
545
  cmd += lint_them.format(prefix, paths, *tools)
534
546
  return cmd
535
547
 
@@ -614,15 +626,6 @@ def _should_run_test_script(path: Path) -> bool:
614
626
  return path.exists()
615
627
 
616
628
 
617
- @cli.command(name="test")
618
- def coverage_test(
619
- dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
620
- ignore_script: bool = Option(False, "--ignore-script", "-i"),
621
- ) -> None:
622
- """Run unittest by pytest and report coverage"""
623
- return test(dry, ignore_script)
624
-
625
-
626
629
  def test(dry: bool, ignore_script=False) -> None:
627
630
  cwd = Path.cwd()
628
631
  root = Project.get_work_dir(cwd=cwd, allow_cwd=True)
@@ -635,10 +638,20 @@ def test(dry: bool, ignore_script=False) -> None:
635
638
  cmd = 'coverage run -m pytest -s && coverage report --omit="tests/*" -m'
636
639
  if not is_venv() or not check_call("coverage --version"):
637
640
  sep = " && "
638
- cmd = sep.join("poetry run " + i for i in cmd.split(sep))
641
+ tool = Project.get_manage_tool()
642
+ cmd = sep.join(f"{tool} run " + i for i in cmd.split(sep))
639
643
  exit_if_run_failed(cmd, dry=dry)
640
644
 
641
645
 
646
+ @cli.command(name="test")
647
+ def coverage_test(
648
+ dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
649
+ ignore_script: bool = Option(False, "--ignore-script", "-i"),
650
+ ) -> None:
651
+ """Run unittest by pytest and report coverage"""
652
+ return test(dry, ignore_script)
653
+
654
+
642
655
  @cli.command()
643
656
  def upload(
644
657
  dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
@@ -668,9 +681,9 @@ def runserver(
668
681
  host: Optional[str] = Option(None, "-h", "--host"),
669
682
  dry: bool = Option(False, "--dry", help="Only print, not really run shell command"),
670
683
  ) -> None:
671
- """Check code style without reformat"""
684
+ """Start a fastapi server(only for fastapi>=0.111.0)"""
672
685
  dev(port, host, dry=dry)
673
686
 
674
687
 
675
- if __name__ == "__main__":
676
- cli() # pragma: no cover
688
+ if __name__ == "__main__": # pragma: no cover
689
+ cli()
@@ -0,0 +1,39 @@
1
+ import os
2
+ from typing import Any, Dict, List
3
+
4
+ from pdm.backend.hooks import Context
5
+
6
+ BUILD_PACKAGE = os.getenv("BUILD_PACKAGE", "fast-dev-cli")
7
+
8
+
9
+ def pdm_build_initialize(context: Context) -> None:
10
+ metadata = context.config.metadata
11
+ # Get custom config for the current package, from the env var
12
+ config: Dict[str, Any] = context.config.data["tool"]["waketzheng"][
13
+ "_internal-slim-build"
14
+ ]["packages"][BUILD_PACKAGE]
15
+ project_config: Dict[str, Any] = config["project"]
16
+ # Get main optional dependencies, extras
17
+ optional_dependencies: Dict[str, List[str]] = metadata.get(
18
+ "optional-dependencies", {}
19
+ )
20
+ # Get custom optional dependencies name to always include in this (non-slim) package
21
+ include_optional_dependencies: List[str] = config.get(
22
+ "include-optional-dependencies", []
23
+ )
24
+ # Override main [project] configs with custom configs for this package
25
+ for key, value in project_config.items():
26
+ metadata[key] = value
27
+ # Get custom build config for the current package
28
+ build_config: Dict[str, Any] = (
29
+ config.get("tool", {}).get("pdm", {}).get("build", {})
30
+ )
31
+ # Override PDM build config with custom build config for this package
32
+ for key, value in build_config.items():
33
+ context.config.build_config[key] = value
34
+ # Get main dependencies
35
+ dependencies: List[str] = metadata.get("dependencies", [])
36
+ # Add optional dependencies to the default dependencies for this (non-slim) package
37
+ for include_optional in include_optional_dependencies:
38
+ optional_dependencies_group = optional_dependencies.get(include_optional, [])
39
+ dependencies.extend(optional_dependencies_group)
@@ -0,0 +1,142 @@
1
+ [build-system]
2
+ requires = [
3
+ "pdm-backend",
4
+ ]
5
+ build-backend = "pdm.backend"
6
+
7
+ [project]
8
+ name = "fast-dev-cli"
9
+ dynamic = []
10
+ description = "Python project development tool."
11
+ authors = [
12
+ { name = "Waket Zheng", email = "waketzheng@gmail.com>" },
13
+ ]
14
+ readme = "README.md"
15
+ requires-python = ">=3.10,<3.13"
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "Intended Audience :: Science/Research",
20
+ "Intended Audience :: System Administrators",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Topic :: Software Development :: Libraries :: Python Modules",
27
+ "Topic :: Software Development :: Libraries",
28
+ "Topic :: Software Development",
29
+ "Typing :: Typed",
30
+ "License :: OSI Approved :: MIT License",
31
+ ]
32
+ dependencies = [
33
+ "typer>=0.12.3,<0.13",
34
+ "typing-extensions>=4.8.0",
35
+ "coverage >=7.5.1,<8",
36
+ "ruff >=0.4.4,<0.5",
37
+ "mypy >=1.10.0,<2",
38
+ "bumpversion >=0.6.0,<0.7",
39
+ "pytest >=8.2.0,<9",
40
+ ]
41
+ version = "0.8.0"
42
+
43
+ [project.urls]
44
+ Homepage = "https://github.com/waketzheng/fast-dev-cli"
45
+
46
+ [project.optional-dependencies]
47
+ all = [
48
+ "ipython >=8.24.0,<9",
49
+ "pytest-mock >=3.14.0,<4",
50
+ ]
51
+
52
+ [project.scripts]
53
+ fast = "fast_dev_cli:cli.cli"
54
+
55
+ [tool.pdm]
56
+ distribution = true
57
+
58
+ [tool.pdm.version]
59
+ source = "file"
60
+ path = "fast_dev_cli/cli.py"
61
+
62
+ [tool.pdm.build]
63
+ source-includes = [
64
+ "scripts/",
65
+ ]
66
+
67
+ [tool.pdm.dev-dependencies]
68
+ dev = [
69
+ "-e file:///${PROJECT_ROOT}/#egg=fast-dev-cli[standard,all]",
70
+ ]
71
+
72
+ [tool.waketzheng._internal-slim-build.packages.fastdevcli-slim.project]
73
+ name = "fastdevcli-slim"
74
+
75
+ [tool.waketzheng._internal-slim-build.packages.fast-dev-cli]
76
+ include-optional-dependencies = [
77
+ "standard",
78
+ ]
79
+
80
+ [tool.waketzheng._internal-slim-build.packages.fast-dev-cli.project.optional-dependencies]
81
+ all = [
82
+ "ipython >=8.24.0,<9",
83
+ "pytest-mock >=3.14.0,<4",
84
+ ]
85
+
86
+ [tool.waketzheng._internal-slim-build.packages.fast-dev-cli.project.scripts]
87
+ fast = "fast_dev_cli:cli.cli"
88
+
89
+ [tool.pytest.ini_options]
90
+ testpaths = [
91
+ "tests",
92
+ ]
93
+
94
+ [tool.coverage.run]
95
+ parallel = true
96
+ source = [
97
+ "fast_dev_cli",
98
+ ]
99
+ omit = [
100
+ "__pypackages__/*",
101
+ ".venv/*",
102
+ "venv*.bak/*",
103
+ ]
104
+ context = "${CONTEXT}"
105
+
106
+ [tool.coverage.report]
107
+ exclude_lines = [
108
+ "pragma: no cover",
109
+ "@overload",
110
+ "if __name__ == \"__main__\":",
111
+ "if TYPE_CHECKING:",
112
+ ]
113
+ omit = [
114
+ "tests/*",
115
+ ]
116
+
117
+ [tool.mypy]
118
+ pretty = true
119
+ ignore_missing_imports = true
120
+ check_untyped_defs = true
121
+ exclude = [
122
+ "^fabfile\\.py$",
123
+ "two\\.pyi$",
124
+ "^\\.venv",
125
+ "\\.bak",
126
+ "__pypackages__",
127
+ ]
128
+
129
+ [tool.ruff.lint]
130
+ extend-select = [
131
+ "E",
132
+ "W",
133
+ "F",
134
+ "I",
135
+ "B",
136
+ "C4",
137
+ ]
138
+
139
+ [tool.ruff.lint.per-file-ignores]
140
+ "test_*.py" = [
141
+ "E501",
142
+ ]
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+ set -x
5
+
6
+ [ -f ../pyproject.toml ] && cd ..
7
+
8
+ pdm run fast check || \
9
+ echo -e "\033[1m Please run './scripts/format.sh' to auto-fix style issues \033[0m"
@@ -0,0 +1,6 @@
1
+ #!/bin/sh -e
2
+ set -x
3
+
4
+ [ -f ../pyproject.toml ] && cd ..
5
+
6
+ pdm run fast lint
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+ pdm run fast test --ignore-script
File without changes
@@ -1,6 +1,16 @@
1
+ from pathlib import Path
2
+
3
+ import pytest
4
+
5
+ from fast_dev_cli.cli import TOML_FILE
6
+
7
+ from .utils import chdir
8
+
9
+ # toml file content before migrate to pdm
10
+ TOML_CONTENT = """
1
11
  [tool.poetry]
2
12
  name = "fast-dev-cli"
3
- version = "0.7.2"
13
+ version = "0.8.0"
4
14
  description = ""
5
15
  authors = ["Waket Zheng <waketzheng@gmail.com>"]
6
16
  readme = "README.md"
@@ -12,7 +22,7 @@ click = ">=7.1.1" # Many package depends on click, so only limit min version
12
22
  strenum = {version = ">=0.4.15", python = "<3.11"}
13
23
  type-extensions = {version = ">=0.1.2", python = "<3.11"}
14
24
  coverage = {version = ">=6.5.0", optional = true}
15
- ruff = {version = "^0.4.2", optional = true}
25
+ ruff = {version = "^0.4.4", optional = true}
16
26
  mypy = {version = "^1.10.0", optional = true}
17
27
  bumpversion = {version = "^0.6.0", optional = true}
18
28
  pytest = {version = "^8.2.0", optional = true}
@@ -25,7 +35,7 @@ all = ["ruff", "typer", "mypy", "bumpversion", "pytest", "coverage"]
25
35
  coveralls = {version = ">=4.0.0", python = ">=3.10,<3.13"}
26
36
  coverage = ">=6.5.0" # use >= to compare with coveralls
27
37
  typer = "^0.12.3"
28
- ruff = "^0.4.2"
38
+ ruff = "^0.4.4"
29
39
  mypy = "^1.10.0"
30
40
  pytest = "^8.2.0"
31
41
  ipython = "^8.24.0"
@@ -37,14 +47,11 @@ strenum = "^0.4.15"
37
47
  [build-system]
38
48
  requires = ["poetry-core"]
39
49
  build-backend = "poetry.core.masonry.api"
50
+ """
40
51
 
41
- [tool.poetry.scripts]
42
- fast = "fast_dev_cli:cli.cli"
43
-
44
- [tool.mypy]
45
- pretty = true
46
- ignore_missing_imports = true
47
- check_untyped_defs = true
48
52
 
49
- [tool.ruff.lint.per-file-ignores]
50
- "test_*.py" = ["E501"]
53
+ @pytest.fixture
54
+ def tmp_poetry_project(tmp_path: Path):
55
+ with chdir(tmp_path):
56
+ tmp_path.joinpath(TOML_FILE).write_text(TOML_CONTENT)
57
+ yield