crackerjack 0.15.10__py3-none-any.whl → 0.16.0__py3-none-any.whl
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/.ruff_cache/0.11.8/530407680854991027 +0 -0
- crackerjack/__main__.py +9 -0
- crackerjack/crackerjack.py +158 -0
- crackerjack/pyproject.toml +1 -1
- {crackerjack-0.15.10.dist-info → crackerjack-0.16.0.dist-info}/METADATA +9 -1
- {crackerjack-0.15.10.dist-info → crackerjack-0.16.0.dist-info}/RECORD +9 -9
- {crackerjack-0.15.10.dist-info → crackerjack-0.16.0.dist-info}/WHEEL +0 -0
- {crackerjack-0.15.10.dist-info → crackerjack-0.16.0.dist-info}/entry_points.txt +0 -0
- {crackerjack-0.15.10.dist-info → crackerjack-0.16.0.dist-info}/licenses/LICENSE +0 -0
Binary file
|
crackerjack/__main__.py
CHANGED
@@ -33,6 +33,7 @@ class Options(BaseModel):
|
|
33
33
|
test: bool = False
|
34
34
|
all: BumpOption | None = None
|
35
35
|
ai_agent: bool = False
|
36
|
+
create_pr: bool = False
|
36
37
|
|
37
38
|
@classmethod
|
38
39
|
@field_validator("publish", "bump", mode="before")
|
@@ -89,6 +90,12 @@ cli_options = {
|
|
89
90
|
help="Run with `-x -t -p <micro|minor|major> -c` development options).",
|
90
91
|
case_sensitive=False,
|
91
92
|
),
|
93
|
+
"create_pr": typer.Option(
|
94
|
+
False,
|
95
|
+
"-r",
|
96
|
+
"--pr",
|
97
|
+
help="Create a pull request to the upstream repository.",
|
98
|
+
),
|
92
99
|
"ai_agent": typer.Option(
|
93
100
|
False,
|
94
101
|
"--ai-agent",
|
@@ -111,6 +118,7 @@ def main(
|
|
111
118
|
bump: BumpOption | None = cli_options["bump"],
|
112
119
|
clean: bool = cli_options["clean"],
|
113
120
|
test: bool = cli_options["test"],
|
121
|
+
create_pr: bool = cli_options["create_pr"],
|
114
122
|
ai_agent: bool = cli_options["ai_agent"],
|
115
123
|
) -> None:
|
116
124
|
options = Options(
|
@@ -126,6 +134,7 @@ def main(
|
|
126
134
|
test=test,
|
127
135
|
all=all,
|
128
136
|
ai_agent=ai_agent,
|
137
|
+
create_pr=create_pr,
|
129
138
|
)
|
130
139
|
|
131
140
|
if ai_agent:
|
crackerjack/crackerjack.py
CHANGED
@@ -43,6 +43,7 @@ class OptionsProtocol(t.Protocol):
|
|
43
43
|
bump: t.Any | None
|
44
44
|
all: t.Any | None
|
45
45
|
ai_agent: bool = False
|
46
|
+
create_pr: bool = False
|
46
47
|
|
47
48
|
|
48
49
|
@dataclass
|
@@ -679,6 +680,159 @@ class Crackerjack:
|
|
679
680
|
)
|
680
681
|
self.execute_command(["git", "push", "origin", "main"])
|
681
682
|
|
683
|
+
def _create_pull_request(self, options: OptionsProtocol) -> None:
|
684
|
+
if options.create_pr:
|
685
|
+
self.console.print("\nCreating pull request...")
|
686
|
+
|
687
|
+
# Get the current branch name
|
688
|
+
current_branch = self.execute_command(
|
689
|
+
["git", "branch", "--show-current"], capture_output=True, text=True
|
690
|
+
).stdout.strip()
|
691
|
+
|
692
|
+
# Get the remote URL to determine if it's GitHub or GitLab
|
693
|
+
remote_url = self.execute_command(
|
694
|
+
["git", "remote", "get-url", "origin"], capture_output=True, text=True
|
695
|
+
).stdout.strip()
|
696
|
+
|
697
|
+
# Determine if we're using GitHub or GitLab
|
698
|
+
is_github = "github.com" in remote_url
|
699
|
+
is_gitlab = "gitlab.com" in remote_url
|
700
|
+
|
701
|
+
if is_github:
|
702
|
+
# Check if GitHub CLI is installed
|
703
|
+
gh_installed = (
|
704
|
+
self.execute_command(
|
705
|
+
["which", "gh"], capture_output=True, text=True
|
706
|
+
).returncode
|
707
|
+
== 0
|
708
|
+
)
|
709
|
+
|
710
|
+
if not gh_installed:
|
711
|
+
self.console.print(
|
712
|
+
"\n[red]GitHub CLI (gh) is not installed. Please install it first:[/red]\n"
|
713
|
+
" brew install gh # for macOS\n"
|
714
|
+
" or visit https://cli.github.com/ for other installation methods"
|
715
|
+
)
|
716
|
+
return
|
717
|
+
|
718
|
+
# Check if user is authenticated with GitHub
|
719
|
+
auth_status = self.execute_command(
|
720
|
+
["gh", "auth", "status"], capture_output=True, text=True
|
721
|
+
).returncode
|
722
|
+
|
723
|
+
if auth_status != 0:
|
724
|
+
self.console.print(
|
725
|
+
"\n[red]You need to authenticate with GitHub first. Run:[/red]\n"
|
726
|
+
" gh auth login"
|
727
|
+
)
|
728
|
+
return
|
729
|
+
|
730
|
+
# Prompt for PR title and description
|
731
|
+
pr_title = input("\nEnter a title for your pull request: ")
|
732
|
+
self.console.print(
|
733
|
+
"Enter a description for your pull request (press Ctrl+D when done):"
|
734
|
+
)
|
735
|
+
pr_description = ""
|
736
|
+
with suppress(EOFError):
|
737
|
+
pr_description = "".join(iter(input, ""))
|
738
|
+
|
739
|
+
# Create the pull request
|
740
|
+
self.console.print("Creating pull request to GitHub repository...")
|
741
|
+
result = self.execute_command(
|
742
|
+
[
|
743
|
+
"gh",
|
744
|
+
"pr",
|
745
|
+
"create",
|
746
|
+
"--title",
|
747
|
+
pr_title,
|
748
|
+
"--body",
|
749
|
+
pr_description,
|
750
|
+
],
|
751
|
+
capture_output=True,
|
752
|
+
text=True,
|
753
|
+
)
|
754
|
+
|
755
|
+
if result.returncode == 0:
|
756
|
+
self.console.print(
|
757
|
+
f"\n[green]Pull request created successfully![/green]\n{result.stdout}"
|
758
|
+
)
|
759
|
+
else:
|
760
|
+
self.console.print(
|
761
|
+
f"\n[red]Failed to create pull request:[/red]\n{result.stderr}"
|
762
|
+
)
|
763
|
+
|
764
|
+
elif is_gitlab:
|
765
|
+
# Check if GitLab CLI is installed
|
766
|
+
glab_installed = (
|
767
|
+
self.execute_command(
|
768
|
+
["which", "glab"], capture_output=True, text=True
|
769
|
+
).returncode
|
770
|
+
== 0
|
771
|
+
)
|
772
|
+
|
773
|
+
if not glab_installed:
|
774
|
+
self.console.print(
|
775
|
+
"\n[red]GitLab CLI (glab) is not installed. Please install it first:[/red]\n"
|
776
|
+
" brew install glab # for macOS\n"
|
777
|
+
" or visit https://gitlab.com/gitlab-org/cli for other installation methods"
|
778
|
+
)
|
779
|
+
return
|
780
|
+
|
781
|
+
# Check if user is authenticated with GitLab
|
782
|
+
auth_status = self.execute_command(
|
783
|
+
["glab", "auth", "status"], capture_output=True, text=True
|
784
|
+
).returncode
|
785
|
+
|
786
|
+
if auth_status != 0:
|
787
|
+
self.console.print(
|
788
|
+
"\n[red]You need to authenticate with GitLab first. Run:[/red]\n"
|
789
|
+
" glab auth login"
|
790
|
+
)
|
791
|
+
return
|
792
|
+
|
793
|
+
# Prompt for MR title and description
|
794
|
+
mr_title = input("\nEnter a title for your merge request: ")
|
795
|
+
self.console.print(
|
796
|
+
"Enter a description for your merge request (press Ctrl+D when done):"
|
797
|
+
)
|
798
|
+
mr_description = ""
|
799
|
+
with suppress(EOFError):
|
800
|
+
mr_description = "".join(iter(input, ""))
|
801
|
+
|
802
|
+
# Create the merge request
|
803
|
+
self.console.print("Creating merge request to GitLab repository...")
|
804
|
+
result = self.execute_command(
|
805
|
+
[
|
806
|
+
"glab",
|
807
|
+
"mr",
|
808
|
+
"create",
|
809
|
+
"--title",
|
810
|
+
mr_title,
|
811
|
+
"--description",
|
812
|
+
mr_description,
|
813
|
+
"--source-branch",
|
814
|
+
current_branch,
|
815
|
+
"--target-branch",
|
816
|
+
"main",
|
817
|
+
],
|
818
|
+
capture_output=True,
|
819
|
+
text=True,
|
820
|
+
)
|
821
|
+
|
822
|
+
if result.returncode == 0:
|
823
|
+
self.console.print(
|
824
|
+
f"\n[green]Merge request created successfully![/green]\n{result.stdout}"
|
825
|
+
)
|
826
|
+
else:
|
827
|
+
self.console.print(
|
828
|
+
f"\n[red]Failed to create merge request:[/red]\n{result.stderr}"
|
829
|
+
)
|
830
|
+
else:
|
831
|
+
self.console.print(
|
832
|
+
f"\n[red]Unsupported git hosting service: {remote_url}[/red]\n"
|
833
|
+
"This command currently supports GitHub and GitLab."
|
834
|
+
)
|
835
|
+
|
682
836
|
def execute_command(
|
683
837
|
self, cmd: list[str], **kwargs: t.Any
|
684
838
|
) -> subprocess.CompletedProcess[str]:
|
@@ -734,6 +888,10 @@ class Crackerjack:
|
|
734
888
|
if options.commit:
|
735
889
|
actions_performed.append("commit_and_push")
|
736
890
|
|
891
|
+
self._create_pull_request(options)
|
892
|
+
if options.create_pr:
|
893
|
+
actions_performed.append("create_pull_request")
|
894
|
+
|
737
895
|
# Check if we're being called by an AI agent
|
738
896
|
if getattr(options, "ai_agent", False):
|
739
897
|
# Use structured output for AI agents
|
crackerjack/pyproject.toml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: crackerjack
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.16.0
|
4
4
|
Summary: Default template for PDM package
|
5
5
|
Keywords: black,ruff,mypy,creosote,refurb
|
6
6
|
Author-Email: lesleslie <les@wedgwoodwebworks.com>
|
@@ -103,6 +103,7 @@ Crackerjack provides:
|
|
103
103
|
- **Easy Version Bumping:** Provides commands to bump the project version (micro, minor, or major).
|
104
104
|
- **Simplified Publishing:** Automates publishing to PyPI via PDM.
|
105
105
|
- **Commit and Push:** Commits and pushes your changes.
|
106
|
+
- **Pull Request Creation:** Creates pull requests to upstream repositories on GitHub or GitLab.
|
106
107
|
|
107
108
|
## Pre-commit Hooks
|
108
109
|
|
@@ -188,6 +189,7 @@ class MyOptions:
|
|
188
189
|
self.publish = None
|
189
190
|
self.bump = "micro"
|
190
191
|
self.all = None
|
192
|
+
self.create_pr = False
|
191
193
|
|
192
194
|
# Create a Crackerjack runner with custom settings
|
193
195
|
runner = create_crackerjack_runner(
|
@@ -211,6 +213,7 @@ runner.process(MyOptions())
|
|
211
213
|
- `-v`, `--verbose`: Enable verbose output.
|
212
214
|
- `-p`, `--publish <micro|minor|major>`: Bump the project version and publish to PyPI using PDM.
|
213
215
|
- `-b`, `--bump <micro|minor|major>`: Bump the project version without publishing.
|
216
|
+
- `-r`, `--pr`: Create a pull request to the upstream repository.
|
214
217
|
- `-x`, `--clean`: Clean code by removing docstrings, line comments, and extra whitespace.
|
215
218
|
- `-t`, `--test`: Run tests using `pytest`.
|
216
219
|
- `-a`, `--all`: Run with `-x -t -p <micro|minor|major> -c` development options.
|
@@ -248,6 +251,11 @@ runner.process(MyOptions())
|
|
248
251
|
python -m crackerjack -u
|
249
252
|
```
|
250
253
|
|
254
|
+
- **Create a pull request to the upstream repository:**
|
255
|
+
```
|
256
|
+
python -m crackerjack -r
|
257
|
+
```
|
258
|
+
|
251
259
|
- **Get help:**
|
252
260
|
```
|
253
261
|
python -m crackerjack --help
|
@@ -1,7 +1,7 @@
|
|
1
|
-
crackerjack-0.
|
2
|
-
crackerjack-0.
|
3
|
-
crackerjack-0.
|
4
|
-
crackerjack-0.
|
1
|
+
crackerjack-0.16.0.dist-info/METADATA,sha256=MYUBgU4OZEhpRTkR7xgUq_kpY2tUPTKSfUxKneqzovI,13198
|
2
|
+
crackerjack-0.16.0.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
crackerjack-0.16.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
4
|
+
crackerjack-0.16.0.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
|
5
5
|
crackerjack/.coverage,sha256=dLzPzp72qZEXohNfxnOAlRwvM9dqF06-HoFqfvXZd1U,53248
|
6
6
|
crackerjack/.gitignore,sha256=oho3dNx7a7y36_y9AsalCkssU4in0MMsNAANWdc-h1c,153
|
7
7
|
crackerjack/.libcst.codemod.yaml,sha256=a8DlErRAIPV1nE6QlyXPAzTOgkB24_spl2E9hphuf5s,772
|
@@ -25,7 +25,7 @@ crackerjack/.ruff_cache/0.11.4/9818742842212983150,sha256=QF9j6-3MH_d0pDNotdbF2h
|
|
25
25
|
crackerjack/.ruff_cache/0.11.6/3557596832929915217,sha256=yR2iXWDkSHVRw2eTiaCE8Eh34JPRUGc8vE3HYEEBk9k,224
|
26
26
|
crackerjack/.ruff_cache/0.11.7/10386934055395314831,sha256=lBNwN5zAgM4OzbkXIOzCczUtfooATrD10htj9ASlFkc,224
|
27
27
|
crackerjack/.ruff_cache/0.11.7/3557596832929915217,sha256=fKlwUbsvT3YIKV6UR-aA_i64lLignWeVfVu-MMmVbU0,207
|
28
|
-
crackerjack/.ruff_cache/0.11.8/530407680854991027,sha256=
|
28
|
+
crackerjack/.ruff_cache/0.11.8/530407680854991027,sha256=vY6TL3JxF2uAWURP-oNnw8Nni9A9uL8kJjfg0T4XF3o,224
|
29
29
|
crackerjack/.ruff_cache/0.2.0/10047773857155985907,sha256=j9LNa_RQ4Plor7go1uTYgz17cEENKvZQ-dP6b9MX0ik,248
|
30
30
|
crackerjack/.ruff_cache/0.2.1/8522267973936635051,sha256=u_aPBMibtAp_iYvLwR88GMAECMcIgHezxMyuapmU2P4,248
|
31
31
|
crackerjack/.ruff_cache/0.2.2/18053836298936336950,sha256=Xb_ebP0pVuUfSqPEZKlhQ70so_vqkEfMYpuHQ06iR5U,248
|
@@ -54,7 +54,7 @@ crackerjack/.ruff_cache/0.9.9/12813592349865671909,sha256=tmr8_vhRD2OxsVuMfbJPdT
|
|
54
54
|
crackerjack/.ruff_cache/0.9.9/8843823720003377982,sha256=e4ymkXfQsUg5e_mtO34xTsaTvs1uA3_fI216Qq9qCAM,136
|
55
55
|
crackerjack/.ruff_cache/CACHEDIR.TAG,sha256=WVMVbX4MVkpCclExbq8m-IcOZIOuIZf5FrYw5Pk-Ma4,43
|
56
56
|
crackerjack/__init__.py,sha256=r9SuEjHUrW99hFWifRk4ofmYPSgf9rblcnzqhdV5bP0,157
|
57
|
-
crackerjack/__main__.py,sha256=
|
58
|
-
crackerjack/crackerjack.py,sha256=
|
59
|
-
crackerjack/pyproject.toml,sha256=
|
60
|
-
crackerjack-0.
|
57
|
+
crackerjack/__main__.py,sha256=O2BZxkwH8FKIhQJyWEaLAxvFT2pRGSyr4J7nXpDKV9U,4291
|
58
|
+
crackerjack/crackerjack.py,sha256=jZ-giToWrfXR13lIQfEN7pSd2T-F9WAkD5VkkOfuoEc,35451
|
59
|
+
crackerjack/pyproject.toml,sha256=yC7E9G8aYuaOwlk59cmMW4atBjMzJDgDyeEkRmqkD4Q,4140
|
60
|
+
crackerjack-0.16.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|