crackerjack 0.20.1__tar.gz → 0.20.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.
- {crackerjack-0.20.1 → crackerjack-0.20.3}/PKG-INFO +59 -3
- {crackerjack-0.20.1 → crackerjack-0.20.3}/README.md +58 -2
- crackerjack-0.20.3/crackerjack/.ruff_cache/0.11.13/1867267426380906393 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/crackerjack.py +26 -15
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/pyproject.toml +1 -1
- {crackerjack-0.20.1 → crackerjack-0.20.3}/pyproject.toml +1 -1
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_crackerjack.py +152 -49
- crackerjack-0.20.1/crackerjack/.ruff_cache/0.11.13/1867267426380906393 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/LICENSE +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.gitignore +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.libcst.codemod.yaml +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.pdm.toml +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.pre-commit-config.yaml +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.pytest_cache/.gitignore +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.pytest_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.pytest_cache/README.md +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.pytest_cache/v/cache/nodeids +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.pytest_cache/v/cache/stepwise +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/.gitignore +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.11/18187162184424859798 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.12/16869036553936192448 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.12/1867267426380906393 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.12/4240757255861806333 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.12/4441409093023629623 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/__init__.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/__main__.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/errors.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/interactive.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/py313.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/TESTING.md +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/__init__.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/conftest.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/data/comments_sample.txt +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/data/docstrings_sample.txt +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/data/expected_comments_sample.txt +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/data/init.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_crackerjack_runner.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_errors.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_interactive.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_interactive_run.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_main.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_py313_advanced.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_py313_features.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_pytest_features.py +0 -0
- {crackerjack-0.20.1 → crackerjack-0.20.3}/tests/test_structured_errors.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: crackerjack
|
3
|
-
Version: 0.20.
|
3
|
+
Version: 0.20.3
|
4
4
|
Summary: Crackerjack: code quality toolkit
|
5
5
|
Keywords: bandit,black,creosote,mypy,pyright,pytest,refurb,ruff
|
6
6
|
Author-Email: lesleslie <les@wedgwoodwebworks.com>
|
@@ -192,9 +192,35 @@ Crackerjack provides advanced testing capabilities powered by pytest:
|
|
192
192
|
### Standard Testing
|
193
193
|
|
194
194
|
- **Parallel Test Execution:** Tests run in parallel by default using pytest-xdist for faster execution
|
195
|
-
- **
|
195
|
+
- **Smart Parallelization:** Automatically adjusts the number of worker processes based on project size
|
196
|
+
- **Timeout Protection:** Tests have dynamic timeouts based on project size to prevent hanging tests
|
196
197
|
- **Coverage Reports:** Automatically generates test coverage reports with configurable thresholds
|
197
198
|
|
199
|
+
### Advanced Test Configuration
|
200
|
+
|
201
|
+
Crackerjack offers fine-grained control over test execution:
|
202
|
+
|
203
|
+
- **Worker Control:** Set the number of parallel workers with `--test-workers` (0 = auto-detect, 1 = disable parallelization)
|
204
|
+
- **Timeout Control:** Customize test timeouts with `--test-timeout` (in seconds)
|
205
|
+
- **Project Size Detection:** Automatically detects project size and adjusts timeout and parallelization settings
|
206
|
+
- **Deadlock Prevention:** Uses advanced threading techniques to prevent deadlocks in test output processing
|
207
|
+
- **Progress Tracking:** Shows periodic heartbeat messages for long-running tests
|
208
|
+
|
209
|
+
Example test execution options:
|
210
|
+
```bash
|
211
|
+
# Run tests with a single worker (no parallelization)
|
212
|
+
python -m crackerjack -t --test-workers=1
|
213
|
+
|
214
|
+
# Run tests with a specific number of workers (e.g., 4)
|
215
|
+
python -m crackerjack -t --test-workers=4
|
216
|
+
|
217
|
+
# Run tests with a custom timeout (5 minutes per test)
|
218
|
+
python -m crackerjack -t --test-timeout=300
|
219
|
+
|
220
|
+
# Combine options for maximum control
|
221
|
+
python -m crackerjack -t --test-workers=2 --test-timeout=600
|
222
|
+
```
|
223
|
+
|
198
224
|
### Benchmark Testing
|
199
225
|
|
200
226
|
Crackerjack includes benchmark testing capabilities:
|
@@ -278,10 +304,16 @@ class MyOptions:
|
|
278
304
|
# Process options
|
279
305
|
self.clean = True # Clean code (remove docstrings, comments, etc.)
|
280
306
|
self.test = True # Run tests using pytest
|
307
|
+
self.skip_hooks = False # Skip running pre-commit hooks
|
308
|
+
|
309
|
+
# Test execution options
|
310
|
+
self.test_workers = 2 # Number of parallel workers (0 = auto-detect, 1 = disable parallelization)
|
311
|
+
self.test_timeout = 120 # Timeout in seconds for individual tests (0 = use default based on project size)
|
312
|
+
|
313
|
+
# Benchmark options
|
281
314
|
self.benchmark = False # Run tests in benchmark mode
|
282
315
|
self.benchmark_regression = False # Fail tests if benchmarks regress beyond threshold
|
283
316
|
self.benchmark_regression_threshold = 5.0 # Threshold percentage for benchmark regression
|
284
|
-
self.skip_hooks = False # Skip running pre-commit hooks
|
285
317
|
|
286
318
|
# Version and publishing options
|
287
319
|
self.publish = None # Publish to PyPI (micro, minor, major)
|
@@ -321,6 +353,8 @@ runner.process(MyOptions())
|
|
321
353
|
- `-s`, `--skip-hooks`: Skip running pre-commit hooks (useful with `-t`).
|
322
354
|
- `-x`, `--clean`: Clean code by removing docstrings, line comments, and extra whitespace.
|
323
355
|
- `-t`, `--test`: Run tests using `pytest`.
|
356
|
+
- `--test-workers`: Set the number of parallel workers for testing (0 = auto-detect, 1 = disable parallelization).
|
357
|
+
- `--test-timeout`: Set the timeout in seconds for individual tests (0 = use default based on project size).
|
324
358
|
- `--benchmark`: Run tests in benchmark mode (disables parallel execution).
|
325
359
|
- `--benchmark-regression`: Fail tests if benchmarks regress beyond threshold.
|
326
360
|
- `--benchmark-regression-threshold`: Set threshold percentage for benchmark regression (default 5.0%).
|
@@ -356,6 +390,28 @@ runner.process(MyOptions())
|
|
356
390
|
python -m crackerjack -t -s
|
357
391
|
```
|
358
392
|
|
393
|
+
#### Test Execution Options
|
394
|
+
|
395
|
+
- **Single-Process Testing** - Run tests sequentially (no parallelization):
|
396
|
+
```bash
|
397
|
+
python -m crackerjack -t --test-workers=1
|
398
|
+
```
|
399
|
+
|
400
|
+
- **Customized Parallel Testing** - Run tests with a specific number of workers:
|
401
|
+
```bash
|
402
|
+
python -m crackerjack -t --test-workers=4
|
403
|
+
```
|
404
|
+
|
405
|
+
- **Long-Running Tests** - Increase test timeout for complex tests:
|
406
|
+
```bash
|
407
|
+
python -m crackerjack -t --test-timeout=600
|
408
|
+
```
|
409
|
+
|
410
|
+
- **Optimized for Large Projects** - Reduce workers and increase timeout for large codebases:
|
411
|
+
```bash
|
412
|
+
python -m crackerjack -t --test-workers=2 --test-timeout=300
|
413
|
+
```
|
414
|
+
|
359
415
|
#### Version Management
|
360
416
|
|
361
417
|
- **Bump and Publish** - Bump version and publish to PyPI:
|
@@ -150,9 +150,35 @@ Crackerjack provides advanced testing capabilities powered by pytest:
|
|
150
150
|
### Standard Testing
|
151
151
|
|
152
152
|
- **Parallel Test Execution:** Tests run in parallel by default using pytest-xdist for faster execution
|
153
|
-
- **
|
153
|
+
- **Smart Parallelization:** Automatically adjusts the number of worker processes based on project size
|
154
|
+
- **Timeout Protection:** Tests have dynamic timeouts based on project size to prevent hanging tests
|
154
155
|
- **Coverage Reports:** Automatically generates test coverage reports with configurable thresholds
|
155
156
|
|
157
|
+
### Advanced Test Configuration
|
158
|
+
|
159
|
+
Crackerjack offers fine-grained control over test execution:
|
160
|
+
|
161
|
+
- **Worker Control:** Set the number of parallel workers with `--test-workers` (0 = auto-detect, 1 = disable parallelization)
|
162
|
+
- **Timeout Control:** Customize test timeouts with `--test-timeout` (in seconds)
|
163
|
+
- **Project Size Detection:** Automatically detects project size and adjusts timeout and parallelization settings
|
164
|
+
- **Deadlock Prevention:** Uses advanced threading techniques to prevent deadlocks in test output processing
|
165
|
+
- **Progress Tracking:** Shows periodic heartbeat messages for long-running tests
|
166
|
+
|
167
|
+
Example test execution options:
|
168
|
+
```bash
|
169
|
+
# Run tests with a single worker (no parallelization)
|
170
|
+
python -m crackerjack -t --test-workers=1
|
171
|
+
|
172
|
+
# Run tests with a specific number of workers (e.g., 4)
|
173
|
+
python -m crackerjack -t --test-workers=4
|
174
|
+
|
175
|
+
# Run tests with a custom timeout (5 minutes per test)
|
176
|
+
python -m crackerjack -t --test-timeout=300
|
177
|
+
|
178
|
+
# Combine options for maximum control
|
179
|
+
python -m crackerjack -t --test-workers=2 --test-timeout=600
|
180
|
+
```
|
181
|
+
|
156
182
|
### Benchmark Testing
|
157
183
|
|
158
184
|
Crackerjack includes benchmark testing capabilities:
|
@@ -236,10 +262,16 @@ class MyOptions:
|
|
236
262
|
# Process options
|
237
263
|
self.clean = True # Clean code (remove docstrings, comments, etc.)
|
238
264
|
self.test = True # Run tests using pytest
|
265
|
+
self.skip_hooks = False # Skip running pre-commit hooks
|
266
|
+
|
267
|
+
# Test execution options
|
268
|
+
self.test_workers = 2 # Number of parallel workers (0 = auto-detect, 1 = disable parallelization)
|
269
|
+
self.test_timeout = 120 # Timeout in seconds for individual tests (0 = use default based on project size)
|
270
|
+
|
271
|
+
# Benchmark options
|
239
272
|
self.benchmark = False # Run tests in benchmark mode
|
240
273
|
self.benchmark_regression = False # Fail tests if benchmarks regress beyond threshold
|
241
274
|
self.benchmark_regression_threshold = 5.0 # Threshold percentage for benchmark regression
|
242
|
-
self.skip_hooks = False # Skip running pre-commit hooks
|
243
275
|
|
244
276
|
# Version and publishing options
|
245
277
|
self.publish = None # Publish to PyPI (micro, minor, major)
|
@@ -279,6 +311,8 @@ runner.process(MyOptions())
|
|
279
311
|
- `-s`, `--skip-hooks`: Skip running pre-commit hooks (useful with `-t`).
|
280
312
|
- `-x`, `--clean`: Clean code by removing docstrings, line comments, and extra whitespace.
|
281
313
|
- `-t`, `--test`: Run tests using `pytest`.
|
314
|
+
- `--test-workers`: Set the number of parallel workers for testing (0 = auto-detect, 1 = disable parallelization).
|
315
|
+
- `--test-timeout`: Set the timeout in seconds for individual tests (0 = use default based on project size).
|
282
316
|
- `--benchmark`: Run tests in benchmark mode (disables parallel execution).
|
283
317
|
- `--benchmark-regression`: Fail tests if benchmarks regress beyond threshold.
|
284
318
|
- `--benchmark-regression-threshold`: Set threshold percentage for benchmark regression (default 5.0%).
|
@@ -314,6 +348,28 @@ runner.process(MyOptions())
|
|
314
348
|
python -m crackerjack -t -s
|
315
349
|
```
|
316
350
|
|
351
|
+
#### Test Execution Options
|
352
|
+
|
353
|
+
- **Single-Process Testing** - Run tests sequentially (no parallelization):
|
354
|
+
```bash
|
355
|
+
python -m crackerjack -t --test-workers=1
|
356
|
+
```
|
357
|
+
|
358
|
+
- **Customized Parallel Testing** - Run tests with a specific number of workers:
|
359
|
+
```bash
|
360
|
+
python -m crackerjack -t --test-workers=4
|
361
|
+
```
|
362
|
+
|
363
|
+
- **Long-Running Tests** - Increase test timeout for complex tests:
|
364
|
+
```bash
|
365
|
+
python -m crackerjack -t --test-timeout=600
|
366
|
+
```
|
367
|
+
|
368
|
+
- **Optimized for Large Projects** - Reduce workers and increase timeout for large codebases:
|
369
|
+
```bash
|
370
|
+
python -m crackerjack -t --test-workers=2 --test-timeout=300
|
371
|
+
```
|
372
|
+
|
317
373
|
#### Version Management
|
318
374
|
|
319
375
|
- **Bump and Publish** - Bump version and publish to PyPI:
|
Binary file
|
@@ -1022,23 +1022,34 @@ class Crackerjack:
|
|
1022
1022
|
|
1023
1023
|
if options.publish:
|
1024
1024
|
if platform.system() == "Darwin":
|
1025
|
-
|
1026
|
-
|
1025
|
+
# First check if keyring is already installed in PDM
|
1026
|
+
check_keyring = self.execute_command(
|
1027
|
+
["pdm", "self", "list"], capture_output=True, text=True
|
1027
1028
|
)
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
error=error,
|
1038
|
-
console=self.console,
|
1039
|
-
verbose=options.verbose,
|
1040
|
-
ai_agent=options.ai_agent,
|
1029
|
+
keyring_installed = "keyring" in check_keyring.stdout
|
1030
|
+
|
1031
|
+
if not keyring_installed:
|
1032
|
+
# Only attempt to install keyring if it's not already installed
|
1033
|
+
self.console.print("Installing keyring for PDM...")
|
1034
|
+
authorize = self.execute_command(
|
1035
|
+
["pdm", "self", "add", "keyring"],
|
1036
|
+
capture_output=True,
|
1037
|
+
text=True,
|
1041
1038
|
)
|
1039
|
+
if authorize.returncode > 0:
|
1040
|
+
error = PublishError(
|
1041
|
+
message="Authentication setup failed",
|
1042
|
+
error_code=ErrorCode.AUTHENTICATION_ERROR,
|
1043
|
+
details=f"Failed to add keyring support to PDM.\nCommand output:\n{authorize.stderr}",
|
1044
|
+
recovery="Please manually add your keyring credentials to PDM. Run `pdm self add keyring` and try again.",
|
1045
|
+
exit_code=1,
|
1046
|
+
)
|
1047
|
+
handle_error(
|
1048
|
+
error=error,
|
1049
|
+
console=self.console,
|
1050
|
+
verbose=options.verbose,
|
1051
|
+
ai_agent=options.ai_agent,
|
1052
|
+
)
|
1042
1053
|
|
1043
1054
|
build = self.execute_command(
|
1044
1055
|
["pdm", "build"], capture_output=True, text=True
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import os
|
2
|
+
import subprocess
|
2
3
|
import typing as t
|
3
4
|
from contextlib import suppress
|
4
5
|
from dataclasses import dataclass
|
@@ -12,6 +13,7 @@ from crackerjack.crackerjack import (
|
|
12
13
|
CodeCleaner,
|
13
14
|
ConfigManager,
|
14
15
|
Crackerjack,
|
16
|
+
OptionsProtocol,
|
15
17
|
ProjectManager,
|
16
18
|
)
|
17
19
|
|
@@ -180,7 +182,7 @@ class TestCrackerjackProcess:
|
|
180
182
|
options = options_factory(commit=True, no_config_updates=True)
|
181
183
|
with patch.object(Crackerjack, "_update_project") as mock_update_project:
|
182
184
|
|
183
|
-
def side_effect(opts:
|
185
|
+
def side_effect(opts: OptionsProtocol) -> None:
|
184
186
|
if opts.no_config_updates:
|
185
187
|
mock_console_print("Skipping config updates.")
|
186
188
|
|
@@ -580,7 +582,9 @@ class TestCrackerjackProcess:
|
|
580
582
|
with patch("platform.system", return_value="Linux"):
|
581
583
|
with patch.object(Crackerjack, "execute_command") as mock_cj_execute:
|
582
584
|
|
583
|
-
def mock_execute_side_effect(
|
585
|
+
def mock_execute_side_effect(
|
586
|
+
*args: t.Any, **kwargs: t.Any
|
587
|
+
) -> subprocess.CompletedProcess[str]:
|
584
588
|
cmd = args[0][0]
|
585
589
|
if cmd == "pdm" and "build" in args[0]:
|
586
590
|
return MagicMock(
|
@@ -596,55 +600,154 @@ class TestCrackerjackProcess:
|
|
596
600
|
|
597
601
|
mock_handle_error.assert_called()
|
598
602
|
|
599
|
-
def
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
tmp_path: Path,
|
604
|
-
tmp_path_package: Path,
|
605
|
-
create_package_dir: None,
|
606
|
-
options_factory: t.Callable[..., OptionsForTesting],
|
607
|
-
) -> None:
|
608
|
-
options = options_factory(publish="micro", no_config_updates=True)
|
609
|
-
with patch("platform.system", return_value="Darwin"):
|
610
|
-
with patch.object(Crackerjack, "execute_command") as mock_cj_execute:
|
611
|
-
mock_cj_execute.side_effect = [
|
612
|
-
MagicMock(returncode=0, stdout="Success"),
|
613
|
-
MagicMock(returncode=0, stdout="Success"),
|
614
|
-
MagicMock(returncode=0, stdout="Success"),
|
615
|
-
MagicMock(returncode=0, stdout="Success"),
|
616
|
-
]
|
617
|
-
with patch.object(Crackerjack, "_update_project"):
|
618
|
-
cj = Crackerjack(dry_run=True)
|
619
|
-
cj.process(options)
|
620
|
-
mock_cj_execute.assert_any_call(
|
621
|
-
["pdm", "self", "add", "keyring"],
|
622
|
-
capture_output=True,
|
623
|
-
text=True,
|
624
|
-
)
|
603
|
+
def test_keyring_check_install_darwin(self) -> None:
|
604
|
+
"""Test checking for keyring on Darwin (macOS) and installing it."""
|
605
|
+
# Create a minimal options object
|
606
|
+
options = OptionsForTesting(publish=BumpOption.micro)
|
625
607
|
|
626
|
-
|
627
|
-
|
628
|
-
mock_execute: MagicMock,
|
629
|
-
mock_console_print: MagicMock,
|
630
|
-
tmp_path: Path,
|
631
|
-
tmp_path_package: Path,
|
632
|
-
create_package_dir: None,
|
633
|
-
options_factory: t.Callable[..., OptionsForTesting],
|
634
|
-
) -> None:
|
635
|
-
with patch("crackerjack.errors.handle_error") as mock_handle_error:
|
636
|
-
options = options_factory(publish="micro", no_config_updates=True)
|
637
|
-
with patch("platform.system", return_value="Darwin"):
|
638
|
-
with patch.object(Crackerjack, "execute_command") as mock_cj_execute:
|
639
|
-
mock_cj_execute.return_value = MagicMock(
|
640
|
-
returncode=1, stdout="", stderr="Authorization failed"
|
641
|
-
)
|
642
|
-
with patch.object(Crackerjack, "_update_project"):
|
643
|
-
with suppress(SystemExit):
|
644
|
-
cj = Crackerjack(dry_run=True)
|
645
|
-
cj.process(options)
|
608
|
+
# Use a list to track actual calls
|
609
|
+
actual_calls = []
|
646
610
|
|
647
|
-
|
611
|
+
# Create a Crackerjack instance for testing
|
612
|
+
crackerjack = Crackerjack(dry_run=False)
|
613
|
+
|
614
|
+
# Mock platform.system to return 'Darwin'
|
615
|
+
with patch("platform.system", return_value="Darwin"):
|
616
|
+
# Create a custom execute_command function that tracks calls
|
617
|
+
def mock_execute_side_effect(
|
618
|
+
*args: t.Any, **kwargs: t.Any
|
619
|
+
) -> subprocess.CompletedProcess[str]:
|
620
|
+
cmd = args[0]
|
621
|
+
actual_calls.append(cmd) # Track each command
|
622
|
+
|
623
|
+
if cmd == ["pdm", "self", "list"]:
|
624
|
+
# Important: This MUST NOT contain the string "keyring" to trigger installation
|
625
|
+
return MagicMock(
|
626
|
+
returncode=0, stdout="packages installed: pytest, black"
|
627
|
+
)
|
628
|
+
elif cmd == ["pdm", "self", "add", "keyring"]:
|
629
|
+
return MagicMock(returncode=0, stdout="installed keyring")
|
630
|
+
elif cmd == ["pdm", "build"]:
|
631
|
+
return MagicMock(returncode=0, stdout="build output")
|
632
|
+
elif cmd == ["pdm", "publish", "--no-build"]:
|
633
|
+
return MagicMock(returncode=0, stdout="publish output")
|
634
|
+
return MagicMock(returncode=0, stdout="")
|
635
|
+
|
636
|
+
# Mock execute_command with our custom side_effect
|
637
|
+
with patch.object(
|
638
|
+
crackerjack, "execute_command", side_effect=mock_execute_side_effect
|
639
|
+
):
|
640
|
+
# Mock console.print
|
641
|
+
with patch.object(crackerjack.console, "print"):
|
642
|
+
# Call the method we're testing
|
643
|
+
crackerjack._publish_project(options)
|
644
|
+
|
645
|
+
# Check that all the expected commands were called
|
646
|
+
assert ["pdm", "self", "list"] in actual_calls
|
647
|
+
assert ["pdm", "self", "add", "keyring"] in actual_calls
|
648
|
+
assert ["pdm", "build"] in actual_calls
|
649
|
+
assert ["pdm", "publish", "--no-build"] in actual_calls
|
650
|
+
|
651
|
+
def test_keyring_already_installed_darwin(self) -> None:
|
652
|
+
"""Test behavior when keyring is already installed on Darwin (macOS)."""
|
653
|
+
# Create a minimal options object
|
654
|
+
options = OptionsForTesting(publish=BumpOption.micro)
|
655
|
+
|
656
|
+
# Use a list to track actual calls
|
657
|
+
actual_calls = []
|
658
|
+
|
659
|
+
# Create a Crackerjack instance for testing
|
660
|
+
crackerjack = Crackerjack(dry_run=False)
|
661
|
+
|
662
|
+
# Mock platform.system to return 'Darwin'
|
663
|
+
with patch("platform.system", return_value="Darwin"):
|
664
|
+
# Create a custom execute_command function that tracks calls
|
665
|
+
def mock_execute_side_effect(
|
666
|
+
*args: t.Any, **kwargs: t.Any
|
667
|
+
) -> subprocess.CompletedProcess[str]:
|
668
|
+
cmd = args[0]
|
669
|
+
actual_calls.append(cmd) # Track each command
|
670
|
+
|
671
|
+
if cmd == ["pdm", "self", "list"]:
|
672
|
+
return MagicMock(returncode=0, stdout="keyring 25.6.0")
|
673
|
+
elif cmd == ["pdm", "build"]:
|
674
|
+
return MagicMock(returncode=0, stdout="build output")
|
675
|
+
elif cmd == ["pdm", "publish", "--no-build"]:
|
676
|
+
return MagicMock(returncode=0, stdout="publish output")
|
677
|
+
return MagicMock(returncode=0, stdout="")
|
678
|
+
|
679
|
+
# Mock execute_command with our custom side_effect
|
680
|
+
with patch.object(
|
681
|
+
crackerjack, "execute_command", side_effect=mock_execute_side_effect
|
682
|
+
):
|
683
|
+
# Mock console.print
|
684
|
+
with patch.object(crackerjack.console, "print"):
|
685
|
+
# Call the method we're testing
|
686
|
+
crackerjack._publish_project(options)
|
687
|
+
|
688
|
+
# Check that keyring installation was skipped
|
689
|
+
assert ["pdm", "self", "list"] in actual_calls
|
690
|
+
assert ["pdm", "self", "add", "keyring"] not in actual_calls
|
691
|
+
assert ["pdm", "build"] in actual_calls
|
692
|
+
assert ["pdm", "publish", "--no-build"] in actual_calls
|
693
|
+
|
694
|
+
def test_keyring_install_failure_darwin(self) -> None:
|
695
|
+
"""Test handling of keyring installation failure on Darwin (macOS)."""
|
696
|
+
# Create a minimal options object with ai_agent False to avoid extra mocking
|
697
|
+
options = OptionsForTesting(publish=BumpOption.micro, ai_agent=False)
|
698
|
+
|
699
|
+
# Create a Crackerjack instance for testing
|
700
|
+
crackerjack = Crackerjack(dry_run=False)
|
701
|
+
|
702
|
+
# Mock the PublishError class to capture its creation
|
703
|
+
with patch("crackerjack.errors.PublishError") as mock_publish_error:
|
704
|
+
# Set up the mock to return a MagicMock that we can track
|
705
|
+
error_instance = MagicMock()
|
706
|
+
mock_publish_error.return_value = error_instance
|
707
|
+
|
708
|
+
# Mock handle_error to avoid actual exit
|
709
|
+
with patch("crackerjack.errors.handle_error") as mock_handle_error:
|
710
|
+
# Mock platform.system to return 'Darwin'
|
711
|
+
with patch("platform.system", return_value="Darwin"):
|
712
|
+
# Create a custom execute_command function with failure scenario
|
713
|
+
def mock_execute_side_effect(
|
714
|
+
*args: t.Any, **kwargs: t.Any
|
715
|
+
) -> subprocess.CompletedProcess[str]:
|
716
|
+
cmd = args[0]
|
717
|
+
|
718
|
+
if cmd == ["pdm", "self", "list"]:
|
719
|
+
# This must NOT contain the string "keyring" to trigger installation
|
720
|
+
return MagicMock(
|
721
|
+
returncode=0, stdout="packages installed: pytest, black"
|
722
|
+
)
|
723
|
+
elif cmd == ["pdm", "self", "add", "keyring"]:
|
724
|
+
# Return a failure for keyring installation
|
725
|
+
mock_result = MagicMock()
|
726
|
+
mock_result.returncode = 1
|
727
|
+
mock_result.stdout = ""
|
728
|
+
mock_result.stderr = "Installation failed"
|
729
|
+
return mock_result
|
730
|
+
return MagicMock(returncode=0, stdout="")
|
731
|
+
|
732
|
+
# Mock execute_command with our custom side_effect
|
733
|
+
with patch.object(
|
734
|
+
crackerjack,
|
735
|
+
"execute_command",
|
736
|
+
side_effect=mock_execute_side_effect,
|
737
|
+
):
|
738
|
+
# Mock console.print to avoid terminal output
|
739
|
+
with patch.object(crackerjack.console, "print"):
|
740
|
+
# Call the method we're testing with error suppression
|
741
|
+
with suppress(SystemExit):
|
742
|
+
crackerjack._publish_project(options)
|
743
|
+
|
744
|
+
# Check that the error handler was called with the right error
|
745
|
+
mock_handle_error.assert_called_once_with(
|
746
|
+
error=error_instance,
|
747
|
+
console=crackerjack.console,
|
748
|
+
verbose=options.verbose,
|
749
|
+
ai_agent=options.ai_agent,
|
750
|
+
)
|
648
751
|
|
649
752
|
def test_process_with_commit_input(
|
650
753
|
self,
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
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.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.11/3256171999636029978
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.4/10355199064880463147
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.6/15140459877605758699
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.1.9/17041001205004563469
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.11/18187162184424859798
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.12/16869036553936192448
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.12/1867267426380906393
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.12/4240757255861806333
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.12/4441409093023629623
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.2/4070660268492669020
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.3/9818742842212983150
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.4/9818742842212983150
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.6/3557596832929915217
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.7/10386934055395314831
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.11.7/3557596832929915217
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.2.0/10047773857155985907
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.2.2/18053836298936336950
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.3.0/12548816621480535786
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.3.3/11081883392474770722
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.3.5/16311176246009842383
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.6.0/11982804814124138945
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/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.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.7.3/16061516852537040135
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.8.4/16354268377385700367
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.9.10/12813592349865671909
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.9.3/13948373885254993391
RENAMED
File without changes
|
{crackerjack-0.20.1 → crackerjack-0.20.3}/crackerjack/.ruff_cache/0.9.9/12813592349865671909
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|