crackerjack 0.22.3__tar.gz → 0.22.5__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.

Potentially problematic release.


This version of crackerjack might be problematic. Click here for more details.

Files changed (91) hide show
  1. {crackerjack-0.22.3 → crackerjack-0.22.5}/PKG-INFO +4 -4
  2. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.pre-commit-config.yaml +5 -5
  3. crackerjack-0.22.5/crackerjack/.ruff_cache/0.12.1/5056746222905752453 +0 -0
  4. crackerjack-0.22.5/crackerjack/.ruff_cache/0.12.2/5056746222905752453 +0 -0
  5. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/crackerjack.py +56 -34
  6. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/pyproject.toml +4 -4
  7. {crackerjack-0.22.3 → crackerjack-0.22.5}/pyproject.toml +4 -4
  8. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_crackerjack.py +9 -3
  9. crackerjack-0.22.3/crackerjack/.ruff_cache/0.12.1/5056746222905752453 +0 -0
  10. {crackerjack-0.22.3 → crackerjack-0.22.5}/LICENSE +0 -0
  11. {crackerjack-0.22.3 → crackerjack-0.22.5}/README.md +0 -0
  12. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.gitignore +0 -0
  13. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.libcst.codemod.yaml +0 -0
  14. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.pdm.toml +0 -0
  15. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.pre-commit-config-ai.yaml +0 -0
  16. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.pytest_cache/.gitignore +0 -0
  17. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.pytest_cache/CACHEDIR.TAG +0 -0
  18. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.pytest_cache/README.md +0 -0
  19. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.pytest_cache/v/cache/nodeids +0 -0
  20. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.pytest_cache/v/cache/stepwise +0 -0
  21. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/.gitignore +0 -0
  22. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
  23. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
  24. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
  25. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
  26. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
  27. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
  28. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.11/18187162184424859798 +0 -0
  29. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.12/16869036553936192448 +0 -0
  30. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.12/1867267426380906393 +0 -0
  31. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.12/4240757255861806333 +0 -0
  32. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.12/4441409093023629623 +0 -0
  33. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.13/1867267426380906393 +0 -0
  34. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.13/4240757255861806333 +0 -0
  35. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
  36. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
  37. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
  38. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
  39. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
  40. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
  41. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
  42. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.12.0/5056746222905752453 +0 -0
  43. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
  44. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
  45. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
  46. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
  47. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
  48. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
  49. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
  50. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
  51. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
  52. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
  53. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
  54. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
  55. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
  56. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
  57. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
  58. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
  59. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
  60. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
  61. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
  62. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
  63. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
  64. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
  65. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
  66. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
  67. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  68. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
  69. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
  70. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/__init__.py +0 -0
  71. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/__main__.py +0 -0
  72. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/errors.py +0 -0
  73. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/interactive.py +0 -0
  74. {crackerjack-0.22.3 → crackerjack-0.22.5}/crackerjack/py313.py +0 -0
  75. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/TESTING.md +0 -0
  76. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/__init__.py +0 -0
  77. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/conftest.py +0 -0
  78. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/data/comments_sample.txt +0 -0
  79. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/data/docstrings_sample.txt +0 -0
  80. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/data/expected_comments_sample.txt +0 -0
  81. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/data/init.py +0 -0
  82. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_crackerjack_runner.py +0 -0
  83. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_errors.py +0 -0
  84. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_interactive.py +0 -0
  85. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_interactive_run.py +0 -0
  86. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_main.py +0 -0
  87. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_multiline_functions.py +0 -0
  88. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_py313_advanced.py +0 -0
  89. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_py313_features.py +0 -0
  90. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_pytest_features.py +0 -0
  91. {crackerjack-0.22.3 → crackerjack-0.22.5}/tests/test_structured_errors.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crackerjack
3
- Version: 0.22.3
3
+ Version: 0.22.5
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>
@@ -24,7 +24,7 @@ Project-URL: repository, https://github.com/lesleslie/crackerjack
24
24
  Requires-Python: >=3.13
25
25
  Requires-Dist: autotyping>=24.9
26
26
  Requires-Dist: keyring>=25.6
27
- Requires-Dist: pdm>=2.25.3
27
+ Requires-Dist: pdm>=2.25.4
28
28
  Requires-Dist: pdm-bump>=0.9.12
29
29
  Requires-Dist: pre-commit>=4.2
30
30
  Requires-Dist: pydantic>=2.11.7
@@ -34,12 +34,12 @@ Requires-Dist: pytest-benchmark>=5.1
34
34
  Requires-Dist: pytest-cov>=6.2.1
35
35
  Requires-Dist: pytest-mock>=3.14.1
36
36
  Requires-Dist: pytest-timeout>=2.4
37
- Requires-Dist: pytest-xdist>=3.7
37
+ Requires-Dist: pytest-xdist>=3.8
38
38
  Requires-Dist: pyyaml>=6.0.2
39
39
  Requires-Dist: rich>=14
40
40
  Requires-Dist: tomli-w>=1.2
41
41
  Requires-Dist: typer>=0.16
42
- Requires-Dist: uv>=0.7.15
42
+ Requires-Dist: uv>=0.7.20
43
43
  Description-Content-Type: text/markdown
44
44
 
45
45
  # Crackerjack: Elevate Your Python Development
@@ -21,7 +21,7 @@ repos:
21
21
 
22
22
  # Package management - once structure is valid
23
23
  - repo: https://github.com/pdm-project/pdm
24
- rev: 2.25.3
24
+ rev: 2.25.4
25
25
  hooks:
26
26
  - id: pdm-lock-check
27
27
  - id: pdm-sync
@@ -29,7 +29,7 @@ repos:
29
29
  - keyring
30
30
 
31
31
  - repo: https://github.com/astral-sh/uv-pre-commit
32
- rev: 0.7.16
32
+ rev: 0.7.20
33
33
  hooks:
34
34
  - id: uv-lock
35
35
  files: ^pyproject\.toml$
@@ -50,7 +50,7 @@ repos:
50
50
  - tomli
51
51
 
52
52
  - repo: https://github.com/astral-sh/ruff-pre-commit
53
- rev: v0.12.1
53
+ rev: v0.12.2
54
54
  hooks:
55
55
  - id: ruff-check
56
56
  - id: ruff-format
@@ -96,12 +96,12 @@ repos:
96
96
  - libcst>=1.1.0
97
97
 
98
98
  - repo: https://github.com/PyCQA/bandit
99
- rev: '1.8.5'
99
+ rev: '1.8.6'
100
100
  hooks:
101
101
  - id: bandit
102
102
  args: ["-c", "pyproject.toml"]
103
103
 
104
104
  - repo: https://github.com/RobertCraigie/pyright-python
105
- rev: v1.1.402
105
+ rev: v1.1.403
106
106
  hooks:
107
107
  - id: pyright
@@ -84,7 +84,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
84
84
  code = self.remove_line_comments(code)
85
85
  except Exception as e:
86
86
  self.console.print(
87
- f"[yellow]Warning: Failed to remove line comments from {file_path}: {e}[/yellow]"
87
+ f"[bright_yellow]⚠️ Warning: Failed to remove line comments from {file_path}: {e}[/bright_yellow]"
88
88
  )
89
89
  code = original_code
90
90
  cleaning_failed = True
@@ -92,7 +92,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
92
92
  code = self.remove_docstrings(code)
93
93
  except Exception as e:
94
94
  self.console.print(
95
- f"[yellow]Warning: Failed to remove docstrings from {file_path}: {e}[/yellow]"
95
+ f"[bright_yellow]⚠️ Warning: Failed to remove docstrings from {file_path}: {e}[/bright_yellow]"
96
96
  )
97
97
  code = original_code
98
98
  cleaning_failed = True
@@ -100,7 +100,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
100
100
  code = self.remove_extra_whitespace(code)
101
101
  except Exception as e:
102
102
  self.console.print(
103
- f"[yellow]Warning: Failed to remove extra whitespace from {file_path}: {e}[/yellow]"
103
+ f"[bright_yellow]⚠️ Warning: Failed to remove extra whitespace from {file_path}: {e}[/bright_yellow]"
104
104
  )
105
105
  code = original_code
106
106
  cleaning_failed = True
@@ -108,20 +108,22 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
108
108
  code = self.reformat_code(code)
109
109
  except Exception as e:
110
110
  self.console.print(
111
- f"[yellow]Warning: Failed to reformat {file_path}: {e}[/yellow]"
111
+ f"[bright_yellow]⚠️ Warning: Failed to reformat {file_path}: {e}[/bright_yellow]"
112
112
  )
113
113
  code = original_code
114
114
  cleaning_failed = True
115
115
  file_path.write_text(code, encoding="utf-8")
116
116
  if cleaning_failed:
117
117
  self.console.print(
118
- f"[yellow]⚠️ Partially cleaned: {file_path}[/yellow]"
118
+ f"[bright_yellow]⚠️ Partially cleaned: {file_path}[/bright_yellow]"
119
119
  )
120
120
  else:
121
- self.console.print(f"[green]✅ Cleaned: {file_path}[/green]")
121
+ self.console.print(
122
+ f"[bright_green]🧹 Cleaned: {file_path}[/bright_green]"
123
+ )
122
124
  except PermissionError as e:
123
125
  self.console.print(
124
- f"[red]❌ Failed to clean: {file_path} (Permission denied)[/red]"
126
+ f"[bright_red]❌ Failed to clean: {file_path} (Permission denied)[/bright_red]"
125
127
  )
126
128
  handle_error(
127
129
  ExecutionError(
@@ -135,7 +137,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
135
137
  )
136
138
  except OSError as e:
137
139
  self.console.print(
138
- f"[red]❌ Failed to clean: {file_path} (File system error)[/red]"
140
+ f"[bright_red]❌ Failed to clean: {file_path} (File system error)[/bright_red]"
139
141
  )
140
142
  handle_error(
141
143
  ExecutionError(
@@ -149,7 +151,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
149
151
  )
150
152
  except UnicodeDecodeError as e:
151
153
  self.console.print(
152
- f"[red]❌ Failed to clean: {file_path} (Encoding error)[/red]"
154
+ f"[bright_red]❌ Failed to clean: {file_path} (Encoding error)[/bright_red]"
153
155
  )
154
156
  handle_error(
155
157
  ExecutionError(
@@ -163,7 +165,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
163
165
  )
164
166
  except Exception as e:
165
167
  self.console.print(
166
- f"[red]❌ Failed to clean: {file_path} (Unexpected error)[/red]"
168
+ f"[bright_red]❌ Failed to clean: {file_path} (Unexpected error)[/bright_red]"
167
169
  )
168
170
  handle_error(
169
171
  ExecutionError(
@@ -613,7 +615,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
613
615
  formatted_code = temp_path.read_text()
614
616
  else:
615
617
  self.console.print(
616
- f"[yellow]Ruff formatting failed: {result.stderr}[/yellow]"
618
+ f"[bright_yellow]⚠️ Ruff formatting failed: {result.stderr}[/bright_yellow]"
617
619
  )
618
620
  handle_error(
619
621
  ExecutionError(
@@ -627,7 +629,9 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
627
629
  )
628
630
  formatted_code = code
629
631
  except Exception as e:
630
- self.console.print(f"[red]Error running Ruff: {e}[/red]")
632
+ self.console.print(
633
+ f"[bright_red]❌ Error running Ruff: {e}[/bright_red]"
634
+ )
631
635
  handle_error(
632
636
  ExecutionError(
633
637
  message="Error running Ruff",
@@ -644,7 +648,9 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
644
648
  temp_path.unlink()
645
649
  return formatted_code
646
650
  except Exception as e:
647
- self.console.print(f"[red]Error during reformatting: {e}[/red]")
651
+ self.console.print(
652
+ f"[bright_red]❌ Error during reformatting: {e}[/bright_red]"
653
+ )
648
654
  handle_error(
649
655
  ExecutionError(
650
656
  message="Error during reformatting",
@@ -816,7 +822,7 @@ class ConfigManager(BaseModel, arbitrary_types_allowed=True):
816
822
  self, cmd: list[str], **kwargs: t.Any
817
823
  ) -> subprocess.CompletedProcess[str]:
818
824
  if self.dry_run:
819
- self.console.print(f"[yellow]Would run: {' '.join(cmd)}[/yellow]")
825
+ self.console.print(f"[dim cyan]🔍 Would run: {' '.join(cmd)}[/dim cyan]")
820
826
  return CompletedProcess(cmd, 0, "", "")
821
827
  return execute(cmd, **kwargs)
822
828
 
@@ -838,7 +844,7 @@ class ProjectManager(BaseModel, arbitrary_types_allowed=True):
838
844
  ["pdm", "list", "--freeze"], capture_output=True, text=True
839
845
  ).stdout.splitlines()
840
846
  if not len([pkg for pkg in installed_pkgs if "pre-commit" in pkg]):
841
- self.console.print("Initializing project...")
847
+ self.console.print("[bright_blue]🚀 Initializing project...[/bright_blue]")
842
848
  self.execute_command(["pdm", "self", "add", "keyring"])
843
849
  self.execute_command(["pdm", "config", "python.use_uv", "true"])
844
850
  self.execute_command(["git", "init"])
@@ -853,22 +859,28 @@ class ProjectManager(BaseModel, arbitrary_types_allowed=True):
853
859
  self.config_manager.update_pyproject_configs()
854
860
 
855
861
  def run_pre_commit(self) -> None:
856
- self.console.print("\nRunning pre-commit hooks...\n")
862
+ self.console.print(
863
+ "\n[bright_blue]🔍 Running pre-commit hooks...[/bright_blue]\n"
864
+ )
857
865
  cmd = ["pre-commit", "run", "--all-files"]
858
866
  if hasattr(self, "options") and getattr(self.options, "ai_agent", False):
859
867
  cmd.extend(["-c", ".pre-commit-config-ai.yaml"])
860
868
  check_all = self.execute_command(cmd)
861
869
  if check_all.returncode > 0:
870
+ self.execute_command(["pdm", "lock"])
871
+ self.console.print("\n[bright_green]✅ Lock file updated[/bright_green]\n")
862
872
  check_all = self.execute_command(cmd)
863
873
  if check_all.returncode > 0:
864
- self.console.print("\n\nPre-commit failed. Please fix errors.\n")
874
+ self.console.print(
875
+ "\n\n[bright_red]❌ Pre-commit failed. Please fix errors.[/bright_red]\n"
876
+ )
865
877
  raise SystemExit(1)
866
878
 
867
879
  def execute_command(
868
880
  self, cmd: list[str], **kwargs: t.Any
869
881
  ) -> subprocess.CompletedProcess[str]:
870
882
  if self.dry_run:
871
- self.console.print(f"[yellow]Would run: {' '.join(cmd)}[/yellow]")
883
+ self.console.print(f"[dim cyan]🔍 Would run: {' '.join(cmd)}[/dim cyan]")
872
884
  return CompletedProcess(cmd, 0, "", "")
873
885
  return execute(cmd, **kwargs)
874
886
 
@@ -911,7 +923,7 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
911
923
  self.pkg_name = self.pkg_path.stem.lower().replace("-", "_")
912
924
  self.pkg_dir = self.pkg_path / self.pkg_name
913
925
  self.pkg_dir.mkdir(exist_ok=True)
914
- self.console.print("\nCrackerjacking...\n")
926
+ self.console.print("\n[bright_magenta]🎯 Crackerjacking...[/bright_magenta]\n")
915
927
  self.config_manager.pkg_name = self.pkg_name
916
928
  self.project_manager.pkg_name = self.pkg_name
917
929
  self.project_manager.pkg_dir = self.pkg_dir
@@ -923,9 +935,7 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
923
935
  ["pdm", "install"], capture_output=True, text=True
924
936
  )
925
937
  if result.returncode == 0:
926
- self.console.print("PDM installed: ✅\n")
927
- self.execute_command(["pdm", "lock"])
928
- self.console.print("Lock file updated: ✅\n")
938
+ self.console.print("[bright_green]✅ PDM installed[/bright_green]\n")
929
939
  else:
930
940
  self.console.print(
931
941
  "\n\n❌ PDM installation failed. Is PDM is installed? Run `pipx install pdm` and try again.\n\n"
@@ -945,7 +955,9 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
945
955
  if self.pkg_path.stem == "crackerjack":
946
956
  tests_dir = self.pkg_path / "tests"
947
957
  if tests_dir.exists() and tests_dir.is_dir():
948
- self.console.print("\nCleaning tests directory...\n")
958
+ self.console.print(
959
+ "\n[bright_blue]🧹 Cleaning tests directory...[/bright_blue]\n"
960
+ )
949
961
  self.code_cleaner.clean_files(tests_dir)
950
962
 
951
963
  def _get_test_timeout(self, options: OptionsProtocol, project_size: str) -> int:
@@ -1042,26 +1054,34 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
1042
1054
 
1043
1055
  def _print_ai_agent_files(self, options: t.Any) -> None:
1044
1056
  if getattr(options, "ai_agent", False):
1045
- self.console.print("📄 Structured test results: test-results.xml")
1046
- self.console.print("📊 Coverage report: coverage.json")
1057
+ self.console.print(
1058
+ "[dim cyan]📄 Structured test results: test-results.xml[/dim cyan]"
1059
+ )
1060
+ self.console.print("[dim cyan]📊 Coverage report: coverage.json[/dim cyan]")
1047
1061
  if options.benchmark or options.benchmark_regression:
1048
- self.console.print("⏱️ Benchmark results: benchmark.json")
1062
+ self.console.print(
1063
+ "[dim cyan]⏱️ Benchmark results: benchmark.json[/dim cyan]"
1064
+ )
1049
1065
 
1050
1066
  def _handle_test_failure(self, result: t.Any, options: t.Any) -> None:
1051
1067
  if result.stderr:
1052
1068
  self.console.print(result.stderr)
1053
- self.console.print("\n\n❌ Tests failed. Please fix errors.\n")
1069
+ self.console.print(
1070
+ "\n\n[bright_red]❌ Tests failed. Please fix errors.[/bright_red]\n"
1071
+ )
1054
1072
  self._print_ai_agent_files(options)
1055
1073
  raise SystemExit(1)
1056
1074
 
1057
1075
  def _handle_test_success(self, options: t.Any) -> None:
1058
- self.console.print("\n\n✅ Tests passed successfully!\n")
1076
+ self.console.print(
1077
+ "\n\n[bright_green]✅ Tests passed successfully![/bright_green]\n"
1078
+ )
1059
1079
  self._print_ai_agent_files(options)
1060
1080
 
1061
1081
  def _run_tests(self, options: t.Any) -> None:
1062
1082
  if not options.test:
1063
1083
  return
1064
- self.console.print("\n\nRunning tests...\n")
1084
+ self.console.print("\n\n[bright_blue]🧪 Running tests...[/bright_blue]\n")
1065
1085
  test_command = self._prepare_pytest_command(options)
1066
1086
  result = self.execute_command(test_command, capture_output=True, text=True)
1067
1087
  if result.stdout:
@@ -1082,7 +1102,7 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
1082
1102
  default=False,
1083
1103
  ):
1084
1104
  self.console.print(
1085
- f"[yellow]Skipping {option} version bump[/yellow]"
1105
+ f"[dim yellow]⏭️ Skipping {option} version bump[/dim yellow]"
1086
1106
  )
1087
1107
  return
1088
1108
  self.execute_command(["pdm", "bump", option])
@@ -1096,7 +1116,9 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
1096
1116
  self.console.print(build.stdout)
1097
1117
  if build.returncode > 0:
1098
1118
  self.console.print(build.stderr)
1099
- self.console.print("\n\nBuild failed. Please fix errors.\n")
1119
+ self.console.print(
1120
+ "\n\n[bright_red]❌ Build failed. Please fix errors.[/bright_red]\n"
1121
+ )
1100
1122
  raise SystemExit(1)
1101
1123
  self.execute_command(["pdm", "publish", "--no-build"])
1102
1124
 
@@ -1112,7 +1134,7 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
1112
1134
  self, cmd: list[str], **kwargs: t.Any
1113
1135
  ) -> subprocess.CompletedProcess[str]:
1114
1136
  if self.dry_run:
1115
- self.console.print(f"[yellow]Would run: {' '.join(cmd)}[/yellow]")
1137
+ self.console.print(f"[dim cyan]🔍 Would run: {' '.join(cmd)}[/dim cyan]")
1116
1138
  return CompletedProcess(cmd, 0, "", "")
1117
1139
  return execute(cmd, **kwargs)
1118
1140
 
@@ -1130,12 +1152,12 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
1130
1152
  if not options.skip_hooks:
1131
1153
  self.project_manager.run_pre_commit()
1132
1154
  else:
1133
- self.console.print("Skipping pre-commit hooks")
1155
+ self.console.print("[dim yellow]⏭️ Skipping pre-commit hooks[/dim yellow]")
1134
1156
  self._run_tests(options)
1135
1157
  self._bump_version(options)
1136
1158
  self._publish_project(options)
1137
1159
  self._commit_and_push(options)
1138
- self.console.print("\n🍺 Crackerjack complete!\n")
1160
+ self.console.print("\n[bright_green]🍺 Crackerjack complete![/bright_green]\n")
1139
1161
 
1140
1162
 
1141
1163
  crackerjack_it = Crackerjack().process
@@ -4,7 +4,7 @@ requires = [ "pdm-backend" ]
4
4
 
5
5
  [project]
6
6
  name = "crackerjack"
7
- version = "0.22.2"
7
+ version = "0.22.4"
8
8
  description = "Crackerjack: code quality toolkit"
9
9
  readme = "README.md"
10
10
  keywords = [
@@ -43,7 +43,7 @@ classifiers = [
43
43
  dependencies = [
44
44
  "autotyping>=24.9",
45
45
  "keyring>=25.6",
46
- "pdm>=2.25.3",
46
+ "pdm>=2.25.4",
47
47
  "pdm-bump>=0.9.12",
48
48
  "pre-commit>=4.2",
49
49
  "pydantic>=2.11.7",
@@ -53,12 +53,12 @@ dependencies = [
53
53
  "pytest-cov>=6.2.1",
54
54
  "pytest-mock>=3.14.1",
55
55
  "pytest-timeout>=2.4",
56
- "pytest-xdist>=3.7",
56
+ "pytest-xdist>=3.8",
57
57
  "pyyaml>=6.0.2",
58
58
  "rich>=14",
59
59
  "tomli-w>=1.2",
60
60
  "typer>=0.16",
61
- "uv>=0.7.15",
61
+ "uv>=0.7.20",
62
62
  ]
63
63
  urls.documentation = "https://github.com/lesleslie/crackerjack"
64
64
  urls.homepage = "https://github.com/lesleslie/crackerjack"
@@ -6,7 +6,7 @@ requires = [
6
6
 
7
7
  [project]
8
8
  name = "crackerjack"
9
- version = "0.22.3"
9
+ version = "0.22.5"
10
10
  description = "Crackerjack: code quality toolkit"
11
11
  readme = "README.md"
12
12
  keywords = [
@@ -43,7 +43,7 @@ classifiers = [
43
43
  dependencies = [
44
44
  "autotyping>=24.9",
45
45
  "keyring>=25.6",
46
- "pdm>=2.25.3",
46
+ "pdm>=2.25.4",
47
47
  "pdm-bump>=0.9.12",
48
48
  "pre-commit>=4.2",
49
49
  "pydantic>=2.11.7",
@@ -53,12 +53,12 @@ dependencies = [
53
53
  "pytest-cov>=6.2.1",
54
54
  "pytest-mock>=3.14.1",
55
55
  "pytest-timeout>=2.4",
56
- "pytest-xdist>=3.7",
56
+ "pytest-xdist>=3.8",
57
57
  "pyyaml>=6.0.2",
58
58
  "rich>=14",
59
59
  "tomli-w>=1.2",
60
60
  "typer>=0.16",
61
- "uv>=0.7.15",
61
+ "uv>=0.7.20",
62
62
  ]
63
63
 
64
64
  [project.license]
@@ -500,7 +500,9 @@ class TestCrackerjackProcess:
500
500
  mock_tests.assert_called_once()
501
501
  mock_publish.assert_called_once()
502
502
  mock_commit.assert_called_once()
503
- mock_console_print.assert_any_call("\n🍺 Crackerjack complete!\n")
503
+ mock_console_print.assert_any_call(
504
+ "\n[bright_green]🍺 Crackerjack complete![/bright_green]\n"
505
+ )
504
506
 
505
507
  def test_process_with_all_option_sets_flags(
506
508
  self,
@@ -672,7 +674,9 @@ class TestCrackerjackProcess:
672
674
  cj = Crackerjack(dry_run=True)
673
675
  with suppress(SystemExit):
674
676
  cj.process(options)
675
- mock_console_print.assert_any_call("\n\nRunning tests...\n")
677
+ mock_console_print.assert_any_call(
678
+ "\n\n[bright_red]❌ Tests failed. Please fix errors.[/bright_red]\n"
679
+ )
676
680
  mock_cj_execute.assert_called_once()
677
681
 
678
682
  def test_process_with_failed_build(
@@ -701,7 +705,9 @@ class TestCrackerjackProcess:
701
705
  cj = Crackerjack(dry_run=True)
702
706
  with suppress(SystemExit):
703
707
  cj.process(options)
704
- mock_console_print.assert_any_call("\n\nBuild failed. Please fix errors.\n")
708
+ mock_console_print.assert_any_call(
709
+ "\n\n[bright_red]❌ Build failed. Please fix errors.[/bright_red]\n"
710
+ )
705
711
 
706
712
  def test_publish_project_darwin(self) -> None:
707
713
  options = OptionsForTesting(publish=BumpOption.micro)
File without changes
File without changes