Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2ba0b73

Browse files
feat(bump): support optional manual version argument
1 parent 230aecf commit 2ba0b73

File tree

5 files changed

+140
-34
lines changed

5 files changed

+140
-34
lines changed

‎commitizen/cli.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@
183183
"default": False,
184184
"help": "retry commit if it fails the 1st time",
185185
},
186+
{
187+
"name": "manual_version",
188+
"type": str,
189+
"nargs": "?",
190+
"help": "bump to the given version (e.g: 1.5.3)",
191+
"metavar": "MANUAL_VERSION",
192+
},
186193
],
187194
},
188195
{

‎commitizen/commands/bump.py‎

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import List, Optional
33

44
import questionary
5-
from packaging.version import Version
5+
from packaging.version import InvalidVersion, Version
66

77
from commitizen import bump, cmd, factory, git, out
88
from commitizen.commands.changelog import Changelog
@@ -12,10 +12,12 @@
1212
BumpTagFailedError,
1313
DryRunExit,
1414
ExpectedExit,
15+
InvalidManualVersion,
1516
NoCommitsFoundError,
1617
NoneIncrementExit,
1718
NoPatternMapError,
1819
NotAGitProjectError,
20+
NotAllowed,
1921
NoVersionSpecifiedError,
2022
)
2123

@@ -106,6 +108,22 @@ def __call__(self): # noqa: C901
106108
devrelease: Optional[int] = self.arguments["devrelease"]
107109
is_files_only: Optional[bool] = self.arguments["files_only"]
108110
is_local_version: Optional[bool] = self.arguments["local_version"]
111+
manual_version = self.arguments["manual_version"]
112+
113+
if manual_version:
114+
if increment:
115+
raise NotAllowed("--increment cannot be combined with MANUAL_VERSION")
116+
117+
if prerelease:
118+
raise NotAllowed("--prerelease cannot be combined with MANUAL_VERSION")
119+
120+
if devrelease is not None:
121+
raise NotAllowed("--devrelease cannot be combined with MANUAL_VERSION")
122+
123+
if is_local_version:
124+
raise NotAllowed(
125+
"--local-version cannot be combined with MANUAL_VERSION"
126+
)
109127

110128
current_tag_version: str = bump.normalize_tag(
111129
current_version, tag_format=tag_format
@@ -127,46 +145,53 @@ def __call__(self): # noqa: C901
127145
if not commits and not current_version_instance.is_prerelease:
128146
raise NoCommitsFoundError("[NO_COMMITS_FOUND]\n" "No new commits found.")
129147

130-
if increment is None:
131-
increment = self.find_increment(commits)
132-
133-
# It may happen that there are commits, but they are not eligible
134-
# for an increment, this generates a problem when using prerelease (#281)
135-
if (
136-
prerelease
137-
and increment is None
138-
and not current_version_instance.is_prerelease
139-
):
140-
raise NoCommitsFoundError(
141-
"[NO_COMMITS_FOUND]\n"
142-
"No commits found to generate a pre-release.\n"
143-
"To avoid this error, manually specify the type of increment with `--increment`"
144-
)
145-
146-
# Increment is removed when current and next version
147-
# are expected to be prereleases.
148-
if prerelease and current_version_instance.is_prerelease:
149-
increment = None
148+
if manual_version:
149+
try:
150+
new_version = Version(manual_version)
151+
except InvalidVersion as exc:
152+
raise InvalidManualVersion(
153+
"[INVALID_MANUAL_VERSION]\n"
154+
f"Invalid manual version: '{manual_version}'"
155+
) from exc
156+
else:
157+
if increment is None:
158+
increment = self.find_increment(commits)
159+
160+
# It may happen that there are commits, but they are not eligible
161+
# for an increment, this generates a problem when using prerelease (#281)
162+
if (
163+
prerelease
164+
and increment is None
165+
and not current_version_instance.is_prerelease
166+
):
167+
raise NoCommitsFoundError(
168+
"[NO_COMMITS_FOUND]\n"
169+
"No commits found to generate a pre-release.\n"
170+
"To avoid this error, manually specify the type of increment with `--increment`"
171+
)
150172

151-
new_version = bump.generate_version(
152-
current_version,
153-
increment,
154-
prerelease=prerelease,
155-
devrelease=devrelease,
156-
is_local_version=is_local_version,
157-
)
173+
# Increment is removed when current and next version
174+
# are expected to be prereleases.
175+
if prerelease and current_version_instance.is_prerelease:
176+
increment = None
177+
178+
new_version = bump.generate_version(
179+
current_version,
180+
increment,
181+
prerelease=prerelease,
182+
devrelease=devrelease,
183+
is_local_version=is_local_version,
184+
)
158185

159186
new_tag_version = bump.normalize_tag(new_version, tag_format=tag_format)
160187
message = bump.create_commit_message(
161188
current_version, new_version, bump_commit_message
162189
)
163190

164191
# Report found information
165-
information = (
166-
f"{message}\n"
167-
f"tag to create: {new_tag_version}\n"
168-
f"increment detected: {increment}\n"
169-
)
192+
information = f"{message}\n" f"tag to create: {new_tag_version}\n"
193+
if increment:
194+
information += f"increment detected: {increment}\n"
170195

171196
if self.changelog_to_stdout:
172197
# When the changelog goes to stdout, we want to send

‎commitizen/exceptions.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ExitCode(enum.IntEnum):
2828
NO_INCREMENT = 21
2929
UNRECOGNIZED_CHARACTERSET_ENCODING = 22
3030
GIT_COMMAND_ERROR = 23
31+
INVALID_MANUAL_VERSION = 24
3132

3233

3334
class CommitizenException(Exception):
@@ -158,3 +159,7 @@ class CharacterSetDecodeError(CommitizenException):
158159

159160
class GitCommandError(CommitizenException):
160161
exit_code = ExitCode.GIT_COMMAND_ERROR
162+
163+
164+
class InvalidManualVersion(CommitizenException):
165+
exit_code = ExitCode.INVALID_MANUAL_VERSION

‎docs/bump.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ usage: cz bump [-h] [--dry-run] [--files-only] [--local-version] [--changelog]
5959
[--bump-message BUMP_MESSAGE] [--prerelease {alpha,beta,rc}]
6060
[--devrelease DEVRELEASE] [--increment {MAJOR,MINOR,PATCH}]
6161
[--check-consistency] [--annotated-tag] [--gpg-sign]
62-
[--changelog-to-stdout] [--retry]
62+
[--changelog-to-stdout] [--retry] [MANUAL_VERSION]
63+
64+
positional arguments:
65+
MANUAL_VERSION bump to the given version (e.g: 1.5.3)
6366

6467
options:
6568
-h, --help show this help message and exit

‎tests/commands/test_bump_command.py‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
DryRunExit,
1515
ExitCode,
1616
ExpectedExit,
17+
InvalidManualVersion,
1718
NoCommitsFoundError,
1819
NoneIncrementExit,
1920
NoPatternMapError,
2021
NotAGitProjectError,
22+
NotAllowed,
2123
NoVersionSpecifiedError,
2224
)
2325
from tests.utils import create_file_and_commit
@@ -614,3 +616,67 @@ def test_bump_changelog_command_commits_untracked_changelog_and_version_files(
614616
commit_file_names = git.get_filenames_in_commit()
615617
assert "CHANGELOG.md" in commit_file_names
616618
assert version_filepath in commit_file_names
619+
620+
621+
@pytest.mark.parametrize(
622+
"testargs",
623+
[
624+
["cz", "bump", "--local-version", "1.2.3"],
625+
["cz", "bump", "--prerelease", "rc", "1.2.3"],
626+
["cz", "bump", "--devrelease", "0", "1.2.3"],
627+
["cz", "bump", "--devrelease", "1", "1.2.3"],
628+
["cz", "bump", "--increment", "PATCH", "1.2.3"],
629+
],
630+
)
631+
def test_bump_invalid_manual_args_raises_exception(mocker, testargs):
632+
mocker.patch.object(sys, "argv", testargs)
633+
634+
with pytest.raises(NotAllowed):
635+
cli.main()
636+
637+
638+
@pytest.mark.usefixtures("tmp_commitizen_project")
639+
@pytest.mark.parametrize(
640+
"manual_version",
641+
[
642+
"noversion",
643+
"1.2..3",
644+
],
645+
)
646+
def test_bump_invalid_manual_version_raises_exception(mocker, manual_version):
647+
create_file_and_commit("feat: new file")
648+
649+
testargs = ["cz", "bump", "--yes", manual_version]
650+
mocker.patch.object(sys, "argv", testargs)
651+
652+
with pytest.raises(InvalidManualVersion) as excinfo:
653+
cli.main()
654+
655+
expected_error_message = (
656+
"[INVALID_MANUAL_VERSION]\n" f"Invalid manual version: '{manual_version}'"
657+
)
658+
assert expected_error_message in str(excinfo.value)
659+
660+
661+
@pytest.mark.usefixtures("tmp_commitizen_project")
662+
@pytest.mark.parametrize(
663+
"manual_version",
664+
[
665+
"0.0.1",
666+
"0.1.0rc2",
667+
"0.1.0.dev2",
668+
"0.1.0+1.0.0",
669+
"0.1.0rc2.dev2+1.0.0",
670+
"0.1.1",
671+
"0.2.0",
672+
"1.0.0",
673+
],
674+
)
675+
def test_bump_manual_version(mocker, manual_version):
676+
create_file_and_commit("feat: new file")
677+
678+
testargs = ["cz", "bump", "--yes", manual_version]
679+
mocker.patch.object(sys, "argv", testargs)
680+
cli.main()
681+
tag_exists = git.tag_exist(manual_version)
682+
assert tag_exists is True

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /