Skip to content

Commit 4b6a441

Browse files
committed
feat(version): add MANUAL_VERSION, --next and --patch to version command
1 parent 1d89195 commit 4b6a441

12 files changed

+326
-111
lines changed

commitizen/cli.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
InvalidCommandArgumentError,
2121
NoCommandFoundError,
2222
)
23+
from commitizen.version_increment import VersionIncrement
2324

2425
logger = logging.getLogger(__name__)
2526

@@ -505,54 +506,79 @@ def __call__(
505506
{
506507
"name": ["version"],
507508
"description": (
508-
"get the version of the installed commitizen or the current project"
509-
" (default: installed commitizen)"
509+
"Shows version of Commitizen or the version of the current project. "
510+
"Combine with other options to simulate the version increment process and play with the selected version scheme. "
511+
"If no arguments are provided, just show the installed Commitizen version."
510512
),
511513
"help": (
512-
"get the version of the installed commitizen or the current project"
513-
" (default: installed commitizen)"
514+
"Shows version of Commitizen or the version of the current project. "
515+
"Combine with other options to simulate the version increment process and play with the selected version scheme."
514516
),
515517
"func": commands.Version,
516518
"arguments": [
517519
{
518520
"name": ["-r", "--report"],
519-
"help": "get system information for reporting bugs",
521+
"help": "Get system information for reporting bugs",
520522
"action": "store_true",
521523
"exclusive_group": "group1",
522524
},
523525
{
524526
"name": ["-p", "--project"],
525-
"help": "get the version of the current project",
527+
"help": "Get the version of the current project",
526528
"action": "store_true",
527529
"exclusive_group": "group1",
528530
},
529531
{
530532
"name": ["-c", "--commitizen"],
531-
"help": "get the version of the installed commitizen",
533+
"help": "Get the version of the installed commitizen",
532534
"action": "store_true",
533535
"exclusive_group": "group1",
534536
},
535537
{
536538
"name": ["-v", "--verbose"],
537539
"help": (
538-
"get the version of both the installed commitizen "
540+
"Get the version of both the installed commitizen "
539541
"and the current project"
540542
),
541543
"action": "store_true",
542544
"exclusive_group": "group1",
543545
},
544546
{
545547
"name": ["--major"],
546-
"help": "get just the major version. Need to be used with --project or --verbose.",
548+
"help": "Output the major version only. Need to be used with MANUAL_VERSION, --project or --verbose.",
547549
"action": "store_true",
548550
"exclusive_group": "group2",
549551
},
550552
{
551553
"name": ["--minor"],
552-
"help": "get just the minor version. Need to be used with --project or --verbose.",
554+
"help": "Output the minor version only. Need to be used with MANUAL_VERSION, --project or --verbose.",
553555
"action": "store_true",
554556
"exclusive_group": "group2",
555557
},
558+
{
559+
"name": ["--patch"],
560+
"help": "Output the patch version only. Need to be used with MANUAL_VERSION, --project or --verbose.",
561+
"action": "store_true",
562+
"exclusive_group": "group2",
563+
},
564+
{
565+
"name": ["--next"],
566+
"help": "Output the next version.",
567+
"type": str,
568+
"nargs": "?",
569+
"default": None,
570+
"const": "USE_GIT_COMMITS",
571+
"choices": ["USE_GIT_COMMITS"]
572+
+ [str(increment) for increment in VersionIncrement],
573+
"exclusive_group": "group2",
574+
},
575+
{
576+
"name": "manual_version",
577+
"type": str,
578+
"nargs": "?",
579+
"help": "Use the version provided instead of the version from the project. Can be used to test the selected version scheme.",
580+
"metavar": "MANUAL_VERSION",
581+
},
556582
],
557583
},
558584
],

commitizen/commands/version.py

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,31 @@
22
import sys
33
from typing import TypedDict
44

5+
from packaging.version import InvalidVersion
6+
57
from commitizen import out
68
from commitizen.__version__ import __version__
79
from commitizen.config import BaseConfig
810
from commitizen.exceptions import NoVersionSpecifiedError, VersionSchemeUnknown
911
from commitizen.providers import get_provider
12+
from commitizen.version_increment import VersionIncrement
1013
from commitizen.version_schemes import get_version_scheme
1114

1215

1316
class VersionArgs(TypedDict, total=False):
17+
manual_version: str | None
18+
next: str | None
19+
20+
# Exclusive groups 1
1421
commitizen: bool
1522
report: bool
1623
project: bool
1724
verbose: bool
25+
26+
# Exclusive groups 2
1827
major: bool
1928
minor: bool
29+
patch: bool
2030

2131

2232
class Version:
@@ -41,24 +51,53 @@ def __call__(self) -> None:
4151
if self.arguments.get("verbose"):
4252
out.write(f"Installed Commitizen Version: {__version__}")
4353

44-
if not self.arguments.get("commitizen") and (
45-
self.arguments.get("project") or self.arguments.get("verbose")
54+
if self.arguments.get("commitizen"):
55+
out.write(__version__)
56+
return
57+
58+
if (
59+
self.arguments.get("project")
60+
or self.arguments.get("verbose")
61+
or self.arguments.get("next")
62+
or self.arguments.get("manual_version")
4663
):
64+
version_str = self.arguments.get("manual_version")
65+
if version_str is None:
66+
try:
67+
version_str = get_provider(self.config).get_version()
68+
except NoVersionSpecifiedError:
69+
out.error("No project information in this project.")
70+
return
4771
try:
48-
version = get_provider(self.config).get_version()
49-
except NoVersionSpecifiedError:
50-
out.error("No project information in this project.")
51-
return
52-
try:
53-
version_scheme = get_version_scheme(self.config.settings)(version)
72+
version_scheme = get_version_scheme(self.config.settings)
5473
except VersionSchemeUnknown:
5574
out.error("Unknown version scheme.")
5675
return
5776

77+
try:
78+
version = version_scheme(version_str)
79+
except InvalidVersion:
80+
out.error(f"Invalid version: '{version_str}'")
81+
return
82+
83+
if next_increment_str := self.arguments.get("next"):
84+
if next_increment_str == "USE_GIT_COMMITS":
85+
# TODO: implement this
86+
raise NotImplementedError("USE_GIT_COMMITS is not implemented")
87+
88+
next_increment = VersionIncrement.from_value(next_increment_str)
89+
# TODO: modify the interface of bump to accept VersionIncrement
90+
version = version.bump(increment=str(next_increment)) # type: ignore[arg-type]
91+
5892
if self.arguments.get("major"):
59-
version = f"{version_scheme.major}"
60-
elif self.arguments.get("minor"):
61-
version = f"{version_scheme.minor}"
93+
out.write(version.major)
94+
return
95+
if self.arguments.get("minor"):
96+
out.write(version.minor)
97+
return
98+
if self.arguments.get("patch"):
99+
out.write(version.micro)
100+
return
62101

63102
out.write(
64103
f"Project Version: {version}"
@@ -67,11 +106,12 @@ def __call__(self) -> None:
67106
)
68107
return
69108

70-
if self.arguments.get("major") or self.arguments.get("minor"):
71-
out.error(
72-
"Major or minor version can only be used with --project or --verbose."
73-
)
74-
return
109+
for argument in ("major", "minor", "patch"):
110+
if self.arguments.get(argument):
111+
out.error(
112+
f"{argument} can only be used with MANUAL_VERSION, --project or --verbose."
113+
)
114+
return
75115

76116
# If no arguments are provided, just show the installed commitizen version
77117
out.write(__version__)

commitizen/git.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ class EOLType(Enum):
2121
def for_open(cls) -> str:
2222
c = cmd.run("git config core.eol")
2323
eol = c.out.strip().upper()
24-
return cls._char_for_open()[cls._safe_cast(eol)]
24+
return cls._char_for_open()[cls._from_value(eol)]
2525

2626
@classmethod
27-
def _safe_cast(cls, eol: str) -> EOLType:
27+
def _from_value(cls, eol: str) -> EOLType:
2828
try:
2929
return cls[eol]
3030
except KeyError:

commitizen/out.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,35 @@
99
sys.stdout.reconfigure(encoding="utf-8")
1010

1111

12-
def write(value: str, *args: object) -> None:
12+
def write(value: object, *args: object) -> None:
1313
"""Intended to be used when value is multiline."""
1414
print(value, *args)
1515

1616

17-
def line(value: str, *args: object, **kwargs: Any) -> None:
17+
def line(value: object, *args: object, **kwargs: Any) -> None:
1818
"""Wrapper in case I want to do something different later."""
1919
print(value, *args, **kwargs)
2020

2121

22-
def error(value: str) -> None:
23-
message = colored(value, "red")
22+
def error(value: object) -> None:
23+
message = colored(str(value), "red")
2424
line(message, file=sys.stderr)
2525

2626

27-
def success(value: str) -> None:
28-
message = colored(value, "green")
27+
def success(value: object) -> None:
28+
message = colored(str(value), "green")
2929
line(message)
3030

3131

32-
def info(value: str) -> None:
33-
message = colored(value, "blue")
32+
def info(value: object) -> None:
33+
message = colored(str(value), "blue")
3434
line(message)
3535

3636

37-
def diagnostic(value: str) -> None:
37+
def diagnostic(value: object) -> None:
3838
line(value, file=sys.stderr)
3939

4040

41-
def warn(value: str) -> None:
42-
message = colored(value, "magenta")
41+
def warn(value: object) -> None:
42+
message = colored(str(value), "magenta")
4343
line(message, file=sys.stderr)

commitizen/version_increment.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from __future__ import annotations
2+
3+
from enum import IntEnum
4+
5+
6+
class VersionIncrement(IntEnum):
7+
"""An enumeration representing semantic versioning increments.
8+
This class defines the four types of version increments according to semantic versioning:
9+
- NONE: For commits that don't require a version bump (docs, style, etc.)
10+
- PATCH: For backwards-compatible bug fixes
11+
- MINOR: For backwards-compatible functionality additions
12+
- MAJOR: For incompatible API changes
13+
"""
14+
15+
NONE = 0
16+
PATCH = 1
17+
MINOR = 2
18+
MAJOR = 3
19+
20+
def __str__(self) -> str:
21+
return self.name
22+
23+
@classmethod
24+
def from_value(cls, value: object) -> VersionIncrement:
25+
if not isinstance(value, str):
26+
return VersionIncrement.NONE
27+
try:
28+
return cls[value]
29+
except KeyError:
30+
return VersionIncrement.NONE

docs/commands/version.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ Get the version of the installed Commitizen or the current project (default: ins
33
## Usage
44

55
![cz version --help](../images/cli_help/cz_version___help.svg)
6+
7+
<!-- TODO: add documentation after this feature is stabilized -->
Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
1-
usage: cz version [-h] [-r | -p | -c | -v] [--major | --minor]
1+
usage: cz version [-h] [-r | -p | -c | -v]
2+
[--major | --minor | --patch | --next [{USE_GIT_COMMITS,NONE,PATCH,MINOR,MAJOR}]]
3+
[MANUAL_VERSION]
24

3-
get the version of the installed commitizen or the current project (default:
4-
installed commitizen)
5+
Shows version of Commitizen or the version of the current project. Combine
6+
with other options to simulate the version increment process and play with the
7+
selected version scheme. If no arguments are provided, just show the installed
8+
Commitizen version.
9+
10+
positional arguments:
11+
MANUAL_VERSION Use the version provided instead of the version from
12+
the project. Can be used to test the selected version
13+
scheme.
514

615
options:
7-
-h, --help show this help message and exit
8-
-r, --report get system information for reporting bugs
9-
-p, --project get the version of the current project
10-
-c, --commitizen get the version of the installed commitizen
11-
-v, --verbose get the version of both the installed commitizen and the
12-
current project
13-
--major get just the major version. Need to be used with --project
14-
or --verbose.
15-
--minor get just the minor version. Need to be used with --project
16-
or --verbose.
16+
-h, --help show this help message and exit
17+
-r, --report Get system information for reporting bugs
18+
-p, --project Get the version of the current project
19+
-c, --commitizen Get the version of the installed commitizen
20+
-v, --verbose Get the version of both the installed commitizen and
21+
the current project
22+
--major Output the major version only. Need to be used with
23+
MANUAL_VERSION, --project or --verbose.
24+
--minor Output the minor version only. Need to be used with
25+
MANUAL_VERSION, --project or --verbose.
26+
--patch Output the patch version only. Need to be used with
27+
MANUAL_VERSION, --project or --verbose.
28+
--next [{USE_GIT_COMMITS,NONE,PATCH,MINOR,MAJOR}]
29+
Output the next version.
Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
1-
usage: cz version [-h] [-r | -p | -c | -v] [--major | --minor]
1+
usage: cz version [-h] [-r | -p | -c | -v]
2+
[--major | --minor | --patch | --next [{USE_GIT_COMMITS,NONE,PATCH,MINOR,MAJOR}]]
3+
[MANUAL_VERSION]
24

3-
get the version of the installed commitizen or the current project (default:
4-
installed commitizen)
5+
Shows version of Commitizen or the version of the current project. Combine
6+
with other options to simulate the version increment process and play with the
7+
selected version scheme. If no arguments are provided, just show the installed
8+
Commitizen version.
9+
10+
positional arguments:
11+
MANUAL_VERSION Use the version provided instead of the version from
12+
the project. Can be used to test the selected version
13+
scheme.
514

615
options:
7-
-h, --help show this help message and exit
8-
-r, --report get system information for reporting bugs
9-
-p, --project get the version of the current project
10-
-c, --commitizen get the version of the installed commitizen
11-
-v, --verbose get the version of both the installed commitizen and the
12-
current project
13-
--major get just the major version. Need to be used with --project
14-
or --verbose.
15-
--minor get just the minor version. Need to be used with --project
16-
or --verbose.
16+
-h, --help show this help message and exit
17+
-r, --report Get system information for reporting bugs
18+
-p, --project Get the version of the current project
19+
-c, --commitizen Get the version of the installed commitizen
20+
-v, --verbose Get the version of both the installed commitizen and
21+
the current project
22+
--major Output the major version only. Need to be used with
23+
MANUAL_VERSION, --project or --verbose.
24+
--minor Output the minor version only. Need to be used with
25+
MANUAL_VERSION, --project or --verbose.
26+
--patch Output the patch version only. Need to be used with
27+
MANUAL_VERSION, --project or --verbose.
28+
--next [{USE_GIT_COMMITS,NONE,PATCH,MINOR,MAJOR}]
29+
Output the next version.

0 commit comments

Comments
 (0)