git-commit-guard 0.6.0__tar.gz → 0.8.0__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.
Files changed (24) hide show
  1. git_commit_guard-0.8.0/.github/workflows/lint-md.yml +26 -0
  2. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/.pre-commit-hooks.yaml +11 -0
  3. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/PKG-INFO +51 -7
  4. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/README.md +50 -6
  5. git_commit_guard-0.8.0/htmlcov/.gitignore +2 -0
  6. git_commit_guard-0.8.0/htmlcov/class_index.html +161 -0
  7. git_commit_guard-0.8.0/htmlcov/coverage_html_cb_dd2e7eb5.js +735 -0
  8. git_commit_guard-0.8.0/htmlcov/favicon_32_cb_c827f16f.png +0 -0
  9. git_commit_guard-0.8.0/htmlcov/function_index.html +331 -0
  10. git_commit_guard-0.8.0/htmlcov/index.html +117 -0
  11. git_commit_guard-0.8.0/htmlcov/keybd_closed_cb_900cfef5.png +0 -0
  12. git_commit_guard-0.8.0/htmlcov/status.json +1 -0
  13. git_commit_guard-0.8.0/htmlcov/style_cb_9ff733b0.css +389 -0
  14. git_commit_guard-0.8.0/htmlcov/z_262b75d81d1cf686___init___py.html +454 -0
  15. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/src/git_commit_guard/__init__.py +90 -15
  16. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/tests/test_git_commit_guard.py +180 -1
  17. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/.github/workflows/lint-commits.yml +0 -0
  18. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/.github/workflows/test.yml +0 -0
  19. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/.gitignore +0 -0
  20. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/.python-version +0 -0
  21. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/LICENSE +0 -0
  22. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/pyproject.toml +0 -0
  23. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/tests/__init__.py +0 -0
  24. {git_commit_guard-0.6.0 → git_commit_guard-0.8.0}/uv.lock +0 -0
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: Lint Markdown
3
+ on: # yamllint disable-line rule:truthy
4
+ pull_request:
5
+ permissions:
6
+ contents: read
7
+ jobs:
8
+ lint-md:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ contents: read
12
+ pull-requests: write
13
+ steps:
14
+ - name: Checkout code
15
+ # yamllint disable-line rule:line-length
16
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
17
+ with:
18
+ persist-credentials: false
19
+ - name: Lint Markdown files with reviewdog
20
+ # yamllint disable-line rule:line-length
21
+ uses: reviewdog/action-markdownlint@3667398db9118d7e78f7a63d10e26ce454ba5f58 # v0.26.2
22
+ with:
23
+ github_token: ${{ secrets.GITHUB_TOKEN }}
24
+ reporter: github-pr-review
25
+ level: info
26
+ fail_on_error: true
@@ -10,3 +10,14 @@
10
10
  always_run: true
11
11
  pass_filenames: true
12
12
  minimum_pre_commit_version: 2.8.0
13
+
14
+ - id: commit-guard-signature
15
+ name: commit-guard (signature)
16
+ description: Verify commit is GPG/SSH signed
17
+ entry: commit-guard
18
+ args: [HEAD, --enable, signature]
19
+ language: python
20
+ stages: [post-commit]
21
+ always_run: true
22
+ pass_filenames: false
23
+ minimum_pre_commit_version: 2.8.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-commit-guard
3
- Version: 0.6.0
3
+ Version: 0.8.0
4
4
  Summary: Opinionated conventional commit message linter with imperative mood detection
5
5
  Project-URL: Homepage, https://github.com/benner/commit-guard
6
6
  Project-URL: Repository, https://github.com/benner/commit-guard
@@ -31,7 +31,8 @@ imperative verb.
31
31
 
32
32
  ```bash
33
33
  $ commit-guard
34
- ✗ subject does not match 'type(scope): description': Merge pull request #5 from fix/branch
34
+ ✗ subject does not match 'type(scope): description':
35
+ Merge pull request #5 from fix/branch
35
36
  ✗ missing 'Signed-off-by' trailer
36
37
  ✗ commit is not signed (GPG/SSH)
37
38
  ```
@@ -100,6 +101,45 @@ Available checks:
100
101
  * `signed-off` - `Signed-off-by:` trailer exists
101
102
  * `signature` - Verify GPG or SSH signature
102
103
 
104
+ ### Scope validation
105
+
106
+ By default any scope is accepted and scope is optional. Use `--scopes` to
107
+ restrict allowed values and `--require-scope` to enforce that a scope is always
108
+ present:
109
+
110
+ ```bash
111
+ # only allow known scopes
112
+ commit-guard --scopes auth,api,db
113
+
114
+ # require a scope
115
+ commit-guard --require-scope
116
+
117
+ # combine both
118
+ commit-guard --scopes auth,api --require-scope
119
+ ```
120
+
121
+ ### Configuration file
122
+
123
+ Place `.commit-guard.toml` in your project root (or any parent directory) to
124
+ set defaults for `enable`, `disable`, `scopes`, and `require-scope`.
125
+ commit-guard searches upward from the working directory and uses the first file
126
+ found.
127
+
128
+ ```toml
129
+ # .commit-guard.toml
130
+ disable = ["signature", "body"]
131
+ scopes = ["auth", "api", "db"]
132
+ require-scope = true
133
+ ```
134
+
135
+ ```toml
136
+ # .commit-guard.toml
137
+ enable = ["subject", "imperative"]
138
+ ```
139
+
140
+ CLI flags (`--enable`, `--disable`, `--scopes`, `--require-scope`) take full
141
+ precedence and ignore config file values when provided.
142
+
103
143
  ### Checking a range of commits
104
144
 
105
145
  ```bash
@@ -125,14 +165,19 @@ repos:
125
165
  rev: v0.1.0
126
166
  hooks:
127
167
  - id: commit-guard
168
+ - id: commit-guard-signature
128
169
  ```
129
170
 
130
- Install the hook:
171
+ Install the hooks:
131
172
 
132
173
  ```bash
133
- pre-commit install --hook-type commit-msg
174
+ pre-commit install --hook-type commit-msg --hook-type post-commit
134
175
  ```
135
176
 
177
+ `commit-guard` runs at the `commit-msg` stage and checks message format.
178
+ `commit-guard-signature` runs at the `post-commit` stage and verifies
179
+ the GPG/SSH signature after the commit object is created.
180
+
136
181
  To selectively enable or disable checks, pass `args`:
137
182
 
138
183
  ```yaml
@@ -144,10 +189,9 @@ To selectively enable or disable checks, pass `args`:
144
189
 
145
190
  commit-guard combines two strategies to detect non-imperative descriptions:
146
191
 
147
- 1. A whitelist common commit verbs (`add`, `fix`, `remove`, etc.)
148
- that pass immediately without NLP.
149
- 2. nltk POS tagging as a fallback — flags words tagged as past tense (`VBD`),
192
+ 1. nltk POS tagging flags words tagged as past tense (`VBD`),
150
193
  gerund (`VBG`), third person (`VBZ`), etc.
194
+ 2. WordNet morphology as a fallback for words the tagger misclassifies.
151
195
 
152
196
  This catches common mistakes like `added logging` or `fixes bug` while
153
197
  keeping false positives low.
@@ -10,7 +10,8 @@ imperative verb.
10
10
 
11
11
  ```bash
12
12
  $ commit-guard
13
- ✗ subject does not match 'type(scope): description': Merge pull request #5 from fix/branch
13
+ ✗ subject does not match 'type(scope): description':
14
+ Merge pull request #5 from fix/branch
14
15
  ✗ missing 'Signed-off-by' trailer
15
16
  ✗ commit is not signed (GPG/SSH)
16
17
  ```
@@ -79,6 +80,45 @@ Available checks:
79
80
  * `signed-off` - `Signed-off-by:` trailer exists
80
81
  * `signature` - Verify GPG or SSH signature
81
82
 
83
+ ### Scope validation
84
+
85
+ By default any scope is accepted and scope is optional. Use `--scopes` to
86
+ restrict allowed values and `--require-scope` to enforce that a scope is always
87
+ present:
88
+
89
+ ```bash
90
+ # only allow known scopes
91
+ commit-guard --scopes auth,api,db
92
+
93
+ # require a scope
94
+ commit-guard --require-scope
95
+
96
+ # combine both
97
+ commit-guard --scopes auth,api --require-scope
98
+ ```
99
+
100
+ ### Configuration file
101
+
102
+ Place `.commit-guard.toml` in your project root (or any parent directory) to
103
+ set defaults for `enable`, `disable`, `scopes`, and `require-scope`.
104
+ commit-guard searches upward from the working directory and uses the first file
105
+ found.
106
+
107
+ ```toml
108
+ # .commit-guard.toml
109
+ disable = ["signature", "body"]
110
+ scopes = ["auth", "api", "db"]
111
+ require-scope = true
112
+ ```
113
+
114
+ ```toml
115
+ # .commit-guard.toml
116
+ enable = ["subject", "imperative"]
117
+ ```
118
+
119
+ CLI flags (`--enable`, `--disable`, `--scopes`, `--require-scope`) take full
120
+ precedence and ignore config file values when provided.
121
+
82
122
  ### Checking a range of commits
83
123
 
84
124
  ```bash
@@ -104,14 +144,19 @@ repos:
104
144
  rev: v0.1.0
105
145
  hooks:
106
146
  - id: commit-guard
147
+ - id: commit-guard-signature
107
148
  ```
108
149
 
109
- Install the hook:
150
+ Install the hooks:
110
151
 
111
152
  ```bash
112
- pre-commit install --hook-type commit-msg
153
+ pre-commit install --hook-type commit-msg --hook-type post-commit
113
154
  ```
114
155
 
156
+ `commit-guard` runs at the `commit-msg` stage and checks message format.
157
+ `commit-guard-signature` runs at the `post-commit` stage and verifies
158
+ the GPG/SSH signature after the commit object is created.
159
+
115
160
  To selectively enable or disable checks, pass `args`:
116
161
 
117
162
  ```yaml
@@ -123,10 +168,9 @@ To selectively enable or disable checks, pass `args`:
123
168
 
124
169
  commit-guard combines two strategies to detect non-imperative descriptions:
125
170
 
126
- 1. A whitelist common commit verbs (`add`, `fix`, `remove`, etc.)
127
- that pass immediately without NLP.
128
- 2. nltk POS tagging as a fallback — flags words tagged as past tense (`VBD`),
171
+ 1. nltk POS tagging flags words tagged as past tense (`VBD`),
129
172
  gerund (`VBG`), third person (`VBZ`), etc.
173
+ 2. WordNet morphology as a fallback for words the tagger misclassifies.
130
174
 
131
175
  This catches common mistakes like `added logging` or `fixes bug` while
132
176
  keeping false positives low.
@@ -0,0 +1,2 @@
1
+ # Created by coverage.py
2
+ *
@@ -0,0 +1,161 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+ <title>Coverage report</title>
6
+ <link rel="icon" sizes="32x32" href="favicon_32_cb_c827f16f.png">
7
+ <link rel="stylesheet" href="style_cb_9ff733b0.css" type="text/css">
8
+ <script src="coverage_html_cb_dd2e7eb5.js" defer></script>
9
+ </head>
10
+ <body class="indexfile">
11
+ <header>
12
+ <div class="content">
13
+ <h1>Coverage report:
14
+ <span class="pc_cov">99%</span>
15
+ </h1>
16
+ <aside id="help_panel_wrapper">
17
+ <input id="help_panel_state" type="checkbox">
18
+ <label for="help_panel_state">
19
+ <img id="keyboard_icon" src="keybd_closed_cb_900cfef5.png" alt="Show/hide keyboard shortcuts">
20
+ </label>
21
+ <div id="help_panel">
22
+ <p class="legend">Shortcuts on this page</p>
23
+ <div class="keyhelp">
24
+ <p>
25
+ <kbd>f</kbd>
26
+ <kbd>n</kbd>
27
+ <kbd>s</kbd>
28
+ <kbd>m</kbd>
29
+ <kbd>x</kbd>
30
+ <kbd>c</kbd>
31
+ &nbsp; change column sorting
32
+ </p>
33
+ <p>
34
+ <kbd>[</kbd>
35
+ <kbd>]</kbd>
36
+ &nbsp; prev/next file
37
+ </p>
38
+ <p>
39
+ <kbd>?</kbd> &nbsp; show/hide this help
40
+ </p>
41
+ </div>
42
+ </div>
43
+ </aside>
44
+ <form id="filter_container">
45
+ <input id="filter" type="text" value="" placeholder="filter...">
46
+ <div>
47
+ <input id="hide100" type="checkbox" >
48
+ <label for="hide100">hide covered</label>
49
+ </div>
50
+ </form>
51
+ <h2>
52
+ <a class="button" href="index.html">Files</a>
53
+ <a class="button" href="function_index.html">Functions</a>
54
+ <a class="button current">Classes</a>
55
+ </h2>
56
+ <p class="text">
57
+ <a class="nav" href="https://coverage.readthedocs.io/en/7.13.5">coverage.py v7.13.5</a>,
58
+ created at 2026-04-18 23:09 +0300
59
+ </p>
60
+ </div>
61
+ </header>
62
+ <main id="index">
63
+ <table class="index" data-sortable>
64
+ <thead>
65
+ <tr class="tablehead" title="Click to sort">
66
+ <th id="file" class="name" aria-sort="none" data-shortcut="f">File<span class="arrows"></span></th>
67
+ <th id="region" class="name" aria-sort="none" data-default-sort-order="ascending" data-shortcut="n">class<span class="arrows"></span></th>
68
+ <th class="spacer">&nbsp;</th>
69
+ <th id="statements" aria-sort="none" data-default-sort-order="descending" data-shortcut="s">statements<span class="arrows"></span></th>
70
+ <th id="missing" aria-sort="none" data-default-sort-order="descending" data-shortcut="m">missing<span class="arrows"></span></th>
71
+ <th id="excluded" aria-sort="none" data-default-sort-order="descending" data-shortcut="x">excluded<span class="arrows"></span></th>
72
+ <th class="spacer">&nbsp;</th>
73
+ <th id="coverage" aria-sort="none" data-shortcut="c">coverage<span class="arrows"></span></th>
74
+ </tr>
75
+ </thead>
76
+ <tbody>
77
+ <tr class="region">
78
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html#t44">src&#8201;/&#8201;git_commit_guard&#8201;/&#8201;__init__.py</a></td>
79
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html#t44"><data value='Check'>Check</data></a></td>
80
+ <td class="spacer">&nbsp;</td>
81
+ <td>0</td>
82
+ <td>0</td>
83
+ <td>0</td>
84
+ <td class="spacer">&nbsp;</td>
85
+ <td data-ratio="0 0">100%</td>
86
+ </tr>
87
+ <tr class="region">
88
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html#t72">src&#8201;/&#8201;git_commit_guard&#8201;/&#8201;__init__.py</a></td>
89
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html#t72"><data value='Level'>Level</data></a></td>
90
+ <td class="spacer">&nbsp;</td>
91
+ <td>0</td>
92
+ <td>0</td>
93
+ <td>0</td>
94
+ <td class="spacer">&nbsp;</td>
95
+ <td data-ratio="0 0">100%</td>
96
+ </tr>
97
+ <tr class="region">
98
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html#t86">src&#8201;/&#8201;git_commit_guard&#8201;/&#8201;__init__.py</a></td>
99
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html#t86"><data value='Result'>Result</data></a></td>
100
+ <td class="spacer">&nbsp;</td>
101
+ <td>4</td>
102
+ <td>0</td>
103
+ <td>0</td>
104
+ <td class="spacer">&nbsp;</td>
105
+ <td data-ratio="4 4">100%</td>
106
+ </tr>
107
+ <tr class="region">
108
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html#t218">src&#8201;/&#8201;git_commit_guard&#8201;/&#8201;__init__.py</a></td>
109
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html#t218"><data value='Args'>Args</data></a></td>
110
+ <td class="spacer">&nbsp;</td>
111
+ <td>0</td>
112
+ <td>0</td>
113
+ <td>0</td>
114
+ <td class="spacer">&nbsp;</td>
115
+ <td data-ratio="0 0">100%</td>
116
+ </tr>
117
+ <tr class="region">
118
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html">src&#8201;/&#8201;git_commit_guard&#8201;/&#8201;__init__.py</a></td>
119
+ <td class="name"><a href="z_262b75d81d1cf686___init___py.html"><data value=''><span class='no-noun'>(no class)</span></data></a></td>
120
+ <td class="spacer">&nbsp;</td>
121
+ <td>212</td>
122
+ <td>2</td>
123
+ <td>0</td>
124
+ <td class="spacer">&nbsp;</td>
125
+ <td data-ratio="210 212">99%</td>
126
+ </tr>
127
+ </tbody>
128
+ <tfoot>
129
+ <tr class="total">
130
+ <td class="name">Total</td>
131
+ <td class="name">&nbsp;</td>
132
+ <td class="spacer">&nbsp;</td>
133
+ <td>216</td>
134
+ <td>2</td>
135
+ <td>0</td>
136
+ <td class="spacer">&nbsp;</td>
137
+ <td data-ratio="214 216">99%</td>
138
+ </tr>
139
+ </tfoot>
140
+ </table>
141
+ <p id="no_rows">
142
+ No items found using the specified filter.
143
+ </p>
144
+ </main>
145
+ <footer>
146
+ <div class="content">
147
+ <p>
148
+ <a class="nav" href="https://coverage.readthedocs.io/en/7.13.5">coverage.py v7.13.5</a>,
149
+ created at 2026-04-18 23:09 +0300
150
+ </p>
151
+ </div>
152
+ <aside class="hidden">
153
+ <a id="prevFileLink" class="nav" href=""></a>
154
+ <a id="nextFileLink" class="nav" href=""></a>
155
+ <button type="button" class="button_prev_file" data-shortcut="["></button>
156
+ <button type="button" class="button_next_file" data-shortcut="]"></button>
157
+ <button type="button" class="button_show_hide_help" data-shortcut="?"></button>
158
+ </aside>
159
+ </footer>
160
+ </body>
161
+ </html>