diff --git a/commitizen/cli.py b/commitizen/cli.py index 2ee7d41eba..4139ff1776 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -108,6 +108,12 @@ def __call__( "required": False, "help": "comma separated error codes that won't rise error, e.g: cz -nr 1,2,3 bump. See codes at https://commitizen-tools.github.io/commitizen/exit_codes/", }, + { + "name": ["-language"], + "type": str, + "default": "en", + "help": "language of the commit message (default: en). Available languages: enGLISH, frENCH. others are welcome", + }, ], "subcommands": { "title": "commands", diff --git a/commitizen/cz/conventional_commits/.cache_multilanguage.txt b/commitizen/cz/conventional_commits/.cache_multilanguage.txt new file mode 100644 index 0000000000..e896e46fe6 --- /dev/null +++ b/commitizen/cz/conventional_commits/.cache_multilanguage.txt @@ -0,0 +1,12 @@ +prefix_en=Select the type of change you are committing +fix_en=A bug fix. Correlates with PATCH in SemVer +feat_en=A new feature. Correlates with MINOR in SemVer +docs_en=Documentation only changes +style_en=Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) +refactor_en=A code change that neither fixes a bug nor adds a feature +perf_en=A code change that improves performance +test_en=Adding missing or correcting existing tests +build_en=Changes that affect the build system or external dependencies (example scopes: pip, docker, npm) +ci_en=Changes to CI configuration files and scripts (example scopes: GitLabCI) +scope_en=What is the scope of this change? (class or file name): (press [enter] to skip) +subject_en=Write a short and imperative summary of the code changes: (lower case and no period) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index dcfd7bab89..5061ad7c9a 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -3,6 +3,9 @@ from commitizen import defaults from commitizen.cz.base import BaseCommitizen +from commitizen.cz.conventional_commits.translation_multilanguage import ( + translate_text_from_eng, +) from commitizen.cz.utils import multiple_line_breaker, required_validator from commitizen.defaults import Questions @@ -40,70 +43,98 @@ class ConventionalCommitsCz(BaseCommitizen): } changelog_pattern = defaults.bump_pattern - def questions(self) -> Questions: + def questions(self, language: str) -> Questions: questions: Questions = [ { "type": "list", "name": "prefix", - "message": "Select the type of change you are committing", + "message": translate_text_from_eng( + "Select the type of change you are committing", language, "prefix" + ), "choices": [ { "value": "fix", - "name": "fix: A bug fix. Correlates with PATCH in SemVer", + "name": "fix: " + + translate_text_from_eng( + "A bug fix. Correlates with PATCH in SemVer", + language, + "fix", + ), "key": "x", }, { "value": "feat", - "name": "feat: A new feature. Correlates with MINOR in SemVer", + "name": "feat: " + + translate_text_from_eng( + "A new feature. Correlates with MINOR in SemVer", + language, + "feat", + ), "key": "f", }, { "value": "docs", - "name": "docs: Documentation only changes", + "name": "docs: " + + translate_text_from_eng( + "Documentation only changes", language, "docs" + ), "key": "d", }, { "value": "style", - "name": ( - "style: Changes that do not affect the " - "meaning of the code (white-space, formatting," - " missing semi-colons, etc)" + "name": "style: " + + translate_text_from_eng( + """Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)""", + language, + "style", ), "key": "s", }, { "value": "refactor", - "name": ( - "refactor: A code change that neither fixes " - "a bug nor adds a feature" + "name": "refactor: " + + translate_text_from_eng( + """A code change that neither fixes a bug nor adds a feature""", + language, + "refactor", ), "key": "r", }, { "value": "perf", - "name": "perf: A code change that improves performance", + "name": "perf: " + + translate_text_from_eng( + "A code change that improves performance", language, "perf" + ), "key": "p", }, { "value": "test", - "name": ( - "test: Adding missing or correcting " "existing tests" + "name": "test: " + + translate_text_from_eng( + "Adding missing or correcting existing tests", + language, + "test", ), "key": "t", }, { "value": "build", - "name": ( - "build: Changes that affect the build system or " - "external dependencies (example scopes: pip, docker, npm)" + "name": "build: " + + translate_text_from_eng( + """Changes that affect the build system or external dependencies (example scopes: pip, docker, npm)""", + language, + "build", ), "key": "b", }, { "value": "ci", - "name": ( - "ci: Changes to CI configuration files and " - "scripts (example scopes: GitLabCI)" + "name": "ci: " + + translate_text_from_eng( + """Changes to CI configuration files and scripts (example scopes: GitLabCI)""", + language, + "ci", ), "key": "c", }, @@ -112,8 +143,10 @@ def questions(self) -> Questions: { "type": "input", "name": "scope", - "message": ( - "What is the scope of this change? (class or file name): (press [enter] to skip)\n" + "message": translate_text_from_eng( + "What is the scope of this change? (class or file name): (press [enter] to skip)\n", + language, + "scope", ), "filter": parse_scope, }, @@ -121,9 +154,9 @@ def questions(self) -> Questions: "type": "input", "name": "subject", "filter": parse_subject, - "message": ( - "Write a short and imperative summary of the code changes: (lower case and no period)\n" - ), + "message": translate_text_from_eng( + "Write a short and imperative summary of the code changes: (lower case and no period)\n", + language, "subject"), }, { "type": "input", diff --git a/commitizen/cz/conventional_commits/translation_multilanguage.py b/commitizen/cz/conventional_commits/translation_multilanguage.py new file mode 100644 index 0000000000..4b1fc521de --- /dev/null +++ b/commitizen/cz/conventional_commits/translation_multilanguage.py @@ -0,0 +1,45 @@ +from translate import Translator + +FILENAME = "commitizen/cz/conventional_commits/.cache_multilanguage.txt" +MULTILANGUAGE = {} + + +def load_multilanguage(): + global MULTILANGUAGE + MULTILANGUAGE = {} + with open(FILENAME) as file: + for line in file: + if not line.strip(): + continue + key, value = line.strip().split("=", 1) + MULTILANGUAGE[key] = value + +def generate_key(original_key, to_lang): + return f"{original_key}_{to_lang}" + +def save_multilanguage(key, value): + if "\n" in value: + value = value.replace("\n", "") + with open(FILENAME, "a") as file: + file.write(f"{key}={value}\n") + +def translate_text(text, from_lang, to_lang): + translator = Translator(from_lang=from_lang, to_lang=to_lang) + translation = translator.translate(text) + return translation + +def translate_text_from_eng(text, to_lang, key): + global MULTILANGUAGE + key_generated = generate_key(key, to_lang) + if not MULTILANGUAGE: + load_multilanguage() + if key_generated in MULTILANGUAGE: + return MULTILANGUAGE[key_generated] + else: + if to_lang == "en": + MULTILANGUAGE[key_generated] = text + save_multilanguage(key_generated, MULTILANGUAGE[key_generated]) + return text + MULTILANGUAGE[key_generated] = translate_text(text, "en", to_lang) + save_multilanguage(key_generated, MULTILANGUAGE[key_generated]) + return MULTILANGUAGE[key_generated]