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.
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.pylintrc +2 -2
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/PKG-INFO +1 -1
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/docs/man/git-cai.1 +2 -2
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/_version.py +3 -3
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/squash.py +15 -2
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/PKG-INFO +1 -1
- git_cai_cli-0.15.3/src/git_cai_cli.egg-info/scm_version.json +8 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_squash.py +42 -1
- git_cai_cli-0.15.2/src/git_cai_cli.egg-info/scm_version.json +0 -8
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.caiignore +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.gitattributes +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/cd/.SRCINFO +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/cd/PKGBUILD +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/ci/_version.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/ci/cai_config.ci.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/ci/tokens.ci.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/workflows/python-tests.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/workflows/release.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.github/workflows/release_aur.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.gitignore +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.bandit.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.checkov.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.flake8 +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.ls-lint.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.markdown-link-check.json +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.markdownlint.json +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.proselintrc +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/.yamllint.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/check_git_branch_name.sh +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/lychee.toml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.linters/pyrightconfig.json +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.markdownlintignore +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.mega-linter.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.semgrepignore +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/.trivyignore +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/CLAUDE.md +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/LICENSE +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/Makefile +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/README.md +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/cai_config.yml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/docs/git-cai.txt +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/pyproject.toml +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/setup.cfg +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/__init__.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/cli/__init__.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/cli/cli.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/cli/helptext.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/cli/modes.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/__init__.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/completion.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/config.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/doctor.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/editors.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/gitutils.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/init.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/languages.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/llm.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/options.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/pr.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/prompts_fallback.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/secrets.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/spinner.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/stats.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/core/validate.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli/main.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/SOURCES.txt +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/dependency_links.txt +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/entry_points.txt +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/requires.txt +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/scm_file_list.json +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/src/git_cai_cli.egg-info/top_level.txt +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/conftest.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_cli_integration.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_config_integration.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_gitutils_integration.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_modes_integration.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_options_integration.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_pr_integration.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/integration/test_squash_integration.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_amend.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_branch_context.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_classification.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_cli.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_completion.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_config.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_conventional.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_doctor.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_gitutils.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_helptext.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_init.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_llm.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_main.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_modes.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_options.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_pr.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_print.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_prompt_loading.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_secrets.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_set_config.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_signoff.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_spinner.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_stats.py +0 -0
- {git_cai_cli-0.15.2 → git_cai_cli-0.15.3}/tests/unit/test_validate.py +0 -0
- {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=
|
|
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=
|
|
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
|
|
@@ -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-
|
|
5
|
+
.\" Date: 2026-06-29
|
|
6
6
|
.\" Manual: \ \&
|
|
7
7
|
.\" Source: \ \&
|
|
8
8
|
.\" Language: English
|
|
9
9
|
.\"
|
|
10
|
-
.TH "GIT\-CAI" "1" "2026-06-
|
|
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.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 15,
|
|
21
|
+
__version__ = version = '0.15.3'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 15, 3)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
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(
|
|
488
|
-
|
|
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."
|
|
@@ -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(
|
|
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 ---
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|