gac 0.16.2__py3-none-any.whl → 0.16.3__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.
Potentially problematic release.
This version of gac might be problematic. Click here for more details.
- gac/__version__.py +1 -1
- gac/constants.py +2 -2
- gac/git.py +18 -5
- gac/prompt.py +95 -4
- gac/utils.py +6 -7
- {gac-0.16.2.dist-info → gac-0.16.3.dist-info}/METADATA +1 -1
- {gac-0.16.2.dist-info → gac-0.16.3.dist-info}/RECORD +10 -10
- {gac-0.16.2.dist-info → gac-0.16.3.dist-info}/WHEEL +0 -0
- {gac-0.16.2.dist-info → gac-0.16.3.dist-info}/entry_points.txt +0 -0
- {gac-0.16.2.dist-info → gac-0.16.3.dist-info}/licenses/LICENSE +0 -0
gac/__version__.py
CHANGED
gac/constants.py
CHANGED
|
@@ -102,8 +102,8 @@ class FileTypeImportance:
|
|
|
102
102
|
".ini": 3.5, # INI config
|
|
103
103
|
".env": 3.5, # Environment variables
|
|
104
104
|
# Documentation
|
|
105
|
-
".md":
|
|
106
|
-
".rst":
|
|
105
|
+
".md": 2.5, # Markdown (reduced to prioritize code changes)
|
|
106
|
+
".rst": 2.5, # reStructuredText (reduced to prioritize code changes)
|
|
107
107
|
# Web
|
|
108
108
|
".html": 3.5, # HTML
|
|
109
109
|
".css": 3.5, # CSS
|
gac/git.py
CHANGED
|
@@ -127,12 +127,25 @@ def run_pre_commit_hooks() -> bool:
|
|
|
127
127
|
|
|
128
128
|
# Run pre-commit hooks on staged files
|
|
129
129
|
logger.info("Running pre-commit hooks...")
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
# Run pre-commit and capture both stdout and stderr
|
|
131
|
+
result = subprocess.run(["pre-commit", "run"], capture_output=True, text=True, check=False)
|
|
132
|
+
|
|
133
|
+
if result.returncode == 0:
|
|
134
|
+
# All hooks passed
|
|
133
135
|
return True
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
else:
|
|
137
|
+
# Pre-commit hooks failed - show the output
|
|
138
|
+
output = result.stdout if result.stdout else ""
|
|
139
|
+
error = result.stderr if result.stderr else ""
|
|
140
|
+
|
|
141
|
+
# Combine outputs (pre-commit usually outputs to stdout)
|
|
142
|
+
full_output = output + ("\n" + error if error else "")
|
|
143
|
+
|
|
144
|
+
if full_output.strip():
|
|
145
|
+
# Show which hooks failed and why
|
|
146
|
+
logger.error(f"Pre-commit hooks failed:\n{full_output}")
|
|
147
|
+
else:
|
|
148
|
+
logger.error(f"Pre-commit hooks failed with exit code {result.returncode}")
|
|
136
149
|
return False
|
|
137
150
|
except Exception as e:
|
|
138
151
|
logger.debug(f"Error running pre-commit: {e}")
|
gac/prompt.py
CHANGED
|
@@ -15,6 +15,22 @@ DEFAULT_TEMPLATE = """<role>
|
|
|
15
15
|
You are an expert git commit message generator. Your task is to analyze code changes and create a concise, meaningful git commit message. You will receive git status and diff information. Your entire response will be used directly as a git commit message.
|
|
16
16
|
</role>
|
|
17
17
|
|
|
18
|
+
<focus>
|
|
19
|
+
Your commit message must reflect the core purpose and impact of these changes.
|
|
20
|
+
Prioritize the primary intent over implementation details.
|
|
21
|
+
Consider what future developers need to understand about this change.
|
|
22
|
+
Identify if this introduces new capabilities, fixes problems, or improves existing code.
|
|
23
|
+
</focus>
|
|
24
|
+
|
|
25
|
+
<mixed_changes>
|
|
26
|
+
When changes span multiple areas:
|
|
27
|
+
- Choose the commit type based on the PRIMARY purpose, not the largest file count
|
|
28
|
+
- Feature additions with supporting tests/docs should use 'feat'
|
|
29
|
+
- Bug fixes with added tests should use 'fix'
|
|
30
|
+
- Refactoring that improves multiple components should use 'refactor'
|
|
31
|
+
- Documentation updates are 'docs' only when that's the sole purpose
|
|
32
|
+
</mixed_changes>
|
|
33
|
+
|
|
18
34
|
<format>
|
|
19
35
|
<one_liner>
|
|
20
36
|
Create a single-line commit message (50-72 characters if possible).
|
|
@@ -31,10 +47,17 @@ You are an expert git commit message generator. Your task is to analyze code cha
|
|
|
31
47
|
</format>
|
|
32
48
|
|
|
33
49
|
<conventions_no_scope>
|
|
34
|
-
You MUST start your commit message with the most appropriate conventional commit prefix
|
|
50
|
+
You MUST start your commit message with the most appropriate conventional commit prefix.
|
|
51
|
+
|
|
52
|
+
IMPORTANT: Check file types FIRST when determining the commit type:
|
|
53
|
+
- If changes are ONLY to documentation files (*.md, *.rst, *.txt in docs/, README*, CHANGELOG*, etc.), ALWAYS use 'docs:'
|
|
54
|
+
- Use 'docs:' ONLY when ALL changes are documentation files - INCLUDING README updates, regardless of how significant the changes are
|
|
55
|
+
- If changes include both documentation and code, use the prefix for the code changes, unless it is a documentation-only change
|
|
56
|
+
|
|
57
|
+
Commit type prefixes:
|
|
35
58
|
- feat: A new feature or functionality addition
|
|
36
59
|
- fix: A bug fix or error correction
|
|
37
|
-
- docs: Documentation changes only
|
|
60
|
+
- docs: Documentation changes only (INCLUDING README updates, regardless of how significant)
|
|
38
61
|
- style: Changes to code style/formatting without logic changes
|
|
39
62
|
- refactor: Code restructuring without behavior changes
|
|
40
63
|
- perf: Performance improvements
|
|
@@ -55,10 +78,14 @@ You MUST write a conventional commit message with EXACTLY ONE type and the REQUI
|
|
|
55
78
|
|
|
56
79
|
FORMAT: type({scope}): description
|
|
57
80
|
|
|
81
|
+
IMPORTANT: Check file types FIRST when determining the commit type:
|
|
82
|
+
- If changes are ONLY to documentation files (*.md, *.rst, *.txt in docs/, README*, CHANGELOG*, etc.), ALWAYS use 'docs'
|
|
83
|
+
- If changes include both documentation and code, use the prefix for the code changes, unless it is a documentation-only change
|
|
84
|
+
|
|
58
85
|
Select ONE type from this list that best matches the primary purpose of the changes:
|
|
59
86
|
- feat: A new feature or functionality addition
|
|
60
87
|
- fix: A bug fix or error correction
|
|
61
|
-
- docs: Documentation changes only
|
|
88
|
+
- docs: Documentation changes only (INCLUDING README and CHANGELOG updates, regardless of how significant)
|
|
62
89
|
- style: Changes to code style/formatting without logic changes
|
|
63
90
|
- refactor: Code restructuring without behavior changes
|
|
64
91
|
- perf: Performance improvements
|
|
@@ -87,10 +114,14 @@ You MUST write a conventional commit message with EXACTLY ONE type and an inferr
|
|
|
87
114
|
|
|
88
115
|
FORMAT: type(scope): description
|
|
89
116
|
|
|
117
|
+
IMPORTANT: Check file types FIRST when determining the commit type:
|
|
118
|
+
- If changes are ONLY to documentation files (*.md, *.rst, *.txt in docs/, README*, CHANGELOG*, etc.), ALWAYS use 'docs'
|
|
119
|
+
- If changes include both documentation and code, use the prefix for the code changes, unless it is a documentation-only change
|
|
120
|
+
|
|
90
121
|
Select ONE type from this list that best matches the primary purpose of the changes:
|
|
91
122
|
- feat: A new feature or functionality addition
|
|
92
123
|
- fix: A bug fix or error correction
|
|
93
|
-
- docs: Documentation changes only
|
|
124
|
+
- docs: Documentation changes only (INCLUDING README and CHANGELOG updates, regardless of how significant)
|
|
94
125
|
- style: Changes to code style/formatting without logic changes
|
|
95
126
|
- refactor: Code restructuring without behavior changes
|
|
96
127
|
- perf: Performance improvements
|
|
@@ -100,6 +131,16 @@ Select ONE type from this list that best matches the primary purpose of the chan
|
|
|
100
131
|
- chore: Miscellaneous changes not affecting src/test files
|
|
101
132
|
|
|
102
133
|
You MUST infer an appropriate scope from the changes. A good scope is concise (usually one word) and indicates the component or area that was changed.
|
|
134
|
+
|
|
135
|
+
<scope_rules>
|
|
136
|
+
For scope inference, select the most specific component affected:
|
|
137
|
+
- Use module/component names from the codebase (auth, api, cli, core)
|
|
138
|
+
- Use functional areas for cross-cutting changes (config, build, test)
|
|
139
|
+
- Keep scopes consistent with existing commit history when possible
|
|
140
|
+
- Prefer established patterns over creating new scope names
|
|
141
|
+
- Use singular form (auth, not auths; test, not tests)
|
|
142
|
+
</scope_rules>
|
|
143
|
+
|
|
103
144
|
Examples of good scopes: api, auth, ui, core, docs, build, prompt, config
|
|
104
145
|
|
|
105
146
|
CORRECT EXAMPLES (these formats are correct):
|
|
@@ -133,6 +174,44 @@ Additional context provided by the user: <hint_text></hint_text>
|
|
|
133
174
|
<diff></diff>
|
|
134
175
|
</git_diff>
|
|
135
176
|
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
<examples_no_scope>
|
|
180
|
+
Good commit messages (no scope):
|
|
181
|
+
[OK] feat: add OAuth2 integration with Google and GitHub
|
|
182
|
+
[OK] fix: resolve race condition in user session management
|
|
183
|
+
[OK] docs: add troubleshooting section for common installation issues
|
|
184
|
+
[OK] refactor: extract validation logic into reusable utilities
|
|
185
|
+
[OK] test: add comprehensive unit tests for token validation
|
|
186
|
+
[OK] build: upgrade to latest security patches
|
|
187
|
+
|
|
188
|
+
Bad commit messages:
|
|
189
|
+
[ERROR] fix stuff
|
|
190
|
+
[ERROR] update code
|
|
191
|
+
[ERROR] feat(auth): add login (scope included when not requested)
|
|
192
|
+
[ERROR] WIP: still working on this
|
|
193
|
+
[ERROR] Fixed bug
|
|
194
|
+
[ERROR] Changes
|
|
195
|
+
</examples_no_scope>
|
|
196
|
+
|
|
197
|
+
<examples_with_scope>
|
|
198
|
+
Good commit messages (with scope):
|
|
199
|
+
[OK] feat(auth): add OAuth2 integration with Google and GitHub
|
|
200
|
+
[OK] fix(api): resolve race condition in user session management
|
|
201
|
+
[OK] docs(readme): add troubleshooting section for common installation issues
|
|
202
|
+
[OK] refactor(core): extract validation logic into reusable utilities
|
|
203
|
+
[OK] test(auth): add comprehensive unit tests for token validation
|
|
204
|
+
[OK] build(deps): upgrade to latest security patches
|
|
205
|
+
|
|
206
|
+
Bad commit messages:
|
|
207
|
+
[ERROR] fix stuff
|
|
208
|
+
[ERROR] update code
|
|
209
|
+
[ERROR] feat: fix(auth): add login (double prefix)
|
|
210
|
+
[ERROR] WIP: still working on this
|
|
211
|
+
[ERROR] Fixed bug
|
|
212
|
+
[ERROR] Changes
|
|
213
|
+
</examples_with_scope>
|
|
214
|
+
|
|
136
215
|
<instructions>
|
|
137
216
|
IMMEDIATELY AFTER ANALYZING THE CHANGES, RESPOND WITH ONLY THE COMMIT MESSAGE.
|
|
138
217
|
DO NOT include any preamble, reasoning, explanations or anything other than the commit message itself.
|
|
@@ -237,6 +316,18 @@ def build_prompt(
|
|
|
237
316
|
else:
|
|
238
317
|
template = re.sub(r"<one_liner>.*?</one_liner>", "", template, flags=re.DOTALL)
|
|
239
318
|
|
|
319
|
+
# Clean up examples sections based on scope settings
|
|
320
|
+
if scope is None:
|
|
321
|
+
# No scope - keep no_scope examples, remove scope examples
|
|
322
|
+
template = re.sub(r"<examples_with_scope>.*?</examples_with_scope>\n?", "", template, flags=re.DOTALL)
|
|
323
|
+
template = template.replace("<examples_no_scope>", "<examples>")
|
|
324
|
+
template = template.replace("</examples_no_scope>", "</examples>")
|
|
325
|
+
else:
|
|
326
|
+
# With scope (either provided or inferred) - keep scope examples, remove no_scope examples
|
|
327
|
+
template = re.sub(r"<examples_no_scope>.*?</examples_no_scope>\n?", "", template, flags=re.DOTALL)
|
|
328
|
+
template = template.replace("<examples_with_scope>", "<examples>")
|
|
329
|
+
template = template.replace("</examples_with_scope>", "</examples>")
|
|
330
|
+
|
|
240
331
|
# Clean up extra whitespace, collapsing blank lines that may contain spaces
|
|
241
332
|
template = re.sub(r"\n(?:[ \t]*\n){2,}", "\n\n", template)
|
|
242
333
|
|
gac/utils.py
CHANGED
|
@@ -102,12 +102,12 @@ def run_subprocess(
|
|
|
102
102
|
timeout=timeout,
|
|
103
103
|
)
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
should_raise = result.returncode != 0 and (check or raise_on_error)
|
|
106
|
+
|
|
107
|
+
if should_raise:
|
|
106
108
|
if not silent:
|
|
107
109
|
logger.debug(f"Command stderr: {result.stderr}")
|
|
108
|
-
|
|
109
|
-
error = subprocess.CalledProcessError(result.returncode, command, result.stdout, result.stderr)
|
|
110
|
-
raise error
|
|
110
|
+
raise subprocess.CalledProcessError(result.returncode, command, result.stdout, result.stderr)
|
|
111
111
|
|
|
112
112
|
output = result.stdout
|
|
113
113
|
if strip_output:
|
|
@@ -119,7 +119,7 @@ def run_subprocess(
|
|
|
119
119
|
raise GacError(f"Command timed out: {' '.join(command)}") from e
|
|
120
120
|
except subprocess.CalledProcessError as e:
|
|
121
121
|
if not silent:
|
|
122
|
-
logger.error(f"Command failed: {e.stderr.strip() if
|
|
122
|
+
logger.error(f"Command failed: {e.stderr.strip() if e.stderr else str(e)}")
|
|
123
123
|
if raise_on_error:
|
|
124
124
|
raise
|
|
125
125
|
return ""
|
|
@@ -128,6 +128,5 @@ def run_subprocess(
|
|
|
128
128
|
logger.debug(f"Command error: {e}")
|
|
129
129
|
if raise_on_error:
|
|
130
130
|
# Convert generic exceptions to CalledProcessError for consistency
|
|
131
|
-
|
|
132
|
-
raise error from e
|
|
131
|
+
raise subprocess.CalledProcessError(1, command, "", str(e)) from e
|
|
133
132
|
return ""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gac
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.3
|
|
4
4
|
Summary: AI-powered Git commit message generator with multi-provider support
|
|
5
5
|
Project-URL: Homepage, https://github.com/cellwebb/gac
|
|
6
6
|
Project-URL: Documentation, https://github.com/cellwebb/gac#readme
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
gac/__init__.py,sha256=z9yGInqtycFIT3g1ca24r-A3699hKVaRqGUI79wsmMc,415
|
|
2
|
-
gac/__version__.py,sha256=
|
|
2
|
+
gac/__version__.py,sha256=ZrOgRPcn114KgqOkRlJyqV-9NfDnOY4PEJ2z42L5dj8,67
|
|
3
3
|
gac/ai.py,sha256=kxZ0UMU_2i9Vb2fXKAUcuFCeZJAZ9G8OSjgTVF06h-Y,5452
|
|
4
4
|
gac/cli.py,sha256=UCGaKpGrm8B603V04yMYGkfv9S5-CksSy7zzeqwp13s,4280
|
|
5
5
|
gac/config.py,sha256=7gyD4dDZhb_xL0gjOxfA3cqmz-5LwaMUT3MCTAPBjug,1330
|
|
6
6
|
gac/config_cli.py,sha256=v9nFHZO1RvK9fzHyuUS6SG-BCLHMsdOMDwWamBhVVh4,1608
|
|
7
|
-
gac/constants.py,sha256=
|
|
7
|
+
gac/constants.py,sha256=7ynwnS6wxT3o7KEed1MZuWrJ9jGf-Yp5aIxRH8P3uwg,4805
|
|
8
8
|
gac/diff_cli.py,sha256=wnVQ9OFGnM0d2Pj9WVjWbo0jxqIuRHVAwmb8wU9Pa3E,5676
|
|
9
9
|
gac/errors.py,sha256=3vIRMQ2QF3sP9_rPfXAFuu5ZSjIVX4FxM-FAuiR8N-8,7416
|
|
10
|
-
gac/git.py,sha256=
|
|
10
|
+
gac/git.py,sha256=csjPf9YzxpYaZjIzIfa0yKTV64q22f718j_Zc9Q9maQ,5725
|
|
11
11
|
gac/init_cli.py,sha256=aNllguofrcLn0ML9tzLVWFkPbwlAvCM9m7undHhMLEo,1825
|
|
12
12
|
gac/main.py,sha256=_BX_B9Denex9MwceT1udBQjzoMLLD2czU8TlHvPRE80,9520
|
|
13
13
|
gac/preprocess.py,sha256=4igtZ9OTHgTpqwlJmbcGaqzmdD0HHCZJwsZ9eG118Gk,15360
|
|
14
|
-
gac/prompt.py,sha256=
|
|
15
|
-
gac/utils.py,sha256=
|
|
16
|
-
gac-0.16.
|
|
17
|
-
gac-0.16.
|
|
18
|
-
gac-0.16.
|
|
19
|
-
gac-0.16.
|
|
20
|
-
gac-0.16.
|
|
14
|
+
gac/prompt.py,sha256=i6XPWXCC_v1k2wVkv5FlL540RKG5uS-U6HJU9wC-cGw,18291
|
|
15
|
+
gac/utils.py,sha256=W3ladtmsH01MNLdckQYTzYrYbTGEdzCKI36he9C-y_E,3945
|
|
16
|
+
gac-0.16.3.dist-info/METADATA,sha256=TvCN3km323w51BSIuHKLE-PJVAoJU4RcUXeqGBeg_JU,7569
|
|
17
|
+
gac-0.16.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
18
|
+
gac-0.16.3.dist-info/entry_points.txt,sha256=tdjN-XMmcWfL92swuRAjT62bFLOAwk9bTMRLGP5Z4aI,36
|
|
19
|
+
gac-0.16.3.dist-info/licenses/LICENSE,sha256=s11puNmYfzwoSwG96nhOJe268Y1QFckr8-Hmzo3_eJE,1087
|
|
20
|
+
gac-0.16.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|