python-semantic-release 9.1.1__py3-none-any.whl → 9.2.1__py3-none-any.whl

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.
Files changed (30) hide show
  1. {python_semantic_release-9.1.1.dist-info → python_semantic_release-9.2.1.dist-info}/METADATA +3 -2
  2. python_semantic_release-9.2.1.dist-info/RECORD +53 -0
  3. {python_semantic_release-9.1.1.dist-info → python_semantic_release-9.2.1.dist-info}/WHEEL +1 -1
  4. semantic_release/__init__.py +2 -1
  5. semantic_release/changelog/release_history.py +11 -11
  6. semantic_release/changelog/template.py +3 -1
  7. semantic_release/cli/commands/changelog.py +2 -2
  8. semantic_release/cli/commands/version.py +51 -6
  9. semantic_release/cli/common.py +5 -3
  10. semantic_release/cli/config.py +7 -2
  11. semantic_release/cli/util.py +1 -0
  12. semantic_release/commit_parser/_base.py +1 -2
  13. semantic_release/commit_parser/angular.py +1 -0
  14. semantic_release/commit_parser/emoji.py +1 -0
  15. semantic_release/commit_parser/scipy.py +1 -0
  16. semantic_release/commit_parser/tag.py +1 -0
  17. semantic_release/commit_parser/util.py +1 -1
  18. semantic_release/helpers.py +2 -2
  19. semantic_release/hvcs/_base.py +1 -0
  20. semantic_release/hvcs/bitbucket.py +8 -9
  21. semantic_release/hvcs/gitea.py +1 -0
  22. semantic_release/hvcs/github.py +1 -0
  23. semantic_release/hvcs/gitlab.py +1 -0
  24. semantic_release/version/algorithm.py +26 -14
  25. semantic_release/version/version.py +2 -4
  26. python_semantic_release-9.1.1.dist-info/RECORD +0 -53
  27. {python_semantic_release-9.1.1.dist-info → python_semantic_release-9.2.1.dist-info}/AUTHORS.rst +0 -0
  28. {python_semantic_release-9.1.1.dist-info → python_semantic_release-9.2.1.dist-info}/LICENSE +0 -0
  29. {python_semantic_release-9.1.1.dist-info → python_semantic_release-9.2.1.dist-info}/entry_points.txt +0 -0
  30. {python_semantic_release-9.1.1.dist-info → python_semantic_release-9.2.1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-semantic-release
3
- Version: 9.1.1
3
+ Version: 9.2.1
4
4
  Summary: Automatic Semantic Versioning for Python projects
5
5
  Author-email: Rolf Erik Lekang <me@rolflekang.com>
6
6
  License: MIT
@@ -21,6 +21,7 @@ Description-Content-Type: text/x-rst
21
21
  License-File: LICENSE
22
22
  License-File: AUTHORS.rst
23
23
  Requires-Dist: click <9,>=8
24
+ Requires-Dist: click-option-group ~=0.5
24
25
  Requires-Dist: gitpython <4,>=3.0.8
25
26
  Requires-Dist: requests <3,>=2.25
26
27
  Requires-Dist: jinja2 <4,>=3.1.2
@@ -34,7 +35,7 @@ Requires-Dist: shellingham >=1.5.0.post1
34
35
  Provides-Extra: dev
35
36
  Requires-Dist: pre-commit ; extra == 'dev'
36
37
  Requires-Dist: tox ; extra == 'dev'
37
- Requires-Dist: ruff ==0.1.11 ; extra == 'dev'
38
+ Requires-Dist: ruff ==0.3.2 ; extra == 'dev'
38
39
  Provides-Extra: docs
39
40
  Requires-Dist: Sphinx <=6.0.0 ; extra == 'docs'
40
41
  Requires-Dist: sphinxcontrib-apidoc ==0.3.0 ; extra == 'docs'
@@ -0,0 +1,53 @@
1
+ semantic_release/__init__.py,sha256=bJVwtLvzG4msFOn0HdwAXWwB5EwPQ3I39rraXXrlhw0,870
2
+ semantic_release/__main__.py,sha256=vXOARLV7KHeVXgpOMU0Q-8wovpdsOrtTsycxulI5xIE,106
3
+ semantic_release/const.py,sha256=Z1o2QNh60wSLeF-_1TemMBjU3ZXbV0XghnUFsbTVfOs,831
4
+ semantic_release/enums.py,sha256=D5B_reQGGKQQT22HO5PUtvn2Bok3fkht6TfJtXkmAUg,1020
5
+ semantic_release/errors.py,sha256=KKKCV45vvE9tla0sxYDGHkHWvqDn1gEfGIpzujcDbeI,809
6
+ semantic_release/helpers.py,sha256=d1jOX0SNyqPc_3wr14xR25FfpqhMd4Ev7MNBOWlScc0,5581
7
+ semantic_release/changelog/__init__.py,sha256=Bg6Xe5Vt32rWoMscW-hd4sUwiZqzWmsg4CD1EhMesMY,262
8
+ semantic_release/changelog/context.py,sha256=ItSz5Bon2mcJkLxyQZzBTukN0zEdcaVQ4iXvz3jGCLc,986
9
+ semantic_release/changelog/release_history.py,sha256=ShzZpxTjhxka6TMbzOzYzG3EuCH8j3xjUQzll-FKcCo,6675
10
+ semantic_release/changelog/template.py,sha256=JqZcjdozM9-059Sa8PfiHxYNeyZFa0jxk_beyRLv5sU,4640
11
+ semantic_release/cli/__init__.py,sha256=gwAYhZO-4TR0tKCkQ4GqutWsL--0CII2_dcbrElI4M4,419
12
+ semantic_release/cli/common.py,sha256=cVQUI7Uaac_nJ7VEXuJ7Q9pVJpuMVRvE7bBl_i96g20,1439
13
+ semantic_release/cli/config.py,sha256=eSNqPv5G-ta3OkD0Wd9p5s2_XbwGTI50YhpWElcahHs,15854
14
+ semantic_release/cli/const.py,sha256=S8oNNpSaKdZxcAs7PAKEjQHic0czoJBGd7XHo57FOzw,39
15
+ semantic_release/cli/github_actions_output.py,sha256=stGWcuMtelY0qM2E_-IfofP6UvsQ6czsO7qpMfnRJI4,2102
16
+ semantic_release/cli/masking_filter.py,sha256=DxqjiJyABlzwwwZ1r8JGQpb6QrF00StJFm0-2-s5Fv0,3071
17
+ semantic_release/cli/util.py,sha256=FyXaBkeL7nXKjy3X9rQLEwvn7p46xPekp2V8Z-5MVrk,3755
18
+ semantic_release/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ semantic_release/cli/commands/changelog.py,sha256=vIJKTy8vPh7xGzJ3jEz-1z9evuJrHVg-Wqmms-c6G_k,4040
20
+ semantic_release/cli/commands/generate_config.py,sha256=BwtwFhh80bkOUUNnR2ArC51YfPKI_y4HMD7C1oAFREA,1695
21
+ semantic_release/cli/commands/main.py,sha256=LBbHbDNIctb35bUQsklefXVPN9bhY-LlrQFF1nNTMLg,5049
22
+ semantic_release/cli/commands/publish.py,sha256=CvhZ4Z8CTPS-4f7kWH-xJ5JTk3jlJ-p8Mg7y2KC4SnY,1492
23
+ semantic_release/cli/commands/version.py,sha256=lFXRUPM-amJaRNSaneV5olrf6UEYN_mCeBN_y7jGssk,22416
24
+ semantic_release/commit_parser/__init__.py,sha256=cv5HFBdw7OJd4Laj4Ex8ZZ5Tml8GwXgQcXW6Pasr2Ao,615
25
+ semantic_release/commit_parser/_base.py,sha256=aDS0dhFosT5i11tA5Ez8BTeikk6jwXjSEpJnJC5D2cs,2609
26
+ semantic_release/commit_parser/angular.py,sha256=bS7Wrzpg_6zFil5Y4GIZkeGDPhvWQdTlFdWTtGVcpp0,4393
27
+ semantic_release/commit_parser/emoji.py,sha256=6cFnqpvtjtxlwDYc8oB9y41RPqFGGD8PbqiAA53SVac,3289
28
+ semantic_release/commit_parser/scipy.py,sha256=AaAtQYUsG_Y29YIgDVISl5mljBCkG8zyzUkn_3HYGeM,5777
29
+ semantic_release/commit_parser/tag.py,sha256=0Y8GTRclyoLMhyDRrcMU8JKTM4lsbfpJbjqZ7qz5ifE,3194
30
+ semantic_release/commit_parser/token.py,sha256=UxYAwEylPvp4x39RqNA9ITcgkaSRDEH7A5XDDJ3tdiM,1505
31
+ semantic_release/commit_parser/util.py,sha256=vLcVDErZrExM55jMffos0hyMbNVQoJ-PeeVDG1Ej51I,730
32
+ semantic_release/data/templates/CHANGELOG.md.j2,sha256=GB3YJwgVrhlcb-g5ESdEh_Gsysb_Texxv-Ip2LjulC0,1066
33
+ semantic_release/data/templates/release_notes.md.j2,sha256=27uIHgG6iYmqdMaoWFP5LJRZcrO-3paqFzHHHsGpXXE,465
34
+ semantic_release/hvcs/__init__.py,sha256=ulesZslSG4Lu8Iz3YzOrPXpdgvgbADq_MV17B-bSYQA,379
35
+ semantic_release/hvcs/_base.py,sha256=VnsEz01W9t3DQ2QHGnsbuAB9jYfZT3hIXRRsCUnhS0g,5635
36
+ semantic_release/hvcs/bitbucket.py,sha256=pGZksLht66zLJXbPIgRz4hntsa-F1A02xl4JNRCXE0o,4626
37
+ semantic_release/hvcs/gitea.py,sha256=HpaqQQxbUiWLByzceFVkR6o_c60gT6HmFwsq4CPwJKY,8459
38
+ semantic_release/hvcs/github.py,sha256=L29AaUmmtdJTNDJqD6ro3YVcDNr8OMwqTx5ofujOZz8,10710
39
+ semantic_release/hvcs/gitlab.py,sha256=qSvNdQK40QM20-HDh3eIO6Rz8Lo3PEND_4kluugVx4w,6154
40
+ semantic_release/hvcs/token_auth.py,sha256=ZjT56-NIPB4OKIt1qwHCu1TavXnrWFIBl9ARlg56hgU,663
41
+ semantic_release/hvcs/util.py,sha256=PNKXApgL2np9lpnKjAbo77toRgElLPXrbS1q7621waI,2886
42
+ semantic_release/version/__init__.py,sha256=CLhtGQry9dLIij5XyRa9ZevxU_1p8tjMTSQ-K_GMpWM,270
43
+ semantic_release/version/algorithm.py,sha256=K9WkPRur0x5baXsqEi8kvaDfxduG4WNUiALXZRXujJ4,16484
44
+ semantic_release/version/declaration.py,sha256=f6Ld7hIhrqvDrRBapJHr-KDimuyo-4IG8009Zu9BIgU,7357
45
+ semantic_release/version/translator.py,sha256=P1noIsVBn8u6zNOFjG0xKYOWapxqf_PHSMvMeLJ9kXg,3050
46
+ semantic_release/version/version.py,sha256=6PCtSbLP88U1daoxnCwHc--YguZo4waGNLqJ5JfeczE,14175
47
+ python_semantic_release-9.2.1.dist-info/AUTHORS.rst,sha256=XOReVvpymEFUPsS2QPH97jlfJBVrxwS2eu8-jVAe4gk,230
48
+ python_semantic_release-9.2.1.dist-info/LICENSE,sha256=NE85nszX252sdQdu0xgS9qwfYES0k8qS6gW3uO4jRGE,1083
49
+ python_semantic_release-9.2.1.dist-info/METADATA,sha256=thUtW1xFlJYtbob07qyQU4AIoWpAyyrDdCMYTHP80_k,5365
50
+ python_semantic_release-9.2.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
51
+ python_semantic_release-9.2.1.dist-info/entry_points.txt,sha256=qojUBx_Ywf4u7KgP6NWlDaBDymZVUGQ7m5wF2duC2F0,95
52
+ python_semantic_release-9.2.1.dist-info/top_level.txt,sha256=qYA24nyg3eP-ti5UW7Vuj2aXVmM0wqVHx4mREdRZNAA,17
53
+ python_semantic_release-9.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,4 +1,5 @@
1
1
  """Python Semantic Release"""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  from semantic_release.commit_parser import (
@@ -23,7 +24,7 @@ from semantic_release.version import (
23
24
  tags_and_versions,
24
25
  )
25
26
 
26
- __version__ = "9.1.1"
27
+ __version__ = "9.2.1"
27
28
 
28
29
 
29
30
  def setup_hook(argv: list[str]) -> None:
@@ -3,20 +3,16 @@ from __future__ import annotations
3
3
  import logging
4
4
  from collections import defaultdict
5
5
  from datetime import datetime, timedelta, timezone
6
- from typing import TYPE_CHECKING, Iterable, Iterator
6
+ from typing import TYPE_CHECKING, TypedDict
7
7
 
8
8
  from git.objects.tag import TagObject
9
9
 
10
- # For Python3.7 compatibility
11
- from typing_extensions import TypedDict
12
-
13
- from semantic_release.commit_parser import (
14
- ParseError,
15
- )
10
+ from semantic_release.commit_parser import ParseError
16
11
  from semantic_release.version.algorithm import tags_and_versions
17
12
 
18
13
  if TYPE_CHECKING:
19
- import re
14
+ from re import Pattern
15
+ from typing import Iterable, Iterator
20
16
 
21
17
  from git.repo.base import Repo
22
18
  from git.util import Actor
@@ -39,7 +35,7 @@ class ReleaseHistory:
39
35
  repo: Repo,
40
36
  translator: VersionTranslator,
41
37
  commit_parser: CommitParser[ParseResult, ParserOptions],
42
- exclude_commit_patterns: Iterable[re.Pattern[str]] = (),
38
+ exclude_commit_patterns: Iterable[Pattern[str]] = (),
43
39
  ) -> ReleaseHistory:
44
40
  all_git_tags_and_versions = tags_and_versions(repo.tags, translator)
45
41
  unreleased: dict[str, list[ParseResult]] = defaultdict(list)
@@ -81,7 +77,9 @@ class ReleaseHistory:
81
77
  if isinstance(tag.object, TagObject):
82
78
  tagger = tag.object.tagger
83
79
  committer = tag.object.tagger.committer()
84
- _tz = timezone(timedelta(seconds=tag.object.tagger_tz_offset))
80
+ _tz = timezone(
81
+ timedelta(seconds=-1 * tag.object.tagger_tz_offset)
82
+ )
85
83
  tagged_date = datetime.fromtimestamp(
86
84
  tag.object.tagged_date, tz=_tz
87
85
  )
@@ -89,7 +87,9 @@ class ReleaseHistory:
89
87
  # For some reason, sometimes tag.object is a Commit
90
88
  tagger = tag.object.author
91
89
  committer = tag.object.author
92
- _tz = timezone(timedelta(seconds=tag.object.author_tz_offset))
90
+ _tz = timezone(
91
+ timedelta(seconds=-1 * tag.object.author_tz_offset)
92
+ )
93
93
  tagged_date = datetime.fromtimestamp(
94
94
  tag.object.committed_date, tz=_tz
95
95
  )
@@ -12,8 +12,10 @@ from jinja2.sandbox import SandboxedEnvironment
12
12
  from semantic_release.helpers import dynamic_import
13
13
 
14
14
  if TYPE_CHECKING:
15
+ from typing import Literal
16
+
15
17
  from jinja2 import Environment
16
- from typing_extensions import Literal
18
+
17
19
 
18
20
  log = logging.getLogger(__name__)
19
21
 
@@ -67,7 +67,7 @@ def changelog(ctx: click.Context, release_tag: str | None = None) -> None:
67
67
  )
68
68
  else:
69
69
  changelog_text = render_default_changelog_file(env)
70
- changelog_file.write_text(changelog_text, encoding="utf-8")
70
+ changelog_file.write_text(f"{changelog_text}\n", encoding="utf-8")
71
71
 
72
72
  else:
73
73
  if runtime.global_cli_options.noop:
@@ -112,7 +112,7 @@ def changelog(ctx: click.Context, release_tag: str | None = None) -> None:
112
112
  else:
113
113
  try:
114
114
  hvcs_client.create_or_update_release(
115
- release_tag, release_notes, prerelease=version.is_prerelease
115
+ release_tag, f"{release_notes}\n", prerelease=version.is_prerelease
116
116
  )
117
117
  except Exception as e:
118
118
  log.exception(e)
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, ContextManager, Iterable
9
9
 
10
10
  import click
11
11
  import shellingham # type: ignore[import]
12
+ from click_option_group import MutuallyExclusiveOptionGroup, optgroup
12
13
  from git.exc import GitCommandError
13
14
 
14
15
  from semantic_release.changelog import ReleaseHistory, environment, recursive_render
@@ -26,8 +27,9 @@ from semantic_release.version import Version, next_version, tags_and_versions
26
27
 
27
28
  log = logging.getLogger(__name__)
28
29
 
29
- if TYPE_CHECKING:
30
+ if TYPE_CHECKING: # pragma: no cover
30
31
  from git import Repo
32
+ from git.refs.tag import Tag
31
33
 
32
34
  from semantic_release.cli.config import RuntimeContext
33
35
  from semantic_release.version import VersionTranslator
@@ -48,6 +50,13 @@ def is_forced_prerelease(
48
50
  return force_prerelease or ((force_level is None) and prerelease)
49
51
 
50
52
 
53
+ def last_released(
54
+ repo: Repo, translator: VersionTranslator
55
+ ) -> tuple[Tag, Version] | None:
56
+ ts_and_vs = tags_and_versions(repo.tags, translator)
57
+ return ts_and_vs[0] if ts_and_vs else None
58
+
59
+
51
60
  def version_from_forced_level(
52
61
  repo: Repo, level_bump: LevelBump, translator: VersionTranslator
53
62
  ) -> Version:
@@ -111,9 +120,26 @@ def shell(cmd: str, *, check: bool = True) -> subprocess.CompletedProcess:
111
120
  "help_option_names": ["-h", "--help"],
112
121
  },
113
122
  )
114
- @click.option(
123
+ @optgroup.group("Print flags", cls=MutuallyExclusiveOptionGroup)
124
+ @optgroup.option(
115
125
  "--print", "print_only", is_flag=True, help="Print the next version and exit"
116
126
  )
127
+ @optgroup.option(
128
+ "--print-tag",
129
+ "print_only_tag",
130
+ is_flag=True,
131
+ help="Print the next version tag and exit",
132
+ )
133
+ @optgroup.option(
134
+ "--print-last-released",
135
+ is_flag=True,
136
+ help="Print the last released version and exit",
137
+ )
138
+ @optgroup.option(
139
+ "--print-last-released-tag",
140
+ is_flag=True,
141
+ help="Print the last released version tag and exit",
142
+ )
117
143
  @click.option(
118
144
  "--prerelease",
119
145
  "force_prerelease",
@@ -191,6 +217,9 @@ def shell(cmd: str, *, check: bool = True) -> subprocess.CompletedProcess:
191
217
  def version( # noqa: C901
192
218
  ctx: click.Context,
193
219
  print_only: bool = False,
220
+ print_only_tag: bool = False,
221
+ print_last_released: bool = False,
222
+ print_last_released_tag: bool = False,
194
223
  force_prerelease: bool = False,
195
224
  prerelease_token: str | None = None,
196
225
  force_level: str | None = None,
@@ -219,8 +248,20 @@ def version( # noqa: C901
219
248
  """
220
249
  runtime: RuntimeContext = ctx.obj
221
250
  repo = runtime.repo
222
- parser = runtime.commit_parser
223
251
  translator = runtime.version_translator
252
+
253
+ # We can short circuit updating the release if we are only printing the last released version
254
+ if print_last_released or print_last_released_tag:
255
+ if last_release := last_released(repo, translator):
256
+ if print_last_released:
257
+ click.echo(last_release[1])
258
+ if print_last_released_tag:
259
+ click.echo(last_release[0])
260
+ else:
261
+ log.warning("No release tags found.")
262
+ ctx.exit(0)
263
+
264
+ parser = runtime.commit_parser
224
265
  prerelease = is_forced_prerelease(
225
266
  force_prerelease=force_prerelease,
226
267
  force_level=force_level,
@@ -291,6 +332,7 @@ def version( # noqa: C901
291
332
  commit_parser=parser,
292
333
  prerelease=prerelease,
293
334
  major_on_zero=major_on_zero,
335
+ allow_zero_version=runtime.allow_zero_version,
294
336
  )
295
337
 
296
338
  if build_metadata:
@@ -301,7 +343,10 @@ def version( # noqa: C901
301
343
  ctx.call_on_close(gha_output.write_if_possible)
302
344
 
303
345
  # Print the new version so that command-line output capture will work
304
- click.echo(str(new_version))
346
+ if print_only_tag:
347
+ click.echo(translator.str_to_tag(str(new_version)))
348
+ else:
349
+ click.echo(str(new_version))
305
350
 
306
351
  # If the new version has already been released, we fail and abort if strict;
307
352
  # otherwise we exit with 0.
@@ -318,7 +363,7 @@ def version( # noqa: C901
318
363
  )
319
364
  ctx.exit(0)
320
365
 
321
- if print_only:
366
+ if print_only or print_only_tag:
322
367
  ctx.exit(0)
323
368
 
324
369
  rprint(f"[bold green]The next version is: [white]{new_version!s}[/white]! :rocket:")
@@ -429,7 +474,7 @@ def version( # noqa: C901
429
474
  )
430
475
  else:
431
476
  changelog_text = render_default_changelog_file(env)
432
- changelog_file.write_text(changelog_text, encoding="utf-8")
477
+ changelog_file.write_text(f"{changelog_text}\n", encoding="utf-8")
433
478
 
434
479
  updated_paths = [str(changelog_file.relative_to(repo.working_dir))]
435
480
 
@@ -34,7 +34,7 @@ def render_default_changelog_file(template_environment: Environment) -> str:
34
34
  .read_text(encoding="utf-8")
35
35
  )
36
36
  tmpl = template_environment.from_string(changelog_text)
37
- return tmpl.render()
37
+ return tmpl.render().rstrip()
38
38
 
39
39
 
40
40
  def render_release_notes(
@@ -43,6 +43,8 @@ def render_release_notes(
43
43
  version: Version,
44
44
  release: Release,
45
45
  ) -> str:
46
- return template_environment.from_string(release_notes_template).render(
47
- version=version, release=release
46
+ return (
47
+ template_environment.from_string(release_notes_template)
48
+ .render(version=version, release=release)
49
+ .rstrip()
48
50
  )
@@ -7,13 +7,15 @@ from collections.abc import Mapping
7
7
  from dataclasses import dataclass, is_dataclass
8
8
  from enum import Enum
9
9
  from pathlib import Path
10
- from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type, Union
10
+ from typing import Any, ClassVar, Dict, List, Literal, Optional, Tuple, Type, Union
11
11
 
12
12
  from git import Actor
13
13
  from git.repo.base import Repo
14
14
  from jinja2 import Environment
15
15
  from pydantic import BaseModel, Field, RootModel, ValidationError, model_validator
16
- from typing_extensions import Annotated, Literal
16
+
17
+ # For Python 3.8 compatibility
18
+ from typing_extensions import Annotated
17
19
 
18
20
  from semantic_release import hvcs
19
21
  from semantic_release.changelog import environment
@@ -145,6 +147,7 @@ class RawConfig(BaseModel):
145
147
  commit_parser_options: Dict[str, Any] = {}
146
148
  logging_use_named_masks: bool = False
147
149
  major_on_zero: bool = True
150
+ allow_zero_version: bool = True
148
151
  remote: RemoteConfig = RemoteConfig()
149
152
  tag_format: str = "v{version}"
150
153
  publish: PublishConfig = PublishConfig()
@@ -229,6 +232,7 @@ class RuntimeContext:
229
232
  commit_parser: CommitParser[ParseResult, ParserOptions]
230
233
  version_translator: VersionTranslator
231
234
  major_on_zero: bool
235
+ allow_zero_version: bool
232
236
  prerelease: bool
233
237
  assets: List[str]
234
238
  commit_author: Actor
@@ -414,6 +418,7 @@ class RuntimeContext:
414
418
  commit_parser=commit_parser,
415
419
  version_translator=version_translator,
416
420
  major_on_zero=raw.major_on_zero,
421
+ allow_zero_version=raw.allow_zero_version,
417
422
  build_command=raw.build_command,
418
423
  version_declarations=tuple(version_declarations),
419
424
  hvcs_client=hvcs_client,
@@ -1,4 +1,5 @@
1
1
  """Utilities for command-line functionality"""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  import json
@@ -71,5 +71,4 @@ class CommitParser(ABC, Generic[_TT, _OPTS]):
71
71
  self.options = options
72
72
 
73
73
  @abstractmethod
74
- def parse(self, commit: Commit) -> _TT:
75
- ...
74
+ def parse(self, commit: Commit) -> _TT: ...
@@ -2,6 +2,7 @@
2
2
  Angular commit style parser
3
3
  https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines
4
4
  """
5
+
5
6
  from __future__ import annotations
6
7
 
7
8
  import logging
@@ -1,4 +1,5 @@
1
1
  """Commit parser which looks for emojis to determine the type of commit"""
2
+
2
3
  import logging
3
4
  from typing import Tuple
4
5
 
@@ -34,6 +34,7 @@ Supported Changelog Sections::
34
34
 
35
35
  .. _`scipy-style`: https://docs.scipy.org/doc/scipy/reference/dev/contributor/development_workflow.html#writing-the-commit-message
36
36
  """
37
+
37
38
  from __future__ import annotations
38
39
 
39
40
  import logging
@@ -1,4 +1,5 @@
1
1
  """Legacy commit parser from Python Semantic Release 1.0"""
2
+
2
3
  import logging
3
4
  import re
4
5
 
@@ -6,7 +6,7 @@ breaking_re = re.compile(r"BREAKING[ -]CHANGE:\s?(.*)")
6
6
 
7
7
 
8
8
  def parse_paragraphs(text: str) -> list[str]:
9
- """
9
+ r"""
10
10
  This will take a text block and return a list containing each
11
11
  paragraph with single line breaks collapsed into spaces.
12
12
 
@@ -114,12 +114,12 @@ def parse_git_url(url: str) -> ParsedGitUrl:
114
114
  # Normalizers are a list of tuples of (pattern, replacement)
115
115
  normalizers = [
116
116
  # normalize implicit ssh urls to explicit ssh://
117
- (r"^(\w+@)", r"ssh://\1"),
117
+ (r"^([\w._-]+@)", r"ssh://\1"),
118
118
  # normalize git+ssh:// urls to ssh://
119
119
  (r"^git\+ssh://", "ssh://"),
120
120
  # normalize an scp like syntax to URL compatible syntax
121
121
  # excluding port definitions (:#####) & including numeric usernames
122
- (r"(ssh://(?:\w+@)?[\w.-]+):(?!\d{1,5}/\w+/)(.*)$", r"\1/\2"),
122
+ (r"(ssh://(?:[\w._-]+@)?[\w.-]+):(?!\d{1,5}/\w+/)(.*)$", r"\1/\2"),
123
123
  # normalize implicit file (windows || posix) urls to explicit file:// urls
124
124
  (r"^([C-Z]:/)|^/(\w)", r"file:///\1\2"),
125
125
  ]
@@ -1,4 +1,5 @@
1
1
  """Common functionality and interface for interacting with Git remote VCS"""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  import logging
@@ -37,7 +37,7 @@ class Bitbucket(HvcsBase):
37
37
  API_VERSION = "2.0"
38
38
  DEFAULT_DOMAIN = "bitbucket.org"
39
39
  DEFAULT_API_DOMAIN = "api.bitbucket.org"
40
- DEFAULT_ENV_TOKEN_NAME = "BITBUCKET_TOKEN"
40
+ DEFAULT_ENV_TOKEN_NAME = "BITBUCKET_TOKEN" # noqa: S105
41
41
 
42
42
  def __init__(
43
43
  self,
@@ -93,14 +93,13 @@ class Bitbucket(HvcsBase):
93
93
  f"https://{user}:{self.token}@"
94
94
  f"{self.hvcs_domain}/{self.owner}/{self.repo_name}.git"
95
95
  )
96
- else:
97
- # Note: Assume the token is a repository token which will only work on the
98
- # repository it was created for.
99
- # https://support.atlassian.com/bitbucket-cloud/docs/using-access-tokens
100
- return (
101
- f"https://x-token-auth:{self.token}@"
102
- f"{self.hvcs_domain}/{self.owner}/{self.repo_name}.git"
103
- )
96
+ # Note: Assume the token is a repository token which will only work on the
97
+ # repository it was created for.
98
+ # https://support.atlassian.com/bitbucket-cloud/docs/using-access-tokens
99
+ return (
100
+ f"https://x-token-auth:{self.token}@"
101
+ f"{self.hvcs_domain}/{self.owner}/{self.repo_name}.git"
102
+ )
104
103
 
105
104
  def commit_hash_url(self, commit_hash: str) -> str:
106
105
  return (
@@ -1,4 +1,5 @@
1
1
  """Helper code for interacting with a Gitea remote VCS"""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  import glob
@@ -1,4 +1,5 @@
1
1
  """Helper code for interacting with a GitHub remote VCS"""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  import glob
@@ -1,4 +1,5 @@
1
1
  """Helper code for interacting with a Gitlab remote VCS"""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  import logging
@@ -143,6 +143,7 @@ def _increment_version(
143
143
  prerelease: bool,
144
144
  prerelease_token: str,
145
145
  major_on_zero: bool,
146
+ allow_zero_version: bool,
146
147
  ) -> Version:
147
148
  """
148
149
  Using the given versions, along with a given `level_bump`, increment to
@@ -158,19 +159,27 @@ def _increment_version(
158
159
  `latest_full_version_in_history`, correspondingly, is the latest full release which
159
160
  is in this branch's history.
160
161
  """
161
- log.debug(
162
- "_increment_version: %s", ", ".join(f"{k} = {v}" for k, v in locals().items())
163
- )
164
- if not major_on_zero and latest_version.major == 0:
165
- # if we are a 0.x.y release and have set `major_on_zero`,
166
- # breaking changes should increment the minor digit
167
- # Correspondingly, we reduce the level that we increment the
168
- # version by.
169
- log.debug(
170
- "reducing version increment due to 0. version and major_on_zero=False"
171
- )
162
+ local_vars = list(locals().items())
163
+ log.debug("_increment_version: %s", ", ".join(f"{k} = {v}" for k, v in local_vars))
164
+ if latest_version.major == 0:
165
+ if not allow_zero_version:
166
+ # Set up default version to be 1.0.0 if currently 0.x.x which means a commented
167
+ # breaking change is not required to bump to 1.0.0
168
+ log.debug(
169
+ "Bumping major version as 0.x.x versions are disabled because of allow_zero_version=False"
170
+ )
171
+ level_bump = LevelBump.MAJOR
172
+
173
+ elif not major_on_zero:
174
+ # if we are a 0.x.y release and have set `major_on_zero`,
175
+ # breaking changes should increment the minor digit
176
+ # Correspondingly, we reduce the level that we increment the
177
+ # version by.
178
+ log.debug(
179
+ "reducing version increment due to 0. version and major_on_zero=False"
180
+ )
172
181
 
173
- level_bump = min(level_bump, LevelBump.MINOR)
182
+ level_bump = min(level_bump, LevelBump.MINOR)
174
183
 
175
184
  if prerelease:
176
185
  log.debug("prerelease=true")
@@ -261,6 +270,7 @@ def next_version(
261
270
  commit_parser: CommitParser[ParseResult, ParserOptions],
262
271
  prerelease: bool = False,
263
272
  major_on_zero: bool = True,
273
+ allow_zero_version: bool = True,
264
274
  ) -> Version:
265
275
  """
266
276
  Evaluate the history within `repo`, and based on the tags and commits in the repo
@@ -398,8 +408,9 @@ def next_version(
398
408
  level_bump = max(parsed_levels, default=LevelBump.NO_RELEASE)
399
409
  log.info("The type of the next release release is: %s", level_bump)
400
410
  if level_bump is LevelBump.NO_RELEASE:
401
- log.info("No release will be made")
402
- return latest_version
411
+ if latest_version.major != 0 or allow_zero_version:
412
+ log.info("No release will be made")
413
+ return latest_version
403
414
 
404
415
  return _increment_version(
405
416
  latest_version=latest_version,
@@ -418,4 +429,5 @@ def next_version(
418
429
  prerelease=prerelease,
419
430
  prerelease_token=translator.prerelease_token,
420
431
  major_on_zero=major_on_zero,
432
+ allow_zero_version=allow_zero_version,
421
433
  )
@@ -25,15 +25,13 @@ VersionComparator = Callable[["Version", "Version"], bool]
25
25
  def _comparator(
26
26
  *,
27
27
  type_guard: bool,
28
- ) -> Callable[[VersionComparator], VersionComparator]:
29
- ...
28
+ ) -> Callable[[VersionComparator], VersionComparator]: ...
30
29
 
31
30
 
32
31
  @overload
33
32
  def _comparator(
34
33
  method: VersionComparator, *, type_guard: bool = True
35
- ) -> VersionComparator:
36
- ...
34
+ ) -> VersionComparator: ...
37
35
 
38
36
 
39
37
  def _comparator(
@@ -1,53 +0,0 @@
1
- semantic_release/__init__.py,sha256=juZt1ZsMQ2L58yaXrSXD9QG-hYFVjolKI0vfDYJfm34,869
2
- semantic_release/__main__.py,sha256=vXOARLV7KHeVXgpOMU0Q-8wovpdsOrtTsycxulI5xIE,106
3
- semantic_release/const.py,sha256=Z1o2QNh60wSLeF-_1TemMBjU3ZXbV0XghnUFsbTVfOs,831
4
- semantic_release/enums.py,sha256=D5B_reQGGKQQT22HO5PUtvn2Bok3fkht6TfJtXkmAUg,1020
5
- semantic_release/errors.py,sha256=KKKCV45vvE9tla0sxYDGHkHWvqDn1gEfGIpzujcDbeI,809
6
- semantic_release/helpers.py,sha256=JYsAVmqF46VLONkT5t_0M5cq4zs6gNC3vzQhW3WlbN8,5571
7
- semantic_release/changelog/__init__.py,sha256=Bg6Xe5Vt32rWoMscW-hd4sUwiZqzWmsg4CD1EhMesMY,262
8
- semantic_release/changelog/context.py,sha256=ItSz5Bon2mcJkLxyQZzBTukN0zEdcaVQ4iXvz3jGCLc,986
9
- semantic_release/changelog/release_history.py,sha256=lphD64zgbE7IBhWoNsXP4uHOXBTuANvo27MLIMdIJOY,6594
10
- semantic_release/changelog/template.py,sha256=Vzsc2dN4_6RuykELN8lqEc4L9Gw6ibpiq4oB36kUoOU,4649
11
- semantic_release/cli/__init__.py,sha256=gwAYhZO-4TR0tKCkQ4GqutWsL--0CII2_dcbrElI4M4,419
12
- semantic_release/cli/common.py,sha256=gmMdTjTyFa6b1ISlIeljgX1UheRwmwwaoIZcXrlAOPU,1401
13
- semantic_release/cli/config.py,sha256=uL-VHyZ-rRbjePMECuw0-Dg5fiom5lUC3RRZUBHJkOQ,15702
14
- semantic_release/cli/const.py,sha256=S8oNNpSaKdZxcAs7PAKEjQHic0czoJBGd7XHo57FOzw,39
15
- semantic_release/cli/github_actions_output.py,sha256=stGWcuMtelY0qM2E_-IfofP6UvsQ6czsO7qpMfnRJI4,2102
16
- semantic_release/cli/masking_filter.py,sha256=DxqjiJyABlzwwwZ1r8JGQpb6QrF00StJFm0-2-s5Fv0,3071
17
- semantic_release/cli/util.py,sha256=toWIrjKhnuU66giiLD5anpHGg1OuVbhnPigIDt4byxA,3754
18
- semantic_release/cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- semantic_release/cli/commands/changelog.py,sha256=sc-unuM2-qtLspJIu2lv-Xh-wm42iokKMnIzmbKfPTI,4026
20
- semantic_release/cli/commands/generate_config.py,sha256=BwtwFhh80bkOUUNnR2ArC51YfPKI_y4HMD7C1oAFREA,1695
21
- semantic_release/cli/commands/main.py,sha256=LBbHbDNIctb35bUQsklefXVPN9bhY-LlrQFF1nNTMLg,5049
22
- semantic_release/cli/commands/publish.py,sha256=CvhZ4Z8CTPS-4f7kWH-xJ5JTk3jlJ-p8Mg7y2KC4SnY,1492
23
- semantic_release/cli/commands/version.py,sha256=7vsfxvqX7DX0fNl_qgazUkpc_3s3aK1lO6gzXpWlzPk,20886
24
- semantic_release/commit_parser/__init__.py,sha256=cv5HFBdw7OJd4Laj4Ex8ZZ5Tml8GwXgQcXW6Pasr2Ao,615
25
- semantic_release/commit_parser/_base.py,sha256=d7-sOgKn44-IG_fpJhSPZuOvkrVrMVTihfH395i3qtE,2617
26
- semantic_release/commit_parser/angular.py,sha256=7kp-vo3hpShHC3X3TZKHiOyXI_grLHn1hZ8L8bI3gC8,4392
27
- semantic_release/commit_parser/emoji.py,sha256=alZL8BgMfdOQYTFwWPn9JtWD2HAoYNeHigFYjxxLqy8,3288
28
- semantic_release/commit_parser/scipy.py,sha256=YOO5SaE0d3R6nCg5WBCBe6Zd0hoPjBZrdRr7IHVsdSw,5776
29
- semantic_release/commit_parser/tag.py,sha256=Ue_XYc-Y_BWda4uMcYcOY9wU_12aw_brySMHekX4EX4,3193
30
- semantic_release/commit_parser/token.py,sha256=UxYAwEylPvp4x39RqNA9ITcgkaSRDEH7A5XDDJ3tdiM,1505
31
- semantic_release/commit_parser/util.py,sha256=2IzDkCt4FslRiUHv0iPnsgYoxBk8ZewrnPYG1DsLtQc,729
32
- semantic_release/data/templates/CHANGELOG.md.j2,sha256=GB3YJwgVrhlcb-g5ESdEh_Gsysb_Texxv-Ip2LjulC0,1066
33
- semantic_release/data/templates/release_notes.md.j2,sha256=27uIHgG6iYmqdMaoWFP5LJRZcrO-3paqFzHHHsGpXXE,465
34
- semantic_release/hvcs/__init__.py,sha256=ulesZslSG4Lu8Iz3YzOrPXpdgvgbADq_MV17B-bSYQA,379
35
- semantic_release/hvcs/_base.py,sha256=CXE-yI1zDgOybSnd7oMQJ_GVyiIA7HrltqoO8I1N1hc,5634
36
- semantic_release/hvcs/bitbucket.py,sha256=jqWWxVOrtrK-Yk9yLzQySb4G41G7yGDkGDUhHW4KuMQ,4654
37
- semantic_release/hvcs/gitea.py,sha256=xQ6sm04YNk30t8ieCNY61DtcDPygppvcvF_meI17Des,8458
38
- semantic_release/hvcs/github.py,sha256=IfBtKSXXoT-H-cKdwmiB-xRGYrvzC5hJN6cf1Ekylgk,10709
39
- semantic_release/hvcs/gitlab.py,sha256=hJCTv4QC9y1iABiqJeSc0V5H8R1HZ8TRTd6ZFIKj4Es,6153
40
- semantic_release/hvcs/token_auth.py,sha256=ZjT56-NIPB4OKIt1qwHCu1TavXnrWFIBl9ARlg56hgU,663
41
- semantic_release/hvcs/util.py,sha256=PNKXApgL2np9lpnKjAbo77toRgElLPXrbS1q7621waI,2886
42
- semantic_release/version/__init__.py,sha256=CLhtGQry9dLIij5XyRa9ZevxU_1p8tjMTSQ-K_GMpWM,270
43
- semantic_release/version/algorithm.py,sha256=DetgOHAnLgOGrmIJRm_nqRl95YVcpta_Vr2UAYX9Oc8,15864
44
- semantic_release/version/declaration.py,sha256=f6Ld7hIhrqvDrRBapJHr-KDimuyo-4IG8009Zu9BIgU,7357
45
- semantic_release/version/translator.py,sha256=P1noIsVBn8u6zNOFjG0xKYOWapxqf_PHSMvMeLJ9kXg,3050
46
- semantic_release/version/version.py,sha256=siyX3Cl_qhw9dTIUpafFX8-wHKW2RILVm8u6i519Pck,14183
47
- python_semantic_release-9.1.1.dist-info/AUTHORS.rst,sha256=XOReVvpymEFUPsS2QPH97jlfJBVrxwS2eu8-jVAe4gk,230
48
- python_semantic_release-9.1.1.dist-info/LICENSE,sha256=NE85nszX252sdQdu0xgS9qwfYES0k8qS6gW3uO4jRGE,1083
49
- python_semantic_release-9.1.1.dist-info/METADATA,sha256=bftBRdumh_mP2QpsXV8rUFqdW4mc608l4_ZszTXbpXA,5326
50
- python_semantic_release-9.1.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
51
- python_semantic_release-9.1.1.dist-info/entry_points.txt,sha256=qojUBx_Ywf4u7KgP6NWlDaBDymZVUGQ7m5wF2duC2F0,95
52
- python_semantic_release-9.1.1.dist-info/top_level.txt,sha256=qYA24nyg3eP-ti5UW7Vuj2aXVmM0wqVHx4mREdRZNAA,17
53
- python_semantic_release-9.1.1.dist-info/RECORD,,