Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: draft of the --empty parameter #696

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6857fd7
build(poetry): commit the lock file
noirbizarre Dec 6, 2022
3e350d1
build(dependabot): add dependabot configuration
noirbizarre Dec 6, 2022
ee12db3
build(python): Sunset Python 3.6 and support Python 3.11
noirbizarre Dec 5, 2022
c48af3a
fix(excepthook): ensure traceback can only be a `TracebackType` or `N…
noirbizarre Dec 7, 2022
802a58d
build(dev): update and fixes some dependencies
noirbizarre Dec 7, 2022
533f9fa
build(poetry): relock poetry.lock
Lee-W Dec 21, 2022
62bfbfe
style: format code through black
Lee-W Dec 21, 2022
b6da548
test(git): ensures that global git user settings are not interfering …
noirbizarre Dec 7, 2022
9f4b9ee
test(warnings): switch from the unmaintained `pytest-freezegun` to `p…
noirbizarre Dec 14, 2022
7860419
style: fix formatting changes with black update
noirbizarre Dec 21, 2022
dcbe385
feat(plugins): Switch to an importlib.metadata.EntryPoint-based plugi…
noirbizarre Dec 5, 2022
37875a6
test: improve git isolation and fixes test missing a repository
noirbizarre Dec 28, 2022
438ca3f
test(tests): format code
Lee-W Feb 11, 2023
2e56cba
feat(providers): add a `commitizen.provider` endpoint for alternative…
noirbizarre Dec 11, 2022
fe1e72d
feat(providers): add support for some TOML-based versions (PEP621, Po…
noirbizarre Dec 27, 2022
6e6ad57
feat(providers): add support for some JSON-based version providers (N…
noirbizarre Dec 27, 2022
01e4788
docs(deps): upgrade mkdocs-material and tidy some snippets
noirbizarre Dec 27, 2022
b0d0a8e
feat(providers): add a `scm` version provider
noirbizarre Jan 1, 2023
9b5f311
test(providers): factorize some version providers tests
noirbizarre Jan 27, 2023
b5125cb
fix(commands/changelog): use topological order for commit ordering
sacha-c Mar 1, 2023
642f2c8
Merge pull request #677 from sacha-c/fix/changelog-commit-order
woile Mar 11, 2023
44c6518
feat: draft of the --empty parameter
12rambau Apr 5, 2023
59ad9c4
feat(changelog): add merge_prereleases flag
MoritzBoehme Apr 13, 2023
558af4b
ci: update codecov to newest version
MoritzBoehme Apr 13, 2023
e34de55
test(scripts): run same file tests individually
MoritzBoehme Apr 13, 2023
7a8c2d8
Merge pull request #703 from MoritzBoehme/merge-prerelease
woile Apr 17, 2023
c3d2c91
feat: add semver support through version provider new api (#686)
Apkawa Apr 19, 2023
acc3485
Merge branch 'v3' into devrelease
12rambau Apr 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 2
updates:
-
# Maintain dependencies for GitHub Actions
package-ecosystem: github-actions
directory: /
schedule:
interval: daily
labels:
- dependencies
commit-message:
prefix: "ci(actions)"
include: "scope"
-
# Maintain python dependencies
package-ecosystem: pip
directory: /
schedule:
interval: daily
labels:
- dependencies
commit-message:
prefix: "build(poetry)"
include: "scope"
4 changes: 2 additions & 2 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
python-check:
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
platform: [ubuntu-20.04, macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
Expand All @@ -30,7 +30,7 @@ jobs:
shell: bash
- name: Upload coverage to Codecov
if: runner.os == 'Linux'
uses: codecov/codecov-action@v1.0.3
uses: codecov/codecov-action@v3
with:
token: ${{secrets.CODECOV_TOKEN}}
file: ./coverage.xml
Expand Down
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,5 @@ venv.bak/
.vscode/
*.bak

# build
poetry.lock

# macOSX
.DS_Store
29 changes: 22 additions & 7 deletions commitizen/bump.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import os
import re
import sys
import typing
from collections import OrderedDict
from itertools import zip_longest
from string import Template
from typing import List, Optional, Tuple, Union
from typing import List, Optional, Tuple, Type, Union

from packaging.version import Version

from commitizen.defaults import MAJOR, MINOR, PATCH, bump_message
from commitizen.exceptions import CurrentVersionNotFoundError
from commitizen.git import GitCommit, smart_open

if sys.version_info >= (3, 8):
from commitizen.version_types import VersionProtocol
else:
# workaround mypy issue for 3.7 python
VersionProtocol = typing.Any


def find_increment(
commits: List[GitCommit], regex: str, increments_map: Union[dict, OrderedDict]
Expand Down Expand Up @@ -120,7 +128,8 @@ def generate_version(
prerelease_offset: int = 0,
devrelease: Optional[int] = None,
is_local_version: bool = False,
) -> Version:
version_type_cls: Optional[Type[VersionProtocol]] = None,
) -> VersionProtocol:
"""Based on the given increment a proper semver will be generated.

For now the rules and versioning scheme is based on
Expand All @@ -132,15 +141,17 @@ def generate_version(
MINOR 1.0.0 -> 1.1.0
MAJOR 1.0.0 -> 2.0.0
"""
if version_type_cls is None:
version_type_cls = Version
if is_local_version:
version = Version(current_version)
version = version_type_cls(current_version)
dev_version = devrelease_generator(devrelease=devrelease)
pre_version = prerelease_generator(
str(version.local), prerelease=prerelease, offset=prerelease_offset
)
semver = semver_generator(str(version.local), increment=increment)

return Version(f"{version.public}+{semver}{pre_version}{dev_version}")
return version_type_cls(f"{version.public}+{semver}{pre_version}{dev_version}")
else:
dev_version = devrelease_generator(devrelease=devrelease)
pre_version = prerelease_generator(
Expand All @@ -149,7 +160,7 @@ def generate_version(
semver = semver_generator(current_version, increment=increment)

# TODO: post version
return Version(f"{semver}{pre_version}{dev_version}")
return version_type_cls(f"{semver}{pre_version}{dev_version}")


def update_version_in_files(
Expand Down Expand Up @@ -208,7 +219,9 @@ def _version_to_regex(version: str) -> str:


def normalize_tag(
version: Union[Version, str], tag_format: Optional[str] = None
version: Union[VersionProtocol, str],
tag_format: Optional[str] = None,
version_type_cls: Optional[Type[VersionProtocol]] = None,
) -> str:
"""The tag and the software version might be different.

Expand All @@ -221,8 +234,10 @@ def normalize_tag(
| ver1.0.0 | 1.0.0 |
| ver1.0.0.a0 | 1.0.0a0 |
"""
if version_type_cls is None:
version_type_cls = Version
if isinstance(version, str):
version = Version(version)
version = version_type_cls(version)

if not tag_format:
return str(version)
Expand Down
56 changes: 49 additions & 7 deletions commitizen/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,56 @@

import os
import re
import sys
import typing
from collections import OrderedDict, defaultdict
from datetime import date
from typing import Callable, Dict, Iterable, List, Optional, Tuple
from typing import Callable, Dict, Iterable, List, Optional, Tuple, Type

from jinja2 import Environment, PackageLoader
from packaging.version import InvalidVersion, Version

from commitizen import defaults
from commitizen.bump import normalize_tag
from commitizen.exceptions import InvalidConfigurationError, NoCommitsFoundError
from commitizen.git import GitCommit, GitTag

if sys.version_info >= (3, 8):
from commitizen.version_types import VersionProtocol
else:
# workaround mypy issue for 3.7 python
VersionProtocol = typing.Any


def get_commit_tag(commit: GitCommit, tags: List[GitTag]) -> Optional[GitTag]:
return next((tag for tag in tags if tag.rev == commit.rev), None)


def get_version(tag: GitTag) -> Optional[Version]:
version = None
try:
version = Version(tag.name)
except InvalidVersion:
pass
return version


def tag_included_in_changelog(
tag: GitTag, used_tags: List, merge_prerelease: bool
) -> bool:
if tag in used_tags:
return False

version = get_version(tag)
if version is None:
return False

if merge_prerelease and version.is_prerelease:
return False

return True


def generate_tree_from_commits(
commits: List[GitCommit],
tags: List[GitTag],
Expand All @@ -51,6 +85,7 @@ def generate_tree_from_commits(
unreleased_version: Optional[str] = None,
change_type_map: Optional[Dict[str, str]] = None,
changelog_message_builder_hook: Optional[Callable] = None,
merge_prerelease: bool = False,
) -> Iterable[Dict]:
pat = re.compile(changelog_pattern)
map_pat = re.compile(commit_parser, re.MULTILINE)
Expand All @@ -73,15 +108,15 @@ def generate_tree_from_commits(
for commit in commits:
commit_tag = get_commit_tag(commit, tags)

if commit_tag is not None and commit_tag not in used_tags:
if commit_tag is not None and tag_included_in_changelog(
commit_tag, used_tags, merge_prerelease
):
used_tags.append(commit_tag)
yield {
"version": current_tag_name,
"date": current_tag_date,
"changes": changes,
}
# TODO: Check if tag matches the version pattern, otherwise skip it.
# This in order to prevent tags that are not versions.
current_tag_name = commit_tag.name
current_tag_date = commit_tag.date
changes = defaultdict(list)
Expand Down Expand Up @@ -286,7 +321,10 @@ def get_smart_tag_range(


def get_oldest_and_newest_rev(
tags: List[GitTag], version: str, tag_format: str
tags: List[GitTag],
version: str,
tag_format: str,
version_type_cls: Optional[Type[VersionProtocol]] = None,
) -> Tuple[Optional[str], Optional[str]]:
"""Find the tags for the given version.

Expand All @@ -301,11 +339,15 @@ def get_oldest_and_newest_rev(
except ValueError:
newest = version

newest_tag = normalize_tag(newest, tag_format=tag_format)
newest_tag = normalize_tag(
newest, tag_format=tag_format, version_type_cls=version_type_cls
)

oldest_tag = None
if oldest:
oldest_tag = normalize_tag(oldest, tag_format=tag_format)
oldest_tag = normalize_tag(
oldest, tag_format=tag_format, version_type_cls=version_type_cls
)

tags_range = get_smart_tag_range(tags, newest=newest_tag, oldest=oldest_tag)
if not tags_range:
Expand Down
33 changes: 28 additions & 5 deletions commitizen/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
import logging
import sys
from functools import partial
from types import TracebackType
from typing import List

import argcomplete
from decli import cli

from commitizen import commands, config, out
from commitizen import commands, config, out, version_types
from commitizen.exceptions import (
CommitizenException,
ExitCode,
Expand Down Expand Up @@ -202,6 +203,18 @@
"help": "bump to the given version (e.g: 1.5.3)",
"metavar": "MANUAL_VERSION",
},
{
"name": ["--empty"],
"default": False,
"help": "bump tags without new commits",
"action": "store_true",
},
{
"name": ["--version-type"],
"help": "choose version type",
"default": None,
"choices": version_types.VERSION_TYPES,
},
],
},
{
Expand Down Expand Up @@ -247,10 +260,19 @@
"name": "--start-rev",
"default": None,
"help": (
"start rev of the changelog."
"start rev of the changelog. "
"If not set, it will generate changelog from the start"
),
},
{
"name": "--merge-prerelease",
"action": "store_true",
"default": False,
"help": (
"collect all changes from prereleases into next non-prerelease. "
"If not set, it will include prereleases in the changelog"
),
},
],
},
{
Expand Down Expand Up @@ -330,21 +352,22 @@


def commitizen_excepthook(
type, value, tracekback, debug=False, no_raise: List[int] = None
type, value, traceback, debug=False, no_raise: List[int] = None
):
traceback = traceback if isinstance(traceback, TracebackType) else None
if not no_raise:
no_raise = []
if isinstance(value, CommitizenException):
if value.message:
value.output_method(value.message)
if debug:
original_excepthook(type, value, tracekback)
original_excepthook(type, value, traceback)
exit_code = value.exit_code
if exit_code in no_raise:
exit_code = 0
sys.exit(exit_code)
else:
original_excepthook(type, value, tracekback)
original_excepthook(type, value, traceback)


commitizen_debug_excepthook = partial(commitizen_excepthook, debug=True)
Expand Down
Loading