diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml
index 6aa1a75e2e..11f509b5b8 100644
--- a/.github/workflows/docspublish.yml
+++ b/.github/workflows/docspublish.yml
@@ -31,8 +31,10 @@ jobs:
token: ${{ secrets.PERSONAL_ACCESS_TOKEN_FOR_ORG }}
file: 'docs/README.md'
- name: Push doc to Github Page
- uses: peaceiris/actions-gh-pages@v2
- env:
- PERSONAL_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
- PUBLISH_BRANCH: gh-pages
- PUBLISH_DIR: ./site
+ uses: peaceiris/actions-gh-pages@v4
+ with:
+ personal_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
+ publish_branch: gh-pages
+ publish_dir: ./site
+ user_name: "github-actions[bot]"
+ user_email: "github-actions[bot]@users.noreply.github.com"
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 5c9623149e..20b8d08ec6 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -46,7 +46,7 @@ repos:
exclude: "poetry.lock"
- repo: https://github.com/commitizen-tools/commitizen
- rev: v3.21.3 # automatically updated by Commitizen
+ rev: v3.22.0 # automatically updated by Commitizen
hooks:
- id: commitizen
- id: commitizen-branch
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a3daec51cd..cf16e6a106 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## v3.22.0 (2024-04-11)
+
+### Feat
+
+- **cli**: add config option to specify config file path
+
## v3.21.3 (2024-03-30)
### Refactor
@@ -14,7 +20,7 @@
### Fix
-- **command-init**: "cz init" should list exisitng tag in reverse order
+- **command-init**: "cz init" should list existing tag in reverse order
## v3.21.0 (2024-03-30)
@@ -484,7 +490,7 @@
### Fix
-- **bump.py**: `CHANGELOG.md` gets git added and commited correctly
+- **bump.py**: `CHANGELOG.md` gets git added and committed correctly
## v2.33.0 (2022-09-15)
@@ -721,7 +727,7 @@
### Fix
-- **bump**: raise non zero error code when there's no elegible commit to bump
+- **bump**: raise non zero error code when there's no eligible commit to bump
## v2.20.3 (2021-12-20)
@@ -771,7 +777,7 @@
### Fix
-- **commit**: correct the stage checker before commiting
+- **commit**: correct the stage checker before committing
## v2.18.0 (2021-08-13)
@@ -846,7 +852,7 @@
### Fix
-- **bump**: replace all occurances that match regex
+- **bump**: replace all occurrences that match regex
- **wip**: add test for current breaking change
## v2.17.1 (2021-04-08)
@@ -1079,7 +1085,7 @@
### BREAKING CHANGE
- setup.cfg, .cz and .cz.cfg are no longer supported
-- Use "cz verion" instead
+- Use "cz version" instead
- "cz --debug" will no longer work
#47
@@ -1226,7 +1232,7 @@
- **changelog**: add incremental flag
- **commands/changelog**: make changelog_file an option in config
- **commands/changelog**: exit when there is no commit exists
-- **commands/changlog**: add --start-rev argument to `cz changelog`
+- **commands/changelog**: add --start-rev argument to `cz changelog`
- **changelog**: generate changelog based on git log
- **commands/changelog**: generate changelog_tree from all past commits
- **cz/conventinal_commits**: add changelog_map, changelog_pattern and implement process_commit
@@ -1369,7 +1375,7 @@
- **cmd**: reimplement how cmd is run
- **git**: Use GitCommit, GitTag object to store commit and git information
- **git**: make arguments other then start and end in get_commit keyword arguments
-- **git**: Change get_commits into returning commits instead of lines of messsages
+- **git**: Change get_commits into returning commits instead of lines of messages
## v1.15.1 (2020-01-20)
@@ -1459,7 +1465,7 @@
- **config**: handle empty config file
- **config**: fix load global_conf even if it doesn't exist
-- **config/ini_config**: replase outdated _parse_ini_settings with _parse_settings
+- **config/ini_config**: replace outdated _parse_ini_settings with _parse_settings
### Refactor
@@ -1515,8 +1521,8 @@
### Fix
-- commit dry-run doesnt require staging to be clean
-- **scripts**: add back the delelte poetry prefix
+- commit dry-run doesn't require staging to be clean
+- **scripts**: add back the delete poetry prefix
- correct typo to spell "convention"
- removing folder in windows throwing a PermissionError
- **test_cli**: testing the version command
@@ -1524,7 +1530,7 @@
### Refactor
- **config**: remove has_pyproject which is no longer used
-- **cz/customize**: make jinja2 a custom requirement. if not installed use string.Tempalte instead
+- **cz/customize**: make jinja2 a custom requirement. if not installed use string.Template instead
- **cz/utils**: rename filters as utils
- **cli**: add back --version and remove subcommand required constraint
@@ -1636,7 +1642,7 @@
- update given files with new version
- **config**: new set key, used to set version to cfg
- support for pyproject.toml
-- first semantic version bump implementaiton
+- first semantic version bump implementation
### Fix
@@ -1695,11 +1701,11 @@
### Fix
-- **manifest**: inluded missing files
+- **manifest**: included missing files
### Refactor
-- **conventionalCommit**: moved fitlers to questions instead of message
+- **conventionalCommit**: moved filters to questions instead of message
## v0.9.5 (2018-08-24)
@@ -1717,7 +1723,7 @@
### Feat
-- **commiter**: conventional commit is a bit more intelligent now
+- **committer**: conventional commit is a bit more intelligent now
## v0.9.2 (2017-11-11)
diff --git a/commitizen/__version__.py b/commitizen/__version__.py
index 322a27ea54..659cac322f 100644
--- a/commitizen/__version__.py
+++ b/commitizen/__version__.py
@@ -1 +1 @@
-__version__ = "3.21.3"
+__version__ = "3.22.0"
diff --git a/commitizen/cli.py b/commitizen/cli.py
index a442803d7f..cf3d6c5eef 100644
--- a/commitizen/cli.py
+++ b/commitizen/cli.py
@@ -92,6 +92,10 @@ def __call__(
),
"formatter_class": argparse.RawDescriptionHelpFormatter,
"arguments": [
+ {
+ "name": "--config",
+ "help": "the path of configuration file",
+ },
{"name": "--debug", "action": "store_true", "help": "use debug mode"},
{
"name": ["-n", "--name"],
@@ -534,9 +538,7 @@ def parse_no_raise(comma_separated_no_raise: str) -> list[int]:
def main():
- conf = config.read_cfg()
parser = cli(data)
-
argcomplete.autocomplete(parser)
# Show help if no arg provided
if len(sys.argv) == 1:
@@ -576,6 +578,11 @@ def main():
extra_args = " ".join(unknown_args[1:])
arguments["extra_cli_args"] = extra_args
+ if args.config:
+ conf = config.read_cfg(args.config)
+ else:
+ conf = config.read_cfg()
+
if args.name:
conf.update({"name": args.name})
elif not args.name and not conf.path:
diff --git a/commitizen/config/__init__.py b/commitizen/config/__init__.py
index 09e38ca96e..a9395fca7d 100644
--- a/commitizen/config/__init__.py
+++ b/commitizen/config/__init__.py
@@ -3,6 +3,7 @@
from pathlib import Path
from commitizen import defaults, git
+from commitizen.exceptions import ConfigFileNotFound, ConfigFileIsEmpty
from .base_config import BaseConfig
from .json_config import JsonConfig
@@ -10,19 +11,26 @@
from .yaml_config import YAMLConfig
-def read_cfg() -> BaseConfig:
+def read_cfg(filepath: str | None = None) -> BaseConfig:
conf = BaseConfig()
- git_project_root = git.find_git_project_root()
- cfg_search_paths = [Path(".")]
- if git_project_root:
- cfg_search_paths.append(git_project_root)
+ if filepath is not None:
+ if not Path(filepath).exists():
+ raise ConfigFileNotFound()
+
+ cfg_paths = (path for path in (Path(filepath),))
+ else:
+ git_project_root = git.find_git_project_root()
+ cfg_search_paths = [Path(".")]
+ if git_project_root:
+ cfg_search_paths.append(git_project_root)
+
+ cfg_paths = (
+ path / Path(filename)
+ for path in cfg_search_paths
+ for filename in defaults.config_files
+ )
- cfg_paths = (
- path / Path(filename)
- for path in cfg_search_paths
- for filename in defaults.config_files
- )
for filename in cfg_paths:
if not filename.exists():
continue
@@ -39,7 +47,9 @@ def read_cfg() -> BaseConfig:
elif "yaml" in filename.suffix:
_conf = YAMLConfig(data=data, path=filename)
- if _conf.is_empty_config:
+ if filepath is not None and _conf.is_empty_config:
+ raise ConfigFileIsEmpty()
+ elif _conf.is_empty_config:
continue
else:
conf = _conf
diff --git a/commitizen/exceptions.py b/commitizen/exceptions.py
index 31b867b8f9..9cb1517680 100644
--- a/commitizen/exceptions.py
+++ b/commitizen/exceptions.py
@@ -34,6 +34,8 @@ class ExitCode(enum.IntEnum):
VERSION_PROVIDER_UNKNOWN = 27
VERSION_SCHEME_UNKNOWN = 28
CHANGELOG_FORMAT_UNKNOWN = 29
+ CONFIG_FILE_NOT_FOUND = 30
+ CONFIG_FILE_IS_EMPTY = 31
class CommitizenException(Exception):
@@ -189,3 +191,13 @@ class VersionSchemeUnknown(CommitizenException):
class ChangelogFormatUnknown(CommitizenException):
exit_code = ExitCode.CHANGELOG_FORMAT_UNKNOWN
message = "Unknown changelog format identifier"
+
+
+class ConfigFileNotFound(CommitizenException):
+ exit_code = ExitCode.CONFIG_FILE_NOT_FOUND
+ message = "Cannot found the config file, please check your file path again."
+
+
+class ConfigFileIsEmpty(CommitizenException):
+ exit_code = ExitCode.CONFIG_FILE_IS_EMPTY
+ message = "Config file is empty, please check your file path again."
diff --git a/docs/README.md b/docs/README.md
index e48062e168..8c7dc51e48 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -107,6 +107,7 @@ For more information about the topic go to https://conventionalcommits.org/
optional arguments:
-h, --help show this help message and exit
+ --config the path of configuration file
--debug use debug mode
-n NAME, --name NAME use the given commitizen (default: cz_conventional_commits)
-nr NO_RAISE, --no-raise NO_RAISE
diff --git a/docs/images/bump.gif b/docs/images/bump.gif
index f9c9e0c8a3..0e97550ade 100644
Binary files a/docs/images/bump.gif and b/docs/images/bump.gif differ
diff --git a/docs/images/cli_help/cz___help.svg b/docs/images/cli_help/cz___help.svg
new file mode 100644
index 0000000000..07b23d558f
--- /dev/null
+++ b/docs/images/cli_help/cz___help.svg
@@ -0,0 +1,198 @@
+
diff --git a/docs/images/cli_help/cz_bump___help.svg b/docs/images/cli_help/cz_bump___help.svg
new file mode 100644
index 0000000000..18d402f16e
--- /dev/null
+++ b/docs/images/cli_help/cz_bump___help.svg
@@ -0,0 +1,373 @@
+
diff --git a/docs/images/cli_help/cz_changelog___help.svg b/docs/images/cli_help/cz_changelog___help.svg
new file mode 100644
index 0000000000..4f236ea467
--- /dev/null
+++ b/docs/images/cli_help/cz_changelog___help.svg
@@ -0,0 +1,217 @@
+
diff --git a/docs/images/cli_help/cz_check___help.svg b/docs/images/cli_help/cz_check___help.svg
new file mode 100644
index 0000000000..82dab7282e
--- /dev/null
+++ b/docs/images/cli_help/cz_check___help.svg
@@ -0,0 +1,149 @@
+
diff --git a/docs/images/cli_help/cz_commit___help.svg b/docs/images/cli_help/cz_commit___help.svg
new file mode 100644
index 0000000000..e29f55607d
--- /dev/null
+++ b/docs/images/cli_help/cz_commit___help.svg
@@ -0,0 +1,123 @@
+
diff --git a/docs/images/cli_help/cz_example___help.svg b/docs/images/cli_help/cz_example___help.svg
new file mode 100644
index 0000000000..a3fee0064a
--- /dev/null
+++ b/docs/images/cli_help/cz_example___help.svg
@@ -0,0 +1,79 @@
+
diff --git a/docs/images/cli_help/cz_info___help.svg b/docs/images/cli_help/cz_info___help.svg
new file mode 100644
index 0000000000..02c2f313df
--- /dev/null
+++ b/docs/images/cli_help/cz_info___help.svg
@@ -0,0 +1,79 @@
+
diff --git a/docs/images/cli_help/cz_init___help.svg b/docs/images/cli_help/cz_init___help.svg
new file mode 100644
index 0000000000..b296b79d76
--- /dev/null
+++ b/docs/images/cli_help/cz_init___help.svg
@@ -0,0 +1,79 @@
+
diff --git a/docs/images/cli_help/cz_ls___help.svg b/docs/images/cli_help/cz_ls___help.svg
new file mode 100644
index 0000000000..7e95d4c8dc
--- /dev/null
+++ b/docs/images/cli_help/cz_ls___help.svg
@@ -0,0 +1,79 @@
+
diff --git a/docs/images/cli_help/cz_schema___help.svg b/docs/images/cli_help/cz_schema___help.svg
new file mode 100644
index 0000000000..201778bdfd
--- /dev/null
+++ b/docs/images/cli_help/cz_schema___help.svg
@@ -0,0 +1,79 @@
+
diff --git a/docs/images/cli_help/cz_version___help.svg b/docs/images/cli_help/cz_version___help.svg
new file mode 100644
index 0000000000..0a7dc85397
--- /dev/null
+++ b/docs/images/cli_help/cz_version___help.svg
@@ -0,0 +1,99 @@
+
diff --git a/docs/images/demo.gif b/docs/images/demo.gif
index 0f2b9f2487..39dcdc9e91 100644
Binary files a/docs/images/demo.gif and b/docs/images/demo.gif differ
diff --git a/docs/images/init.gif b/docs/images/init.gif
new file mode 100644
index 0000000000..f2cdf6b310
Binary files /dev/null and b/docs/images/init.gif differ
diff --git a/docs/init.md b/docs/init.md
index f818dac62f..778a79f529 100644
--- a/docs/init.md
+++ b/docs/init.md
@@ -1,3 +1,5 @@
+
+
To start using commitizen, the recommended approach is to run
```sh
@@ -16,3 +18,4 @@ The `init` will help you with
5. Choosing a version type (`semver` or `pep440`)
6. Whether to create the changelog automatically or not during bump
7. Whether you want to keep the major as zero while building alpha software.
+8. Whether to setup pre-commit hooks.
diff --git a/poetry.lock b/poetry.lock
index 2d49e41b5a..4cc8f16674 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]]
name = "appnope"
@@ -617,6 +617,30 @@ importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"]
testing = ["coverage", "pyyaml"]
+[[package]]
+name = "markdown-it-py"
+version = "3.0.0"
+description = "Python port of markdown-it. Markdown parsing, done right!"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
+ {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
+]
+
+[package.dependencies]
+mdurl = ">=0.1,<1.0"
+
+[package.extras]
+benchmarking = ["psutil", "pytest", "pytest-benchmark"]
+code-style = ["pre-commit (>=3.0,<4.0)"]
+compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"]
+linkify = ["linkify-it-py (>=1,<3)"]
+plugins = ["mdit-py-plugins"]
+profiling = ["gprof2dot"]
+rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
+testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
+
[[package]]
name = "markupsafe"
version = "2.1.3"
@@ -700,6 +724,17 @@ files = [
[package.dependencies]
traitlets = "*"
+[[package]]
+name = "mdurl"
+version = "0.1.2"
+description = "Markdown URL utilities"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
+ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
+]
+
[[package]]
name = "mergedeep"
version = "1.3.4"
@@ -744,13 +779,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp
[[package]]
name = "mkdocs-material"
-version = "9.5.15"
+version = "9.5.17"
description = "Documentation that simply works"
optional = false
python-versions = ">=3.8"
files = [
- {file = "mkdocs_material-9.5.15-py3-none-any.whl", hash = "sha256:e5c96dec3d19491de49ca643fc1dbb92b278e43cdb816c775bc47db77d9b62fb"},
- {file = "mkdocs_material-9.5.15.tar.gz", hash = "sha256:39f03cca45e82bf54eb7456b5a18bd252eabfdd67f237a229471484a0a4d4635"},
+ {file = "mkdocs_material-9.5.17-py3-none-any.whl", hash = "sha256:14a2a60119a785e70e765dd033e6211367aca9fc70230e577c1cf6a326949571"},
+ {file = "mkdocs_material-9.5.17.tar.gz", hash = "sha256:06ae1275a72db1989cf6209de9e9ecdfbcfdbc24c58353877b2bb927dbe413e4"},
]
[package.dependencies]
@@ -1405,30 +1440,49 @@ urllib3 = ">=1.21.1,<3"
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+[[package]]
+name = "rich"
+version = "13.7.1"
+description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"},
+ {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"},
+]
+
+[package.dependencies]
+markdown-it-py = ">=2.2.0"
+pygments = ">=2.13.0,<3.0.0"
+typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""}
+
+[package.extras]
+jupyter = ["ipywidgets (>=7.5.1,<9)"]
+
[[package]]
name = "ruff"
-version = "0.3.4"
+version = "0.3.5"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
- {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:60c870a7d46efcbc8385d27ec07fe534ac32f3b251e4fc44b3cbfd9e09609ef4"},
- {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6fc14fa742e1d8f24910e1fff0bd5e26d395b0e0e04cc1b15c7c5e5fe5b4af91"},
- {file = "ruff-0.3.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3ee7880f653cc03749a3bfea720cf2a192e4f884925b0cf7eecce82f0ce5854"},
- {file = "ruff-0.3.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf133dd744f2470b347f602452a88e70dadfbe0fcfb5fd46e093d55da65f82f7"},
- {file = "ruff-0.3.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3860057590e810c7ffea75669bdc6927bfd91e29b4baa9258fd48b540a4365"},
- {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:986f2377f7cf12efac1f515fc1a5b753c000ed1e0a6de96747cdf2da20a1b369"},
- {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fd98e85869603e65f554fdc5cddf0712e352fe6e61d29d5a6fe087ec82b76c"},
- {file = "ruff-0.3.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64abeed785dad51801b423fa51840b1764b35d6c461ea8caef9cf9e5e5ab34d9"},
- {file = "ruff-0.3.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df52972138318bc7546d92348a1ee58449bc3f9eaf0db278906eb511889c4b50"},
- {file = "ruff-0.3.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:98e98300056445ba2cc27d0b325fd044dc17fcc38e4e4d2c7711585bd0a958ed"},
- {file = "ruff-0.3.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:519cf6a0ebed244dce1dc8aecd3dc99add7a2ee15bb68cf19588bb5bf58e0488"},
- {file = "ruff-0.3.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bb0acfb921030d00070539c038cd24bb1df73a2981e9f55942514af8b17be94e"},
- {file = "ruff-0.3.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cf187a7e7098233d0d0c71175375c5162f880126c4c716fa28a8ac418dcf3378"},
- {file = "ruff-0.3.4-py3-none-win32.whl", hash = "sha256:af27ac187c0a331e8ef91d84bf1c3c6a5dea97e912a7560ac0cef25c526a4102"},
- {file = "ruff-0.3.4-py3-none-win_amd64.whl", hash = "sha256:de0d5069b165e5a32b3c6ffbb81c350b1e3d3483347196ffdf86dc0ef9e37dd6"},
- {file = "ruff-0.3.4-py3-none-win_arm64.whl", hash = "sha256:6810563cc08ad0096b57c717bd78aeac888a1bfd38654d9113cb3dc4d3f74232"},
- {file = "ruff-0.3.4.tar.gz", hash = "sha256:f0f4484c6541a99862b693e13a151435a279b271cff20e37101116a21e2a1ad1"},
+ {file = "ruff-0.3.5-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:aef5bd3b89e657007e1be6b16553c8813b221ff6d92c7526b7e0227450981eac"},
+ {file = "ruff-0.3.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:89b1e92b3bd9fca249153a97d23f29bed3992cff414b222fcd361d763fc53f12"},
+ {file = "ruff-0.3.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e55771559c89272c3ebab23326dc23e7f813e492052391fe7950c1a5a139d89"},
+ {file = "ruff-0.3.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dabc62195bf54b8a7876add6e789caae0268f34582333cda340497c886111c39"},
+ {file = "ruff-0.3.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a05f3793ba25f194f395578579c546ca5d83e0195f992edc32e5907d142bfa3"},
+ {file = "ruff-0.3.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:dfd3504e881082959b4160ab02f7a205f0fadc0a9619cc481982b6837b2fd4c0"},
+ {file = "ruff-0.3.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87258e0d4b04046cf1d6cc1c56fadbf7a880cc3de1f7294938e923234cf9e498"},
+ {file = "ruff-0.3.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:712e71283fc7d9f95047ed5f793bc019b0b0a29849b14664a60fd66c23b96da1"},
+ {file = "ruff-0.3.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a532a90b4a18d3f722c124c513ffb5e5eaff0cc4f6d3aa4bda38e691b8600c9f"},
+ {file = "ruff-0.3.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:122de171a147c76ada00f76df533b54676f6e321e61bd8656ae54be326c10296"},
+ {file = "ruff-0.3.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d80a6b18a6c3b6ed25b71b05eba183f37d9bc8b16ace9e3d700997f00b74660b"},
+ {file = "ruff-0.3.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7b6e63194c68bca8e71f81de30cfa6f58ff70393cf45aab4c20f158227d5936"},
+ {file = "ruff-0.3.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a759d33a20c72f2dfa54dae6e85e1225b8e302e8ac655773aff22e542a300985"},
+ {file = "ruff-0.3.5-py3-none-win32.whl", hash = "sha256:9d8605aa990045517c911726d21293ef4baa64f87265896e491a05461cae078d"},
+ {file = "ruff-0.3.5-py3-none-win_amd64.whl", hash = "sha256:dc56bb16a63c1303bd47563c60482a1512721053d93231cf7e9e1c6954395a0e"},
+ {file = "ruff-0.3.5-py3-none-win_arm64.whl", hash = "sha256:faeeae9905446b975dcf6d4499dc93439b131f1443ee264055c5716dd947af55"},
+ {file = "ruff-0.3.5.tar.gz", hash = "sha256:a067daaeb1dc2baf9b82a32dae67d154d95212080c80435eb052d95da647763d"},
]
[[package]]
@@ -1574,13 +1628,13 @@ files = [
[[package]]
name = "typing-extensions"
-version = "4.10.0"
+version = "4.11.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
- {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
- {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
+ {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"},
+ {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"},
]
[[package]]
@@ -1766,4 +1820,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = ">=3.8"
-content-hash = "614f9b1db867d5b7f954c318309b0e7b18951ed7be6d8016af79a08b8c2c7a89"
+content-hash = "5cd809db4e9dc8005ab2295ca7d182435021752953a7b1552bb81912b54df791"
diff --git a/pyproject.toml b/pyproject.toml
index d1e03c436e..b6d766ef19 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,5 +1,5 @@
[tool.commitizen]
-version = "3.21.3"
+version = "3.22.0"
tag_format = "v$version"
version_files = [
"pyproject.toml:version",
@@ -9,7 +9,7 @@ version_files = [
[tool.poetry]
name = "commitizen"
-version = "3.21.3"
+version = "3.22.0"
description = "Python commitizen client tool"
authors = ["Santiago Fraire "]
license = "MIT"
@@ -73,6 +73,7 @@ mkdocs-material = "^9.1.6"
deprecated = "^1.2.13"
types-deprecated = "^1.2.9.2"
types-python-dateutil = "^2.8.19.13"
+rich = "^13.7.1"
[tool.poetry.scripts]
diff --git a/scripts/gen_cli_help_screenshots.py b/scripts/gen_cli_help_screenshots.py
new file mode 100644
index 0000000000..0706612391
--- /dev/null
+++ b/scripts/gen_cli_help_screenshots.py
@@ -0,0 +1,42 @@
+import os
+import subprocess
+from pathlib import Path
+
+from rich.console import Console
+
+from commitizen.cli import data
+
+project_root = Path(__file__).parent.parent.absolute()
+images_root = project_root / Path("docs") / Path("images") / Path("cli_help")
+
+
+def gen_cli_help_screenshots() -> None:
+ """Generate the screenshot for help message on each cli command and save them as svg files."""
+ if not os.path.exists(images_root):
+ os.makedirs(images_root)
+ print(f"Created {images_root}")
+
+ help_cmds = _list_help_cmds()
+ for cmd in help_cmds:
+ file_name = f"{cmd.replace(' ', '_').replace('-', '_')}.svg"
+ _export_cmd_as_svg(cmd, f"{images_root}/{file_name}")
+
+
+def _list_help_cmds() -> list[str]:
+ cmds = [f"{data['prog']} --help"] + [
+ f"{data['prog']} {sub_c['name'] if isinstance(sub_c['name'], str) else sub_c['name'][0]} --help"
+ for sub_c in data["subcommands"]["commands"]
+ ]
+
+ return cmds
+
+
+def _export_cmd_as_svg(cmd: str, file_name: str) -> None:
+ stdout = subprocess.run(cmd, shell=True, capture_output=True).stdout.decode("utf-8")
+ console = Console(record=True, width=80)
+ console.print(f"$ {cmd}\n{stdout}")
+ console.save_svg(file_name, title="")
+
+
+if __name__ == "__main__":
+ gen_cli_help_screenshots()
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 93f6c16ddd..345f0b1b00 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -12,6 +12,7 @@
NoCommandFoundError,
NotAGitProjectError,
InvalidCommandArgumentError,
+ ConfigFileNotFound,
)
@@ -25,6 +26,15 @@ def test_sysexit_no_argv(mocker: MockFixture, capsys):
assert out.startswith("usage")
+def test_cz_config_file_without_correct_file_path(mocker: MockFixture, capsys):
+ testargs = ["cz", "--config", "./config/pyproject.toml", "example"]
+ mocker.patch.object(sys, "argv", testargs)
+
+ with pytest.raises(ConfigFileNotFound) as excinfo:
+ cli.main()
+ assert "Cannot found the config file" in str(excinfo.value)
+
+
def test_cz_with_arg_but_without_command(mocker: MockFixture):
testargs = ["cz", "--name", "cz_jira"]
mocker.patch.object(sys, "argv", testargs)
diff --git a/tests/test_conf.py b/tests/test_conf.py
index a12bcdd35d..786f12b36b 100644
--- a/tests/test_conf.py
+++ b/tests/test_conf.py
@@ -9,7 +9,7 @@
import yaml
from commitizen import config, defaults, git
-from commitizen.exceptions import InvalidConfigurationError
+from commitizen.exceptions import InvalidConfigurationError, ConfigFileIsEmpty
PYPROJECT = """
[tool.commitizen]
@@ -44,6 +44,27 @@
}
}
+JSON_STR = r"""
+ {
+ "commitizen": {
+ "name": "cz_jira",
+ "version": "1.0.0",
+ "version_files": [
+ "commitizen/__version__.py",
+ "pyproject.toml"
+ ]
+ }
+ }
+"""
+
+YAML_STR = """
+commitizen:
+ name: cz_jira
+ version: 1.0.0
+ version_files:
+ - commitizen/__version__.py
+ - pyproject.toml
+"""
_settings: dict[str, Any] = {
"name": "cz_jira",
@@ -158,6 +179,40 @@ def test_load_empty_pyproject_toml_and_cz_toml_with_config(_, tmpdir):
cfg = config.read_cfg()
assert cfg.settings == _settings
+ def test_load_pyproject_toml_from_config_argument(_, tmpdir):
+ with tmpdir.as_cwd():
+ _not_root_path = tmpdir.mkdir("not_in_root").join("pyproject.toml")
+ _not_root_path.write(PYPROJECT)
+
+ cfg = config.read_cfg(filepath="./not_in_root/pyproject.toml")
+ assert cfg.settings == _settings
+
+ def test_load_cz_json_not_from_config_argument(_, tmpdir):
+ with tmpdir.as_cwd():
+ _not_root_path = tmpdir.mkdir("not_in_root").join(".cz.json")
+ _not_root_path.write(JSON_STR)
+
+ cfg = config.read_cfg(filepath="./not_in_root/.cz.json")
+ json_cfg_by_class = config.JsonConfig(data=JSON_STR, path=_not_root_path)
+ assert cfg.settings == json_cfg_by_class.settings
+
+ def test_load_cz_yaml_not_from_config_argument(_, tmpdir):
+ with tmpdir.as_cwd():
+ _not_root_path = tmpdir.mkdir("not_in_root").join(".cz.yaml")
+ _not_root_path.write(YAML_STR)
+
+ cfg = config.read_cfg(filepath="./not_in_root/.cz.yaml")
+ yaml_cfg_by_class = config.YAMLConfig(data=YAML_STR, path=_not_root_path)
+ assert cfg.settings == yaml_cfg_by_class._settings
+
+ def test_load_empty_pyproject_toml_from_config_argument(_, tmpdir):
+ with tmpdir.as_cwd():
+ _not_root_path = tmpdir.mkdir("not_in_root").join("pyproject.toml")
+ _not_root_path.write("")
+
+ with pytest.raises(ConfigFileIsEmpty):
+ config.read_cfg(filepath="./not_in_root/pyproject.toml")
+
class TestTomlConfig:
def test_init_empty_config_content(self, tmpdir):