commit-check 2.19.2__py3-none-any.whl → 2.19.4__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.
commit_check/__init__.py CHANGED
@@ -86,6 +86,10 @@ DEFAULT_BRANCH_TYPES = [
86
86
  "codex",
87
87
  "copilot",
88
88
  "cursor",
89
+ # VS Code's Agents window hard-codes this prefix and users cannot change
90
+ # it; the spec will accept it as an alias of "ai"
91
+ # (https://github.com/conventional-branch/conventional-branch/issues/196).
92
+ "agents",
89
93
  # Automation/bot prefixes
90
94
  "dependabot",
91
95
  "renovate",
@@ -242,15 +242,35 @@ CURSOR = KnownAiTool(
242
242
  # Cursor's agent signs as ``Cursor Agent <cursoragent@cursor.com>``;
243
243
  # the address catches it under any display name.
244
244
  *_identity(r"[^<\n]*<cursoragent@cursor\.com>", "... <cursoragent@cursor.com>"),
245
+ # Cursor's own mark on commits it writes:
246
+ # https://forum.cursor.com/t/allow-disabling-made-with-cursor-commit-trailer/154494
247
+ _trailer(
248
+ ("Made-with",), r"Cursor", ROLE_STAMP, "``Made-with: Cursor`` trailer"
249
+ ),
245
250
  ],
246
251
  )
247
252
 
248
253
  # --- Devin ---
254
+ # Devin credits itself as ``Devin AI`` with its GitHub App's address,
255
+ # ``158243242+devin-ai-integration[bot]@users.noreply.github.com``.
256
+ # "Devin" alone is a person's name, so with an address it counts only when
257
+ # the address is the app's.
249
258
  DEVIN = KnownAiTool(
250
259
  name="Devin",
251
260
  name_pattern=_names(r"devin"),
252
261
  patterns=[
253
- *_identity(r"Devin[ \t]*(?:<[^>\n]*>)?", "Devin"),
262
+ *_identity(r"Devin AI[ \t]*(?:<[^>\n]*>)?", "Devin AI"),
263
+ *_identity(
264
+ r"Devin(?:[ \t]*<(?:\d+\+)?devin-ai-integration\[bot\]"
265
+ r"@users\.noreply\.github\.com>)?",
266
+ "Devin",
267
+ ),
268
+ # The app's address catches it under any display name.
269
+ *_identity(
270
+ r"[^<\n]*<(?:\d+\+)?devin-ai-integration\[bot\]"
271
+ r"@users\.noreply\.github\.com>",
272
+ "... <N+devin-ai-integration[bot]@users.noreply.github.com>",
273
+ ),
254
274
  ],
255
275
  )
256
276
 
@@ -21,6 +21,7 @@ from commit_check import (
21
21
  GIT_MERGE_SUBJECT_PATTERN,
22
22
  )
23
23
  from commit_check.config import ConfigError
24
+ from commit_check.config_merger import get_default_config
24
25
  from commit_check.rules_catalog import (
25
26
  BRANCH_RULES,
26
27
  COMMIT_RULES,
@@ -194,6 +195,32 @@ def _string_list(
194
195
  )
195
196
 
196
197
 
198
+ #: The settings that take ``true`` or ``false``, as (section, key).
199
+ _BOOLEAN_SETTINGS = tuple(
200
+ (section, key)
201
+ for section, defaults in get_default_config().items()
202
+ for key, default in defaults.items()
203
+ if isinstance(default, bool)
204
+ )
205
+
206
+
207
+ def _check_booleans(config: dict[str, Any]) -> None:
208
+ """Refuse a boolean setting given anything but ``true`` or ``false``.
209
+
210
+ ``"false"`` is a non-empty string, so it used to turn the rule on.
211
+ """
212
+ for section, key in _BOOLEAN_SETTINGS:
213
+ values = config.get(section)
214
+ if not isinstance(values, dict):
215
+ continue
216
+ value = values.get(key)
217
+ if value is not None and not isinstance(value, bool):
218
+ setting = f"[{section}] {key}"
219
+ raise ConfigError(
220
+ f"{setting} must be true or false, got {value!r}", setting=setting
221
+ )
222
+
223
+
197
224
  class RuleBuilder:
198
225
  """Builds validation rules from config and catalog entries."""
199
226
 
@@ -204,6 +231,7 @@ class RuleBuilder:
204
231
  self.push_config = config.get("push", {})
205
232
  self.tag_config = config.get("tag", {})
206
233
  self.files_config = config.get("files", {})
234
+ _check_booleans(config)
207
235
  self.warn_checks = self._resolve_warn_list(config.get("warn", []))
208
236
 
209
237
  def build_all_rules(self) -> list[ValidationRule]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: commit-check
3
- Version: 2.19.2
3
+ Version: 2.19.4
4
4
  Summary: Commit policy as code for teams and AI agents: check commit messages, branch names, authors, tags, files and AI attribution.
5
5
  Author-email: Xianpeng Shen <xianpeng.shen@gmail.com>
6
6
  License-Expression: MIT
@@ -65,6 +65,10 @@ attribution against one `cchk.toml` — in your commit hook, in CI, on every
65
65
  pull request and inside your AI agent. When the fix is obvious, it hands you
66
66
  the line.
67
67
 
68
+ **On GitHub?** [Install the Commit Check App](https://github.com/apps/commit-check)
69
+ and every push and pull request gets a check run, with no workflow file. It is
70
+ free for public repositories and personal accounts.
71
+
68
72
  ![commit-check demo](https://github.com/commit-check/commit-check/raw/main/assets/demo.gif)
69
73
 
70
74
  ## Quick start
@@ -84,7 +88,7 @@ Stop bad commits before they exist. In `.pre-commit-config.yaml`:
84
88
  ```yaml
85
89
  repos:
86
90
  - repo: https://github.com/commit-check/commit-check
87
- rev: v2.19.0
91
+ rev: v2.19.4
88
92
  hooks:
89
93
  - id: check-message
90
94
  - id: check-branch
@@ -102,8 +106,8 @@ The same `cchk.toml` drives all of them:
102
106
 
103
107
  | Run it in | How |
104
108
  |---|---|
105
- | GitHub Actions | `uses: commit-check/commit-check-action@v2` — see [commit-check-action](https://github.com/commit-check/commit-check-action) |
106
109
  | GitHub, no workflow | [Install the GitHub App](https://github.com/apps/commit-check) — one check run per commit |
110
+ | GitHub Actions | `uses: commit-check/commit-check-action@v2` — see [commit-check-action](https://github.com/commit-check/commit-check-action) |
107
111
  | AI agents | `--format json`, the [Python API](#ai-native-usage), or the [MCP server](https://github.com/commit-check/commit-check-mcp) |
108
112
 
109
113
  ## What it checks
@@ -171,7 +175,7 @@ Priority: CLI > env > TOML > default. Booleans accept `true/false`, `yes/no`,
171
175
  | `commit.author_name_pattern` | `""` | `--author-name-pattern` | `CCHK_AUTHOR_NAME_PATTERN` | Regex the author name must match (CC101, with `--author-name`) |
172
176
  | `branch.conventional_branch` | `true` | `--conventional-branch` | `CCHK_CONVENTIONAL_BRANCH` | Enforce `<type>/<description>` branch names (CC201) |
173
177
  | `branch.require_description_grammar` | `false` | `--require-description-grammar` | `CCHK_REQUIRE_DESCRIPTION_GRAMMAR` | Also hold the description after `<type>/` to the Conventional Branch grammar: lowercase alphanumeric words joined by single hyphens, dots allowed inside a word (CC201). Off by default, since bot branches such as `dependabot/npm_and_yarn/lodash-4.17.21` do not follow it |
174
- | `branch.allow_branch_types` | `feature, bugfix, hotfix, release, chore, feat, fix, build, ci, docs, perf, refactor, test, style, ai, claude, codex, copilot, cursor, dependabot, renovate` | `--allow-branch-types` | `CCHK_ALLOW_BRANCH_TYPES` | Allowed branch `<type>` prefixes; each entry is a regex matched against the whole type |
178
+ | `branch.allow_branch_types` | `feature, bugfix, hotfix, release, chore, feat, fix, build, ci, docs, perf, refactor, test, style, ai, claude, codex, copilot, cursor, agents, dependabot, renovate` | `--allow-branch-types` | `CCHK_ALLOW_BRANCH_TYPES` | Allowed branch `<type>` prefixes; each entry is a regex matched against the whole type |
175
179
  | `branch.allow_branch_names` | `[]` | `--allow-branch-names` | `CCHK_ALLOW_BRANCH_NAMES` | Extra branch names allowed besides `main`, `master`, `develop`, `HEAD`, `PR-.+`; each entry is a regex matched against the whole branch name, so `create-pull-request/.+` allows a family of them |
176
180
  | `branch.require_rebase_target` | `""` | `--require-rebase-target` | `CCHK_REQUIRE_REBASE_TARGET` | Branch the current branch must be rebased onto (CC202); empty disables |
177
181
  | `branch.ignore_authors` | `[]` | `--branch-ignore-authors` | `CCHK_BRANCH_IGNORE_AUTHORS` | Authors whose branches skip the branch checks |
@@ -231,8 +235,10 @@ shape. Unlike the CLI they do not read `cchk.toml`: pass the policy as a
231
235
  page covers each function and how to load a repository's file.
232
236
 
233
237
  Exit codes: `0` passed · `1` a check failed · `2` nothing was checked — bad
234
- usage, or a config that is missing, is not valid TOML, names an unknown rule or
235
- holds a regex that does not compile. `--dry-run` reports everything and exits `0`. More output formats: [examples](https://commit-check.com/example/).
238
+ usage, or a config that is missing, is not valid TOML, names an unknown rule,
239
+ holds a regex that does not compile or gives a `[commit]` or `[branch]` setting
240
+ a value of the wrong type (`subject_max_length = "abc"`). A `[files]` value it
241
+ cannot use turns that rule off with a notice instead. `--dry-run` reports everything and exits `0`. More output formats: [examples](https://commit-check.com/example/).
236
242
 
237
243
  ## Why Commit Check
238
244
 
@@ -1,7 +1,7 @@
1
- commit_check/__init__.py,sha256=wHIreV-DEKM5AiobnjfvxIuvIQ2DShRxc5SwSx50oX4,5232
1
+ commit_check/__init__.py,sha256=UAg0cSgL4QKAOc9GEbqFdoQ94JejOupRGoGgaDwIcF0,5456
2
2
  commit_check/ai_policy.py,sha256=gYC3ROLgGL1TDyhPkFXkV-NiYbvMt80Qt0MFrJcbJY4,8131
3
3
  commit_check/ai_signatures.py,sha256=0HTZy4othuwKVqfGZ2J7PaIMUPmQArhEQa0k7zGnCzs,10251
4
- commit_check/ai_signatures_data.py,sha256=2xWH8M3HoFlUh7n766GK4ahkKJi8_FvcTTOuYv_yWls,14314
4
+ commit_check/ai_signatures_data.py,sha256=dgTJxur3IqYLbmj0PzhG6LWb8mY2QwWUJVaFCLQJYzo,15258
5
5
  commit_check/api.py,sha256=07bvBtV8PrhZIOwCDHiHfu_7CXsX_4U2_K2xMAucd6c,12905
6
6
  commit_check/config.py,sha256=SB8Zvcll-kFOZgQ-olzYLv9CLJqaYIaCb37bcrjVNOE,14068
7
7
  commit_check/config_merger.py,sha256=umsjoTcWG7WXufxn7dIMlHrek0a8VWmqjynJR-A4LYQ,13406
@@ -10,12 +10,12 @@ commit_check/fixes.py,sha256=BpbdoHsKDyw2WfsqymwYpnrW73aHdCDGr8tMF6Ho2RU,7305
10
10
  commit_check/imperatives.py,sha256=dEd_ssu4G0j6Cann6jqPdB97lw5Adua43K0_Odg_FyA,9518
11
11
  commit_check/main.py,sha256=LR3uyJXXHHLsVS90pshHbB7FfyTiUr-OmecI8wwvgEo,28157
12
12
  commit_check/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- commit_check/rule_builder.py,sha256=YDa3re0-gNTKEBBOvnF_K8kP8MpFo9UC_l9eC_punsw,33435
13
+ commit_check/rule_builder.py,sha256=XqTjDrPcepC6jP-ui0RyiMFYSVvKXGuRxwllg_XxvKI,34391
14
14
  commit_check/rules_catalog.py,sha256=-C3Jo721vXRrY7-LzJs9iNF3ffXKEFldDfmBoLtujt4,11920
15
15
  commit_check/util.py,sha256=Q9nI_0yYu6WEJLD55vMnFozWhZzfP2Z4xrElecmqZBQ,32755
16
- commit_check-2.19.2.dist-info/licenses/LICENSE,sha256=9mdTva71kQhrpWh_nZulxrdCnUrl5c6xJYh5hdo4p_s,1070
17
- commit_check-2.19.2.dist-info/METADATA,sha256=ArwljHXzZqWZE2oKS5aSfoosL9b5RrPG49bS-MIsRyg,15971
18
- commit_check-2.19.2.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
19
- commit_check-2.19.2.dist-info/entry_points.txt,sha256=YMrkFGeub-3-IanV1d9qnopXVaRQM7MA9foXKW9iZ88,86
20
- commit_check-2.19.2.dist-info/top_level.txt,sha256=Wf46u-ooHBMJNHbhfrBNQw3wC5_m8wt-o_Lfbc4QpRg,13
21
- commit_check-2.19.2.dist-info/RECORD,,
16
+ commit_check-2.19.4.dist-info/licenses/LICENSE,sha256=9mdTva71kQhrpWh_nZulxrdCnUrl5c6xJYh5hdo4p_s,1070
17
+ commit_check-2.19.4.dist-info/METADATA,sha256=Nmu5vjvJVhOUeHNlCRmoVzk-HMjHnU-l8VLPLh1x_ns,16369
18
+ commit_check-2.19.4.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
19
+ commit_check-2.19.4.dist-info/entry_points.txt,sha256=YMrkFGeub-3-IanV1d9qnopXVaRQM7MA9foXKW9iZ88,86
20
+ commit_check-2.19.4.dist-info/top_level.txt,sha256=Wf46u-ooHBMJNHbhfrBNQw3wC5_m8wt-o_Lfbc4QpRg,13
21
+ commit_check-2.19.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (84.0.0)
2
+ Generator: setuptools (84.2.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5