Skip to content

Commit 54159ff

Browse files
committed
feat(version): add MANUAL_VERSION, --next and --patch to version command, remove type alias
1 parent 2072f8e commit 54159ff

File tree

10 files changed

+218
-71
lines changed

10 files changed

+218
-71
lines changed

‎commitizen/bump.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
ifTYPE_CHECKING:
1616
fromcollections.abcimportGenerator, Iterable
1717

18-
fromcommitizen.version_schemesimportIncrement, Version
18+
fromcommitizen.version_schemesimportIncrement, VersionProtocol
1919

2020
VERSION_TYPES= [None, PATCH, MINOR, MAJOR]
2121

@@ -131,8 +131,8 @@ def _resolve_files_and_regexes(
131131

132132

133133
defcreate_commit_message(
134-
current_version: Version|str,
135-
new_version: Version|str,
134+
current_version: VersionProtocol|str,
135+
new_version: VersionProtocol|str,
136136
message_template: str|None=None,
137137
) ->str:
138138
ifmessage_templateisNone:

‎commitizen/cli.py‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
InvalidCommandArgumentError,
2121
NoCommandFoundError,
2222
)
23+
fromcommitizen.version_incrementimportVersionIncrement
2324

2425
logger=logging.getLogger(__name__)
2526

@@ -543,16 +544,36 @@ def __call__(
543544
},
544545
{
545546
"name": ["--major"],
546-
"help": "get just the major version. Need to be used with --project or --verbose.",
547+
"help": "Output the major version only. Need to be used with MANUAL_VERSION, --project or --verbose.",
547548
"action": "store_true",
548549
"exclusive_group": "group2",
549550
},
550551
{
551552
"name": ["--minor"],
552-
"help": "get just the minor version. Need to be used with --project or --verbose.",
553+
"help": "Output the minor version only. Need to be used with MANUAL_VERSION, --project or --verbose.",
553554
"action": "store_true",
554555
"exclusive_group": "group2",
555556
},
557+
{
558+
"name": ["--patch"],
559+
"help": "Output the patch version only. Need to be used with MANUAL_VERSION, --project or --verbose.",
560+
"action": "store_true",
561+
"exclusive_group": "group2",
562+
},
563+
{
564+
"name": ["--next"],
565+
"help": "Output the next version.",
566+
"type": str,
567+
"choices": [str(increment) forincrementinVersionIncrement],
568+
"exclusive_group": "group2",
569+
},
570+
{
571+
"name": "manual_version",
572+
"type": str,
573+
"nargs": "?",
574+
"help": "Use the version provided instead of the version from the project. Can be used to test the selected version scheme",
575+
"metavar": "MANUAL_VERSION",
576+
},
556577
],
557578
},
558579
],

‎commitizen/commands/init.py‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
fromcommitizen.defaultsimportCONFIG_FILES, DEFAULT_SETTINGS
1414
fromcommitizen.exceptionsimportInitFailedError, NoAnswersError
1515
fromcommitizen.gitimportget_latest_tag_name, get_tag_names, smart_open
16-
fromcommitizen.version_schemesimportKNOWN_SCHEMES, Version, get_version_scheme
16+
fromcommitizen.version_schemesimport (
17+
KNOWN_SCHEMES,
18+
VersionProtocol,
19+
get_version_scheme,
20+
)
1721

1822
ifTYPE_CHECKING:
1923
fromcommitizen.configimport (
@@ -238,7 +242,7 @@ def _ask_version_scheme(self) -> str:
238242
).unsafe_ask()
239243
returnscheme
240244

241-
def_ask_major_version_zero(self, version: Version) ->bool:
245+
def_ask_major_version_zero(self, version: VersionProtocol) ->bool:
242246
"""Ask for setting: major_version_zero"""
243247
ifversion.major>0:
244248
returnFalse
@@ -295,7 +299,7 @@ def _write_config_to_file(
295299
cz_name: str,
296300
version_provider: str,
297301
version_scheme: str,
298-
version: Version,
302+
version: VersionProtocol,
299303
tag_format: str,
300304
update_changelog_on_bump: bool,
301305
major_version_zero: bool,

‎commitizen/commands/version.py‎

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,31 @@
22
importsys
33
fromtypingimportTypedDict
44

5+
frompackaging.versionimportInvalidVersion
6+
57
fromcommitizenimportout
68
fromcommitizen.__version__import__version__
79
fromcommitizen.configimportBaseConfig
810
fromcommitizen.exceptionsimportNoVersionSpecifiedError, VersionSchemeUnknown
911
fromcommitizen.providersimportget_provider
12+
fromcommitizen.version_incrementimportVersionIncrement
1013
fromcommitizen.version_schemesimportget_version_scheme
1114

1215

1316
classVersionArgs(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
classVersion:
@@ -41,24 +51,49 @@ def __call__(self) -> None:
4151
ifself.arguments.get("verbose"):
4252
out.write(f"Installed Commitizen Version: {__version__}")
4353

44-
ifnotself.arguments.get("commitizen") and (
45-
self.arguments.get("project") orself.arguments.get("verbose")
54+
ifself.arguments.get("commitizen"):
55+
out.write(__version__)
56+
return
57+
58+
if (
59+
self.arguments.get("project")
60+
orself.arguments.get("verbose")
61+
orself.arguments.get("next")
62+
orself.arguments.get("manual_version")
4663
):
64+
version_str=self.arguments.get("manual_version")
65+
ifversion_strisNone:
66+
try:
67+
version_str=get_provider(self.config).get_version()
68+
exceptNoVersionSpecifiedError:
69+
out.error("No project information in this project.")
70+
return
4771
try:
48-
version=get_provider(self.config).get_version()
49-
exceptNoVersionSpecifiedError:
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
exceptVersionSchemeUnknown:
5574
out.error("Unknown version scheme.")
5675
return
5776

77+
try:
78+
version=version_scheme(version_str)
79+
exceptInvalidVersion:
80+
out.error("Invalid version.")
81+
return
82+
83+
ifnext_str:=self.arguments.get("next"):
84+
next_increment=VersionIncrement.safe_cast(next_str)
85+
# TODO: modify the interface of bump to accept VersionIncrement
86+
version=version.bump(increment=str(next_increment)) # type: ignore[arg-type]
87+
5888
ifself.arguments.get("major"):
59-
version=f"{version_scheme.major}"
60-
elifself.arguments.get("minor"):
61-
version=f"{version_scheme.minor}"
89+
out.write(version.major)
90+
return
91+
ifself.arguments.get("minor"):
92+
out.write(version.minor)
93+
return
94+
ifself.arguments.get("patch"):
95+
out.write(version.micro)
96+
return
6297

6398
out.write(
6499
f"Project Version: {version}"
@@ -67,11 +102,12 @@ def __call__(self) -> None:
67102
)
68103
return
69104

70-
ifself.arguments.get("major") orself.arguments.get("minor"):
71-
out.error(
72-
"Major or minor version can only be used with --project or --verbose."
73-
)
74-
return
105+
forargumentin ("major", "minor", "patch"):
106+
ifself.arguments.get(argument):
107+
out.error(
108+
f"{argument} can only be used with MANUAL_VERSION, --project or --verbose."
109+
)
110+
return
75111

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

‎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-
defwrite(value: str, *args: object) ->None:
12+
defwrite(value: object, *args: object) ->None:
1313
"""Intended to be used when value is multiline."""
1414
print(value, *args)
1515

1616

17-
defline(value: str, *args: object, **kwargs: Any) ->None:
17+
defline(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-
deferror(value: str) ->None:
23-
message=colored(value, "red")
22+
deferror(value: object) ->None:
23+
message=colored(str(value), "red")
2424
line(message, file=sys.stderr)
2525

2626

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

3131

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

3636

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

4040

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

‎commitizen/tags.py‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,14 @@
1414
fromcommitizen.version_schemesimport (
1515
DEFAULT_SCHEME,
1616
InvalidVersion,
17-
Version,
18-
VersionScheme,
17+
VersionProtocol,
1918
get_version_scheme,
2019
)
2120

2221
ifTYPE_CHECKING:
2322
importsys
2423
fromcollections.abcimportIterable, Sequence
2524

26-
fromcommitizen.version_schemesimportVersionScheme
27-
2825
# Self is Python 3.11+ but backported in typing-extensions
2926
ifsys.version_info< (3, 11):
3027
fromtyping_extensionsimportSelf
@@ -75,15 +72,15 @@ class TagRules:
7572
assert not rules.is_version_tag("warn1.0.0", warn=True) # Does warn
7673
7774
assert rules.search_version("# My v1.0.0 version").version == "1.0.0"
78-
assert rules.extract_version("v1.0.0") == Version("1.0.0")
75+
assert rules.extract_version("v1.0.0") == VersionProtocol("1.0.0")
7976
try:
8077
assert rules.extract_version("not-a-v1.0.0")
8178
except InvalidVersion:
8279
print("Does not match a tag format")
8380
```
8481
"""
8582

86-
scheme: VersionScheme=DEFAULT_SCHEME
83+
scheme: type[VersionProtocol]=DEFAULT_SCHEME
8784
tag_format: str=DEFAULT_SETTINGS["tag_format"]
8885
legacy_tag_formats: Sequence[str] =field(default_factory=list)
8986
ignored_tag_formats: Sequence[str] =field(default_factory=list)
@@ -145,7 +142,7 @@ def get_version_tags(
145142
"""Filter in version tags and warn on unexpected tags"""
146143
return [tagfortagintagsifself.is_version_tag(tag, warn)]
147144

148-
defextract_version(self, tag: GitTag) ->Version:
145+
defextract_version(self, tag: GitTag) ->VersionProtocol:
149146
"""
150147
Extract a version from the tag as defined in tag formats.
151148
@@ -211,7 +208,7 @@ def search_version(self, text: str, last: bool = False) -> VersionTag | None:
211208
returnVersionTag(version, match.group(0))
212209

213210
defnormalize_tag(
214-
self, version: Version|str, tag_format: str|None=None
211+
self, version: VersionProtocol|str, tag_format: str|None=None
215212
) ->str:
216213
"""
217214
The tag and the software version might be different.
@@ -241,7 +238,7 @@ def normalize_tag(
241238
)
242239

243240
deffind_tag_for(
244-
self, tags: Iterable[GitTag], version: Version|str
241+
self, tags: Iterable[GitTag], version: VersionProtocol|str
245242
) ->GitTag|None:
246243
"""Find the first matching tag for a given version."""
247244
version=self.scheme(version) ifisinstance(version, str) elseversion

‎commitizen/version_increment.py‎

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

0 commit comments

Comments
(0)