crackerjack 0.10.8__tar.gz → 0.11.2__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 (47) hide show
  1. {crackerjack-0.10.8 → crackerjack-0.11.2}/PKG-INFO +5 -5
  2. crackerjack-0.11.2/crackerjack/.pdm.toml +1 -0
  3. crackerjack-0.11.2/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  4. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/__main__.py +1 -2
  5. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/crackerjack.py +49 -75
  6. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/pyproject.toml +15 -5
  7. {crackerjack-0.10.8 → crackerjack-0.11.2}/pyproject.toml +15 -5
  8. crackerjack-0.11.2/tests/test_crackerjack.py +174 -0
  9. crackerjack-0.11.2/tests/test_main.py +142 -0
  10. crackerjack-0.10.8/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  11. {crackerjack-0.10.8 → crackerjack-0.11.2}/LICENSE +0 -0
  12. {crackerjack-0.10.8 → crackerjack-0.11.2}/README.md +0 -0
  13. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.gitignore +0 -0
  14. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.libcst.codemod.yaml +0 -0
  15. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.pre-commit-config.yaml +0 -0
  16. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/.gitignore +0 -0
  17. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
  18. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
  19. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
  20. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
  21. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
  22. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
  23. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
  24. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
  25. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
  26. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
  27. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
  28. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
  29. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
  30. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
  31. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
  32. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
  33. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
  34. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
  35. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
  36. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
  37. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
  38. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
  39. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
  40. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
  41. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
  42. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
  43. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
  44. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
  45. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
  46. {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/__init__.py +0 -0
  47. {crackerjack-0.10.8 → crackerjack-0.11.2}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crackerjack
3
- Version: 0.10.8
3
+ Version: 0.11.2
4
4
  Summary: Default template for PDM package
5
5
  Keywords: black,ruff,mypy,creosote,refurb
6
6
  Author-Email: lesleslie <les@wedgwoodwebworks.com>
@@ -23,17 +23,17 @@ Project-URL: documentation, https://github.com/lesleslie/crackerjack
23
23
  Project-URL: repository, https://github.com/lesleslie/crackerjack
24
24
  Requires-Python: >=3.13
25
25
  Requires-Dist: click>=8.1.8
26
- Requires-Dist: aioconsole>=0.8.1
27
- Requires-Dist: inflection>=0.5.1
28
26
  Requires-Dist: autotyping>=24.9.0
29
27
  Requires-Dist: pre-commit>=4.0.1
30
28
  Requires-Dist: pytest>=8.3.4
31
29
  Requires-Dist: pydantic>=2.10.4
32
- Requires-Dist: aiopath>=0.7.7
33
30
  Requires-Dist: pdm-bump>=0.9.10
34
31
  Requires-Dist: pdm>=2.22.1
35
- Requires-Dist: acb>=0.8.0
36
32
  Requires-Dist: uv>=0.5.13
33
+ Requires-Dist: pytest-cov>=6.0.0
34
+ Requires-Dist: pytest-mock>=3.14.0
35
+ Requires-Dist: tomli-w>=1.2.0
36
+ Requires-Dist: pytest-asyncio>=0.25.3
37
37
  Description-Content-Type: text/markdown
38
38
 
39
39
  # Crackerjack Python
@@ -0,0 +1 @@
1
+ test crackerjack config
@@ -1,4 +1,3 @@
1
- import asyncio
2
1
  import typing as t
3
2
 
4
3
  from click import command, help_option, option
@@ -58,7 +57,7 @@ def crackerjack(
58
57
  if v:
59
58
  print("-v not currently implemented")
60
59
  options.verbose = v
61
- asyncio.run(crackerjack_it(options=options))
60
+ crackerjack_it(options=options)
62
61
 
63
62
 
64
63
  if __name__ == "__main__":
@@ -1,43 +1,35 @@
1
- import asyncio
2
1
  import re
3
- import sys
4
2
  import typing as t
5
3
  from pathlib import Path
6
4
  from subprocess import run as execute
5
+ from tomllib import loads
7
6
 
8
- from acb.actions.encode import dump, load
9
- from aioconsole import ainput, aprint
10
- from aiopath import AsyncPath
11
- from inflection import underscore
12
7
  from pydantic import BaseModel
13
-
14
-
15
- class Config(BaseModel):
16
- python_version: str = "3.13"
8
+ from tomli_w import dumps
17
9
 
18
10
 
19
11
  class Crackerjack(BaseModel, arbitrary_types_allowed=True):
20
- our_path: AsyncPath = AsyncPath(__file__).parent
21
- pkg_path: AsyncPath = AsyncPath(Path.cwd())
22
- settings_path: AsyncPath = pkg_path / ".crackerjack.yaml"
23
- pkg_dir: t.Optional[AsyncPath] = None
12
+ our_path: Path = Path(__file__).parent
13
+ pkg_path: Path = Path(Path.cwd())
14
+ pkg_dir: t.Optional[Path] = None
24
15
  pkg_name: str = "crackerjack"
25
16
  our_toml: t.Optional[dict[str, t.Any]] = None
26
17
  pkg_toml: t.Optional[dict[str, t.Any]] = None
27
- our_toml_path: t.Optional[AsyncPath] = None
28
- pkg_toml_path: t.Optional[AsyncPath] = None
29
- config: t.Optional[Config] = None
18
+ our_toml_path: t.Optional[Path] = None
19
+ pkg_toml_path: t.Optional[Path] = None
20
+ python_version: str = "3.13"
30
21
 
31
- async def update_pyproject_configs(self) -> None:
22
+ def update_pyproject_configs(self) -> None:
32
23
  toml_file = "pyproject.toml"
33
24
  self.our_toml_path = self.our_path / toml_file
34
25
  self.pkg_toml_path = self.pkg_path / toml_file
35
26
  if self.pkg_path.stem == "crackerjack":
36
- await self.our_toml_path.write_text(await self.pkg_toml_path.read_text())
27
+ self.our_toml_path.write_text(self.pkg_toml_path.read_text())
37
28
  return
38
- our_toml_config: t.Any = await load.toml(self.our_toml_path) # type: ignore
39
- pkg_toml_config: t.Any = await load.toml(self.pkg_toml_path) # type: ignore
40
- pkg_deps = pkg_toml_config["dependency-groups"]
29
+ our_toml_config: t.Any = loads(self.our_toml_path.read_text())
30
+ pkg_toml_config: t.Any = loads(self.pkg_toml_path.read_text())
31
+ pkg_toml_config.setdefault("tool", {})
32
+ pkg_toml_config.setdefault("project", {})
41
33
  for tool, settings in our_toml_config["tool"].items():
42
34
  for setting, value in settings.items():
43
35
  if isinstance(value, str | list) and "crackerjack" in value:
@@ -54,54 +46,50 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
54
46
  "skips",
55
47
  "ignore",
56
48
  ) and isinstance(value, list):
57
- settings[setting] = set(
58
- pkg_toml_config["tool"][tool][setting] + value
59
- )
49
+ conf = pkg_toml_config["tool"].get(tool, {}).get(setting, [])
50
+ settings[setting] = list(set(conf + value))
60
51
  pkg_toml_config["tool"][tool] = settings
61
- pkg_toml_config["dependency-groups"] = pkg_deps
62
52
  python_version_pattern = r"\s*W*(\d\.\d*)"
63
53
  requires_python = our_toml_config["project"]["requires-python"]
64
54
  classifiers = []
65
- for classifier in pkg_toml_config["project"]["classifiers"]:
55
+ for classifier in pkg_toml_config["project"].get("classifiers", []):
66
56
  classifier = re.sub(
67
- python_version_pattern, f" {self.config.python_version}", classifier
57
+ python_version_pattern, f" {self.python_version}", classifier
68
58
  )
69
59
  classifiers.append(classifier)
70
60
  pkg_toml_config["project"]["classifiers"] = classifiers
71
61
  pkg_toml_config["project"]["requires-python"] = requires_python
72
- await dump.toml(pkg_toml_config, self.pkg_toml_path) # type: ignore
62
+ self.pkg_toml_path.write_text(dumps(pkg_toml_config))
73
63
 
74
- async def copy_configs(self) -> None:
64
+ def copy_configs(self) -> None:
75
65
  config_files = (".gitignore", ".pre-commit-config.yaml", ".libcst.codemod.yaml")
76
66
  for config in config_files:
77
67
  config_path = self.our_path / config
78
68
  pkg_config_path = self.pkg_path / config
79
- await pkg_config_path.touch(exist_ok=True)
69
+ pkg_config_path.touch()
80
70
  if self.pkg_path.stem == "crackerjack":
81
- await config_path.write_text(await pkg_config_path.read_text())
71
+ config_path.write_text(pkg_config_path.read_text())
82
72
  continue
83
73
  if config != ".gitignore":
84
- await pkg_config_path.write_text(
85
- (await config_path.read_text()).replace(
86
- "crackerjack", self.pkg_name
87
- )
74
+ pkg_config_path.write_text(
75
+ (config_path.read_text()).replace("crackerjack", self.pkg_name)
88
76
  )
89
77
  execute(["git", "add", config])
90
78
 
91
- async def run_interactive(self, hook: str) -> None:
79
+ def run_interactive(self, hook: str) -> None:
92
80
  success: bool = False
93
81
  while not success:
94
82
  fail = execute(["pre-commit", "run", hook.lower(), "--all-files"])
95
83
  if fail.returncode > 0:
96
- retry = await ainput(f"\n\n{hook.title()} failed. Retry? (y/N): ")
97
- await aprint()
84
+ retry = input(f"\n\n{hook.title()} failed. Retry? (y/N): ")
85
+ print()
98
86
  if retry.strip().lower() == "y":
99
87
  continue
100
- sys.exit()
88
+ raise SystemExit(1)
101
89
  success = True
102
90
 
103
- async def update_pkg_configs(self) -> None:
104
- await self.copy_configs()
91
+ def update_pkg_configs(self) -> None:
92
+ self.copy_configs()
105
93
  installed_pkgs = execute(
106
94
  ["pdm", "list", "--freeze"],
107
95
  capture_output=True,
@@ -117,71 +105,57 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
117
105
  execute(["git", "add", "pdm.lock"])
118
106
  execute(["pre-commit", "install"])
119
107
  execute(["git", "config", "advice.addIgnoredFile", "false"])
120
- await self.update_pyproject_configs()
121
-
122
- async def load_config(self) -> None:
123
- await self.settings_path.touch(exist_ok=True)
124
- try:
125
- self.config = Config(**await load.yaml(self.settings_path))
126
- except TypeError:
127
- self.config = Config()
128
- await dump.yaml(self.config.model_dump(), self.settings_path)
129
- raise SystemExit("\nPlease configure '.crackerjack.yaml' and try again\n")
108
+ self.update_pyproject_configs()
130
109
 
131
- async def run_pre_commit(self) -> None:
110
+ def run_pre_commit(self) -> None:
132
111
  check_all = execute(["pre-commit", "run", "--all-files"])
133
112
  if check_all.returncode > 0:
134
113
  check_all = execute(["pre-commit", "run", "--all-files"])
135
114
  if check_all.returncode > 0:
136
- await aprint("\n\nPre-commit failed. Please fix errors.\n")
137
- raise SystemExit()
115
+ print("\n\nPre-commit failed. Please fix errors.\n")
116
+ raise SystemExit(1)
138
117
 
139
- async def process(self, options: t.Any) -> None:
140
- self.pkg_name = underscore(self.pkg_path.stem.lower())
118
+ def process(self, options: t.Any) -> None:
119
+ self.pkg_name = self.pkg_path.stem.lower().replace("-", "_")
141
120
  self.pkg_dir = self.pkg_path / self.pkg_name
142
- await self.pkg_dir.mkdir(exist_ok=True)
143
- await aprint("\nCrackerjacking...\n")
121
+ self.pkg_dir.mkdir(exist_ok=True)
122
+ print("\nCrackerjacking...\n")
144
123
  if not options.do_not_update_configs:
145
- await self.update_pkg_configs()
124
+ self.update_pkg_configs()
146
125
  execute(["pdm", "install"])
147
126
  if self.pkg_path.stem == "crackerjack" and options.update_precommit:
148
127
  execute(["pre-commit", "autoupdate"])
149
128
  if options.interactive:
150
129
  for hook in ("refurb", "bandit", "pyright"):
151
- await self.run_interactive(hook)
152
- await self.run_pre_commit()
130
+ self.run_interactive(hook)
131
+ self.run_pre_commit()
153
132
  for option in (options.publish, options.bump):
154
133
  if option:
155
134
  execute(["pdm", "bump", option])
156
135
  break
157
136
  if options.publish:
158
137
  build = execute(["pdm", "build"], capture_output=True, text=True)
159
- await aprint(build.stdout)
138
+ print(build.stdout)
160
139
  if build.returncode > 0:
161
- await aprint(build.stderr)
162
- await aprint("\n\nBuild failed. Please fix errors.\n")
163
- raise SystemExit()
140
+ print(build.stderr)
141
+ print("\n\nBuild failed. Please fix errors.\n")
142
+ raise SystemExit(1)
164
143
  execute(["pdm", "publish", "--no-build"])
165
144
  if options.commit:
166
- commit_msg = await ainput("\nCommit message: ")
145
+ commit_msg = input("\nCommit message: ")
167
146
  execute(
168
147
  [
169
148
  "git",
170
149
  "commit",
171
150
  "-m",
172
- str(commit_msg),
151
+ commit_msg,
173
152
  "--no-verify",
174
153
  "--",
175
154
  ".",
176
155
  ]
177
156
  )
178
157
  execute(["git", "push", "origin", "main"])
179
- await aprint("\nCrackerjack complete!\n")
180
-
181
- async def run(self, options: t.Any) -> None:
182
- await self.load_config()
183
- process = asyncio.create_task(self.process(options))
184
- await process
158
+ print("\nCrackerjack complete!\n")
185
159
 
186
160
 
187
- crackerjack_it = Crackerjack().run
161
+ crackerjack_it = Crackerjack().process
@@ -1,3 +1,7 @@
1
+ [tool.pytest.ini_options]
2
+ addopts = "--cov=crackerjack"
3
+ asyncio_default_fixture_loop_scope = "function"
4
+
1
5
  [tool.codespell]
2
6
  skip = "*/data/*"
3
7
  quiet-level = 3
@@ -9,6 +13,7 @@ target-version = "py313"
9
13
  fix = true
10
14
  show-fixes = true
11
15
  output-format = "full"
16
+ unsafe-fixes = true
12
17
 
13
18
  [tool.ruff.format]
14
19
  docstring-code-format = true
@@ -57,6 +62,9 @@ exclude-deps = [
57
62
  "autotyping",
58
63
  "pre-commit",
59
64
  "pytest",
65
+ "pytest-asyncio",
66
+ "pytest-cov",
67
+ "pytest-mock",
60
68
  "pdm",
61
69
  "pyfiglet",
62
70
  "pyyaml",
@@ -72,6 +80,7 @@ target = [
72
80
  "crackerjack",
73
81
  ]
74
82
  skips = [
83
+ "B101",
75
84
  "B301",
76
85
  "B311",
77
86
  "B403",
@@ -79,6 +88,7 @@ skips = [
79
88
  "B602",
80
89
  "B603",
81
90
  "B607",
91
+ "B704",
82
92
  ]
83
93
 
84
94
  [tool.pyright]
@@ -105,7 +115,7 @@ pythonPlatform = "Darwin"
105
115
 
106
116
  [project]
107
117
  name = "crackerjack"
108
- version = "0.10.7"
118
+ version = "0.11.1"
109
119
  description = "Default template for PDM package"
110
120
  requires-python = ">=3.13"
111
121
  readme = "README.md"
@@ -132,17 +142,17 @@ classifiers = [
132
142
  ]
133
143
  dependencies = [
134
144
  "click>=8.1.8",
135
- "aioconsole>=0.8.1",
136
- "inflection>=0.5.1",
137
145
  "autotyping>=24.9.0",
138
146
  "pre-commit>=4.0.1",
139
147
  "pytest>=8.3.4",
140
148
  "pydantic>=2.10.4",
141
- "aiopath>=0.7.7",
142
149
  "pdm-bump>=0.9.10",
143
150
  "pdm>=2.22.1",
144
- "acb>=0.8.0",
145
151
  "uv>=0.5.13",
152
+ "pytest-cov>=6.0.0",
153
+ "pytest-mock>=3.14.0",
154
+ "tomli-w>=1.2.0",
155
+ "pytest-asyncio>=0.25.3",
146
156
  ]
147
157
  authors = [
148
158
  { name = "lesleslie", email = "les@wedgwoodwebworks.com" },
@@ -1,3 +1,7 @@
1
+ [tool.pytest.ini_options]
2
+ addopts = "--cov=crackerjack"
3
+ asyncio_default_fixture_loop_scope = "function"
4
+
1
5
  [tool.codespell]
2
6
  skip = "*/data/*"
3
7
  quiet-level = 3
@@ -9,6 +13,7 @@ target-version = "py313"
9
13
  fix = true
10
14
  show-fixes = true
11
15
  output-format = "full"
16
+ unsafe-fixes = true
12
17
 
13
18
  [tool.ruff.format]
14
19
  docstring-code-format = true
@@ -59,6 +64,9 @@ exclude-deps = [
59
64
  "autotyping",
60
65
  "pre-commit",
61
66
  "pytest",
67
+ "pytest-asyncio",
68
+ "pytest-cov",
69
+ "pytest-mock",
62
70
  "pdm",
63
71
  "pyfiglet",
64
72
  "pyyaml",
@@ -74,6 +82,7 @@ target = [
74
82
  "crackerjack",
75
83
  ]
76
84
  skips = [
85
+ "B101",
77
86
  "B301",
78
87
  "B311",
79
88
  "B403",
@@ -81,6 +90,7 @@ skips = [
81
90
  "B602",
82
91
  "B603",
83
92
  "B607",
93
+ "B704",
84
94
  ]
85
95
 
86
96
  [tool.pyright]
@@ -107,7 +117,7 @@ pythonPlatform = "Darwin"
107
117
 
108
118
  [project]
109
119
  name = "crackerjack"
110
- version = "0.10.8"
120
+ version = "0.11.2"
111
121
  description = "Default template for PDM package"
112
122
  requires-python = ">=3.13"
113
123
  readme = "README.md"
@@ -134,17 +144,17 @@ classifiers = [
134
144
  ]
135
145
  dependencies = [
136
146
  "click>=8.1.8",
137
- "aioconsole>=0.8.1",
138
- "inflection>=0.5.1",
139
147
  "autotyping>=24.9.0",
140
148
  "pre-commit>=4.0.1",
141
149
  "pytest>=8.3.4",
142
150
  "pydantic>=2.10.4",
143
- "aiopath>=0.7.7",
144
151
  "pdm-bump>=0.9.10",
145
152
  "pdm>=2.22.1",
146
- "acb>=0.8.0",
147
153
  "uv>=0.5.13",
154
+ "pytest-cov>=6.0.0",
155
+ "pytest-mock>=3.14.0",
156
+ "tomli-w>=1.2.0",
157
+ "pytest-asyncio>=0.25.3",
148
158
  ]
149
159
  authors = [
150
160
  { name = "lesleslie", email = "les@wedgwoodwebworks.com" },
@@ -0,0 +1,174 @@
1
+ import typing as t
2
+ from pathlib import Path
3
+ from unittest.mock import MagicMock, call, patch
4
+
5
+ import pytest
6
+ from crackerjack.__main__ import options
7
+ from crackerjack.crackerjack import Crackerjack
8
+
9
+
10
+ @pytest.fixture
11
+ def mock_execute() -> t.Generator[t.Any, t.Any, t.Any]:
12
+ with patch("crackerjack.crackerjack.execute") as mock:
13
+ yield mock
14
+
15
+
16
+ @pytest.fixture
17
+ def mock_subprocess_run() -> t.Generator[t.Any, t.Any, t.Any]:
18
+ with patch("subprocess.run") as mock:
19
+ yield mock
20
+
21
+
22
+ @pytest.fixture
23
+ def mock_print() -> t.Generator[t.Any, t.Any, t.Any]:
24
+ with patch("builtins.print") as mock:
25
+ yield mock
26
+
27
+
28
+ @pytest.fixture
29
+ def mock_input() -> t.Generator[t.Any, t.Any, t.Any]:
30
+ with patch("builtins.input") as mock:
31
+ yield mock
32
+
33
+
34
+ @pytest.fixture(autouse=True)
35
+ def reset_options() -> None:
36
+ """Resets the options before each test."""
37
+ options.commit = False
38
+ options.interactive = False
39
+ options.doc = False
40
+ options.update_precommit = False
41
+ options.do_not_update_configs = False
42
+ options.publish = False
43
+ options.bump = False
44
+ options.verbose = False
45
+
46
+
47
+ @pytest.fixture
48
+ def tmp_path_package(tmp_path: Path) -> Path:
49
+ return tmp_path / "my-package"
50
+
51
+
52
+ @pytest.fixture
53
+ def create_package_dir(tmp_path_package: Path) -> None:
54
+ (tmp_path_package / "my_package").mkdir(parents=True)
55
+ (tmp_path_package / "pyproject.toml").touch()
56
+ (tmp_path_package / ".gitignore").touch()
57
+ (tmp_path_package / ".pre-commit-config.yaml").touch()
58
+ (tmp_path_package / ".libcst.codemod.yaml").touch()
59
+
60
+
61
+ class TestCrackerjackProcess:
62
+ def test_process_all_options(
63
+ self,
64
+ mock_execute: MagicMock,
65
+ mock_print: MagicMock,
66
+ mock_input: MagicMock,
67
+ mock_subprocess_run: MagicMock,
68
+ tmp_path: Path,
69
+ tmp_path_package: Path,
70
+ create_package_dir: None,
71
+ ) -> None:
72
+ mock_input.return_value = "Test Commit"
73
+ mock_execute.return_value.returncode = 0
74
+ mock_execute.return_value.stdout = "Mock Build Output"
75
+ mock_subprocess_run.return_value.returncode = 0
76
+ mock_execute.return_value.stderr = ""
77
+ mock_subprocess_run.return_value.stdout = ""
78
+ mock_subprocess_run.return_value.stderr = ""
79
+ crackerjack_instance = Crackerjack(pkg_path=tmp_path_package)
80
+ options_mock = MagicMock()
81
+ options_mock.do_not_update_configs = False
82
+ options_mock.update_precommit = True
83
+ options_mock.interactive = True
84
+ options_mock.commit = False
85
+ options_mock.publish = None
86
+ options_mock.bump = None
87
+ crackerjack_instance.process(options_mock)
88
+
89
+ assert crackerjack_instance.pkg_name == "my_package"
90
+ (tmp_path_package / "my_package").exists()
91
+ mock_execute.assert_has_calls(
92
+ [
93
+ call(["pdm", "self", "add", "keyring"]),
94
+ call(["pdm", "config", "python.use_uv", "true"]),
95
+ call(["git", "init"]),
96
+ call(["git", "branch", "-m", "main"]),
97
+ call(["git", "add", "pyproject.toml"]),
98
+ call(["git", "add", "pdm.lock"]),
99
+ call(["pre-commit", "install"]),
100
+ call(["git", "config", "advice.addIgnoredFile", "false"]),
101
+ call(["pdm", "install"]),
102
+ call(["pre-commit", "run", "refurb", "--all-files"]),
103
+ call(["pre-commit", "run", "bandit", "--all-files"]),
104
+ call(["pre-commit", "run", "pyright", "--all-files"]),
105
+ call(["pre-commit", "run", "--all-files"]),
106
+ call(["git", "add", ".gitignore"]),
107
+ call(["git", "add", ".pre-commit-config.yaml"]),
108
+ call(["git", "add", ".libcst.codemod.yaml"]),
109
+ ],
110
+ any_order=True,
111
+ )
112
+
113
+ def test_process_no_options(
114
+ self,
115
+ mock_execute: MagicMock,
116
+ mock_print: MagicMock,
117
+ mock_subprocess_run: MagicMock,
118
+ tmp_path_package: Path,
119
+ create_package_dir: None,
120
+ ) -> None:
121
+ mock_execute.return_value.returncode = 0
122
+ mock_subprocess_run.return_value.returncode = 0
123
+ crackerjack_instance = Crackerjack(pkg_path=tmp_path_package)
124
+ options_mock = MagicMock()
125
+ options_mock.do_not_update_configs = True
126
+ options_mock.update_precommit = False
127
+ options_mock.interactive = False
128
+ options_mock.publish = None
129
+ options_mock.bump = None
130
+ options_mock.commit = False
131
+
132
+ crackerjack_instance.process(options_mock)
133
+
134
+ assert crackerjack_instance.pkg_name == "my_package"
135
+ (tmp_path_package / "my_package").exists()
136
+ mock_execute.assert_has_calls(
137
+ [
138
+ call(["pre-commit", "run", "--all-files"]),
139
+ ]
140
+ )
141
+
142
+ def test_process_interactive_hooks(
143
+ self,
144
+ mock_execute: MagicMock,
145
+ mock_print: MagicMock,
146
+ mock_subprocess_run: MagicMock,
147
+ tmp_path_package: Path,
148
+ create_package_dir: None,
149
+ ) -> None:
150
+ mock_execute.return_value.returncode = 0
151
+ mock_subprocess_run.return_value.returncode = 0
152
+
153
+ crackerjack_instance = Crackerjack(pkg_path=tmp_path_package)
154
+ options_mock = MagicMock()
155
+ options_mock.do_not_update_configs = False
156
+ options_mock.update_precommit = False
157
+ options_mock.interactive = True
158
+ options_mock.publish = None
159
+ options_mock.bump = None
160
+ options_mock.commit = False
161
+
162
+ crackerjack_instance.process(options_mock)
163
+
164
+ assert crackerjack_instance.pkg_name == "my_package"
165
+ (tmp_path_package / "my_package").exists()
166
+
167
+ mock_execute.assert_has_calls(
168
+ [
169
+ call(["pre-commit", "run", "refurb", "--all-files"]),
170
+ call(["pre-commit", "run", "bandit", "--all-files"]),
171
+ call(["pre-commit", "run", "pyright", "--all-files"]),
172
+ call(["pre-commit", "run", "--all-files"]),
173
+ ]
174
+ )
@@ -0,0 +1,142 @@
1
+ import typing as t
2
+
3
+ import pytest
4
+ from click.testing import CliRunner
5
+ from crackerjack.__main__ import crackerjack, options
6
+ from crackerjack.crackerjack import Crackerjack
7
+
8
+
9
+ @pytest.fixture(autouse=True)
10
+ def mock_crackerjack_it(monkeypatch: pytest.MonkeyPatch) -> None:
11
+ def mock_process(self: Crackerjack, options: t.Any) -> None:
12
+ pass
13
+
14
+ monkeypatch.setattr(Crackerjack, "process", mock_process)
15
+
16
+
17
+ @pytest.fixture
18
+ def runner() -> CliRunner:
19
+ return CliRunner()
20
+
21
+
22
+ @pytest.fixture(autouse=True)
23
+ def reset_options() -> None:
24
+ options.commit = False
25
+ options.interactive = False
26
+ options.doc = False
27
+ options.update_precommit = False
28
+ options.do_not_update_configs = False
29
+ options.publish = False
30
+ options.bump = False
31
+ options.verbose = False
32
+
33
+
34
+ def test_no_options(runner: CliRunner) -> None:
35
+ result = runner.invoke(crackerjack)
36
+ assert result.exit_code == 0
37
+ assert not options.commit
38
+ assert not options.interactive
39
+ assert not options.doc
40
+ assert not options.update_precommit
41
+ assert not options.do_not_update_configs
42
+ assert options.publish is False
43
+ assert options.bump is False
44
+ assert not options.verbose
45
+
46
+
47
+ def test_commit_option(runner: CliRunner) -> None:
48
+ result = runner.invoke(crackerjack, ["-c"])
49
+ assert result.exit_code == 1
50
+ assert options.commit
51
+
52
+
53
+ def test_interactive_option(runner: CliRunner) -> None:
54
+ result = runner.invoke(crackerjack, ["-i"])
55
+ assert result.exit_code == 0
56
+ assert options.interactive
57
+
58
+
59
+ def test_doc_option(runner: CliRunner) -> None:
60
+ result = runner.invoke(crackerjack, ["-d"])
61
+ assert result.exit_code == 0
62
+ assert options.doc
63
+
64
+
65
+ def test_update_precommit_option(runner: CliRunner) -> None:
66
+ result = runner.invoke(crackerjack, ["-u"])
67
+ assert result.exit_code == 0
68
+ assert options.update_precommit
69
+
70
+
71
+ def test_do_not_update_configs_option(runner: CliRunner) -> None:
72
+ result = runner.invoke(crackerjack, ["-x"])
73
+ assert result.exit_code == 0
74
+ assert options.do_not_update_configs
75
+
76
+
77
+ # def test_publish_micro_option(runner: CliRunner) -> None:
78
+ # result = runner.invoke(crackerjack, ["-p", "micro"])
79
+ # assert result.exit_code == 0
80
+ # assert options.publish == "micro"
81
+ #
82
+ #
83
+ # def test_publish_minor_option(runner: CliRunner) -> None:
84
+ # result = runner.invoke(crackerjack, ["-p", "minor"])
85
+ # assert result.exit_code == 0
86
+ # assert options.publish == "minor"
87
+ #
88
+ #
89
+ # def test_publish_major_option(runner: CliRunner) -> None:
90
+ # result = runner.invoke(crackerjack, ["-p", "major"])
91
+ # assert result.exit_code == 0
92
+ # assert options.publish == "major"
93
+ #
94
+ #
95
+ # def test_bump_micro_option(runner: CliRunner) -> None:
96
+ # result = runner.invoke(crackerjack, ["-b", "micro"])
97
+ # assert result.exit_code == 0
98
+ # assert options.bump == "micro"
99
+ #
100
+ #
101
+ # def test_bump_minor_option(runner: CliRunner) -> None:
102
+ # result = runner.invoke(crackerjack, ["-b", "minor"])
103
+ # assert result.exit_code == 0
104
+ # assert options.bump == "minor"
105
+ #
106
+ #
107
+ # def test_bump_major_option(runner: CliRunner) -> None:
108
+ # result = runner.invoke(crackerjack, ["-b", "major"])
109
+ # assert result.exit_code == 0
110
+ # assert options.bump == "major"
111
+
112
+
113
+ def test_verbose_option(runner: CliRunner) -> None:
114
+ result = runner.invoke(crackerjack, ["-v"])
115
+ assert result.exit_code == 0
116
+ assert options.verbose
117
+ assert "-v not currently implemented" in result.output
118
+
119
+
120
+ def test_multiple_options(runner: CliRunner) -> None:
121
+ result = runner.invoke(crackerjack, ["-c", "-i"])
122
+ assert result.exit_code == 1
123
+ assert options.commit
124
+ assert options.interactive
125
+
126
+
127
+ def test_help_option(runner: CliRunner) -> None:
128
+ result = runner.invoke(crackerjack, ["-h"])
129
+ assert result.exit_code == 0
130
+ assert "Usage: " in result.output
131
+
132
+
133
+ def test_invalid_publish_option(runner: CliRunner) -> None:
134
+ result = runner.invoke(crackerjack, ["-p", "invalid"])
135
+ assert result.exit_code == 0
136
+ assert options.publish is False
137
+
138
+
139
+ def test_invalid_bump_option(runner: CliRunner) -> None:
140
+ result = runner.invoke(crackerjack, ["-b", "invalid"])
141
+ assert result.exit_code == 0
142
+ assert options.bump is False
File without changes
File without changes