fast-dev-cli 0.17.1__tar.gz → 0.17.3__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 (31) hide show
  1. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/PKG-INFO +6 -6
  2. fast_dev_cli-0.17.3/fast_dev_cli/__init__.py +1 -0
  3. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/fast_dev_cli/cli.py +213 -15
  4. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/pyproject.toml +6 -8
  5. fast_dev_cli-0.17.3/tests/test_deps.py +33 -0
  6. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_help.py +1 -1
  7. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_lint.py +11 -3
  8. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_version.py +4 -4
  9. fast_dev_cli-0.17.1/fast_dev_cli/__init__.py +0 -1
  10. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/LICENSE +0 -0
  11. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/README.md +0 -0
  12. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/fast_dev_cli/__main__.py +0 -0
  13. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/fast_dev_cli/py.typed +0 -0
  14. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/pdm_build.py +0 -0
  15. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/scripts/check.py +0 -0
  16. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/scripts/deps.py +0 -0
  17. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/scripts/format.py +0 -0
  18. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/scripts/test.py +0 -0
  19. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/__init__.py +0 -0
  20. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/conftest.py +0 -0
  21. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_bump.py +0 -0
  22. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_exec.py +0 -0
  23. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_fast_test.py +0 -0
  24. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_functions.py +0 -0
  25. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_poetry_version_plugin.py +0 -0
  26. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_runserver.py +0 -0
  27. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_sync.py +0 -0
  28. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_tag.py +0 -0
  29. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_upgrade.py +0 -0
  30. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/test_upload.py +0 -0
  31. {fast_dev_cli-0.17.1 → fast_dev_cli-0.17.3}/tests/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fast-dev-cli
3
- Version: 0.17.1
3
+ Version: 0.17.3
4
4
  Summary: Python project development tool.
5
5
  Author-Email: Waket Zheng <waketzheng@gmail.com>>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -24,12 +24,12 @@ Project-URL: Homepage, https://github.com/waketzheng/fast-dev-cli
24
24
  Requires-Python: >=3.9
25
25
  Requires-Dist: typer<1,>=0.12.3
26
26
  Requires-Dist: tomli<3,>=2.0.1; python_version < "3.11"
27
- Requires-Dist: emoji<3,>=2.12.1
27
+ Requires-Dist: emoji>=2.12.1
28
28
  Requires-Dist: packaging>=20.5
29
- Requires-Dist: coverage<8,>=7.5.1
30
- Requires-Dist: mypy<2,>=1.15.0
31
- Requires-Dist: bumpversion2<2,>=1.4.3
32
- Requires-Dist: pytest<9,>=8.2.0
29
+ Requires-Dist: coverage>=7.5.1
30
+ Requires-Dist: mypy>=1.15.0
31
+ Requires-Dist: bumpversion2>=1.4.3
32
+ Requires-Dist: pytest>=8.2.0
33
33
  Provides-Extra: include-optional-dependencies
34
34
  Requires-Dist: all; extra == "include-optional-dependencies"
35
35
  Description-Content-Type: text/markdown
@@ -0,0 +1 @@
1
+ __version__ = "0.17.3"
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import contextlib
4
+ import functools
4
5
  import importlib.metadata as importlib_metadata
5
6
  import os
6
7
  import re
@@ -21,6 +22,7 @@ from typing import (
21
22
  )
22
23
 
23
24
  import typer
25
+ from click import UsageError
24
26
  from typer import Exit, Option, echo, secho
25
27
  from typer.models import ArgumentInfo, OptionInfo
26
28
 
@@ -89,6 +91,10 @@ def is_emoji(char: str) -> bool:
89
91
  return not "\u4e00" <= char <= "\u9fff" # Chinese character
90
92
 
91
93
 
94
+ def yellow_warn(msg: str) -> None:
95
+ secho(msg, fg="yellow")
96
+
97
+
92
98
  def load_bool(name: str, default: bool = False) -> bool:
93
99
  if not (v := os.getenv(name)):
94
100
  return default
@@ -281,7 +287,7 @@ def exit_if_run_failed(
281
287
 
282
288
  class DryRun:
283
289
  def __init__(self, _exit: bool = False, dry: bool = False) -> None:
284
- self.dry = dry
290
+ self.dry = _ensure_bool(dry)
285
291
  self._exit = _exit
286
292
 
287
293
  def gen(self) -> str:
@@ -922,6 +928,7 @@ class LintCode(DryRun):
922
928
  skip_mypy: bool = False,
923
929
  dmypy: bool = False,
924
930
  tool: str = ToolOption.default,
931
+ prefix: bool = False,
925
932
  ) -> None:
926
933
  self.args = args
927
934
  self.check_only = check_only
@@ -929,6 +936,7 @@ class LintCode(DryRun):
929
936
  self._skip_mypy = skip_mypy
930
937
  self._use_dmypy = dmypy
931
938
  self._tool = tool
939
+ self._prefix = prefix
932
940
  super().__init__(_exit, dry)
933
941
 
934
942
  @staticmethod
@@ -962,6 +970,7 @@ class LintCode(DryRun):
962
970
  skip_mypy: bool = False,
963
971
  use_dmypy: bool = False,
964
972
  tool: str = ToolOption.default,
973
+ with_prefix: bool = False,
965
974
  ) -> str:
966
975
  if paths != "." and all(i.endswith(".html") for i in paths.split()):
967
976
  return f"prettier -w {paths}"
@@ -991,23 +1000,28 @@ class LintCode(DryRun):
991
1000
  for i, tool in enumerate(tools, 2)
992
1001
  )
993
1002
  prefix = ""
994
- should_run_by_tool = False
995
- if is_venv() and Path(sys.argv[0]).parent != Path.home().joinpath(".local/bin"):
996
- if not ruff_exists:
1003
+ should_run_by_tool = with_prefix
1004
+ if not should_run_by_tool:
1005
+ if is_venv() and Path(sys.argv[0]).parent != Path.home().joinpath(
1006
+ ".local/bin"
1007
+ ):
1008
+ if not ruff_exists:
1009
+ should_run_by_tool = True
1010
+ if check_call('python -c "import fast_dev_cli"'):
1011
+ command = 'python -m pip install -U "fast-dev-cli"'
1012
+ yellow_warn(
1013
+ "You may need to run the following command"
1014
+ f" to install lint tools:\n\n {command}\n"
1015
+ )
1016
+ else:
997
1017
  should_run_by_tool = True
998
- if check_call('python -c "import fast_dev_cli"'):
999
- command = 'python -m pip install -U "fast-dev-cli"'
1000
- tip = "You may need to run following command to install lint tools:"
1001
- secho(f"{tip}\n\n {command}\n", fg="yellow")
1002
- else:
1003
- should_run_by_tool = True
1004
1018
  if should_run_by_tool and tool:
1005
1019
  if tool == ToolOption.default:
1006
1020
  tool = Project.get_manage_tool() or ""
1007
1021
  if tool:
1008
1022
  prefix = (
1009
- str(bin_dir)
1010
- if tool == "uv" and (bin_dir := Path(".venv/bin/")).exists()
1023
+ bin_dir
1024
+ if tool == "uv" and Path(bin_dir := ".venv/bin/").exists()
1011
1025
  else (tool + " run ")
1012
1026
  )
1013
1027
  if cls.prefer_dmypy(paths, tools, use_dmypy=use_dmypy):
@@ -1030,7 +1044,13 @@ class LintCode(DryRun):
1030
1044
  args = args.split()
1031
1045
  paths = " ".join(map(str, args)) if args else "."
1032
1046
  return self.to_cmd(
1033
- paths, self.check_only, self._bandit, self._skip_mypy, self._use_dmypy
1047
+ paths,
1048
+ self.check_only,
1049
+ self._bandit,
1050
+ self._skip_mypy,
1051
+ self._use_dmypy,
1052
+ tool=self._tool,
1053
+ with_prefix=self._prefix,
1034
1054
  )
1035
1055
 
1036
1056
 
@@ -1045,13 +1065,20 @@ def lint(
1045
1065
  skip_mypy: bool = False,
1046
1066
  dmypy: bool = False,
1047
1067
  tool: str = ToolOption.default,
1068
+ prefix: bool = False,
1048
1069
  ) -> None:
1049
1070
  if files is None:
1050
1071
  files = parse_files(sys.argv[1:])
1051
1072
  if files and files[0] == "lint":
1052
1073
  files = files[1:]
1053
1074
  LintCode(
1054
- files, dry=dry, skip_mypy=skip_mypy, bandit=bandit, dmypy=dmypy, tool=tool
1075
+ files,
1076
+ dry=dry,
1077
+ skip_mypy=skip_mypy,
1078
+ bandit=bandit,
1079
+ dmypy=dmypy,
1080
+ tool=tool,
1081
+ prefix=prefix,
1055
1082
  ).run()
1056
1083
 
1057
1084
 
@@ -1080,6 +1107,11 @@ def make_style(
1080
1107
  files: Optional[list[str]] = typer.Argument(default=None), # noqa:B008
1081
1108
  check_only: bool = Option(False, "--check-only", "-c"),
1082
1109
  bandit: bool = Option(False, "--bandit", help="Run `bandit -r <package_dir>`"),
1110
+ prefix: bool = Option(
1111
+ False,
1112
+ "--prefix",
1113
+ help="Run lint command with tool prefix, e.g.: pdm run ruff ...",
1114
+ ),
1083
1115
  skip_mypy: bool = Option(False, "--skip-mypy"),
1084
1116
  use_dmypy: bool = Option(
1085
1117
  False, "--dmypy", help="Use `dmypy run` instead of `mypy`"
@@ -1095,11 +1127,20 @@ def make_style(
1095
1127
  skip = _ensure_bool(skip_mypy)
1096
1128
  dmypy = _ensure_bool(use_dmypy)
1097
1129
  bandit = _ensure_bool(bandit)
1130
+ prefix = _ensure_bool(prefix)
1098
1131
  tool = _ensure_str(tool)
1099
1132
  if _ensure_bool(check_only):
1100
1133
  check(files, dry=dry, skip_mypy=skip, dmypy=dmypy, bandit=bandit, tool=tool)
1101
1134
  else:
1102
- lint(files, dry=dry, skip_mypy=skip, dmypy=dmypy, bandit=bandit, tool=tool)
1135
+ lint(
1136
+ files,
1137
+ dry=dry,
1138
+ skip_mypy=skip,
1139
+ dmypy=dmypy,
1140
+ bandit=bandit,
1141
+ tool=tool,
1142
+ prefix=prefix,
1143
+ )
1103
1144
 
1104
1145
 
1105
1146
  @cli.command(name="check")
@@ -1278,6 +1319,163 @@ def run_by_subprocess(cmd: str, dry: bool = DryOption) -> None:
1278
1319
  raise Exit(rc)
1279
1320
 
1280
1321
 
1322
+ class MakeDeps(DryRun):
1323
+ def __init__(self, tool: str, prod: bool = False, dry: bool = False) -> None:
1324
+ self._tool = tool
1325
+ self._prod = prod
1326
+ super().__init__(dry=dry)
1327
+
1328
+ def should_ensure_pip(self) -> bool:
1329
+ return True
1330
+
1331
+ def should_upgrade_pip(self) -> bool:
1332
+ return True
1333
+
1334
+ def get_groups(self) -> list[str]:
1335
+ if self._prod:
1336
+ return []
1337
+ return ["dev"]
1338
+
1339
+ def gen(self) -> str:
1340
+ if self._tool == "pdm":
1341
+ return "pdm sync " + ("--prod" if self._prod else "-G :all")
1342
+ elif self._tool == "uv":
1343
+ return "uv sync --inexact --active" + (
1344
+ "" if self._prod else " --all-extras --all-groups"
1345
+ )
1346
+ elif self._tool == "poetry":
1347
+ return "poetry install " + (
1348
+ "--only=main" if self._prod else "--all-extras --all-groups"
1349
+ )
1350
+ else:
1351
+ cmd = "python -m pip install -e ."
1352
+ if gs := self.get_groups():
1353
+ cmd += " " + " ".join(f"--group {g}" for g in gs)
1354
+ upgrade = "python -m pip install --upgrade pip"
1355
+ if self.should_ensure_pip():
1356
+ cmd = f"python -m ensurepip && {upgrade} && {cmd}"
1357
+ elif self.should_upgrade_pip():
1358
+ cmd = "{upgrade} && {cmd}"
1359
+ return cmd
1360
+
1361
+
1362
+ @cli.command(name="deps")
1363
+ def make_deps(
1364
+ prod: bool = Option(
1365
+ False,
1366
+ "--prod",
1367
+ help="Only instead production dependencies.",
1368
+ ),
1369
+ tool: str = ToolOption,
1370
+ use_uv: bool = Option(False, "--uv", help="Use `uv` to install deps"),
1371
+ use_pdm: bool = Option(False, "--pdm", help="Use `pdm` to install deps"),
1372
+ use_pip: bool = Option(False, "--pip", help="Use `pip` to install deps"),
1373
+ use_poetry: bool = Option(False, "--poetry", help="Use `poetry` to install deps"),
1374
+ dry: bool = DryOption,
1375
+ ) -> None:
1376
+ """Run: ruff check/format to reformat code and then mypy to check"""
1377
+ if use_uv + use_pdm + use_pip + use_poetry > 1:
1378
+ raise UsageError("`--uv/--pdm/--pip/--poetry` can only choose one!")
1379
+ if use_uv:
1380
+ tool = "uv"
1381
+ elif use_pdm:
1382
+ tool = "pdm"
1383
+ elif use_pip:
1384
+ tool = "pip"
1385
+ elif use_poetry:
1386
+ tool = "poetry"
1387
+ elif tool == ToolOption.default:
1388
+ tool = Project.get_manage_tool(cache=True) or "pip"
1389
+ MakeDeps(tool, prod, dry=dry).run()
1390
+
1391
+
1392
+ class UvPypi(DryRun):
1393
+ PYPI = "https://pypi.org/simple"
1394
+ HOST = "https://files.pythonhosted.org"
1395
+
1396
+ def __init__(self, lock_file: Path, dry: bool, verbose: bool, quiet: bool) -> None:
1397
+ super().__init__(dry=dry)
1398
+ self.lock_file = lock_file
1399
+ self._verbose = _ensure_bool(verbose)
1400
+ self._quiet = _ensure_bool(quiet)
1401
+
1402
+ def run(self) -> None:
1403
+ try:
1404
+ rc = self.update_lock(self.lock_file, self._verbose, self._quiet)
1405
+ except ValueError as e:
1406
+ secho(str(e), fg=typer.colors.RED)
1407
+ raise Exit(1) from e
1408
+ else:
1409
+ if rc != 0:
1410
+ raise Exit(rc)
1411
+
1412
+ @classmethod
1413
+ def update_lock(cls, p: Path, verbose: bool, quiet: bool) -> int:
1414
+ text = p.read_text("utf-8")
1415
+ registry_pattern = r'(registry = ")(.*?)"'
1416
+ replace_registry = functools.partial(
1417
+ re.sub, registry_pattern, rf'\1{cls.PYPI}"'
1418
+ )
1419
+ registry_urls = {i[1] for i in re.findall(registry_pattern, text)}
1420
+ download_pattern = r'(url = ")(https?://.*?)(/packages/.*?\.)(gz|whl)"'
1421
+ replace_host = functools.partial(
1422
+ re.sub, download_pattern, rf'\1{cls.HOST}\3\4"'
1423
+ )
1424
+ download_hosts = {i[1] for i in re.findall(download_pattern, text)}
1425
+ if not registry_urls:
1426
+ raise ValueError(f"Failed to find pattern {registry_pattern!r} in {p}")
1427
+ if len(registry_urls) == 1:
1428
+ current_registry = registry_urls.pop()
1429
+ if current_registry == cls.PYPI:
1430
+ if download_hosts == {cls.HOST}:
1431
+ if verbose:
1432
+ echo(f"Registry of {p} is {cls.PYPI}, no need to change.")
1433
+ return 0
1434
+ else:
1435
+ text = replace_registry(text)
1436
+ if verbose:
1437
+ echo(f"{current_registry} --> {cls.PYPI}")
1438
+ else:
1439
+ # TODO: ask each one to confirm replace
1440
+ text = replace_registry(text)
1441
+ if verbose:
1442
+ for current_registry in sorted(registry_urls):
1443
+ echo(f"{current_registry} --> {cls.PYPI}")
1444
+ if len(download_hosts) == 1:
1445
+ current_host = download_hosts.pop()
1446
+ if current_host != cls.HOST:
1447
+ text = replace_host(text)
1448
+ if verbose:
1449
+ print(current_host, "-->", cls.HOST)
1450
+ elif download_hosts:
1451
+ # TODO: ask each one to confirm replace
1452
+ text = replace_host(text)
1453
+ if verbose:
1454
+ for current_host in sorted(download_hosts):
1455
+ echo(f"{current_host} --> {cls.HOST}")
1456
+ size = p.write_text(text, encoding="utf-8")
1457
+ if verbose:
1458
+ echo(f"Updated {p} with {size} bytes.")
1459
+ if quiet:
1460
+ return 0
1461
+ return 1
1462
+
1463
+
1464
+ @cli.command()
1465
+ def pypi(
1466
+ dry: bool = DryOption,
1467
+ verbose: bool = False,
1468
+ quiet: bool = False,
1469
+ ) -> None:
1470
+ """Change registry of uv.lock to be pypi.org"""
1471
+ if not (p := Path("uv.lock")).exists() and not (
1472
+ (p := Project.get_work_dir() / p.name).exists()
1473
+ ):
1474
+ yellow_warn(f"{p.name!r} not found!")
1475
+ return
1476
+ UvPypi(p, dry, verbose, quiet).run()
1477
+
1478
+
1281
1479
  def version_callback(value: bool) -> None:
1282
1480
  if value:
1283
1481
  echo("Fast Dev Cli Version: " + typer.style(__version__, bold=True))
@@ -35,14 +35,14 @@ classifiers = [
35
35
  dependencies = [
36
36
  "typer >=0.12.3,<1",
37
37
  "tomli >=2.0.1,<3; python_version < '3.11'",
38
- "emoji >=2.12.1,<3",
38
+ "emoji >=2.12.1",
39
39
  "packaging >=20.5",
40
- "coverage >=7.5.1,<8",
41
- "mypy >=1.15.0,<2",
42
- "bumpversion2 >=1.4.3,<2",
43
- "pytest >=8.2.0,<9",
40
+ "coverage >=7.5.1",
41
+ "mypy >=1.15.0",
42
+ "bumpversion2 >=1.4.3",
43
+ "pytest >=8.2.0",
44
44
  ]
45
- version = "0.17.1"
45
+ version = "0.17.3"
46
46
 
47
47
  [project.urls]
48
48
  Homepage = "https://github.com/waketzheng/fast-dev-cli"
@@ -58,8 +58,6 @@ fast = "fast_dev_cli:cli.main"
58
58
  [dependency-groups]
59
59
  dev = [
60
60
  "twine>=6.1.0",
61
- ]
62
- test = [
63
61
  "asynctor>=0.8.6",
64
62
  ]
65
63
 
@@ -0,0 +1,33 @@
1
+ from fast_dev_cli.cli import MakeDeps, capture_cmd_output
2
+
3
+
4
+ def test_make_deps_class():
5
+ assert (
6
+ MakeDeps("uv", prod=False).gen()
7
+ == "uv sync --inexact --active --all-extras --all-groups"
8
+ )
9
+ assert MakeDeps("uv", prod=True).gen() == "uv sync --inexact --active"
10
+ assert MakeDeps("pdm", prod=False).gen() == "pdm sync -G :all"
11
+ assert MakeDeps("pdm", prod=True).gen() == "pdm sync --prod"
12
+ assert (
13
+ MakeDeps("poetry", prod=False).gen()
14
+ == "poetry install --all-extras --all-groups"
15
+ )
16
+ assert MakeDeps("poetry", prod=True).gen() == "poetry install --only=main"
17
+ assert (
18
+ MakeDeps("pip", prod=False).gen()
19
+ == "python -m ensurepip && python -m pip install --upgrade pip && python -m pip install -e . --group dev"
20
+ )
21
+ assert (
22
+ MakeDeps("pip", prod=True).gen()
23
+ == "python -m ensurepip && python -m pip install --upgrade pip && python -m pip install -e ."
24
+ )
25
+
26
+
27
+ def test_fast_deps():
28
+ out = capture_cmd_output("fast deps --dry")
29
+ assert out == "--> pdm sync -G :all"
30
+ out = capture_cmd_output("fast deps --uv --prod --dry")
31
+ assert out == "--> uv sync --inexact --active"
32
+ out = capture_cmd_output("fast deps --uv --dry")
33
+ assert out == "--> uv sync --inexact --active --all-extras --all-groups"
@@ -4,4 +4,4 @@ from asynctor import Shell
4
4
  def test_help():
5
5
  out = Shell("fast").capture_output()
6
6
  out_help = Shell("fast --help").capture_output()
7
- assert out == out_help
7
+ assert out.strip() == out_help.strip()
@@ -99,7 +99,7 @@ def test_check_bandit(tmp_path):
99
99
  assert "bandit -r ." in command
100
100
 
101
101
 
102
- def test_check_skip_mypy(mock_skip_mypy_0, mocker, capsys):
102
+ def test_check_skip_mypy(mock_skip_mypy_0, mocker):
103
103
  cmd = "fast check --skip-mypy --dry"
104
104
  cmd2 = "fast lint --check-only --skip-mypy --dry"
105
105
  mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
@@ -187,6 +187,14 @@ def test_lint_with_prefix(mocker):
187
187
  assert "pdm run" in stream.getvalue()
188
188
 
189
189
 
190
+ def test_fast_lint_with_uv():
191
+ command = capture_cmd_output("fast lint --tool=uv --prefix --dry")
192
+ assert (
193
+ command
194
+ == "--> ruff format . && ruff check --extend-select=I,B,SIM --fix . && .venv/bin/mypy ."
195
+ )
196
+
197
+
190
198
  def test_make_style(mock_skip_mypy_0, mocker, mock_no_dmypy):
191
199
  mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
192
200
  with capture_stdout() as stream:
@@ -239,7 +247,7 @@ def test_lint_without_ruff_installed(mocker, mock_no_dmypy):
239
247
  output = stream.getvalue()
240
248
  cmd = 'python -m pip install -U "fast-dev-cli"'
241
249
  assert cmd in output
242
- tip = "You may need to run following command to install lint tools"
250
+ tip = "You may need to run the following command to install lint tools"
243
251
  assert tip in output
244
252
  assert f"{tip}:\n\n {cmd}" in output
245
253
 
@@ -263,7 +271,7 @@ def test_skip_mypy_option(mock_skip_mypy_0, mocker):
263
271
  )
264
272
 
265
273
 
266
- def test_skip_mypy_fast_lint(mock_skip_mypy_0, mocker, capsys):
274
+ def test_skip_mypy_fast_lint(mock_skip_mypy_0, mocker):
267
275
  mocker.patch("fast_dev_cli.cli.is_venv", return_value=True)
268
276
  command = capture_cmd_output("fast lint --skip-mypy --dry")
269
277
  cmds = LINT_CMD.split(SEP)
@@ -67,12 +67,12 @@ def test_display_self_version(capsys):
67
67
  version_callback(True)
68
68
  assert __version__ in capsys.readouterr().out
69
69
  out = Shell("fast --version").capture_output().strip()
70
- assert out == "Fast Dev Cli Version: 0.17.0"
70
+ assert out == f"Fast Dev Cli Version: {__version__}"
71
71
  out_v = Shell("fast -V").capture_output().strip()
72
72
  assert out_v == out
73
73
 
74
74
 
75
- def test_fast_version(capsys):
75
+ def test_fast_version():
76
76
  out = Shell("fast version").capture_output().strip()
77
- assert "Fast Dev Cli Version: 0.17.0" in out
78
- assert "fast_dev_cli/__init__.py: 0.17.0" in out
77
+ assert f"Fast Dev Cli Version: {__version__}" in out
78
+ assert f"fast_dev_cli/__init__.py: {__version__}" in out
@@ -1 +0,0 @@
1
- __version__ = "0.17.1"
File without changes
File without changes