commitizen 4.15.0__tar.gz → 4.15.1__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.
- {commitizen-4.15.0 → commitizen-4.15.1}/PKG-INFO +1 -1
- commitizen-4.15.1/commitizen/__version__.py +1 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cli.py +1 -1
- commitizen-4.15.1/commitizen/cmd.py +105 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/bump.py +2 -2
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/changelog.py +1 -1
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/commit.py +3 -3
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/init.py +5 -4
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/git.py +53 -36
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/hooks.py +1 -1
- {commitizen-4.15.0 → commitizen-4.15.1}/pyproject.toml +1 -1
- commitizen-4.15.0/commitizen/__version__.py +0 -1
- commitizen-4.15.0/commitizen/cmd.py +0 -57
- {commitizen-4.15.0 → commitizen-4.15.1}/LICENSE +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/__main__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/bump.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/changelog.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/changelog_formats/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/changelog_formats/asciidoc.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/changelog_formats/base.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/changelog_formats/markdown.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/changelog_formats/restructuredtext.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/changelog_formats/textile.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/check.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/example.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/info.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/list_cz.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/schema.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/commands/version.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/config/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/config/base_config.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/config/factory.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/config/json_config.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/config/toml_config.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/config/yaml_config.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/base.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/conventional_commits/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/conventional_commits/conventional_commits.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/conventional_commits/conventional_commits_info.txt +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/customize/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/customize/customize.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/customize/customize_info.txt +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/exceptions.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/jira/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/jira/jira.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/jira/jira_info.txt +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/utils.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/defaults.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/exceptions.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/factory.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/out.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/project_info.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/__init__.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/base_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/cargo_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/commitizen_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/composer_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/npm_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/pep621_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/poetry_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/scm_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/providers/uv_provider.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/py.typed +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/question.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/tags.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/templates/CHANGELOG.adoc.j2 +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/templates/CHANGELOG.md.j2 +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/templates/CHANGELOG.rst.j2 +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/templates/CHANGELOG.textile.j2 +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/version_increment.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/commitizen/version_schemes.py +0 -0
- {commitizen-4.15.0 → commitizen-4.15.1}/docs/README.md +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "4.15.1"
|
|
@@ -704,7 +704,7 @@ def main() -> None:
|
|
|
704
704
|
logger.warning(
|
|
705
705
|
"\nWARN: Incomplete commit command: received -- separator without any following git arguments\n"
|
|
706
706
|
)
|
|
707
|
-
extra_args =
|
|
707
|
+
extra_args = unknown_args[1:]
|
|
708
708
|
arguments["extra_cli_args"] = extra_args
|
|
709
709
|
|
|
710
710
|
conf = config.read_cfg(args.config)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
import warnings
|
|
6
|
+
from typing import TYPE_CHECKING, NamedTuple, overload
|
|
7
|
+
|
|
8
|
+
from charset_normalizer import from_bytes
|
|
9
|
+
|
|
10
|
+
from commitizen.exceptions import CharacterSetDecodeError
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from collections.abc import Mapping, Sequence
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Command(NamedTuple):
|
|
17
|
+
out: str
|
|
18
|
+
err: str
|
|
19
|
+
stdout: bytes
|
|
20
|
+
stderr: bytes
|
|
21
|
+
return_code: int
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _try_decode(bytes_: bytes) -> str:
|
|
25
|
+
try:
|
|
26
|
+
return bytes_.decode("utf-8")
|
|
27
|
+
except UnicodeDecodeError:
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
charset_match = from_bytes(bytes_).best()
|
|
31
|
+
if charset_match is None:
|
|
32
|
+
raise CharacterSetDecodeError()
|
|
33
|
+
try:
|
|
34
|
+
return bytes_.decode(charset_match.encoding)
|
|
35
|
+
except UnicodeDecodeError as e:
|
|
36
|
+
raise CharacterSetDecodeError() from e
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _popen(
|
|
40
|
+
cmd: str | Sequence[str],
|
|
41
|
+
*,
|
|
42
|
+
shell: bool,
|
|
43
|
+
env: Mapping[str, str] | None = None,
|
|
44
|
+
) -> Command:
|
|
45
|
+
if env is not None:
|
|
46
|
+
env = {**os.environ, **env}
|
|
47
|
+
|
|
48
|
+
process = subprocess.Popen(
|
|
49
|
+
cmd,
|
|
50
|
+
shell=shell,
|
|
51
|
+
stdout=subprocess.PIPE,
|
|
52
|
+
stderr=subprocess.PIPE,
|
|
53
|
+
stdin=subprocess.PIPE,
|
|
54
|
+
env=env,
|
|
55
|
+
)
|
|
56
|
+
stdout, stderr = process.communicate()
|
|
57
|
+
return_code = process.returncode
|
|
58
|
+
return Command(
|
|
59
|
+
_try_decode(stdout),
|
|
60
|
+
_try_decode(stderr),
|
|
61
|
+
stdout,
|
|
62
|
+
stderr,
|
|
63
|
+
return_code,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@overload
|
|
68
|
+
def run(cmd: str, env: Mapping[str, str] | None = None) -> Command: ...
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@overload
|
|
72
|
+
def run(cmd: Sequence[str], env: Mapping[str, str] | None = None) -> Command: ...
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def run(cmd: str | Sequence[str], env: Mapping[str, str] | None = None) -> Command:
|
|
76
|
+
"""Run a command safely without shell interpretation (shell=False).
|
|
77
|
+
|
|
78
|
+
Arguments are passed directly to the OS, preventing shell-injection
|
|
79
|
+
vulnerabilities (CWE-78).
|
|
80
|
+
|
|
81
|
+
Passing a string is deprecated and will be removed in a future version.
|
|
82
|
+
Use a list of arguments instead, or use run_shell() for shell features.
|
|
83
|
+
"""
|
|
84
|
+
if isinstance(cmd, str):
|
|
85
|
+
warnings.warn(
|
|
86
|
+
"Passing a string to cmd.run() is deprecated and will be removed in v5. "
|
|
87
|
+
"Use a list of arguments instead, or use cmd.run_shell() explicitly.",
|
|
88
|
+
DeprecationWarning,
|
|
89
|
+
stacklevel=2,
|
|
90
|
+
)
|
|
91
|
+
return _popen(cmd, shell=True, env=env)
|
|
92
|
+
return _popen(cmd, shell=False, env=env)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def run_shell(cmd: str, env: Mapping[str, str] | None = None) -> Command:
|
|
96
|
+
"""Run a command string via the system shell (shell=True).
|
|
97
|
+
|
|
98
|
+
Only use this for cases that intentionally require shell features
|
|
99
|
+
(e.g., user-defined hooks with pipes/redirects). Never pass
|
|
100
|
+
untrusted/user-controlled values into *cmd*.
|
|
101
|
+
|
|
102
|
+
Related: CWE-78 (OS Command Injection),
|
|
103
|
+
https://github.com/commitizen-tools/commitizen/issues/1918
|
|
104
|
+
"""
|
|
105
|
+
return _popen(cmd, shell=True, env=env)
|
|
@@ -439,8 +439,8 @@ class Bump:
|
|
|
439
439
|
else:
|
|
440
440
|
out.success("Done!")
|
|
441
441
|
|
|
442
|
-
def _get_commit_args(self) -> str:
|
|
442
|
+
def _get_commit_args(self) -> list[str]:
|
|
443
443
|
commit_args = ["-a"]
|
|
444
444
|
if self.no_verify:
|
|
445
445
|
commit_args.append("--no-verify")
|
|
446
|
-
return
|
|
446
|
+
return commit_args
|
|
@@ -257,7 +257,7 @@ class Changelog:
|
|
|
257
257
|
changelog_meta.latest_version_position = None
|
|
258
258
|
changelog_meta.unreleased_end = latest_full_release_info.index + 1
|
|
259
259
|
|
|
260
|
-
commits = git.get_commits(start=start_rev, end=end_rev, args="--topo-order")
|
|
260
|
+
commits = git.get_commits(start=start_rev, end=end_rev, args=["--topo-order"])
|
|
261
261
|
if (
|
|
262
262
|
not self.allow_no_commit
|
|
263
263
|
and not commits
|
|
@@ -34,7 +34,7 @@ class CommitArgs(TypedDict, total=False):
|
|
|
34
34
|
all: bool
|
|
35
35
|
dry_run: bool
|
|
36
36
|
edit: bool
|
|
37
|
-
extra_cli_args: str
|
|
37
|
+
extra_cli_args: list[str]
|
|
38
38
|
message_length_limit: int
|
|
39
39
|
no_retry: bool
|
|
40
40
|
signoff: bool
|
|
@@ -132,7 +132,7 @@ class Commit:
|
|
|
132
132
|
return self._get_message_by_prompt_commit_questions()
|
|
133
133
|
|
|
134
134
|
def __call__(self) -> None:
|
|
135
|
-
extra_args = self.arguments.get("extra_cli_args",
|
|
135
|
+
extra_args: list[str] = self.arguments.get("extra_cli_args", [])
|
|
136
136
|
dry_run = bool(self.arguments.get("dry_run"))
|
|
137
137
|
write_message_to_file = self.arguments.get("write_message_to_file")
|
|
138
138
|
signoff = bool(self.arguments.get("signoff"))
|
|
@@ -167,7 +167,7 @@ class Commit:
|
|
|
167
167
|
raise DryRunExit()
|
|
168
168
|
|
|
169
169
|
if self.config.settings["always_signoff"] or signoff:
|
|
170
|
-
extra_args =
|
|
170
|
+
extra_args = [*extra_args, "-s"]
|
|
171
171
|
|
|
172
172
|
c = git.commit(commit_message, args=extra_args)
|
|
173
173
|
if c.return_code != 0:
|
|
@@ -134,11 +134,12 @@ class Init:
|
|
|
134
134
|
"pre-commit is not installed in current environment."
|
|
135
135
|
)
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
c = cmd.run(
|
|
137
|
+
cmd_args = ["pre-commit", "install"]
|
|
138
|
+
for ty in hook_types:
|
|
139
|
+
cmd_args.extend(["--hook-type", ty])
|
|
140
|
+
c = cmd.run(cmd_args)
|
|
141
141
|
if c.return_code != 0:
|
|
142
|
+
cmd_str = " ".join(cmd_args)
|
|
142
143
|
raise InitFailedError(
|
|
143
144
|
"Failed to install pre-commit hook.\n"
|
|
144
145
|
f"Error running {cmd_str}."
|
|
@@ -5,10 +5,14 @@ from enum import Enum
|
|
|
5
5
|
from functools import lru_cache
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from tempfile import NamedTemporaryFile
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
8
9
|
|
|
9
10
|
from commitizen import cmd, out
|
|
10
11
|
from commitizen.exceptions import GitCommandError
|
|
11
12
|
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from collections.abc import Sequence
|
|
15
|
+
|
|
12
16
|
|
|
13
17
|
class EOLType(Enum):
|
|
14
18
|
"""The EOL type from `git config core.eol`."""
|
|
@@ -19,7 +23,7 @@ class EOLType(Enum):
|
|
|
19
23
|
|
|
20
24
|
@classmethod
|
|
21
25
|
def for_open(cls) -> str:
|
|
22
|
-
c = cmd.run("git config core.eol")
|
|
26
|
+
c = cmd.run(["git", "config", "core.eol"])
|
|
23
27
|
eol = c.out.strip().upper()
|
|
24
28
|
return cls._char_for_open()[cls._safe_cast(eol)]
|
|
25
29
|
|
|
@@ -164,49 +168,47 @@ def tag(
|
|
|
164
168
|
tag: str, annotated: bool = False, signed: bool = False, msg: str | None = None
|
|
165
169
|
) -> cmd.Command:
|
|
166
170
|
if not annotated and not signed:
|
|
167
|
-
return cmd.run(
|
|
171
|
+
return cmd.run(["git", "tag", tag])
|
|
168
172
|
|
|
169
173
|
# according to https://git-scm.com/book/en/v2/Git-Basics-Tagging,
|
|
170
174
|
# we're not able to create lightweight tag with message.
|
|
171
175
|
# by adding message, we make it a annotated tags
|
|
172
176
|
option = "-s" if signed else "-a" # The else case is for annotated tags
|
|
173
|
-
return cmd.run(
|
|
177
|
+
return cmd.run(["git", "tag", option, tag, "-m", msg or tag])
|
|
174
178
|
|
|
175
179
|
|
|
176
180
|
def add(*args: str) -> cmd.Command:
|
|
177
|
-
return cmd.run(
|
|
181
|
+
return cmd.run(["git", "add", *args])
|
|
178
182
|
|
|
179
183
|
|
|
180
184
|
def commit(
|
|
181
185
|
message: str,
|
|
182
|
-
args: str =
|
|
186
|
+
args: Sequence[str] = (),
|
|
183
187
|
committer_date: str | None = None,
|
|
184
188
|
) -> cmd.Command:
|
|
185
189
|
f = NamedTemporaryFile("wb", delete=False)
|
|
186
190
|
f.write(message.encode("utf-8"))
|
|
187
191
|
f.close()
|
|
188
192
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
+
cmd_args = ["git", "commit"]
|
|
194
|
+
if args:
|
|
195
|
+
cmd_args.extend(args)
|
|
196
|
+
cmd_args.extend(["-F", f.name])
|
|
193
197
|
|
|
198
|
+
env: dict[str, str] | None = None
|
|
199
|
+
if committer_date:
|
|
200
|
+
env = {"GIT_COMMITTER_DATE": committer_date}
|
|
194
201
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
return command
|
|
199
|
-
if os.name != "nt":
|
|
200
|
-
return f"GIT_COMMITTER_DATE={committer_date} {command}"
|
|
201
|
-
# Using `cmd /v /c "{command}"` sets environment variables only for that command
|
|
202
|
-
return f'cmd /v /c "set GIT_COMMITTER_DATE={committer_date}&& {command}"'
|
|
202
|
+
c = cmd.run(cmd_args, env=env)
|
|
203
|
+
os.unlink(f.name)
|
|
204
|
+
return c
|
|
203
205
|
|
|
204
206
|
|
|
205
207
|
def get_commits(
|
|
206
208
|
start: str | None = None,
|
|
207
209
|
end: str | None = None,
|
|
208
210
|
*,
|
|
209
|
-
args: str =
|
|
211
|
+
args: Sequence[str] = (),
|
|
210
212
|
) -> list[GitCommit]:
|
|
211
213
|
"""Get the commits between start and end."""
|
|
212
214
|
if end is None:
|
|
@@ -226,7 +228,10 @@ def get_filenames_in_commit(git_reference: str = "") -> list[str]:
|
|
|
226
228
|
|
|
227
229
|
:returns: file names committed in the last commit by default or inside the passed git reference
|
|
228
230
|
"""
|
|
229
|
-
|
|
231
|
+
cmd_args = ["git", "show", "--name-only", "--pretty=format:"]
|
|
232
|
+
if git_reference:
|
|
233
|
+
cmd_args.append(git_reference)
|
|
234
|
+
c = cmd.run(cmd_args)
|
|
230
235
|
if c.return_code == 0:
|
|
231
236
|
return c.out.strip().split("\n")
|
|
232
237
|
raise GitCommandError(c.err)
|
|
@@ -237,15 +242,17 @@ def get_tags(
|
|
|
237
242
|
) -> list[GitTag]:
|
|
238
243
|
inner_delimiter = "---inner_delimiter---"
|
|
239
244
|
formatter = (
|
|
240
|
-
f
|
|
245
|
+
f"%(refname:strip=2){inner_delimiter}"
|
|
241
246
|
f"%(objectname){inner_delimiter}"
|
|
242
247
|
f"%(creatordate:format:{dateformat}){inner_delimiter}"
|
|
243
|
-
f
|
|
248
|
+
f"%(object)"
|
|
244
249
|
)
|
|
245
|
-
|
|
250
|
+
cmd_args = ["git", "tag", f"--format={formatter}", "--sort=-creatordate"]
|
|
251
|
+
if reachable_only:
|
|
252
|
+
cmd_args.append("--merged")
|
|
246
253
|
# Force the default language for parsing
|
|
247
254
|
env = {"LC_ALL": "C", "LANG": "C", "LANGUAGE": "C"}
|
|
248
|
-
c = cmd.run(
|
|
255
|
+
c = cmd.run(cmd_args, env=env)
|
|
249
256
|
if c.return_code != 0:
|
|
250
257
|
if reachable_only and c.err == "fatal: malformed object name HEAD\n":
|
|
251
258
|
# this can happen if there are no commits in the repo yet
|
|
@@ -262,37 +269,37 @@ def get_tags(
|
|
|
262
269
|
|
|
263
270
|
|
|
264
271
|
def tag_exist(tag: str) -> bool:
|
|
265
|
-
c = cmd.run(
|
|
272
|
+
c = cmd.run(["git", "tag", "--list", tag])
|
|
266
273
|
return tag in c.out
|
|
267
274
|
|
|
268
275
|
|
|
269
276
|
def is_signed_tag(tag: str) -> bool:
|
|
270
|
-
return cmd.run(
|
|
277
|
+
return cmd.run(["git", "tag", "-v", tag]).return_code == 0
|
|
271
278
|
|
|
272
279
|
|
|
273
280
|
def get_latest_tag_name() -> str | None:
|
|
274
|
-
c = cmd.run("git describe --abbrev=0 --tags")
|
|
281
|
+
c = cmd.run(["git", "describe", "--abbrev=0", "--tags"])
|
|
275
282
|
if c.err:
|
|
276
283
|
return None
|
|
277
284
|
return c.out.strip()
|
|
278
285
|
|
|
279
286
|
|
|
280
287
|
def get_tag_message(tag: str) -> str | None:
|
|
281
|
-
c = cmd.run(
|
|
288
|
+
c = cmd.run(["git", "tag", "-l", "--format=%(contents:subject)", tag])
|
|
282
289
|
if c.err:
|
|
283
290
|
return None
|
|
284
291
|
return c.out.strip()
|
|
285
292
|
|
|
286
293
|
|
|
287
294
|
def get_tag_names() -> list[str]:
|
|
288
|
-
c = cmd.run("git tag --list")
|
|
295
|
+
c = cmd.run(["git", "tag", "--list"])
|
|
289
296
|
if c.err:
|
|
290
297
|
return []
|
|
291
298
|
return [tag for raw in c.out.split("\n") if (tag := raw.strip())]
|
|
292
299
|
|
|
293
300
|
|
|
294
301
|
def find_git_project_root() -> Path | None:
|
|
295
|
-
c = cmd.run("git rev-parse --show-toplevel")
|
|
302
|
+
c = cmd.run(["git", "rev-parse", "--show-toplevel"])
|
|
296
303
|
if c.err:
|
|
297
304
|
return None
|
|
298
305
|
return Path(c.out.strip())
|
|
@@ -300,17 +307,17 @@ def find_git_project_root() -> Path | None:
|
|
|
300
307
|
|
|
301
308
|
def is_staging_clean() -> bool:
|
|
302
309
|
"""Check if staging is clean."""
|
|
303
|
-
c = cmd.run("git diff --no-ext-diff --cached --name-only")
|
|
310
|
+
c = cmd.run(["git", "diff", "--no-ext-diff", "--cached", "--name-only"])
|
|
304
311
|
return not bool(c.out)
|
|
305
312
|
|
|
306
313
|
|
|
307
314
|
def is_git_project() -> bool:
|
|
308
|
-
c = cmd.run("git rev-parse --is-inside-work-tree")
|
|
315
|
+
c = cmd.run(["git", "rev-parse", "--is-inside-work-tree"])
|
|
309
316
|
return c.out.strip() == "true"
|
|
310
317
|
|
|
311
318
|
|
|
312
319
|
def get_core_editor() -> str | None:
|
|
313
|
-
c = cmd.run("git var GIT_EDITOR")
|
|
320
|
+
c = cmd.run(["git", "var", "GIT_EDITOR"])
|
|
314
321
|
if c.out:
|
|
315
322
|
return c.out.strip()
|
|
316
323
|
return None
|
|
@@ -321,21 +328,31 @@ def smart_open(*args, **kwargs): # type: ignore[no-untyped-def,unused-ignore] #
|
|
|
321
328
|
return open(*args, newline=EOLType.for_open(), **kwargs)
|
|
322
329
|
|
|
323
330
|
|
|
324
|
-
def _get_log_as_str_list(start: str | None, end: str, args: str) -> list[str]:
|
|
331
|
+
def _get_log_as_str_list(start: str | None, end: str, args: Sequence[str]) -> list[str]:
|
|
325
332
|
"""Get string representation of each log entry"""
|
|
326
333
|
delimiter = "----------commit-delimiter----------"
|
|
327
334
|
log_format: str = "%H%n%P%n%s%n%an%n%ae%n%b"
|
|
328
335
|
command_range = f"{start}..{end}" if start else end
|
|
329
|
-
|
|
336
|
+
cmd_args = [
|
|
337
|
+
"git",
|
|
338
|
+
"-c",
|
|
339
|
+
"log.showSignature=False",
|
|
340
|
+
"log",
|
|
341
|
+
f"--pretty={log_format}{delimiter}",
|
|
342
|
+
]
|
|
343
|
+
if args:
|
|
344
|
+
cmd_args.extend(args)
|
|
345
|
+
if command_range:
|
|
346
|
+
cmd_args.append(command_range)
|
|
330
347
|
|
|
331
|
-
c = cmd.run(
|
|
348
|
+
c = cmd.run(cmd_args)
|
|
332
349
|
if c.return_code != 0:
|
|
333
350
|
raise GitCommandError(c.err)
|
|
334
351
|
return c.out.split(f"{delimiter}\n")
|
|
335
352
|
|
|
336
353
|
|
|
337
354
|
def get_default_branch() -> str:
|
|
338
|
-
c = cmd.run("git symbolic-ref refs/remotes/origin/HEAD")
|
|
355
|
+
c = cmd.run(["git", "symbolic-ref", "refs/remotes/origin/HEAD"])
|
|
339
356
|
if c.return_code != 0:
|
|
340
357
|
raise GitCommandError(c.err)
|
|
341
358
|
return c.out.strip()
|
|
@@ -17,7 +17,7 @@ def run(hooks: str | list[str], _env_prefix: str = "CZ_", **env: object) -> None
|
|
|
17
17
|
for hook in hooks:
|
|
18
18
|
out.info(f"Running hook '{hook}'")
|
|
19
19
|
|
|
20
|
-
c = cmd.
|
|
20
|
+
c = cmd.run_shell(hook, env=_format_env(_env_prefix, env))
|
|
21
21
|
|
|
22
22
|
if c.out:
|
|
23
23
|
out.write(c.out)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "4.15.0"
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import subprocess
|
|
5
|
-
from typing import TYPE_CHECKING, NamedTuple
|
|
6
|
-
|
|
7
|
-
from charset_normalizer import from_bytes
|
|
8
|
-
|
|
9
|
-
from commitizen.exceptions import CharacterSetDecodeError
|
|
10
|
-
|
|
11
|
-
if TYPE_CHECKING:
|
|
12
|
-
from collections.abc import Mapping
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class Command(NamedTuple):
|
|
16
|
-
out: str
|
|
17
|
-
err: str
|
|
18
|
-
stdout: bytes
|
|
19
|
-
stderr: bytes
|
|
20
|
-
return_code: int
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def _try_decode(bytes_: bytes) -> str:
|
|
24
|
-
try:
|
|
25
|
-
return bytes_.decode("utf-8")
|
|
26
|
-
except UnicodeDecodeError:
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
charset_match = from_bytes(bytes_).best()
|
|
30
|
-
if charset_match is None:
|
|
31
|
-
raise CharacterSetDecodeError()
|
|
32
|
-
try:
|
|
33
|
-
return bytes_.decode(charset_match.encoding)
|
|
34
|
-
except UnicodeDecodeError as e:
|
|
35
|
-
raise CharacterSetDecodeError() from e
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def run(cmd: str, env: Mapping[str, str] | None = None) -> Command:
|
|
39
|
-
if env is not None:
|
|
40
|
-
env = {**os.environ, **env}
|
|
41
|
-
process = subprocess.Popen(
|
|
42
|
-
cmd,
|
|
43
|
-
shell=True,
|
|
44
|
-
stdout=subprocess.PIPE,
|
|
45
|
-
stderr=subprocess.PIPE,
|
|
46
|
-
stdin=subprocess.PIPE,
|
|
47
|
-
env=env,
|
|
48
|
-
)
|
|
49
|
-
stdout, stderr = process.communicate()
|
|
50
|
-
return_code = process.returncode
|
|
51
|
-
return Command(
|
|
52
|
-
_try_decode(stdout),
|
|
53
|
-
_try_decode(stderr),
|
|
54
|
-
stdout,
|
|
55
|
-
stderr,
|
|
56
|
-
return_code,
|
|
57
|
-
)
|
|
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
|
{commitizen-4.15.0 → commitizen-4.15.1}/commitizen/cz/conventional_commits/conventional_commits.py
RENAMED
|
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
|