From e70d15d662f868d88114f6567fb27f8bfa18b2c4 Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Fri, 2 Dec 2022 20:57:46 -0800 Subject: [PATCH 01/10] feat(unicode): add unicode support This will allow commiting, e.g., emoji's and parsing commit messages for unicode characters when creating change logs. --- commitizen/bump.py | 27 ++++++-- commitizen/changelog.py | 2 +- commitizen/changelog_parser.py | 4 +- commitizen/commands/bump.py | 2 + commitizen/commands/changelog.py | 13 ++-- commitizen/commands/check.py | 3 +- commitizen/commands/commit.py | 5 +- commitizen/commands/init.py | 9 ++- commitizen/config/json_config.py | 5 +- commitizen/config/toml_config.py | 5 +- commitizen/config/yaml_config.py | 5 +- .../conventional_commits.py | 2 +- commitizen/cz/customize/customize.py | 2 +- commitizen/cz/jira/jira.py | 2 +- commitizen/defaults.py | 3 + tests/commands/test_bump_command.py | 27 ++++---- tests/commands/test_changelog_command.py | 66 ++++++++++--------- tests/commands/test_init_command.py | 2 +- tests/test_bump_update_version_in_files.py | 36 +++++----- ...t_multiple_versions_to_bump_with_eol_.toml | 27 ++++++++ ...ultiple_versions_to_bump_without_eol_.toml | 27 ++++++++ tests/test_changelog.py | 2 +- tests/test_changelog_meta.py | 16 ++--- tests/test_changelog_parser.py | 10 +-- tests/test_conf.py | 10 +-- 25 files changed, 205 insertions(+), 107 deletions(-) create mode 100644 tests/test_bump_update_version_in_files/test_multiple_versions_to_bump_with_eol_.toml create mode 100644 tests/test_bump_update_version_in_files/test_multiple_versions_to_bump_without_eol_.toml diff --git a/commitizen/bump.py b/commitizen/bump.py index 020cd0a228..285c6b4e9c 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -8,7 +8,7 @@ from commitizen.defaults import MAJOR, MINOR, PATCH, bump_message from commitizen.exceptions import CurrentVersionNotFoundError from commitizen.git import GitCommit, smart_open -from commitizen.version_schemes import DEFAULT_SCHEME, VersionScheme, Version +from commitizen.version_schemes import DEFAULT_SCHEME, Version, VersionScheme def find_increment( @@ -45,7 +45,12 @@ def find_increment( def update_version_in_files( - current_version: str, new_version: str, files: list[str], *, check_consistency=False + current_version: str, + new_version: str, + files: List[str], + encoding: str, + *, + check_consistency=False, ) -> None: """Change old version to the new one in every file given. @@ -62,7 +67,11 @@ def update_version_in_files( regex = _version_to_regex(current_version) current_version_found, version_file = _bump_with_regex( - filepath, current_version, new_version, regex + filepath, + current_version, + new_version, + regex, + encoding, ) if check_consistency and not current_version_found: @@ -73,17 +82,21 @@ def update_version_in_files( ) # Write the file out again - with smart_open(filepath, "w") as file: + with smart_open(filepath, "w", encoding=encoding) as file: file.write(version_file) def _bump_with_regex( - version_filepath: str, current_version: str, new_version: str, regex: str -) -> tuple[bool, str]: + version_filepath: str, + current_version: str, + new_version: str, + regex: str, + encoding: str, +) -> Tuple[bool, str]: current_version_found = False lines = [] pattern = re.compile(regex) - with open(version_filepath, "r") as f: + with open(version_filepath, "r", encoding=encoding) as f: for line in f: if pattern.search(line): bumped_line = line.replace(current_version, new_version) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 820b926f68..59bdfca1d5 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -227,7 +227,7 @@ def get_metadata(filepath: str, scheme: VersionScheme = Pep440) -> dict: "latest_version_position": None, } - with open(filepath, "r") as changelog_file: + with open(filepath, "r", encoding=encoding) as changelog_file: for index, line in enumerate(changelog_file): line = line.strip().lower() diff --git a/commitizen/changelog_parser.py b/commitizen/changelog_parser.py index eb1b264d36..7e37b0eef2 100644 --- a/commitizen/changelog_parser.py +++ b/commitizen/changelog_parser.py @@ -36,7 +36,7 @@ ] -def find_version_blocks(filepath: str) -> Generator: +def find_version_blocks(filepath: str, encoding: str) -> Generator: """Find version block (version block: contains all the information about a version.) E.g: @@ -53,7 +53,7 @@ def find_version_blocks(filepath: str) -> Generator: ``` """ - with open(filepath, "r") as f: + with open(filepath, "r", encoding=encoding) as f: block: list = [] for line in f: line = line.strip("\n") diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 13e30a90a6..5896964ffb 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -36,6 +36,7 @@ def __init__(self, config: BaseConfig, arguments: dict): raise NotAGitProjectError() self.config: BaseConfig = config + self.encoding = config.settings["encoding"] self.arguments: dict = arguments self.bump_settings: dict = { **config.settings, @@ -297,6 +298,7 @@ def __call__(self): # noqa: C901 str(current_version), str(new_version), version_files, + self.encoding, check_consistency=self.check_consistency, ) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index cf667a299b..7015cab1b8 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -27,6 +27,7 @@ def __init__(self, config: BaseConfig, args): raise NotAGitProjectError() self.config: BaseConfig = config + self.encoding = self.config.settings["encoding"] self.cz = factory.commiter_factory(self.config) self.start_rev = args.get("start_rev") or self.config.settings.get( @@ -100,9 +101,9 @@ def write_changelog( f"or the setting `changelog_file` in {self.config.path}" ) - changelog_hook: Callable | None = self.cz.changelog_hook - with smart_open(self.file_name, "w") as changelog_file: - partial_changelog: str | None = None + changelog_hook: Optional[Callable] = self.cz.changelog_hook + with smart_open(self.file_name, "w", encoding=self.encoding) as changelog_file: + partial_changelog: Optional[str] = None if self.incremental: new_lines = changelog.incremental_build( changelog_out, lines, changelog_meta @@ -141,7 +142,9 @@ def __call__(self): end_rev = "" if self.incremental: - changelog_meta = changelog.get_metadata(self.file_name, self.scheme) + changelog_meta = changelog.get_metadata( + self.file_name, self.scheme, self.encoding + ) latest_version = changelog_meta.get("latest_version") if latest_version: latest_tag_version: str = bump.normalize_tag( @@ -187,7 +190,7 @@ def __call__(self): lines = [] if self.incremental and os.path.isfile(self.file_name): - with open(self.file_name, "r") as changelog_file: + with open(self.file_name, "r", encoding=self.encoding) as changelog_file: lines = changelog_file.readlines() self.write_changelog(changelog_out, lines, changelog_meta) diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index d615867d2a..a320b5b8ac 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -44,6 +44,7 @@ def __init__(self, config: BaseConfig, arguments: dict[str, Any], cwd=os.getcwd( self._valid_command_argument() self.config: BaseConfig = config + self.encoding = config.settings["encoding"] self.cz = factory.commiter_factory(self.config) def _valid_command_argument(self): @@ -97,7 +98,7 @@ def _get_commits(self): # Get commit message from file (--commit-msg-file) if self.commit_msg_file is not None: # Enter this branch if commit_msg_file is "". - with open(self.commit_msg_file, "r", encoding="utf-8") as commit_file: + with open(self.commit_msg_file, "r", encoding=self.encoding) as commit_file: msg = commit_file.read() # Get commit message from command line (--message) elif self.commit_msg is not None: diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 4d9da5c3fa..85512d3473 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -28,6 +28,7 @@ def __init__(self, config: BaseConfig, arguments: dict): raise NotAGitProjectError() self.config: BaseConfig = config + self.encoding = config.settings["encoding"] self.cz = factory.commiter_factory(self.config) self.arguments = arguments self.temp_file: str = os.path.join( @@ -41,7 +42,7 @@ def read_backup_message(self) -> str: raise NoCommitBackupError() # Read commit message from backup - with open(self.temp_file, "r") as f: + with open(self.temp_file, "r", encoding=self.encoding) as f: return f.read().strip() def prompt_commit_questions(self) -> str: @@ -99,7 +100,7 @@ def __call__(self): out.error(c.err) # Create commit backup - with smart_open(self.temp_file, "w") as f: + with smart_open(self.temp_file, "w", encoding=self.encoding) as f: f.write(m) raise CommitError() diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 33cd9a26f4..62b3aec971 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -72,6 +72,7 @@ def is_pre_commit_installed(self) -> bool: class Init: def __init__(self, config: BaseConfig, *args): self.config: BaseConfig = config + self.encoding = config.settings["encoding"] self.cz = factory.commiter_factory(self.config) self.project_info = ProjectInfo() @@ -324,7 +325,9 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None = None): # .pre-commit-config.yaml does not exist config_data["repos"] = [cz_hook_config] else: - with open(pre_commit_config_filename) as config_file: + with open( + pre_commit_config_filename, encoding=self.encoding + ) as config_file: yaml_data = yaml.safe_load(config_file) if yaml_data: config_data = yaml_data @@ -340,7 +343,9 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None = None): # .pre-commit-config.yaml exists but there's no "repos" key config_data["repos"] = [cz_hook_config] - with smart_open(pre_commit_config_filename, "w") as config_file: + with smart_open( + pre_commit_config_filename, "w", encoding=self.encoding + ) as config_file: yaml.safe_dump(config_data, stream=config_file) if not self.project_info.is_pre_commit_installed: diff --git a/commitizen/config/json_config.py b/commitizen/config/json_config.py index 10d60de880..e081d26643 100644 --- a/commitizen/config/json_config.py +++ b/commitizen/config/json_config.py @@ -12,12 +12,13 @@ class JsonConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super(JsonConfig, self).__init__() + self.encoding = self.settings["encoding"] self.is_empty_config = False self.add_path(path) self._parse_setting(data) def init_empty_config_content(self): - with smart_open(self.path, "a") as json_file: + with smart_open(self.path, "a", encoding=self.encoding) as json_file: json.dump({"commitizen": {}}, json_file) def set_key(self, key, value): @@ -30,7 +31,7 @@ def set_key(self, key, value): parser = json.load(f) parser["commitizen"][key] = value - with smart_open(self.path, "w") as f: + with smart_open(self.path, "w", encoding=self.encoding) as f: json.dump(parser, f, indent=2) return self diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index ee379aab77..faa0e8b33d 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -11,6 +11,7 @@ class TomlConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super(TomlConfig, self).__init__() + self.encoding = self.settings["encoding"] self.is_empty_config = False self._parse_setting(data) self.add_path(path) @@ -26,7 +27,7 @@ def init_empty_config_content(self): if parser.get("tool") is None: parser["tool"] = table() parser["tool"]["commitizen"] = table() - output_toml_file.write(parser.as_string().encode("utf-8")) + output_toml_file.write(parser.as_string().encode(self.encoding)) def set_key(self, key, value): """Set or update a key in the conf. @@ -39,7 +40,7 @@ def set_key(self, key, value): parser["tool"]["commitizen"][key] = value with open(self.path, "wb") as f: - f.write(parser.as_string().encode("utf-8")) + f.write(parser.as_string().encode(self.encoding)) return self def _parse_setting(self, data: bytes | str) -> None: diff --git a/commitizen/config/yaml_config.py b/commitizen/config/yaml_config.py index d67d7fb253..1bdb1c7355 100644 --- a/commitizen/config/yaml_config.py +++ b/commitizen/config/yaml_config.py @@ -12,12 +12,13 @@ class YAMLConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super(YAMLConfig, self).__init__() + self.encoding = self.settings["encoding"] self.is_empty_config = False self._parse_setting(data) self.add_path(path) def init_empty_config_content(self): - with smart_open(self.path, "a") as json_file: + with smart_open(self.path, "a", encoding=self.encoding) as json_file: yaml.dump({"commitizen": {}}, json_file, explicit_start=True) def _parse_setting(self, data: bytes | str) -> None: @@ -44,7 +45,7 @@ def set_key(self, key, value): parser = yaml.load(yaml_file, Loader=yaml.FullLoader) parser["commitizen"][key] = value - with smart_open(self.path, "w") as yaml_file: + with smart_open(self.path, "w", encoding=self.encoding) as yaml_file: yaml.dump(parser, yaml_file, explicit_start=True) return self diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 8cb27eaf81..1382622fee 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -202,7 +202,7 @@ def schema_pattern(self) -> str: def info(self) -> str: dir_path = os.path.dirname(os.path.realpath(__file__)) filepath = os.path.join(dir_path, "conventional_commits_info.txt") - with open(filepath, "r") as f: + with open(filepath, "r", encoding=self.config.settings["encoding"]) as f: content = f.read() return content diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index 28ea5047bc..7bc650ecf6 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -81,7 +81,7 @@ def info(self) -> str | None: info_path = self.custom_settings.get("info_path") info = self.custom_settings.get("info") if info_path: - with open(info_path, "r") as f: + with open(info_path, "r", encoding=self.config.settings["encoding"]) as f: content = f.read() return content elif info: diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index bd3cd3c7ee..cc33cd791a 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -76,6 +76,6 @@ def schema_pattern(self) -> str: def info(self) -> str: dir_path = os.path.dirname(os.path.realpath(__file__)) filepath = os.path.join(dir_path, "jira_info.txt") - with open(filepath, "r") as f: + with open(filepath, "r", encoding=self.config.settings["encoding"]) as f: content = f.read() return content diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 62e634dbb7..ea48e49437 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -55,6 +55,7 @@ class Settings(TypedDict, total=False): pre_bump_hooks: list[str] | None post_bump_hooks: list[str] | None prerelease_offset: int + encoding: str name: str = "cz_conventional_commits" @@ -66,6 +67,7 @@ class Settings(TypedDict, total=False): ".cz.yaml", "cz.yaml", ] +encoding: str = "utf-8" DEFAULT_SETTINGS: Settings = { "name": "cz_conventional_commits", @@ -93,6 +95,7 @@ class Settings(TypedDict, total=False): "pre_bump_hooks": [], "post_bump_hooks": [], "prerelease_offset": 0, + "encoding": "utf-8", } MAJOR = "MAJOR" diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index acc2ad69a6..1faa55ff5e 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -227,7 +227,7 @@ def test_bump_command_prelease(mocker: MockFixture): def test_bump_on_git_with_hooks_no_verify_disabled(mocker: MockFixture): """Bump commit without --no-verify""" cmd.run("mkdir .git/hooks") - with open(".git/hooks/pre-commit", "w") as f: + with open(".git/hooks/pre-commit", "w", encoding="utf-8") as f: f.write("#!/usr/bin/env bash\n" 'echo "0.1.0"') cmd.run("chmod +x .git/hooks/pre-commit") @@ -246,7 +246,7 @@ def test_bump_on_git_with_hooks_no_verify_disabled(mocker: MockFixture): @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_tag_exists_raises_exception(mocker: MockFixture): cmd.run("mkdir .git/hooks") - with open(".git/hooks/post-commit", "w") as f: + with open(".git/hooks/post-commit", "w", encoding="utf-8") as f: f.write("#!/usr/bin/env bash\n" "exit 9") cmd.run("chmod +x .git/hooks/post-commit") @@ -265,7 +265,7 @@ def test_bump_tag_exists_raises_exception(mocker: MockFixture): @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_on_git_with_hooks_no_verify_enabled(mocker: MockFixture): cmd.run("mkdir .git/hooks") - with open(".git/hooks/pre-commit", "w") as f: + with open(".git/hooks/pre-commit", "w", encoding="utf-8") as f: f.write("#!/usr/bin/env bash\n" 'echo "0.1.0"') cmd.run("chmod +x .git/hooks/pre-commit") @@ -406,10 +406,10 @@ def test_bump_files_only(mocker: MockFixture, tmp_commitizen_project): tag_exists = git.tag_exist("0.3.0") assert tag_exists is False - with open(tmp_version_file, "r") as f: + with open(tmp_version_file, "r", encoding="utf-8") as f: assert "0.3.0" in f.read() - with open(tmp_commitizen_cfg_file, "r") as f: + with open(tmp_commitizen_cfg_file, "r", encoding="utf-8") as f: assert "0.3.0" in f.read() @@ -431,7 +431,7 @@ def test_bump_local_version(mocker: MockFixture, tmp_commitizen_project): tag_exists = git.tag_exist("4.5.1+0.2.0") assert tag_exists is True - with open(tmp_version_file, "r") as f: + with open(tmp_version_file, "r", encoding="utf-8") as f: assert "4.5.1+0.2.0" in f.read() @@ -511,7 +511,7 @@ def test_bump_with_changelog_arg(mocker: MockFixture, changelog_path): tag_exists = git.tag_exist("0.2.0") assert tag_exists is True - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() assert out.startswith("#") assert "0.2.0" in out @@ -520,7 +520,7 @@ def test_bump_with_changelog_arg(mocker: MockFixture, changelog_path): @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_with_changelog_config(mocker: MockFixture, changelog_path, config_path): create_file_and_commit("feat(user): new file") - with open(config_path, "a") as fp: + with open(config_path, "a", encoding="utf-8") as fp: fp.write("update_changelog_on_bump = true\n") testargs = ["cz", "bump", "--yes"] @@ -529,7 +529,7 @@ def test_bump_with_changelog_config(mocker: MockFixture, changelog_path, config_ tag_exists = git.tag_exist("0.2.0") assert tag_exists is True - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() assert out.startswith("#") assert "0.2.0" in out @@ -572,7 +572,7 @@ def test_bump_with_changelog_to_stdout_arg(mocker: MockFixture, capsys, changelo tag_exists = git.tag_exist("0.2.0") assert tag_exists is True - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() assert out.startswith("#") assert "0.2.0" in out @@ -694,11 +694,14 @@ def test_bump_changelog_command_commits_untracked_changelog_and_version_files( """ with tmp_commitizen_project.join("pyproject.toml").open( - mode="a" + mode="a", + encoding="utf-8", ) as commitizen_config: commitizen_config.write(f"version_files = [\n" f"'{version_regex}'\n]") - with tmp_commitizen_project.join(version_filepath).open(mode="a+") as version_file: + with tmp_commitizen_project.join(version_filepath).open( + mode="a+", encoding="utf-8" + ) as version_file: version_file.write(version_file_content) create_file_and_commit("fix: some test commit") diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 79115a2e4c..b9560216b9 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -3,6 +3,9 @@ from datetime import datetime import pytest +from dateutil import relativedelta +from pytest_mock import MockFixture + from commitizen import cli, git from commitizen.commands.changelog import Changelog from commitizen.exceptions import ( @@ -12,8 +15,6 @@ NotAGitProjectError, NotAllowed, ) -from dateutil import relativedelta -from pytest_mock import MockFixture from tests.utils import ( create_branch, create_file_and_commit, @@ -76,7 +77,7 @@ def test_changelog_from_start( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() file_regression.check(out, extension=".md") @@ -105,7 +106,7 @@ def test_changelog_replacing_unreleased_using_incremental( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read().replace( datetime.strftime(datetime.now(), "%Y-%m-%d"), "2022-08-14" ) @@ -129,7 +130,7 @@ def test_changelog_is_persisted_using_incremental( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "a") as f: + with open(changelog_path, "a", encoding="utf-8") as f: f.write("\nnote: this should be persisted using increment\n") create_file_and_commit("fix: mama gotta work") @@ -141,7 +142,7 @@ def test_changelog_is_persisted_using_incremental( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read().replace( datetime.strftime(datetime.now(), "%Y-%m-%d"), "2022-08-14" ) @@ -153,7 +154,7 @@ def test_changelog_is_persisted_using_incremental( def test_changelog_incremental_angular_sample( mocker: MockFixture, capsys, changelog_path, file_regression ): - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write( "# [10.0.0-rc.3](https://github.com/angular/angular/compare/10.0.0-rc.2...10.0.0-rc.3) (2020-04-22)\n" "\n" @@ -175,7 +176,7 @@ def test_changelog_incremental_angular_sample( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() file_regression.check(out, extension=".md") @@ -210,7 +211,7 @@ def test_changelog_incremental_angular_sample( def test_changelog_incremental_keep_a_changelog_sample( mocker: MockFixture, capsys, changelog_path, file_regression ): - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write(KEEP_A_CHANGELOG) create_file_and_commit("irrelevant commit") git.tag("1.0.0") @@ -226,7 +227,7 @@ def test_changelog_incremental_keep_a_changelog_sample( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() file_regression.check(out, extension=".md") @@ -374,7 +375,7 @@ def test_changelog_multiple_incremental_do_not_add_new_lines( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() file_regression.check(out, extension=".md") @@ -385,7 +386,7 @@ def test_changelog_incremental_newline_separates_new_content_from_old( mocker: MockFixture, changelog_path ): """Test for https://github.com/commitizen-tools/commitizen/issues/509""" - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write("Pre-existing content that should be kept\n") create_file_and_commit("feat: add more cat videos") @@ -395,7 +396,7 @@ def test_changelog_incremental_newline_separates_new_content_from_old( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() assert ( @@ -550,9 +551,9 @@ def test_breaking_change_content_v1_with_exclamation_mark_feat( def test_changelog_config_flag_increment( mocker: MockFixture, changelog_path, config_path, file_regression ): - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write("changelog_incremental = true\n") - with open(changelog_path, "a") as f: + with open(changelog_path, "a", encoding="utf-8") as f: f.write("\nnote: this should be persisted using increment\n") create_file_and_commit("feat: add new output") @@ -561,7 +562,7 @@ def test_changelog_config_flag_increment( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() assert "this should be persisted using increment" in out @@ -616,7 +617,7 @@ def test_changelog_config_start_rev_option( create_file_and_commit("feat: after 0.2.0") create_file_and_commit("feat: after 0.2") - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write('changelog_start_rev = "0.2.0"\n') testargs = ["cz", "changelog", "--dry-run"] @@ -633,7 +634,7 @@ def test_changelog_incremental_keep_a_changelog_sample_with_annotated_tag( mocker: MockFixture, capsys, changelog_path, file_regression ): """Fix #378""" - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write(KEEP_A_CHANGELOG) create_file_and_commit("irrelevant commit") git.tag("1.0.0", annotated=True) @@ -649,7 +650,7 @@ def test_changelog_incremental_keep_a_changelog_sample_with_annotated_tag( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() file_regression.check(out, extension=".md") @@ -662,7 +663,7 @@ def test_changelog_incremental_with_release_candidate_version( mocker: MockFixture, changelog_path, file_regression, test_input ): """Fix #357""" - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write(KEEP_A_CHANGELOG) create_file_and_commit("irrelevant commit") git.tag("1.0.0", annotated=True) @@ -683,7 +684,7 @@ def test_changelog_incremental_with_release_candidate_version( mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() file_regression.check(out, extension=".md") @@ -797,7 +798,7 @@ def test_changelog_incremental_with_merge_prerelease( def test_changelog_with_filename_as_empty_string( mocker: MockFixture, changelog_path, config_path ): - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write("changelog_file = true\n") create_file_and_commit("feat: add new output") @@ -815,7 +816,7 @@ def test_changelog_from_rev_first_version_from_arg( ): mocker.patch("commitizen.git.GitTag.date", "2022-02-13") - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write('tag_format = "$version"\n') # create commit and tag @@ -836,7 +837,7 @@ def test_changelog_from_rev_first_version_from_arg( testargs = ["cz", "changelog", "0.2.0"] mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() file_regression.check(out, extension=".md") @@ -849,7 +850,7 @@ def test_changelog_from_rev_latest_version_from_arg( ): mocker.patch("commitizen.git.GitTag.date", "2022-02-13") - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write('tag_format = "$version"\n') # create commit and tag @@ -884,7 +885,7 @@ def test_changelog_from_rev_single_version_not_found( mocker: MockFixture, config_path, changelog_path ): """Provides an invalid revision ID to changelog command""" - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write('tag_format = "$version"\n') # create commit and tag @@ -946,7 +947,7 @@ def test_changelog_from_rev_range_default_tag_format( @pytest.mark.freeze_time("2022-02-13") def test_changelog_from_rev_range_version_not_found(mocker: MockFixture, config_path): """Provides an invalid end revision ID to changelog command""" - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write('tag_format = "$version"\n') # create commit and tag @@ -977,7 +978,7 @@ def test_changelog_from_rev_version_range_including_first_tag( ): mocker.patch("commitizen.git.GitTag.date", "2022-02-13") - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write('tag_format = "$version"\n') # create commit and tag @@ -996,7 +997,7 @@ def test_changelog_from_rev_version_range_including_first_tag( testargs = ["cz", "changelog", "0.2.0..0.3.0"] mocker.patch.object(sys, "argv", testargs) cli.main() - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: out = f.read() file_regression.check(out, extension=".md") @@ -1009,7 +1010,7 @@ def test_changelog_from_rev_version_range_from_arg( ): mocker.patch("commitizen.git.GitTag.date", "2022-02-13") - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write('tag_format = "$version"\n') # create commit and tag @@ -1049,7 +1050,7 @@ def test_changelog_from_rev_version_with_big_range_from_arg( ): mocker.patch("commitizen.git.GitTag.date", "2022-02-13") - with open(config_path, "a") as f: + with open(config_path, "a", encoding="utf-8") as f: f.write('tag_format = "$version"\n') # create commit and tag @@ -1275,7 +1276,8 @@ def test_changelog_uses_version_tags_for_header(mocker: MockFixture, config): """Tests that changelog headers always use version tags even if there are non-version tags This tests a scenario fixed in this commit: - The first header was using a non-version tag and outputting "## 0-not-a-version" instead of "## 1.0.0""" + The first header was using a non-version tag and outputting "## 0-not-a-version" instead of "## 1.0.0 + """ create_file_and_commit("feat: commit in 1.0.0") create_tag("0-not-a-version") create_tag("1.0.0") diff --git a/tests/commands/test_init_command.py b/tests/commands/test_init_command.py index d5c8b5965b..94506fedf0 100644 --- a/tests/commands/test_init_command.py +++ b/tests/commands/test_init_command.py @@ -74,7 +74,7 @@ def test_init_without_setup_pre_commit_hook(tmpdir, mocker: MockFixture, config) with tmpdir.as_cwd(): commands.Init(config)() - with open("pyproject.toml", "r") as toml_file: + with open("pyproject.toml", "r", encoding="utf-8") as toml_file: config_data = toml_file.read() assert config_data == expected_config diff --git a/tests/test_bump_update_version_in_files.py b/tests/test_bump_update_version_in_files.py index b1b9c0b1d5..9fe3c66801 100644 --- a/tests/test_bump_update_version_in_files.py +++ b/tests/test_bump_update_version_in_files.py @@ -102,11 +102,13 @@ def version_files( def test_update_version_in_files(version_files, file_regression): old_version = "1.2.3" new_version = "2.0.0" - bump.update_version_in_files(old_version, new_version, version_files) + bump.update_version_in_files( + old_version, new_version, version_files, encoding="utf-8" + ) file_contents = "" for filepath in version_files: - with open(filepath, "r") as f: + with open(filepath, "r", encoding="utf-8") as f: file_contents += f.read() file_regression.check(file_contents, extension=".txt") @@ -117,8 +119,8 @@ def test_partial_update_of_file(version_repeated_file, file_regression): regex = "version" location = f"{version_repeated_file}:{regex}" - bump.update_version_in_files(old_version, new_version, [location]) - with open(version_repeated_file, "r") as f: + bump.update_version_in_files(old_version, new_version, [location], encoding="utf-8") + with open(version_repeated_file, "r", encoding="utf-8") as f: file_regression.check(f.read(), extension=".json") @@ -127,8 +129,8 @@ def test_random_location(random_location_version_file, file_regression): new_version = "2.0.0" location = f"{random_location_version_file}:version.+Commitizen" - bump.update_version_in_files(old_version, new_version, [location]) - with open(random_location_version_file, "r") as f: + bump.update_version_in_files(old_version, new_version, [location], encoding="utf-8") + with open(random_location_version_file, "r", encoding="utf-8") as f: file_regression.check(f.read(), extension=".lock") @@ -139,8 +141,8 @@ def test_duplicates_are_change_with_no_regex( new_version = "2.0.0" location = f"{random_location_version_file}:version" - bump.update_version_in_files(old_version, new_version, [location]) - with open(random_location_version_file, "r") as f: + bump.update_version_in_files(old_version, new_version, [location], encoding="utf-8") + with open(random_location_version_file, "r", encoding="utf-8") as f: file_regression.check(f.read(), extension=".lock") @@ -151,8 +153,8 @@ def test_version_bump_increase_string_length( new_version = "1.2.10" location = f"{multiple_versions_increase_string}:version" - bump.update_version_in_files(old_version, new_version, [location]) - with open(multiple_versions_increase_string, "r") as f: + bump.update_version_in_files(old_version, new_version, [location], encoding="utf-8") + with open(multiple_versions_increase_string, "r", encoding="utf-8") as f: file_regression.check(f.read(), extension=".txt") @@ -163,8 +165,8 @@ def test_version_bump_reduce_string_length( new_version = "2.0.0" location = f"{multiple_versions_reduce_string}:version" - bump.update_version_in_files(old_version, new_version, [location]) - with open(multiple_versions_reduce_string, "r") as f: + bump.update_version_in_files(old_version, new_version, [location], encoding="utf-8") + with open(multiple_versions_reduce_string, "r", encoding="utf-8") as f: file_regression.check(f.read(), extension=".txt") @@ -180,7 +182,11 @@ def test_file_version_inconsistent_error( new_version = "2.0.0" with pytest.raises(CurrentVersionNotFoundError) as excinfo: bump.update_version_in_files( - old_version, new_version, version_files, check_consistency=True + old_version, + new_version, + version_files, + check_consistency=True, + encoding="utf-8", ) expected_msg = ( @@ -198,6 +204,6 @@ def test_multiplt_versions_to_bump( new_version = "1.2.10" location = f"{multiple_versions_to_update_poetry_lock}:version" - bump.update_version_in_files(old_version, new_version, [location]) - with open(multiple_versions_to_update_poetry_lock, "r") as f: + bump.update_version_in_files(old_version, new_version, [location], encoding="utf-8") + with open(multiple_versions_to_update_poetry_lock, "r", encoding="utf-8") as f: file_regression.check(f.read(), extension=".toml") diff --git a/tests/test_bump_update_version_in_files/test_multiple_versions_to_bump_with_eol_.toml b/tests/test_bump_update_version_in_files/test_multiple_versions_to_bump_with_eol_.toml new file mode 100644 index 0000000000..f279eb4d61 --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_multiple_versions_to_bump_with_eol_.toml @@ -0,0 +1,27 @@ +[[package]] +name = "to-update-1" +version = "1.2.10" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "to-update-2" +version = "1.2.10" diff --git a/tests/test_bump_update_version_in_files/test_multiple_versions_to_bump_without_eol_.toml b/tests/test_bump_update_version_in_files/test_multiple_versions_to_bump_without_eol_.toml new file mode 100644 index 0000000000..47092b958b --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_multiple_versions_to_bump_without_eol_.toml @@ -0,0 +1,27 @@ +[[package]] +name = "to-update-1" +version = "1.2.10" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "not-to-update" +version = "1.3.3" + +[[package]] +name = "to-update-2" +version = "1.2.10" \ No newline at end of file diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 78a2697c36..f16f4a1459 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -496,7 +496,7 @@ def tags() -> list: @pytest.fixture def changelog_content() -> str: changelog_path = "tests/CHANGELOG_FOR_TEST.md" - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: return f.read() diff --git a/tests/test_changelog_meta.py b/tests/test_changelog_meta.py index 505daefb83..4b3b9caa01 100644 --- a/tests/test_changelog_meta.py +++ b/tests/test_changelog_meta.py @@ -44,7 +44,7 @@ def changelog_a_file(): changelog_path = "tests/CHANGELOG.md" - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write(CHANGELOG_A) yield changelog_path @@ -56,7 +56,7 @@ def changelog_a_file(): def changelog_b_file(): changelog_path = "tests/CHANGELOG.md" - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write(CHANGELOG_B) yield changelog_path @@ -68,7 +68,7 @@ def changelog_b_file(): def changelog_c_file(): changelog_path = "tests/CHANGELOG.md" - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write(CHANGELOG_C) yield changelog_path @@ -80,7 +80,7 @@ def changelog_c_file(): def changelog_d_file(): changelog_path = "tests/CHANGELOG.md" - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write(CHANGELOG_D) yield changelog_path @@ -126,7 +126,7 @@ def test_parse_title_type_of_line(line_from_changelog, output_title): def test_get_metadata_from_a(changelog_a_file): - meta = changelog.get_metadata(changelog_a_file) + meta = changelog.get_metadata(changelog_a_file, encoding="utf-8") assert meta == { "latest_version": "1.0.0", "latest_version_position": 10, @@ -136,7 +136,7 @@ def test_get_metadata_from_a(changelog_a_file): def test_get_metadata_from_b(changelog_b_file): - meta = changelog.get_metadata(changelog_b_file) + meta = changelog.get_metadata(changelog_b_file, encoding="utf-8") assert meta == { "latest_version": "1.2.0", "latest_version_position": 3, @@ -146,7 +146,7 @@ def test_get_metadata_from_b(changelog_b_file): def test_get_metadata_from_c(changelog_c_file): - meta = changelog.get_metadata(changelog_c_file) + meta = changelog.get_metadata(changelog_c_file, encoding="utf-8") assert meta == { "latest_version": "1.0.0", "latest_version_position": 3, @@ -156,7 +156,7 @@ def test_get_metadata_from_c(changelog_c_file): def test_get_metadata_from_d(changelog_d_file): - meta = changelog.get_metadata(changelog_d_file) + meta = changelog.get_metadata(changelog_d_file, encoding="utf-8") assert meta == { "latest_version": None, "latest_version_position": None, diff --git a/tests/test_changelog_parser.py b/tests/test_changelog_parser.py index 540f62fd19..75f6788a8d 100644 --- a/tests/test_changelog_parser.py +++ b/tests/test_changelog_parser.py @@ -28,7 +28,7 @@ @pytest.fixture def changelog_content() -> str: changelog_path = "tests/CHANGELOG_FOR_TEST.md" - with open(changelog_path, "r") as f: + with open(changelog_path, "r", encoding="utf-8") as f: return f.read() @@ -38,7 +38,7 @@ def existing_changelog_file(tmpdir): changelog_path = os.path.join(os.getcwd(), "CHANGELOG.md") # changelog_path = "tests/CHANGELOG.md" - with open(changelog_path, "w") as f: + with open(changelog_path, "w", encoding="utf-8") as f: f.write(CHANGELOG_TEMPLATE) yield changelog_path @@ -47,7 +47,7 @@ def existing_changelog_file(tmpdir): def test_read_changelog_blocks(existing_changelog_file): - blocks = changelog_parser.find_version_blocks(existing_changelog_file) + blocks = changelog_parser.find_version_blocks(existing_changelog_file, "utf-8") blocks = list(blocks) amount_of_blocks = len(blocks) assert amount_of_blocks == 2 @@ -127,7 +127,7 @@ def test_transform_change_type_fail(): def test_generate_block_tree(existing_changelog_file): - blocks = changelog_parser.find_version_blocks(existing_changelog_file) + blocks = changelog_parser.find_version_blocks(existing_changelog_file, "utf-8") block = next(blocks) tree = changelog_parser.generate_block_tree(block) assert tree == { @@ -157,7 +157,7 @@ def test_generate_block_tree(existing_changelog_file): def test_generate_full_tree(existing_changelog_file): - blocks = changelog_parser.find_version_blocks(existing_changelog_file) + blocks = changelog_parser.find_version_blocks(existing_changelog_file, "utf-8") tree = list(changelog_parser.generate_full_tree(blocks)) assert tree == [ diff --git a/tests/test_conf.py b/tests/test_conf.py index 5c2cb6b6ff..7061d30146 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -62,6 +62,7 @@ "pre_bump_hooks": ["scripts/generate_documentation.sh"], "post_bump_hooks": ["scripts/slack_notification.sh"], "prerelease_offset": 0, + "encoding": "utf-8", } _new_settings = { @@ -85,6 +86,7 @@ "pre_bump_hooks": ["scripts/generate_documentation.sh"], "post_bump_hooks": ["scripts/slack_notification.sh"], "prerelease_offset": 0, + "encoding": "utf-8", } _read_settings = { @@ -102,7 +104,7 @@ def config_files_manager(request, tmpdir): with tmpdir.as_cwd(): filename = request.param - with open(filename, "w") as f: + with open(filename, "w", encoding="utf-8") as f: if "toml" in filename: f.write(PYPROJECT) elif "json" in filename: @@ -159,7 +161,7 @@ def test_init_empty_config_content(self, tmpdir): toml_config = config.TomlConfig(data="", path=path) toml_config.init_empty_config_content() - with open(path, "r") as toml_file: + with open(path, "r", encoding="utf-8") as toml_file: assert toml_file.read() == "[tool.commitizen]\n" def test_init_empty_config_content_with_existing_content(self, tmpdir): @@ -170,7 +172,7 @@ def test_init_empty_config_content_with_existing_content(self, tmpdir): toml_config = config.TomlConfig(data="", path=path) toml_config.init_empty_config_content() - with open(path, "r") as toml_file: + with open(path, "r", encoding="utf-8") as toml_file: assert toml_file.read() == existing_content + "\n[tool.commitizen]\n" @@ -180,7 +182,7 @@ def test_init_empty_config_content(self, tmpdir): json_config = config.JsonConfig(data="{}", path=path) json_config.init_empty_config_content() - with open(path, "r") as json_file: + with open(path, "r", encoding="utf-8") as json_file: assert json.load(json_file) == {"commitizen": {}} From d9801aebcf8bcf561328cb5b2227194cca2f0637 Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Fri, 2 Dec 2022 21:08:09 -0800 Subject: [PATCH 02/10] test(unicode): add tests --- tests/test_cz_customize.py | 232 +++++++++++++++++++++++++++++++++++-- 1 file changed, 222 insertions(+), 10 deletions(-) diff --git a/tests/test_cz_customize.py b/tests/test_cz_customize.py index 84e463cf96..9f3556fce8 100644 --- a/tests/test_cz_customize.py +++ b/tests/test_cz_customize.py @@ -7,7 +7,7 @@ TOML_STR = r""" [tool.commitizen.customize] message_template = "{{change_type}}:{% if show_message %} {{message}}{% endif %}" - example = "feature: this feature enable customize through config file" + example = "feature: this feature enables customization through a config file" schema = ": " schema_pattern = "(feature|bug fix):(\\s.*)" commit_parser = "^(?Pfeature|bug fix):\\s(?P.*)?" @@ -50,7 +50,7 @@ ], "customize": { "message_template": "{{change_type}}:{% if show_message %} {{message}}{% endif %}", - "example": "feature: this feature enable customize through config file", + "example": "feature: this feature enables customization through a config file", "schema": ": ", "schema_pattern": "(feature|bug fix):(\\s.*)", "bump_pattern": "^(break|new|fix|hotfix)", @@ -106,7 +106,7 @@ - pyproject.toml customize: message_template: "{{change_type}}:{% if show_message %} {{message}}{% endif %}" - example: 'feature: this feature enable customize through config file' + example: 'feature: this feature enables customization through a config file' schema: ": " schema_pattern: "(feature|bug fix):(\\s.*)" bump_pattern: "^(break|new|fix|hotfix)" @@ -134,11 +134,105 @@ message: Do you want to add body message in commit? """ +TOML_WITH_UNICODE = r""" + [tool.commitizen] + name = "cz_customize" + version = "1.0.0" + version_files = [ + "commitizen/__version__.py", + "pyproject.toml:version" + ] + [tool.commitizen.customize] + message_template = "{{change_type}}:{% if show_message %} {{message}}{% endif %}" + example = "✨ feature: this feature enables customization through a config file" + schema = ": " + schema_pattern = "(✨ feature|🐛 bug fix):(\\s.*)" + commit_parser = "^(?P✨ feature|🐛 bug fix):\\s(?P.*)?" + changelog_pattern = "^(✨ feature|🐛 bug fix)?(!)?" + change_type_map = {"✨ feature" = "Feat", "🐛 bug fix" = "Fix"} + bump_pattern = "^(✨ feat|🐛 bug fix)" + bump_map = {"break" = "MAJOR", "✨ feat" = "MINOR", "🐛 bug fix" = "MINOR"} + change_type_order = ["perf", "BREAKING CHANGE", "feat", "fix", "refactor"] + info = "This is a customized cz with emojis 🎉!" + [[tool.commitizen.customize.questions]] + type = "list" + name = "change_type" + choices = [ + {value = "✨ feature", name = "✨ feature: A new feature."}, + {value = "🐛 bug fix", name = "🐛 bug fix: A bug fix."} + ] + message = "Select the type of change you are committing" + [[tool.commitizen.customize.questions]] + type = "input" + name = "message" + message = "Body." + [[tool.commitizen.customize.questions]] + type = "confirm" + name = "show_message" + message = "Do you want to add body message in commit?" +""" + +JSON_WITH_UNICODE = r""" + { + "commitizen": { + "name": "cz_customize", + "version": "1.0.0", + "version_files": [ + "commitizen/__version__.py", + "pyproject.toml:version" + ], + "customize": { + "message_template": "{{change_type}}:{% if show_message %} {{message}}{% endif %}", + "example": "✨ feature: this feature enables customization through a config file", + "schema": ": ", + "schema_pattern": "(✨ feature|🐛 bug fix):(\\s.*)", + "bump_pattern": "^(✨ feat|🐛 bug fix)", + "bump_map": { + "break": "MAJOR", + "✨ feat": "MINOR", + "🐛 bug fix": "MINOR" + }, + "commit_parser": "^(?P✨ feature|🐛 bug fix):\\s(?P.*)?", + "changelog_pattern": "^(✨ feature|🐛 bug fix)?(!)?", + "change_type_map": {"✨ feature": "Feat", "🐛 bug fix": "Fix"}, + "change_type_order": ["perf", "BREAKING CHANGE", "feat", "fix", "refactor"], + "info": "This is a customized cz with emojis 🎉!", + "questions": [ + { + "type": "list", + "name": "change_type", + "choices": [ + { + "value": "✨ feature", + "name": "✨ feature: A new feature." + }, + { + "value": "🐛 bug fix", + "name": "🐛 bug fix: A bug fix." + } + ], + "message": "Select the type of change you are committing" + }, + { + "type": "input", + "name": "message", + "message": "Body." + }, + { + "type": "confirm", + "name": "show_message", + "message": "Do you want to add body message in commit?" + } + ] + } + } + } +""" TOML_STR_INFO_PATH = """ [tool.commitizen.customize] message_template = "{{change_type}}:{% if show_message %} {{message}}{% endif %}" - example = "feature: this feature enable customize through config file" + example = "feature: this feature enables customization through a config file" schema = ": " bump_pattern = "^(break|new|fix|hotfix)" bump_map = {"break" = "MAJOR", "new" = "MINOR", "fix" = "PATCH", "hotfix" = "PATCH"} @@ -150,7 +244,7 @@ "commitizen": { "customize": { "message_template": "{{change_type}}:{% if show_message %} {{message}}{% endif %}", - "example": "feature: this feature enable customize through config file", + "example": "feature: this feature enables customization through a config file", "schema": ": ", "bump_pattern": "^(break|new|fix|hotfix)", "bump_map": { @@ -169,7 +263,7 @@ commitizen: customize: message_template: "{{change_type}}:{% if show_message %} {{message}}{% endif %}" - example: 'feature: this feature enable customize through config file' + example: 'feature: this feature enables customization through a config file' schema: ": " bump_pattern: "^(break|new|fix|hotfix)" bump_map: @@ -183,7 +277,7 @@ TOML_STR_WITHOUT_INFO = """ [tool.commitizen.customize] message_template = "{{change_type}}:{% if show_message %} {{message}}{% endif %}" - example = "feature: this feature enable customize through config file" + example = "feature: this feature enables customization through a config file" schema = ": " bump_pattern = "^(break|new|fix|hotfix)" bump_map = {"break" = "MAJOR", "new" = "MINOR", "fix" = "PATCH", "hotfix" = "PATCH"} @@ -194,7 +288,7 @@ "commitizen": { "customize": { "message_template": "{{change_type}}:{% if show_message %} {{message}}{% endif %}", - "example": "feature: this feature enable customize through config file", + "example": "feature: this feature enables customization through a config file", "schema": ": ", "bump_pattern": "^(break|new|fix|hotfix)", "bump_map": { @@ -212,7 +306,7 @@ commitizen: customize: message_template: "{{change_type}}:{% if show_message %} {{message}}{% endif %}" - example: 'feature: this feature enable customize through config file' + example: 'feature: this feature enables customization through a config file' schema: ": " bump_pattern: "^(break|new|fix|hotfix)" bump_map: @@ -260,6 +354,16 @@ def config_without_info(request): return request.param +@pytest.fixture( + params=[ + TomlConfig(data=TOML_WITH_UNICODE, path="not_exist.toml"), + JsonConfig(data=JSON_WITH_UNICODE, path="not_exist.json"), + ] +) +def config_with_unicode(request): + return request.param + + def test_initialize_cz_customize_failed(): with pytest.raises(MissingCzCustomizeConfigError) as excinfo: config = BaseConfig() @@ -273,6 +377,11 @@ def test_bump_pattern(config): assert cz.bump_pattern == "^(break|new|fix|hotfix)" +def test_bump_pattern_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert cz.bump_pattern == "^(✨ feat|🐛 bug fix)" + + def test_bump_map(config): cz = CustomizeCommitsCz(config) assert cz.bump_map == { @@ -283,6 +392,15 @@ def test_bump_map(config): } +def test_bump_map_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert cz.bump_map == { + "break": "MAJOR", + "✨ feat": "MINOR", + "🐛 bug fix": "MINOR", + } + + def test_change_type_order(config): cz = CustomizeCommitsCz(config) assert cz.change_type_order == [ @@ -294,6 +412,17 @@ def test_change_type_order(config): ] +def test_change_type_order_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert cz.change_type_order == [ + "perf", + "BREAKING CHANGE", + "feat", + "fix", + "refactor", + ] + + def test_questions(config): cz = CustomizeCommitsCz(config) questions = cz.questions() @@ -317,6 +446,29 @@ def test_questions(config): assert list(questions) == expected_questions +def test_questions_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + questions = cz.questions() + expected_questions = [ + { + "type": "list", + "name": "change_type", + "choices": [ + {"value": "✨ feature", "name": "✨ feature: A new feature."}, + {"value": "🐛 bug fix", "name": "🐛 bug fix: A bug fix."}, + ], + "message": "Select the type of change you are committing", + }, + {"type": "input", "name": "message", "message": "Body."}, + { + "type": "confirm", + "name": "show_message", + "message": "Do you want to add body message in commit?", + }, + ] + assert list(questions) == expected_questions + + def test_answer(config): cz = CustomizeCommitsCz(config) answers = { @@ -337,9 +489,42 @@ def test_answer(config): assert message == "feature:" +def test_answer_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + answers = { + "change_type": "✨ feature", + "message": "this feature enables customization through a config file", + "show_message": True, + } + message = cz.message(answers) + assert ( + message == "✨ feature: this feature enables customization through a config file" + ) + + cz = CustomizeCommitsCz(config_with_unicode) + answers = { + "change_type": "✨ feature", + "message": "this feature enables customization through a config file", + "show_message": False, + } + message = cz.message(answers) + assert message == "✨ feature:" + + def test_example(config): cz = CustomizeCommitsCz(config) - assert "feature: this feature enable customize through config file" in cz.example() + assert ( + "feature: this feature enables customization through a config file" + in cz.example() + ) + + +def test_example_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert ( + "✨ feature: this feature enables customization through a config file" + in cz.example() + ) def test_schema(config): @@ -352,11 +537,21 @@ def test_schema_pattern(config): assert r"(feature|bug fix):(\s.*)" in cz.schema_pattern() +def test_schema_pattern_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert r"(✨ feature|🐛 bug fix):(\s.*)" in cz.schema_pattern() + + def test_info(config): cz = CustomizeCommitsCz(config) assert "This is a customized cz." in cz.info() +def test_info_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert "This is a customized cz with emojis 🎉!" in cz.info() + + def test_info_with_info_path(tmpdir, config_info): with tmpdir.as_cwd(): tmpfile = tmpdir.join("info.txt") @@ -376,11 +571,28 @@ def test_commit_parser(config): assert cz.commit_parser == "^(?Pfeature|bug fix):\\s(?P.*)?" +def test_commit_parser_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert ( + cz.commit_parser == "^(?P✨ feature|🐛 bug fix):\\s(?P.*)?" + ) + + def test_changelog_pattern(config): cz = CustomizeCommitsCz(config) assert cz.changelog_pattern == "^(feature|bug fix)?(!)?" +def test_changelog_pattern_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert cz.changelog_pattern == "^(✨ feature|🐛 bug fix)?(!)?" + + def test_change_type_map(config): cz = CustomizeCommitsCz(config) assert cz.change_type_map == {"feature": "Feat", "bug fix": "Fix"} + + +def test_change_type_map_unicode(config_with_unicode): + cz = CustomizeCommitsCz(config_with_unicode) + assert cz.change_type_map == {"✨ feature": "Feat", "🐛 bug fix": "Fix"} From c480d899166c3e9c26d2f4208f8670380e52167d Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Tue, 6 Dec 2022 22:05:48 -0800 Subject: [PATCH 03/10] fix: use base config for encoding Also, use `utf-8` by default on Windows in `out.py`. --- commitizen/config/base_config.py | 3 ++- commitizen/config/json_config.py | 1 - commitizen/config/toml_config.py | 1 - commitizen/config/yaml_config.py | 1 - commitizen/out.py | 3 +++ 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/commitizen/config/base_config.py b/commitizen/config/base_config.py index 3762b30589..e700676753 100644 --- a/commitizen/config/base_config.py +++ b/commitizen/config/base_config.py @@ -8,7 +8,8 @@ class BaseConfig: def __init__(self): self._settings: Settings = DEFAULT_SETTINGS.copy() - self._path: Path | None = None + self.encoding = self.settings["encoding"] + self._path: Optional[Path] = None @property def settings(self) -> Settings: diff --git a/commitizen/config/json_config.py b/commitizen/config/json_config.py index e081d26643..a22d3485db 100644 --- a/commitizen/config/json_config.py +++ b/commitizen/config/json_config.py @@ -12,7 +12,6 @@ class JsonConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super(JsonConfig, self).__init__() - self.encoding = self.settings["encoding"] self.is_empty_config = False self.add_path(path) self._parse_setting(data) diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index faa0e8b33d..1c8ea8ef61 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -11,7 +11,6 @@ class TomlConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super(TomlConfig, self).__init__() - self.encoding = self.settings["encoding"] self.is_empty_config = False self._parse_setting(data) self.add_path(path) diff --git a/commitizen/config/yaml_config.py b/commitizen/config/yaml_config.py index 1bdb1c7355..5863aaa7b5 100644 --- a/commitizen/config/yaml_config.py +++ b/commitizen/config/yaml_config.py @@ -12,7 +12,6 @@ class YAMLConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super(YAMLConfig, self).__init__() - self.encoding = self.settings["encoding"] self.is_empty_config = False self._parse_setting(data) self.add_path(path) diff --git a/commitizen/out.py b/commitizen/out.py index 811fe09c9f..2ff29d692a 100644 --- a/commitizen/out.py +++ b/commitizen/out.py @@ -2,6 +2,9 @@ from termcolor import colored +if sys.platform == "win32": + sys.stdout.reconfigure(encoding="utf-8") + def write(value: str, *args) -> None: """Intended to be used when value is multiline.""" From be49729cc06da0a6c3f8ede21ddd0ab87cca4c8e Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Fri, 7 Jul 2023 13:55:57 -0700 Subject: [PATCH 04/10] fix: correct type hinting --- commitizen/bump.py | 4 ++-- commitizen/changelog.py | 2 +- commitizen/commands/changelog.py | 8 +++++--- commitizen/config/base_config.py | 2 +- commitizen/out.py | 3 ++- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/commitizen/bump.py b/commitizen/bump.py index 285c6b4e9c..42becbd0c8 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -47,7 +47,7 @@ def find_increment( def update_version_in_files( current_version: str, new_version: str, - files: List[str], + files: list[str], encoding: str, *, check_consistency=False, @@ -92,7 +92,7 @@ def _bump_with_regex( new_version: str, regex: str, encoding: str, -) -> Tuple[bool, str]: +) -> tuple[bool, str]: current_version_found = False lines = [] pattern = re.compile(regex) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 59bdfca1d5..820b926f68 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -227,7 +227,7 @@ def get_metadata(filepath: str, scheme: VersionScheme = Pep440) -> dict: "latest_version_position": None, } - with open(filepath, "r", encoding=encoding) as changelog_file: + with open(filepath, "r") as changelog_file: for index, line in enumerate(changelog_file): line = line.strip().lower() diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 7015cab1b8..be1c6c8c24 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -101,9 +101,9 @@ def write_changelog( f"or the setting `changelog_file` in {self.config.path}" ) - changelog_hook: Optional[Callable] = self.cz.changelog_hook + changelog_hook: Callable | None = self.cz.changelog_hook with smart_open(self.file_name, "w", encoding=self.encoding) as changelog_file: - partial_changelog: Optional[str] = None + partial_changelog: str | None = None if self.incremental: new_lines = changelog.incremental_build( changelog_out, lines, changelog_meta @@ -143,7 +143,9 @@ def __call__(self): end_rev = "" if self.incremental: changelog_meta = changelog.get_metadata( - self.file_name, self.scheme, self.encoding + self.file_name, + self.scheme, + self.encoding, ) latest_version = changelog_meta.get("latest_version") if latest_version: diff --git a/commitizen/config/base_config.py b/commitizen/config/base_config.py index e700676753..478691aa14 100644 --- a/commitizen/config/base_config.py +++ b/commitizen/config/base_config.py @@ -9,7 +9,7 @@ class BaseConfig: def __init__(self): self._settings: Settings = DEFAULT_SETTINGS.copy() self.encoding = self.settings["encoding"] - self._path: Optional[Path] = None + self._path: Path | None = None @property def settings(self) -> Settings: diff --git a/commitizen/out.py b/commitizen/out.py index 2ff29d692a..9d6ae63043 100644 --- a/commitizen/out.py +++ b/commitizen/out.py @@ -3,7 +3,8 @@ from termcolor import colored if sys.platform == "win32": - sys.stdout.reconfigure(encoding="utf-8") + # See: https://github.com/python/typeshed/issues/3049 + sys.stdout.reconfigure(encoding="utf-8") # type: ignore def write(value: str, *args) -> None: From 3aef21db1b1454a1eed0cdc5975d90e833ff88e0 Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Fri, 7 Jul 2023 14:09:02 -0700 Subject: [PATCH 05/10] feat(changelog.py): add encoding to get_metadata --- commitizen/changelog.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 820b926f68..12cb2058b0 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -213,7 +213,9 @@ def parse_title_type_of_line(value: str) -> str | None: return m.groupdict().get("title") -def get_metadata(filepath: str, scheme: VersionScheme = Pep440) -> dict: +def get_metadata( + filepath: str, scheme: VersionScheme = Pep440, encoding: str = "utf-8" +) -> dict: unreleased_start: int | None = None unreleased_end: int | None = None unreleased_title: str | None = None @@ -227,7 +229,7 @@ def get_metadata(filepath: str, scheme: VersionScheme = Pep440) -> dict: "latest_version_position": None, } - with open(filepath, "r") as changelog_file: + with open(filepath, "r", encoding=encoding) as changelog_file: for index, line in enumerate(changelog_file): line = line.strip().lower() From e4611e2bb13993a43be68cd99f5867b0d852a2a2 Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Fri, 7 Jul 2023 17:25:35 -0700 Subject: [PATCH 06/10] fix(out.py): `TextIOWrapper.reconfigure` typing See https://github.com/python/typeshed/issues/3049 --- commitizen/out.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/commitizen/out.py b/commitizen/out.py index 9d6ae63043..3801ad4c15 100644 --- a/commitizen/out.py +++ b/commitizen/out.py @@ -1,10 +1,11 @@ +import io import sys from termcolor import colored if sys.platform == "win32": - # See: https://github.com/python/typeshed/issues/3049 - sys.stdout.reconfigure(encoding="utf-8") # type: ignore + if isinstance(sys.stdout, io.TextIOWrapper) and sys.version_info >= (3, 7): + sys.stdout.reconfigure(encoding="utf-8") def write(value: str, *args) -> None: From a588dfdd1f106d85c299e90ddb1be39fdbeef38d Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Mon, 10 Jul 2023 10:51:29 -0700 Subject: [PATCH 07/10] refactor(defaults.py): use variables in `DEFAULT_SETTINGS` Map `"encoding"` and `"name"` to `encoding` and `name` variables, respectively (removes hard-coding of values). --- commitizen/defaults.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index ea48e49437..37024e9be5 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -70,7 +70,7 @@ class Settings(TypedDict, total=False): encoding: str = "utf-8" DEFAULT_SETTINGS: Settings = { - "name": "cz_conventional_commits", + "name": name, "version": None, "version_files": [], "version_provider": "commitizen", @@ -95,7 +95,7 @@ class Settings(TypedDict, total=False): "pre_bump_hooks": [], "post_bump_hooks": [], "prerelease_offset": 0, - "encoding": "utf-8", + "encoding": encoding, } MAJOR = "MAJOR" From 10c2b798d7fc4078db46853a81037875da63a840 Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Mon, 10 Jul 2023 11:12:19 -0700 Subject: [PATCH 08/10] docs: add encoding configuration --- docs/config.md | 9 +++++++++ docs/tutorials/writing_commits.md | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/docs/config.md b/docs/config.md index fdd0ae2460..cb377caf06 100644 --- a/docs/config.md +++ b/docs/config.md @@ -184,6 +184,14 @@ Default: `[]` Calls the hook scripts **after** bumping the version. [Read more][post_bump_hooks] +### `encoding` + +Type: `str` + +Default: `utf-8` + +Sets the character encoding to be used when parsing commit messages. [Read more][encoding] + ## Configuration file ### pyproject.toml or .cz.toml @@ -357,3 +365,4 @@ setup( [customization]: customization.md [shortcuts]: customization.md#shortcut-keys [annotated-tags-vs-lightweight]: https://stackoverflow.com/a/11514139/2047185 +[encoding]: tutorials/writing_commits.md#writing-commits diff --git a/docs/tutorials/writing_commits.md b/docs/tutorials/writing_commits.md index dbeee66db8..9ba151cc37 100644 --- a/docs/tutorials/writing_commits.md +++ b/docs/tutorials/writing_commits.md @@ -23,6 +23,8 @@ Now to the important part, when writing commits, it's important to think about: You may think this is trivial, but it's not. It's important for the reader to understand what happened. +Emojis may be added as well (e.g. see [cz-emoji][cz_emoji]), which requires the `utf-8`, or equivalent, character encoding to support unicode characters. By default, `commitizen` uses the `utf-8` character encoding, but a different encoding may be set through the `encoding` [configuration option][configuration]. + ### Recommendations - **Keep the message short**: Makes the list of commits more readable (~50 chars). @@ -40,3 +42,5 @@ understand what happened. [customization]: ../customization.md [conventional_commits]: https://www.conventionalcommits.org +[cz_emoji]: https://commitizen-tools.github.io/commitizen/third-party-commitizen/#cz-emoji +[configuration]: ../config.md#encoding From 8563db03d0b79a4a7ae9c022557c8914d8501b73 Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Tue, 25 Jul 2023 12:46:34 -0700 Subject: [PATCH 09/10] fix: add missing `encoding` parameter Add `encoding` parameter to `open` and `smart_open` method calls where missed. Use `defaults.encoding` as default. --- commitizen/bump.py | 8 ++++---- commitizen/changelog.py | 3 ++- commitizen/changelog_parser.py | 4 +++- commitizen/commands/bump.py | 6 +++--- commitizen/commands/changelog.py | 2 +- commitizen/commands/commit.py | 2 +- tests/test_changelog_parser.py | 12 +++++++++--- 7 files changed, 23 insertions(+), 14 deletions(-) diff --git a/commitizen/bump.py b/commitizen/bump.py index 42becbd0c8..504aa87478 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -5,7 +5,7 @@ from collections import OrderedDict from string import Template -from commitizen.defaults import MAJOR, MINOR, PATCH, bump_message +from commitizen.defaults import MAJOR, MINOR, PATCH, bump_message, encoding from commitizen.exceptions import CurrentVersionNotFoundError from commitizen.git import GitCommit, smart_open from commitizen.version_schemes import DEFAULT_SCHEME, Version, VersionScheme @@ -48,9 +48,9 @@ def update_version_in_files( current_version: str, new_version: str, files: list[str], - encoding: str, *, check_consistency=False, + encoding: str = encoding, ) -> None: """Change old version to the new one in every file given. @@ -71,7 +71,7 @@ def update_version_in_files( current_version, new_version, regex, - encoding, + encoding=encoding, ) if check_consistency and not current_version_found: @@ -91,7 +91,7 @@ def _bump_with_regex( current_version: str, new_version: str, regex: str, - encoding: str, + encoding: str = encoding, ) -> tuple[bool, str]: current_version_found = False lines = [] diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 12cb2058b0..d500110dc0 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -36,6 +36,7 @@ from commitizen import out from commitizen.bump import normalize_tag +from commitizen.defaults import encoding from commitizen.exceptions import InvalidConfigurationError, NoCommitsFoundError from commitizen.git import GitCommit, GitTag from commitizen.version_schemes import ( @@ -214,7 +215,7 @@ def parse_title_type_of_line(value: str) -> str | None: def get_metadata( - filepath: str, scheme: VersionScheme = Pep440, encoding: str = "utf-8" + filepath: str, scheme: VersionScheme = Pep440, encoding: str = encoding ) -> dict: unreleased_start: int | None = None unreleased_end: int | None = None diff --git a/commitizen/changelog_parser.py b/commitizen/changelog_parser.py index 7e37b0eef2..51348d347c 100644 --- a/commitizen/changelog_parser.py +++ b/commitizen/changelog_parser.py @@ -13,6 +13,8 @@ from collections import defaultdict from typing import Generator, Iterable +from commitizen.defaults import encoding + MD_VERSION_RE = r"^##\s(?P[a-zA-Z0-9.+]+)\s?\(?(?P[0-9-]+)?\)?" MD_CHANGE_TYPE_RE = r"^###\s(?P[a-zA-Z0-9.+\s]+)" MD_MESSAGE_RE = ( @@ -36,7 +38,7 @@ ] -def find_version_blocks(filepath: str, encoding: str) -> Generator: +def find_version_blocks(filepath: str, encoding: str = encoding) -> Generator: """Find version block (version block: contains all the information about a version.) E.g: diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 5896964ffb..8e67014149 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -1,8 +1,8 @@ from __future__ import annotations import os -from logging import getLogger import warnings +from logging import getLogger import questionary @@ -23,7 +23,7 @@ NoVersionSpecifiedError, ) from commitizen.providers import get_provider -from commitizen.version_schemes import get_version_scheme, InvalidVersion +from commitizen.version_schemes import InvalidVersion, get_version_scheme logger = getLogger("commitizen") @@ -298,8 +298,8 @@ def __call__(self): # noqa: C901 str(current_version), str(new_version), version_files, - self.encoding, check_consistency=self.check_consistency, + encoding=self.encoding, ) provider.set_version(str(new_version)) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index be1c6c8c24..3e167099b7 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -145,7 +145,7 @@ def __call__(self): changelog_meta = changelog.get_metadata( self.file_name, self.scheme, - self.encoding, + encoding=self.encoding, ) latest_version = changelog_meta.get("latest_version") if latest_version: diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 85512d3473..67a7797b4e 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -83,7 +83,7 @@ def __call__(self): out.info(f"\n{m}\n") if write_message_to_file: - with smart_open(write_message_to_file, "w") as file: + with smart_open(write_message_to_file, "w", encoding=self.encoding) as file: file.write(m) if dry_run: diff --git a/tests/test_changelog_parser.py b/tests/test_changelog_parser.py index 75f6788a8d..9145934131 100644 --- a/tests/test_changelog_parser.py +++ b/tests/test_changelog_parser.py @@ -47,7 +47,9 @@ def existing_changelog_file(tmpdir): def test_read_changelog_blocks(existing_changelog_file): - blocks = changelog_parser.find_version_blocks(existing_changelog_file, "utf-8") + blocks = changelog_parser.find_version_blocks( + existing_changelog_file, encoding="utf-8" + ) blocks = list(blocks) amount_of_blocks = len(blocks) assert amount_of_blocks == 2 @@ -127,7 +129,9 @@ def test_transform_change_type_fail(): def test_generate_block_tree(existing_changelog_file): - blocks = changelog_parser.find_version_blocks(existing_changelog_file, "utf-8") + blocks = changelog_parser.find_version_blocks( + existing_changelog_file, encoding="utf-8" + ) block = next(blocks) tree = changelog_parser.generate_block_tree(block) assert tree == { @@ -157,7 +161,9 @@ def test_generate_block_tree(existing_changelog_file): def test_generate_full_tree(existing_changelog_file): - blocks = changelog_parser.find_version_blocks(existing_changelog_file, "utf-8") + blocks = changelog_parser.find_version_blocks( + existing_changelog_file, encoding="utf-8" + ) tree = list(changelog_parser.generate_full_tree(blocks)) assert tree == [ From ecc3365927378dddb0c7ec127ab3ceff18e9c5c4 Mon Sep 17 00:00:00 2001 From: Adam Hendry Date: Mon, 31 Jul 2023 14:38:26 -0700 Subject: [PATCH 10/10] style(bump.py): add type hinting to `update_version_in_files` --- commitizen/bump.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/bump.py b/commitizen/bump.py index 504aa87478..979d066033 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -49,7 +49,7 @@ def update_version_in_files( new_version: str, files: list[str], *, - check_consistency=False, + check_consistency: bool = False, encoding: str = encoding, ) -> None: """Change old version to the new one in every file given.