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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz --help +usage: cz [-h][--debug][-n NAME][-nr NO_RAISE] +{init,commit,c,ls,example,info,schema,bump,changelog,ch,check,version} +... + +Commitizen is a cli tool to generate conventional commits. +For more information about the topic go to https://conventionalcommits.org/ + +options: +  -h, --help            show this help message and exit +  --debug               use debug mode +  -n NAME, --name NAME  use the given commitizen (default: +                        cz_conventional_commits) +  -nr NO_RAISE, --no-raise NO_RAISE +                        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/ + +commands: +{init,commit,c,ls,example,info,schema,bump,changelog,ch,check,version} +    init                init commitizen configuration +    commit (c)          create new commit +    ls                  show available commitizens +    example             show commit example +    info                show information about the cz +    schema              show commit schema +    bump                bump semantic version based on the git log +    changelog (ch)      generate changelog (note that it will overwrite +                        existing file) +    check               validates that a commit message matches the commitizen +                        schema +    version             get the version of the installed commitizen or the +                        current project (default: installed commitizen) + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz bump --help +usage: cz bump [-h][--dry-run][--files-only][--local-version][--changelog] +[--no-verify][--yes][--tag-format TAG_FORMAT] +[--bump-message BUMP_MESSAGE][--prerelease {alpha,beta,rc}] +[--devrelease DEVRELEASE][--increment {MAJOR,MINOR,PATCH}] +[--increment-mode {linear,exact}][--check-consistency] +[--annotated-tag] +[--annotated-tag-message ANNOTATED_TAG_MESSAGE][--gpg-sign] +[--changelog-to-stdout][--git-output-to-stderr][--retry] +[--major-version-zero][--template TEMPLATE][--extra EXTRA] +[--file-name FILE_NAME][--prerelease-offset PRERELEASE_OFFSET] +[--version-scheme {semver,pep440}] +[--version-type {semver,pep440}] +[--build-metadata BUILD_METADATA] +[MANUAL_VERSION] + +positional arguments: +  MANUAL_VERSION        bump to the given version (e.g: 1.5.3) + +options: +  -h, --help            show this help message and exit +  --dry-run             show output to stdout, no commit, no modified files +  --files-only          bump version in the files from the config +  --local-version       bump only the local version portion +  --changelog, -ch      generate the changelog for the newest version +  --no-verify           this option bypasses the pre-commit and commit-msg +                        hooks +  --yes                 accept automatically questions done +  --tag-format TAG_FORMAT +                        the format used to tag the commit and read it, use it +                        in existing projects, wrap around simple quotes +  --bump-message BUMP_MESSAGE +                        template used to create the release commit, useful +                        when working with CI +  --prerelease {alpha,beta,rc}, -pr {alpha,beta,rc} +                        choose type of prerelease +  --devrelease DEVRELEASE, -d DEVRELEASE +                        specify non-negative integer for dev. release +  --increment {MAJOR,MINOR,PATCH} +                        manually specify the desired increment +  --increment-mode {linear,exact} +                        set the method by which the new version is chosen. +'linear'(default) guesses the next version based on +                        typical linear version progression, such that bumping +                        of a pre-release with lower precedence than the +                        current pre-release phase maintains the current phase +                        of higher precedence. 'exact' applies the changes that +                        have been specified (or determined from the commit +                        log) without interpretation, such that the increment +                        and pre-release are always honored +  --check-consistency, -cc +                        check consistency among versions defined in commitizen +                        configuration and version_files +  --annotated-tag, -at  create annotated tag instead of lightweight one +  --annotated-tag-message ANNOTATED_TAG_MESSAGE, -atm ANNOTATED_TAG_MESSAGE +                        create annotated tag message +  --gpg-sign, -s        sign tag instead of lightweight one +  --changelog-to-stdout +                        Output changelog to the stdout +  --git-output-to-stderr +                        Redirect git output to stderr +  --retry               retry commit if it fails the 1st time +  --major-version-zero  keep major version at zero, even for breaking changes +  --template TEMPLATE, -t TEMPLATE +                        changelog template file name (relative to the current +                        working directory) +  --extra EXTRA, -e EXTRA +                        a changelog extra variable (in the form 'key=value') +  --file-name FILE_NAME +                        file name of changelog (default: 'CHANGELOG.md') +  --prerelease-offset PRERELEASE_OFFSET +                        start pre-releases with this offset +  --version-scheme {semver,pep440} +                        choose version scheme +  --version-type {semver,pep440} +                        Deprecated, use --version-scheme +  --build-metadata BUILD_METADATA +                        Add additional build-metadata to the version-number + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz changelog --help +usage: cz changelog [-h][--dry-run][--file-name FILE_NAME] +[--unreleased-version UNRELEASED_VERSION][--incremental] +[--start-rev START_REV][--merge-prerelease] +[--version-scheme {pep440,semver}] +[--export-template EXPORT_TEMPLATE][--template TEMPLATE] +[--extra EXTRA] + + +positional arguments: +  rev_range             generates changelog for the given version (e.g: 1.5.3) +                        or version range (e.g: 1.5.3..1.7.9) + +options: +  -h, --help            show this help message and exit +  --dry-run             show changelog to stdout +  --file-name FILE_NAME +                        file name of changelog (default: 'CHANGELOG.md') +  --unreleased-version UNRELEASED_VERSION +                        set the value for the new version (use the tag value), +                        instead of using unreleased +  --incremental         generates changelog from last created version, useful +                        if the changelog has been manually modified +  --start-rev START_REV +                        start rev of the changelog. If not set, it will +                        generate changelog from the start +  --merge-prerelease    collect all changes from prereleases into next non- +                        prerelease. If not set, it will include prereleases in +                        the changelog +  --version-scheme {pep440,semver} +                        choose version scheme +  --export-template EXPORT_TEMPLATE +                        Export the changelog template into this file instead +                        of rendering it +  --template TEMPLATE, -t TEMPLATE +                        changelog template file name (relative to the current +                        working directory) +  --extra EXTRA, -e EXTRA +                        a changelog extra variable (in the form 'key=value') + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz check --help +usage: cz check [-h] +[--commit-msg-file COMMIT_MSG_FILE | --rev-range REV_RANGE | -m  +MESSAGE] +[--allow-abort][--allowed-prefixes [ALLOWED_PREFIXES ...]] + +options: +  -h, --help            show this help message and exit +  --commit-msg-file COMMIT_MSG_FILE +                        ask for the name of the temporal file that contains +                        the commit message. Using it in a git hook script: +MSG_FILE=$1 +  --rev-range REV_RANGE +                        a range of git rev to check. e.g, master..HEAD +  -m MESSAGE, --message MESSAGE +                        commit message that needs to be checked +  --allow-abort         allow empty commit messages, which typically abort a +                        commit +  --allowed-prefixes [ALLOWED_PREFIXES ...] +                        allowed commit message prefixes. If the message starts +                        by one of these prefixes, the message won't be checked +                        against the regex + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz commit --help +usage: cz commit [-h][--retry][--no-retry][--dry-run] +[--write-message-to-file FILE_PATH][-s][-a] + +options: +  -h, --help            show this help message and exit +  --retry               retry last commit +  --no-retry            skip retry if retry_after_failure is set to true +  --dry-run             show output to stdout, no commit, no modified files +  --write-message-to-file FILE_PATH +                        write message to file before committing (can be +                        combined with --dry-run) +  -s, --signoff         sign off the commit +  -a, --all             Tell the command to automatically stage files that +                        have been modified and deleted, but new files you have +                        not told Git about are not affected. + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz example --help +usage: cz example [-h] + +options: +  -h, --help  show this help message and exit + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz info --help +usage: cz info [-h] + +options: +  -h, --help  show this help message and exit + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz init --help +usage: cz init [-h] + +options: +  -h, --help  show this help message and exit + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz ls --help +usage: cz ls [-h] + +options: +  -h, --help  show this help message and exit + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz schema --help +usage: cz schema [-h] + +options: +  -h, --help  show this help message and exit + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $ cz version --help +usage: cz version [-h][-r | -p | -c | -v] + +options: +  -h, --help        show this help message and exit +  -r, --report      get system information for reporting bugs +  -p, --project     get the version of the current project +  -c, --commitizen  get the version of the installed commitizen +  -v, --verbose     get the version of both the installed commitizen and the +                    current project + + + + + 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 @@ +![Bump version](images/init.gif) + 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):