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.
- {crackerjack-0.10.8 → crackerjack-0.11.2}/PKG-INFO +5 -5
- crackerjack-0.11.2/crackerjack/.pdm.toml +1 -0
- crackerjack-0.11.2/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/__main__.py +1 -2
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/crackerjack.py +49 -75
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/pyproject.toml +15 -5
- {crackerjack-0.10.8 → crackerjack-0.11.2}/pyproject.toml +15 -5
- crackerjack-0.11.2/tests/test_crackerjack.py +174 -0
- crackerjack-0.11.2/tests/test_main.py +142 -0
- crackerjack-0.10.8/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/LICENSE +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/README.md +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.gitignore +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.libcst.codemod.yaml +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.pre-commit-config.yaml +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/.gitignore +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/__init__.py +0 -0
- {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.
|
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
|
Binary file
|
@@ -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
|
-
|
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:
|
21
|
-
pkg_path:
|
22
|
-
|
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[
|
28
|
-
pkg_toml_path: t.Optional[
|
29
|
-
|
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
|
-
|
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
|
-
|
27
|
+
self.our_toml_path.write_text(self.pkg_toml_path.read_text())
|
37
28
|
return
|
38
|
-
our_toml_config: t.Any =
|
39
|
-
pkg_toml_config: t.Any =
|
40
|
-
|
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
|
-
|
58
|
-
|
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"]
|
55
|
+
for classifier in pkg_toml_config["project"].get("classifiers", []):
|
66
56
|
classifier = re.sub(
|
67
|
-
python_version_pattern, f" {self.
|
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
|
-
|
62
|
+
self.pkg_toml_path.write_text(dumps(pkg_toml_config))
|
73
63
|
|
74
|
-
|
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
|
-
|
69
|
+
pkg_config_path.touch()
|
80
70
|
if self.pkg_path.stem == "crackerjack":
|
81
|
-
|
71
|
+
config_path.write_text(pkg_config_path.read_text())
|
82
72
|
continue
|
83
73
|
if config != ".gitignore":
|
84
|
-
|
85
|
-
(
|
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
|
-
|
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 =
|
97
|
-
|
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
|
-
|
88
|
+
raise SystemExit(1)
|
101
89
|
success = True
|
102
90
|
|
103
|
-
|
104
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
137
|
-
raise SystemExit()
|
115
|
+
print("\n\nPre-commit failed. Please fix errors.\n")
|
116
|
+
raise SystemExit(1)
|
138
117
|
|
139
|
-
|
140
|
-
self.pkg_name =
|
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
|
-
|
143
|
-
|
121
|
+
self.pkg_dir.mkdir(exist_ok=True)
|
122
|
+
print("\nCrackerjacking...\n")
|
144
123
|
if not options.do_not_update_configs:
|
145
|
-
|
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
|
-
|
152
|
-
|
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
|
-
|
138
|
+
print(build.stdout)
|
160
139
|
if build.returncode > 0:
|
161
|
-
|
162
|
-
|
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 =
|
145
|
+
commit_msg = input("\nCommit message: ")
|
167
146
|
execute(
|
168
147
|
[
|
169
148
|
"git",
|
170
149
|
"commit",
|
171
150
|
"-m",
|
172
|
-
|
151
|
+
commit_msg,
|
173
152
|
"--no-verify",
|
174
153
|
"--",
|
175
154
|
".",
|
176
155
|
]
|
177
156
|
)
|
178
157
|
execute(["git", "push", "origin", "main"])
|
179
|
-
|
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().
|
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.
|
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.
|
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
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.11/3256171999636029978
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.4/10355199064880463147
RENAMED
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.6/15140459877605758699
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.1.9/17041001205004563469
RENAMED
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.2.0/10047773857155985907
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.2.2/18053836298936336950
RENAMED
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.0/12548816621480535786
RENAMED
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.3/11081883392474770722
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.3.5/16311176246009842383
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.0/11982804814124138945
RENAMED
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.6.0/12055761203849489982
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.7.3/16061516852537040135
RENAMED
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.8.4/16354268377385700367
RENAMED
File without changes
|
{crackerjack-0.10.8 → crackerjack-0.11.2}/crackerjack/.ruff_cache/0.9.3/13948373885254993391
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|