git-cai-cli 0.15.2__tar.gz → 0.15.3__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 (104) hide show
  1. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.pylintrc +2 -2
  2. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/PKG-INFO +1 -1
  3. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/docs/man/git-cai.1 +2 -2
  4. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/_version.py +3 -3
  5. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/squash.py +15 -2
  6. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/PKG-INFO +1 -1
  7. git_cai_cli-0.15.3/src/git_cai_cli.egg-info/scm_version.json +8 -0
  8. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_squash.py +42 -1
  9. git_cai_cli-0.15.2/src/git_cai_cli.egg-info/scm_version.json +0 -8
  10. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.caiignore +0 -0
  11. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.gitattributes +0 -0
  12. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/cd/.SRCINFO +0 -0
  13. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/cd/PKGBUILD +0 -0
  14. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/ci/_version.py +0 -0
  15. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/ci/cai_config.ci.yml +0 -0
  16. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/ci/tokens.ci.yml +0 -0
  17. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/workflows/python-tests.yml +0 -0
  18. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/workflows/release.yml +0 -0
  19. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/workflows/release_aur.yml +0 -0
  20. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.gitignore +0 -0
  21. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.bandit.yml +0 -0
  22. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.checkov.yml +0 -0
  23. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.flake8 +0 -0
  24. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.ls-lint.yml +0 -0
  25. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.markdown-link-check.json +0 -0
  26. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.markdownlint.json +0 -0
  27. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.proselintrc +0 -0
  28. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.yamllint.yml +0 -0
  29. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/check_git_branch_name.sh +0 -0
  30. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/lychee.toml +0 -0
  31. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/pyrightconfig.json +0 -0
  32. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.markdownlintignore +0 -0
  33. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.mega-linter.yml +0 -0
  34. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.semgrepignore +0 -0
  35. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.trivyignore +0 -0
  36. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/CLAUDE.md +0 -0
  37. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/LICENSE +0 -0
  38. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/Makefile +0 -0
  39. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/README.md +0 -0
  40. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/cai_config.yml +0 -0
  41. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/docs/git-cai.txt +0 -0
  42. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/pyproject.toml +0 -0
  43. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/setup.cfg +0 -0
  44. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/__init__.py +0 -0
  45. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/cli/__init__.py +0 -0
  46. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/cli/cli.py +0 -0
  47. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/cli/helptext.py +0 -0
  48. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/cli/modes.py +0 -0
  49. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/__init__.py +0 -0
  50. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/completion.py +0 -0
  51. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/config.py +0 -0
  52. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/doctor.py +0 -0
  53. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/editors.py +0 -0
  54. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/gitutils.py +0 -0
  55. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/init.py +0 -0
  56. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/languages.py +0 -0
  57. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/llm.py +0 -0
  58. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/options.py +0 -0
  59. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/pr.py +0 -0
  60. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/prompts_fallback.py +0 -0
  61. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/secrets.py +0 -0
  62. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/spinner.py +0 -0
  63. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/stats.py +0 -0
  64. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/validate.py +0 -0
  65. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/main.py +0 -0
  66. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/SOURCES.txt +0 -0
  67. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/dependency_links.txt +0 -0
  68. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/entry_points.txt +0 -0
  69. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/requires.txt +0 -0
  70. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/scm_file_list.json +0 -0
  71. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/top_level.txt +0 -0
  72. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/conftest.py +0 -0
  73. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_cli_integration.py +0 -0
  74. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_config_integration.py +0 -0
  75. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_gitutils_integration.py +0 -0
  76. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_modes_integration.py +0 -0
  77. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_options_integration.py +0 -0
  78. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_pr_integration.py +0 -0
  79. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_squash_integration.py +0 -0
  80. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_amend.py +0 -0
  81. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_branch_context.py +0 -0
  82. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_classification.py +0 -0
  83. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_cli.py +0 -0
  84. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_completion.py +0 -0
  85. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_config.py +0 -0
  86. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_conventional.py +0 -0
  87. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_doctor.py +0 -0
  88. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_gitutils.py +0 -0
  89. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_helptext.py +0 -0
  90. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_init.py +0 -0
  91. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_llm.py +0 -0
  92. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_main.py +0 -0
  93. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_modes.py +0 -0
  94. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_options.py +0 -0
  95. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_pr.py +0 -0
  96. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_print.py +0 -0
  97. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_prompt_loading.py +0 -0
  98. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_secrets.py +0 -0
  99. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_set_config.py +0 -0
  100. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_signoff.py +0 -0
  101. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_spinner.py +0 -0
  102. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_stats.py +0 -0
  103. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_validate.py +0 -0
  104. {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/uv.lock +0 -0
@@ -68,10 +68,10 @@ check-protected-access-in-special-methods=no
68
68
  [DESIGN]
69
69
  max-args=30 # Max arguments per function
70
70
  max-attributes=12 # Max attributes per class
71
- max-branches=30 # Max branches per function
71
+ max-branches=35 # Max branches per function
72
72
  max-locals=80 # Max locals per function
73
73
  max-returns=10 # Max return statements per function
74
- max-statements=130 # Max total statements per function
74
+ max-statements=140 # Max total statements per function
75
75
  max-public-methods=20 # Max public methods per class
76
76
  min-public-methods=1 # Min public methods per class
77
77
  max-nested-blocks=15 # Max nesting depth
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-cai-cli
3
- Version: 0.15.2
3
+ Version: 0.15.3
4
4
  Summary: Use LLM to create git commit messages
5
5
  Author-email: Thorsten Foltz <thorsten.foltz@live.com>
6
6
  License-Expression: MIT
@@ -2,12 +2,12 @@
2
2
  .\" Title: git-cai
3
3
  .\" Author: Thorsten Foltz
4
4
  .\" Generator: Asciidoctor 2.0.26
5
- .\" Date: 2026-06-24
5
+ .\" Date: 2026-06-29
6
6
  .\" Manual: \ \&
7
7
  .\" Source: \ \&
8
8
  .\" Language: English
9
9
  .\"
10
- .TH "GIT\-CAI" "1" "2026-06-24" "\ \&" "\ \&"
10
+ .TH "GIT\-CAI" "1" "2026-06-29" "\ \&" "\ \&"
11
11
  .ie \n(.g .ds Aq \(aq
12
12
  .el .ds Aq '
13
13
  .ss \n[.ss] 0
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.15.2'
22
- __version_tuple__ = version_tuple = (0, 15, 2)
21
+ __version__ = version = '0.15.3'
22
+ __version_tuple__ = version_tuple = (0, 15, 3)
23
23
 
24
- __commit_id__ = commit_id = 'g12ea7cd4d'
24
+ __commit_id__ = commit_id = 'g0517f2f82'
@@ -484,8 +484,21 @@ def squash_branch(
484
484
  )
485
485
  choice = input("Shall I execute it for you now? [yes/no]: ").strip().lower()
486
486
  if choice in ("y", "yes"):
487
- subprocess.run(["git", "push", "--force-with-lease"], check=True)
488
- log.info("✅ Successfully pushed the squashed branch to remote.")
487
+ push_result = subprocess.run(
488
+ ["git", "push", "--force-with-lease"],
489
+ capture_output=True,
490
+ text=True,
491
+ check=False,
492
+ )
493
+ if push_result.returncode == 0:
494
+ log.info("✅ Successfully pushed the squashed branch to remote.")
495
+ else:
496
+ log.debug("git push failed:\n%s", push_result.stderr.strip())
497
+ log.error(
498
+ "❌ Push failed. The remote branch may have been merged and "
499
+ "deleted.\nCheck whether the remote branch still exists "
500
+ "(e.g. `git branch -r`), then push manually if needed."
501
+ )
489
502
  else:
490
503
  log.info(
491
504
  "No upstream branch detected. Normal `git push` will work as expected."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-cai-cli
3
- Version: 0.15.2
3
+ Version: 0.15.3
4
4
  Summary: Use LLM to create git commit messages
5
5
  Author-email: Thorsten Foltz <thorsten.foltz@live.com>
6
6
  License-Expression: MIT
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.15.3",
3
+ "distance": 0,
4
+ "node": "g0517f2f8232a68669e43295b3030acf47d550e97",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-06-29"
8
+ }
@@ -267,7 +267,48 @@ def test_force_push_prompt_and_execution(
267
267
  ):
268
268
  squash_branch()
269
269
 
270
- run_mock.assert_any_call(["git", "push", "--force-with-lease"], check=True)
270
+ run_mock.assert_any_call(
271
+ ["git", "push", "--force-with-lease"],
272
+ capture_output=True,
273
+ text=True,
274
+ check=False,
275
+ )
276
+
277
+
278
+ def test_force_push_failure_is_handled(
279
+ mock_repo_root, clean_git_state, mock_generator, caplog
280
+ ) -> None:
281
+ """
282
+ Test that a failed force push is reported gracefully without raising.
283
+ """
284
+
285
+ def run_side_effect(cmd, *args, **kwargs):
286
+ if cmd[:2] == ["git", "push"]:
287
+ return MagicMock(returncode=1, stderr="! [rejected] (stale info)")
288
+ return MagicMock(returncode=0)
289
+
290
+ run_mock = MagicMock(side_effect=run_side_effect)
291
+
292
+ with (
293
+ patch("git_cai_cli.core.squash.find_git_root", return_value=mock_repo_root),
294
+ patch("subprocess.check_output", side_effect=clean_git_state),
295
+ patch(
296
+ "git_cai_cli.core.squash.load_config", return_value={"default": "openai"}
297
+ ),
298
+ patch("git_cai_cli.core.squash.load_token", return_value="token"),
299
+ patch(
300
+ "git_cai_cli.core.squash.CommitMessageGenerator",
301
+ return_value=mock_generator,
302
+ ),
303
+ patch("git_cai_cli.core.squash.get_git_editor", return_value="true"),
304
+ patch("git_cai_cli.core.squash.sha256_of_file", side_effect=["a", "b"]),
305
+ patch("subprocess.run", run_mock),
306
+ patch("git_cai_cli.core.squash._has_upstream", return_value=True),
307
+ patch.object(builtins, "input", return_value="yes"),
308
+ ):
309
+ squash_branch()
310
+
311
+ assert "Push failed" in caplog.text
271
312
 
272
313
 
273
314
  # --- Tests for new squash argument helpers ---
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "0.15.2",
3
- "distance": 0,
4
- "node": "g12ea7cd4d5eac2e8dff9c32e94c875b7fefce00a",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-06-24"
8
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes