From a10ba848603c58caaba2a60216c36ab6981c5678 Mon Sep 17 00:00:00 2001 From: Brighten Tompkins Date: Fri, 12 Jan 2024 12:18:54 -0800 Subject: [PATCH 001/598] docs(version_scheme): fixed typo sever -> semver --- docs/bump.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bump.md b/docs/bump.md index d0ceb90ea0..00de9809fe 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -549,7 +549,7 @@ Choose version scheme | devrelease | `0.1.1.dev1` | `0.1.1-dev1` | | dev and pre | `1.0.0a3.dev1` | `1.0.0-a3-dev1` | -Options: `sever`, `pep440` +Options: `semver`, `pep440` Defaults to: `pep440` From 3e73157f366472f5065680ed5b72976d40a7b9ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 01:55:10 +0000 Subject: [PATCH 002/598] build(deps-dev): bump ruff from 0.1.12 to 0.1.13 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.12 to 0.1.13. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.12...v0.1.13) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 29409aa76b..a3a8f0fae0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1406,28 +1406,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.1.12" +version = "0.1.13" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.12-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:544038693543c11edc56bb94a9875df2dc249e3616f90c15964c720dcccf0745"}, - {file = "ruff-0.1.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8a0e3ef6299c4eab75a7740730e4b4bd4a36e0bd8102ded01553403cad088fd4"}, - {file = "ruff-0.1.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47f6d939461e3273f10f4cd059fd0b83c249d73f1736032fffbac83a62939395"}, - {file = "ruff-0.1.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25be18abc1fc3f3d3fb55855c41ed5d52063316defde202f413493bb3888218c"}, - {file = "ruff-0.1.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d41e9f100b50526d80b076fc9c103c729387ff3f10f63606ed1038c30a372a40"}, - {file = "ruff-0.1.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:472a0548738d4711549c7874b43fab61aacafb1fede29c5232d4cfb8e2d13f69"}, - {file = "ruff-0.1.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46685ef2f106b827705df876d38617741ed4f858bbdbc0817f94476c45ab6669"}, - {file = "ruff-0.1.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf6073749c70b616d7929897b14824ec6713a6c3a8195dfd2ffdcc66594d880c"}, - {file = "ruff-0.1.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bdf26e5a2efab4c3aaf6b61648ea47a525dc12775810a85c285dc9ca03e5ac0"}, - {file = "ruff-0.1.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b631c6a95e4b6d5c4299e599067b5a89f5b18e2f2d9a6c22b879b3c4b077c96e"}, - {file = "ruff-0.1.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f193f460e231e63af5fc7516897cf5ab257cbda72ae83cf9a654f1c80c3b758a"}, - {file = "ruff-0.1.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:718523c3a0b787590511f212d30cc9b194228ef369c8bdd72acd1282cc27c468"}, - {file = "ruff-0.1.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1c49e826de55d81a6ef93808b760925e492bad7cc470aaa114a3be158b2c7f99"}, - {file = "ruff-0.1.12-py3-none-win32.whl", hash = "sha256:fbb1c002eeacb60161e51d77b2274c968656599477a1c8c65066953276e8ee2b"}, - {file = "ruff-0.1.12-py3-none-win_amd64.whl", hash = "sha256:7fe06ba77e5b7b78db1d058478c47176810f69bb5be7c1b0d06876af59198203"}, - {file = "ruff-0.1.12-py3-none-win_arm64.whl", hash = "sha256:bb29f8e3e6c95024902eaec5a9ce1fd5ac4e77f4594f4554e67fbb0f6d9a2f37"}, - {file = "ruff-0.1.12.tar.gz", hash = "sha256:97189f38c655e573f6bea0d12e9f18aad5539fd08ab50651449450999f45383a"}, + {file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e3fd36e0d48aeac672aa850045e784673449ce619afc12823ea7868fcc41d8ba"}, + {file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9fb6b3b86450d4ec6a6732f9f60c4406061b6851c4b29f944f8c9d91c3611c7a"}, + {file = "ruff-0.1.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b13ba5d7156daaf3fd08b6b993360a96060500aca7e307d95ecbc5bb47a69296"}, + {file = "ruff-0.1.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ebb40442f7b531e136d334ef0851412410061e65d61ca8ce90d894a094feb22"}, + {file = "ruff-0.1.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226b517f42d59a543d6383cfe03cccf0091e3e0ed1b856c6824be03d2a75d3b6"}, + {file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5f0312ba1061e9b8c724e9a702d3c8621e3c6e6c2c9bd862550ab2951ac75c16"}, + {file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2f59bcf5217c661254bd6bc42d65a6fd1a8b80c48763cb5c2293295babd945dd"}, + {file = "ruff-0.1.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6894b00495e00c27b6ba61af1fc666f17de6140345e5ef27dd6e08fb987259d"}, + {file = "ruff-0.1.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1600942485c6e66119da294c6294856b5c86fd6df591ce293e4a4cc8e72989"}, + {file = "ruff-0.1.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ee3febce7863e231a467f90e681d3d89210b900d49ce88723ce052c8761be8c7"}, + {file = "ruff-0.1.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dcaab50e278ff497ee4d1fe69b29ca0a9a47cd954bb17963628fa417933c6eb1"}, + {file = "ruff-0.1.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f57de973de4edef3ad3044d6a50c02ad9fc2dff0d88587f25f1a48e3f72edf5e"}, + {file = "ruff-0.1.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7a36fa90eb12208272a858475ec43ac811ac37e91ef868759770b71bdabe27b6"}, + {file = "ruff-0.1.13-py3-none-win32.whl", hash = "sha256:a623349a505ff768dad6bd57087e2461be8db58305ebd5577bd0e98631f9ae69"}, + {file = "ruff-0.1.13-py3-none-win_amd64.whl", hash = "sha256:f988746e3c3982bea7f824c8fa318ce7f538c4dfefec99cd09c8770bd33e6539"}, + {file = "ruff-0.1.13-py3-none-win_arm64.whl", hash = "sha256:6bbbc3042075871ec17f28864808540a26f0f79a4478c357d3e3d2284e832998"}, + {file = "ruff-0.1.13.tar.gz", hash = "sha256:e261f1baed6291f434ffb1d5c6bd8051d1c2a26958072d38dfbec39b3dda7352"}, ] [[package]] From eb5f7374e8ab6fdacaeafff85ee956c85694d8c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 01:57:48 +0000 Subject: [PATCH 003/598] build(deps-dev): bump mkdocs-material from 9.5.3 to 9.5.4 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.3 to 9.5.4. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.3...9.5.4) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index a3a8f0fae0..2ea4288d1c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.3" +version = "9.5.4" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.3-py3-none-any.whl", hash = "sha256:76c93a8525cceb0b395b9cedab3428bf518cf6439adef2b940f1c1574b775d89"}, - {file = "mkdocs_material-9.5.3.tar.gz", hash = "sha256:5899219f422f0a6de784232d9d40374416302ffae3c160cacc72969fcc1ee372"}, + {file = "mkdocs_material-9.5.4-py3-none-any.whl", hash = "sha256:efd7cc8ae03296d728da9bd38f4db8b07ab61f9738a0cbd0dfaf2a15a50e7343"}, + {file = "mkdocs_material-9.5.4.tar.gz", hash = "sha256:3d196ee67fad16b2df1a458d650a8ac1890294eaae368d26cee71bc24ad41c40"}, ] [package.dependencies] From 2ceeed3e574fb0ca17fca634ee3d5a3132532c98 Mon Sep 17 00:00:00 2001 From: Kartik Vashistha Date: Thu, 18 Jan 2024 08:53:42 +0000 Subject: [PATCH 004/598] docs(github_actions.md): fix typo crendetial -> credential --- docs/tutorials/github_actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/github_actions.md b/docs/tutorials/github_actions.md index 3cb92725a5..7a98abe2be 100644 --- a/docs/tutorials/github_actions.md +++ b/docs/tutorials/github_actions.md @@ -72,7 +72,7 @@ newely created version. Once the new tag is created, triggering an automatic publish command would be desired. -In order to do so, the crendetial needs to be added with the information of our PyPI account. +In order to do so, the credential needs to be added with the information of our PyPI account. Instead of using username and password, we suggest using [api token](https://pypi.org/help/#apitoken) generated from PyPI. From 735dd4b2f4037fbff24be37f03677a209b6fd9e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 01:39:15 +0000 Subject: [PATCH 005/598] build(deps-dev): bump ruff from 0.1.13 to 0.1.14 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.13 to 0.1.14. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.13...v0.1.14) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2ea4288d1c..fb726689a8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1224,6 +1224,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1406,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.1.13" +version = "0.1.14" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e3fd36e0d48aeac672aa850045e784673449ce619afc12823ea7868fcc41d8ba"}, - {file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9fb6b3b86450d4ec6a6732f9f60c4406061b6851c4b29f944f8c9d91c3611c7a"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b13ba5d7156daaf3fd08b6b993360a96060500aca7e307d95ecbc5bb47a69296"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ebb40442f7b531e136d334ef0851412410061e65d61ca8ce90d894a094feb22"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226b517f42d59a543d6383cfe03cccf0091e3e0ed1b856c6824be03d2a75d3b6"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5f0312ba1061e9b8c724e9a702d3c8621e3c6e6c2c9bd862550ab2951ac75c16"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2f59bcf5217c661254bd6bc42d65a6fd1a8b80c48763cb5c2293295babd945dd"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6894b00495e00c27b6ba61af1fc666f17de6140345e5ef27dd6e08fb987259d"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1600942485c6e66119da294c6294856b5c86fd6df591ce293e4a4cc8e72989"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ee3febce7863e231a467f90e681d3d89210b900d49ce88723ce052c8761be8c7"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dcaab50e278ff497ee4d1fe69b29ca0a9a47cd954bb17963628fa417933c6eb1"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f57de973de4edef3ad3044d6a50c02ad9fc2dff0d88587f25f1a48e3f72edf5e"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7a36fa90eb12208272a858475ec43ac811ac37e91ef868759770b71bdabe27b6"}, - {file = "ruff-0.1.13-py3-none-win32.whl", hash = "sha256:a623349a505ff768dad6bd57087e2461be8db58305ebd5577bd0e98631f9ae69"}, - {file = "ruff-0.1.13-py3-none-win_amd64.whl", hash = "sha256:f988746e3c3982bea7f824c8fa318ce7f538c4dfefec99cd09c8770bd33e6539"}, - {file = "ruff-0.1.13-py3-none-win_arm64.whl", hash = "sha256:6bbbc3042075871ec17f28864808540a26f0f79a4478c357d3e3d2284e832998"}, - {file = "ruff-0.1.13.tar.gz", hash = "sha256:e261f1baed6291f434ffb1d5c6bd8051d1c2a26958072d38dfbec39b3dda7352"}, + {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:96f76536df9b26622755c12ed8680f159817be2f725c17ed9305b472a757cdbb"}, + {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ab3f71f64498c7241123bb5a768544cf42821d2a537f894b22457a543d3ca7a9"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7060156ecc572b8f984fd20fd8b0fcb692dd5d837b7606e968334ab7ff0090ab"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a53d8e35313d7b67eb3db15a66c08434809107659226a90dcd7acb2afa55faea"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bea9be712b8f5b4ebed40e1949379cfb2a7d907f42921cf9ab3aae07e6fba9eb"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2270504d629a0b064247983cbc495bed277f372fb9eaba41e5cf51f7ba705a6a"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80258bb3b8909b1700610dfabef7876423eed1bc930fe177c71c414921898efa"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:653230dd00aaf449eb5ff25d10a6e03bc3006813e2cb99799e568f55482e5cae"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b3acc6c4e6928459ba9eb7459dd4f0c4bf266a053c863d72a44c33246bfdbf"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6b3dadc9522d0eccc060699a9816e8127b27addbb4697fc0c08611e4e6aeb8b5"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c8eca1a47b4150dc0fbec7fe68fc91c695aed798532a18dbb1424e61e9b721f"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:62ce2ae46303ee896fc6811f63d6dabf8d9c389da0f3e3f2bce8bc7f15ef5488"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b2027dde79d217b211d725fc833e8965dc90a16d0d3213f1298f97465956661b"}, + {file = "ruff-0.1.14-py3-none-win32.whl", hash = "sha256:722bafc299145575a63bbd6b5069cb643eaa62546a5b6398f82b3e4403329cab"}, + {file = "ruff-0.1.14-py3-none-win_amd64.whl", hash = "sha256:e3d241aa61f92b0805a7082bd89a9990826448e4d0398f0e2bc8f05c75c63d99"}, + {file = "ruff-0.1.14-py3-none-win_arm64.whl", hash = "sha256:269302b31ade4cde6cf6f9dd58ea593773a37ed3f7b97e793c8594b262466b67"}, + {file = "ruff-0.1.14.tar.gz", hash = "sha256:ad3f8088b2dfd884820289a06ab718cde7d38b94972212cc4ba90d5fbc9955f3"}, ] [[package]] From e1ace264837a70d6a1d7e5c3a169cad1f4f1b7f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 01:30:23 +0000 Subject: [PATCH 006/598] build(deps): bump argcomplete from 3.2.1 to 3.2.2 Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 3.2.1 to 3.2.2. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v3.2.1...v3.2.2) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index fb726689a8..de3534b58e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,13 +13,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.2.1" +version = "3.2.2" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.2.1-py3-none-any.whl", hash = "sha256:30891d87f3c1abe091f2142613c9d33cac84a5e15404489f033b20399b691fec"}, - {file = "argcomplete-3.2.1.tar.gz", hash = "sha256:437f67fb9b058da5a090df505ef9be0297c4883993f3f56cb186ff087778cfb4"}, + {file = "argcomplete-3.2.2-py3-none-any.whl", hash = "sha256:e44f4e7985883ab3e73a103ef0acd27299dbfe2dfed00142c35d4ddd3005901d"}, + {file = "argcomplete-3.2.2.tar.gz", hash = "sha256:f3e49e8ea59b4026ee29548e24488af46e30c9de57d48638e24f54a1ea1000a2"}, ] [package.extras] From 45586973170edfb100cfca7db226506b38811238 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 01:16:11 +0000 Subject: [PATCH 007/598] build(deps-dev): bump mkdocs-material from 9.5.4 to 9.5.5 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.4 to 9.5.5. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.4...9.5.5) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index de3534b58e..b53a62304d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.4" +version = "9.5.5" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.4-py3-none-any.whl", hash = "sha256:efd7cc8ae03296d728da9bd38f4db8b07ab61f9738a0cbd0dfaf2a15a50e7343"}, - {file = "mkdocs_material-9.5.4.tar.gz", hash = "sha256:3d196ee67fad16b2df1a458d650a8ac1890294eaae368d26cee71bc24ad41c40"}, + {file = "mkdocs_material-9.5.5-py3-none-any.whl", hash = "sha256:ac50b2431a79a3b160fdefbba37c9132485f1a69166aba115ad49fafdbbbc5df"}, + {file = "mkdocs_material-9.5.5.tar.gz", hash = "sha256:4480d9580faf42fed0123d0465502bfc1c0c239ecc9c4d66159cf0459ea1b4ae"}, ] [package.dependencies] @@ -768,7 +768,7 @@ requests = ">=2.26,<3.0" [package.extras] git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] -imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] [[package]] From 43b1654cc0df2be45f3a581b50c0d1056f0dc963 Mon Sep 17 00:00:00 2001 From: ljnsn <82611987+ljnsn@users.noreply.github.com> Date: Thu, 25 Jan 2024 01:30:52 +0100 Subject: [PATCH 008/598] docs: add cz-conventional-gitmoji to the third party docs --- docs/third-party-commitizen.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/third-party-commitizen.md b/docs/third-party-commitizen.md index 671cdc0fd1..dbbd879434 100644 --- a/docs/third-party-commitizen.md +++ b/docs/third-party-commitizen.md @@ -46,6 +46,24 @@ pip install cz-emoji cz --name cz_emoji commit ``` +### [cz-conventional-gitmoji](https://github.com/ljnsn/cz-conventional-gitmoji) + +*conventional commit*s, but with [gitmojis](https://gitmoji.dev). + +Includes a pre-commit hook that automatically adds the correct gitmoji to the commit message based on the conventional type. + +### Installation + +```bash +pip install cz-conventional-gitmoji +``` + +### Usage + +```bash +cz --name cz_gitmoji commit +``` + ### [Commitizen emoji](https://pypi.org/project/commitizen-emoji/) (Unmaintained) From bf1f818d02963e51e20dab1228455c56f22232d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 01:24:42 +0000 Subject: [PATCH 009/598] build(deps-dev): bump mkdocs-material from 9.5.5 to 9.5.6 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.5 to 9.5.6. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.5...9.5.6) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index b53a62304d..13c276540c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.5" +version = "9.5.6" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.5-py3-none-any.whl", hash = "sha256:ac50b2431a79a3b160fdefbba37c9132485f1a69166aba115ad49fafdbbbc5df"}, - {file = "mkdocs_material-9.5.5.tar.gz", hash = "sha256:4480d9580faf42fed0123d0465502bfc1c0c239ecc9c4d66159cf0459ea1b4ae"}, + {file = "mkdocs_material-9.5.6-py3-none-any.whl", hash = "sha256:e115b90fccf5cd7f5d15b0c2f8e6246b21041628b8f590630e7fca66ed7fcf6c"}, + {file = "mkdocs_material-9.5.6.tar.gz", hash = "sha256:5b24df36d8ac6cecd611241ce6f6423ccde3e1ad89f8360c3f76d5565fc2d82a"}, ] [package.dependencies] From 129ddca71512cea2a6f6b2b018f2658fa20dc5fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 00:22:47 +0000 Subject: [PATCH 010/598] build(deps-dev): bump pytest from 7.4.4 to 8.0.0 Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.4 to 8.0.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.4.4...8.0.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 13c276540c..b5c8cde8a1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1048,13 +1048,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "7.4.4" +version = "8.0.0" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, + {file = "pytest-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"}, + {file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"}, ] [package.dependencies] @@ -1062,7 +1062,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" +pluggy = ">=1.3.0,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] @@ -1766,4 +1766,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "a5c0fbba4345989709fd201b2755ec9445972072108b5962666f41d451c7e6e2" +content-hash = "48784ae66f8098a8edaf69c3a1c49c5bf564cf94eda4ca7a20914675674afd18" diff --git a/pyproject.toml b/pyproject.toml index b644753b1b..3cd0c7ab58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ importlib_metadata = { version = ">=4.13,<8"} # dev tool ipython = "^8.0" # test -pytest = "^7.2.0" +pytest = ">=7.2,<9.0" pytest-cov = "^4.0" pytest-mock = "^3.10" pytest-regressions = "^2.4.0" From 657d9cfc03305a53af9d03c45cc2f0dd740f8b3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 01:53:13 +0000 Subject: [PATCH 011/598] build(deps-dev): bump ruff from 0.1.14 to 0.1.15 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.14 to 0.1.15. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.14...v0.1.15) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index b5c8cde8a1..4ff2455fbd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.1.14" +version = "0.1.15" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:96f76536df9b26622755c12ed8680f159817be2f725c17ed9305b472a757cdbb"}, - {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ab3f71f64498c7241123bb5a768544cf42821d2a537f894b22457a543d3ca7a9"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7060156ecc572b8f984fd20fd8b0fcb692dd5d837b7606e968334ab7ff0090ab"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a53d8e35313d7b67eb3db15a66c08434809107659226a90dcd7acb2afa55faea"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bea9be712b8f5b4ebed40e1949379cfb2a7d907f42921cf9ab3aae07e6fba9eb"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2270504d629a0b064247983cbc495bed277f372fb9eaba41e5cf51f7ba705a6a"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80258bb3b8909b1700610dfabef7876423eed1bc930fe177c71c414921898efa"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:653230dd00aaf449eb5ff25d10a6e03bc3006813e2cb99799e568f55482e5cae"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b3acc6c4e6928459ba9eb7459dd4f0c4bf266a053c863d72a44c33246bfdbf"}, - {file = "ruff-0.1.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6b3dadc9522d0eccc060699a9816e8127b27addbb4697fc0c08611e4e6aeb8b5"}, - {file = "ruff-0.1.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c8eca1a47b4150dc0fbec7fe68fc91c695aed798532a18dbb1424e61e9b721f"}, - {file = "ruff-0.1.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:62ce2ae46303ee896fc6811f63d6dabf8d9c389da0f3e3f2bce8bc7f15ef5488"}, - {file = "ruff-0.1.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b2027dde79d217b211d725fc833e8965dc90a16d0d3213f1298f97465956661b"}, - {file = "ruff-0.1.14-py3-none-win32.whl", hash = "sha256:722bafc299145575a63bbd6b5069cb643eaa62546a5b6398f82b3e4403329cab"}, - {file = "ruff-0.1.14-py3-none-win_amd64.whl", hash = "sha256:e3d241aa61f92b0805a7082bd89a9990826448e4d0398f0e2bc8f05c75c63d99"}, - {file = "ruff-0.1.14-py3-none-win_arm64.whl", hash = "sha256:269302b31ade4cde6cf6f9dd58ea593773a37ed3f7b97e793c8594b262466b67"}, - {file = "ruff-0.1.14.tar.gz", hash = "sha256:ad3f8088b2dfd884820289a06ab718cde7d38b94972212cc4ba90d5fbc9955f3"}, + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, + {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, + {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, + {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, + {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, ] [[package]] From bb2433bcb1658058fe5435af63fe1a022f520d6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 01:39:26 +0000 Subject: [PATCH 012/598] ci(deps): bump codecov/codecov-action from 3 to 4 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3...v4) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/pythonpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 00ab9a765d..f5967f3a93 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -31,7 +31,7 @@ jobs: shell: bash - name: Upload coverage to Codecov if: runner.os == 'Linux' - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: token: ${{secrets.CODECOV_TOKEN}} file: ./coverage.xml From db97a5ff08b0a2669103d1a7340601634c12fa91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez-Mondrag=C3=B3n?= Date: Tue, 30 Jan 2024 15:56:00 -0600 Subject: [PATCH 013/598] chore: Declare support for Python 3.12 in PyPI classifiers --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 3cd0c7ab58..d2d26e517c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", ] From d2377dde4911c377a209531c07a29c89de4a0805 Mon Sep 17 00:00:00 2001 From: Eduardo Cardoso Date: Thu, 1 Feb 2024 05:02:48 -0300 Subject: [PATCH 014/598] feat: properly bump versions between prereleases (#799) * fix: properly bump versions between prereleases * refactor: incorporate PR feedback * refactor: lower version bump into BaseVersion class and simplify callers of BaseVersion.bump() * feat: preserve prerelease linearity * docs: document the `--prerelease` option --------- Co-authored-by: Jens Troeger --- commitizen/commands/bump.py | 41 +++++++-- commitizen/version_schemes.py | 60 ++++++++---- docs/bump.md | 28 ++++++ tests/commands/test_bump_command.py | 91 ++++++++++++++++++- ...rsion_to_prerelease_version_beta_alpha_.md | 2 +- ...version_to_prerelease_version_rc_alpha_.md | 2 +- ..._version_to_prerelease_version_rc_beta_.md | 2 +- tests/test_version_scheme_pep440.py | 77 +++++++++++++++- tests/test_version_scheme_semver.py | 11 ++- 9 files changed, 277 insertions(+), 37 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index af365ecd28..b2ecd3130f 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -24,7 +24,11 @@ ) from commitizen.changelog_formats import get_changelog_format from commitizen.providers import get_provider -from commitizen.version_schemes import InvalidVersion, get_version_scheme +from commitizen.version_schemes import ( + get_version_scheme, + InvalidVersion, + VersionProtocol, +) logger = getLogger("commitizen") @@ -226,11 +230,6 @@ def __call__(self): # noqa: C901 "To avoid this error, manually specify the type of increment with `--increment`" ) - # Increment is removed when current and next version - # are expected to be prereleases. - if prerelease and current_version.is_prerelease: - increment = None - new_version = current_version.bump( increment, prerelease=prerelease, @@ -398,3 +397,33 @@ def _get_commit_args(self): if self.no_verify: commit_args.append("--no-verify") return " ".join(commit_args) + + def find_previous_final_version( + self, current_version: VersionProtocol + ) -> VersionProtocol | None: + tag_format: str = self.bump_settings["tag_format"] + current = bump.normalize_tag( + current_version, + tag_format=tag_format, + scheme=self.scheme, + ) + + final_versions = [] + for tag in git.get_tag_names(): + assert tag + try: + version = self.scheme(tag) + if not version.is_prerelease or tag == current: + final_versions.append(version) + except InvalidVersion: + continue + + if not final_versions: + return None + + final_versions = sorted(final_versions) # type: ignore [type-var] + current_index = final_versions.index(current_version) + previous_index = current_index - 1 + if previous_index < 0: + return None + return final_versions[previous_index] diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index d7967ae928..c277d2efc4 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -100,6 +100,7 @@ def bump( prerelease_offset: int = 0, devrelease: int | None = None, is_local_version: bool = False, + force_bump: bool = False, ) -> Self: """ Based on the given increment, generate the next bumped version according to the version scheme @@ -146,6 +147,12 @@ def generate_prerelease( if not prerelease: return "" + # prevent down-bumping the pre-release phase, e.g. from 'b1' to 'a2' + # https://packaging.python.org/en/latest/specifications/version-specifiers/#pre-releases + # https://semver.org/#spec-item-11 + if self.is_prerelease and self.pre: + prerelease = max(prerelease, self.pre[0]) + # version.pre is needed for mypy check if self.is_prerelease and self.pre and prerelease.startswith(self.pre[0]): prev_prerelease: int = self.pre[1] @@ -171,20 +178,15 @@ def increment_base(self, increment: str | None = None) -> str: increments = [MAJOR, MINOR, PATCH] base = dict(zip_longest(increments, prev_release, fillvalue=0)) - # This flag means that current version - # must remove its prerelease tag, - # so it doesn't matter the increment. - # Example: 1.0.0a0 with PATCH/MINOR -> 1.0.0 - if not self.is_prerelease: - if increment == MAJOR: - base[MAJOR] += 1 - base[MINOR] = 0 - base[PATCH] = 0 - elif increment == MINOR: - base[MINOR] += 1 - base[PATCH] = 0 - elif increment == PATCH: - base[PATCH] += 1 + if increment == MAJOR: + base[MAJOR] += 1 + base[MINOR] = 0 + base[PATCH] = 0 + elif increment == MINOR: + base[MINOR] += 1 + base[PATCH] = 0 + elif increment == PATCH: + base[PATCH] += 1 return f"{base[MAJOR]}.{base[MINOR]}.{base[PATCH]}" @@ -195,6 +197,7 @@ def bump( prerelease_offset: int = 0, devrelease: int | None = None, is_local_version: bool = False, + force_bump: bool = False, ) -> Self: """Based on the given increment a proper semver will be generated. @@ -212,9 +215,34 @@ def bump( local_version = self.scheme(self.local).bump(increment) return self.scheme(f"{self.public}+{local_version}") # type: ignore else: - base = self.increment_base(increment) + if not self.is_prerelease: + base = self.increment_base(increment) + elif force_bump: + base = self.increment_base(increment) + else: + base = f"{self.major}.{self.minor}.{self.micro}" + if increment == PATCH: + pass + elif increment == MINOR: + if self.micro != 0: + base = self.increment_base(increment) + elif increment == MAJOR: + if self.minor != 0 or self.micro != 0: + base = self.increment_base(increment) dev_version = self.generate_devrelease(devrelease) - pre_version = self.generate_prerelease(prerelease, offset=prerelease_offset) + release = list(self.release) + if len(release) < 3: + release += [0] * (3 - len(release)) + current_base = ".".join(str(part) for part in release) + if base == current_base: + pre_version = self.generate_prerelease( + prerelease, offset=prerelease_offset + ) + else: + base_version = cast(BaseVersion, self.scheme(base)) + pre_version = base_version.generate_prerelease( + prerelease, offset=prerelease_offset + ) # TODO: post version return self.scheme(f"{base}{pre_version}{dev_version}") # type: ignore diff --git a/docs/bump.md b/docs/bump.md index 00de9809fe..7bf6689231 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -113,6 +113,34 @@ Generate a **changelog** along with the new version and tag when bumping. cz bump --changelog ``` +### `--prerelease` + +The bump is a pre-release bump, meaning that in addition to a possible version bump the new version receives a +pre-release segment compatible with the bump’s version scheme, where the segment consist of a _phase_ and a +non-negative number. Supported options for `--prerelease` are the following phase names `alpha`, `beta`, or +`rc` (release candidate). For more details, refer to the +[Python Packaging User Guide](https://packaging.python.org/en/latest/specifications/version-specifiers/#pre-releases). + +Note that as per [semantic versioning spec](https://semver.org/#spec-item-9) + +> Pre-release versions have a lower precedence than the associated normal version. A pre-release version +> indicates that the version is unstable and might not satisfy the intended compatibility requirements +> as denoted by its associated normal version. + +For example, the following versions (using the [PEP 440](https://peps.python.org/pep-0440/) scheme) are ordered +by their precedence and showcase how a release might flow through a development cycle: + +- `1.0.0` is the current published version +- `1.0.1a0` after committing a `fix:` for pre-release +- `1.1.0a1` after committing an additional `feat:` for pre-release +- `1.1.0b0` after bumping a beta release +- `1.1.0rc0` after bumping the release candidate +- `1.1.0` next feature release + +Also note that bumping pre-releases _maintains linearity_: bumping of a pre-release with lower precedence than +the current pre-release phase maintains the current phase of higher precedence. For example, if the current +version is `1.0.0b1` then bumping with `--prerelease alpha` will continue to bump the “beta” phase. + ### `--check-consistency` Check whether the versions defined in `version_files` and the version in commitizen diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 774ec0a95f..d05c8f3301 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -208,9 +208,9 @@ def test_bump_command_increment_option( @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_command_prelease(mocker: MockFixture): - # PRERELEASE create_file_and_commit("feat: location") + # Create an alpha pre-release. testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] mocker.patch.object(sys, "argv", testargs) cli.main() @@ -218,7 +218,58 @@ def test_bump_command_prelease(mocker: MockFixture): tag_exists = git.tag_exist("0.2.0a0") assert tag_exists is True - # PRERELEASE BUMP CREATES VERSION WITHOUT PRERELEASE + # Create a beta pre-release. + testargs = ["cz", "bump", "--prerelease", "beta", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.2.0b0") + assert tag_exists is True + + # With a current beta pre-release, bumping alpha must bump beta + # because we can't bump "backwards". + testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.2.0a1") + assert tag_exists is False + tag_exists = git.tag_exist("0.2.0b1") + assert tag_exists is True + + # Create a rc pre-release. + testargs = ["cz", "bump", "--prerelease", "rc", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.2.0rc0") + assert tag_exists is True + + # With a current rc pre-release, bumping alpha must bump rc. + testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.2.0a1") + assert tag_exists is False + tag_exists = git.tag_exist("0.2.0b2") + assert tag_exists is False + tag_exists = git.tag_exist("0.2.0rc1") + assert tag_exists is True + + # With a current rc pre-release, bumping beta must bump rc. + testargs = ["cz", "bump", "--prerelease", "beta", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.2.0a2") + assert tag_exists is False + tag_exists = git.tag_exist("0.2.0b2") + assert tag_exists is False + tag_exists = git.tag_exist("0.2.0rc2") + assert tag_exists is True + + # Create a final release from the current pre-release. testargs = ["cz", "bump"] mocker.patch.object(sys, "argv", testargs) cli.main() @@ -227,6 +278,42 @@ def test_bump_command_prelease(mocker: MockFixture): assert tag_exists is True +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_command_prelease_increment(mocker: MockFixture): + # FINAL RELEASE + create_file_and_commit("fix: location") + + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + assert git.tag_exist("0.1.1") + + # PRERELEASE + create_file_and_commit("fix: location") + + testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + assert git.tag_exist("0.1.2a0") + + create_file_and_commit("feat: location") + + testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + assert git.tag_exist("0.2.0a0") + + create_file_and_commit("feat!: breaking") + + testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + assert git.tag_exist("1.0.0a0") + + @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_on_git_with_hooks_no_verify_disabled(mocker: MockFixture): """Bump commit without --no-verify""" diff --git a/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_beta_alpha_.md b/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_beta_alpha_.md index 300ca95756..ec9ab11d7b 100644 --- a/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_beta_alpha_.md +++ b/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_beta_alpha_.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.2.0a0 (2021-06-11) +## 0.2.0b1 (2021-06-11) ## 0.2.0b0 (2021-06-11) diff --git a/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_rc_alpha_.md b/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_rc_alpha_.md index 9a7e9f161f..e1c20b7e0d 100644 --- a/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_rc_alpha_.md +++ b/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_rc_alpha_.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.2.0a0 (2021-06-11) +## 0.2.0rc1 (2021-06-11) ## 0.2.0rc0 (2021-06-11) diff --git a/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_rc_beta_.md b/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_rc_beta_.md index b3be6f3c1d..e1c20b7e0d 100644 --- a/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_rc_beta_.md +++ b/tests/commands/test_changelog_command/test_changelog_incremental_with_prerelease_version_to_prerelease_version_rc_beta_.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.2.0b0 (2021-06-11) +## 0.2.0rc1 (2021-06-11) ## 0.2.0rc0 (2021-06-11) diff --git a/tests/test_version_scheme_pep440.py b/tests/test_version_scheme_pep440.py index 89f5a137ad..aa2120fad4 100644 --- a/tests/test_version_scheme_pep440.py +++ b/tests/test_version_scheme_pep440.py @@ -43,10 +43,11 @@ (("4.5.0+0.2.0", "MAJOR", None, 0, None), "4.5.0+1.0.0"), ] -# this cases should be handled gracefully -unexpected_cases = [ - (("0.1.1rc0", None, "alpha", 0, None), "0.1.1a0"), - (("0.1.1b1", None, "alpha", 0, None), "0.1.1a0"), +# never bump backwards on pre-releases +linear_prerelease_cases = [ + (("0.1.1b1", None, "alpha", 0, None), "0.1.1b2"), + (("0.1.1rc0", None, "alpha", 0, None), "0.1.1rc1"), + (("0.1.1rc0", None, "beta", 0, None), "0.1.1rc1"), ] weird_cases = [ @@ -78,10 +79,76 @@ (("1.0.0rc1", None, "rc", 0, None), "1.0.0rc2"), ] +# additional pre-release tests run through various release scenarios +prerelease_cases = [ + # + (("3.3.3", "PATCH", "alpha", 0, None), "3.3.4a0"), + (("3.3.4a0", "PATCH", "alpha", 0, None), "3.3.4a1"), + (("3.3.4a1", "MINOR", "alpha", 0, None), "3.4.0a0"), + (("3.4.0a0", "PATCH", "alpha", 0, None), "3.4.0a1"), + (("3.4.0a1", "MINOR", "alpha", 0, None), "3.4.0a2"), + (("3.4.0a2", "MAJOR", "alpha", 0, None), "4.0.0a0"), + (("4.0.0a0", "PATCH", "alpha", 0, None), "4.0.0a1"), + (("4.0.0a1", "MINOR", "alpha", 0, None), "4.0.0a2"), + (("4.0.0a2", "MAJOR", "alpha", 0, None), "4.0.0a3"), + # + (("1.0.0", "PATCH", "alpha", 0, None), "1.0.1a0"), + (("1.0.1a0", "PATCH", "alpha", 0, None), "1.0.1a1"), + (("1.0.1a1", "MINOR", "alpha", 0, None), "1.1.0a0"), + (("1.1.0a0", "PATCH", "alpha", 0, None), "1.1.0a1"), + (("1.1.0a1", "MINOR", "alpha", 0, None), "1.1.0a2"), + (("1.1.0a2", "MAJOR", "alpha", 0, None), "2.0.0a0"), + # + (("1.0.0", "MINOR", "alpha", 0, None), "1.1.0a0"), + (("1.1.0a0", "PATCH", "alpha", 0, None), "1.1.0a1"), + (("1.1.0a1", "MINOR", "alpha", 0, None), "1.1.0a2"), + (("1.1.0a2", "PATCH", "alpha", 0, None), "1.1.0a3"), + (("1.1.0a3", "MAJOR", "alpha", 0, None), "2.0.0a0"), + # + (("1.0.0", "MAJOR", "alpha", 0, None), "2.0.0a0"), + (("2.0.0a0", "MINOR", "alpha", 0, None), "2.0.0a1"), + (("2.0.0a1", "PATCH", "alpha", 0, None), "2.0.0a2"), + (("2.0.0a2", "MAJOR", "alpha", 0, None), "2.0.0a3"), + (("2.0.0a3", "MINOR", "alpha", 0, None), "2.0.0a4"), + (("2.0.0a4", "PATCH", "alpha", 0, None), "2.0.0a5"), + (("2.0.0a5", "MAJOR", "alpha", 0, None), "2.0.0a6"), + # + (("1.0.1a0", "PATCH", None, 0, None), "1.0.1"), + (("1.0.1a0", "MINOR", None, 0, None), "1.1.0"), + (("1.0.1a0", "MAJOR", None, 0, None), "2.0.0"), + # + (("1.1.0a0", "PATCH", None, 0, None), "1.1.0"), + (("1.1.0a0", "MINOR", None, 0, None), "1.1.0"), + (("1.1.0a0", "MAJOR", None, 0, None), "2.0.0"), + # + (("2.0.0a0", "MINOR", None, 0, None), "2.0.0"), + (("2.0.0a0", "MAJOR", None, 0, None), "2.0.0"), + (("2.0.0a0", "PATCH", None, 0, None), "2.0.0"), + # + (("3.0.0a1", None, None, 0, None), "3.0.0"), + (("3.0.0b1", None, None, 0, None), "3.0.0"), + (("3.0.0rc1", None, None, 0, None), "3.0.0"), + # + (("3.1.4", None, "alpha", 0, None), "3.1.4a0"), + (("3.1.4", None, "beta", 0, None), "3.1.4b0"), + (("3.1.4", None, "rc", 0, None), "3.1.4rc0"), + # + (("3.1.4", None, "alpha", 0, None), "3.1.4a0"), + (("3.1.4a0", "PATCH", "alpha", 0, None), "3.1.4a1"), # UNEXPECTED! + (("3.1.4a0", "MINOR", "alpha", 0, None), "3.2.0a0"), + (("3.1.4a0", "MAJOR", "alpha", 0, None), "4.0.0a0"), +] + @pytest.mark.parametrize( "test_input,expected", - itertools.chain(tdd_cases, weird_cases, simple_flow, unexpected_cases), + itertools.chain( + tdd_cases, + weird_cases, + simple_flow, + linear_prerelease_cases, + prerelease_cases, + ), ) def test_bump_pep440_version(test_input, expected): current_version = test_input[0] diff --git a/tests/test_version_scheme_semver.py b/tests/test_version_scheme_semver.py index 82ed33c229..85cfcf5df1 100644 --- a/tests/test_version_scheme_semver.py +++ b/tests/test_version_scheme_semver.py @@ -44,10 +44,11 @@ (("4.5.0+0.2.0", "MAJOR", None, 0, None), "4.5.0+1.0.0"), ] -# this cases should be handled gracefully -unexpected_cases = [ - (("0.1.1rc0", None, "alpha", 0, None), "0.1.1-a0"), - (("0.1.1b1", None, "alpha", 0, None), "0.1.1-a0"), +# never bump backwards on pre-releases +linear_prerelease_cases = [ + (("0.1.1b1", None, "alpha", 0, None), "0.1.1-b2"), + (("0.1.1rc0", None, "alpha", 0, None), "0.1.1-rc1"), + (("0.1.1rc0", None, "beta", 0, None), "0.1.1-rc1"), ] weird_cases = [ @@ -84,7 +85,7 @@ @pytest.mark.parametrize( "test_input, expected", - itertools.chain(tdd_cases, weird_cases, simple_flow, unexpected_cases), + itertools.chain(tdd_cases, weird_cases, simple_flow, linear_prerelease_cases), ) def test_bump_semver_version(test_input, expected): current_version = test_input[0] From 05bdead2a5238cc77560bd192b72294e824f2ef5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Feb 2024 08:03:12 +0000 Subject: [PATCH 015/598] =?UTF-8?q?bump:=20version=203.13.0=20=E2=86=92=20?= =?UTF-8?q?3.14.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dbe313c5da..55836498a0 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.13.0 # automatically updated by Commitizen + rev: v3.14.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index c071ba9075..4ad6367e31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +## v3.14.0 (2024-02-01) + +### Feat + +- properly bump versions between prereleases (#799) + ## v3.13.0 (2023-12-03) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 62ee17b836..382c7be006 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.13.0" +__version__ = "3.14.0" diff --git a/pyproject.toml b/pyproject.toml index d2d26e517c..7c3266469c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.13.0" +version = "3.14.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.13.0" +version = "3.14.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 9c02ae2d35034e244002bde9b33d3f6297a6aad1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 02:05:05 +0000 Subject: [PATCH 016/598] build(deps-dev): bump ruff from 0.1.15 to 0.2.0 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.15 to 0.2.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.15...v0.2.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4ff2455fbd..fc4c115f03 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.1.15" +version = "0.2.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, - {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, - {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, - {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, - {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, - {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, + {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:638ea3294f800d18bae84a492cb5a245c8d29c90d19a91d8e338937a4c27fca0"}, + {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3ff35433fcf4dff6d610738712152df6b7d92351a1bde8e00bd405b08b3d5759"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9faafbdcf4f53917019f2c230766da437d4fd5caecd12ddb68bb6a17d74399"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8153a3e4128ed770871c47545f1ae7b055023e0c222ff72a759f5a341ee06483"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a75a98ae989a27090e9c51f763990ad5bbc92d20626d54e9701c7fe597f399"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:87057dd2fdde297130ff99553be8549ca38a2965871462a97394c22ed2dfc19d"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d232f99d3ab00094ebaf88e0fb7a8ccacaa54cc7fa3b8993d9627a11e6aed7a"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3c641f95f435fc6754b05591774a17df41648f0daf3de0d75ad3d9f099ab92"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3826fb34c144ef1e171b323ed6ae9146ab76d109960addca730756dc19dc7b22"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eceab7d85d09321b4de18b62d38710cf296cb49e98979960a59c6b9307c18cfe"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:30ad74687e1f4a9ff8e513b20b82ccadb6bd796fe5697f1e417189c5cde6be3e"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7e3818698f8460bd0f8d4322bbe99db8327e9bc2c93c789d3159f5b335f47da"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:edf23041242c48b0d8295214783ef543847ef29e8226d9f69bf96592dba82a83"}, + {file = "ruff-0.2.0-py3-none-win32.whl", hash = "sha256:e155147199c2714ff52385b760fe242bb99ea64b240a9ffbd6a5918eb1268843"}, + {file = "ruff-0.2.0-py3-none-win_amd64.whl", hash = "sha256:ba918e01cdd21e81b07555564f40d307b0caafa9a7a65742e98ff244f5035c59"}, + {file = "ruff-0.2.0-py3-none-win_arm64.whl", hash = "sha256:3fbaff1ba9564a2c5943f8f38bc221f04bac687cc7485e45237579fee7ccda79"}, + {file = "ruff-0.2.0.tar.gz", hash = "sha256:63856b91837606c673537d2889989733d7dffde553828d3b0f0bacfa6def54be"}, ] [[package]] @@ -1766,4 +1766,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "48784ae66f8098a8edaf69c3a1c49c5bf564cf94eda4ca7a20914675674afd18" +content-hash = "c23e3f50c2653e7204507694115f192306fb54b4eeb90087daf088ab67016b94" diff --git a/pyproject.toml b/pyproject.toml index 7c3266469c..2b06cb9b38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,7 @@ pytest-xdist = "^3.1.0" # code formatter black = "~=23.11" # linter -ruff = "~=0.1.6" +ruff = ">=0.1.6,<0.3.0" pre-commit = ">=2.18,<4.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" From e3c6bc93e7e94c3efe7d40eac2c83596ca7d91b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 02:18:49 +0000 Subject: [PATCH 017/598] build(deps-dev): bump black from 23.12.1 to 24.1.1 Bumps [black](https://github.com/psf/black) from 23.12.1 to 24.1.1. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.12.1...24.1.1) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- poetry.lock | 48 ++++++++++++++++++++++++------------------------ pyproject.toml | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/poetry.lock b/poetry.lock index fc4c115f03..d0be3bc97b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -73,33 +73,33 @@ files = [ [[package]] name = "black" -version = "23.12.1" +version = "24.1.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, - {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, - {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, - {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, - {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, - {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, - {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, - {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, - {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, - {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, - {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, - {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, - {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, - {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, - {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, - {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, - {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, - {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, - {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, - {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, - {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, - {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, + {file = "black-24.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2588021038bd5ada078de606f2a804cadd0a3cc6a79cb3e9bb3a8bf581325a4c"}, + {file = "black-24.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a95915c98d6e32ca43809d46d932e2abc5f1f7d582ffbe65a5b4d1588af7445"}, + {file = "black-24.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa6a0e965779c8f2afb286f9ef798df770ba2b6cee063c650b96adec22c056a"}, + {file = "black-24.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5242ecd9e990aeb995b6d03dc3b2d112d4a78f2083e5a8e86d566340ae80fec4"}, + {file = "black-24.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc1ec9aa6f4d98d022101e015261c056ddebe3da6a8ccfc2c792cbe0349d48b7"}, + {file = "black-24.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0269dfdea12442022e88043d2910429bed717b2d04523867a85dacce535916b8"}, + {file = "black-24.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d64db762eae4a5ce04b6e3dd745dcca0fb9560eb931a5be97472e38652a161"}, + {file = "black-24.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5d7b06ea8816cbd4becfe5f70accae953c53c0e53aa98730ceccb0395520ee5d"}, + {file = "black-24.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e2c8dfa14677f90d976f68e0c923947ae68fa3961d61ee30976c388adc0b02c8"}, + {file = "black-24.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a21725862d0e855ae05da1dd25e3825ed712eaaccef6b03017fe0853a01aa45e"}, + {file = "black-24.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07204d078e25327aad9ed2c64790d681238686bce254c910de640c7cc4fc3aa6"}, + {file = "black-24.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a83fe522d9698d8f9a101b860b1ee154c1d25f8a82ceb807d319f085b2627c5b"}, + {file = "black-24.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08b34e85170d368c37ca7bf81cf67ac863c9d1963b2c1780c39102187ec8dd62"}, + {file = "black-24.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7258c27115c1e3b5de9ac6c4f9957e3ee2c02c0b39222a24dc7aa03ba0e986f5"}, + {file = "black-24.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40657e1b78212d582a0edecafef133cf1dd02e6677f539b669db4746150d38f6"}, + {file = "black-24.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e298d588744efda02379521a19639ebcd314fba7a49be22136204d7ed1782717"}, + {file = "black-24.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34afe9da5056aa123b8bfda1664bfe6fb4e9c6f311d8e4a6eb089da9a9173bf9"}, + {file = "black-24.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:854c06fb86fd854140f37fb24dbf10621f5dab9e3b0c29a690ba595e3d543024"}, + {file = "black-24.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3897ae5a21ca132efa219c029cce5e6bfc9c3d34ed7e892113d199c0b1b444a2"}, + {file = "black-24.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:ecba2a15dfb2d97105be74bbfe5128bc5e9fa8477d8c46766505c1dda5883aac"}, + {file = "black-24.1.1-py3-none-any.whl", hash = "sha256:5cdc2e2195212208fbcae579b931407c1fa9997584f0a415421748aeafff1168"}, + {file = "black-24.1.1.tar.gz", hash = "sha256:48b5760dcbfe5cf97fd4fba23946681f3a81514c6ab8a45b50da67ac8fbc6c7b"}, ] [package.dependencies] @@ -1766,4 +1766,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "c23e3f50c2653e7204507694115f192306fb54b4eeb90087daf088ab67016b94" +content-hash = "ae231a49c0c27985defdc7adba7a112eecc8c8abe1e9a8e5cf5358f7a71637c0" diff --git a/pyproject.toml b/pyproject.toml index 2b06cb9b38..c4b204e287 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,7 +60,7 @@ pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" # code formatter -black = "~=23.11" +black = ">=23.11,<25.0" # linter ruff = ">=0.1.6,<0.3.0" pre-commit = ">=2.18,<4.0" From a8e970bfec0f08015aa340507cc1acf5722cac82 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 2 Feb 2024 12:13:23 +0800 Subject: [PATCH 018/598] style: format the code with the latest black and ruff --- commitizen/changelog.py | 1 + commitizen/cz/base.py | 6 +++--- commitizen/cz/exceptions.py | 6 ++---- tests/test_bump_find_increment.py | 1 + tests/test_changelog.py | 6 +++--- tests/test_cz_customize.py | 6 ++++-- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index cd9e76a320..e4273db93a 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -24,6 +24,7 @@ - [x] hook after changelog is generated (api calls) - [x] add support for change_type maps """ + from __future__ import annotations import re diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index d9bf5ea4a0..14d9e5a522 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -37,9 +37,9 @@ class BaseCommitizen(metaclass=ABCMeta): change_type_order: list[str] | None = None # Executed per message parsed by the commitizen - changelog_message_builder_hook: None | ( - Callable[[dict, git.GitCommit], dict] - ) = None + changelog_message_builder_hook: None | (Callable[[dict, git.GitCommit], dict]) = ( + None + ) # Executed only at the end of the changelog generation changelog_hook: Callable[[str, str | None], str] | None = None diff --git a/commitizen/cz/exceptions.py b/commitizen/cz/exceptions.py index 2597b68813..d74f39aaaa 100644 --- a/commitizen/cz/exceptions.py +++ b/commitizen/cz/exceptions.py @@ -1,6 +1,4 @@ -class CzException(Exception): - ... +class CzException(Exception): ... -class AnswerRequiredError(CzException): - ... +class AnswerRequiredError(CzException): ... diff --git a/tests/test_bump_find_increment.py b/tests/test_bump_find_increment.py index 8e8fc2705e..ff24ff17a7 100644 --- a/tests/test_bump_find_increment.py +++ b/tests/test_bump_find_increment.py @@ -2,6 +2,7 @@ CC: Conventional commits SVE: Semantic version at the end """ + import pytest from commitizen import bump diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 8aef10a31f..879443f334 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1298,9 +1298,9 @@ def test_render_changelog_with_changelog_message_builder_hook( gitcommits, tags, any_changelog_format: ChangelogFormat ): def changelog_message_builder_hook(message: dict, commit: git.GitCommit) -> dict: - message[ - "message" - ] = f"{message['message']} [link](github.com/232323232) {commit.author} {commit.author_email}" + message["message"] = ( + f"{message['message']} [link](github.com/232323232) {commit.author} {commit.author_email}" + ) return message parser = ConventionalCommitsCz.commit_parser diff --git a/tests/test_cz_customize.py b/tests/test_cz_customize.py index 9f3556fce8..20a17b3d9c 100644 --- a/tests/test_cz_customize.py +++ b/tests/test_cz_customize.py @@ -498,7 +498,8 @@ def test_answer_unicode(config_with_unicode): } message = cz.message(answers) assert ( - message == "✨ feature: this feature enables customization through a config file" + message + == "✨ feature: this feature enables customization through a config file" ) cz = CustomizeCommitsCz(config_with_unicode) @@ -574,7 +575,8 @@ def test_commit_parser(config): def test_commit_parser_unicode(config_with_unicode): cz = CustomizeCommitsCz(config_with_unicode) assert ( - cz.commit_parser == "^(?P✨ feature|🐛 bug fix):\\s(?P.*)?" + cz.commit_parser + == "^(?P✨ feature|🐛 bug fix):\\s(?P.*)?" ) From 893cf8c538c70ccf80b4325b62d6ccef8bc65e3e Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 2 Feb 2024 12:13:54 +0800 Subject: [PATCH 019/598] style: update ruff config with the latest config format --- pyproject.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c4b204e287..37603738f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -141,6 +141,8 @@ addopts = "--strict-markers" [tool.ruff] line-length = 88 + +[tool.ruff.lint] select = ["E", "F", "UP"] ignore = [ "E501", @@ -148,10 +150,10 @@ ignore = [ "D415" ] -[tool.ruff.isort] +[tool.ruff.lint.isort] known-first-party = ["commitizen", "tests"] -[tool.ruff.pydocstyle] +[tool.ruff.lint.pydocstyle] convention = "google" [tool.mypy] From 1c022ddfd0afbd73ddc15a7533b949ce86d4dd9d Mon Sep 17 00:00:00 2001 From: Chad Dombrova Date: Mon, 29 Jan 2024 13:06:25 -0800 Subject: [PATCH 020/598] fix(scm): only search tags that are reachable by the current commit The scm provider requires tags to be the source of truth for the current version, instead of files. Therefore, the current version should be the highest tag version upstream from the current commit. --- commitizen/commands/bump.py | 2 +- commitizen/git.py | 10 ++++- commitizen/providers/scm_provider.py | 36 +++++++++++++----- commitizen/version_schemes.py | 20 +++++++++- tests/providers/test_scm_provider.py | 56 +++++++++++++++++++++++++++- tests/test_git.py | 31 ++++++++++++++- 6 files changed, 138 insertions(+), 17 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index b2ecd3130f..023d4f805b 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -421,7 +421,7 @@ def find_previous_final_version( if not final_versions: return None - final_versions = sorted(final_versions) # type: ignore [type-var] + final_versions = sorted(final_versions) current_index = final_versions.index(current_version) previous_index = current_index - 1 if previous_index < 0: diff --git a/commitizen/git.py b/commitizen/git.py index 4c4dfdb961..6cdc7e2752 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -164,7 +164,9 @@ def get_filenames_in_commit(git_reference: str = ""): raise GitCommandError(c.err) -def get_tags(dateformat: str = "%Y-%m-%d") -> list[GitTag]: +def get_tags( + dateformat: str = "%Y-%m-%d", reachable_only: bool = False +) -> list[GitTag]: inner_delimiter = "---inner_delimiter---" formatter = ( f'"%(refname:lstrip=2){inner_delimiter}' @@ -172,8 +174,12 @@ def get_tags(dateformat: str = "%Y-%m-%d") -> list[GitTag]: f"%(creatordate:format:{dateformat}){inner_delimiter}" f'%(object)"' ) - c = cmd.run(f"git tag --format={formatter} --sort=-creatordate") + extra = "--merged" if reachable_only else "" + c = cmd.run(f"git tag --format={formatter} --sort=-creatordate {extra}") if c.return_code != 0: + if reachable_only and c.err == "fatal: malformed object name HEAD\n": + # this can happen if there are no commits in the repo yet + return [] raise GitCommandError(c.err) if c.err: diff --git a/commitizen/providers/scm_provider.py b/commitizen/providers/scm_provider.py index bc9dda4b8a..37329d07a5 100644 --- a/commitizen/providers/scm_provider.py +++ b/commitizen/providers/scm_provider.py @@ -1,11 +1,16 @@ from __future__ import annotations import re -from typing import Callable, cast +from typing import Callable from commitizen.git import get_tags -from commitizen.version_schemes import get_version_scheme +from commitizen.version_schemes import ( + get_version_scheme, + InvalidVersion, + Version, + VersionProtocol, +) from commitizen.providers.base_provider import VersionProvider @@ -28,7 +33,7 @@ class ScmProvider(VersionProvider): "$devrelease": r"(?P\.dev\d+)?", } - def _tag_format_matcher(self) -> Callable[[str], str | None]: + def _tag_format_matcher(self) -> Callable[[str], VersionProtocol | None]: version_scheme = get_version_scheme(self.config) pattern = self.config.settings["tag_format"] if pattern == "$version": @@ -38,15 +43,15 @@ def _tag_format_matcher(self) -> Callable[[str], str | None]: regex = re.compile(f"^{pattern}$", re.VERBOSE) - def matcher(tag: str) -> str | None: + def matcher(tag: str) -> Version | None: match = regex.match(tag) if not match: return None groups = match.groupdict() if "version" in groups: - return groups["version"] + ver = groups["version"] elif "major" in groups: - return "".join( + ver = "".join( ( groups["major"], f".{groups['minor']}" if groups.get("minor") else "", @@ -56,16 +61,27 @@ def matcher(tag: str) -> str | None: ) ) elif pattern == version_scheme.parser.pattern: - return str(version_scheme(tag)) - return None + ver = tag + else: + return None + + try: + return version_scheme(ver) + except InvalidVersion: + return None return matcher def get_version(self) -> str: matcher = self._tag_format_matcher() - return next( - (cast(str, matcher(t.name)) for t in get_tags() if matcher(t.name)), "0.0.0" + matches = sorted( + version + for t in get_tags(reachable_only=True) + if (version := matcher(t.name)) ) + if not matches: + return "0.0.0" + return str(matches[-1]) def set_version(self, version: str): # Not necessary diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index c277d2efc4..8fcec9e74f 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -4,7 +4,7 @@ import sys import warnings from itertools import zip_longest -from typing import TYPE_CHECKING, ClassVar, Protocol, Type, cast, runtime_checkable +from typing import TYPE_CHECKING, Any, ClassVar, Protocol, Type, cast, runtime_checkable import importlib_metadata as metadata from packaging.version import InvalidVersion # noqa: F401: Rexpose the common exception @@ -93,6 +93,24 @@ def micro(self) -> int: """The third item of :attr:`release` or ``0`` if unavailable.""" raise NotImplementedError("must be implemented") + def __lt__(self, other: Any) -> bool: + raise NotImplementedError("must be implemented") + + def __le__(self, other: Any) -> bool: + raise NotImplementedError("must be implemented") + + def __eq__(self, other: object) -> bool: + raise NotImplementedError("must be implemented") + + def __ge__(self, other: Any) -> bool: + raise NotImplementedError("must be implemented") + + def __gt__(self, other: Any) -> bool: + raise NotImplementedError("must be implemented") + + def __ne__(self, other: object) -> bool: + raise NotImplementedError("must be implemented") + def bump( self, increment: str, diff --git a/tests/providers/test_scm_provider.py b/tests/providers/test_scm_provider.py index a0bfc46474..9611dd9ee0 100644 --- a/tests/providers/test_scm_provider.py +++ b/tests/providers/test_scm_provider.py @@ -6,7 +6,13 @@ from commitizen.config.base_config import BaseConfig from commitizen.providers import get_provider from commitizen.providers.scm_provider import ScmProvider -from tests.utils import create_file_and_commit, create_tag +from tests.utils import ( + create_branch, + create_file_and_commit, + create_tag, + merge_branch, + switch_branch, +) @pytest.mark.parametrize( @@ -22,7 +28,8 @@ # much more lenient but require a v prefix. ("v$version", "v0.1.0", "0.1.0"), ("v$version", "no-match-because-no-v-prefix", "0.0.0"), - ("v$version", "v-match-TAG_FORMAT_REGEXS", "-match-TAG_FORMAT_REGEXS"), + # no match because not a valid version + ("v$version", "v-match-TAG_FORMAT_REGEXS", "0.0.0"), ("version-$version", "version-0.1.0", "0.1.0"), ("version-$version", "version-0.1", "0.1"), ("version-$version", "version-0.1.0rc1", "0.1.0rc1"), @@ -62,3 +69,48 @@ def test_scm_provider_default_without_commits_and_tags(config: BaseConfig): provider = get_provider(config) assert isinstance(provider, ScmProvider) assert provider.get_version() == "0.0.0" + + +@pytest.mark.usefixtures("tmp_git_project") +def test_scm_provider_default_with_commits_and_tags(config: BaseConfig): + config.settings["version_provider"] = "scm" + + provider = get_provider(config) + assert isinstance(provider, ScmProvider) + assert provider.get_version() == "0.0.0" + + create_file_and_commit("Initial state") + create_tag("1.0.0") + # create develop + create_branch("develop") + switch_branch("develop") + + # add a feature to develop + create_file_and_commit("develop: add beta feature1") + assert provider.get_version() == "1.0.0" + create_tag("1.1.0b0") + + # create staging + create_branch("staging") + switch_branch("staging") + create_file_and_commit("staging: Starting release candidate") + assert provider.get_version() == "1.1.0b0" + create_tag("1.1.0rc0") + + # add another feature to develop + switch_branch("develop") + create_file_and_commit("develop: add beta feature2") + assert provider.get_version() == "1.1.0b0" + create_tag("1.2.0b0") + + # add a hotfix to master + switch_branch("master") + create_file_and_commit("master: add hotfix") + assert provider.get_version() == "1.0.0" + create_tag("1.0.1") + + # merge the hotfix to staging + switch_branch("staging") + merge_branch("master") + + assert provider.get_version() == "1.1.0rc0" diff --git a/tests/test_git.py b/tests/test_git.py index 4ae11a45dd..79eb49f10c 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -9,7 +9,13 @@ from commitizen import cmd, exceptions, git from pytest_mock import MockFixture -from tests.utils import FakeCommand, create_file_and_commit, create_tag +from tests.utils import ( + FakeCommand, + create_file_and_commit, + create_tag, + create_branch, + switch_branch, +) def test_git_object_eq(): @@ -42,6 +48,29 @@ def test_get_tags(mocker: MockFixture): assert git.get_tags() == [] +def test_get_reachable_tags(tmp_commitizen_project): + with tmp_commitizen_project.as_cwd(): + create_file_and_commit("Initial state") + create_tag("1.0.0") + # create develop + create_branch("develop") + switch_branch("develop") + + # add a feature to develop + create_file_and_commit("develop") + create_tag("1.1.0b0") + + # create staging + switch_branch("master") + create_file_and_commit("master") + create_tag("1.0.1") + + tags = git.get_tags(reachable_only=True) + tag_names = set([t.name for t in tags]) + # 1.1.0b0 is not present + assert tag_names == {"1.0.0", "1.0.1"} + + def test_get_tag_names(mocker: MockFixture): tag_str = "v1.0.0\n" "v0.5.0\n" "v0.0.1\n" mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=tag_str)) From 6b84f30716ceea85701b5a50649cf05b289fb102 Mon Sep 17 00:00:00 2001 From: Chad Dombrova Date: Sat, 3 Feb 2024 09:46:53 -0800 Subject: [PATCH 021/598] test(version_schemes): add tests for version sortability --- tests/test_version_scheme_pep440.py | 98 +++++++++++++++++++++++++++++ tests/test_version_scheme_semver.py | 74 ++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/tests/test_version_scheme_pep440.py b/tests/test_version_scheme_pep440.py index aa2120fad4..ac99450652 100644 --- a/tests/test_version_scheme_pep440.py +++ b/tests/test_version_scheme_pep440.py @@ -1,6 +1,8 @@ import itertools +import random import pytest + from commitizen.version_schemes import Pep440, VersionProtocol simple_flow = [ @@ -140,6 +142,29 @@ ] +# test driven development +sortability = [ + "0.10.0a0", + "0.1.1", + "0.1.2", + "2.1.1", + "3.0.0", + "0.9.1a0", + "1.0.0a1", + "1.0.0b1", + "1.0.0a1", + "1.0.0a2.dev1", + "1.0.0rc2", + "1.0.0a3.dev0", + "1.0.0a2.dev0", + "1.0.0a3.dev1", + "1.0.0a2.dev0", + "1.0.0b0", + "1.0.0rc0", + "1.0.0rc1", +] + + @pytest.mark.parametrize( "test_input,expected", itertools.chain( @@ -198,3 +223,76 @@ def test_pep440_scheme_property(): def test_pep440_implement_version_protocol(): assert isinstance(Pep440("0.0.1"), VersionProtocol) + + +def test_pep440_sortable(): + test_input = [x[0][0] for x in simple_flow] + test_input.extend([x[1] for x in simple_flow]) + # randomize + random_input = [Pep440(x) for x in random.sample(test_input, len(test_input))] + assert len(random_input) == len(test_input) + sorted_result = [str(x) for x in sorted(random_input)] + assert sorted_result == [ + "0.1.0", + "0.1.0", + "0.1.1.dev1", + "0.1.1", + "0.1.1", + "0.2.0", + "0.2.0", + "0.2.0", + "0.3.0.dev1", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.1a0", + "0.3.1a0", + "0.3.1a0", + "0.3.1a0", + "0.3.1a1", + "0.3.1a1", + "0.3.1a1", + "0.3.1", + "0.3.1", + "0.3.1", + "0.3.2", + "0.4.2", + "1.0.0a0", + "1.0.0a0", + "1.0.0a1", + "1.0.0a1", + "1.0.0a1", + "1.0.0a1", + "1.0.0a2.dev0", + "1.0.0a2.dev0", + "1.0.0a2.dev1", + "1.0.0a2", + "1.0.0a3.dev0", + "1.0.0a3.dev0", + "1.0.0a3.dev1", + "1.0.0b0", + "1.0.0b0", + "1.0.0b0", + "1.0.0b1", + "1.0.0b1", + "1.0.0rc0", + "1.0.0rc0", + "1.0.0rc0", + "1.0.0rc0", + "1.0.0rc1.dev1", + "1.0.0rc1", + "1.0.0", + "1.0.0", + "1.0.1", + "1.0.1", + "1.0.2", + "1.0.2", + "1.1.0", + "1.1.0", + "1.2.0", + "1.2.0", + "1.2.1", + "1.2.1", + "2.0.0", + ] diff --git a/tests/test_version_scheme_semver.py b/tests/test_version_scheme_semver.py index 85cfcf5df1..a0d6e14b50 100644 --- a/tests/test_version_scheme_semver.py +++ b/tests/test_version_scheme_semver.py @@ -1,4 +1,5 @@ import itertools +import random import pytest @@ -135,3 +136,76 @@ def test_semver_scheme_property(): def test_semver_implement_version_protocol(): assert isinstance(SemVer("0.0.1"), VersionProtocol) + + +def test_semver_sortable(): + test_input = [x[0][0] for x in simple_flow] + test_input.extend([x[1] for x in simple_flow]) + # randomize + random_input = [SemVer(x) for x in random.sample(test_input, len(test_input))] + assert len(random_input) == len(test_input) + sorted_result = [str(x) for x in sorted(random_input)] + assert sorted_result == [ + "0.1.0", + "0.1.0", + "0.1.1-dev1", + "0.1.1", + "0.1.1", + "0.2.0", + "0.2.0", + "0.2.0", + "0.3.0-dev1", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.1-a0", + "0.3.1-a0", + "0.3.1-a0", + "0.3.1-a0", + "0.3.1-a1", + "0.3.1-a1", + "0.3.1-a1", + "0.3.1", + "0.3.1", + "0.3.1", + "0.3.2", + "0.4.2", + "1.0.0-a0", + "1.0.0-a0", + "1.0.0-a1", + "1.0.0-a1", + "1.0.0-a1", + "1.0.0-a1", + "1.0.0-a2-dev0", + "1.0.0-a2-dev0", + "1.0.0-a2-dev1", + "1.0.0-a2", + "1.0.0-a3-dev0", + "1.0.0-a3-dev0", + "1.0.0-a3-dev1", + "1.0.0-b0", + "1.0.0-b0", + "1.0.0-b0", + "1.0.0-b1", + "1.0.0-b1", + "1.0.0-rc0", + "1.0.0-rc0", + "1.0.0-rc0", + "1.0.0-rc0", + "1.0.0-rc1-dev1", + "1.0.0-rc1", + "1.0.0", + "1.0.0", + "1.0.1", + "1.0.1", + "1.0.2", + "1.0.2", + "1.1.0", + "1.1.0", + "1.2.0", + "1.2.0", + "1.2.1", + "1.2.1", + "2.0.0", + ] From c1b13865a0836bd3e439db481d4f820fcc32eb5e Mon Sep 17 00:00:00 2001 From: Chad Dombrova Date: Sat, 3 Feb 2024 16:58:49 -0800 Subject: [PATCH 022/598] fix(bump): remove unused method --- commitizen/commands/bump.py | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 023d4f805b..2b108b26c5 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -27,7 +27,6 @@ from commitizen.version_schemes import ( get_version_scheme, InvalidVersion, - VersionProtocol, ) logger = getLogger("commitizen") @@ -397,33 +396,3 @@ def _get_commit_args(self): if self.no_verify: commit_args.append("--no-verify") return " ".join(commit_args) - - def find_previous_final_version( - self, current_version: VersionProtocol - ) -> VersionProtocol | None: - tag_format: str = self.bump_settings["tag_format"] - current = bump.normalize_tag( - current_version, - tag_format=tag_format, - scheme=self.scheme, - ) - - final_versions = [] - for tag in git.get_tag_names(): - assert tag - try: - version = self.scheme(tag) - if not version.is_prerelease or tag == current: - final_versions.append(version) - except InvalidVersion: - continue - - if not final_versions: - return None - - final_versions = sorted(final_versions) - current_index = final_versions.index(current_version) - previous_index = current_index - 1 - if previous_index < 0: - return None - return final_versions[previous_index] From 4055bbb444ea66dca166828d6bc11bf7ba7fc157 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 4 Feb 2024 08:20:31 +0000 Subject: [PATCH 023/598] =?UTF-8?q?bump:=20version=203.14.0=20=E2=86=92=20?= =?UTF-8?q?3.14.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 7 +++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 55836498a0..6556a068ba 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.14.0 # automatically updated by Commitizen + rev: v3.14.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ad6367e31..db06703c98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,11 @@ +## v3.14.1 (2024-02-04) + +### Fix + +- **bump**: remove unused method +- **scm**: only search tags that are reachable by the current commit + ## v3.14.0 (2024-02-01) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 382c7be006..237d3a709b 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.14.0" +__version__ = "3.14.1" diff --git a/pyproject.toml b/pyproject.toml index 37603738f7..455693e9b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.14.0" +version = "3.14.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.14.0" +version = "3.14.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 6b675292a3dcf300a50ca81ef7cf664e4e916a86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 01:21:55 +0000 Subject: [PATCH 024/598] build(deps-dev): bump mkdocs-material from 9.5.6 to 9.5.7 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.6 to 9.5.7. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.6...9.5.7) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d0be3bc97b..22ad17fa7f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.6" +version = "9.5.7" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.6-py3-none-any.whl", hash = "sha256:e115b90fccf5cd7f5d15b0c2f8e6246b21041628b8f590630e7fca66ed7fcf6c"}, - {file = "mkdocs_material-9.5.6.tar.gz", hash = "sha256:5b24df36d8ac6cecd611241ce6f6423ccde3e1ad89f8360c3f76d5565fc2d82a"}, + {file = "mkdocs_material-9.5.7-py3-none-any.whl", hash = "sha256:0be8ce8bcfebb52bae9b00cf9b851df45b8a92d629afcfd7f2c09b2dfa155ea3"}, + {file = "mkdocs_material-9.5.7.tar.gz", hash = "sha256:16110292575d88a338d2961f3cb665cf12943ff8829e551a9b364f24019e46af"}, ] [package.dependencies] From 56129248b32abd131aa866ed01a31193b77a2d54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 01:26:50 +0000 Subject: [PATCH 025/598] build(deps-dev): bump ruff from 0.2.0 to 0.2.1 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.0 to 0.2.1. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.2.0...v0.2.1) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 22ad17fa7f..13711f36b3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.2.0" +version = "0.2.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:638ea3294f800d18bae84a492cb5a245c8d29c90d19a91d8e338937a4c27fca0"}, - {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3ff35433fcf4dff6d610738712152df6b7d92351a1bde8e00bd405b08b3d5759"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9faafbdcf4f53917019f2c230766da437d4fd5caecd12ddb68bb6a17d74399"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8153a3e4128ed770871c47545f1ae7b055023e0c222ff72a759f5a341ee06483"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a75a98ae989a27090e9c51f763990ad5bbc92d20626d54e9701c7fe597f399"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:87057dd2fdde297130ff99553be8549ca38a2965871462a97394c22ed2dfc19d"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d232f99d3ab00094ebaf88e0fb7a8ccacaa54cc7fa3b8993d9627a11e6aed7a"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3c641f95f435fc6754b05591774a17df41648f0daf3de0d75ad3d9f099ab92"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3826fb34c144ef1e171b323ed6ae9146ab76d109960addca730756dc19dc7b22"}, - {file = "ruff-0.2.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eceab7d85d09321b4de18b62d38710cf296cb49e98979960a59c6b9307c18cfe"}, - {file = "ruff-0.2.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:30ad74687e1f4a9ff8e513b20b82ccadb6bd796fe5697f1e417189c5cde6be3e"}, - {file = "ruff-0.2.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7e3818698f8460bd0f8d4322bbe99db8327e9bc2c93c789d3159f5b335f47da"}, - {file = "ruff-0.2.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:edf23041242c48b0d8295214783ef543847ef29e8226d9f69bf96592dba82a83"}, - {file = "ruff-0.2.0-py3-none-win32.whl", hash = "sha256:e155147199c2714ff52385b760fe242bb99ea64b240a9ffbd6a5918eb1268843"}, - {file = "ruff-0.2.0-py3-none-win_amd64.whl", hash = "sha256:ba918e01cdd21e81b07555564f40d307b0caafa9a7a65742e98ff244f5035c59"}, - {file = "ruff-0.2.0-py3-none-win_arm64.whl", hash = "sha256:3fbaff1ba9564a2c5943f8f38bc221f04bac687cc7485e45237579fee7ccda79"}, - {file = "ruff-0.2.0.tar.gz", hash = "sha256:63856b91837606c673537d2889989733d7dffde553828d3b0f0bacfa6def54be"}, + {file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:dd81b911d28925e7e8b323e8d06951554655021df8dd4ac3045d7212ac4ba080"}, + {file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:dc586724a95b7d980aa17f671e173df00f0a2eef23f8babbeee663229a938fec"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c92db7101ef5bfc18e96777ed7bc7c822d545fa5977e90a585accac43d22f18a"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13471684694d41ae0f1e8e3a7497e14cd57ccb7dd72ae08d56a159d6c9c3e30e"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a11567e20ea39d1f51aebd778685582d4c56ccb082c1161ffc10f79bebe6df35"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:00a818e2db63659570403e44383ab03c529c2b9678ba4ba6c105af7854008105"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be60592f9d218b52f03384d1325efa9d3b41e4c4d55ea022cd548547cc42cd2b"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbd2288890b88e8aab4499e55148805b58ec711053588cc2f0196a44f6e3d855"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ef052283da7dec1987bba8d8733051c2325654641dfe5877a4022108098683"}, + {file = "ruff-0.2.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7022d66366d6fded4ba3889f73cd791c2d5621b2ccf34befc752cb0df70f5fad"}, + {file = "ruff-0.2.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0a725823cb2a3f08ee743a534cb6935727d9e47409e4ad72c10a3faf042ad5ba"}, + {file = "ruff-0.2.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0034d5b6323e6e8fe91b2a1e55b02d92d0b582d2953a2b37a67a2d7dedbb7acc"}, + {file = "ruff-0.2.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e5cb5526d69bb9143c2e4d2a115d08ffca3d8e0fddc84925a7b54931c96f5c02"}, + {file = "ruff-0.2.1-py3-none-win32.whl", hash = "sha256:6b95ac9ce49b4fb390634d46d6ece32ace3acdd52814671ccaf20b7f60adb232"}, + {file = "ruff-0.2.1-py3-none-win_amd64.whl", hash = "sha256:e3affdcbc2afb6f5bd0eb3130139ceedc5e3f28d206fe49f63073cb9e65988e0"}, + {file = "ruff-0.2.1-py3-none-win_arm64.whl", hash = "sha256:efababa8e12330aa94a53e90a81eb6e2d55f348bc2e71adbf17d9cad23c03ee6"}, + {file = "ruff-0.2.1.tar.gz", hash = "sha256:3b42b5d8677cd0c72b99fcaf068ffc62abb5a19e71b4a3b9cfa50658a0af02f1"}, ] [[package]] From 1d842b5d823a452109070f8af8857249e95f7713 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 02:02:39 +0000 Subject: [PATCH 026/598] build(deps-dev): bump mkdocs-material from 9.5.7 to 9.5.8 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.7 to 9.5.8. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.7...9.5.8) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 13711f36b3..a148ab8e83 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.7" +version = "9.5.8" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.7-py3-none-any.whl", hash = "sha256:0be8ce8bcfebb52bae9b00cf9b851df45b8a92d629afcfd7f2c09b2dfa155ea3"}, - {file = "mkdocs_material-9.5.7.tar.gz", hash = "sha256:16110292575d88a338d2961f3cb665cf12943ff8829e551a9b364f24019e46af"}, + {file = "mkdocs_material-9.5.8-py3-none-any.whl", hash = "sha256:14563314bbf97da4bfafc69053772341babfaeb3329cde01d3e63cec03997af8"}, + {file = "mkdocs_material-9.5.8.tar.gz", hash = "sha256:2a429213e83f84eda7a588e2b186316d806aac602b7f93990042f7a1f3d3cf65"}, ] [package.dependencies] @@ -767,7 +767,7 @@ regex = ">=2022.4" requests = ">=2.26,<3.0" [package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] From 730a28a8b1ae9529fd7b4324b4e0b931786928fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 01:36:16 +0000 Subject: [PATCH 027/598] build(deps-dev): bump mkdocs-material from 9.5.8 to 9.5.9 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.8 to 9.5.9. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.8...9.5.9) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index a148ab8e83..21e87431db 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.8" +version = "9.5.9" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.8-py3-none-any.whl", hash = "sha256:14563314bbf97da4bfafc69053772341babfaeb3329cde01d3e63cec03997af8"}, - {file = "mkdocs_material-9.5.8.tar.gz", hash = "sha256:2a429213e83f84eda7a588e2b186316d806aac602b7f93990042f7a1f3d3cf65"}, + {file = "mkdocs_material-9.5.9-py3-none-any.whl", hash = "sha256:a5d62b73b3b74349e45472bfadc129c871dd2d4add68d84819580597b2f50d5d"}, + {file = "mkdocs_material-9.5.9.tar.gz", hash = "sha256:635df543c01c25c412d6c22991872267723737d5a2f062490f33b2da1c013c6d"}, ] [package.dependencies] From 3e51e8878cffc858fc992b8e33e07eb1cd1c2e26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 01:35:56 +0000 Subject: [PATCH 028/598] build(deps-dev): bump black from 24.1.1 to 24.2.0 Bumps [black](https://github.com/psf/black) from 24.1.1 to 24.2.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/24.1.1...24.2.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/poetry.lock b/poetry.lock index 21e87431db..b05a5ab1f5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -73,33 +73,33 @@ files = [ [[package]] name = "black" -version = "24.1.1" +version = "24.2.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2588021038bd5ada078de606f2a804cadd0a3cc6a79cb3e9bb3a8bf581325a4c"}, - {file = "black-24.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a95915c98d6e32ca43809d46d932e2abc5f1f7d582ffbe65a5b4d1588af7445"}, - {file = "black-24.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa6a0e965779c8f2afb286f9ef798df770ba2b6cee063c650b96adec22c056a"}, - {file = "black-24.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5242ecd9e990aeb995b6d03dc3b2d112d4a78f2083e5a8e86d566340ae80fec4"}, - {file = "black-24.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc1ec9aa6f4d98d022101e015261c056ddebe3da6a8ccfc2c792cbe0349d48b7"}, - {file = "black-24.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0269dfdea12442022e88043d2910429bed717b2d04523867a85dacce535916b8"}, - {file = "black-24.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d64db762eae4a5ce04b6e3dd745dcca0fb9560eb931a5be97472e38652a161"}, - {file = "black-24.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5d7b06ea8816cbd4becfe5f70accae953c53c0e53aa98730ceccb0395520ee5d"}, - {file = "black-24.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e2c8dfa14677f90d976f68e0c923947ae68fa3961d61ee30976c388adc0b02c8"}, - {file = "black-24.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a21725862d0e855ae05da1dd25e3825ed712eaaccef6b03017fe0853a01aa45e"}, - {file = "black-24.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07204d078e25327aad9ed2c64790d681238686bce254c910de640c7cc4fc3aa6"}, - {file = "black-24.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a83fe522d9698d8f9a101b860b1ee154c1d25f8a82ceb807d319f085b2627c5b"}, - {file = "black-24.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08b34e85170d368c37ca7bf81cf67ac863c9d1963b2c1780c39102187ec8dd62"}, - {file = "black-24.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7258c27115c1e3b5de9ac6c4f9957e3ee2c02c0b39222a24dc7aa03ba0e986f5"}, - {file = "black-24.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40657e1b78212d582a0edecafef133cf1dd02e6677f539b669db4746150d38f6"}, - {file = "black-24.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e298d588744efda02379521a19639ebcd314fba7a49be22136204d7ed1782717"}, - {file = "black-24.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34afe9da5056aa123b8bfda1664bfe6fb4e9c6f311d8e4a6eb089da9a9173bf9"}, - {file = "black-24.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:854c06fb86fd854140f37fb24dbf10621f5dab9e3b0c29a690ba595e3d543024"}, - {file = "black-24.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3897ae5a21ca132efa219c029cce5e6bfc9c3d34ed7e892113d199c0b1b444a2"}, - {file = "black-24.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:ecba2a15dfb2d97105be74bbfe5128bc5e9fa8477d8c46766505c1dda5883aac"}, - {file = "black-24.1.1-py3-none-any.whl", hash = "sha256:5cdc2e2195212208fbcae579b931407c1fa9997584f0a415421748aeafff1168"}, - {file = "black-24.1.1.tar.gz", hash = "sha256:48b5760dcbfe5cf97fd4fba23946681f3a81514c6ab8a45b50da67ac8fbc6c7b"}, + {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, + {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, + {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, + {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, + {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, + {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, + {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, + {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, + {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, + {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, + {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, + {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, + {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, + {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, + {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, + {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, + {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, + {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, + {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, + {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, + {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, + {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, ] [package.dependencies] From 981065ea129fb2b1eabe7a18e579dd28f0eccd32 Mon Sep 17 00:00:00 2001 From: Lars Solberg Date: Fri, 29 Dec 2023 00:41:20 +0100 Subject: [PATCH 029/598] feat(bump): functionality to add build-metadata to version string --- commitizen/cli.py | 5 +++ commitizen/commands/bump.py | 13 +++++++ commitizen/commands/changelog.py | 12 +++++- commitizen/cz/utils.py | 6 +++ commitizen/version_schemes.py | 17 ++++++++- docs/bump.md | 23 +++++++++++- tests/commands/test_bump_command.py | 2 + tests/test_bump_create_commit_message.py | 47 ++++++++++++++++++++++++ 8 files changed, 121 insertions(+), 4 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 511f745652..12e3aa6451 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -308,6 +308,11 @@ def __call__( "help": "bump to the given version (e.g: 1.5.3)", "metavar": "MANUAL_VERSION", }, + { + "name": ["--build-metadata"], + "help": "Add additional build-metadata to the version-number", + "default": None, + }, ], }, { diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 2b108b26c5..7eb9ead144 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -155,6 +155,7 @@ def __call__(self): # noqa: C901 is_files_only: bool | None = self.arguments["files_only"] is_local_version: bool | None = self.arguments["local_version"] manual_version = self.arguments["manual_version"] + build_metadata = self.arguments["build_metadata"] if manual_version: if increment: @@ -171,6 +172,11 @@ def __call__(self): # noqa: C901 "--local-version cannot be combined with MANUAL_VERSION" ) + if build_metadata: + raise NotAllowed( + "--build-metadata cannot be combined with MANUAL_VERSION" + ) + if major_version_zero: raise NotAllowed( "--major-version-zero cannot be combined with MANUAL_VERSION" @@ -187,6 +193,12 @@ def __call__(self): # noqa: C901 f"--major-version-zero is meaningless for current version {current_version}" ) + if build_metadata: + if is_local_version: + raise NotAllowed( + "--local-version cannot be combined with --build-metadata" + ) + current_tag_version: str = bump.normalize_tag( current_version, tag_format=tag_format, @@ -235,6 +247,7 @@ def __call__(self): # noqa: C901 prerelease_offset=prerelease_offset, devrelease=devrelease, is_local_version=is_local_version, + build_metadata=build_metadata, ) new_tag_version = bump.normalize_tag( diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 8b3c309636..f44f59bb7c 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -20,6 +20,7 @@ from commitizen.changelog_formats import get_changelog_format from commitizen.git import GitTag, smart_open from commitizen.version_schemes import get_version_scheme +from commitizen.cz.utils import strip_local_version class Changelog: @@ -98,7 +99,12 @@ def _find_incremental_rev(self, latest_version: str, tags: list[GitTag]) -> str: """ SIMILARITY_THRESHOLD = 0.89 tag_ratio = map( - lambda tag: (SequenceMatcher(None, latest_version, tag.name).ratio(), tag), + lambda tag: ( + SequenceMatcher( + None, latest_version, strip_local_version(tag.name) + ).ratio(), + tag, + ), tags, ) try: @@ -169,7 +175,9 @@ def __call__(self): tag_format=self.tag_format, scheme=self.scheme, ) - start_rev = self._find_incremental_rev(latest_tag_version, tags) + start_rev = self._find_incremental_rev( + strip_local_version(latest_tag_version), tags + ) if self.rev_range: start_rev, end_rev = changelog.get_oldest_and_newest_rev( diff --git a/commitizen/cz/utils.py b/commitizen/cz/utils.py index ea13be22c5..71dac105a7 100644 --- a/commitizen/cz/utils.py +++ b/commitizen/cz/utils.py @@ -1,3 +1,5 @@ +import re + from commitizen.cz import exceptions @@ -9,3 +11,7 @@ def required_validator(answer, msg=None): def multiple_line_breaker(answer, sep="|"): return "\n".join(line.strip() for line in answer.split(sep) if line) + + +def strip_local_version(version: str) -> str: + return re.sub(r"\+.+", "", version) diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 8fcec9e74f..0b04c4bc36 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -118,6 +118,7 @@ def bump( prerelease_offset: int = 0, devrelease: int | None = None, is_local_version: bool = False, + build_metadata: str | None = None, force_bump: bool = False, ) -> Self: """ @@ -191,6 +192,17 @@ def generate_devrelease(self, devrelease: int | None) -> str: return f"dev{devrelease}" + def generate_build_metadata(self, build_metadata: str | None) -> str: + """Generate build-metadata + + Build-metadata (local version) is not used in version calculations + but added after + statically. + """ + if build_metadata is None: + return "" + + return f"+{build_metadata}" + def increment_base(self, increment: str | None = None) -> str: prev_release = list(self.release) increments = [MAJOR, MINOR, PATCH] @@ -215,6 +227,7 @@ def bump( prerelease_offset: int = 0, devrelease: int | None = None, is_local_version: bool = False, + build_metadata: str | None = None, force_bump: bool = False, ) -> Self: """Based on the given increment a proper semver will be generated. @@ -248,6 +261,7 @@ def bump( if self.minor != 0 or self.micro != 0: base = self.increment_base(increment) dev_version = self.generate_devrelease(devrelease) + release = list(self.release) if len(release) < 3: release += [0] * (3 - len(release)) @@ -261,8 +275,9 @@ def bump( pre_version = base_version.generate_prerelease( prerelease, offset=prerelease_offset ) + build_metadata = self.generate_build_metadata(build_metadata) # TODO: post version - return self.scheme(f"{base}{pre_version}{dev_version}") # type: ignore + return self.scheme(f"{base}{pre_version}{dev_version}{build_metadata}") # type: ignore class Pep440(BaseVersion): diff --git a/docs/bump.md b/docs/bump.md index 7bf6689231..6045024dd4 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -55,7 +55,7 @@ $ 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}] [--check-consistency] [--annotated-tag] [--gpg-sign] [--changelog-to-stdout] [--git-output-to-stderr] [--retry] [--major-version-zero] - [--prerelease-offset PRERELEASE_OFFSET] [--version-scheme {semver,pep440}] [--version-type {semver,pep440}] + [--prerelease-offset PRERELEASE_OFFSET] [--version-scheme {semver,pep440}] [--version-type {semver,pep440}] [--build-metadata BUILD_METADATA] [MANUAL_VERSION] positional arguments: @@ -95,6 +95,8 @@ options: choose version scheme --version-type {semver,pep440} Deprecated, use --version-scheme + --build-metadata {BUILD_METADATA} + additional metadata in the version string ``` ### `--files-only` @@ -292,6 +294,25 @@ cz bump --changelog --extra key=value -e short="quoted value" See [the template customization section](customization.md#customizing-the-changelog-template). +### `--build-metadata` + +Provides a way to specify additional metadata in the version string. This parameter is not compatible with `--local-version` as it uses the same part of the version string. + +```bash +cz bump --build-metadata yourmetadata +``` + +Will create a version like `1.1.2+yourmetadata`. +This can be useful for multiple things +* Git hash in version +* Labeling the version with additional metadata. + +Note that Commitizen ignores everything after `+` when it bumps the version. It is therefore safe to write different build-metadata between versions. + +You should normally not use this functionality, but if you decide to do, keep in mind that +* Version `1.2.3+a`, and `1.2.3+b` are the same version! Tools should not use the string after `+` for version calculation. This is probably not a guarantee (example in helm) even tho it is in the spec. +* It might be problematic having the metadata in place when doing upgrades depending on what tool you use. + ## Avoid raising errors Some situations from commitizen raise an exit code different than 0. diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index d05c8f3301..9a877c9ac0 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -813,6 +813,8 @@ def test_bump_changelog_command_commits_untracked_changelog_and_version_files( ["cz", "bump", "--devrelease", "0", "1.2.3"], ["cz", "bump", "--devrelease", "1", "1.2.3"], ["cz", "bump", "--increment", "PATCH", "1.2.3"], + ["cz", "bump", "--build-metadata=a.b.c", "1.2.3"], + ["cz", "bump", "--local-version", "--build-metadata=a.b.c"], ], ) @pytest.mark.usefixtures("tmp_commitizen_project") diff --git a/tests/test_bump_create_commit_message.py b/tests/test_bump_create_commit_message.py index c096f23c39..517c7a0459 100644 --- a/tests/test_bump_create_commit_message.py +++ b/tests/test_bump_create_commit_message.py @@ -99,3 +99,50 @@ def test_bump_pre_commit_changelog_fails_always(mocker: MockFixture, freezer, re cmd.run("pre-commit install") with pytest.raises(exceptions.BumpCommitFailedError): cli.main() + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_with_build_metadata(mocker: MockFixture, freezer): + def _add_entry(test_str: str, args: list): + Path(test_str).write_text("") + cmd.run("git add -A") + cmd.run(f'git commit -m "fix: test-{test_str}"') + cz_args = ["cz", "bump", "--changelog", "--yes"] + args + mocker.patch.object(sys, "argv", cz_args) + cli.main() + + freezer.move_to("2024-01-01") + + _add_entry("a", ["--build-metadata", "a.b.c"]) + _add_entry("b", []) + _add_entry("c", ["--build-metadata", "alongmetadatastring"]) + _add_entry("d", []) + + # Pre-commit fixed last line adding extra indent and "\" char + assert Path("CHANGELOG.md").read_text() == dedent( + """\ + ## 0.1.4 (2024-01-01) + + ### Fix + + - test-d + + ## 0.1.3+alongmetadatastring (2024-01-01) + + ### Fix + + - test-c + + ## 0.1.2 (2024-01-01) + + ### Fix + + - test-b + + ## 0.1.1+a.b.c (2024-01-01) + + ### Fix + + - test-a + """ + ) From 2ee371be1bb6f5da2811e50e307a3562165fcd47 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 17 Feb 2024 03:21:49 +0000 Subject: [PATCH 030/598] =?UTF-8?q?bump:=20version=203.14.1=20=E2=86=92=20?= =?UTF-8?q?3.15.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6556a068ba..c1120176b9 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.14.1 # automatically updated by Commitizen + rev: v3.15.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index db06703c98..c61279fe1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +## v3.15.0 (2024-02-17) + +### Feat + +- **bump**: functionality to add build-metadata to version string + ## v3.14.1 (2024-02-04) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 237d3a709b..11d9fee7b3 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.14.1" +__version__ = "3.15.0" diff --git a/pyproject.toml b/pyproject.toml index 455693e9b6..a8ef9705cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.14.1" +version = "3.15.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.14.1" +version = "3.15.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From ab8873b7245f77bf4aba06995e8a525366042739 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 01:29:27 +0000 Subject: [PATCH 031/598] build(deps-dev): bump ruff from 0.2.1 to 0.2.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.1 to 0.2.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.2.1...v0.2.2) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index b05a5ab1f5..7087b33be2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.2.1" +version = "0.2.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:dd81b911d28925e7e8b323e8d06951554655021df8dd4ac3045d7212ac4ba080"}, - {file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:dc586724a95b7d980aa17f671e173df00f0a2eef23f8babbeee663229a938fec"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c92db7101ef5bfc18e96777ed7bc7c822d545fa5977e90a585accac43d22f18a"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13471684694d41ae0f1e8e3a7497e14cd57ccb7dd72ae08d56a159d6c9c3e30e"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a11567e20ea39d1f51aebd778685582d4c56ccb082c1161ffc10f79bebe6df35"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:00a818e2db63659570403e44383ab03c529c2b9678ba4ba6c105af7854008105"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be60592f9d218b52f03384d1325efa9d3b41e4c4d55ea022cd548547cc42cd2b"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbd2288890b88e8aab4499e55148805b58ec711053588cc2f0196a44f6e3d855"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ef052283da7dec1987bba8d8733051c2325654641dfe5877a4022108098683"}, - {file = "ruff-0.2.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7022d66366d6fded4ba3889f73cd791c2d5621b2ccf34befc752cb0df70f5fad"}, - {file = "ruff-0.2.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0a725823cb2a3f08ee743a534cb6935727d9e47409e4ad72c10a3faf042ad5ba"}, - {file = "ruff-0.2.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0034d5b6323e6e8fe91b2a1e55b02d92d0b582d2953a2b37a67a2d7dedbb7acc"}, - {file = "ruff-0.2.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e5cb5526d69bb9143c2e4d2a115d08ffca3d8e0fddc84925a7b54931c96f5c02"}, - {file = "ruff-0.2.1-py3-none-win32.whl", hash = "sha256:6b95ac9ce49b4fb390634d46d6ece32ace3acdd52814671ccaf20b7f60adb232"}, - {file = "ruff-0.2.1-py3-none-win_amd64.whl", hash = "sha256:e3affdcbc2afb6f5bd0eb3130139ceedc5e3f28d206fe49f63073cb9e65988e0"}, - {file = "ruff-0.2.1-py3-none-win_arm64.whl", hash = "sha256:efababa8e12330aa94a53e90a81eb6e2d55f348bc2e71adbf17d9cad23c03ee6"}, - {file = "ruff-0.2.1.tar.gz", hash = "sha256:3b42b5d8677cd0c72b99fcaf068ffc62abb5a19e71b4a3b9cfa50658a0af02f1"}, + {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0a9efb032855ffb3c21f6405751d5e147b0c6b631e3ca3f6b20f917572b97eb6"}, + {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d450b7fbff85913f866a5384d8912710936e2b96da74541c82c1b458472ddb39"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecd46e3106850a5c26aee114e562c329f9a1fbe9e4821b008c4404f64ff9ce73"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e22676a5b875bd72acd3d11d5fa9075d3a5f53b877fe7b4793e4673499318ba"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1695700d1e25a99d28f7a1636d85bafcc5030bba9d0578c0781ba1790dbcf51c"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b0c232af3d0bd8f521806223723456ffebf8e323bd1e4e82b0befb20ba18388e"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f63d96494eeec2fc70d909393bcd76c69f35334cdbd9e20d089fb3f0640216ca"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a61ea0ff048e06de273b2e45bd72629f470f5da8f71daf09fe481278b175001"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1439c8f407e4f356470e54cdecdca1bd5439a0673792dbe34a2b0a551a2fe3"}, + {file = "ruff-0.2.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:940de32dc8853eba0f67f7198b3e79bc6ba95c2edbfdfac2144c8235114d6726"}, + {file = "ruff-0.2.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c126da55c38dd917621552ab430213bdb3273bb10ddb67bc4b761989210eb6e"}, + {file = "ruff-0.2.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3b65494f7e4bed2e74110dac1f0d17dc8e1f42faaa784e7c58a98e335ec83d7e"}, + {file = "ruff-0.2.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1ec49be4fe6ddac0503833f3ed8930528e26d1e60ad35c2446da372d16651ce9"}, + {file = "ruff-0.2.2-py3-none-win32.whl", hash = "sha256:d920499b576f6c68295bc04e7b17b6544d9d05f196bb3aac4358792ef6f34325"}, + {file = "ruff-0.2.2-py3-none-win_amd64.whl", hash = "sha256:cc9a91ae137d687f43a44c900e5d95e9617cb37d4c989e462980ba27039d239d"}, + {file = "ruff-0.2.2-py3-none-win_arm64.whl", hash = "sha256:c9d15fc41e6054bfc7200478720570078f0b41c9ae4f010bcc16bd6f4d1aacdd"}, + {file = "ruff-0.2.2.tar.gz", hash = "sha256:e62ed7f36b3068a30ba39193a14274cd706bc486fad521276458022f7bccb31d"}, ] [[package]] From 80ad200925ec6a54d25f67a404519201ede72d80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 01:30:13 +0000 Subject: [PATCH 032/598] build(deps-dev): bump pytest from 8.0.0 to 8.0.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.0 to 8.0.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.0.0...8.0.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7087b33be2..fe5bfbe014 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1048,13 +1048,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.0.0" +version = "8.0.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"}, - {file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"}, + {file = "pytest-8.0.1-py3-none-any.whl", hash = "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca"}, + {file = "pytest-8.0.1.tar.gz", hash = "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae"}, ] [package.dependencies] From e8362ccfcbf31e9633f3fba9c8d46a32bc7ca35d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 01:20:54 +0000 Subject: [PATCH 033/598] build(deps-dev): bump mkdocs-material from 9.5.9 to 9.5.10 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.9 to 9.5.10. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.9...9.5.10) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index fe5bfbe014..11ca81c1a7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.9" +version = "9.5.10" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.9-py3-none-any.whl", hash = "sha256:a5d62b73b3b74349e45472bfadc129c871dd2d4add68d84819580597b2f50d5d"}, - {file = "mkdocs_material-9.5.9.tar.gz", hash = "sha256:635df543c01c25c412d6c22991872267723737d5a2f062490f33b2da1c013c6d"}, + {file = "mkdocs_material-9.5.10-py3-none-any.whl", hash = "sha256:3c6c46b57d2ee3c8890e6e0406e68b6863cf65768f0f436990a742702d198442"}, + {file = "mkdocs_material-9.5.10.tar.gz", hash = "sha256:6ad626dbb31070ebbaedff813323a16a406629620e04b96458f16e6e9c7008fe"}, ] [package.dependencies] From 26329cf73e777efc88f70958379a408460b16e1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 01:49:05 +0000 Subject: [PATCH 034/598] build(deps-dev): bump pytest from 8.0.1 to 8.0.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.1 to 8.0.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.0.1...8.0.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 11ca81c1a7..c253b8faab 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1048,13 +1048,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.0.1" +version = "8.0.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.0.1-py3-none-any.whl", hash = "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca"}, - {file = "pytest-8.0.1.tar.gz", hash = "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae"}, + {file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"}, + {file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"}, ] [package.dependencies] From c1467c83cd98e6a243458c7fe208a6f741f1c746 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 02:33:21 +0000 Subject: [PATCH 035/598] build(deps): bump typing-extensions from 4.9.0 to 4.10.0 Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.9.0 to 4.10.0. - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/commits) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index c253b8faab..a02c025e14 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1574,13 +1574,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.9.0" +version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, - {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] [[package]] From 74153b740e881df70e7680599217fa246489199b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 03:32:18 +0000 Subject: [PATCH 036/598] build(deps-dev): bump mkdocs-material from 9.5.10 to 9.5.11 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.10 to 9.5.11. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.10...9.5.11) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index a02c025e14..9f02b028b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.10" +version = "9.5.11" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.10-py3-none-any.whl", hash = "sha256:3c6c46b57d2ee3c8890e6e0406e68b6863cf65768f0f436990a742702d198442"}, - {file = "mkdocs_material-9.5.10.tar.gz", hash = "sha256:6ad626dbb31070ebbaedff813323a16a406629620e04b96458f16e6e9c7008fe"}, + {file = "mkdocs_material-9.5.11-py3-none-any.whl", hash = "sha256:788ee0f3e036dca2dc20298d65e480297d348a44c9d7b2ee05c5262983e66072"}, + {file = "mkdocs_material-9.5.11.tar.gz", hash = "sha256:7af7f8af0dea16175558f3fb9245d26c83a17199baa5f157755e63d7437bf971"}, ] [package.dependencies] From ddab5463ded3f030fe7722f5a50a01bef89be9eb Mon Sep 17 00:00:00 2001 From: Chad Dombrova Date: Sun, 4 Feb 2024 21:18:35 -0800 Subject: [PATCH 037/598] fix: Improve type annotations --- commitizen/bump.py | 7 ++++--- commitizen/commands/bump.py | 14 ++++++++------ commitizen/version_schemes.py | 23 +++++++++++++++++------ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/commitizen/bump.py b/commitizen/bump.py index 74d08381dc..f0e45e3432 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -4,18 +4,19 @@ import re from collections import OrderedDict from string import Template +from typing import cast 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 +from commitizen.version_schemes import DEFAULT_SCHEME, Increment, Version, VersionScheme VERSION_TYPES = [None, PATCH, MINOR, MAJOR] def find_increment( commits: list[GitCommit], regex: str, increments_map: dict | OrderedDict -) -> str | None: +) -> Increment | None: if isinstance(increments_map, dict): increments_map = OrderedDict(increments_map) @@ -42,7 +43,7 @@ def find_increment( if increment == MAJOR: break - return increment + return cast(Increment, increment) def update_version_in_files( diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 7eb9ead144..9464b0bab1 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -26,7 +26,9 @@ from commitizen.providers import get_provider from commitizen.version_schemes import ( get_version_scheme, + Increment, InvalidVersion, + Prerelease, ) logger = getLogger("commitizen") @@ -112,7 +114,7 @@ def is_initial_tag(self, current_tag_version: str, is_yes: bool = False) -> bool is_initial = questionary.confirm("Is this the first tag created?").ask() return is_initial - def find_increment(self, commits: list[git.GitCommit]) -> str | None: + def find_increment(self, commits: list[git.GitCommit]) -> Increment | None: # Update the bump map to ensure major version doesn't increment. is_major_version_zero: bool = self.bump_settings["major_version_zero"] # self.cz.bump_map = defaults.bump_map_major_version_zero @@ -132,7 +134,7 @@ def find_increment(self, commits: list[git.GitCommit]) -> str | None: ) return increment - def __call__(self): # noqa: C901 + def __call__(self) -> None: # noqa: C901 """Steps executed to bump.""" provider = get_provider(self.config) @@ -149,11 +151,11 @@ def __call__(self): # noqa: C901 dry_run: bool = self.arguments["dry_run"] is_yes: bool = self.arguments["yes"] - increment: str | None = self.arguments["increment"] - prerelease: str | None = self.arguments["prerelease"] + increment: Increment | None = self.arguments["increment"] + prerelease: Prerelease | None = self.arguments["prerelease"] devrelease: int | None = self.arguments["devrelease"] is_files_only: bool | None = self.arguments["files_only"] - is_local_version: bool | None = self.arguments["local_version"] + is_local_version: bool = self.arguments["local_version"] manual_version = self.arguments["manual_version"] build_metadata = self.arguments["build_metadata"] @@ -404,7 +406,7 @@ def __call__(self): # noqa: C901 else: out.success("Done!") - def _get_commit_args(self): + def _get_commit_args(self) -> str: commit_args = ["-a"] if self.no_verify: commit_args.append("--no-verify") diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 0b04c4bc36..aeebe6cc35 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -4,7 +4,16 @@ import sys import warnings from itertools import zip_longest -from typing import TYPE_CHECKING, Any, ClassVar, Protocol, Type, cast, runtime_checkable +from typing import ( + TYPE_CHECKING, + Any, + ClassVar, + Literal, + Protocol, + Type, + cast, + runtime_checkable, +) import importlib_metadata as metadata from packaging.version import InvalidVersion # noqa: F401: Rexpose the common exception @@ -28,6 +37,8 @@ from typing import Self +Increment: TypeAlias = Literal["MAJOR", "MINOR", "PATCH"] +Prerelease: TypeAlias = Literal["alpha", "beta", "rc"] DEFAULT_VERSION_PARSER = r"v?(?P([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?(\w+)?)" @@ -113,8 +124,8 @@ def __ne__(self, other: object) -> bool: def bump( self, - increment: str, - prerelease: str | None = None, + increment: Increment | None, + prerelease: Prerelease | None = None, prerelease_offset: int = 0, devrelease: int | None = None, is_local_version: bool = False, @@ -203,7 +214,7 @@ def generate_build_metadata(self, build_metadata: str | None) -> str: return f"+{build_metadata}" - def increment_base(self, increment: str | None = None) -> str: + def increment_base(self, increment: Increment | None = None) -> str: prev_release = list(self.release) increments = [MAJOR, MINOR, PATCH] base = dict(zip_longest(increments, prev_release, fillvalue=0)) @@ -222,8 +233,8 @@ def increment_base(self, increment: str | None = None) -> str: def bump( self, - increment: str, - prerelease: str | None = None, + increment: Increment | None, + prerelease: Prerelease | None = None, prerelease_offset: int = 0, devrelease: int | None = None, is_local_version: bool = False, From 1059556c52e57ebf9d2baec84966bfad371af8f2 Mon Sep 17 00:00:00 2001 From: Chad Dombrova Date: Tue, 30 Jan 2024 09:39:24 -0800 Subject: [PATCH 038/598] feat(commands): add bump --exact When bumping a prerelease to a new prerelease, honor the detected increment and preserve the prerelease suffix, rather than bumping to the next non-prerelease version --- commitizen/cli.py | 10 ++++ commitizen/commands/bump.py | 4 ++ commitizen/version_schemes.py | 13 +++-- docs/bump.md | 21 ++++++++ tests/commands/test_bump_command.py | 49 +++++++++++++++++ tests/test_version_scheme_pep440.py | 82 +++++++++++++++++++++-------- tests/test_version_scheme_semver.py | 58 ++++++++++++++++++++ 7 files changed, 213 insertions(+), 24 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 12e3aa6451..a6dcaabd2a 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -230,6 +230,16 @@ def __call__( "choices": ["MAJOR", "MINOR", "PATCH"], "type": str.upper, }, + { + "name": ["--exact-increment"], + "action": "store_true", + "help": ( + "apply the exact changes that have been specified (or " + "determined from the commit log), disabling logic that " + "guesses the next version based on typical version " + "progression when a prelease suffix is present." + ), + }, { "name": ["--check-consistency", "-cc"], "help": ( diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 9464b0bab1..435c0039f9 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -52,6 +52,7 @@ def __init__(self, config: BaseConfig, arguments: dict): "tag_format", "prerelease", "increment", + "exact_increment", "bump_message", "gpg_sign", "annotated_tag", @@ -158,6 +159,7 @@ def __call__(self) -> None: # noqa: C901 is_local_version: bool = self.arguments["local_version"] manual_version = self.arguments["manual_version"] build_metadata = self.arguments["build_metadata"] + exact_increment: bool = self.arguments["exact_increment"] if manual_version: if increment: @@ -250,6 +252,7 @@ def __call__(self) -> None: # noqa: C901 devrelease=devrelease, is_local_version=is_local_version, build_metadata=build_metadata, + exact_increment=exact_increment, ) new_tag_version = bump.normalize_tag( @@ -351,6 +354,7 @@ def __call__(self) -> None: # noqa: C901 if is_files_only: raise ExpectedExit() + # FIXME: check if any changes have been staged c = git.commit(message, args=self._get_commit_args()) if self.retry and c.return_code != 0 and self.changelog: # Maybe pre-commit reformatted some files? Retry once diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index aeebe6cc35..ec04fde1e7 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -130,10 +130,17 @@ def bump( devrelease: int | None = None, is_local_version: bool = False, build_metadata: str | None = None, - force_bump: bool = False, + exact_increment: bool = False, ) -> Self: """ Based on the given increment, generate the next bumped version according to the version scheme + + Args: + increment: The component to increase + prerelease: The type of prerelease, if Any + is_local_version: Whether to increment the local version instead + exact_increment: Treat the increment and prerelease arguments explicitly. Disables logic + that attempts to deduce the correct increment when a prelease suffix is present. """ @@ -239,7 +246,7 @@ def bump( devrelease: int | None = None, is_local_version: bool = False, build_metadata: str | None = None, - force_bump: bool = False, + exact_increment: bool = False, ) -> Self: """Based on the given increment a proper semver will be generated. @@ -259,7 +266,7 @@ def bump( else: if not self.is_prerelease: base = self.increment_base(increment) - elif force_bump: + elif exact_increment: base = self.increment_base(increment) else: base = f"{self.major}.{self.minor}.{self.micro}" diff --git a/docs/bump.md b/docs/bump.md index 6045024dd4..904fb7dfc3 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -79,6 +79,7 @@ options: specify non-negative integer for dev. release --increment {MAJOR,MINOR,PATCH} manually specify the desired increment + --exact-increment apply the exact changes that have been specified (or determined from the commit log), disabling logic that guesses the next version based on typical version progression when a prelease suffix is present. --check-consistency, -cc check consistency among versions defined in commitizen configuration and version_files --annotated-tag, -at create annotated tag instead of lightweight one @@ -142,6 +143,26 @@ by their precedence and showcase how a release might flow through a development Also note that bumping pre-releases _maintains linearity_: bumping of a pre-release with lower precedence than the current pre-release phase maintains the current phase of higher precedence. For example, if the current version is `1.0.0b1` then bumping with `--prerelease alpha` will continue to bump the “beta” phase. +This behavior can be overridden by passing `--exact-increment` (see below). + +### `--exact-increment` + +The `--exact-increment` flag bypasses the logic that creates a best guess for the next version based on the +principle of maintaining linearity when a pre-release is present (see above). Instead, `bump` will apply the +exact changes that have been specified with `--increment` or determined from the commit log. For example, +`--prerelease beta` will always result in a `b` tag, and `--increment PATCH` will always increase the patch component. + +Below are some examples that illustrate the difference in behavior: + + +| Increment | Pre-release | Start Version | Without `--exact-increment` | With `--exact-increment` | +|-----------|-------------|---------------|-----------------------------|--------------------------| +| `MAJOR` | | `2.0.0b0` | `2.0.0` | `3.0.0` | +| `MINOR` | | `2.0.0b0` | `2.0.0` | `2.1.0` | +| `PATCH` | | `2.0.0b0` | `2.0.0` | `2.0.1` | +| `MAJOR` | `alpha` | `2.0.0b0` | `3.0.0a0` | `3.0.0a0` | +| `MINOR` | `alpha` | `2.0.0b0` | `2.0.0b1` | `2.1.0a0` | +| `PATCH` | `alpha` | `2.0.0b0` | `2.0.0b1` | `2.0.1a0` | ### `--check-consistency` diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 9a877c9ac0..11137ed629 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -314,6 +314,55 @@ def test_bump_command_prelease_increment(mocker: MockFixture): assert git.tag_exist("1.0.0a0") +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_command_prelease_exact_mode(mocker: MockFixture): + # PRERELEASE + create_file_and_commit("feat: location") + + testargs = ["cz", "bump", "--prerelease", "alpha", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.2.0a0") + assert tag_exists is True + + # PRERELEASE + PATCH BUMP + testargs = ["cz", "bump", "--prerelease", "alpha", "--yes", "--exact-increment"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.2.0a1") + assert tag_exists is True + + # PRERELEASE + MINOR BUMP + # --exact-increment allows the minor version to bump, and restart the prerelease + create_file_and_commit("feat: location") + + testargs = ["cz", "bump", "--prerelease", "alpha", "--yes", "--exact-increment"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.3.0a0") + assert tag_exists is True + + # PRERELEASE + MAJOR BUMP + # --exact-increment allows the major version to bump, and restart the prerelease + testargs = [ + "cz", + "bump", + "--prerelease", + "alpha", + "--yes", + "--increment=MAJOR", + "--exact-increment", + ] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("1.0.0a0") + assert tag_exists is True + + @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_on_git_with_hooks_no_verify_disabled(mocker: MockFixture): """Bump commit without --no-verify""" diff --git a/tests/test_version_scheme_pep440.py b/tests/test_version_scheme_pep440.py index ac99450652..6b1f621cb8 100644 --- a/tests/test_version_scheme_pep440.py +++ b/tests/test_version_scheme_pep440.py @@ -115,6 +115,9 @@ (("2.0.0a4", "PATCH", "alpha", 0, None), "2.0.0a5"), (("2.0.0a5", "MAJOR", "alpha", 0, None), "2.0.0a6"), # + (("2.0.0b0", "MINOR", "alpha", 0, None), "2.0.0b1"), + (("2.0.0b0", "PATCH", "alpha", 0, None), "2.0.0b1"), + # (("1.0.1a0", "PATCH", None, 0, None), "1.0.1"), (("1.0.1a0", "MINOR", None, 0, None), "1.1.0"), (("1.0.1a0", "MAJOR", None, 0, None), "2.0.0"), @@ -141,27 +144,43 @@ (("3.1.4a0", "MAJOR", "alpha", 0, None), "4.0.0a0"), ] - -# test driven development -sortability = [ - "0.10.0a0", - "0.1.1", - "0.1.2", - "2.1.1", - "3.0.0", - "0.9.1a0", - "1.0.0a1", - "1.0.0b1", - "1.0.0a1", - "1.0.0a2.dev1", - "1.0.0rc2", - "1.0.0a3.dev0", - "1.0.0a2.dev0", - "1.0.0a3.dev1", - "1.0.0a2.dev0", - "1.0.0b0", - "1.0.0rc0", - "1.0.0rc1", +excact_cases = [ + (("1.0.0", "PATCH", None, 0, None), "1.0.1"), + (("1.0.0", "MINOR", None, 0, None), "1.1.0"), + # with exact_increment=False: "1.0.0b0" + (("1.0.0a1", "PATCH", "beta", 0, None), "1.0.1b0"), + # with exact_increment=False: "1.0.0b1" + (("1.0.0b0", "PATCH", "beta", 0, None), "1.0.1b0"), + # with exact_increment=False: "1.0.0rc0" + (("1.0.0b1", "PATCH", "rc", 0, None), "1.0.1rc0"), + # with exact_increment=False: "1.0.0-rc1" + (("1.0.0rc0", "PATCH", "rc", 0, None), "1.0.1rc0"), + # with exact_increment=False: "1.0.0rc1-dev1" + (("1.0.0rc0", "PATCH", "rc", 0, 1), "1.0.1rc0.dev1"), + # with exact_increment=False: "1.0.0b0" + (("1.0.0a1", "MINOR", "beta", 0, None), "1.1.0b0"), + # with exact_increment=False: "1.0.0b1" + (("1.0.0b0", "MINOR", "beta", 0, None), "1.1.0b0"), + # with exact_increment=False: "1.0.0b1" + (("1.0.0b0", "MINOR", "alpha", 0, None), "1.1.0a0"), + # with exact_increment=False: "1.0.0rc0" + (("1.0.0b1", "MINOR", "rc", 0, None), "1.1.0rc0"), + # with exact_increment=False: "1.0.0rc1" + (("1.0.0rc0", "MINOR", "rc", 0, None), "1.1.0rc0"), + # with exact_increment=False: "1.0.0rc1-dev1" + (("1.0.0rc0", "MINOR", "rc", 0, 1), "1.1.0rc0.dev1"), + # with exact_increment=False: "2.0.0" + (("2.0.0b0", "MAJOR", None, 0, None), "3.0.0"), + # with exact_increment=False: "2.0.0" + (("2.0.0b0", "MINOR", None, 0, None), "2.1.0"), + # with exact_increment=False: "2.0.0" + (("2.0.0b0", "PATCH", None, 0, None), "2.0.1"), + # same with exact_increment=False + (("2.0.0b0", "MAJOR", "alpha", 0, None), "3.0.0a0"), + # with exact_increment=False: "2.0.0b1" + (("2.0.0b0", "MINOR", "alpha", 0, None), "2.1.0a0"), + # with exact_increment=False: "2.0.0b1" + (("2.0.0b0", "PATCH", "alpha", 0, None), "2.0.1a0"), ] @@ -194,6 +213,27 @@ def test_bump_pep440_version(test_input, expected): ) +@pytest.mark.parametrize("test_input, expected", excact_cases) +def test_bump_pep440_version_force(test_input, expected): + current_version = test_input[0] + increment = test_input[1] + prerelease = test_input[2] + prerelease_offset = test_input[3] + devrelease = test_input[4] + assert ( + str( + Pep440(current_version).bump( + increment=increment, + prerelease=prerelease, + prerelease_offset=prerelease_offset, + devrelease=devrelease, + exact_increment=True, + ) + ) + == expected + ) + + @pytest.mark.parametrize("test_input,expected", local_versions) def test_bump_pep440_version_local(test_input, expected): current_version = test_input[0] diff --git a/tests/test_version_scheme_semver.py b/tests/test_version_scheme_semver.py index a0d6e14b50..71d5e5876c 100644 --- a/tests/test_version_scheme_semver.py +++ b/tests/test_version_scheme_semver.py @@ -83,6 +83,43 @@ (("1.0.0-alpha1", None, "alpha", 0, None), "1.0.0-a2"), ] +excact_cases = [ + (("1.0.0", "PATCH", None, 0, None), "1.0.1"), + (("1.0.0", "MINOR", None, 0, None), "1.1.0"), + # with exact_increment=False: "1.0.0-b0" + (("1.0.0a1", "PATCH", "beta", 0, None), "1.0.1-b0"), + # with exact_increment=False: "1.0.0-b1" + (("1.0.0b0", "PATCH", "beta", 0, None), "1.0.1-b0"), + # with exact_increment=False: "1.0.0-rc0" + (("1.0.0b1", "PATCH", "rc", 0, None), "1.0.1-rc0"), + # with exact_increment=False: "1.0.0-rc1" + (("1.0.0rc0", "PATCH", "rc", 0, None), "1.0.1-rc0"), + # with exact_increment=False: "1.0.0-rc1-dev1" + (("1.0.0rc0", "PATCH", "rc", 0, 1), "1.0.1-rc0-dev1"), + # with exact_increment=False: "1.0.0-b0" + (("1.0.0a1", "MINOR", "beta", 0, None), "1.1.0-b0"), + # with exact_increment=False: "1.0.0-b1" + (("1.0.0b0", "MINOR", "beta", 0, None), "1.1.0-b0"), + # with exact_increment=False: "1.0.0-rc0" + (("1.0.0b1", "MINOR", "rc", 0, None), "1.1.0-rc0"), + # with exact_increment=False: "1.0.0-rc1" + (("1.0.0rc0", "MINOR", "rc", 0, None), "1.1.0-rc0"), + # with exact_increment=False: "1.0.0-rc1-dev1" + (("1.0.0rc0", "MINOR", "rc", 0, 1), "1.1.0-rc0-dev1"), + # with exact_increment=False: "2.0.0" + (("2.0.0b0", "MAJOR", None, 0, None), "3.0.0"), + # with exact_increment=False: "2.0.0" + (("2.0.0b0", "MINOR", None, 0, None), "2.1.0"), + # with exact_increment=False: "2.0.0" + (("2.0.0b0", "PATCH", None, 0, None), "2.0.1"), + # same with exact_increment=False + (("2.0.0b0", "MAJOR", "alpha", 0, None), "3.0.0-a0"), + # with exact_increment=False: "2.0.0b1" + (("2.0.0b0", "MINOR", "alpha", 0, None), "2.1.0-a0"), + # with exact_increment=False: "2.0.0b1" + (("2.0.0b0", "PATCH", "alpha", 0, None), "2.0.1-a0"), +] + @pytest.mark.parametrize( "test_input, expected", @@ -107,6 +144,27 @@ def test_bump_semver_version(test_input, expected): ) +@pytest.mark.parametrize("test_input, expected", excact_cases) +def test_bump_semver_version_force(test_input, expected): + current_version = test_input[0] + increment = test_input[1] + prerelease = test_input[2] + prerelease_offset = test_input[3] + devrelease = test_input[4] + assert ( + str( + SemVer(current_version).bump( + increment=increment, + prerelease=prerelease, + prerelease_offset=prerelease_offset, + devrelease=devrelease, + exact_increment=True, + ) + ) + == expected + ) + + @pytest.mark.parametrize("test_input,expected", local_versions) def test_bump_semver_version_local(test_input, expected): current_version = test_input[0] From c245b14c834818b0a434aac6e45fc298cbb93222 Mon Sep 17 00:00:00 2001 From: Chad Dombrova Date: Mon, 5 Feb 2024 14:29:32 -0800 Subject: [PATCH 039/598] fix(bump): only get and validate commits if increment is not provided This avoids calls to git and additional validations that are not necessary when using --increment --- commitizen/commands/bump.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 435c0039f9..f30f1c0e94 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -209,21 +209,10 @@ def __call__(self) -> None: # noqa: C901 scheme=self.scheme, ) - is_initial = self.is_initial_tag(current_tag_version, is_yes) - if is_initial: - commits = git.get_commits() - else: - commits = git.get_commits(current_tag_version) - # If user specified changelog_to_stdout, they probably want the # changelog to be generated as well, this is the most intuitive solution self.changelog = self.changelog or bool(self.changelog_to_stdout) - # No commits, there is no need to create an empty tag. - # Unless we previously had a prerelease. - if not commits and not current_version.is_prerelease: - raise NoCommitsFoundError("[NO_COMMITS_FOUND]\n" "No new commits found.") - if manual_version: try: new_version = self.scheme(manual_version) @@ -234,6 +223,19 @@ def __call__(self) -> None: # noqa: C901 ) from exc else: if increment is None: + is_initial = self.is_initial_tag(current_tag_version, is_yes) + if is_initial: + commits = git.get_commits() + else: + commits = git.get_commits(current_tag_version) + + # No commits, there is no need to create an empty tag. + # Unless we previously had a prerelease. + if not commits and not current_version.is_prerelease: + raise NoCommitsFoundError( + "[NO_COMMITS_FOUND]\n" "No new commits found." + ) + increment = self.find_increment(commits) # It may happen that there are commits, but they are not eligible From f9a0e2b405d2042f82f2172acb6cda3a50fa8960 Mon Sep 17 00:00:00 2001 From: Chad Dombrova Date: Mon, 19 Feb 2024 16:11:15 -0800 Subject: [PATCH 040/598] fix(bump): change --exact-increment to --increment-mode This provides some future proofing for implementing new version progression behaviors --- commitizen/cli.py | 15 +++++++----- commitizen/commands/bump.py | 6 ++--- docs/bump.md | 37 ++++++++++++++++------------- tests/commands/test_bump_command.py | 24 +++++++++++++++---- 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index a6dcaabd2a..c25bd4f713 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -231,13 +231,16 @@ def __call__( "type": str.upper, }, { - "name": ["--exact-increment"], - "action": "store_true", + "name": ["--increment-mode"], + "choices": ["linear", "exact"], + "default": "linear", "help": ( - "apply the exact changes that have been specified (or " - "determined from the commit log), disabling logic that " - "guesses the next version based on typical version " - "progression when a prelease suffix is present." + "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" ), }, { diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index f30f1c0e94..c29c4c35c5 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -52,7 +52,7 @@ def __init__(self, config: BaseConfig, arguments: dict): "tag_format", "prerelease", "increment", - "exact_increment", + "increment_mode", "bump_message", "gpg_sign", "annotated_tag", @@ -159,7 +159,7 @@ def __call__(self) -> None: # noqa: C901 is_local_version: bool = self.arguments["local_version"] manual_version = self.arguments["manual_version"] build_metadata = self.arguments["build_metadata"] - exact_increment: bool = self.arguments["exact_increment"] + increment_mode: str = self.arguments["increment_mode"] if manual_version: if increment: @@ -254,7 +254,7 @@ def __call__(self) -> None: # noqa: C901 devrelease=devrelease, is_local_version=is_local_version, build_metadata=build_metadata, - exact_increment=exact_increment, + exact_increment=increment_mode == "exact", ) new_tag_version = bump.normalize_tag( diff --git a/docs/bump.md b/docs/bump.md index 904fb7dfc3..9a968f7500 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -79,7 +79,12 @@ options: specify non-negative integer for dev. release --increment {MAJOR,MINOR,PATCH} manually specify the desired increment - --exact-increment apply the exact changes that have been specified (or determined from the commit log), disabling logic that guesses the next version based on typical version progression when a prelease suffix is present. + --increment-mode + 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 @@ -140,29 +145,27 @@ by their precedence and showcase how a release might flow through a development - `1.1.0rc0` after bumping the release candidate - `1.1.0` next feature release -Also note that bumping pre-releases _maintains linearity_: bumping of a pre-release with lower precedence than -the current pre-release phase maintains the current phase of higher precedence. For example, if the current -version is `1.0.0b1` then bumping with `--prerelease alpha` will continue to bump the “beta” phase. -This behavior can be overridden by passing `--exact-increment` (see below). +### `--increment-mode` -### `--exact-increment` +By default, `--increment-mode` is set to `linear`, which ensures taht bumping pre-releases _maintains linearity_: +bumping of a pre-release with lower precedence than the current pre-release phase maintains the current phase of +higher precedence. For example, if the current version is `1.0.0b1` then bumping with `--prerelease alpha` will +continue to bump the “beta” phase. -The `--exact-increment` flag bypasses the logic that creates a best guess for the next version based on the -principle of maintaining linearity when a pre-release is present (see above). Instead, `bump` will apply the +Setting `--increment-mode` to `exact` instructs `cz bump` to instead apply the exact changes that have been specified with `--increment` or determined from the commit log. For example, `--prerelease beta` will always result in a `b` tag, and `--increment PATCH` will always increase the patch component. Below are some examples that illustrate the difference in behavior: - -| Increment | Pre-release | Start Version | Without `--exact-increment` | With `--exact-increment` | -|-----------|-------------|---------------|-----------------------------|--------------------------| -| `MAJOR` | | `2.0.0b0` | `2.0.0` | `3.0.0` | -| `MINOR` | | `2.0.0b0` | `2.0.0` | `2.1.0` | -| `PATCH` | | `2.0.0b0` | `2.0.0` | `2.0.1` | -| `MAJOR` | `alpha` | `2.0.0b0` | `3.0.0a0` | `3.0.0a0` | -| `MINOR` | `alpha` | `2.0.0b0` | `2.0.0b1` | `2.1.0a0` | -| `PATCH` | `alpha` | `2.0.0b0` | `2.0.0b1` | `2.0.1a0` | +| Increment | Pre-release | Start Version | `--increment-mode=linear` | `--increment-mode=exact` | +|-----------|-------------|---------------|---------------------------|--------------------------| +| `MAJOR` | | `2.0.0b0` | `2.0.0` | `3.0.0` | +| `MINOR` | | `2.0.0b0` | `2.0.0` | `2.1.0` | +| `PATCH` | | `2.0.0b0` | `2.0.0` | `2.0.1` | +| `MAJOR` | `alpha` | `2.0.0b0` | `3.0.0a0` | `3.0.0a0` | +| `MINOR` | `alpha` | `2.0.0b0` | `2.0.0b1` | `2.1.0a0` | +| `PATCH` | `alpha` | `2.0.0b0` | `2.0.0b1` | `2.0.1a0` | ### `--check-consistency` diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 11137ed629..b39271f284 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -327,7 +327,14 @@ def test_bump_command_prelease_exact_mode(mocker: MockFixture): assert tag_exists is True # PRERELEASE + PATCH BUMP - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes", "--exact-increment"] + testargs = [ + "cz", + "bump", + "--prerelease", + "alpha", + "--yes", + "--increment-mode=exact", + ] mocker.patch.object(sys, "argv", testargs) cli.main() @@ -335,10 +342,17 @@ def test_bump_command_prelease_exact_mode(mocker: MockFixture): assert tag_exists is True # PRERELEASE + MINOR BUMP - # --exact-increment allows the minor version to bump, and restart the prerelease + # --increment-mode allows the minor version to bump, and restart the prerelease create_file_and_commit("feat: location") - testargs = ["cz", "bump", "--prerelease", "alpha", "--yes", "--exact-increment"] + testargs = [ + "cz", + "bump", + "--prerelease", + "alpha", + "--yes", + "--increment-mode=exact", + ] mocker.patch.object(sys, "argv", testargs) cli.main() @@ -346,7 +360,7 @@ def test_bump_command_prelease_exact_mode(mocker: MockFixture): assert tag_exists is True # PRERELEASE + MAJOR BUMP - # --exact-increment allows the major version to bump, and restart the prerelease + # --increment-mode=exact allows the major version to bump, and restart the prerelease testargs = [ "cz", "bump", @@ -354,7 +368,7 @@ def test_bump_command_prelease_exact_mode(mocker: MockFixture): "alpha", "--yes", "--increment=MAJOR", - "--exact-increment", + "--increment-mode=exact", ] mocker.patch.object(sys, "argv", testargs) cli.main() From f75eddcc1e69195a6edf07bfe7f75dbe6838361a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 26 Feb 2024 07:05:10 +0000 Subject: [PATCH 041/598] =?UTF-8?q?bump:=20version=203.15.0=20=E2=86=92=20?= =?UTF-8?q?3.16.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 12 ++++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c1120176b9..a40195711e 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.15.0 # automatically updated by Commitizen + rev: v3.16.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index c61279fe1e..045d308e8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ +## v3.16.0 (2024-02-26) + +### Feat + +- **commands**: add bump --exact + +### Fix + +- **bump**: change --exact-increment to --increment-mode +- **bump**: only get and validate commits if increment is not provided +- Improve type annotations + ## v3.15.0 (2024-02-17) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 11d9fee7b3..331093ae1a 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.15.0" +__version__ = "3.16.0" diff --git a/pyproject.toml b/pyproject.toml index a8ef9705cf..3a2d3bf79f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.15.0" +version = "3.16.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.15.0" +version = "3.16.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From fc54b519a96192553d4149dbd75f7db3d8e581da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 01:07:23 +0000 Subject: [PATCH 042/598] build(deps): bump tomlkit from 0.12.3 to 0.12.4 Bumps [tomlkit](https://github.com/sdispater/tomlkit) from 0.12.3 to 0.12.4. - [Release notes](https://github.com/sdispater/tomlkit/releases) - [Changelog](https://github.com/sdispater/tomlkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/sdispater/tomlkit/compare/0.12.3...0.12.4) --- updated-dependencies: - dependency-name: tomlkit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9f02b028b8..091376ec3e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1504,13 +1504,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.3" +version = "0.12.4" description = "Style preserving TOML library" optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"}, - {file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"}, + {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"}, + {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"}, ] [[package]] From 71a594dbac9176bfd19130a48a8cffdf5638cd2e Mon Sep 17 00:00:00 2001 From: Axel H Date: Tue, 5 Mar 2024 13:13:15 +0100 Subject: [PATCH 043/598] feat(changelog): `changelog_message_build_hook` can remove message by returning a falsy value --- commitizen/changelog.py | 10 ++++++++-- commitizen/commands/changelog.py | 3 ++- commitizen/cz/base.py | 12 ++++++++---- docs/bump.md | 10 +++++----- docs/customization.md | 4 ++-- tests/test_changelog.py | 28 ++++++++++++++++++++++++++++ 6 files changed, 53 insertions(+), 14 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index e4273db93a..bf0f18576f 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -166,7 +166,8 @@ def generate_tree_from_commits( change_type = change_type_map.get(change_type, change_type) if changelog_message_builder_hook: parsed_message = changelog_message_builder_hook(parsed_message, commit) - changes[change_type].append(parsed_message) + if parsed_message: + changes[change_type].append(parsed_message) # Process body from commit message body_parts = commit.body.split("\n\n") @@ -179,7 +180,12 @@ def generate_tree_from_commits( change_type = parsed_message_body.pop("change_type", None) if change_type_map: change_type = change_type_map.get(change_type, change_type) - changes[change_type].append(parsed_message_body) + if changelog_message_builder_hook: + parsed_message_body = changelog_message_builder_hook( + parsed_message_body, commit + ) + if parsed_message_body: + changes[change_type].append(parsed_message_body) yield {"version": current_tag_name, "date": current_tag_date, "changes": changes} diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index f44f59bb7c..8b3d126fe3 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -9,6 +9,7 @@ from commitizen import bump, changelog, defaults, factory, git, out from commitizen.config import BaseConfig +from commitizen.cz.base import MessageBuilderHook from commitizen.exceptions import ( DryRunExit, NoCommitsFoundError, @@ -145,7 +146,7 @@ def __call__(self): unreleased_version = self.unreleased_version changelog_meta = changelog.Metadata() change_type_map: dict | None = self.change_type_map - changelog_message_builder_hook: Callable | None = ( + changelog_message_builder_hook: MessageBuilderHook | None = ( self.cz.changelog_message_builder_hook ) merge_prerelease = self.merge_prerelease diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 14d9e5a522..766c252eee 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -1,7 +1,7 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod -from typing import Any, Callable +from typing import Any, Callable, Protocol from jinja2 import BaseLoader, PackageLoader from prompt_toolkit.styles import Style, merge_styles @@ -11,6 +11,12 @@ from commitizen.defaults import Questions +class MessageBuilderHook(Protocol): + def __call__( + self, message: dict[str, Any], commit: git.GitCommit + ) -> dict[str, Any] | None: ... + + class BaseCommitizen(metaclass=ABCMeta): bump_pattern: str | None = None bump_map: dict[str, str] | None = None @@ -37,9 +43,7 @@ class BaseCommitizen(metaclass=ABCMeta): change_type_order: list[str] | None = None # Executed per message parsed by the commitizen - changelog_message_builder_hook: None | (Callable[[dict, git.GitCommit], dict]) = ( - None - ) + changelog_message_builder_hook: MessageBuilderHook | None = None # Executed only at the end of the changelog generation changelog_hook: Callable[[str, str | None], str] | None = None diff --git a/docs/bump.md b/docs/bump.md index 9a968f7500..0e35083b0a 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -147,13 +147,13 @@ by their precedence and showcase how a release might flow through a development ### `--increment-mode` -By default, `--increment-mode` is set to `linear`, which ensures taht bumping pre-releases _maintains linearity_: -bumping of a pre-release with lower precedence than the current pre-release phase maintains the current phase of -higher precedence. For example, if the current version is `1.0.0b1` then bumping with `--prerelease alpha` will +By default, `--increment-mode` is set to `linear`, which ensures that bumping pre-releases _maintains linearity_: +bumping of a pre-release with lower precedence than the current pre-release phase maintains the current phase of +higher precedence. For example, if the current version is `1.0.0b1` then bumping with `--prerelease alpha` will continue to bump the “beta” phase. -Setting `--increment-mode` to `exact` instructs `cz bump` to instead apply the -exact changes that have been specified with `--increment` or determined from the commit log. For example, +Setting `--increment-mode` to `exact` instructs `cz bump` to instead apply the +exact changes that have been specified with `--increment` or determined from the commit log. For example, `--prerelease beta` will always result in a `b` tag, and `--increment PATCH` will always increase the patch component. Below are some examples that illustrate the difference in behavior: diff --git a/docs/customization.md b/docs/customization.md index 0c86f60d20..bc51cd2179 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -318,7 +318,7 @@ You can customize it of course, and this are the variables you need to add to yo | `commit_parser` | `str` | NO | Regex which should provide the variables explained in the [changelog description][changelog-des] | | `changelog_pattern` | `str` | NO | Regex to validate the commits, this is useful to skip commits that don't meet your ruling standards like a Merge. Usually the same as bump_pattern | | `change_type_map` | `dict` | NO | Convert the title of the change type that will appear in the changelog, if a value is not found, the original will be provided | -| `changelog_message_builder_hook` | `method: (dict, git.GitCommit) -> dict` | NO | Customize with extra information your message output, like adding links, this function is executed per parsed commit. Each GitCommit contains the following attrs: `rev`, `title`, `body`, `author`, `author_email` | +| `changelog_message_builder_hook` | `method: (dict, git.GitCommit) -> dict | None` | NO | Customize with extra information your message output, like adding links, this function is executed per parsed commit. Each GitCommit contains the following attrs: `rev`, `title`, `body`, `author`, `author_email`. Returning a falsy value ignore the commit. | | `changelog_hook` | `method: (full_changelog: str, partial_changelog: Optional[str]) -> str` | NO | Receives the whole and partial (if used incremental) changelog. Useful to send slack messages or notify a compliance department. Must return the full_changelog | ```python @@ -339,7 +339,7 @@ class StrangeCommitizen(BaseCommitizen): def changelog_message_builder_hook( self, parsed_message: dict, commit: git.GitCommit - ) -> dict: + ) -> dict | None: rev = commit.rev m = parsed_message["message"] parsed_message[ diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 879443f334..0aff996ff5 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,3 +1,5 @@ +import re + from pathlib import Path import pytest @@ -1319,6 +1321,32 @@ def changelog_message_builder_hook(message: dict, commit: git.GitCommit) -> dict assert "[link](github.com/232323232) Commitizen author@cz.dev" in result +def test_changelog_message_builder_hook_can_remove_commits( + gitcommits, tags, any_changelog_format: ChangelogFormat +): + def changelog_message_builder_hook(message: dict, commit: git.GitCommit): + return None + + parser = ConventionalCommitsCz.commit_parser + changelog_pattern = ConventionalCommitsCz.changelog_pattern + loader = ConventionalCommitsCz.template_loader + template = any_changelog_format.template + tree = changelog.generate_tree_from_commits( + gitcommits, + tags, + parser, + changelog_pattern, + changelog_message_builder_hook=changelog_message_builder_hook, + ) + result = changelog.render_changelog(tree, loader, template) + + RE_HEADER = re.compile(r"^## v?\d+\.\d+\.\d+(\w)* \(\d{4}-\d{2}-\d{2}\)$") + # Rendered changelog should be empty, only containing version headers + for no, line in enumerate(result.splitlines()): + if line := line.strip(): + assert RE_HEADER.match(line), f"Line {no} should not be there: {line}" + + def test_get_smart_tag_range_returns_an_extra_for_a_range(tags): start, end = ( tags[0], From c0b7229d05cf7aebb1acaf3b88e8cd5c8f958cc9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 6 Mar 2024 07:12:39 +0000 Subject: [PATCH 044/598] =?UTF-8?q?bump:=20version=203.16.0=20=E2=86=92=20?= =?UTF-8?q?3.17.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a40195711e..7c76998942 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.16.0 # automatically updated by Commitizen + rev: v3.17.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 045d308e8b..ad2aa15e82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +## v3.17.0 (2024-03-06) + +### Feat + +- **changelog**: `changelog_message_build_hook` can remove message by returning a falsy value + ## v3.16.0 (2024-02-26) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 331093ae1a..a3207ca50c 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.16.0" +__version__ = "3.17.0" diff --git a/pyproject.toml b/pyproject.toml index 3a2d3bf79f..eef6e327cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.16.0" +version = "3.17.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.16.0" +version = "3.17.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From dd5dfed2df27699adfd14a5df75aa475c4c0d680 Mon Sep 17 00:00:00 2001 From: Axel H Date: Thu, 7 Mar 2024 14:42:31 +0100 Subject: [PATCH 045/598] fix(bump): pre and post bump hooks were failing when an increment was provided (fix #1004) --- commitizen/commands/bump.py | 3 ++- tests/commands/test_bump_command.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index c29c4c35c5..efbe1e0c3c 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -209,6 +209,8 @@ def __call__(self) -> None: # noqa: C901 scheme=self.scheme, ) + is_initial = self.is_initial_tag(current_tag_version, is_yes) + # If user specified changelog_to_stdout, they probably want the # changelog to be generated as well, this is the most intuitive solution self.changelog = self.changelog or bool(self.changelog_to_stdout) @@ -223,7 +225,6 @@ def __call__(self) -> None: # noqa: C901 ) from exc else: if increment is None: - is_initial = self.is_initial_tag(current_tag_version, is_yes) if is_initial: commits = git.get_commits() else: diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index b39271f284..c9e73649f4 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1007,6 +1007,29 @@ def test_bump_with_pre_bump_hooks( ) +def test_bump_with_hooks_and_increment(mocker: MockFixture, tmp_commitizen_project): + pre_bump_hook = "scripts/pre_bump_hook.sh" + post_bump_hook = "scripts/post_bump_hook.sh" + + tmp_commitizen_cfg_file = tmp_commitizen_project.join("pyproject.toml") + tmp_commitizen_cfg_file.write( + f"{tmp_commitizen_cfg_file.read()}\n" + f'pre_bump_hooks = ["{pre_bump_hook}"]\n' + f'post_bump_hooks = ["{post_bump_hook}"]\n' + ) + + run_mock = mocker.Mock() + mocker.patch.object(hooks, "run", run_mock) + + create_file_and_commit("test: some test") + testargs = ["cz", "bump", "--yes", "--increment", "MINOR"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + tag_exists = git.tag_exist("0.2.0") + assert tag_exists is True + + @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_manual_version_disallows_prerelease_offset(mocker): create_file_and_commit("feat: new file") From 9a49892dc40e914d437033e44269815a9c25e826 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 7 Mar 2024 14:31:00 +0000 Subject: [PATCH 046/598] =?UTF-8?q?bump:=20version=203.17.0=20=E2=86=92=20?= =?UTF-8?q?3.17.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7c76998942..7c8d5dae6a 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.17.0 # automatically updated by Commitizen + rev: v3.17.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index ad2aa15e82..7b1b49e72c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +## v3.17.1 (2024-03-07) + +### Fix + +- **bump**: pre and post bump hooks were failing when an increment was provided (fix #1004) + ## v3.17.0 (2024-03-06) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index a3207ca50c..7e84c71b24 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.17.0" +__version__ = "3.17.1" diff --git a/pyproject.toml b/pyproject.toml index eef6e327cd..80578d5731 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.17.0" +version = "3.17.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.17.0" +version = "3.17.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 15ea15d31c46ef49ae36ab1269d6a85e465262e4 Mon Sep 17 00:00:00 2001 From: Axel H Date: Thu, 7 Mar 2024 15:32:14 +0100 Subject: [PATCH 047/598] fix(changelog): ensure `changelog_message_builder_hook` can access and modify `change_type` (#1002) --- commitizen/changelog.py | 13 ++++++------- tests/test_changelog.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index bf0f18576f..28481a1dea 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -159,14 +159,13 @@ def generate_tree_from_commits( message = map_pat.match(commit.message) if message: parsed_message: dict = message.groupdict() - # change_type becomes optional by providing None - change_type = parsed_message.pop("change_type", None) - if change_type_map: - change_type = change_type_map.get(change_type, change_type) if changelog_message_builder_hook: parsed_message = changelog_message_builder_hook(parsed_message, commit) if parsed_message: + change_type = parsed_message.pop("change_type", None) + if change_type_map: + change_type = change_type_map.get(change_type, change_type) changes[change_type].append(parsed_message) # Process body from commit message @@ -177,14 +176,14 @@ def generate_tree_from_commits( continue parsed_message_body: dict = message_body.groupdict() - change_type = parsed_message_body.pop("change_type", None) - if change_type_map: - change_type = change_type_map.get(change_type, change_type) if changelog_message_builder_hook: parsed_message_body = changelog_message_builder_hook( parsed_message_body, commit ) if parsed_message_body: + change_type = parsed_message_body.pop("change_type", None) + if change_type_map: + change_type = change_type_map.get(change_type, change_type) changes[change_type].append(parsed_message_body) yield {"version": current_tag_name, "date": current_tag_date, "changes": changes} diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 0aff996ff5..af7846f6f0 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1347,6 +1347,37 @@ def changelog_message_builder_hook(message: dict, commit: git.GitCommit): assert RE_HEADER.match(line), f"Line {no} should not be there: {line}" +def test_changelog_message_builder_hook_can_access_and_modify_change_type( + gitcommits, tags, any_changelog_format: ChangelogFormat +): + def changelog_message_builder_hook(message: dict, commit: git.GitCommit): + assert "change_type" in message + message["change_type"] = "overridden" + return message + + parser = ConventionalCommitsCz.commit_parser + changelog_pattern = ConventionalCommitsCz.changelog_pattern + loader = ConventionalCommitsCz.template_loader + template = any_changelog_format.template + tree = changelog.generate_tree_from_commits( + gitcommits, + tags, + parser, + changelog_pattern, + changelog_message_builder_hook=changelog_message_builder_hook, + ) + result = changelog.render_changelog(tree, loader, template) + + RE_HEADER = re.compile(r"^### (?P.+)$") + # There should be only "overridden" change type headers + for no, line in enumerate(result.splitlines()): + if (line := line.strip()) and (match := RE_HEADER.match(line)): + change_type = match.group("type") + assert ( + change_type == "overridden" + ), f"Line {no}: type {change_type} should have been overridden" + + def test_get_smart_tag_range_returns_an_extra_for_a_range(tags): start, end = ( tags[0], From a9c265277ba53fdbe0d87cee90e95cb77ebbe2bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 7 Mar 2024 14:32:41 +0000 Subject: [PATCH 048/598] =?UTF-8?q?bump:=20version=203.17.1=20=E2=86=92=20?= =?UTF-8?q?3.17.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7c8d5dae6a..d5362edf53 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.17.1 # automatically updated by Commitizen + rev: v3.17.2 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b1b49e72c..e94f04133f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +## v3.17.2 (2024-03-07) + +### Fix + +- **changelog**: ensure `changelog_message_builder_hook` can access and modify `change_type` (#1002) + ## v3.17.1 (2024-03-07) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 7e84c71b24..4874dc2b76 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.17.1" +__version__ = "3.17.2" diff --git a/pyproject.toml b/pyproject.toml index 80578d5731..9e0356b686 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.17.1" +version = "3.17.2" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.17.1" +version = "3.17.2" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 41f9b820dabf7f1595ee95533c53d11dd904a0ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:35:02 +0100 Subject: [PATCH 049/598] build(deps-dev): bump mkdocs-material from 9.5.11 to 9.5.13 (#1006) Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.11 to 9.5.13. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.11...9.5.13) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 091376ec3e..f8463928f4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.11" +version = "9.5.13" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.11-py3-none-any.whl", hash = "sha256:788ee0f3e036dca2dc20298d65e480297d348a44c9d7b2ee05c5262983e66072"}, - {file = "mkdocs_material-9.5.11.tar.gz", hash = "sha256:7af7f8af0dea16175558f3fb9245d26c83a17199baa5f157755e63d7437bf971"}, + {file = "mkdocs_material-9.5.13-py3-none-any.whl", hash = "sha256:5cbe17fee4e3b4980c8420a04cc762d8dc052ef1e10532abd4fce88e5ea9ce6a"}, + {file = "mkdocs_material-9.5.13.tar.gz", hash = "sha256:d8e4caae576312a88fd2609b81cf43d233cdbe36860d67a68702b018b425bd87"}, ] [package.dependencies] From ec2da068723a0e1c12be4f40cf7ee1e7faab85d4 Mon Sep 17 00:00:00 2001 From: Axel H Date: Thu, 7 Mar 2024 15:41:32 +0100 Subject: [PATCH 050/598] feat(changelog): `changelog_message_build_hook` can now generate multiple changelog entries from a single commit (#1003) --- commitizen/changelog.py | 62 ++++++++++++++++++++++++----------------- commitizen/cz/base.py | 4 +-- docs/customization.md | 4 +-- tests/test_changelog.py | 26 +++++++++++++++++ 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 28481a1dea..5c713af0e6 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -31,7 +31,7 @@ from collections import OrderedDict, defaultdict from dataclasses import dataclass from datetime import date -from typing import TYPE_CHECKING, Callable, Iterable +from typing import TYPE_CHECKING, Iterable from jinja2 import ( BaseLoader, @@ -52,6 +52,7 @@ ) if TYPE_CHECKING: + from commitizen.cz.base import MessageBuilderHook from commitizen.version_schemes import VersionScheme @@ -111,7 +112,7 @@ def generate_tree_from_commits( changelog_pattern: str, unreleased_version: str | None = None, change_type_map: dict[str, str] | None = None, - changelog_message_builder_hook: Callable | None = None, + changelog_message_builder_hook: MessageBuilderHook | None = None, merge_prerelease: bool = False, scheme: VersionScheme = DEFAULT_SCHEME, ) -> Iterable[dict]: @@ -156,39 +157,48 @@ def generate_tree_from_commits( continue # Process subject from commit message - message = map_pat.match(commit.message) - if message: - parsed_message: dict = message.groupdict() - - if changelog_message_builder_hook: - parsed_message = changelog_message_builder_hook(parsed_message, commit) - if parsed_message: - change_type = parsed_message.pop("change_type", None) - if change_type_map: - change_type = change_type_map.get(change_type, change_type) - changes[change_type].append(parsed_message) + if message := map_pat.match(commit.message): + process_commit_message( + changelog_message_builder_hook, + message, + commit, + changes, + change_type_map, + ) # Process body from commit message body_parts = commit.body.split("\n\n") for body_part in body_parts: - message_body = body_map_pat.match(body_part) - if not message_body: - continue - parsed_message_body: dict = message_body.groupdict() - - if changelog_message_builder_hook: - parsed_message_body = changelog_message_builder_hook( - parsed_message_body, commit + if message := body_map_pat.match(body_part): + process_commit_message( + changelog_message_builder_hook, + message, + commit, + changes, + change_type_map, ) - if parsed_message_body: - change_type = parsed_message_body.pop("change_type", None) - if change_type_map: - change_type = change_type_map.get(change_type, change_type) - changes[change_type].append(parsed_message_body) yield {"version": current_tag_name, "date": current_tag_date, "changes": changes} +def process_commit_message( + hook: MessageBuilderHook | None, + parsed: re.Match[str], + commit: GitCommit, + changes: dict[str | None, list], + change_type_map: dict[str, str] | None = None, +): + message: dict = parsed.groupdict() + + if processed := hook(message, commit) if hook else message: + messages = [processed] if isinstance(processed, dict) else processed + for msg in messages: + change_type = msg.pop("change_type", None) + if change_type_map: + change_type = change_type_map.get(change_type, change_type) + changes[change_type].append(msg) + + def order_changelog_tree(tree: Iterable, change_type_order: list[str]) -> Iterable: if len(set(change_type_order)) != len(change_type_order): raise InvalidConfigurationError( diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 766c252eee..5a84d1f101 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -1,7 +1,7 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod -from typing import Any, Callable, Protocol +from typing import Any, Callable, Iterable, Protocol from jinja2 import BaseLoader, PackageLoader from prompt_toolkit.styles import Style, merge_styles @@ -14,7 +14,7 @@ class MessageBuilderHook(Protocol): def __call__( self, message: dict[str, Any], commit: git.GitCommit - ) -> dict[str, Any] | None: ... + ) -> dict[str, Any] | Iterable[dict[str, Any]] | None: ... class BaseCommitizen(metaclass=ABCMeta): diff --git a/docs/customization.md b/docs/customization.md index bc51cd2179..7d352f0313 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -318,7 +318,7 @@ You can customize it of course, and this are the variables you need to add to yo | `commit_parser` | `str` | NO | Regex which should provide the variables explained in the [changelog description][changelog-des] | | `changelog_pattern` | `str` | NO | Regex to validate the commits, this is useful to skip commits that don't meet your ruling standards like a Merge. Usually the same as bump_pattern | | `change_type_map` | `dict` | NO | Convert the title of the change type that will appear in the changelog, if a value is not found, the original will be provided | -| `changelog_message_builder_hook` | `method: (dict, git.GitCommit) -> dict | None` | NO | Customize with extra information your message output, like adding links, this function is executed per parsed commit. Each GitCommit contains the following attrs: `rev`, `title`, `body`, `author`, `author_email`. Returning a falsy value ignore the commit. | +| `changelog_message_builder_hook` | `method: (dict, git.GitCommit) -> dict | list | None` | NO | Customize with extra information your message output, like adding links, this function is executed per parsed commit. Each GitCommit contains the following attrs: `rev`, `title`, `body`, `author`, `author_email`. Returning a falsy value ignore the commit. | | `changelog_hook` | `method: (full_changelog: str, partial_changelog: Optional[str]) -> str` | NO | Receives the whole and partial (if used incremental) changelog. Useful to send slack messages or notify a compliance department. Must return the full_changelog | ```python @@ -339,7 +339,7 @@ class StrangeCommitizen(BaseCommitizen): def changelog_message_builder_hook( self, parsed_message: dict, commit: git.GitCommit - ) -> dict | None: + ) -> dict | list | None: rev = commit.rev m = parsed_message["message"] parsed_message[ diff --git a/tests/test_changelog.py b/tests/test_changelog.py index af7846f6f0..7944f66dd8 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1347,6 +1347,32 @@ def changelog_message_builder_hook(message: dict, commit: git.GitCommit): assert RE_HEADER.match(line), f"Line {no} should not be there: {line}" +def test_render_changelog_with_changelog_message_builder_hook_multiple_entries( + gitcommits, tags, any_changelog_format: ChangelogFormat +): + def changelog_message_builder_hook(message: dict, commit: git.GitCommit): + messages = [message.copy(), message.copy(), message.copy()] + for idx, msg in enumerate(messages): + msg["message"] = "Message #{idx}" + return messages + + parser = ConventionalCommitsCz.commit_parser + changelog_pattern = ConventionalCommitsCz.changelog_pattern + loader = ConventionalCommitsCz.template_loader + template = any_changelog_format.template + tree = changelog.generate_tree_from_commits( + gitcommits, + tags, + parser, + changelog_pattern, + changelog_message_builder_hook=changelog_message_builder_hook, + ) + result = changelog.render_changelog(tree, loader, template) + + for idx in range(3): + assert "Message #{idx}" in result + + def test_changelog_message_builder_hook_can_access_and_modify_change_type( gitcommits, tags, any_changelog_format: ChangelogFormat ): From 99b6fba066fc409b6132d6de9a6afa1cdcdd100f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 7 Mar 2024 14:42:00 +0000 Subject: [PATCH 051/598] =?UTF-8?q?bump:=20version=203.17.2=20=E2=86=92=20?= =?UTF-8?q?3.18.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d5362edf53..4df7b3f62b 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.17.2 # automatically updated by Commitizen + rev: v3.18.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index e94f04133f..6bd7818283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +## v3.18.0 (2024-03-07) + +### Feat + +- **changelog**: `changelog_message_build_hook` can now generate multiple changelog entries from a single commit (#1003) + ## v3.17.2 (2024-03-07) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 4874dc2b76..1b052a2ba3 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.17.2" +__version__ = "3.18.0" diff --git a/pyproject.toml b/pyproject.toml index 9e0356b686..a81cf299ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.17.2" +version = "3.18.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.17.2" +version = "3.18.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 33b75e3a93087c1b91e1151988a58af38bd808c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Mar 2024 19:19:57 +0100 Subject: [PATCH 052/598] build(deps): bump importlib-metadata from 7.0.1 to 7.0.2 (#1010) --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index f8463928f4..1018676276 100644 --- a/poetry.lock +++ b/poetry.lock @@ -496,22 +496,22 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.0.1" +version = "7.0.2" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, - {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, + {file = "importlib_metadata-7.0.2-py3-none-any.whl", hash = "sha256:f4bc4c0c070c490abf4ce96d715f68e95923320370efb66143df00199bb6c100"}, + {file = "importlib_metadata-7.0.2.tar.gz", hash = "sha256:198f568f3230878cb1b44fbd7975f87906c22336dba2e4a7f05278c281fbd792"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "iniconfig" From 3100fd51739b499d4daedf3586e5235ebc49804f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Mar 2024 19:20:27 +0100 Subject: [PATCH 053/598] build(deps): bump argcomplete from 3.2.2 to 3.2.3 (#1009) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1018676276..ecdde80af8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,13 +13,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.2.2" +version = "3.2.3" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.2.2-py3-none-any.whl", hash = "sha256:e44f4e7985883ab3e73a103ef0acd27299dbfe2dfed00142c35d4ddd3005901d"}, - {file = "argcomplete-3.2.2.tar.gz", hash = "sha256:f3e49e8ea59b4026ee29548e24488af46e30c9de57d48638e24f54a1ea1000a2"}, + {file = "argcomplete-3.2.3-py3-none-any.whl", hash = "sha256:c12355e0494c76a2a7b73e3a59b09024ca0ba1e279fb9ed6c1b82d5b74b6a70c"}, + {file = "argcomplete-3.2.3.tar.gz", hash = "sha256:bf7900329262e481be5a15f56f19736b376df6f82ed27576fa893652c5de6c23"}, ] [package.extras] From 267f374966ae1e6d64765a3721a64ad0fae1e9de Mon Sep 17 00:00:00 2001 From: Axel H Date: Sat, 9 Mar 2024 18:35:29 +0100 Subject: [PATCH 054/598] fix(changelog): changelog hook was not called on dry run --- commitizen/commands/changelog.py | 9 +++++---- tests/commands/test_changelog_command.py | 13 +++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 8b3d126fe3..5d710ed5d0 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -132,6 +132,11 @@ def write_changelog( if changelog_hook: changelog_out = changelog_hook(changelog_out, partial_changelog) + + if self.dry_run: + out.write(changelog_out) + raise DryRunExit() + changelog_file.write(changelog_out) def export_template(self): @@ -216,10 +221,6 @@ def __call__(self): ) changelog_out = changelog_out.lstrip("\n") - if self.dry_run: - out.write(changelog_out) - raise DryRunExit() - lines = [] if self.incremental and os.path.isfile(self.file_name): with open(self.file_name, encoding=self.encoding) as changelog_file: diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index a0183e1cd9..971d04cce5 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -12,6 +12,7 @@ from commitizen import __file__ as commitizen_init from commitizen import cli, git from commitizen.commands.changelog import Changelog +from commitizen.config.base_config import BaseConfig from commitizen.cz.base import BaseCommitizen from commitizen.exceptions import ( DryRunExit, @@ -275,7 +276,8 @@ def test_changelog_incremental_keep_a_changelog_sample( @pytest.mark.usefixtures("tmp_commitizen_project") -def test_changelog_hook(mocker: MockFixture, config): +@pytest.mark.parametrize("dry_run", [True, False]) +def test_changelog_hook(mocker: MockFixture, config: BaseConfig, dry_run: bool): changelog_hook_mock = mocker.Mock() changelog_hook_mock.return_value = "cool changelog hook" @@ -283,12 +285,15 @@ def test_changelog_hook(mocker: MockFixture, config): create_file_and_commit("refactor: is in changelog") create_file_and_commit("Merge into master") - config.settings["change_type_order"] = ["Refactor", "Feat"] + config.settings["change_type_order"] = ["Refactor", "Feat"] # type: ignore[typeddict-unknown-key] changelog = Changelog( - config, {"unreleased_version": None, "incremental": True, "dry_run": False} + config, {"unreleased_version": None, "incremental": True, "dry_run": dry_run} ) mocker.patch.object(changelog.cz, "changelog_hook", changelog_hook_mock) - changelog() + try: + changelog() + except DryRunExit: + pass full_changelog = ( "## Unreleased\n\n### Refactor\n\n- is in changelog\n\n### Feat\n\n- new file\n" ) From 0e93206748dfdbcd71514fa61d75557e7b816e2d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 11 Mar 2024 07:13:27 +0000 Subject: [PATCH 055/598] =?UTF-8?q?bump:=20version=203.18.0=20=E2=86=92=20?= =?UTF-8?q?3.18.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4df7b3f62b..088e42daa6 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.18.0 # automatically updated by Commitizen + rev: v3.18.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bd7818283..cfb874f5eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +## v3.18.1 (2024-03-11) + +### Fix + +- **changelog**: changelog hook was not called on dry run + ## v3.18.0 (2024-03-07) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 1b052a2ba3..1e25597fcc 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.18.0" +__version__ = "3.18.1" diff --git a/pyproject.toml b/pyproject.toml index a81cf299ba..31c83527b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.18.0" +version = "3.18.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.18.0" +version = "3.18.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 6654ef1340c485455d672cafcbbbe03ab974a8a2 Mon Sep 17 00:00:00 2001 From: Axel H Date: Mon, 11 Mar 2024 11:29:07 +0100 Subject: [PATCH 056/598] fix(git): force the default git locale on methods relying on parsing the output (#1012) --- commitizen/cmd.py | 3 +++ commitizen/git.py | 4 +++- tests/test_git.py | 12 ++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/commitizen/cmd.py b/commitizen/cmd.py index 51ef4523ff..ba48ac7881 100644 --- a/commitizen/cmd.py +++ b/commitizen/cmd.py @@ -1,3 +1,4 @@ +import os import subprocess from typing import NamedTuple @@ -28,6 +29,8 @@ def _try_decode(bytes_: bytes) -> str: def run(cmd: str, env=None) -> Command: + if env is not None: + env = {**os.environ, **env} process = subprocess.Popen( cmd, shell=True, diff --git a/commitizen/git.py b/commitizen/git.py index 6cdc7e2752..900ca9298e 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -175,7 +175,9 @@ def get_tags( f'%(object)"' ) extra = "--merged" if reachable_only else "" - c = cmd.run(f"git tag --format={formatter} --sort=-creatordate {extra}") + # Force the default language for parsing + env = {"LC_ALL": "C", "LANG": "C", "LANGUAGE": "C"} + c = cmd.run(f"git tag --format={formatter} --sort=-creatordate {extra}", env=env) if c.return_code != 0: if reachable_only and c.err == "fatal: malformed object name HEAD\n": # this can happen if there are no commits in the repo yet diff --git a/tests/test_git.py b/tests/test_git.py index 79eb49f10c..3b7a08f94a 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -71,6 +71,18 @@ def test_get_reachable_tags(tmp_commitizen_project): assert tag_names == {"1.0.0", "1.0.1"} +@pytest.mark.parametrize("locale", ["en_US", "fr_FR"]) +def test_get_reachable_tags_with_commits( + tmp_commitizen_project, locale: str, monkeypatch: pytest.MonkeyPatch +): + monkeypatch.setenv("LANG", f"{locale}.UTF-8") + monkeypatch.setenv("LANGUAGE", f"{locale}.UTF-8") + monkeypatch.setenv("LC_ALL", f"{locale}.UTF-8") + with tmp_commitizen_project.as_cwd(): + tags = git.get_tags(reachable_only=True) + assert tags == [] + + def test_get_tag_names(mocker: MockFixture): tag_str = "v1.0.0\n" "v0.5.0\n" "v0.0.1\n" mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=tag_str)) From 66899a39a864ae21a9ff1560adfaf5bc4b6e4c57 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 11 Mar 2024 10:29:32 +0000 Subject: [PATCH 057/598] =?UTF-8?q?bump:=20version=203.18.1=20=E2=86=92=20?= =?UTF-8?q?3.18.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 353 +++++++++++++++++++------------------- commitizen/__version__.py | 2 +- pyproject.toml | 4 +- 4 files changed, 184 insertions(+), 177 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 088e42daa6..d674bf0aa6 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.18.1 # automatically updated by Commitizen + rev: v3.18.2 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index cfb874f5eb..8576467f2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## v3.18.2 (2024-03-11) + +### Fix + +- **git**: force the default git locale on methods relying on parsing the output (#1012) ## v3.18.1 (2024-03-11) @@ -86,17 +91,12 @@ - **formats**: expose some new customizable changelog formats on the `commitizen.changelog_format` endpoint (Textile, AsciiDoc and RestructuredText) - **template**: add `changelog --export-template` command - **template**: allow to override the template from cli, configuration and plugins +- **cli.py**: Added support for extra git CLI args after -- separator for `cz commit` command ### Fix - **filename**: ensure `file_name` can be passed to `changelog` from `bump` command -## v3.11.0 (2023-10-17) - -### Feat - -- **cli.py**: Added support for extra git CLI args after -- separator for `cz commit` command - ### Refactor - **git.py**: Removed 'extra_args' from git.commit @@ -304,6 +304,7 @@ ### BREAKING CHANGE - Plugins are now exposed as `commitizen.plugin` entrypoints +- Python 3.6 is not officially supported anymore. Please migrate from 3.6 to 3.7 or greater. ### Feat @@ -427,7 +428,7 @@ ### Fix -- **bump.py**: `CHANGELOG.md` gets git added and committed correctly +- **bump.py**: `CHANGELOG.md` gets git added and commited correctly ## v2.33.0 (2022-09-15) @@ -491,16 +492,16 @@ ## v2.31.0 (2022-08-14) +### Feat + +- new file + ### Fix - **pyproject.toml**: remove test added configurations - **changelog**: use defaults.change_type_order in conventional commit - capitalize types in default change_type_order -### Feat - -- new file - ## v2.30.0 (2022-08-14) ### Feat @@ -605,14 +606,14 @@ ## v2.24.0 (2022-04-15) -### Fix - -- change error code for NoneIncrementExit - ### Feat - add --no-raise to avoid raising error codes +### Fix + +- change error code for NoneIncrementExit + ## v2.23.0 (2022-03-29) ### Feat @@ -621,15 +622,15 @@ ## v2.22.0 (2022-03-29) +### Feat + +- **changelog**: add support for single version and version range + ### Refactor - speed up testing and wait for tags - **git**: use date as a function in GitTag to easily patch -### Feat - -- **changelog**: add support for single version and version range - ## v2.21.2 (2022-02-22) ### Fix @@ -648,26 +649,23 @@ ### Feat -- skip merge messages that start with Pull request - skip merge messages that start with Pull request ## v2.20.5 (2022-02-07) -### Refactor - -- iter_modules only accepts str - ### Fix -- Ignore packages that are not plugins - Ignore packages that are not plugins +### Refactor + +- iter_modules only accepts str + ## v2.20.4 (2022-01-17) ### Fix -- **bump**: raise non zero error code when there's no eligible commit to bump -- **bump**: raise non zero error code when there's no eligible commit to bump +- **bump**: raise non zero error code when there's no elegible commit to bump ## v2.20.3 (2021-12-20) @@ -683,6 +681,10 @@ ## v2.20.1 (2021-12-14) +### Fix + +- import TypedDict from type_extensions for backward compatibility + ### Refactor - **conventional_commits**: remove duplicate patterns and import from defaults @@ -690,10 +692,6 @@ - **defaults**: add Settings typeddict - **defaults**: move bump_map, bump_pattern, commit_parser from defaults to ConventionalCommitsCz -### Fix - -- import TypedDict from type_extensions for backward compatibility - ## v2.20.0 (2021-10-06) ### Feat @@ -717,18 +715,18 @@ ### Fix -- **commit**: correct the stage checker before committing +- **commit**: correct the stage checker before commiting ## v2.18.0 (2021-08-13) -### Refactor - -- **shortcuts**: move check for shortcut config setting to apply to any list select - ### Feat - **prompt**: add keyboard shortcuts with config option +### Refactor + +- **shortcuts**: move check for shortcut config setting to apply to any list select + ## v2.17.13 (2021-07-14) ## v2.17.12 (2021-07-06) @@ -792,7 +790,7 @@ ### Fix -- **bump**: replace all occurrences that match regex +- **bump**: replace all occurances that match regex - **wip**: add test for current breaking change ## v2.17.1 (2021-04-08) @@ -857,16 +855,16 @@ ## v2.13.0 (2021-01-01) +### Feat + +- **#319**: add optional change_type_order + ### Refactor - raise an InvalidConfigurationError - **#323**: address PR feedback - move expected COMMITS_TREE to global -### Feat - -- **#319**: add optional change_type_order - ## v2.12.1 (2020-12-30) ### Fix @@ -890,10 +888,12 @@ ### Feat - add yaml as a config option +- **config**: add support for the new class YAMLConfig at the root of the confi internal package +- **init**: add support for yaml config file at init -### feat +### Fix -- **config**: add support for the new class YAMLConfig at the root of the confi internal package +- **YAMLConfig**: add a TypeError exception to handle in _parse_settings method ## v2.10.0 (2020-12-02) @@ -903,15 +903,15 @@ ## v2.9.0 (2020-12-02) -### Fix - -- **json_config**: fix the emtpy_config_content method - ### Feat - **Init**: add the json config support as an option at Init - **commitizen/config/json_config**: add json support for configuration +### Fix + +- **json_config**: fix the emtpy_config_content method + ## v2.8.2 (2020-11-21) ### Fix @@ -979,15 +979,15 @@ ## v2.3.0 (2020-09-03) +### Feat + +- **cli**: rewrite cli instructions to be more succinct about what they require + ### Fix - **cli**: add guideline for subject input - **cli**: wrap the word enter with brackets -### Feat - -- **cli**: rewrite cli instructions to be more succinct about what they require - ## v2.2.0 (2020-08-31) ### Feat @@ -996,15 +996,15 @@ ## v2.1.0 (2020-08-06) -### Refactor - -- **cz_check**: Refactor _get_commits to return GitCommit instead of dict - ### Feat - **cz_check**: Add rev to all displayed ill-formatted commits - **cz_check**: Update to show all ill-formatted commits +### Refactor + +- **cz_check**: Refactor _get_commits to return GitCommit instead of dict + ## v2.0.2 (2020-08-03) ### Fix @@ -1020,27 +1020,28 @@ ## v2.0.0 (2020-07-26) -### Fix +### BREAKING CHANGE -- add missing `pyyaml` dependency -- **cli**: make command required for commitizen +- setup.cfg, .cz and .cz.cfg are no longer supported +- Use "cz verion" instead +- "cz --debug" will no longer work + #47 ### Feat - **init**: enable setting up pre-commit hook through "cz init" +### Fix + +- add missing `pyyaml` dependency +- **cli**: make command required for commitizen + ### Refactor - **config**: drop "files" configure support. Please use "version_files" instead - **config**: remove ini configuration support - **cli**: remove "--version" argument -### BREAKING CHANGE - -- setup.cfg, .cz and .cz.cfg are no longer supported -- Use "cz version" instead -- "cz --debug" will no longer work - ## v1.25.0 (2020-07-26) ### Feat @@ -1084,6 +1085,10 @@ ## v1.23.0 (2020-06-14) +### Feat + +- **cli**: enable displaying all traceback for CommitizenException when --debug flag is used + ### Refactor - **exception**: rename MissingConfigError as MissingCzCustomizeConfigError @@ -1096,10 +1101,6 @@ - use custom exception for error handling - **error_codes**: remove unused NO_COMMIT_MSG error code -### Feat - -- **cli**: enable displaying all traceback for CommitizenException when --debug flag is used - ## v1.22.3 (2020-06-10) ## v1.22.2 (2020-05-29) @@ -1116,16 +1117,16 @@ ## v1.22.0 (2020-05-13) -### Fix - -- **changelog**: rename `message_hook` -> `changelog_message_builder_hook` - ### Feat - **changelog**: add support for `changelog_hook` when changelog finishes the generation - **changelog**: add support for `message_hook` method - **changelog**: add support for modifying the change_type in the title of the changelog +### Fix + +- **changelog**: rename `message_hook` -> `changelog_message_builder_hook` + ## v1.21.0 (2020-05-09) ### Feat @@ -1163,27 +1164,31 @@ ## v1.19.0 (2020-05-02) -### Fix - -- **git**: missing dependency removed -- **changelog**: check get_metadata for existing changelog file - ### Feat - **changelog**: add support for any commit rule system - **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` +- **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 +- **cz/base**: add default process_commit for processing commit message +- **changelog**: changelog tree generation from markdown -## v1.18.3 (2020-04-22) - -### Refactor - -- **commands/init**: fix typo +### Fix -## v1.18.2 (2020-04-22) +- **git**: missing dependency removed +- **changelog**: check get_metadata for existing changelog file +- **cz/conventional_commits**: fix schema_pattern break due to rebase +- **changelog_template**: fix list format +- **commitizen/cz**: set changelog_map, changelog_pattern to none as default +- **commands/changelog**: remove --skip-merge argument +- **cli**: add changelog arguments ### Refactor -- **git**: replace GitCommit.message code with one-liner - **changelog**: use functions from changelog.py - **changelog**: rename category to change_type to fit 'keep a changelog' - **templates**: rename as "keep_a_changelog_template.j2" @@ -1194,25 +1199,21 @@ - **commands/changelog**: remove redundant if statement - **commands/changelog**: use jinja2 template instead of string concatenation to build changelog +## v1.18.3 (2020-04-22) + +### Refactor + +- **commands/init**: fix typo + +## v1.18.2 (2020-04-22) + ### Fix - **git**: fix returned value for GitCommit.message when body is empty -- **cz/conventional_commits**: fix schema_pattern break due to rebase -- **changelog_template**: fix list format -- **commitizen/cz**: set changelog_map, changelog_pattern to none as default -- **commands/changelog**: remove --skip-merge argument -- **cli**: add changelog arguments -### Feat +### Refactor -- **commands/changelog**: make changelog_file an option in config -- **commands/changelog**: exit when there is no commit exists -- **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 -- **cz/base**: add default process_commit for processing commit message -- **changelog**: changelog tree generation from markdown +- **git**: replace GitCommit.message code with one-liner ## v1.18.1 (2020-04-16) @@ -1222,6 +1223,14 @@ ## v1.18.0 (2020-04-13) +### Feat + +- **bump**: support for ! as BREAKING change in commit message + +### Fix + +- **cz/customize**: add error handling when customize detail is not set + ### Refactor - **cz/customize**: remove unused mypy ignore @@ -1233,14 +1242,6 @@ - **cz**: add type annotation for each function in cz - **config**: fix mypy warning for _conf -### Fix - -- **cz/customize**: add error handling when customize detail is not set - -### Feat - -- **bump**: support for ! as BREAKING change in commit message - ## v1.17.1 (2020-03-24) ### Fix @@ -1253,19 +1254,19 @@ ## v1.17.0 (2020-03-15) -### Refactor +### Feat -- **tests/bump**: use parameterize to group similliar tests -- **cz/connventional_commit**: use \S to check scope -- **git**: remove unnecessary dot between git range +- **commands/check**: add --rev-range argument for checking commits within some range ### Fix - **bump**: fix bump find_increment error -### Feat +### Refactor -- **commands/check**: add --rev-range argument for checking commits within some range +- **cz/connventional_commit**: use \S to check scope +- **git**: remove unnecessary dot between git range +- **tests/bump**: use parameterize to group similliar tests ## v1.16.4 (2020-03-03) @@ -1301,6 +1302,10 @@ ## v1.16.0 (2020-01-21) +### Feat + +- **git**: get_commits default from first_commit + ### Refactor - **commands/bump**: rename parameter into bump_setting to distinguish bump_setting and argument @@ -1308,39 +1313,41 @@ - **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 messages - -### Feat - -- **git**: get_commits default from first_commit +- **git**: Change get_commits into returning commits instead of lines of messsages ## v1.15.1 (2020-01-20) -## v1.15.0 (2020-01-20) +### Fix + +- **cli**: fix --version not functional ### Refactor - **tests/commands/bump**: use tmp_dir to replace self implemented tmp dir behavior -- **git**: make find_git_project_root return None if it's not a git project -- **config/base_config**: make set_key not implemented -- **error_codes**: move all the error_codes to a module -- **config**: replace string type path with pathlib.Path - **test_bump_command**: rename camel case variables - **tests/commands/check**: use pytest fixture tmpdir replace self implemented contextmanager - **test/commands/other**: replace unit test style mock with mocker fixture - **tests/commands**: separate command unit tests into modules - **tests/commands**: make commands related tests a module -### Fix - -- **git**: remove breakline in the return value of find_git_project_root -- **cli**: fix --version not functional +## v1.15.0 (2020-01-20) ### Feat - **config**: look up configuration in git project root - **git**: add find_git_project_root +### Fix + +- **git**: remove breakline in the return value of find_git_project_root + +### Refactor + +- **git**: make find_git_project_root return None if it's not a git project +- **config/base_config**: make set_key not implemented +- **error_codes**: move all the error_codes to a module +- **config**: replace string type path with pathlib.Path + ## v1.14.2 (2020-01-14) ### Fix @@ -1349,20 +1356,20 @@ ## v1.14.1 (2020-01-11) -## v1.14.0 (2020-01-06) +### Fix -### Refactor +- **cli**: fix the way default handled for name argument +- **cli**: fix name cannot be overwritten through config in newly refactored config design -- **pre-commit-hooks**: add metadata for the check hook +## v1.14.0 (2020-01-06) ### Feat - **pre-commit-hooks**: add pre-commit hook -### Fix +### Refactor -- **cli**: fix the way default handled for name argument -- **cli**: fix name cannot be overwritten through config in newly refactored config design +- **pre-commit-hooks**: add metadata for the check hook ## v1.13.1 (2019-12-31) @@ -1392,6 +1399,12 @@ ## v1.10.2 (2019-12-27) +### Fix + +- **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 + ### Refactor - new config system where each config type has its own class @@ -1404,12 +1417,6 @@ - **config**: move default settings back to defaults - **config**: Make config a class and each type of config (e.g., toml, ini) a child class -### Fix - -- **config**: handle empty config file -- **config**: fix load global_conf even if it doesn't exist -- **config/ini_config**: replace outdated _parse_ini_settings with _parse_settings - ## v1.10.1 (2019-12-10) ### Fix @@ -1444,28 +1451,34 @@ - **config**: add deprecation warning for loading config from ini files - **cz/customize**: add jinja support to enhance template flexibility - **cz/filters**: add required_validator and multiple_line_breaker +- **Commands/commit**: add ´--dry-run´ flag to the Commit command - **cz/cz_customize**: implement info to support info and info_path - **cz/cz_customize**: enable bump_pattern bump_map customization - **cz/cz_customize**: implement customizable cz -- **Commands/commit**: add ´--dry-run´ flag to the Commit command - new 'git-cz' entrypoint +### Fix + +- commit dry-run doesnt require staging to be clean +- **scripts**: add back the delelte poetry prefix +- correct typo to spell "convention" +- removing folder in windows throwing a PermissionError +- **test_cli**: testing the version command + ### Refactor - **config**: remove has_pyproject which is no longer used -- **cz/customize**: make jinja2 a custom requirement. if not installed use string.Template instead +- **cz/customize**: make jinja2 a custom requirement. if not installed use string.Tempalte instead - **cz/utils**: rename filters as utils - **cli**: add back --version and remove subcommand required constraint -### Fix +## v1.8.0 (2019-11-12) -- commit dry-run doesn't require staging to be clean -- correct typo to spell "convention" -- removing folder in windows throwing a PermissionError -- **scripts**: add back the delete poetry prefix -- **test_cli**: testing the version command +### Feat -## v1.8.0 (2019-11-12) +- **cz**: add a base exception for cz customization +- **commands/commit**: abort commit if there is nothing to commit +- **git**: add is_staging_clean to check if there is any file in git staging ### Fix @@ -1479,13 +1492,13 @@ - **command/version**: use out.write instead of out.line - **command**: make version a command instead of an argument -### Feat +## v1.7.0 (2019-11-08) -- **cz**: add a base exception for cz customization -- **commands/commit**: abort commit if there is nothing to commit -- **git**: add is_staging_clean to check if there is any file in git staging +### Feat -## v1.7.0 (2019-11-08) +- **config**: update style instead of overwrite +- **config**: parse style in config +- **commit**: make style configurable for commit command ### Fix @@ -1497,12 +1510,6 @@ - **cz**: change the color of default style -### Feat - -- **config**: update style instead of overwrite -- **config**: parse style in config -- **commit**: make style configurable for commit command - ## v1.6.0 (2019-11-05) ### Feat @@ -1523,14 +1530,14 @@ ## v1.4.0 (2019-04-26) -### Fix - -- **bump**: handle commit and create tag failure - ### Feat - added argument yes to bump in order to accept questions +### Fix + +- **bump**: handle commit and create tag failure + ## v1.3.0 (2019-04-24) ### Feat @@ -1551,6 +1558,11 @@ ## v1.1.1 (2019-04-18) +### Fix + +- **bump**: commit message now fits better with semver +- conventional commit 'breaking change' in body instead of title + ### Refactor - changed stdout statements @@ -1559,11 +1571,6 @@ - **example**: command logic removed from commitizen base - **commit**: moved most of the commit logic to the commit command -### Fix - -- **bump**: commit message now fits better with semver -- conventional commit 'breaking change' in body instead of title - ## v1.1.0 (2019-04-14) ### Feat @@ -1573,7 +1580,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 implementation +- first semantic version bump implementaiton ### Fix @@ -1630,13 +1637,13 @@ ## v0.9.6 (2018-09-19) -### Refactor +### Fix -- **conventionalCommit**: moved filters to questions instead of message +- **manifest**: inluded missing files -### Fix +### Refactor -- **manifest**: included missing files +- **conventionalCommit**: moved fitlers to questions instead of message ## v0.9.5 (2018-08-24) @@ -1654,7 +1661,7 @@ ### Feat -- **committer**: conventional commit is a bit more intelligent now +- **commiter**: 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 1e25597fcc..c98522b415 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.18.1" +__version__ = "3.18.2" diff --git a/pyproject.toml b/pyproject.toml index 31c83527b6..dfb5527052 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.18.1" +version = "3.18.2" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.18.1" +version = "3.18.2" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From a92c4341c4d55e6dfffc89dd8952620195449705 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:36:42 +0100 Subject: [PATCH 058/598] build(deps-dev): bump pytest from 8.0.2 to 8.1.1 (#1014) --- poetry.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index ecdde80af8..652ec0a120 100644 --- a/poetry.lock +++ b/poetry.lock @@ -943,13 +943,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co [[package]] name = "pluggy" -version = "1.3.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] [package.extras] @@ -1048,13 +1048,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.0.2" +version = "8.1.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"}, - {file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"}, + {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, + {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, ] [package.dependencies] @@ -1062,11 +1062,11 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.3.0,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +pluggy = ">=1.4,<2.0" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" From 7bee8e7d697f3816cb0996c7e92a5d5714bd8b9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:47:22 +0100 Subject: [PATCH 059/598] build(deps): bump packaging from 23.2 to 24.0 (#1015) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 652ec0a120..54be67d4c4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -856,13 +856,13 @@ setuptools = "*" [[package]] name = "packaging" -version = "23.2" +version = "24.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] From 579205dbbc46120205550a69b84e065fa3d40bfe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:56:34 +0100 Subject: [PATCH 060/598] build(deps-dev): bump mypy from 1.8.0 to 1.9.0 (#1016) --- poetry.lock | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/poetry.lock b/poetry.lock index 54be67d4c4..b67f1fa4b2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -784,38 +784,38 @@ files = [ [[package]] name = "mypy" -version = "1.8.0" +version = "1.9.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, - {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, - {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, - {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, - {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, - {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, - {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, - {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, - {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, - {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, - {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, - {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, - {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, - {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, - {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, - {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, - {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, - {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, - {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, + {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, + {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, + {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, + {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, + {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, + {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, + {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, + {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, + {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, + {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, + {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, + {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, + {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, + {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, + {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, + {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, + {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, ] [package.dependencies] From 61b1570c7b8affc348223acb755664eb7c2b3cf4 Mon Sep 17 00:00:00 2001 From: Axel H Date: Mon, 11 Mar 2024 16:14:43 +0100 Subject: [PATCH 061/598] fix(warnings): all warnings should go to `stdout` --- commitizen/out.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/out.py b/commitizen/out.py index 3801ad4c15..40342e9de5 100644 --- a/commitizen/out.py +++ b/commitizen/out.py @@ -39,4 +39,4 @@ def diagnostic(value: str): def warn(value: str) -> None: message = colored(value, "magenta") - line(message) + line(message, file=sys.stderr) From 7eb6477b14a45f3f0b526a162594045ade174f3b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 11 Mar 2024 17:59:04 +0000 Subject: [PATCH 062/598] =?UTF-8?q?bump:=20version=203.18.2=20=E2=86=92=20?= =?UTF-8?q?3.18.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d674bf0aa6..c47d83a992 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.18.2 # automatically updated by Commitizen + rev: v3.18.3 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 8576467f2c..e0c221824f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.18.3 (2024-03-11) + +### Fix + +- **warnings**: all warnings should go to `stdout` + ## v3.18.2 (2024-03-11) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index c98522b415..c3689ecdcd 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.18.2" +__version__ = "3.18.3" diff --git a/pyproject.toml b/pyproject.toml index dfb5527052..00107d2201 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.18.2" +version = "3.18.3" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.18.2" +version = "3.18.3" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 2155fb3189a73208a81584d1da1c2ce49e31d716 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 01:51:43 +0000 Subject: [PATCH 063/598] build(deps-dev): bump ruff from 0.2.2 to 0.3.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.2 to 0.3.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.2.2...v0.3.2) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index b67f1fa4b2..c580fc260c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.2.2" +version = "0.3.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0a9efb032855ffb3c21f6405751d5e147b0c6b631e3ca3f6b20f917572b97eb6"}, - {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d450b7fbff85913f866a5384d8912710936e2b96da74541c82c1b458472ddb39"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecd46e3106850a5c26aee114e562c329f9a1fbe9e4821b008c4404f64ff9ce73"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e22676a5b875bd72acd3d11d5fa9075d3a5f53b877fe7b4793e4673499318ba"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1695700d1e25a99d28f7a1636d85bafcc5030bba9d0578c0781ba1790dbcf51c"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b0c232af3d0bd8f521806223723456ffebf8e323bd1e4e82b0befb20ba18388e"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f63d96494eeec2fc70d909393bcd76c69f35334cdbd9e20d089fb3f0640216ca"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a61ea0ff048e06de273b2e45bd72629f470f5da8f71daf09fe481278b175001"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1439c8f407e4f356470e54cdecdca1bd5439a0673792dbe34a2b0a551a2fe3"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:940de32dc8853eba0f67f7198b3e79bc6ba95c2edbfdfac2144c8235114d6726"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c126da55c38dd917621552ab430213bdb3273bb10ddb67bc4b761989210eb6e"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3b65494f7e4bed2e74110dac1f0d17dc8e1f42faaa784e7c58a98e335ec83d7e"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1ec49be4fe6ddac0503833f3ed8930528e26d1e60ad35c2446da372d16651ce9"}, - {file = "ruff-0.2.2-py3-none-win32.whl", hash = "sha256:d920499b576f6c68295bc04e7b17b6544d9d05f196bb3aac4358792ef6f34325"}, - {file = "ruff-0.2.2-py3-none-win_amd64.whl", hash = "sha256:cc9a91ae137d687f43a44c900e5d95e9617cb37d4c989e462980ba27039d239d"}, - {file = "ruff-0.2.2-py3-none-win_arm64.whl", hash = "sha256:c9d15fc41e6054bfc7200478720570078f0b41c9ae4f010bcc16bd6f4d1aacdd"}, - {file = "ruff-0.2.2.tar.gz", hash = "sha256:e62ed7f36b3068a30ba39193a14274cd706bc486fad521276458022f7bccb31d"}, + {file = "ruff-0.3.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:77f2612752e25f730da7421ca5e3147b213dca4f9a0f7e0b534e9562c5441f01"}, + {file = "ruff-0.3.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9966b964b2dd1107797be9ca7195002b874424d1d5472097701ae8f43eadef5d"}, + {file = "ruff-0.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b83d17ff166aa0659d1e1deaf9f2f14cbe387293a906de09bc4860717eb2e2da"}, + {file = "ruff-0.3.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb875c6cc87b3703aeda85f01c9aebdce3d217aeaca3c2e52e38077383f7268a"}, + {file = "ruff-0.3.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be75e468a6a86426430373d81c041b7605137a28f7014a72d2fc749e47f572aa"}, + {file = "ruff-0.3.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:967978ac2d4506255e2f52afe70dda023fc602b283e97685c8447d036863a302"}, + {file = "ruff-0.3.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1231eacd4510f73222940727ac927bc5d07667a86b0cbe822024dd00343e77e9"}, + {file = "ruff-0.3.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c6d613b19e9a8021be2ee1d0e27710208d1603b56f47203d0abbde906929a9b"}, + {file = "ruff-0.3.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8439338a6303585d27b66b4626cbde89bb3e50fa3cae86ce52c1db7449330a7"}, + {file = "ruff-0.3.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:de8b480d8379620cbb5ea466a9e53bb467d2fb07c7eca54a4aa8576483c35d36"}, + {file = "ruff-0.3.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b74c3de9103bd35df2bb05d8b2899bf2dbe4efda6474ea9681280648ec4d237d"}, + {file = "ruff-0.3.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f380be9fc15a99765c9cf316b40b9da1f6ad2ab9639e551703e581a5e6da6745"}, + {file = "ruff-0.3.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0ac06a3759c3ab9ef86bbeca665d31ad3aa9a4b1c17684aadb7e61c10baa0df4"}, + {file = "ruff-0.3.2-py3-none-win32.whl", hash = "sha256:9bd640a8f7dd07a0b6901fcebccedadeb1a705a50350fb86b4003b805c81385a"}, + {file = "ruff-0.3.2-py3-none-win_amd64.whl", hash = "sha256:0c1bdd9920cab5707c26c8b3bf33a064a4ca7842d91a99ec0634fec68f9f4037"}, + {file = "ruff-0.3.2-py3-none-win_arm64.whl", hash = "sha256:5f65103b1d76e0d600cabd577b04179ff592064eaa451a70a81085930e907d0b"}, + {file = "ruff-0.3.2.tar.gz", hash = "sha256:fa78ec9418eb1ca3db392811df3376b46471ae93792a81af2d1cbb0e5dcb5142"}, ] [[package]] @@ -1766,4 +1766,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "ae231a49c0c27985defdc7adba7a112eecc8c8abe1e9a8e5cf5358f7a71637c0" +content-hash = "e30411f9893b8c5788c5665a2a888596bcc1c170ac3681f868822e69a4ae1f46" diff --git a/pyproject.toml b/pyproject.toml index 00107d2201..58886b920e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,7 @@ pytest-xdist = "^3.1.0" # code formatter black = ">=23.11,<25.0" # linter -ruff = ">=0.1.6,<0.3.0" +ruff = ">=0.1.6,<0.4.0" pre-commit = ">=2.18,<4.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" From a0003aef26a37b6e4dda43cb07058fc2e9c3feba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:58:14 +0100 Subject: [PATCH 064/598] build(deps-dev): bump types-deprecated from 1.2.9.20240106 to 1.2.9.20240311 (#1022) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index c580fc260c..db0f51c766 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1530,13 +1530,13 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "types-deprecated" -version = "1.2.9.20240106" +version = "1.2.9.20240311" description = "Typing stubs for Deprecated" optional = false python-versions = ">=3.8" files = [ - {file = "types-Deprecated-1.2.9.20240106.tar.gz", hash = "sha256:afeb819e9a03d0a5795f18c88fe6207c48ed13c639e93281bd9d9b7bb6d34310"}, - {file = "types_Deprecated-1.2.9.20240106-py3-none-any.whl", hash = "sha256:9dcb258493b5be407574ee21e50ddac9e429072d39b576126bf1ac00764fb9a8"}, + {file = "types-Deprecated-1.2.9.20240311.tar.gz", hash = "sha256:0680e89989a8142707de8103f15d182445a533c1047fd9b7e8c5459101e9b90a"}, + {file = "types_Deprecated-1.2.9.20240311-py3-none-any.whl", hash = "sha256:d7793aaf32ff8f7e49a8ac781de4872248e0694c4b75a7a8a186c51167463f9d"}, ] [[package]] From 602d668ef6f99d60a6322d78a8534a3b20a9424b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:58:39 +0100 Subject: [PATCH 065/598] build(deps-dev): bump types-python-dateutil from 2.8.19.20240106 to 2.8.19.20240311 (#1021) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index db0f51c766..7af6d53177 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1541,13 +1541,13 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.8.19.20240106" +version = "2.8.19.20240311" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, - {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, + {file = "types-python-dateutil-2.8.19.20240311.tar.gz", hash = "sha256:51178227bbd4cbec35dc9adffbf59d832f20e09842d7dcb8c73b169b8780b7cb"}, + {file = "types_python_dateutil-2.8.19.20240311-py3-none-any.whl", hash = "sha256:ef813da0809aca76472ca88807addbeea98b19339aebe56159ae2f4b4f70857a"}, ] [[package]] From cbcfa7f7332533c4be12820c64dcc3d663758150 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:59:06 +0100 Subject: [PATCH 066/598] build(deps-dev): bump types-pyyaml from 6.0.12.12 to 6.0.12.20240311 (#1020) --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7af6d53177..f40bf129ea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1552,13 +1552,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.12" +version = "6.0.12.20240311" description = "Typing stubs for PyYAML" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.12.tar.gz", hash = "sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062"}, - {file = "types_PyYAML-6.0.12.12-py3-none-any.whl", hash = "sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24"}, + {file = "types-PyYAML-6.0.12.20240311.tar.gz", hash = "sha256:a9e0f0f88dc835739b0c1ca51ee90d04ca2a897a71af79de9aec5f38cb0a5342"}, + {file = "types_PyYAML-6.0.12.20240311-py3-none-any.whl", hash = "sha256:b845b06a1c7e54b8e5b4c683043de0d9caf205e7434b3edc678ff2411979b8f6"}, ] [[package]] From 3c9988acebaa8664873004f259614a2690ebc4da Mon Sep 17 00:00:00 2001 From: Santiago Fraire Date: Thu, 14 Mar 2024 11:11:35 +0100 Subject: [PATCH 067/598] fix(changelog): include latest change when dry run and incremental Closes #1024 --- commitizen/commands/changelog.py | 12 ++++++--- tests/commands/test_bump_command.py | 33 ++++++++++++++++++++++++ tests/commands/test_changelog_command.py | 6 ++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 5d710ed5d0..6b7a63ba9e 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -133,10 +133,6 @@ def write_changelog( if changelog_hook: changelog_out = changelog_hook(changelog_out, partial_changelog) - if self.dry_run: - out.write(changelog_out) - raise DryRunExit() - changelog_file.write(changelog_out) def export_template(self): @@ -221,6 +217,14 @@ def __call__(self): ) changelog_out = changelog_out.lstrip("\n") + # Dry_run is executed here to avoid checking and reading the files + if self.dry_run: + changelog_hook: Callable | None = self.cz.changelog_hook + if changelog_hook: + changelog_out = changelog_hook(changelog_out, "") + out.write(changelog_out) + raise DryRunExit() + lines = [] if self.incremental and os.path.isfile(self.file_name): with open(self.file_name, encoding=self.encoding) as changelog_file: diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index c9e73649f4..6cf8a8d00c 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1406,3 +1406,36 @@ def test_bump_template_extra_quotes( changelog = project_root / any_changelog_format.default_changelog_file assert changelog.read_text() == "no-quote - single quotes - double quotes" + + +def test_bump_changelog_contains_increment_only(mocker, tmp_commitizen_project, capsys): + """Issue 1024""" + # Initialize commitizen up to v1.0.0 + project_root = Path(tmp_commitizen_project) + tmp_commitizen_cfg_file = project_root / "pyproject.toml" + tmp_commitizen_cfg_file.write_text( + "[tool.commitizen]\n" 'version="1.0.0"\n' "update_changelog_on_bump = true\n" + ) + tmp_changelog_file = project_root / "CHANGELOG.md" + tmp_changelog_file.write_text("## v1.0.0") + create_file_and_commit("feat(user): new file") + create_tag("v1.0.0") + + # Add a commit and bump to v2.0.0 + create_file_and_commit("feat(user)!: new file") + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + _ = capsys.readouterr() + + # Add a commit and create the incremental changelog to v3.0.0 + # it should only include v3 changes + create_file_and_commit("feat(next)!: next version") + testargs = ["cz", "bump", "--yes", "--files-only", "--changelog-to-stdout"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(ExpectedExit): + cli.main() + out, _ = capsys.readouterr() + + assert "3.0.0" in out + assert "2.0.0" not in out diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 971d04cce5..c8072831e8 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -294,11 +294,15 @@ def test_changelog_hook(mocker: MockFixture, config: BaseConfig, dry_run: bool): changelog() except DryRunExit: pass + full_changelog = ( "## Unreleased\n\n### Refactor\n\n- is in changelog\n\n### Feat\n\n- new file\n" ) + partial_changelog = full_changelog + if dry_run: + partial_changelog = "" - changelog_hook_mock.assert_called_with(full_changelog, full_changelog) + changelog_hook_mock.assert_called_with(full_changelog, partial_changelog) @pytest.mark.usefixtures("tmp_commitizen_project") From 94f07adcfbc8aac7b85438358e0444aad3660e09 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 14 Mar 2024 18:37:49 +0000 Subject: [PATCH 068/598] =?UTF-8?q?bump:=20version=203.18.3=20=E2=86=92=20?= =?UTF-8?q?3.18.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c47d83a992..74d6c53d56 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.18.3 # automatically updated by Commitizen + rev: v3.18.4 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index e0c221824f..2cfbeb556a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.18.4 (2024-03-14) + +### Fix + +- **changelog**: include latest change when dry run and incremental + ## v3.18.3 (2024-03-11) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index c3689ecdcd..e3c8f4ce80 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.18.3" +__version__ = "3.18.4" diff --git a/pyproject.toml b/pyproject.toml index 58886b920e..8f0995e1e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.18.3" +version = "3.18.4" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.18.3" +version = "3.18.4" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 90d9dadf20e59d58c42f371442e30c57dc8517ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 01:20:53 +0000 Subject: [PATCH 069/598] build(deps-dev): bump ruff from 0.3.2 to 0.3.3 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.2 to 0.3.3. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.3.2...v0.3.3) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index f40bf129ea..82ebb56a61 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.3.2" +version = "0.3.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.3.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:77f2612752e25f730da7421ca5e3147b213dca4f9a0f7e0b534e9562c5441f01"}, - {file = "ruff-0.3.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9966b964b2dd1107797be9ca7195002b874424d1d5472097701ae8f43eadef5d"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b83d17ff166aa0659d1e1deaf9f2f14cbe387293a906de09bc4860717eb2e2da"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb875c6cc87b3703aeda85f01c9aebdce3d217aeaca3c2e52e38077383f7268a"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be75e468a6a86426430373d81c041b7605137a28f7014a72d2fc749e47f572aa"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:967978ac2d4506255e2f52afe70dda023fc602b283e97685c8447d036863a302"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1231eacd4510f73222940727ac927bc5d07667a86b0cbe822024dd00343e77e9"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c6d613b19e9a8021be2ee1d0e27710208d1603b56f47203d0abbde906929a9b"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8439338a6303585d27b66b4626cbde89bb3e50fa3cae86ce52c1db7449330a7"}, - {file = "ruff-0.3.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:de8b480d8379620cbb5ea466a9e53bb467d2fb07c7eca54a4aa8576483c35d36"}, - {file = "ruff-0.3.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b74c3de9103bd35df2bb05d8b2899bf2dbe4efda6474ea9681280648ec4d237d"}, - {file = "ruff-0.3.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f380be9fc15a99765c9cf316b40b9da1f6ad2ab9639e551703e581a5e6da6745"}, - {file = "ruff-0.3.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0ac06a3759c3ab9ef86bbeca665d31ad3aa9a4b1c17684aadb7e61c10baa0df4"}, - {file = "ruff-0.3.2-py3-none-win32.whl", hash = "sha256:9bd640a8f7dd07a0b6901fcebccedadeb1a705a50350fb86b4003b805c81385a"}, - {file = "ruff-0.3.2-py3-none-win_amd64.whl", hash = "sha256:0c1bdd9920cab5707c26c8b3bf33a064a4ca7842d91a99ec0634fec68f9f4037"}, - {file = "ruff-0.3.2-py3-none-win_arm64.whl", hash = "sha256:5f65103b1d76e0d600cabd577b04179ff592064eaa451a70a81085930e907d0b"}, - {file = "ruff-0.3.2.tar.gz", hash = "sha256:fa78ec9418eb1ca3db392811df3376b46471ae93792a81af2d1cbb0e5dcb5142"}, + {file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:973a0e388b7bc2e9148c7f9be8b8c6ae7471b9be37e1cc732f8f44a6f6d7720d"}, + {file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfa60d23269d6e2031129b053fdb4e5a7b0637fc6c9c0586737b962b2f834493"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eca7ff7a47043cf6ce5c7f45f603b09121a7cc047447744b029d1b719278eb5"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7d3f6762217c1da954de24b4a1a70515630d29f71e268ec5000afe81377642d"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b24c19e8598916d9c6f5a5437671f55ee93c212a2c4c569605dc3842b6820386"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5a6cbf216b69c7090f0fe4669501a27326c34e119068c1494f35aaf4cc683778"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352e95ead6964974b234e16ba8a66dad102ec7bf8ac064a23f95371d8b198aab"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d6ab88c81c4040a817aa432484e838aaddf8bfd7ca70e4e615482757acb64f8"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79bca3a03a759cc773fca69e0bdeac8abd1c13c31b798d5bb3c9da4a03144a9f"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2700a804d5336bcffe063fd789ca2c7b02b552d2e323a336700abb8ae9e6a3f8"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fd66469f1a18fdb9d32e22b79f486223052ddf057dc56dea0caaf1a47bdfaf4e"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:45817af234605525cdf6317005923bf532514e1ea3d9270acf61ca2440691376"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0da458989ce0159555ef224d5b7c24d3d2e4bf4c300b85467b08c3261c6bc6a8"}, + {file = "ruff-0.3.3-py3-none-win32.whl", hash = "sha256:f2831ec6a580a97f1ea82ea1eda0401c3cdf512cf2045fa3c85e8ef109e87de0"}, + {file = "ruff-0.3.3-py3-none-win_amd64.whl", hash = "sha256:be90bcae57c24d9f9d023b12d627e958eb55f595428bafcb7fec0791ad25ddfc"}, + {file = "ruff-0.3.3-py3-none-win_arm64.whl", hash = "sha256:0171aab5fecdc54383993389710a3d1227f2da124d76a2784a7098e818f92d61"}, + {file = "ruff-0.3.3.tar.gz", hash = "sha256:38671be06f57a2f8aba957d9f701ea889aa5736be806f18c0cd03d6ff0cbca8d"}, ] [[package]] From 7d7fc3a18104880358871e11de0acfe31d28e7ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:40:46 +0100 Subject: [PATCH 070/598] build(deps-dev): bump mkdocs-material from 9.5.13 to 9.5.14 (#1031) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 82ebb56a61..e1348cd972 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.13" +version = "9.5.14" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.13-py3-none-any.whl", hash = "sha256:5cbe17fee4e3b4980c8420a04cc762d8dc052ef1e10532abd4fce88e5ea9ce6a"}, - {file = "mkdocs_material-9.5.13.tar.gz", hash = "sha256:d8e4caae576312a88fd2609b81cf43d233cdbe36860d67a68702b018b425bd87"}, + {file = "mkdocs_material-9.5.14-py3-none-any.whl", hash = "sha256:a45244ac221fda46ecf8337f00ec0e5cb5348ab9ffb203ca2a0c313b0d4dbc27"}, + {file = "mkdocs_material-9.5.14.tar.gz", hash = "sha256:2a1f8e67cda2587ab93ecea9ba42d0ca61d1d7b5fad8cf690eeaeb39dcd4b9af"}, ] [package.dependencies] From e392672725ba6f74312c64dce563d39ccac71aec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:41:07 +0100 Subject: [PATCH 071/598] build(deps-dev): bump black from 24.2.0 to 24.3.0 (#1030) --- poetry.lock | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/poetry.lock b/poetry.lock index e1348cd972..704ef0dd63 100644 --- a/poetry.lock +++ b/poetry.lock @@ -73,33 +73,33 @@ files = [ [[package]] name = "black" -version = "24.2.0" +version = "24.3.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, - {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, - {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, - {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, - {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, - {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, - {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, - {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, - {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, - {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, - {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, - {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, - {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, - {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, - {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, - {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, - {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, - {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, - {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, - {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, - {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, - {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, + {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"}, + {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"}, + {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"}, + {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"}, + {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"}, + {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"}, + {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"}, + {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"}, + {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"}, + {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"}, + {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"}, + {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"}, + {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"}, + {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"}, + {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"}, + {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"}, + {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"}, + {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"}, + {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"}, + {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, + {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, + {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, ] [package.dependencies] From 5d64224c2741970995aa960b0b9144ab3158591b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:41:27 +0100 Subject: [PATCH 072/598] build(deps-dev): bump types-python-dateutil from 2.8.19.20240311 to 2.9.0.20240316 (#1029) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 704ef0dd63..4f0fbb5deb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1541,13 +1541,13 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.8.19.20240311" +version = "2.9.0.20240316" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.20240311.tar.gz", hash = "sha256:51178227bbd4cbec35dc9adffbf59d832f20e09842d7dcb8c73b169b8780b7cb"}, - {file = "types_python_dateutil-2.8.19.20240311-py3-none-any.whl", hash = "sha256:ef813da0809aca76472ca88807addbeea98b19339aebe56159ae2f4b4f70857a"}, + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, ] [[package]] From f72828a0a1451035ef5ffdb61bed47a081014763 Mon Sep 17 00:00:00 2001 From: Axel H Date: Tue, 19 Mar 2024 11:42:16 +0100 Subject: [PATCH 073/598] feat(changelog): adds a `changelog_release_hook` called for each release in the changelog (#1018) --- commitizen/changelog.py | 16 ++++++++++++++-- commitizen/commands/changelog.py | 6 +++++- commitizen/cz/base.py | 9 +++++++++ docs/customization.md | 5 +++++ tests/commands/test_changelog_command.py | 22 ++++++++++++++++++++++ tests/test_changelog.py | 21 +++++++++++++++++++++ 6 files changed, 76 insertions(+), 3 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 5c713af0e6..7caa64c640 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -43,6 +43,7 @@ from commitizen import out from commitizen.bump import normalize_tag +from commitizen.cz.base import ChangelogReleaseHook from commitizen.exceptions import InvalidConfigurationError, NoCommitsFoundError from commitizen.git import GitCommit, GitTag from commitizen.version_schemes import ( @@ -113,6 +114,7 @@ def generate_tree_from_commits( unreleased_version: str | None = None, change_type_map: dict[str, str] | None = None, changelog_message_builder_hook: MessageBuilderHook | None = None, + changelog_release_hook: ChangelogReleaseHook | None = None, merge_prerelease: bool = False, scheme: VersionScheme = DEFAULT_SCHEME, ) -> Iterable[dict]: @@ -143,11 +145,14 @@ def generate_tree_from_commits( commit_tag, used_tags, merge_prerelease, scheme=scheme ): used_tags.append(commit_tag) - yield { + release = { "version": current_tag_name, "date": current_tag_date, "changes": changes, } + if changelog_release_hook: + release = changelog_release_hook(release, commit_tag) + yield release current_tag_name = commit_tag.name current_tag_date = commit_tag.date changes = defaultdict(list) @@ -178,7 +183,14 @@ def generate_tree_from_commits( change_type_map, ) - yield {"version": current_tag_name, "date": current_tag_date, "changes": changes} + release = { + "version": current_tag_name, + "date": current_tag_date, + "changes": changes, + } + if changelog_release_hook: + release = changelog_release_hook(release, commit_tag) + yield release def process_commit_message( diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 6b7a63ba9e..3fc204eba9 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -9,7 +9,7 @@ from commitizen import bump, changelog, defaults, factory, git, out from commitizen.config import BaseConfig -from commitizen.cz.base import MessageBuilderHook +from commitizen.cz.base import MessageBuilderHook, ChangelogReleaseHook from commitizen.exceptions import ( DryRunExit, NoCommitsFoundError, @@ -150,6 +150,9 @@ def __call__(self): changelog_message_builder_hook: MessageBuilderHook | None = ( self.cz.changelog_message_builder_hook ) + changelog_release_hook: ChangelogReleaseHook | None = ( + self.cz.changelog_release_hook + ) merge_prerelease = self.merge_prerelease if self.export_template_to: @@ -203,6 +206,7 @@ def __call__(self): unreleased_version, change_type_map=change_type_map, changelog_message_builder_hook=changelog_message_builder_hook, + changelog_release_hook=changelog_release_hook, merge_prerelease=merge_prerelease, scheme=self.scheme, ) diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 5a84d1f101..bd116ceb02 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -17,6 +17,12 @@ def __call__( ) -> dict[str, Any] | Iterable[dict[str, Any]] | None: ... +class ChangelogReleaseHook(Protocol): + def __call__( + self, release: dict[str, Any], tag: git.GitTag | None + ) -> dict[str, Any]: ... + + class BaseCommitizen(metaclass=ABCMeta): bump_pattern: str | None = None bump_map: dict[str, str] | None = None @@ -48,6 +54,9 @@ class BaseCommitizen(metaclass=ABCMeta): # Executed only at the end of the changelog generation changelog_hook: Callable[[str, str | None], str] | None = None + # Executed for each release in the changelog + changelog_release_hook: ChangelogReleaseHook | None = None + # Plugins can override templates and provide extra template data template_loader: BaseLoader = PackageLoader("commitizen", "templates") template_extras: dict[str, Any] = {} diff --git a/docs/customization.md b/docs/customization.md index 7d352f0313..24f749a1eb 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -320,6 +320,7 @@ You can customize it of course, and this are the variables you need to add to yo | `change_type_map` | `dict` | NO | Convert the title of the change type that will appear in the changelog, if a value is not found, the original will be provided | | `changelog_message_builder_hook` | `method: (dict, git.GitCommit) -> dict | list | None` | NO | Customize with extra information your message output, like adding links, this function is executed per parsed commit. Each GitCommit contains the following attrs: `rev`, `title`, `body`, `author`, `author_email`. Returning a falsy value ignore the commit. | | `changelog_hook` | `method: (full_changelog: str, partial_changelog: Optional[str]) -> str` | NO | Receives the whole and partial (if used incremental) changelog. Useful to send slack messages or notify a compliance department. Must return the full_changelog | +| `changelog_release_hook` | `method: (release: dict, tag: git.GitTag) -> dict` | NO | Receives each generated changelog release and its associated tag. Useful to enrich a releases before they are rendered. Must return the update release ```python from commitizen.cz.base import BaseCommitizen @@ -347,6 +348,10 @@ class StrangeCommitizen(BaseCommitizen): ] = f"{m} {rev} [{commit.author}]({commit.author_email})" return parsed_message + def changelog_release_hook(self, release: dict, tag: git.GitTag) -> dict: + release["author"] = tag.author + return release + def changelog_hook( self, full_changelog: str, partial_changelog: Optional[str] ) -> str: diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index c8072831e8..4596724158 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -327,6 +327,28 @@ def test_changelog_hook_customize(mocker: MockFixture, config_customize): changelog_hook_mock.assert_called_with(full_changelog, full_changelog) +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_changelog_release_hook(mocker: MockFixture, config): + def changelog_release_hook(release: dict, tag: git.GitTag) -> dict: + return release + + for i in range(3): + create_file_and_commit("feat: new file") + create_file_and_commit("refactor: is in changelog") + create_file_and_commit("Merge into master") + git.tag(f"0.{i + 1}.0") + + # changelog = Changelog(config, {}) + changelog = Changelog( + config, {"unreleased_version": None, "incremental": True, "dry_run": False} + ) + mocker.patch.object(changelog.cz, "changelog_release_hook", changelog_release_hook) + spy = mocker.spy(changelog.cz, "changelog_release_hook") + changelog() + + assert spy.call_count == 3 + + @pytest.mark.usefixtures("tmp_commitizen_project") def test_changelog_with_non_linear_merges_commit_order( mocker: MockFixture, config_customize diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 7944f66dd8..831e013e3c 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,6 +1,7 @@ import re from pathlib import Path +from typing import Optional import pytest from jinja2 import FileSystemLoader @@ -1404,6 +1405,26 @@ def changelog_message_builder_hook(message: dict, commit: git.GitCommit): ), f"Line {no}: type {change_type} should have been overridden" +def test_render_changelog_with_changelog_release_hook( + gitcommits, tags, any_changelog_format: ChangelogFormat +): + def changelog_release_hook(release: dict, tag: Optional[git.GitTag]) -> dict: + release["extra"] = "whatever" + return release + + parser = ConventionalCommitsCz.commit_parser + changelog_pattern = ConventionalCommitsCz.changelog_pattern + tree = changelog.generate_tree_from_commits( + gitcommits, + tags, + parser, + changelog_pattern, + changelog_release_hook=changelog_release_hook, + ) + for release in tree: + assert release["extra"] == "whatever" + + def test_get_smart_tag_range_returns_an_extra_for_a_range(tags): start, end = ( tags[0], From c8a9008df7540dd527b3a81787e4d7aa2cf1fdea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 19 Mar 2024 10:42:39 +0000 Subject: [PATCH 074/598] =?UTF-8?q?bump:=20version=203.18.4=20=E2=86=92=20?= =?UTF-8?q?3.19.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 74d6c53d56..6adebbedd0 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.18.4 # automatically updated by Commitizen + rev: v3.19.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cfbeb556a..3e90176111 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.19.0 (2024-03-19) + +### Feat + +- **changelog**: adds a `changelog_release_hook` called for each release in the changelog (#1018) + ## v3.18.4 (2024-03-14) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index e3c8f4ce80..0e6cf3e2e7 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.18.4" +__version__ = "3.19.0" diff --git a/pyproject.toml b/pyproject.toml index 8f0995e1e1..4ac781df3f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.18.4" +version = "3.19.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.18.4" +version = "3.19.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From bbae8e0880f0aa6359e2781a54e0bb56248c3049 Mon Sep 17 00:00:00 2001 From: Axel H Date: Tue, 19 Mar 2024 11:49:41 +0100 Subject: [PATCH 075/598] feat(changelog): expose commits `sha1`, `author` and `author_email` in changelog tree (fix #987) (#1013) --- commitizen/changelog.py | 7 ++++++- docs/customization.md | 3 +++ tests/test_changelog.py | 22 ++++++++++++++++++---- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 7caa64c640..12d52f7b08 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -200,7 +200,12 @@ def process_commit_message( changes: dict[str | None, list], change_type_map: dict[str, str] | None = None, ): - message: dict = parsed.groupdict() + message: dict = { + "sha1": commit.rev, + "author": commit.author, + "author_email": commit.author_email, + **parsed.groupdict(), + } if processed := hook(message, commit) if hook else message: messages = [processed] if isinstance(processed, dict) else processed diff --git a/docs/customization.md b/docs/customization.md index 24f749a1eb..1fd1826e03 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -505,6 +505,9 @@ Each `Change` has the following fields: | ---- | ---- | ----------- | | scope | `str | None` | An optional scope | | message | `str` | The commit message body | +| sha1 | `str` | The commit `sha1` | +| author | `str` | The commit author name | +| author_email | `str` | The commit author email | !!! Note The field values depend on the customization class and/or the settings you provide diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 831e013e3c..9ccc207936 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1084,10 +1084,24 @@ def test_generate_tree_from_commits(gitcommits, tags, merge_prereleases): tree = changelog.generate_tree_from_commits( gitcommits, tags, parser, changelog_pattern, merge_prerelease=merge_prereleases ) - if merge_prereleases: - assert tuple(tree) == COMMITS_TREE_AFTER_MERGED_PRERELEASES - else: - assert tuple(tree) == COMMITS_TREE + expected = ( + COMMITS_TREE_AFTER_MERGED_PRERELEASES if merge_prereleases else COMMITS_TREE + ) + + for release, expected_release in zip(tree, expected): + assert release["version"] == expected_release["version"] + assert release["date"] == expected_release["date"] + assert release["changes"].keys() == expected_release["changes"].keys() + for change_type in release["changes"]: + changes = release["changes"][change_type] + expected_changes = expected_release["changes"][change_type] + for change, expected_change in zip(changes, expected_changes): + assert change["scope"] == expected_change["scope"] + assert change["breaking"] == expected_change["breaking"] + assert change["message"] == expected_change["message"] + assert change["author"] == "Commitizen" + assert change["author_email"] in "author@cz.dev" + assert "sha1" in change def test_generate_tree_from_commits_with_no_commits(tags): From 91753282436eda42fe95b73eee0c2931b1858f43 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 19 Mar 2024 10:50:09 +0000 Subject: [PATCH 076/598] =?UTF-8?q?bump:=20version=203.19.0=20=E2=86=92=20?= =?UTF-8?q?3.20.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6adebbedd0..fb3881cc7a 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.19.0 # automatically updated by Commitizen + rev: v3.20.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e90176111..38f588354c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.20.0 (2024-03-19) + +### Feat + +- **changelog**: expose commits `sha1`, `author` and `author_email` in changelog tree (fix #987) (#1013) + ## v3.19.0 (2024-03-19) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 0e6cf3e2e7..10c5c0dd1b 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.19.0" +__version__ = "3.20.0" diff --git a/pyproject.toml b/pyproject.toml index 4ac781df3f..30d548890a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.19.0" +version = "3.20.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.19.0" +version = "3.20.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From f485108485ed61b49df02779f741000159ba32ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 01:09:08 +0000 Subject: [PATCH 077/598] build(deps): bump importlib-metadata from 7.0.2 to 7.1.0 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 7.0.2 to 7.1.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v7.0.2...v7.1.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4f0fbb5deb..923d0ba013 100644 --- a/poetry.lock +++ b/poetry.lock @@ -496,13 +496,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.0.2" +version = "7.1.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.0.2-py3-none-any.whl", hash = "sha256:f4bc4c0c070c490abf4ce96d715f68e95923320370efb66143df00199bb6c100"}, - {file = "importlib_metadata-7.0.2.tar.gz", hash = "sha256:198f568f3230878cb1b44fbd7975f87906c22336dba2e4a7f05278c281fbd792"}, + {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, + {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, ] [package.dependencies] @@ -511,7 +511,7 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "iniconfig" From 49dc1bec07019e7721652f9b17d9652ecd196956 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 01:32:38 +0000 Subject: [PATCH 078/598] build(deps-dev): bump pytest-mock from 3.12.0 to 3.14.0 Bumps [pytest-mock](https://github.com/pytest-dev/pytest-mock) from 3.12.0 to 3.14.0. - [Release notes](https://github.com/pytest-dev/pytest-mock/releases) - [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.12.0...v3.14.0) --- updated-dependencies: - dependency-name: pytest-mock dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 923d0ba013..d91e6a7d02 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1117,17 +1117,17 @@ pytest = ">=3.6" [[package]] name = "pytest-mock" -version = "3.12.0" +version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-mock-3.12.0.tar.gz", hash = "sha256:31a40f038c22cad32287bb43932054451ff5583ff094bca6f675df2f8bc1a6e9"}, - {file = "pytest_mock-3.12.0-py3-none-any.whl", hash = "sha256:0972719a7263072da3a21c7f4773069bcc7486027d7e8e1f81d98a47e701bc4f"}, + {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, + {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, ] [package.dependencies] -pytest = ">=5.0" +pytest = ">=6.2.5" [package.extras] dev = ["pre-commit", "pytest-asyncio", "tox"] From 00daf2ae360e3332b68e11783d2d08a53a547f90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 01:33:20 +0000 Subject: [PATCH 079/598] build(deps-dev): bump ruff from 0.3.3 to 0.3.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.3 to 0.3.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.3.3...v0.3.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index d91e6a7d02..d208512744 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.3.3" +version = "0.3.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:973a0e388b7bc2e9148c7f9be8b8c6ae7471b9be37e1cc732f8f44a6f6d7720d"}, - {file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfa60d23269d6e2031129b053fdb4e5a7b0637fc6c9c0586737b962b2f834493"}, - {file = "ruff-0.3.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eca7ff7a47043cf6ce5c7f45f603b09121a7cc047447744b029d1b719278eb5"}, - {file = "ruff-0.3.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7d3f6762217c1da954de24b4a1a70515630d29f71e268ec5000afe81377642d"}, - {file = "ruff-0.3.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b24c19e8598916d9c6f5a5437671f55ee93c212a2c4c569605dc3842b6820386"}, - {file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5a6cbf216b69c7090f0fe4669501a27326c34e119068c1494f35aaf4cc683778"}, - {file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352e95ead6964974b234e16ba8a66dad102ec7bf8ac064a23f95371d8b198aab"}, - {file = "ruff-0.3.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d6ab88c81c4040a817aa432484e838aaddf8bfd7ca70e4e615482757acb64f8"}, - {file = "ruff-0.3.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79bca3a03a759cc773fca69e0bdeac8abd1c13c31b798d5bb3c9da4a03144a9f"}, - {file = "ruff-0.3.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2700a804d5336bcffe063fd789ca2c7b02b552d2e323a336700abb8ae9e6a3f8"}, - {file = "ruff-0.3.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fd66469f1a18fdb9d32e22b79f486223052ddf057dc56dea0caaf1a47bdfaf4e"}, - {file = "ruff-0.3.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:45817af234605525cdf6317005923bf532514e1ea3d9270acf61ca2440691376"}, - {file = "ruff-0.3.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0da458989ce0159555ef224d5b7c24d3d2e4bf4c300b85467b08c3261c6bc6a8"}, - {file = "ruff-0.3.3-py3-none-win32.whl", hash = "sha256:f2831ec6a580a97f1ea82ea1eda0401c3cdf512cf2045fa3c85e8ef109e87de0"}, - {file = "ruff-0.3.3-py3-none-win_amd64.whl", hash = "sha256:be90bcae57c24d9f9d023b12d627e958eb55f595428bafcb7fec0791ad25ddfc"}, - {file = "ruff-0.3.3-py3-none-win_arm64.whl", hash = "sha256:0171aab5fecdc54383993389710a3d1227f2da124d76a2784a7098e818f92d61"}, - {file = "ruff-0.3.3.tar.gz", hash = "sha256:38671be06f57a2f8aba957d9f701ea889aa5736be806f18c0cd03d6ff0cbca8d"}, + {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"}, ] [[package]] From d34b94686815c74ed8df55b7f14f1566c3101101 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 01:48:47 +0000 Subject: [PATCH 080/598] build(deps-dev): bump mkdocs-material from 9.5.14 to 9.5.15 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.14 to 9.5.15. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.14...9.5.15) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d208512744..961540443e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.14" +version = "9.5.15" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.14-py3-none-any.whl", hash = "sha256:a45244ac221fda46ecf8337f00ec0e5cb5348ab9ffb203ca2a0c313b0d4dbc27"}, - {file = "mkdocs_material-9.5.14.tar.gz", hash = "sha256:2a1f8e67cda2587ab93ecea9ba42d0ca61d1d7b5fad8cf690eeaeb39dcd4b9af"}, + {file = "mkdocs_material-9.5.15-py3-none-any.whl", hash = "sha256:e5c96dec3d19491de49ca643fc1dbb92b278e43cdb816c775bc47db77d9b62fb"}, + {file = "mkdocs_material-9.5.15.tar.gz", hash = "sha256:39f03cca45e82bf54eb7456b5a18bd252eabfdd67f237a229471484a0a4d4635"}, ] [package.dependencies] From 8daca3faf836e49ffd65da93e0b7c87e101f5071 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 01:46:39 +0000 Subject: [PATCH 081/598] build(deps-dev): bump pytest-cov from 4.1.0 to 5.0.0 Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 4.1.0 to 5.0.0. - [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-cov/compare/v4.1.0...v5.0.0) --- updated-dependencies: - dependency-name: pytest-cov dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 961540443e..2d49e41b5a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1070,13 +1070,13 @@ testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygm [[package]] name = "pytest-cov" -version = "4.1.0" +version = "5.0.0" description = "Pytest plugin for measuring coverage." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, ] [package.dependencies] @@ -1084,7 +1084,7 @@ coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-datadir" @@ -1766,4 +1766,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "e30411f9893b8c5788c5665a2a888596bcc1c170ac3681f868822e69a4ae1f46" +content-hash = "614f9b1db867d5b7f954c318309b0e7b18951ed7be6d8016af79a08b8c2c7a89" diff --git a/pyproject.toml b/pyproject.toml index 30d548890a..82f415ff34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ importlib_metadata = { version = ">=4.13,<8"} ipython = "^8.0" # test pytest = ">=7.2,<9.0" -pytest-cov = "^4.0" +pytest-cov = ">=4,<6" pytest-mock = "^3.10" pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" From 3212eaa0621dcb7634a0f944eeb7663b136d570c Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 18:02:26 +0100 Subject: [PATCH 082/598] feat(commit): add retry_after_failure config option and --no-retry flag --- commitizen/cli.py | 6 ++++++ commitizen/commands/commit.py | 19 +++++++++++++++---- commitizen/defaults.py | 2 ++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index c25bd4f713..a442803d7f 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -123,6 +123,12 @@ def __call__( "action": "store_true", "help": "retry last commit", }, + { + "name": ["--no-retry"], + "action": "store_true", + "default": False, + "help": "skip retry if retry_after_failure is set to true", + }, { "name": "--dry-run", "action": "store_true", diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index b8e5eed6d4..390741afc1 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -33,13 +33,16 @@ def __init__(self, config: BaseConfig, arguments: dict): self.arguments = arguments self.temp_file: str = os.path.join( tempfile.gettempdir(), - "cz.commit{user}.backup".format(user=os.environ.get("USER", "")), + "cz.commit%{user}%{project_root}.backup".format( + user=os.environ.get("USER", ""), + project_root=str(git.find_git_project_root()).replace("/", "%"), + ), ) - def read_backup_message(self) -> str: + def read_backup_message(self) -> str | None: # Check the commit backup file exists if not os.path.isfile(self.temp_file): - raise NoCommitBackupError() + return None # Read commit message from backup with open(self.temp_file, encoding=self.encoding) as f: @@ -65,7 +68,7 @@ def prompt_commit_questions(self) -> str: def __call__(self): dry_run: bool = self.arguments.get("dry_run") - write_message_to_file = self.arguments.get("write_message_to_file") + write_message_to_file: bool = self.arguments.get("write_message_to_file") is_all: bool = self.arguments.get("all") if is_all: @@ -78,9 +81,17 @@ def __call__(self): raise NotAllowed(f"{write_message_to_file} is a directory") retry: bool = self.arguments.get("retry") + no_retry: bool = self.arguments.get("no_retry") + retry_after_failure: bool = self.config.settings.get("retry_after_failure") if retry: m = self.read_backup_message() + if m is None: + raise NoCommitBackupError() + elif retry_after_failure and not no_retry: + m = self.read_backup_message() + if m is None: + m = self.prompt_commit_questions() else: m = self.prompt_commit_questions() diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 7aa2c793c5..071efd10b9 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -37,6 +37,7 @@ class Settings(TypedDict, total=False): version_type: str | None tag_format: str bump_message: str | None + retry_after_failure: bool allow_abort: bool allowed_prefixes: list[str] changelog_file: str @@ -77,6 +78,7 @@ class Settings(TypedDict, total=False): "version_scheme": None, "tag_format": "$version", # example v$version "bump_message": None, # bumped v$current_version to $new_version + "retry_after_failure": False, "allow_abort": False, "allowed_prefixes": [ "Merge", From 25320034fadf0bd30b67dedfbe3e07a1c6ef0bf5 Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 18:50:41 +0100 Subject: [PATCH 083/598] test(commit): add tests for retry_after_failure config option and --no-retry flag --- tests/commands/test_commit_command.py | 63 +++++++++++++++++++++++++++ tests/test_conf.py | 2 + 2 files changed, 65 insertions(+) diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index e3f9989823..545defe0e4 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -94,6 +94,69 @@ def test_commit_retry_works(config, mocker: MockFixture): assert not os.path.isfile(temp_file) +@pytest.mark.usefixtures("staging_is_clean") +def test_commit_retry_after_failure_no_backup(config, mocker: MockFixture): + prompt_mock = mocker.patch("questionary.prompt") + prompt_mock.return_value = { + "prefix": "feat", + "subject": "user created", + "scope": "", + "is_breaking_change": False, + "body": "closes #21", + "footer": "", + } + + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) + success_mock = mocker.patch("commitizen.out.success") + + config.settings["retry_after_failure"] = True + commands.Commit(config, {})() + + commit_mock.assert_called_with("feat: user created\n\ncloses #21", args="") + prompt_mock.assert_called_once() + success_mock.assert_called_once() + + +@pytest.mark.usefixtures("staging_is_clean") +def test_commit_retry_after_failure_works(config, mocker: MockFixture): + prompt_mock = mocker.patch("questionary.prompt") + prompt_mock.return_value = { + "prefix": "feat", + "subject": "user created", + "scope": "", + "is_breaking_change": False, + "body": "closes #21", + "footer": "", + } + + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("", "error", b"", b"", 9) + error_mock = mocker.patch("commitizen.out.error") + + with pytest.raises(CommitError): + commit_cmd = commands.Commit(config, {}) + temp_file = commit_cmd.temp_file + commit_cmd() + + prompt_mock.assert_called_once() + error_mock.assert_called_once() + assert os.path.isfile(temp_file) + + # Previous commit failed, so retry should pick up the backup commit + # commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) + success_mock = mocker.patch("commitizen.out.success") + + config.settings["retry_after_failure"] = True + commands.Commit(config, {})() + + commit_mock.assert_called_with("feat: user created\n\ncloses #21", args="") + prompt_mock.assert_called_once() + success_mock.assert_called_once() + assert not os.path.isfile(temp_file) + + @pytest.mark.usefixtures("staging_is_clean") def test_commit_command_with_dry_run_option(config, mocker: MockFixture): prompt_mock = mocker = mocker.patch("questionary.prompt") diff --git a/tests/test_conf.py b/tests/test_conf.py index dcac8e015c..a12bcdd35d 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -52,6 +52,7 @@ "version_scheme": None, "tag_format": "$version", "bump_message": None, + "retry_after_failure": False, "allow_abort": False, "allowed_prefixes": ["Merge", "Revert", "Pull request", "fixup!", "squash!"], "version_files": ["commitizen/__version__.py", "pyproject.toml"], @@ -80,6 +81,7 @@ "version_scheme": None, "tag_format": "$version", "bump_message": None, + "retry_after_failure": False, "allow_abort": False, "allowed_prefixes": ["Merge", "Revert", "Pull request", "fixup!", "squash!"], "version_files": ["commitizen/__version__.py", "pyproject.toml"], From f1c1e576fab6b2ab52ce03ad64a0bdda8f14605a Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 19:02:20 +0100 Subject: [PATCH 084/598] refactor(utils): move backup path creation to utils --- commitizen/commands/commit.py | 9 ++------- commitizen/cz/utils.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 390741afc1..f2ccc6b1af 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -7,6 +7,7 @@ from commitizen import factory, git, out from commitizen.config import BaseConfig from commitizen.cz.exceptions import CzException +from commitizen.cz.utils import get_backup_file_path from commitizen.exceptions import ( CommitError, CustomError, @@ -31,13 +32,7 @@ def __init__(self, config: BaseConfig, arguments: dict): self.encoding = config.settings["encoding"] self.cz = factory.commiter_factory(self.config) self.arguments = arguments - self.temp_file: str = os.path.join( - tempfile.gettempdir(), - "cz.commit%{user}%{project_root}.backup".format( - user=os.environ.get("USER", ""), - project_root=str(git.find_git_project_root()).replace("/", "%"), - ), - ) + self.temp_file: str = get_backup_file_path() def read_backup_message(self) -> str | None: # Check the commit backup file exists diff --git a/commitizen/cz/utils.py b/commitizen/cz/utils.py index 71dac105a7..93c63a2213 100644 --- a/commitizen/cz/utils.py +++ b/commitizen/cz/utils.py @@ -1,6 +1,9 @@ import re +import os +import tempfile from commitizen.cz import exceptions +from commitizen import git def required_validator(answer, msg=None): @@ -15,3 +18,13 @@ def multiple_line_breaker(answer, sep="|"): def strip_local_version(version: str) -> str: return re.sub(r"\+.+", "", version) + + +def get_backup_file_path() -> str: + return os.path.join( + tempfile.gettempdir(), + "cz.commit%{user}%{project_root}.backup".format( + user=os.environ.get("USER", ""), + project_root=str(git.find_git_project_root()).replace("/", "%"), + ), + ) From e4b7e01fd181c06231f5975df303daff222fd5ec Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 19:16:54 +0100 Subject: [PATCH 085/598] refactor(git-hooks): make git hooks use get_backup_file_path --- hooks/post-commit.py | 13 ++++++++----- hooks/prepare-commit-msg.py | 18 ++++++++---------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/hooks/post-commit.py b/hooks/post-commit.py index c2faebb738..a0ad5a7749 100755 --- a/hooks/post-commit.py +++ b/hooks/post-commit.py @@ -1,13 +1,16 @@ #!/usr/bin/env python -import os -import tempfile from pathlib import Path +try: + from commitizen.cz.utils import get_backup_file_path +except ImportError as error: + print("could not import commitizen:") + print(error) + exit(1) + def post_commit(): - backup_file = Path( - tempfile.gettempdir(), f"cz.commit{os.environ.get('USER', '')}.backup" - ) + backup_file = Path(get_backup_file_path()) # remove backup file if it exists if backup_file.is_file(): diff --git a/hooks/prepare-commit-msg.py b/hooks/prepare-commit-msg.py index 58beb3a0f8..d1ccf169cf 100755 --- a/hooks/prepare-commit-msg.py +++ b/hooks/prepare-commit-msg.py @@ -1,19 +1,19 @@ #!/usr/bin/env python -import os import shutil import subprocess import sys -import tempfile from pathlib import Path from subprocess import CalledProcessError +try: + from commitizen.cz.utils import get_backup_file_path +except ImportError as error: + print("could not import commitizen:") + print(error) + exit(1) -def prepare_commit_msg(commit_msg_file: Path) -> int: - # check that commitizen is installed - if shutil.which("cz") is None: - print("commitizen is not installed!") - return 0 +def prepare_commit_msg(commit_msg_file: Path) -> int: # check if the commit message needs to be generated using commitizen if ( subprocess.run( @@ -27,9 +27,7 @@ def prepare_commit_msg(commit_msg_file: Path) -> int: ).returncode != 0 ): - backup_file = Path( - tempfile.gettempdir(), f"cz.commit{os.environ.get('USER', '')}.backup" - ) + backup_file = Path(get_backup_file_path()) if backup_file.is_file(): # confirm if commit message from backup file should be reused From 0c95c160d715f5cad5bfc709d8ee4b0780c73641 Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 19:27:59 +0100 Subject: [PATCH 086/598] refactor(commit): remove unused tempfile import --- commitizen/commands/commit.py | 1 - 1 file changed, 1 deletion(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index f2ccc6b1af..c9712a0fc7 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -1,6 +1,5 @@ import contextlib import os -import tempfile import questionary From e6b5e8bd882bdd0892877b9927bf1201af4f7113 Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 20:26:36 +0100 Subject: [PATCH 087/598] test(commit): add test for --no-retry flag --- tests/commands/test_commit_command.py | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 545defe0e4..f2f4f174c6 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -157,6 +157,54 @@ def test_commit_retry_after_failure_works(config, mocker: MockFixture): assert not os.path.isfile(temp_file) +@pytest.mark.usefixtures("staging_is_clean") +def test_commit_retry_after_failure_with_no_retry_works(config, mocker: MockFixture): + prompt_mock = mocker.patch("questionary.prompt") + prompt_mock.return_value = { + "prefix": "feat", + "subject": "user created", + "scope": "", + "is_breaking_change": False, + "body": "closes #21", + "footer": "", + } + + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("", "error", b"", b"", 9) + error_mock = mocker.patch("commitizen.out.error") + + with pytest.raises(CommitError): + commit_cmd = commands.Commit(config, {}) + temp_file = commit_cmd.temp_file + commit_cmd() + + prompt_mock.assert_called_once() + error_mock.assert_called_once() + assert os.path.isfile(temp_file) + + # provide different prompt to test that --no-retry ignore backup file + prompt_mock = mocker.patch("questionary.prompt") + prompt_mock.return_value = { + "prefix": "feat", + "subject": "user created", + "scope": "", + "is_breaking_change": False, + "body": "closes #22", + "footer": "", + } + + commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) + success_mock = mocker.patch("commitizen.out.success") + + config.settings["retry_after_failure"] = True + commands.Commit(config, {"no_retry": True})() + + commit_mock.assert_called_with("feat: user created\n\ncloses #22", args="") + prompt_mock.assert_called() + success_mock.assert_called_once() + assert not os.path.isfile(temp_file) + + @pytest.mark.usefixtures("staging_is_clean") def test_commit_command_with_dry_run_option(config, mocker: MockFixture): prompt_mock = mocker = mocker.patch("questionary.prompt") From d3f2b68fa012a4c9a9030f7da93c2f268803259e Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 20:50:01 +0100 Subject: [PATCH 088/598] docs: add retry_after_failure config and retry options for commit command --- docs/commit.md | 7 +++++++ docs/config.md | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/docs/commit.md b/docs/commit.md index 2215e0d805..54c792f743 100644 --- a/docs/commit.md +++ b/docs/commit.md @@ -29,3 +29,10 @@ For example, using the `-S` option on `git commit` to sign a commit is now commi !!! note Deprecation warning: A commit can be signed off using `cz commit --signoff` or the shortcut `cz commit -s`. This syntax is now deprecated in favor of the new `cz commit -- -s` syntax. + +### Retry + +You can use `cz commit --retry` to reuse the last commit message when the previous commit attempt failed. +To automatically retry when running `cz commit`, you can set the `retry_after_failure` +configuration option to `true`. Running `cz commit --no-retry` makes commitizen ignore `retry_after_failure`, forcing +a new commit message to be prompted. diff --git a/docs/config.md b/docs/config.md index 391c20f0fc..d6ab12abcd 100644 --- a/docs/config.md +++ b/docs/config.md @@ -82,6 +82,14 @@ Default: `None` Create custom commit message, useful to skip ci. [Read more][bump_message] +### `retry_after_failure` + +Type: `bool` + +Default: `false` + +Automatically retry failed commit when running `cz commit`. [Read more][retry_after_failure] + ### `allow_abort` Type: `bool` @@ -380,6 +388,7 @@ setup( [bump_message]: bump.md#bump_message [major-version-zero]: bump.md#-major-version-zero [prerelease-offset]: bump.md#-prerelease_offset +[retry_after_failure]: commit.md#retry [allow_abort]: check.md#allow-abort [version-scheme]: bump.md#version-scheme [pre_bump_hooks]: bump.md#pre_bump_hooks From e2644c9f67cf17c8124f12ab7ab2352d48dbd5ce Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 21:17:18 +0100 Subject: [PATCH 089/598] refactor(commit): use Optional[str] instead of str | None --- commitizen/commands/commit.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index c9712a0fc7..2489abaf29 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -1,6 +1,8 @@ import contextlib import os +from typing import Optional + import questionary from commitizen import factory, git, out @@ -33,7 +35,7 @@ def __init__(self, config: BaseConfig, arguments: dict): self.arguments = arguments self.temp_file: str = get_backup_file_path() - def read_backup_message(self) -> str | None: + def read_backup_message(self) -> Optional[str]: # Check the commit backup file exists if not os.path.isfile(self.temp_file): return None From 820ada2c005a53e64527b479a3181125c249bef9 Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 21:34:22 +0100 Subject: [PATCH 090/598] refactor(utils): convert git project root to posix path for backup file name --- commitizen/cz/utils.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/commitizen/cz/utils.py b/commitizen/cz/utils.py index 93c63a2213..d5bd63c6fc 100644 --- a/commitizen/cz/utils.py +++ b/commitizen/cz/utils.py @@ -21,10 +21,17 @@ def strip_local_version(version: str) -> str: def get_backup_file_path() -> str: + project_root = git.find_git_project_root() + + if project_root is None: + project = "" + else: + project = project_root.as_posix().replace("/", "%") + return os.path.join( tempfile.gettempdir(), - "cz.commit%{user}%{project_root}.backup".format( + "cz.commit%{user}%{project}.backup".format( user=os.environ.get("USER", ""), - project_root=str(git.find_git_project_root()).replace("/", "%"), + project=project, ), ) From 4f3931a49985d584b246fdf9df5a741581a160b3 Mon Sep 17 00:00:00 2001 From: crai0 Date: Fri, 15 Mar 2024 21:51:38 +0100 Subject: [PATCH 091/598] test(utils): add test for get_backup_file_path when git.find_project_root returns None --- tests/test_cz_utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_cz_utils.py b/tests/test_cz_utils.py index 94cc7f5b87..25c960c9a7 100644 --- a/tests/test_cz_utils.py +++ b/tests/test_cz_utils.py @@ -1,4 +1,5 @@ import pytest +from pytest_mock import MockFixture from commitizen.cz import exceptions, utils @@ -17,3 +18,9 @@ def test_multiple_line_breaker(): result = utils.multiple_line_breaker(message, "is") assert result == "th\n\nthe first line | and th\n\nthe second line" + + +def test_get_backup_file_path_no_project_root(mocker: MockFixture): + project_root_mock = mocker.patch("commitizen.git.find_git_project_root") + project_root_mock.return_value = None + assert utils.get_backup_file_path() From fc3c1e9975fbc4181a89932b01a8928886d74b31 Mon Sep 17 00:00:00 2001 From: crai0 Date: Sat, 16 Mar 2024 19:48:54 +0100 Subject: [PATCH 092/598] test(commit): create new test for backup file creation and use fixture for other retry test cases --- tests/commands/test_commit_command.py | 112 ++++++++++---------------- 1 file changed, 42 insertions(+), 70 deletions(-) diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index f2f4f174c6..1930b2eaee 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -6,6 +6,7 @@ from commitizen import cmd, commands from commitizen.cz.exceptions import CzException +from commitizen.cz.utils import get_backup_file_path from commitizen.exceptions import ( CommitError, CustomError, @@ -25,6 +26,12 @@ def staging_is_clean(mocker: MockFixture, tmp_git_project): return tmp_git_project +@pytest.fixture +def backup_file(tmp_git_project): + with open(get_backup_file_path(), "w") as backup_file: + backup_file.write("backup commit") + + @pytest.mark.usefixtures("staging_is_clean") def test_commit(config, mocker: MockFixture): prompt_mock = mocker.patch("questionary.prompt") @@ -46,18 +53,7 @@ def test_commit(config, mocker: MockFixture): @pytest.mark.usefixtures("staging_is_clean") -def test_commit_retry_fails_no_backup(config, mocker: MockFixture): - commit_mock = mocker.patch("commitizen.git.commit") - commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) - - with pytest.raises(NoCommitBackupError) as excinfo: - commands.Commit(config, {"retry": True})() - - assert NoCommitBackupError.message in str(excinfo.value) - - -@pytest.mark.usefixtures("staging_is_clean") -def test_commit_retry_works(config, mocker: MockFixture): +def test_commit_backup_on_failure(config, mocker: MockFixture): prompt_mock = mocker.patch("questionary.prompt") prompt_mock.return_value = { "prefix": "feat", @@ -81,15 +77,32 @@ def test_commit_retry_works(config, mocker: MockFixture): error_mock.assert_called_once() assert os.path.isfile(temp_file) - # Previous commit failed, so retry should pick up the backup commit - # commit_mock = mocker.patch("commitizen.git.commit") + +@pytest.mark.usefixtures("staging_is_clean") +def test_commit_retry_fails_no_backup(config, mocker: MockFixture): + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) + + with pytest.raises(NoCommitBackupError) as excinfo: + commands.Commit(config, {"retry": True})() + + assert NoCommitBackupError.message in str(excinfo.value) + + +@pytest.mark.usefixtures("staging_is_clean", "backup_file") +def test_commit_retry_works(config, mocker: MockFixture): + prompt_mock = mocker.patch("questionary.prompt") + + commit_mock = mocker.patch("commitizen.git.commit") commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) success_mock = mocker.patch("commitizen.out.success") - commands.Commit(config, {"retry": True})() + commit_cmd = commands.Commit(config, {"retry": True}) + temp_file = commit_cmd.temp_file + commit_cmd() - commit_mock.assert_called_with("feat: user created\n\ncloses #21", args="") - prompt_mock.assert_called_once() + commit_mock.assert_called_with("backup commit", args="") + prompt_mock.assert_not_called() success_mock.assert_called_once() assert not os.path.isfile(temp_file) @@ -118,46 +131,26 @@ def test_commit_retry_after_failure_no_backup(config, mocker: MockFixture): success_mock.assert_called_once() -@pytest.mark.usefixtures("staging_is_clean") +@pytest.mark.usefixtures("staging_is_clean", "backup_file") def test_commit_retry_after_failure_works(config, mocker: MockFixture): prompt_mock = mocker.patch("questionary.prompt") - prompt_mock.return_value = { - "prefix": "feat", - "subject": "user created", - "scope": "", - "is_breaking_change": False, - "body": "closes #21", - "footer": "", - } commit_mock = mocker.patch("commitizen.git.commit") - commit_mock.return_value = cmd.Command("", "error", b"", b"", 9) - error_mock = mocker.patch("commitizen.out.error") - - with pytest.raises(CommitError): - commit_cmd = commands.Commit(config, {}) - temp_file = commit_cmd.temp_file - commit_cmd() - - prompt_mock.assert_called_once() - error_mock.assert_called_once() - assert os.path.isfile(temp_file) - - # Previous commit failed, so retry should pick up the backup commit - # commit_mock = mocker.patch("commitizen.git.commit") commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) success_mock = mocker.patch("commitizen.out.success") config.settings["retry_after_failure"] = True - commands.Commit(config, {})() + commit_cmd = commands.Commit(config, {}) + temp_file = commit_cmd.temp_file + commit_cmd() - commit_mock.assert_called_with("feat: user created\n\ncloses #21", args="") - prompt_mock.assert_called_once() + commit_mock.assert_called_with("backup commit", args="") + prompt_mock.assert_not_called() success_mock.assert_called_once() assert not os.path.isfile(temp_file) -@pytest.mark.usefixtures("staging_is_clean") +@pytest.mark.usefixtures("staging_is_clean", "backup_file") def test_commit_retry_after_failure_with_no_retry_works(config, mocker: MockFixture): prompt_mock = mocker.patch("questionary.prompt") prompt_mock.return_value = { @@ -170,37 +163,16 @@ def test_commit_retry_after_failure_with_no_retry_works(config, mocker: MockFixt } commit_mock = mocker.patch("commitizen.git.commit") - commit_mock.return_value = cmd.Command("", "error", b"", b"", 9) - error_mock = mocker.patch("commitizen.out.error") - - with pytest.raises(CommitError): - commit_cmd = commands.Commit(config, {}) - temp_file = commit_cmd.temp_file - commit_cmd() - - prompt_mock.assert_called_once() - error_mock.assert_called_once() - assert os.path.isfile(temp_file) - - # provide different prompt to test that --no-retry ignore backup file - prompt_mock = mocker.patch("questionary.prompt") - prompt_mock.return_value = { - "prefix": "feat", - "subject": "user created", - "scope": "", - "is_breaking_change": False, - "body": "closes #22", - "footer": "", - } - commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) success_mock = mocker.patch("commitizen.out.success") config.settings["retry_after_failure"] = True - commands.Commit(config, {"no_retry": True})() + commit_cmd = commands.Commit(config, {"no_retry": True}) + temp_file = commit_cmd.temp_file + commit_cmd() - commit_mock.assert_called_with("feat: user created\n\ncloses #22", args="") - prompt_mock.assert_called() + commit_mock.assert_called_with("feat: user created\n\ncloses #21", args="") + prompt_mock.assert_called_once() success_mock.assert_called_once() assert not os.path.isfile(temp_file) From b42a676d1074f80bb8fab431d41f04a6b1e6317c Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sat, 30 Mar 2024 15:22:30 +0800 Subject: [PATCH 093/598] style: refine coding style based on reviews --- commitizen/commands/commit.py | 5 +++-- commitizen/cz/utils.py | 9 ++------- hooks/post-commit.py | 3 +-- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 2489abaf29..7591a28658 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -1,7 +1,8 @@ +from __future__ import annotations + import contextlib import os -from typing import Optional import questionary @@ -35,7 +36,7 @@ def __init__(self, config: BaseConfig, arguments: dict): self.arguments = arguments self.temp_file: str = get_backup_file_path() - def read_backup_message(self) -> Optional[str]: + def read_backup_message(self) -> str | None: # Check the commit backup file exists if not os.path.isfile(self.temp_file): return None diff --git a/commitizen/cz/utils.py b/commitizen/cz/utils.py index d5bd63c6fc..4df2edf39c 100644 --- a/commitizen/cz/utils.py +++ b/commitizen/cz/utils.py @@ -28,10 +28,5 @@ def get_backup_file_path() -> str: else: project = project_root.as_posix().replace("/", "%") - return os.path.join( - tempfile.gettempdir(), - "cz.commit%{user}%{project}.backup".format( - user=os.environ.get("USER", ""), - project=project, - ), - ) + user = os.environ.get("USER", "") + return os.path.join(tempfile.gettempdir(), f"cz.commit%{user}%{project}.backup") diff --git a/hooks/post-commit.py b/hooks/post-commit.py index a0ad5a7749..6444e5ca84 100755 --- a/hooks/post-commit.py +++ b/hooks/post-commit.py @@ -4,8 +4,7 @@ try: from commitizen.cz.utils import get_backup_file_path except ImportError as error: - print("could not import commitizen:") - print(error) + print(f"could not import commitizen:\n{error}") exit(1) From ffb6df72be3f93ebfecdd94b74c43ba429157f1a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 30 Mar 2024 07:58:00 +0000 Subject: [PATCH 094/598] =?UTF-8?q?bump:=20version=203.20.0=20=E2=86=92=20?= =?UTF-8?q?3.21.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 14 ++++++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fb3881cc7a..d66d4eb558 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.20.0 # automatically updated by Commitizen + rev: v3.21.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 38f588354c..83cb977b2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## v3.21.0 (2024-03-30) + +### Feat + +- **commit**: add retry_after_failure config option and --no-retry flag + +### Refactor + +- **utils**: convert git project root to posix path for backup file name +- **commit**: use Optional[str] instead of str | None +- **commit**: remove unused tempfile import +- **git-hooks**: make git hooks use get_backup_file_path +- **utils**: move backup path creation to utils + ## v3.20.0 (2024-03-19) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 10c5c0dd1b..f87b7d84cf 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.20.0" +__version__ = "3.21.0" diff --git a/pyproject.toml b/pyproject.toml index 82f415ff34..310c80eedc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.20.0" +version = "3.21.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.20.0" +version = "3.21.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 7c0e78093bdaa72e8f6be078a80ac315a2761049 Mon Sep 17 00:00:00 2001 From: ellie Date: Sat, 30 Mar 2024 15:33:01 +0800 Subject: [PATCH 095/598] fix(command-init): "cz init" should list exisitng tag in reverse order --- commitizen/commands/init.py | 4 +++- tests/commands/test_init_command.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 62b3aec971..9775ec7fc8 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -186,9 +186,11 @@ def _ask_tag(self) -> str: out.error("No Existing Tag. Set tag to v0.0.1") return "0.0.1" + # the latest tag is most likely with the largest number. Thus list the tags in reverse order makes more sense + sorted_tags = sorted(tags, reverse=True) latest_tag = questionary.select( "Please choose the latest tag: ", - choices=tags, + choices=sorted_tags, style=self.cz.style, ).unsafe_ask() diff --git a/tests/commands/test_init_command.py b/tests/commands/test_init_command.py index ba77a12e3c..1814acb135 100644 --- a/tests/commands/test_init_command.py +++ b/tests/commands/test_init_command.py @@ -93,7 +93,7 @@ def test_init_when_config_already_exists(config, capsys): def test_init_without_choosing_tag(config, mocker: MockFixture, tmpdir): mocker.patch( - "commitizen.commands.init.get_tag_names", return_value=["0.0.1", "0.0.2"] + "commitizen.commands.init.get_tag_names", return_value=["0.0.2", "0.0.1"] ) mocker.patch("commitizen.commands.init.get_latest_tag_name", return_value="0.0.2") mocker.patch( From 223532b2782519b968cfa534b6dff4b3a102ce3a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 30 Mar 2024 08:03:21 +0000 Subject: [PATCH 096/598] =?UTF-8?q?bump:=20version=203.21.0=20=E2=86=92=20?= =?UTF-8?q?3.21.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d66d4eb558..63c283e1c1 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.0 # automatically updated by Commitizen + rev: v3.21.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 83cb977b2c..ca27f0a2ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.21.1 (2024-03-30) + +### Fix + +- **command-init**: "cz init" should list exisitng tag in reverse order + ## v3.21.0 (2024-03-30) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index f87b7d84cf..ea92c23757 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.21.0" +__version__ = "3.21.1" diff --git a/pyproject.toml b/pyproject.toml index 310c80eedc..4697401b98 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.21.0" +version = "3.21.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.21.0" +version = "3.21.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 3519ae7d300fcb3095b9064272f025255adf4c2b Mon Sep 17 00:00:00 2001 From: TTW Date: Sat, 30 Mar 2024 15:50:22 +0800 Subject: [PATCH 097/598] fix(commitizen/git.py,-tests/test_git.py): Resolve tempfile path spaces issue in git commit function This test verifies parameter passing using markers to ensure that function arguments are correctly handled and propagated. #572 --- commitizen/git.py | 2 +- tests/test_git.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/commitizen/git.py b/commitizen/git.py index 900ca9298e..53e7335a3f 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -112,7 +112,7 @@ def commit( f.write(message.encode("utf-8")) f.close() - command = f"git commit {args} -F {f.name}" + command = f'git commit {args} -F "{f.name}"' if committer_date and os.name == "nt": # pragma: no cover # Using `cmd /v /c "{command}"` sets environment variables only for that command diff --git a/tests/test_git.py b/tests/test_git.py index 3b7a08f94a..60001d2e9b 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -293,3 +293,32 @@ def test_create_tag_with_message(tmp_commitizen_project): assert git.get_tag_message(tag_name) == ( tag_message if platform.system() != "Windows" else f"'{tag_message}'" ) + + +@pytest.mark.parametrize( + "file_path,expected_cmd", + [ + ( + "/tmp/temp file", + 'git commit --signoff -F "/tmp/temp file"', + ), # File contains spaces + ( + "/tmp dir/temp file", + 'git commit --signoff -F "/tmp dir/temp file"', + ), # Path contains spaces + ( + "/tmp/tempfile", + 'git commit --signoff -F "/tmp/tempfile"', + ), # Path does not contain spaces + ], +) +def test_commit_with_spaces_in_path(mocker, file_path, expected_cmd): + mock_run = mocker.patch("commitizen.cmd.run", return_value=FakeCommand()) + mock_unlink = mocker.patch("os.unlink") + mock_temp_file = mocker.patch("commitizen.git.NamedTemporaryFile") + mock_temp_file.return_value.name = file_path + + git.commit("feat: new feature", "--signoff") + + mock_run.assert_called_once_with(expected_cmd) + mock_unlink.assert_called_once_with(file_path) From 6148bf1d98d40d9ff344b5fc1095f721c646527c Mon Sep 17 00:00:00 2001 From: TTW Date: Sat, 30 Mar 2024 16:22:08 +0800 Subject: [PATCH 098/598] test(tests/test_git.py): use the IDs tool to clearly describe each test item --- tests/test_git.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/test_git.py b/tests/test_git.py index 60001d2e9b..8af332d214 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -301,15 +301,20 @@ def test_create_tag_with_message(tmp_commitizen_project): ( "/tmp/temp file", 'git commit --signoff -F "/tmp/temp file"', - ), # File contains spaces + ), ( "/tmp dir/temp file", 'git commit --signoff -F "/tmp dir/temp file"', - ), # Path contains spaces + ), ( "/tmp/tempfile", 'git commit --signoff -F "/tmp/tempfile"', - ), # Path does not contain spaces + ), + ], + ids=[ + "File contains spaces", + "Path contains spaces", + "Path does not contain spaces", ], ) def test_commit_with_spaces_in_path(mocker, file_path, expected_cmd): From 8d5f6303e7501317ea3e4a3569fa7111411a5ad5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 30 Mar 2024 08:31:53 +0000 Subject: [PATCH 099/598] =?UTF-8?q?bump:=20version=203.21.1=20=E2=86=92=20?= =?UTF-8?q?3.21.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 63c283e1c1..a07b16ca20 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.1 # automatically updated by Commitizen + rev: v3.21.2 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index ca27f0a2ee..82e455c569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.21.2 (2024-03-30) + +### Fix + +- **commitizen/git.py,-tests/test_git.py**: Resolve tempfile path spaces issue in git commit function + ## v3.21.1 (2024-03-30) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index ea92c23757..6a2d1c0215 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.21.1" +__version__ = "3.21.2" diff --git a/pyproject.toml b/pyproject.toml index 4697401b98..d250e274af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.21.1" +version = "3.21.2" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.21.1" +version = "3.21.2" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 7b49f8ad524d48f8c9cf7ca815faa3dc692b577d Mon Sep 17 00:00:00 2001 From: itinghung Date: Sat, 30 Mar 2024 16:10:15 +0800 Subject: [PATCH 100/598] refactor(defaults): move cz_conventional_commit defaults out of defaults.py --- .../cz/conventional_commits/conventional_commits.py | 2 +- commitizen/defaults.py | 2 -- tests/test_changelog.py | 10 +++++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index f927a94fdd..5f693963e7 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -31,7 +31,7 @@ class ConventionalCommitsCz(BaseCommitizen): bump_pattern = defaults.bump_pattern bump_map = defaults.bump_map bump_map_major_version_zero = defaults.bump_map_major_version_zero - commit_parser = defaults.commit_parser + commit_parser = r"^((?Pfeat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P[^()\r\n]*)\)|\()?(?P!)?|\w+!):\s(?P.*)?" # noqa change_type_map = { "feat": "Feat", "fix": "Fix", diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 071efd10b9..a1651ebe88 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -133,5 +133,3 @@ class Settings(TypedDict, total=False): ) change_type_order = ["BREAKING CHANGE", "Feat", "Fix", "Refactor", "Perf"] bump_message = "bump: version $current_version → $new_version" - -commit_parser = r"^((?Pfeat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P[^()\r\n]*)\)|\()?(?P!)?|\w+!):\s(?P.*)?" # noqa diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 9ccc207936..d382a67f30 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -6,7 +6,7 @@ import pytest from jinja2 import FileSystemLoader -from commitizen import changelog, defaults, git +from commitizen import changelog, git from commitizen.cz.conventional_commits.conventional_commits import ( ConventionalCommitsCz, ) @@ -1079,8 +1079,8 @@ def test_invalid_tag_included_in_changelog(): @pytest.mark.parametrize("merge_prereleases", (True, False)) def test_generate_tree_from_commits(gitcommits, tags, merge_prereleases): - parser = defaults.commit_parser - changelog_pattern = defaults.bump_pattern + parser = ConventionalCommitsCz.commit_parser + changelog_pattern = ConventionalCommitsCz.bump_pattern tree = changelog.generate_tree_from_commits( gitcommits, tags, parser, changelog_pattern, merge_prerelease=merge_prereleases ) @@ -1106,8 +1106,8 @@ def test_generate_tree_from_commits(gitcommits, tags, merge_prereleases): def test_generate_tree_from_commits_with_no_commits(tags): gitcommits = [] - parser = defaults.commit_parser - changelog_pattern = defaults.bump_pattern + parser = ConventionalCommitsCz.commit_parser + changelog_pattern = ConventionalCommitsCz.bump_pattern tree = changelog.generate_tree_from_commits( gitcommits, tags, parser, changelog_pattern ) From 669080c8c180a1f81bc3f0666b0d49fb71ab6dde Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 30 Mar 2024 09:15:00 +0000 Subject: [PATCH 101/598] =?UTF-8?q?bump:=20version=203.21.2=20=E2=86=92=20?= =?UTF-8?q?3.21.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a07b16ca20..5c9623149e 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.2 # automatically updated by Commitizen + rev: v3.21.3 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e455c569..a3daec51cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.21.3 (2024-03-30) + +### Refactor + +- **defaults**: move cz_conventional_commit defaults out of defaults.py + ## v3.21.2 (2024-03-30) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 6a2d1c0215..322a27ea54 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.21.2" +__version__ = "3.21.3" diff --git a/pyproject.toml b/pyproject.toml index d250e274af..d1e03c436e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.21.2" +version = "3.21.3" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.21.2" +version = "3.21.3" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From b4060a5d78ca85399202ebee9fa02aaeb2474662 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 01:41:56 +0000 Subject: [PATCH 102/598] build(deps-dev): bump mkdocs-material from 9.5.15 to 9.5.16 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.15 to 9.5.16. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.15...9.5.16) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2d49e41b5a..21dfdb2d79 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" @@ -744,13 +744,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.16" 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.16-py3-none-any.whl", hash = "sha256:32fce3cd8ecbd5dca6e5887cc0cf5bc78707a36f7d0f6f1bbbe9edaf428b8055"}, + {file = "mkdocs_material-9.5.16.tar.gz", hash = "sha256:8b89b639592660f24657bb058de4aff0060cd0383148f8f51711201730f17503"}, ] [package.dependencies] From 90e2fd84b918153facf7a41d6ff40e2c75839c53 Mon Sep 17 00:00:00 2001 From: rockleona <34214497+rockleona@users.noreply.github.com> Date: Mon, 1 Apr 2024 23:26:37 +0800 Subject: [PATCH 103/598] docs(CHANGELOG): fix typo in the file --- CHANGELOG.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3daec51cd..a27d8610ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,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 +484,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 +721,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 +771,7 @@ ### Fix -- **commit**: correct the stage checker before commiting +- **commit**: correct the stage checker before committing ## v2.18.0 (2021-08-13) @@ -846,7 +846,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 +1079,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 +1226,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 +1369,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 +1459,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 +1515,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 +1524,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 +1636,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 +1695,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 +1717,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) From 17ffe48f9660d935fc1e82a8ce47649f660c5567 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 01:17:51 +0000 Subject: [PATCH 104/598] build(deps-dev): bump ruff from 0.3.4 to 0.3.5 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.4 to 0.3.5. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.3.4...v0.3.5) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 21dfdb2d79..ff37d5da32 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[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]] From 947a715cd090d304a282516e8cccdc8d625bedbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Apr 2024 01:30:34 +0000 Subject: [PATCH 105/598] build(deps-dev): bump mkdocs-material from 9.5.16 to 9.5.17 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.16 to 9.5.17. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.16...9.5.17) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index ff37d5da32..ca440f619f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -744,13 +744,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.16" +version = "9.5.17" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.16-py3-none-any.whl", hash = "sha256:32fce3cd8ecbd5dca6e5887cc0cf5bc78707a36f7d0f6f1bbbe9edaf428b8055"}, - {file = "mkdocs_material-9.5.16.tar.gz", hash = "sha256:8b89b639592660f24657bb058de4aff0060cd0383148f8f51711201730f17503"}, + {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] From daef1d3e639f77a5fa23dbf806be7cd1b9ff8064 Mon Sep 17 00:00:00 2001 From: ellie Date: Thu, 4 Apr 2024 14:25:01 +0800 Subject: [PATCH 106/598] build(pyproject.toml): add `rich` in dev.dependencies --- poetry.lock | 56 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index ca440f619f..5b28bf5776 100644 --- a/poetry.lock +++ b/poetry.lock @@ -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" @@ -1405,6 +1440,25 @@ 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.5" @@ -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..3410a50aba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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] From 3593dfc78661603bd49533c9677ffc101cd83edd Mon Sep 17 00:00:00 2001 From: ellie Date: Fri, 5 Apr 2024 13:19:52 +0800 Subject: [PATCH 107/598] ci(scripts): a script to gen cli help screenshots --- scripts/gen_cli_help_screenshots.py | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 scripts/gen_cli_help_screenshots.py 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() From 9d6c0877a20e3aff7d24f653d9224cb2c9e26bdf Mon Sep 17 00:00:00 2001 From: ellie Date: Fri, 5 Apr 2024 13:20:44 +0800 Subject: [PATCH 108/598] docs(docs/images): add cli help screenshots (not used yet) --- docs/images/cli_help/cz___help.svg | 198 ++++++++++ docs/images/cli_help/cz_bump___help.svg | 373 +++++++++++++++++++ docs/images/cli_help/cz_changelog___help.svg | 217 +++++++++++ docs/images/cli_help/cz_check___help.svg | 149 ++++++++ docs/images/cli_help/cz_commit___help.svg | 123 ++++++ docs/images/cli_help/cz_example___help.svg | 79 ++++ docs/images/cli_help/cz_info___help.svg | 79 ++++ docs/images/cli_help/cz_init___help.svg | 79 ++++ docs/images/cli_help/cz_ls___help.svg | 79 ++++ docs/images/cli_help/cz_schema___help.svg | 79 ++++ docs/images/cli_help/cz_version___help.svg | 99 +++++ 11 files changed, 1554 insertions(+) create mode 100644 docs/images/cli_help/cz___help.svg create mode 100644 docs/images/cli_help/cz_bump___help.svg create mode 100644 docs/images/cli_help/cz_changelog___help.svg create mode 100644 docs/images/cli_help/cz_check___help.svg create mode 100644 docs/images/cli_help/cz_commit___help.svg create mode 100644 docs/images/cli_help/cz_example___help.svg create mode 100644 docs/images/cli_help/cz_info___help.svg create mode 100644 docs/images/cli_help/cz_init___help.svg create mode 100644 docs/images/cli_help/cz_ls___help.svg create mode 100644 docs/images/cli_help/cz_schema___help.svg create mode 100644 docs/images/cli_help/cz_version___help.svg 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 + + + + + From b93e9b4b9229f652272a041808118c56b0b55d1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 01:29:54 +0000 Subject: [PATCH 109/598] build(deps): bump typing-extensions from 4.10.0 to 4.11.0 Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.10.0 to 4.11.0. - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.10.0...4.11.0) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5b28bf5776..4cc8f16674 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1628,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]] From 57e8e685bb660db17d6a5d03d2b752d2fbb7a31c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:22:38 +0200 Subject: [PATCH 110/598] ci(deps): bump peaceiris/actions-gh-pages from 2 to 4 (#1057) --- .github/workflows/docspublish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index 6aa1a75e2e..670864757b 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -31,7 +31,7 @@ jobs: token: ${{ secrets.PERSONAL_ACCESS_TOKEN_FOR_ORG }} file: 'docs/README.md' - name: Push doc to Github Page - uses: peaceiris/actions-gh-pages@v2 + uses: peaceiris/actions-gh-pages@v4 env: PERSONAL_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} PUBLISH_BRANCH: gh-pages From c0e41ca9397fa952cca2464213d8fdfb026be591 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Wed, 10 Apr 2024 02:03:42 +0800 Subject: [PATCH 111/598] ci(github-actions): update env var used in doc publish actions (#1058) it has been changed since peaceiris/actions-gh-pages@3 --- .github/workflows/docspublish.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index 670864757b..1001be8d9b 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -33,6 +33,8 @@ jobs: - name: Push doc to Github Page uses: peaceiris/actions-gh-pages@v4 env: - PERSONAL_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} - PUBLISH_BRANCH: gh-pages - PUBLISH_DIR: ./site + 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" From fb5f05f3751292ff92817a63001bbc2652319e82 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sun, 7 Apr 2024 11:54:32 +0800 Subject: [PATCH 112/598] docs(images): update outdated gifs --- docs/images/bump.gif | Bin 646444 -> 95853 bytes docs/images/demo.gif | Bin 699893 -> 132841 bytes docs/images/init.gif | Bin 0 -> 133852 bytes docs/init.md | 3 +++ 4 files changed, 3 insertions(+) create mode 100644 docs/images/init.gif diff --git a/docs/images/bump.gif b/docs/images/bump.gif index f9c9e0c8a3b49280623136dd37adbf310b6bd813..0e97550ade305b62d716f6ebfce5f8e3d1a297bf 100644 GIT binary patch literal 95853 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 literal 646444 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%0DmkKeM&96@aE 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

#0lflQOR< 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 _uC<*qYGAB7IC5381IP>G0;l0xywqpf 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�BY|MF>TD3B3sjiKS0cD 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

lJh=qXnNFqR04-(qt0pJvOAeEI~q+S2b~m zg^?IRwKdYQ#_{qTE)<)pluA?fjaT!fa`skbP2y4aK`;Gj=!G%)i(?A-c=8vdFqW1_ zjz_hoDY&OSJyNQ&Xt;rBc0Pun8Ot5f*dZ?a}#qSca)@)C?}JBLRAOt2i}{ofm6UXK;kLEDfB!E&Dm7} zAXbb_FL%1%NNJi1M9>W)iihCKGjH^ya!x5V99R(_&o2WOE~H_7GgX!| zNh~y;0dRa!i4o!=A=xhTpD4hZ>E_^| z%YSiDv{>bQ6vk4%Z zyKyv)JzytP-#_Z#qrt4msjSbv#1L85WI@{4X+_OJ}3AOLhb%7EDLnAdis8V zVN`XRMV}hSkWx>gb9RO`t|f?<^O{hzj?_;~Qx55l?&~%?wBYU0`^FiQ9_)rf6j znnFfd6B1=PC@8()gfH!>KWLv#MheLNOF7>Pe*eBwC598qMre{lX8tTp;~~b&W3!y{ zaxVuYS^@fd{{n|Ls%|g~*!VK2gES>LIGZp5;=43DWbH;;{pPreql1Etaw$dE@7h?fcGDP(6X>*(#RqI#~h5V5qSERvnhby*4)x_A-4Q zfg?k7{6T_QV>51GSsM0qB3+(rLC1Q}o<68_iQevG_rS}wD^INZ?kh<`ju<74H#$v9 z1$-wDilaQgYk~N@$&Zss8>F}M26k# zCrfqz%AmmhFBGqbk~8}ZGI$HYx`i`ol5ehR`dk}DVZ8DW{m$IDn>p|DLhSe>l9w;N z@WrryV&jK5DYKlX41}IACH*QtdfM@LH9J*Sg#(0wPtZ6(C`iCZ80?F|7;_o`jxXOu zdekqi%0J8VFbt z$i~W8@be|Q@PyeNar&a-TLs;_@9=b669|oNqvJ$(3!sm!lrDE>XZ)gP;Zt*rQ**tL zZ!e}679xj7kfjT$tEc(f*qUi(U1<&PO01%p*0kA;n&jD34^ znegV*w|8UO@8I7TleOQ#P2Ss{S$q6#%=P=H46VC{X8I&Ey}@|Sdcn#w&55_h-n+dm zCd0KocXaE|tSX(I1uwlmB=NTD%!<~J?eh}A>ucwK>`Iw@+wQ&3MxD?7F%eTb zUnChW{ve_5djMCWI<@)+1iRD<{wssZbjX4d71dd~)|9<5%BP{T`^A@II?^78p`_n` z-Jv<}`GS5wl4chLYS_oC7skuhDJUJFsQXbw3TVN7FD=O+;S1sTpU|yomdq{P=%+ou zzq1(hgCo7{mE57qdXSuK8%l$fpg=%zh(ytQa$*dyaT^5SFro7ad|44{mTMN|v$A#@ z_?N5&J?;2sY4Gm@)xYG^qEaQRP#Sd*5>H~}Py`&4Xju=r3eY%8sQL4AFC8~XGX)=o z1v`_zML^7-nVzdD|B(QKnXa7E?2b>UgRF^eT6KSS^4vV&*=``RZ1|JX#JIIJr+oQf z+7*;aQ{AS5f2OE(q|4{X{mPq1W;71|j0&NhwaABF|LULTc(lNDsJd>`GBou&I7^+( zatWfk-h1nFLiOZ7TVW}}z^Bh=n^D%U8d`Q6K8dQgHJ~(t;3*U9OE}F03u3H&D8c~y_F*%txWm;W)4xv$3YFQ3>y+-}m3lW=G zhtF(*~r`OF{T-Kuvcaz9M??4lTyoeb4t7%8TLd+FBa!aLxI zc4Gomp3xNDJ^%7++x%`5KDJ3^ul^tH%A2>oe@8WbF6JF3G*S2LuOLnd=PX7(;afT!k)`t=m8!F`@&p!} z=UupKLo{~^3zJ1beU9UqQ9f^Nv_4;&!jfFTNxj#R`U`}HOD*?S7kC4@5trs)O1ZC> z>GDW7;@j@OeLo z2Oc!6JcI)IDMNH+U1RTQ6FA)rL z8cgKEsA;J9@8_YpcqxFNvgB;z(R!hziAUw*nR0eH8X@Znleuc1ZDC*56{ibzgB~}T zMDW)gVuby16#gdO9l5iL(+tfG9*BHBVB@qsCERqVT&ZT{y)qIGSJ=k;vZ)^@08DJ~ zJbsFalEJ8MM>5hp)SuJDlSxYxFef<8Tb_S#h*&-^#<4cO3|qQ4iM;~?HR*?$J|6rS4p{={G)ffqtkJX=$;5A*cdu|x?q~-LU;rG{l7dF0^^51eT z+ebrLguXuhxW?tCZRycY)F~P*Kbngty6GAqj^`9$`(d~>X1QH0@B8gX(;OH9ci(@; z{I(27dIyo^+7JLOnQo7`xPZKgB-sevIFeleT#n4o4#OLGVg2RfD5KnHh1R2|76b_9X<62soYoQWoD(F=!B2CLi|brR(Yfk+eoS{-AbjQOjRn9#A50kRZ!i2;ab96A0qTjgQ~LSD2Lww z@3Ob#FIe$k`~c*4IUMAT%_59QOCch;git;gaol=6&u;?0x>%WfsIYy~4Y!P!*m9mV zhpZY0=j=TA6%CUd9EtQvD6Y7-daJNEs? zJ=fydW4};W*Y3hjf5JmCA8)wvI~B(13SF+|Rvs6-@N|9j)ug%J1A|w`PInKt;c z>`bzjaW~(?34l-J_ADe~mZG1bDFe|TJX7}deKu+wFkNZxe|zv@di;t?wJyYGPAc{{ z(WZ#ndWnnI&*DwU)5X#8SfUbaXvE%I(~LdK?EqW16C!N}Z3DLcU}+&O%iR8KEw?p0 z8HXmP*4ubow%J~+pi0*IG^XS7-goIcaYT*u69WzMA+s!-WzIjS7u;7i8gKqt2m-Fi zW>Ig)%E07R25*dh_cj+OhzJYP!aO(?FZEjnVXZQRYiWr$`*7sjq=D+Y$gD)II9aqm zNBxXYS5|#|q-rS7%7LrdNV8fNo1iix%dZo!G%foru69sJxHZ)^PEN4Ocv$}7LmRU@ zrGo8sqnZ(|SD#nD=epfP)Xr&5KWQ#6<`1zIR6CGl;VdulL1o+|Km3|$m^|i7-MGbi zYv!Sj#Y&BdF?8Rf%w%%~Ie`#8GbMI*)m$xG zZ(+BLx#ae(Yc9r#RuF|IjFNPH?!&_R1x;$W=}K9km`~G^yl+kNDWT+&M?50{PmJYG z{S0P1fXcH=h;P!lURAOgY+$W+P&Q-T*e^iN!JW#qkf?=vf{N#-E5T|YKZIHqEnchg zAWZ7ynW%p6x4IE9OFWIur6n_T9U%GcrAxyMEs)lg-(FIdopc)sc}4F9D$>~^^ce6v~h z{AlBGGeQwPB+yU9B$JFfjE_^SExO#BK~7)rq#gUhC~;^C^eJJ}iF^=ewL=3w3 zzWy~bs_^;9iRgqhSvvo#>~Mnm$|1Bu`kp`jq74r!2-GBdq#nap{cPB@HK$ zq`LaE+PceDJoj&%ANIZ~9wBS`h>38xwDx?+&~Q}d=p$>N*=pWD?i%F0u$y|N_Fc~m zXyqBvcKBt#;#9y!Gm-W99zW3?d z;>8DH3nZi*u#Ka<<8FFKNo{5&wU5kqHeWl>6(MDycjvuuchB&(uwsn+;&CO6z8?vc3fueHItA@O3c#N^?*mUHP(e+PYfV=|ktZ=*~b_tDDI z^l_@orj^p&FRt3XiGd=v*DUXTJ$!-n`1-Y+exZj6*}_ks-_|<6FX+!FrR+f=g_vgl zlM1U`zU+Sch0D0^b4yl9#O|TZ$2GKhN!pF#uif6|w69jG-Ts#5xGDBI%;a6!$V_b~ zvD;bW{t7;SInmlI1`YNM^M}KUTD?nAN<0o1LTLzaI8kfNz|<9j`FsEU)}!1p@j3eu zAB#5MZ+vIV_deg0UV^j=`uk$^?CH|);~;%DcedgZ?ygq-WA#$JRQ|?{BULG{a^8@BQJ@R;u4GK;Gxdbo{b`#_3 z;SrLImICwMU>@$=Uz{!D@4cX^YW zvvc$#*G+)R9N0W6O=a@`2A{x@)^V^v1=5O+ds_(^#a9VyE_a+yI|+K)2pqP;Ci}`H z`)wu#evl=E4Iaee`a6}3<0$&|O@<~CEa=nG9ql}!8#00S9 z-iP<3&W&GU&d0hH+zR2o5X~L!ED|>|sxOCt=H@M}J&O&OKj%>p8Rc(se$+sXWIo{U z$@rjogY@nXSYS47!2CX3CROU$xQ@~XDGl23Qs#cU+aJCk6?eo@3~#G6LR~AcFI(D|PwFeAA`&0Iq65ar zhaUy2A_@5cSSeqf57tsOVK${Qe{vpZN;%m3+ide*4P5G5#1o?x*08A_2LsIZdHlHh zCM9q(_jI7fSCJzx$6Vu@_#X%Mf$Pi?TH*(h3gl z9+Wo-{B{lI-X&jfAkeD1h)E9262$l?bM1Ono2eeLH7^24FLG^^$nKx&D4%X9p0p|{ zVkQ*@_$fhyKgG`;c{8|p95RGk7D8b?i2Nh#n#2uUpfy|Z?4&cPY{a?;cs+Z<^Nbj8 zg+&?#T z-tf~udVV)we6r@$$r-7*RA7R9njiMHUTWn_?SbvuEBupZ%Ov*}5DvBbZ(qao)o^bE zm;sMWgmKW?$cX`$&+*aT?Y<+OHpOLvhx<)b?q2flVMi_ZOD^};i1*KV(+!vV1B1H` z)Iu)FuoOpdFsl(R;Y*M}WrM-)R?rFIk5||#4`C+_J?8I&>$9a)$;Y20y7*+v)nDHi zlBin$l$YQ4uypQm)%?r$)RU?O=f9i@t1n2dFMI|o%&0Fa`{J0ZdZR_P_;TWnF4dB; zFTkDpl4oCTJpN+Cpoy=Bh_6zQ_9dcvz?gZ}3bk0Zs)bwQ<0zG*{~*dH0xa z1g!UAX!%=aPa7Djpl161)X?|(;oYxyU#<+eYGkFZ0B8;IFtu*cQ$r060HLWopE{8i zmQ>y_$WcH2O0y0Y9y{>H0jmzL4jq&V8|Q}&*RI%b3VfC}U_rv@BPh3GJC@|ZWbo1PwiGNTkGJ`duXZfJN3v}v7cSNb;o=~QRmAnzR}FM~Lc zTv+9*`6|tQu1l@?J2kwO{k3eJ*%+e%B{VHhH&lIRBG4m<>d;qw-}OB-7o}RJMYY~* zonf?STtBS(!M5dzYRl4LtrsR*d61^OqgtQ+BtGfZd^+E<%=hLq`_!XrEj*Vv;+)*q zF20WslM$Q1t;cX|B>2)N+uYF_Cn`t~7%ZnU1(sVxzECA7-YfZTUqS_zF57b}G`ONh z_$G)FvoLP-pa4MQ59Sle9bEec{|k{m9pm7W0%#OJ2O?!2^V!lej2OYqigew%Z6CmV zF$or5X0}LauWvV!)y^(op5UIKNibRfCI^RQI;R8wQAnZkU})IcpI?*F!H^3Tq`wO3 zG51t9havr?<@lE&<={O+zlUJlgh8LjiN7OAa0U%D&glPoHs|eZZv6Kz5C*7#;t~v! zRfrdm85BSdA%>|iODt}fv#dfuUMKNPkx;i;&gMF{3si|aVDt|r-?SF5vf@8{AybB` zjua5zCV*jq_&{#RRRE))CLYP;Q)xgl*6!y#;S(T9D2LVwkBD`LSAMEMEK{Z1iC1QC zi+*PI34-O(@z6{LKZhf=XCOdCtTP2Z4PXNzlBNNXX%MF;iyH>U;?c;bXRwi_R>$7G zt??SF2DyYBaYTdVu^f&R#NkMBz#xiB70?Is17MiE>yP6jTlq{j(s)qw+~FVRLFi-J zf}~_Pn)pMGX0g>`U`9J_2o^M^-G~CTpc_0(Tml;`8#f(PBP*=%ob@JEViU9`c2?wx z^V}Jx*a!pkN}VIiT1*XcKiv?UC8B?TPznv8ejUg#g(yPW_v2jBJRq^!j*JE@##!QZ zAbA0Zyu{#+)Zni(XF1@keE|_`KDV75DOw0%3-v{_!1kG&=tBLUelRI#sLKa1aavzW zAL_E-+Pjj(jUSTBy^rH?r0E2OOx7=@p?4?_j%_7)EK$}tN-mus4^X(%3AjTBsA%A@ zcqa-m;(o|L7CnMXG?14WdZ-JaNCqBy@%nb`L4+O6;1utrUM4P)iId=Xq*VSUXO2h8 zuL2ezfCs9nI29Vd1o3DPfNBTe=3UQ0=lRjZ;V_WzRVEf;h)x8VT;D<(!PbVr=;3qb zdnecVzpR%f@=ky`^kUnj7L-W^O??mD*dX;2d0$gE$C&$g2om#lJlNZhgjr#)fYXiN ztxufdHSa(&HpE|3d6^7x&TyAwk)orH>sdKmjdUy^!mIT~qu1@O6EARsovucT&Yy9* z1&X!~t?dB`I48JZMx6IU6`oRYRBh86i2?)&0%NcvY=GS}!X+@^q^P6nFmLI2eyolh zmFY3QbyN?60>JWkD;%4%HYN@^#h|8Ow!HjvQqa}q-h5`5#(RtpEzdfHq*$H^=QNihJ3wcrz~~NuC$1A% z-liyrnH3Zkx9f=?qXOm~Jj)xCRFK33QI5PRQ~e9KdBLIB7EbLzQX}bIk)m0H@MxNS z6%cc!Lxir2rRqb}V7Q5&F8iS>f^Dw-E>`JOjw(5ZCI*#I;YQPL;t+0fhrk``A!saH zZdDCEz25BAZtx?_UD}FCWx5Xoi5RQnq$nQqSP4@~{CHQZ9_W}rynxE!4o4qdHC>4T z@qoMs`tpJhIZ~TF24;V+;{s;H?#iZptSOQjBT{1IeCV}bgXyLH z35(x`^k26y8C!Ay?XN$Ijt8*egcC;cWIfxPAckcWO%LGL19+HhWBJu+ckPK+cE1WZ z0I6WCoH-9}&$~4x`at_19xr2r$cV97xQ{aU6rLEPV8X3He0yZuHyYqq0HY}sL6H%h zjNvCeVvN`JB;ECDDbsft*fWf?W&wcH9g$azd%I`(_BuLHl)nZkg0+(fnwX+ZO@Z&f z3n!MF|DN5~jHDnDgo$A0l+%x%Nt!Hv2+Q$DRfz5!e^jCs_-$@4Ffv;J#uBKvu7Do@ z6G!Vj`(&mYnBI)Hx0u5u%E=Gn1h<~0-0cz>YDXKu{PhvJ7EnZNtMt%`NNUPImH-1W z$i!9&qwxX22*Q@zHXV>5Arf$Mspv{VLZ{EM?y?I=?^IPLp6MCDc2X!{;Cs==W$1FMTwOx2xbB5hGbZABhm z?C_7gLKt2SuNA$jyHT&7fg49!1?;tLz)?3h1MDP^@hij z>aEiUr!;$4A5Rr*e_grFgsVHZ>V5N_)|pVKn%3=&nI{@Ayq_m`N;yur7(I3G=jAgw zgID8j$7fwLOw{eso0*N2&$z}PO@5kacyeVSp7H*#Pm16LqY_IJ_$s~*tZ;l%YL?dA z_W_>${i4+gXA(pw7~j>m=C4m!{KDpB?&~y{aZiQ$iZPhbRCXX}5Ptfunibqj1)(T> zNSBbtM*u1-Y5M|3*VQ=QEo)(8fqwFKOg0TK+M}whWa<_V zPqZSSZt-fpSLI60bwDRx32{JNz|kN1jLj>m1yg+N6M>9TOe^PfWzV($3GMA^7pdbF@Tr9zc21Bg$; zd8x!VrYQ2u-p4DQzyG#9?6_u!q$A&n-)r}^-^KO1N*xN+^R`_LGz`3~rzIR649%#y zNInRaTA)^O3#ud~lYSp_9l#BVZtEARe+MAsYrnt@d~WT56L_YA7xvYK?r z7X(fQo`^c_pfmX94oI@6HT29&UnZQIC8-lf5o$R9NtkfK5b-j;%Zb(a`N6tn3NMi6O7F>0d<~XNN zg#YP}IP--+B$75H$Jct(TH;~xw|~{o8M5xVOEqEd_WTSVT;O=5VZefT%!2;K7&Piw zBE(E~1feiwgA6ezu?1nKZmIvOpDI4f4wFG;5iUE&KH3n)4rXWMR&&%(WxcP{LGKUc zt($#u@)bK&^f0$p+eLNH`TpZy2ij{bwm2oPV(t}M*R@qnDY^a-b;;~=*ODd>6;i}J z>Rt01JW7{czP->b{d!$%q~ojSpxEKojJyD^H_L}D#R|}`%k{!$X_N^u&)$c5Em2Xa zM?4#z=C4216lI83MUp)S`SKY_TdK#;H9Rk!HqwhlVafbxmux8-%N2EI$3uRb4n zo04OVxs!I}QAU18jpoghoef?sLy8)dWoMl^s{}PpS=OPfRH5xG?>C3jwMZ=MtKa9i z+v8-AG!RLEjkpiuTcyF3$V1ZGO!X(O1$}e8s-ce(57+j6gpTZ7JDRbOQrtsD)XNSc zXN%(jSfzgijwW3_MO7kH7$3hqEJ0o4`UkU>-HOK`A~fn1=H-RPgY3sa+XC4fHRj zLD$-~`vv4tjUKJ+-M2?_SShQ$0f=drDP&~vD|H#zeTU<^9ow@H6v%_go~&VM2HHpd z&ipwgymH2%#7UhC4&z#fP9OcqpWmAMQC)$ZhTdj;?4W?|M!9O0uEfPJ=`NsL@RQQU z>|ZI0bn0y4@ui4=3{Ki;-*^OE`1Gyoqo3%W#*vp-vyf9eax$C=PkCq!-|t0)7fS-S>-JD? z!1z(i`R(>2yr+U)V>-`%k*Z>HFIi~N;Q9os&^oM-Xu3B%c5Di_O9)Mk1o6sOuF%dM^pg*6WzxgQkM%DWSwex+nd(WrOA%JsDV&61Cr7kcv!4*UqcSMtfAd*`U17W+Zo zyOPfq_bxsxFpap0DP30JjtRP27Fl!Q_ww)KyH6^BcB}N;>6tJ^jp=q&EA5gqqCp+ zu#$}8Y>-!?N3{n^Q-gkgkUilvZdbORXW9HV^Tyn2+UxbwpLc#K{d4hA=02wi_xc}}{V4AI^Das{?sf6;U!!&wYu9f6o{>MX z^Wc{GMyd3lQR@@Cb0X$j%{MRg`=8i*bJpzVU1@e}!inD>-_75JL0g29j`gI#DOL&Q8 zY{3bfUC)nF9H|4lqU84Yawf=#0IO+%p4$JJx*v9cGN()6ke?lg8C<^D_TvP2$SmU| z10Fuxa)!WtkDGkXCL^h!=gMchz)aEmg71-J`0;)c%x|V@zWmUEi zczWF`yBIu!gm(McpUzm=Fbf^>mFE$K_nHIm3l=Z&KJOxh&&YxA3yW`joNtYSv9rZ+ zQlJ)N7;reYn}kKKVSUe_xmZwKEAGvGtfUTq;C|{(}*Wr%}7ZGn2xwM9*>EOA; zIpini+8X{RK{RiTuc%e@GfT8$jkhLT>^VcMc@5pFBR)tG@6G19yC&XBkQmKI-EWns zU`ag6M$UyxW-}z;WFr=Jq-YeWFWKDR)}+D-(p%Z^omOdImNYnriz`Cr07HgX7lzZ7 zHK53fK88rH%gPeu6m!6;ZE`#;Ii0qD^dsaqZp&M=u>oC$4`&q|+Wt7ND?HIw^l1C- z)uuT7L(#WwFCapx{kGESwq1&@a@ASoi)}k`>&l#?I;rg!o8G39@IxhA_h)W|s{d`( z()F!!PWe-&pb%D|K1ZZEVqBP@ekEM}0b2boKkin9Mgc~{-$mm=8~#zm%cJ3%FAfSF znSoAWwUSyjw>a>puGY0sEhobAc8<1e^H1Re+R*Emsda+1wvN!bU6$?#u_vO^?dtLZ ze4_2TJU?`G^jP}m^wwJREY9sI9n!ScLlfKeKYZ6eu(4;mq3PMqUOH#;T-&7np~+Q-NzI`zb?v6_ zFs5fQW@`t`_Gg)$Vwn!Me;zq!e&wOrgIRMVzr~y$Vyc~OfpOCc$wVg!>^sM@_$B~- zp=bFs+;ZoM^q&n&s4l=2Y4Pzo!3k%?qtCT=j`+_HKyyva=Lu0L2T+ZKif>w}YFQgR zeQVrdUGdGD`1A!SlH}b?a&hO<)VJZq+8l{|bZpaRT*Ed{@ZI4KTg!FZaCe2MNIR!C zyGw$KG<|!|$7Xso`#o)ebU}x${SLDF;NHhSGIAZh%{c5u?Bmh9$)Qbaa~(fw|D{b^ z1c^c#(x#}tv}sp|)7__knC}15rWHl&U`L-ZXX#G&e4`yp=ZYf9s~kvIpN_1pl{gN^>@v6V34z39uEk@BBj| zI&*YWuQ`v~{NnQpE*#x7zWMOo+Z^50^=t+IH+@GTArW9pkVW?z-4AyKduVsMwQiQ- zKZqO89a6Ryf)J06YGX&93cKfd+^Znu8#rDv5EbUYoxT$zox6rqfu<DKtn-1?lhr*!DDM4 zCon<>p6Kp>BP0^Gc*0{*kOQ0oz5@EP0s-ewDp&kZ^>aIjW*E#)Iv3QL>#e-3t`EHl*bJ$_o z?Z3LI(zc*uMWD@KAaU`()z7Z8f40wpjVN3fD9COK?@tQOC|u}5xM+8{j=e|1w?-_L^Ho+o{{vc%)^PG0~Aa&*&$^Fr>v=l56qm--oX z;ljo43zvRgpczFcU5HNYj=uIYI@{=C-i3=r-4{!L{!jI@ASTFD=&)=g2REHOFXCu) zqL=3B`8Dvck!T{A?H9f%97Yp9NfaiF2rqYE{`T|on$eZ53s-i!ul)IW1#C>^issZv zQU5>GPgSqWLEyNvV383|{6k@Jdt_8+r_M74F>=(UE50H}e+nO)7bY7g2Sz7{^dz7D zmHdCNe%_o9D(N6Pb#`0N!Gz4?3-Y+CLSQybD(dwRDv-1Jsd%&m)kx7hz@ z_47upzgYQBZ;el%bGvEd?cK&f)27jwru%(OoEM-+rpCgbva|M-YsFN|hw^9ucIfp-B}`5h<1=1PDm43aFtzmvL}D+oju89ukTu)rQiB6rnR}Xwf$FX zhko0Wn6|#wwr9U2+D7!-U&ORewzj|i)jqHPXffu|O6#Lf1ug$y(M|0Vt{qECa*vB8 zQKEdVo(UlPoFRLkx$JW$G$7bNDA+&vOhD+_;B(=@7a~I=V?txDgj|gcr6qTB?8Y4v{a$gAuzsjSEA!Qg4ui-0Fn=lkX^K3j|# zUcNNEvbzn;#kN1aUEgqzS$iLFO{=S`D=RC@%kLDIl-@2b$uBNVDZdwA(;U~(No(ni zfBY<|=Vj{iH~-R2XFlh>{sL?_WKPe*J~}%7Vtis^VruHYu})vVe*HIa z3W%nE$KTTF;=jfFe`0BAX=P<)b#?W_e~Hh3;>$m={$FC_Pi$^(e)|S&yYc=1GPbt1 zw*NDL=l{NK|NQy$*Pqz=C;oo9@e|R(6X-l zS%J>^)tSD!JI`<9Vv$l-^%Wx}7Fnt%`s*vl?hs3?ZdyI8dQt6C7x=pWVfCx~q^{9H z^M<>Vb^c>jCk7hsO*e+U>%VE;So69ya%1)NK;!*4kI7JOX`3eId{>!dd@JuCT-hNzcN;Ftor1$mWLl+RZia0{&l_J({$7M53|o& z8^63^#d6EowKaWx*PEqwYN)MwV`=#R*G(%*lYS~=J5|K}wEthIn`){4Kc<@^RZElQ z`q{JpH+0i<>VL1BRxI-%l?yg&`o83Q$o&s=)4bb;Yx$dxxRe>`SM=2CCaBk@R$GQN zO``hsH#8c0y?)3X+yX&4|A)G1{u&LjgX3Y7^;{>Y7lLD68+-XFczy(G&#uu>#Q#n= zEfx?}iM3#bUg)ei)w=cr^Lr#!BqFFo;NNvqi>I1bm>d-)Pj)i-yM7%svG{r}p63jh z+sUIN`9E~iuW96+d10WWThuJWT+;`^bMvg}afVj{#C19=c)oD^}c zcY5>3HTPbEaLF=G>5p!@p2JKoD&Kml+Mj%tiHlS5+0{)quJ_s~ zDVkD}2%qInw4!|Xdn)yuAY}*@694F?A<-KJvJ0@idd=62*Bvre(xpC~u1z}XBUreW ze8*tP^10VJFQIDo^(Q;4%Fp7`IYN@P%T!Hjxwx*dI8PzEM1wIn0B?f_&?|U@hgtj| zN$@jG%ZSy!k<{qT5}DUDmEfpr_GYnmpRIb0{0?eS1ca!f6?n1JR%6)lISAJ{h)=G6 zjJ}S8a&?2urg7uNpFvQ}AKi4^IVrm|P=D`Xha~hKKsODS^v6p@Qu3oOlV|VUs*XG!aS@DQ}p8Z_hdE469tI$>XSL!e<~u&q^+$_L#`k zhinXk!6lTCy$wMmu?G9N>XgGY?yY%$R#9>omeMxFzX62#X@NJ0(V*ap3*_=;hcT ze#tjVqDNb=_?86!)}8Plf62@XBM}Cy$My>m+kMY`iJ6RcRgMwj8tDbGA;xGPMG~2# zy7zaT|hM+5`9DfN$Tx`E~@G<(aptD6?PL;ZFrU_duL zX^M;65g`if>ZVnIZaN{>qqnP@QvT?s*??}k|2N!^2d)(psc$%OB3f8BPyMh@awBi$MV2w(j?(E7TJiN2TpGauU9@v zI2G#L|N35F&izZ%-dbS;ecv^~>>ICxAuSgNeaj;a?yL<#zf@Dc9yXnP}SOTF)toyVib`KG$1_nb7(&)^!Ih#d0}xY>3C zJSDlLcXj8vBKu89e`5?+BLWOQ{LxD~hBbXl1~dNabpqH6Gbh1>BRL~E?%jFx;jU=R zfb7W5!Y?E0!=4jO7tx`OF^M_BEyrqyRK;ldDk_Ko;wfR*-O6+*#E~hJx1oX z;NXrjg%pymRxMqCjz?cz`-e8gP>wI-z>zVXxiQ`GzI@|O9wNs%w2zY_j&o!m_kMre zxye==#0Ai%nG6`r5t=oJDoA%r^t*hm2b9uyUIhV|rr}O=s7R7Ck%(rGn?f)R+>scZ ze#MoMCti!@xGW}VD2z+c%(Ixq6-gvjMO>|ZMe|C4UnO%_VWWetCvj%SbsTa(F>w}K z=5lg(rVKg5H{SmnS^V4as)=g^?TANW$sFBDXATD+=e*dK=Z+{Nq7I&nJbYC6!cp;u z&|c-_mvjOvGUbs)vbZ@}A|ZK7EVU;)PJ8~6|-1sikq#7`LLDx z9nej;OusHC_4t#ww{~??e0`duSsGI%9RcX3D|pyS#GBHfMhH&s^C`m+fO`YU*ZHEoX8RrNS+<^qRBS zepxU|*51A>f^PQ6`z$CpyU!xqsyVyLHyc99wh_;9sC2dq;3MkhxZKE*cFJ+C%sIK8 z^QJoodn1eFntM9H#w#ElAC((CnOmKmt8ybdL^m&-%OZ>`)5kS0x;ZZ@JWp(I-X-zt z)IQTIT&b~9*XfleaazZ$W)jK}tYD6PJSw2~t&G@U^tSN&#X>x~QlC zJ2mWSqyV`Z7N!7$*v-LCz-|sTJL}=#T!=zX_I6Oit0WHbJkxP-FpHCFjx)f)&!Pz$ zVmEEDS5dl2M zoQ^s>yOJJgnQyQO4#&YCyW+5GoQ5F6f9R$*Yq!2~nP@V(1P=d8H$4I9ri|M{f9s~J zI4&eXat)@2BN+AL{?<*Sm5XK+3XK5WH0fWusmh+g!L^E)z zr6z&pC>k^z1m~%O>W4vXrfltycu6wUa2RSphQ2+FQ)EI7vA2SU!EAjNrv?dPFbqAX zw`-in>D}UAzC%{6c)S;)hpu?H;>DeR2l&LzSO{uZv3@@+fr#)>g%B{X6aC&==~c!U zoYoqL)^L^58o1Jm0T`#1sxX~$oC5>S`guX60 zcoJrXMx3+2$)XWD(KtIa0x(W(=U`YYATcteK+q9!#M?VyQ}j(MTnTjZ9;E*she8d& zqJGxJNn!3C{|N~^RBkwhGhN*^PURh$$Z=@+F!a@po9C-+F91cVe~eQdEKUat7qy1V zkZOZiwGu5*73?hu)e709Qr z9EQ+$tI|)pok+g4BaT37H&D|5(>T2V7^jTJfNBWTr163~0u~OV0>&w^29*x+c5h53 z!XPar-=^*%9ZNOHFj+Fp5-?6#FejJ#0}PnW8qA&%y*CVyPGOdeCUNwxamuvDNugV; ziLlEp;4(FcDYhkP0EaBVy%LA>AZz&xYy|aBo{8S2O`rUsO`ilnC4SaQta2V?he4Oc zp;E0yVJwi+FyvJqr!=zt5T;!^2y)<$Zh9aHg8D}{O5x8?zlcrHW6w;yd8KPzg2nrbir+Z_p5dUkCtpJ262z4l^S|Y%oyW!eYr?{uLt6gp_^ov?0P2agcps40&8juuThp zKlpeuM2QHq4!hE%2DJusQwB`cqd9OYW>+`uc5mwmZ$r`A0sOTI&`sUy$AW4@8I_WN zZpvs6|D&6d^>Gtwk6_)sJ9_OXKsObJhtEMIe>G!B{fUe^YI?WjFkso%OXY$IK@h?< zrVO^;wiWC_VyO^0PtI`wAXBSqy#fnoLhOL~JY+B`Pv|GYwIL&w(Lxcsy6NRWfXD>v z0lFy*K|v2CqKgKs5U4Q7H@EwXdJPHKs{sFs#dJ{_r@f~k>%rm5Rh?KC0xyXe%)h_W zhfpRpBnd~9_zcxu6fNilbUQ=70>?|n}%TkQg;K>%=y9fcvGR&xRPDz<6U z0F1vMbZO9=DKS=SjeA@G*zu)_HoXD^Hz6u%`=g3P0ONF~eAhT-)w(V8N(a@7>*Eec z6s1JtZrb3?ZQ+)$!DB)FOTPWVdT^;f#wisrP8oIVWJEmZ_ECKtK_AMt#^Hikfcgm- zrzgp*W3BhO>IYqe9!>`Ok1-123t<1&2I+Kg0tNxyEW3K9VYG4=I1K}U)ATYk7Dyfa zBw_&M{h{!tdRKolM1A;qA}RjV6ij;cIn;6D=ne#A+iccY0_7foEkLY6j^@O;ph2)T z$Pz_v^;iO1GhtZFed&~Pj_$h3f);yXT+^>+6dEGUo`am3c}jI2Lx$h7sv3JbFy_{q zb~Oqw#ejw~i_V2Xm6%2Admw2x@TG6#DD(?X?HADO*>L6`<}}HB54tW`70xlvhz~=U zrX!MuVctQAeXKIr_)CI2t{ZjRD3v-QL)r&WcMo(1D>H~ZpuxZIjPZ{+>nr7 zR`L3I94Y>EL9re;B=Z?)q3v!0jv+PIr85M1d+|9m8~kfu*V9jJba&kSn^XAY1~VeW zs%8P4e;c8|^mUuIz~anV7lI@q_Kb3t;jVFNy#_PICc=Yoz9`7)koQ&fiyY%%v01=4 zy*9zq7EY=?PfVFnw~lYyHBQ-oBd6PjI8^KSXItD_%8MWBFVysLWIMRJ;j$dF=ycWV zgTV0Uc=Sz3Mav(?4&`Vz?gy4QfY^}cAVBVKF-??v|LwihOXz;|+JPh`hdS=%+ zU4q{X|J84Kw^Mxxv|sui;M9g+o8s<%M@apEyK-NDYE&HCU`bklW|zIr2k*fQ#IL=0 z&{~4GV>%ivqKJzq=2N*fnB_B&3ic_i9;`}+*1oWPw;#k~rE zR$f~2UwJJYoe^)j%bcp8SUJZ8m(M^IvCH8Yh{&(m)FZg^eRrhOp*^N=3|_AB0n90J z7GO@NY}s%nQf+KB_|@J&%xRd1EaUd=Ay5f>;3Nwy3Sx03uU38L2x%{t0E|=2Ger0N zvwa_oMc?u+fO`}N!U|>zq&~hiz;WM1m;k^j!}QSV!oW$Ko&-XQ4BkmZNU1O2gBuco zA21h$JQ))H0j9_Vb6ocDw>|;5yUtf}x!j-MK6)xed*5z*yUn- z_~*p-b8DQTpr*3hrFZOibyHDpc-BWq`965L4P1AwO{xE$h7nH7XjK{e@GHBy-XQdq zcv!u~z&5OYuyt79!|$O?%_dqKLMJ04*dHAJ+RQQhhSF}J6DMe4S56pR*>z3#e5yVkJIY^ zrkk3z!;r%NhMJyv{piepqNd!!71l1UYhi-s|Bjl5EYGJa|Bb2XpMGRC(c^r^1j&5JM3Eyjtn*-dW(>!P(CZl#&&1(fA! zOfLCt@Z?X?@Ac1d7EcU!^kn#Mb-~IXbLt1zLL*wdi6y+-RVX^dHX+luiP~GcRNflW zs;1uRTkqX~gzL>=tP-TE+FHZ9_{?`cw^1U*-WOGO)+H1R-f25Gu)i_tY=wkqbYPWq zN~}uB?P7qk+)4M6Rof)Be~W9;^h$#s8;>34%iiirQ(1VAi)j+_GY!o*W z_rZ#0NZ)Ufq=IPkN)mHHoV1K?gc*(FU{^6|TbBT!T@m4!&1(*f;me8;_+ICMVM|9)~ z^j{z|6-gT3mbI_W6J5KzcLg-=&GeT9lSid@lRXo4LpK_z+A>fmq}{1=v?M#QTO z`XJ$_(=BX{kEQu&_bNB9*oI|}74gL_;|Im7gw}b^>1?q|*0kX^oQm;H1_%V36qoN? z3B7F5DT8rE%P&)$Iag3Peutj<4I+-4 zEgQ>yu=j963)}foer*L$jO!8;qPTZ)CC;{}1%%3(D+21MY=XL^ZjMx z<9ib!X{%OqBCncy9_EGtv!50Yy=s2`B>S9iHDUSqtCm-bnc*_0kA94J)%xaMQiPPb z$6D^Iw)evKNzYqPe!p_Keeg`^rNwJAKOA1EsyE$oTx+$hV1lBr5D5lL`XtDQyN_mW zCLw|&IoNup9Wf-VqXRQRMQ51LX&6U2*fyUfC06NhfFNW;rg0ut?3UL!aI9(#u73c; zg;)$r_O&^{=F1XQRag3&BADq_M91-&sL&C2iE({H6TRk21ulomn0F|l&EFqdrIyJp zmU|r425!r^v*+Ln7bge4RDC^Ofyz0s-#2Nws6#+33})!FH4qxFRoi(tM^nFS2!CUj zH04k^^ zF)bi=(DdssyvW9R!%(2V_La?{={*VVfNrYa^5gyW+3%l1siKAU>xUvch1tTi{WJ4? zeEV5ypFXU3?RhKO6M0=>Hb~i7azgyh%%BzW+>L?U32i?wRMxzr{dCT~1AG(0Su8Ym+%-LVj%hrMF`M>l1`lu>K~#&oW=8|~zl zxT~AK*_?O`=%(i_*R8)w%!QP(1HPGLHs8enzhm zhPqyFn}n|7)9+s@&U1w6%^i`T9eX&x#85CJ6K6R(X~sg3RXH>jT|7ia4Pw~F#8K1( z@2i5BFl;LY%9bEi)eZUHQ_6u`UfhDBx(vmPCBbC@)RclFgXP1h!cEOeL@JI5@dFw> z1d+-Jnt%>PDU8ZFPX@pVUNX3l8-^YMm7j+wUYFu`?BFw?3xrdZA}i%;StBtN)LFv` zeeKB&B%lYXHyakwC2xN)tlc&&pCI>wcqCQW2+1(v;Vp8nOYA-yq!6a1*yWKl3Di&o zJ%mH-yKA6WODQ8D1=m2T`;azMFHC`6Vk0J`ZgT`m!f{^=-&p-3+|WGBPVgDTgXlTQNkizO=iqxH22MIfn>D8d`9=1bmXlscru zR)GYaBH^#gNv0J0>&CE4W7YQ|4_8p0lXLnDy5{{U=J>9r4RZ-l?+x8QuBi@Ekd<|~ z39M2CJ*-39!ooPi(iFndaLGnd3dvK7dI_0XSmcsLCCVhM()`7L^tWyb3q}o~hE2>!XfYQE!KMFHo3Q49lBfkl9tT!Rr_}oJ@!}wg z)IC~?;j0i}b=%;a2@c(ggYJh8KE z3nkies2F1m*^2~5{eC^4Bj8UFQ$dRPQ$$!r&;5Ig7_k!{$&=lJ0B}mBL-oSI5vmBZ z%a9434**UT{2^w`#+$vMIV^aN+{TyQ_hEwk9t~MuqrRO3hW7B@6G-|D>ZhXlh+;<8 zA5~~#;KFIXw6&6s0pTBjZc67z|P{Uq`#H*$_vsiB@Z>0y`WZuj^`>`^(S$y~brCXstS#bh7d%)~NwuFEKx zR{;Cm*r!`_xuY!Xxn*HI?>@vvx-N~y=PZWrb+uH@HZ8+Sh3E^Fac2)DoUT~as$EZLM?F1 zq_2?`U3PWT+=}+t;S8zCjB75L5lAp!7^VNNjjubQJhG&?sco-QzN&B%0Gu9HLFzVv zUov8$M}@IDsD1`?0DFvv8w*oIUQ|yKV5=mdN695?61qBwVl2&Ag=#{i@q5CINq?AA z_1IVy-dUH__mQc~{@p&vR))nmLoyAJ8_RU4-*l)uI8FI<0X{UGg*S^G&MLoTNq zW0QGt*7dLqZgo0pf>^V!jn|YG%W`u4Hcaj1lUJdX+D;jDv@j-K?EPTvK}94+Qqhsr zV7Z=ObP6z3-C7f&U_yTiqtr@G=l8i4T9n@$?h84AbSZ|q3OK8#m{Y8E?}pWJ)4|2$ zSpJDuRF+`m1zpYGqo;kzF*)={zU0Tkl;X&nq4&Vu&p_c$X>sy>sET2-M8^pZ<@;@pIMV8 z;~VJqGdyK21GSu%Gn!t^@uK{-D^HW1u};5JHs8sVDd8eF{z$4CV4PlmIzR*~U=q9Sh-}nS@^q=JGi{k7wU*J76U*Z=B&|YuTn6Q*C$nxkFP6rt zekDtyMY^7me}6hviUx-K#R_a4*TYhJNk_)9f0$ErF1ojQkSF#18icnAl;g;Y<9WU8 z(mi`URU8xhb7A7PqvOum@rpH&XY-JQ!kZsqt}{*}CS*_A@MKq)-n=1w%LR`b)-z!+ zTwk;2PxvIt{Q*wh&jP?HSwJ{<2gAo_LB*KSPv*FZL;+u?K`H`VlY%IzbEB#tl*DX- z;RUIhsLi;eXL8I!E<5~uqLLErj!k`2aN`Z-W>=?NmlTLcH%wRUUzr-|OC^g;`F zewS%OC7%*p(noHeTjC4PAgB%ustbpDf#vC?zd9f_x6+&ZOf3C54mm2i6(^o`gt?{OQwY2NqybR)zj7f zJ>TP#Ms;tFdy-#7?W5L&@J&2W!zkoX_rBQ+*`-bA>g1MVNB68jLho!fgr#r=Cr#I+ z#URJDWhyLge+!V|jJ&;d<97KL)HstWXQ3d6U;9N2^UMSvae=5{AxB7LAyFlfH_-2G zYclo^wx1quk@|R-RHVBZM5D81$F=EuT4e8R#TpVJw}DKG`AMZ{jOI^OJ`1qnGFj#J zIe}Nu4UToqzeMM6&4uwK=}x(1F&~y~K~Y)=qvdkZQ*s-vwe)+|Irh_4dv6{2Ys1`Gi?9@a@xbPV;#j0nV5C4& zRF!f?WGLs_f%Rof?D7Wu0oCepxRL!gr!SlC_BE(4O+3mU%YoZd=^>+dS+k2%8FHNr zi*Jg{v6&TA+aF{#;+l&e$okDmH~3y(We<;65w7?%WqSU1BCAZZRIBz#-|bfwN~4O* z?W0*yj{v%96ZH=Df-C#}cOyVI4J`+BQ%C%nM~CkIKECg%7pP}S{+1fuh$J=Kuf*qH zt;V2O=0ybdY#J@cJ}-t)XMZI72^ssH^R~Q@0^hdg4~g8~NU*1VWlmjjY9=kE>2R3LWli0w2RX_P648DZCAAFum|uEEpRB+aSar*61C{YIqJsjni>zdpT+5x;X*qUY@5(pgf{A-I}i z?63^`s|?63LRk(2O_JmA!oaDR43=Er0}N^u!@G__%hk=lMR2;I6&8yrT0+DcS&Csd83|??387vfxmP7e3A2@oh6lExD7PuwvTZ)%QRVM-O)A99^2nwa4v=RYd7zopWW?nGfI9XPV9}jou6Tp)uPQ{bT*phaX>Ntr^6Q z2jA3O>qBQo7weX`4*2wJkDmP{0$ewDCXv#j{li|k7WErv*@RXyF#?=YS2}?YK3puG zo;pCVN5xy!pxYkY;afWroo-@rRklB9CW{8+qE9GMp85XO;Blz+%b z;ASfwH8l;8|2lHw_*%~5Ehqd9km$N5j>RUzAEy_>GXx{*=M7B;bH9#mksKjHB__@vMmCIQUK}R^My+xto|x zdX)!C(k0zUyLp3=k7}5l7r0DjO(jTsd?oUWJcv*Zj?xtR$dnO2JLW32nL(qW#Eala z1)d~-%l#=nRB1asH+f^zM7MNlE2mZY+s95L1s*Ean(w!C+6=ELHBtw2u)xP^&DkOO zxwQLLMzXZgWr zo||wdmojeN{MC^I-N&BEpZ#=jLYZ!OeiBv2G#A=8JZJ77f*<+x^2AlChU41PgRIGz z>em;i$scZhpAu4gr1LICpI!9?oLX7yBe~InDLDK4=rI|`g$d%Q^DxfyK}3tByUe9< z_IA@1laXBf2hB~2z?DtUIQ}6X!_i*n3Omzwn^)n(78=A3IBmr18TqBt8GZI8+gAsC zs2>yz`Pw&ooa_a-dwvylGi=QKUVQ8F1Da0db7U@mSP9}b{FOFfWc2&n^i}7D#?yr# zY684M%IZEVv%msCrqlof`IKptd^E%xvHqr~N{9t>U{XceFq~SwRUCGy=YDTozrUr0 z=gDN!lni8%$F>A{-&%Rgd~|y62Px$SEd!p%L(3is<+N&rX0z>CbKPIdED0Fh#a|7x`t?B z=;@H<*X*NoxU%d)-|{sE?)f(cA}lj~wUs za%Ed-HgG`qFw!|QEzz8pK<-^Z{P0vpMt*mY!c&uSO>r-S1$9|B?;?tDx^kRkZ7=L7 zI`x?U5BRH<;E18STs$?~={|v^8>>FbmNsh%(!Ng+F>6Xt4@Lt21S*eXaS?yDayV`j zdp$$E+`|#{IDdxbcXdtNUb7UeiZ$oZoJ)05&>JZ*ITPr_ecLIMnIO+(ahRd=rE}*J z_RulPsJTfYz%D({J5VfknQk%fJfgM`&c4$rH}j@S4w9Z~g8b~xT@{%qQmI*AbzF*J z{A{6D;ZYe>Io+SXC4$Q9;mh~Q#L;B!DM-NeNi|702tFQ{9pSrpNRvy{^lWifE`2~& z6Hj#&@04pi#8J~6&SmqtACyj~?Nc5Zva+BKRGNLO%5C2VsjI5KSGBI5F%F`cQ7hC8 za_+e%`jlFD-Mp(p;d?8`Wt$vZn7E^)(*^#NaBH;K@~4tc=SsSJ$T8;YeOab?%2pYOBg7LO1m8?0 zLTL1&fE;Hs-M+`^b5?%!o8PLRo7ub{uZJ&=f^UeM)Z)dZPKdAP2WI-Pep`LAI9}jj z$QW<=Etg$n*`kWNGYWmNR2WGjKGTmp3`;vcya-{Nn+yl$LScn`F3Gy7!$u^v*FFtpFpK|b% zlk5k%ZiB8~j}{BHNqBzEdYGZYJmM8(uS+fo_CENP>S?p{@m5v`t5XyWEsB9uhLz8) zZEy+Ro0UJk^ZxUU?z6+6CZF>f9(r8K;dfPYdVcHBN+$>JS&JvyQ`$W5k7l(T@k;$H zzqk&*u}(p%F+!QUV5vuknk3tTDpP}jimAO+t^RIYeM*Y><-*23?Fz_xMS8*dP)$VR zfYjYzm>{>M@2@&S8a{e8{8TXv z;Xx%RT<%pL8PhN>ITg0*RLTBH^Wn5?Zshpv>I#t|G9ls?MIQ2rz0#c*A>!zhd`B^D zs3E}&l_my9fRcXL^P2B{(6QH|A21S&?dPE_hN=;F_P=%(|5?AdxpWe z=ZnruKOVNKKo=~b(Jy}yM`vO)$0}iqA8dZj*dICaP{7V8d2DCW=l#~0QP!7)s~*1$ z2387G4bk1*CifcG1$K^E4$fLw%zl!>a4w$oNM~`Gn0z@(5%RzbfchU{$yT-5)*ab4 zBiXj|*>+zY`Dt|2TE}Cy7+A)@?daEW2a`FN8I21jya{`5AM9v;IomFhag+i=@jfS( z%^h`}vwApg{fTsPo`D=C@kcr)XV^O2I4P41L#%ZKticd-Qmz@a4;ipu&*sjIWP#-{ zVoK?d{wF0SE~&CfCo-H*Dt4cg6IxJN(drTGZ49?o<*Q4NaAO%PXA zv7T4XqU{K8(dhLTacVzrl`VHi&I@O>i$-6@t<(?3FMB5y_N@D-OnZuI*1U+~P|(Uh zL8wAR9!!oo=o2lzaIlkO_68ZD;6$Y3G%u%A(%<^`+O=e#02ja2yXEtaDd#cx4z~&$ za-2y24Ws9n7`_>njGzU~p^}_sr^svF8;#=%bzx*TJA`2;w=q_H zB@vnWiJgn|?_PFt+qVe+Wdr=-MmE`4OWU45&3c?edsGUavw-e|gHKj+qNYI5PUGPItY z$qwh`4)#5rbSE)&>8gjc@WIUYQm+#qsU({v`#n`jd8x9HuH5E3`}jp+%J+)2(|yV8 zigez}%dowGZko9sm!Y&b>rlYeIhFU5BdH;`vW{2gR6WT&S(zKM7wWS&?@B;cbbuqX zLn0f%OF=eoySR(w*iEL28qsrUS9)-Exg{dYyZ4{ohCy2HV z-krTAZXS%xZbqt!MEzdqIOs+Tn9l?*vBrY0ktLeIyh6*omsI((L6&54@u8}!_34sS zlTu9>Up*K)0V;UP+T}|NdkSv>d?`yJ{2F|)lBXLa(bTaO#sXMOc9n)&>qAxJHdSbH z6(``RCc|!PsNPWhVAF=LSS3r)xvSz=E!yzB*y?5t$?O^xgN9`fT=kur6&_sR!=cIu zET~x%bR)O&k;ZCM(uZbtb&{^yqvIbe)<6ceiW?OkpRRavjrCYKKqx|ny{kx9t%>`COB?B)bIz%0p zE{_Yve&RsrPz0O$S8{6vS3pvmZi^x#i&g>ek7!&DXB8fjg|305x+$l^aQqAn!8uz1 zwfwMXzKfR*CJ15)s|`p&055g)a1X~}U=Ve)zKeL2K=6GhAKdsT;FppspVoXVuh8eM zd3Ul8J`9#3Y8bOv5}UYF|M;bBO)ymG%h$IFs9;Fa6VqM4)Mqgl;7bicJ^t{eJJAV0 z-g3YV@J>HXf7~(!_|jkO2xde6mv@+&6ZKzyy-eUl6XbNjf;t@-gE0QB`yeieypQv5 z9W1P*ANIzS<5buwAFS&fNQwo911UV0eF*)b>2v?ErOEcYZ0X?MUAA<%l4}jeCw74A z*k|GAdmm?-2-$xvJXwTT28q{E&Xe~GF0q(mV0i?UeFQ5Au%%n~5kNKPPAKOfS(>jS zYLF#5NR|QE(&gHwbh0!z<@xXK&rt<|Io3!=ybPLh0w7O!*-{*aMdsJ(Ko*7ws^Br% z#gi}y^e>tqi~tzjz*+PSb$cT;L?#lbbjX7N@W3ZX*ly&(ym;3c&q~+zOjd1_v zfdRRczz2p7;!Gq$kK;PE!?hLCVdlmJt?*54n6F1T8Ng^$6~OY6ozUs8(8Hl}40U6Z zP>hSI6`UYvfR$ehg&Tx%Z)gK@De-YV65DOJ5iXnD&94B+rG$NVa8?@t0@?BH$lCrp z=Ukbo+?bAQ3V>P)5)=Z|QnCQHL(l;Hu$0A*1q&*$@%#L68~|H7{%z>`Hvu7hcre-R zm9kqG4uP%n(bckS3Xu%M9`ZYX^_j-Cn)@CTIP@Fxy@*}2^jCz2Pu9kfU9%MTtpAG9MJmW0G0?@(79Xt~tcx#6&s9x5Egsamw{&0ZcM@Cy{ z%Zlz7$Aya{z^2L<#c3g?cUWOrlv}AVWD`!vrpr7HW^NBv90#b?(DqK#jU)T5_3vBX zVQ%!VZ3N=1dd@l8e3QjeQ1TGOj`s08Wa|>##vTGc3&$-%bzzdpb(;=wfGmZ0e7VTU z(3VF*P%M@Jnhza4BPLue$k?7GO8xd~RK;oLLP zL#y{=oDZ?(g(5LN>sa&s@`WI48OS0amlo;)aw$2j8769c{+(d zW^L%?YhAdcHW*5U^30KGv35`}`+l19Y4;wGmi2}U9b{k}m3e0&b4h*vX&hWE3Z18V zIq|&r1#-^Cy2rD1l@VX%ZU-bx@j9@ zw9WGH?R&z{X_1SvK*cc~=lrxE{ic=r9X1ZD->b#au!&uczGmH1zl)b5AjZ9GLv`V+ zkWH?_pSIP9q4i9MdQjXCZD?uuMN<3a=e@{!5NhsAaBrAkdiN{Q$l+sK+(NC#m)IYn z+|9XXzX{Nv@Grz)JI@mEmpb)^2H)2qzyeVHx}z-*=Zx?nYX?>0K~^_G0$4E0=YD$@ z$Cs8b@Gq^IC81G=LOzX}!ndk^^#hlk{L9Q5pg1rpIT86-#c6stSr}f5uTr7D^i(KWsF56}TN9g>jV-eT%jD0}N>BG3ohH~k& zsjS~jEt<6izMHTQ7mn!e<$}h-#mS`Z3Me6gPaJdh>@bHwthozT>?>QLJ1dd%ut8rh z%Q#ulK8dc=JKu*)ut_4P@2&If%|MGYTsjvx2#GppSAk}Rp+bIKhLTfDcEGVa_C;nn zdO3kk)y}o2Uqo{Wsk$^=QM~p&#l7Xy_u+D9nqDssw55z{wa!Tlh znGF{m>m>1Y$k3;BRQ#~9yi~kF8$RJ#2P;KftX!V3W-d()LMRPlx+L_Vp5bdOTr8sf zME{_UOZgyjN>!YMIrh|ATo%=oy-lVb{`dy2In&?}p`Z?sol_HDl!vs-T9?n6fXoqLUM^Q&uG%U3-UMhIEn zu{z7kMX+awtb-2>vf3!6lBrmPpikj;TUp$_dsR$De$LAqB-EH^Fl9nBaOphcsK zk!=sfhHwvY^J<`}hb*shhv>|nX4p3HoW?*8Gp?Wij9D(#qU(LgU1vOlzft?rw)ryX z{)_Jmzl4;3iIMPaRF%yym~W635L9WCy8~y2X8W)VOnToj=maxdk-oCk#2igw%7Dhd zVqnpEyimgjW6X&iT~6dBX{yk&G^apCsSY~+W(g!x=gU2(E+IGs11_m}lt#1Wp+%^I zckT-Ob}sXA;vp0B)!93LSJGNNET>s(w0!KeR(;H-8Z)KECh*vfg^8maT0CCC+RseN zp&YSFS?^K~JF0B^=sA=d$4N%Sd-n)HrOInJI2Z)KlNuzJEa8uVew*YXGdi0C>GKpeJwLyABXo9qspz(u>8d zYcjp}m3dL%hu@}m@kj@bli@mZ%V3Vf%Pfj7(DM_JaJYNP^Wfo&kDg!JeBmbp$8GyT zI_{cr1S8(;5%NwKfytetVeE^&j1T5qXB_rjrUo}0-+TXSJXiwV8PdBJCr)Ank74Ic zUY@RM(DlVEpGCYTU1&TWg>zSJ$+;rniBO&i4dXouhVmbv!{tg5v%0;U*GUMIWi+P% zm4cCTMktG2155g|sj}yqjLX7@tSuPD0PQVB7yM<)AY)GB_X5Q(%y(DFG z3`KIK7pBlX2bB`yCmct|#)HZtb!x#9UJaZFP17<`!WZOa#Y^*5KIfSg?C?aR zFV`mUiUAN8C{Ot0`0V&QWpCzeD-#ohqt2EP%ZR&D{H{T!b5Vt#u!T$L>jYNScH+G(?0|hVZ#IJiSc9l`7_#CN z%yM*4W-IgWIr_J5x@;<2NhEP<-TYtd-DgmfecLYjG|~tVdg#3uLvNy2Aaq1P5R_t2 zP?`#ef;1Bdy@e)CARr*1Voll#Sm+ObZ;3brIlJC{#N?Asa>7j>?N z74oUh@Fk@6OI>V0iI>P?<3}wU{hhgXEX`o+nm&ee^2)tqd=2gQefqFx2Ybh;rV=KW zoyMIdDYA2#sF|2dU@<%LW~hHnkEi(_>(Hc`Y?#O>wP)np zmordFyLT4DT}R_H&;T;EZDtXiB9^;lWtdCxqJs#mWBCUlyirQIAza3!swKP?Kx=md*@*`8TCJ$BETJUCY#X5hr+AW@%h{k8n@3>Kn#ABcWaT;81)uoS%+V%I0 zWwqQ3KB;ap`AAPLA7MWAP)=pqQb_mXdGUD~!fO83W;4K*Mif_-ETI+k#RmC&`EjrG z_N)4;#X>5NrlZxcLE)!3JpNZ7mbB@D`oW;@jGREnuCEkjaq6L({56|VG29TWe# zzr^&Jrdv*w?prx4%z7QTrYtL^{%bGt+u6RVYx2Q+WoqFbOK=`n0IqIp^8!tS2_0r6 ziU2geJ0jn2$>n%P7`YXg<&4M)c2St4KxYEeA~&vl?lnhsAklg#baND?K_Dq{?L>1k z!?<>=(y+g>*6)WWaGs}Mn`n%T4tqe8j;vM)ea|*r8qEWB(`{Gg-@RLXTrGXF@xsLI z!l?$|3h9rHpl<3DW&cDY;ne-oaLg9o(BrKhc2c1d@BC_ z>wR7K`h%p()w-(2`L<&*Pp>4@HsqQu`pLwmcl)ljb;Of{&cwd_vg2IW`^_)3T!+`F zs`bGmb4%G(ac_-q8+W5PU(?6p=66^9z~BA#RP^q~m`Bymmv>gboyeHDbo15Ew?;cH zYR@EmE8n@f7E}^qld|Ai~&0I%`C^a6`Nfzpk7E860_SnWH?A;M;OBi>fJ$Kg>|REQ7wd`N2gQ5#fnhwN|h?x(XM<6iiky<|_)tL`AC=wB1$3 z)Fnlit0?yfr4uYApQ}heU1gsz92a3V&K$a7*T z(OE}SPZC}*OV-g9`&zGfoL}RKuF^Ffy*+|6IeKP-dIsBsEcfUShwGl^HF)S^@G{?E zTb{O`;JW__!;Oaqn~x1;S`1HqU5mbE1jQT42^#Y+8>I`bWqmcqI2#-7G5M5dvipe% zM#rSCU=`F&cYZN#`MT12!b}Wr`sIPyZ~pB+owk2qncdf09@R7FJ8nMlmGfoltGOCu zyV&j>Qu#Y<9`5KP?)Y}%^ZK=&FFx;tMt(v>0w(yKCXWC!0g{aisgwmswJyr)TXY<= zP;*<*T(z)ckPKGkOwrQopH}O5 zhIP2mY-FU3AB)`bg?#>r&At`ubT{SfRof6j!(uA&xLIH1;yIXhLbf#FKtEA> zpBPJS_uy`i0zXk>Ya#kKn3bO$NTC)M?K{aY(L{CuDb#aE_Y1S&)^e`LXNcR}ozBa- z#|sPJ*ySzijCAhv3_0nxOQ>RURwA;<Ia zQM`bx{RS!2`6Acze*41RcSi~D2PsrpId6qEj;XA`7KK_(+4;mx>#0_!ffyCKKY%9u zs}1=>)&DI>p#qeBBoXwpgF5YQyV|yKT%HDm_lcP96?XO$B7@aE(4&SVLFQgTZNI;D zQ^Sz9Qz2dLA-!uMeTJcfr$UF@L+`JJJ~BM|^wiOb_MM{LxLLPN_UUZU+t9qEKi2)t>rl zDEoEh@IFBewT@Y@bowU{u_2N8J7I zagU7RpGI-wCpzL^evh9qN_ZQU@B!3KJrd4?7V1nCXrUsbL{q*W>>_!!s2|D)E!3HS z|DaIMiHayjC#rQOYON>g7$+G-Cz*66nXf02jOkX$F zzjf09LgJCWGa!Wu@g!hHCDezb-Gl8L{C)Tdgakj)Q+~ALG}_Ub^lIaby6B9?&Wy|J z87;<{ZPA%soteGsnSI7tgV9;TomuzSvmP1$t8UtvT^^lUv@S~ROSLIFm|+yS{8Z~z zqStfx)42o!V_g()k|%sRPpm6XY9mk1Bwy)tz8a@1U+a%YYH+&1q^rPuqu}3lQ5}xWlI)F=Jd@I*)1{?dr4<{c)h1>C zm2P?y6iiISwNIVBTXXj4>9iN}#V7YM?weG;Jze>stMb!E<+4fDx6@S{T~(VKTPi6i za{QON>EyYVnVOq4&Bqh2$ec4(zowho{};OH&l}5T zH^0T++_-*o^XEhUwHnw(lHVzJUj=OA~oa|lq*t@wqxVt;M@A25X z$IH#lXa8Pb-#rwHgf)&!p{6%X0f~4E4V;)PHtS{~bF0PZBD4 z_urrM-xz8*=ZwVe8$BCe=bv0W@bE_O&+kib?pE!-d1LeE`q#zR4{zT5{TqT*ou(p0 z0;g$nGtWHtNz;mRj=u3z@Y5IC8#t3pINUIkB6(_lCRH{?bv8}$Y~XCVYJJ0OhGzTx zY$oxx>YFV6XMu0BjrXd`8NQjgO-K^Y8zj&Lt>4@OL+t10@*NF7%oR9WtGz9B+Z*(@ z$n$XH+q2%MKD;faq^P|s@jn~%t~9W|@m*PHdzW&)jjQU6(T;k{z19{2c7FN8X!yOV zn+WxJCS4?WzB*00X}%`QaAE#D!&?1AZQET!i=mSLOAM9pZy4&Kf5%W6|3@%X%KtYpR9UVq4Au3YF;swm znu}KitAlWw|~mll|^`#p!|veI6DZlZ&O8LMFb4it7iSl%?LDIdQU|12fA4=8^E=Z)bMnAoH*n`_)7qzCe z9m2V^Ig07H^q5~b?c_9yAn`1PcNCdtu3?2yh20e|K7T2GL7+37i%?6!w2oS06kHGj z?+m)eed+7#81@1e;}do*g8eDxHKLajvEk*|(4c zVv_BzL_t^dC*jp;RK5rlTgb2yLK4zdfrG*Ywon;BCqs-l-OOO6>aB!%hzQLgaCoRR zy&AjYV+WcE^ecK+A3(C%(sD$mVm%dgBrp+)Tc?^k-i4^zCPKwnsr>SO+}lea0!?WM zn@wiwj-FF}U$Z0lJAQf?K6q9|&rUhY7mGnDkM$UAT0o!2K7$<;x?xjsiBq^UgC59! zN|j4X5g@V>-RHkyZ;n?BhlRfui?b}s8%3ZsA(;K1o!Ff>G~lOPe5?*kKRTU8c2ZbQ z#YIB+z#e%$uw;}c&Ekq2vp<1b72`fifxFuxQIYo!$>>4gYwTNGrc2!RIB|hPm~`@<|5_0AQRoCEsu1gAP7zWj0UG2)sK>e? zJdnc2OPq$SjUH6|j6Qbkt0+OVd9g-9>kCw*PfRw2q<as56`LhR|nAH0|8nNG-_Px?Q#woqe-e%@?50Ta0iitiP ze8la|*K_@5eB-I0N*uVD?16oc~Q zlYkurNm@Pw26cgQC4XPP!}9He$W@<2I@0FPu)5e!dB3(tG2RT`xN5-?e-&WH>UqEm zj}c?O3hXGRemQwsVs7zNn81w0d1Z=Ih!dbR_6=+HWdm}C6ILx)0kuBR{aE-uWV?4I zlsrBN4U)}jIeL?<^#K=GJ3B~b8fPB{B@($ESnnBqP95G{FH>QCZL^ z_bnAQ*KkWkl>}8(AhPyI3=SWhZUoeczzIaIPNo}+>7l^J{1T1zHv(F}qi(Vg1OPq- zffL4)c_XPeqC(llq26o20j|S`+<^eA!$IyqNb=$1Z!x(W$R1{2zzNF%_EhPb=kKuiXE2j8~Dr3)4 zQRubcO_f-;v{TVbs7@xfNhP&85TFExwpyhqi0;Yc+G||5hhKHy(T2Uk(QbC%GWu=F zK}K1(J%JY0sG<6RlSXmf0dUMWus|*jv+8Va@E45ga%Vhyhg;SwJ|Sm5 z+HtxhC&D-f6Nu;bO!;V>yXu)so69-qnbW6|yEdN7Slh{!ruxVyGLt4xKIl{$QxL3(xYT|G`kZ?87$lo&R8{ z)W~9$uCrShYN<`aM&4J< zWr~#%=1L>f%IZ&-@sZ0?)5|VRl)-Dun#Ibm4nsf>wf%Hi+v)P|;nJ?I@*8%gy&L6n zTrg$Iv3{}LeT`(fQFyF}g~bw=?3$(g5{lQxLS`D_G-@TwnMOPv-jY!b!p;rZh4!js z;?j$)2DV^SE8~B_sQPIYj`#{6XC&Xer8|+w!~^7T&=bQ}j%?7t%j6$`((vd{!+`B5 zEM|JQ)k$0`q{a3>PBEecvso>xh)tKntI^)C|p(%mdr+{Q_-3u2wYgz z#)PE~3k0Su)EVehAlnXvQSnTnRcIC)eR~7I|AA4}0SlWEKn$o>Fs(ULTs>8IZl_|6 zVupn{fKH!AY{96+S}WP}XBE*|VTiMewPbP9t_2b}R#6zM$Nqs)g+Lf}^qgCn<6bOD z;tz}}&IRKj$S|`}_~I~9k_8WC!<54si~zuMe+`b^uy~rr<=>FjU3nXXQCW?lY!?CX z29wbQYY;}AuCe?Bqw0!p!KfRhP+j~*%h3egB`#g(iy(~JVj8S~zi2_N=2qm23A+^V zJ~3w6`=3?RZFuxHP(@|JUi?u}PybO-fj=s$;vW@t8xfFTFeR5@<6>x?dZ-n(!hYK8 zZ5ea6tntGn;*kj;Nxkg503+4aTP*+)Bc$UawY-ynIe;=>s+j4z@N(<|Z!0teU#DOn z4SJ~J4k&3xOUQJKLN|yURw|S=sAB7cgE;_LTl47%JYuOu8Glur8>Pl*qO;LBTh|Ae6uTP@iTU3Tkw7r-F$c>X*sYQ)1B#d(_Xd=DT=QqWn`OglC@ zl~{Y(wDxx?S^)sy;%F>+%R{vsK@&%ymg4nMu`p?NM=T!R%BW>U3t?4?3#qxLSVKGgybm9k)4cVL-qdQp<01Nj}05)$UrbNp?2LMsBs-J z0M%zAKoXTc0+9&omUBkbUGKzAvT&;v;Xt*ZL(2>QmO1weMi96W`<%96jkz=2kVC97 zbU+<*h8sbuh)XRBSQL%|(_E?ur5+dy=^YP&>HQ&5^+I5Le@IlJ1!O8~i$pzAjyMwA z+G6^LM7@6T``;ug)*CqrlBfXNf9Wu)5Jtpvd3ymKAc+dVZP`^~6w+@o<`HgY(2F`q za6PmM>aWp*n%g2#4}&Bsv!mc5EGQQC8zfPeV1B`9(jd$tu08oKL<=NQ8HlA3bP5A{ z2vkv*VB1&-x^sVSW;@!UN9!*Y6@Y_~>gmia6;+-IyI@8KRa8YHOkmt;f`G3Kv{idx0O#qqEhlp%r$~O5f#(^;EczUVc{FPpW`VnK%K^|@LL5v*IIy9hF)2=jJF>3#UbG6#;-r5RhlS(d za!ZeYa>4Bxd+nO6dha4m-h(9m3cmK@Nvi{Z0eMtNT^PPG^WKnzcnUnI1QdVMyf190 zR!dE{G?b6XmbcKsy+N-#1u;OaBd}+4q#>)fIm@?ss`muGA5N}LlSQXe(Pkl|X%zH# z&;b{^2Xh2S7umS5drFLZzHGKz`5A8g`}GACoUDs3? z4t!_H_|eO#S_`( zfOoT@_{rUeIxL0sl;4(SAsis^>t5IGg8}oq-Iq8&5hBm7R~pl$S&vR=-boi7!>(4k z#*D?4jlJ8KClf=G1XWaG&6bKv?S&&?XB|=V2GZ7u&EWLnxaaC5a_oN}?eZL+{-(VvB$HlkvJniCsvUCL*iHMFx z1jVBL#9v%{nR0~tyxC9ax%-fh=g^O^kE%5Wc07RTtZk{N@T0fxc#Nhw1D#qgkmf*8 z2tpD6)+L7tDYLkKzkYuf0v?IjFZ5V;2{91+7(NHpVfmLd*=snbdrBb!>>caIYvHE`&uvoKVN_Lil2zuI>WXq`H?XUTc{F zsg?7Y(lCXL?r9&mLfI2B)+==H!%rZLigy!u0EzZN&Zk0m-@Pa1ipukco=%Ka>c;tem1nka7E{QNGVv2o5deN8I z=6(^X3n10A0eP@+s4`N814vW7yEQwwB0ml{KY)`Tr88EydAH-H&$~N)Mzmf7opezm zGmZK9nmKUfVrR7%BAE!A!7&wCP~M99Ag?VFH9iM;cjK)O2O+sM2$HCWk3HcU_*}Cc za3l^LymUW|_Y1uC<%>hP)Dkh>qDEcLXsfsg(1P+7HR)E`Y%aHGW*MK-Ki6V(i2sQ6D>>dks*zPg*u$c4e&IGI%r606h- zs7+?8x6JGl7I&}0DG#sN-7+M3DmrcS{oaRY!<=t$p?bI9AJc!1(?=5yRwZap)>t-u za^!tjakxJ4V$<=E!KfE3$PAtTyd~U)2$VR>Stx1=v;&DtXl|r@WhismABj`eE9s;- z(^IhgiW$UZ#?o8{zm^+uoZ*k*=GVxfPA$=EEO_POIIHP$ez%gX_^(!5+BmtInq~bv zhMK@7u{ZSTzozy@Jw8u${!40qpoojlD15GSrjJHLN{3Ca5@%9)a||Lw6}|VvW>Tb% z^M2*n4o@TZm;8FWKRKc0+?lY`TJ@#GGRbE>@c$~b-o zyD`lIEuXG>6~s^jDe~zeMB79p(v~T=g`p-QDg!+e@9^VebZiwVwrUqRmn>Y=CB~@= zjRwaE7w!KEL# z?(wGIKr}iaKC45Vetx^_!djA{R=}S@VW1+ULf)( zS`;qa{MHlv1@FZt7O~gw9~kO0hh29*jyXEN6)3vz`r6U3i948b>zYwabmM-viq27t zMdOd-!uq9~kO^;Oqa4p&kJ-)R@V%HV{Lt9Ump>LuxHxZ3#(Wq)C)+y7vw zo_)Fp`4EDMq+Ge3&a-?wYtU!m=7B`Hj2)}Sximu4bW*NHMsdwayhtJ~<4JLJB~+cs zewn*7bf72p%gsBUCvr`S%QW~D9fDUI^2gt#2~&vuxA~ozJGowlZ>rPHGi*Q+^QPW zZRv+~SKYQ;ksTNGA_F~+M5$W^aNSJ8BAKjIAxA6t&R^9jc-VlfJOXffyzv)Og=Oh9TnSCu$+M8)O_UQ~PZAQSAuD+1Mwj=^V4rqc8$M`C4xD`ProA6t z-^rtHKYdFu`(U4#<6Fe#LobE#D>eW&A8M3UB+x8dsPVCyFIUo+99K-ImrS3Qn@^I- zAZjN^@+Y17c*vr`nQL($3G}!QNVs>|@9qDPeI(=j`_`3)k$bcPD-(IQZbDvT7&YPM z$Cukaa8x=p(jLL%r+sCZvarLtPpCoOXf%VkUF{=QuF?_By}D$IoLh;(&cJ`~H*tzM zTcB~J)p4`wO(HBP@N@5r{La#GNf;v>l2we1+sR z{#D8@)k#blrcum7a{WO_On91~u9d;6MPjlK`P>K(mmsHatE;(WVTXNXE>Y;StdnvY)PCXh zQIxuyj+~GGOa4F=^PSEQtNFDS$e?vP>3WQ%{l;UXN4INo3q$1^Kl&8oJqu!}!h*;4 z1e^v#-p{+9+8^^f`O|v=#868zjve!h_W2BAs9qzVZyEpaSphNBeV8k6&c^z#wRiM> zFt`-^*6hI7{;2NN!Q%;4A+J9LCv#0+8#(jaxk#9`7xQ)Oc%twnJxs&1W@h+z=@8kwGhnmP8u=Z5f{l$`O~M(v*I z&mD?XnoI8BXv=%ZOq9GV8L_vaKOh_|qA$3wS?)Uih>bcZYb6-I88a{ez)mhHI`0 z=FjjvWZz0!JK5f*B}_SBRbQY~=M;5;aU8BYbz7{%0vp#2=NtzyRBih|80vNYCu=_@ z-WeYS_dQ>{&d&dSlWRwqHrKgnlufiJt}-me=$AToRP=z7^p{whiO?{&&jWo%*Ukld zhYPA6L5`_S!5(5H-$5 znk&qnM1~)n4__HFiGum1a#((lm?h`TLq+K7o?A2`t{P((s z6-O-r?)?@Owb2zItuDbP@x`#=xyp2e*?iyV1e+$sqH!q$oP$QMH{S8ZH(^Z@R#JWS z_~(J2p|WmI=~YRE1UZW+8MGj;3;IGTfVPM>h3m>Dedm)?(jDjB+_gmezB3&0MKtkH zY{omk3bz;Pge?g*N&YJq4N9odG$0z3P+`K%e@LjwXd1xkt_e#7WNCtdFqJR{51I~4 zQ$^Fd099Td)x?rLiGAFCLaV?>jXq_j8ZQ%gbOMSG>3yDweZieM@j^geGh?XF;6SuF25Uus%z zqAa@Gp|HC^;u5#e`SmRZb@f^SO|_RsL0H-i(v0cH)COs)bh>e(CmDev(SAFF3~Hi~ zBwFGZ;GAim#;8}ErixG!J!hz5&M@U@SOt(KWSl5vm+09?z3m0Xjar|pfhu_>$~QFci(a31m?H`d`6Kc0Dorw9wkbqTTF*5;~y;had#o4Cw~i>DnYiPAwdiP#;l+ zM;x%mL|&0-A>G=F_>VT@L|PpMF3~`%BSN>IPLhbur*235043D4T*b899dS2jKnZn- zSByb>Eei*Fa%KR#B8e>twNNqXGciMmx+S67IHIj<5uk+HcuVC{gDE{Nm#mgH3QDMX zCOqqWCp57>|Bz6j@C_?r)igmo8U!gtRn09SIwHio>m^pmK&TZ!SEP`viF6!`Y#qoD z1u<0H5g$c#Q((TxUl=NrCO?ffBf*rI7-8ydJcyyn()c~0sRY`Q+IvS<^Gb+`g2Z&C zr3>dE0wPNgC5F9UZN^tW?6-Y)I9I~^YY05XENG}DmN;cO-jHRanu7}~5}-iiYr#4D zU1^K7N0g!SO!&k{$T%DHP$BfRq{m?@n}H9=%)c>I_N{M2)EOd;JjPdYkC%taD_6q1 z4dB&=uxIeV`E}kZa@q%X>rJMrms`47mSEf=&hlA7Ga6X>~8ma136zIBGb;+VbE)} zy%*;1sx-(edct^FXr86CFuL{NfJ_ORHcY2gHGl>w%p_!c#t=q%i64pIg&e)DeAG1= z=&xaLs*}7gjro^7^-kjjWQ?bw_vaxV6X|b$-5Ft6&^@s-r8}NUT3&_iq2u@P1v>Qy zJ$O`-w8sJq=59t=VnVFa@Jm#YhI=Dp z=T!}`ruNvo*IeuR9w&o|?&zdi2Kf2SK0`*ki|x6~#+i<0>HDB(E-8+4(w^56Xtl<2 zJf7H_dGKTaYiUfEw?$YH_&fcfV}~Gs7WiP!>oDGV2JeC`nTe)d(a2bfbmQ3N7M-{H zZk(8COn-dwsh3pidNkh;7T+(>L*0cyn;-_KA=k$CiKyl{kkfFZ&X*;(Bd49gFKpko zr@U5aiA0z{*!~Nfg1facWD(E&=IYWL(o`Tc(8&r&t}%>FlxGVoxTW3xMZIS3HMq3@ z-0XN2+b&ECyT1mWr|xm$=$*K7-RL=^CdQVET1!njQ$um?jB1p;r??2D|DaI zR4tlTJB|szOslnhjPrcH#uzOeh44dk(u&6MeUOhp4kt4^XQkCMd5BsAlBk<@Uje>v z(HY8MJwT0#SM`IgLi^&)u@W93a!b+vZ+zD1>ouPs)$VD6gtWVxd?l0kIwki;DS1#u zy{d_w3lO;IlXr;+8c0S9ExnR+g(^~Dk`)HE-o445FF=Y-CHe8VrOn;w2i?2MPV7pP z9;Z#@1L!AeIUk)a(|M5^8YF6<3q}s9k0D{ci{fg&c zsa4wJuQM0c`N*SWi=_hiKD0=u*>wr@`*>dqf;?Fcy(*F4<2J|=L?;r{1|9PB9_-H= zMdvJ`8F)-S5mV@lQRYxE#Z*iw6I0H{Y;P}U=gFv^e*>0|)OYT%cqe9gnA)eB_0T!% zNp#jw3C`AV4?HFP!Ftvxfv29BeY+&^DTU|xw8sRKr@xQq*&p~>djnAy1Vca#AL5JVdX$Y+!=m#T_Zt{t!wjC` zCw!PZ9s+;e-Xm@P@BhU>-N=(QNqhwrP&Uq2ga+Qw3_K5Lsx`VMzY4}qP4gHG-?lQn=)ZKNr?(m zn1&1Zo`>c{=r*#+Rf=*y#9$im|rr5ecO!kK%+4UD+UCbfGoe%LI}6W(z==(sMmqzIG#Y<2&BrvY|EPbxt*R=N z`8=bxsvLWrh|MJ4^g;)}VTDL=gJA%dkk}?>Y|EAA3pSFX+y)U2EjM?g#TIo8QY+Y3 ze$tnI4&2H3~kCBg7m${y*d;3-Xcca zD11a_$r@Bq&ny$FmJc?CccmNZzh}GIqkltXq4LZf(aH!{rbdJ;I$suR3gwP@*0Ugc z16$3nUhVxvj}q`pYf)xfd8@ikg6h-FYDn5n98y3ta7nhGjuq7nonMk0NE1+Ty%e}C ze>+RuDB|P%vcgbeF;JZtu;_6$@O5Y1-6LO=?v-r&TK8s6YyZ^)?UZWR$>G_mEmW28 z7pjUrHL91CvIpt$E84a?)pE4jDpz2N<4jMsR6V1M)5ks=s^Wp0gFPP9Bx!REBuA~E zk|HgLIW!L?Ip2~|Lu8Bl0am#_NQp^PvOK=#O^WmGDW5-*WSm3lH{&bmYrbDt3-ZjXq+(i#57 zAO<={Q;y3;d{vI%Z~d#izA03`RlTD3#}5rwAJ(g^LTu!AbtQ4Rv^=e+h%he@zwVx# zE$vO4&(!fXcmq6Yzu?J#!eopjW7lBJ;E&Pl5{b4F7$A|9=lzr$;x~oIDKSFUTt)Ee z?rD;5dWbXUEKJnR$`^hTbJ)TGSSAj*eI!+!g{EHDNJ7dCEV86xf9VX#J=qr;D)IR2 zCG)!}of7FnoBUkd8UXZwK>RsYzcAO1qWK!#e$B59Q6E}T_wy?8KSw+6va-bLIr|mY zBh9y4Vl{z28?>WSl*Kb#B!-Jy=T~?#s(vq~ktBC63?`It$p=P?=HJDb480x?n}QGf z=%0@zxAfx@j8XhTi}G$!FOJ_a*MFV%x}szB1m9feth`r($-B}JUV-6g`OK>$38sq? z-to>P9k{f2{2=ajTZz{B7i)c~9~$`l6J=Zgf1%5WcqUyY-qVl#%tci3t8nWc9U?q# zFqu=>@3!P}DE3!n#wpT=+ijb19q%hQ*QNyN*FWEJ_>w9RP%zPEF`4>$Gy1jQ+>P~D z#kt4U!~1TU{NDWe`^-Djs7nP(8j<&d_l0zFvAJ|vG~PH_#BUX#pgL4p=Ag)3=~^~A zf|VrwOBQWuT!wkqn25Z`OfppM7rx3$){dKj+pTxOe8U3HB+BugXt*V{LQK_FWL7#w z-;x$+NweNAFJQiQ3tN9FrN)vXa9(v#&9xbhgaQKU2M9^0*~OCgc$Qt}!`-prRk2^+aaRE!fWa5!ob7e-dxd9V=bV zN>=no2L6q49*{uKKXz3yhzusWy`g!yQAHJV%!rfW)x!GPSq1ae+bX_@0?BZtWQv%$ z0=W+%S$;t4czUyU%u3;nUv=m`T`K1G0`i1Wh}U5zEkGa{Dnop}7Ck^yKqzUCOAP50 zbUE_q3nJfp^>>Kq!ZjRsW5?w3F*TzV1HV4=bvaA|l^dynho7ju2t91}TI|Zs)r;}5 z1aRiBpIGz3RR^x7N{YqYOV%Bu^=H{BR-^eZ&h6I5%>yc>DWV;LRP4MR3Ac0}pYiUv z_JKovxZCwRk`?{%|1STG|A^xM6w#2!nGiYxBkt1)Xvc7#GRO7JH`HZ zGHB-{Cx=%f)rRdv3Khz_n>ScUG(Ei>{JDBWzMd@8PZRX4Lx-3_dl)QKbZ`?o27r=& zgx&982Z>9s-G}=Sa#on7Pu5)1 zaUeC@KfM%u_G0B`=$)S6KKEmf{o*&8jkMGxazrBf_2lT6d4mYT^>AWDcu;D zYW9kBIeXIm9CP`s*-MNYxzFw#Y1`0Ash7I!kK{}%nX(6H( z!zvR__E?=Oq%6_rGF)~Dnepb})BbicZO?m!`&<@Ik%OK64P+DMs4N%n)T=9lzupt{CLILXnW{Q|ed^MvZwxL@i)I|r0=3aEWC{5Zh< zY7A50GePg-@ck3b1nlwHYMKUjz=ZyWTJw)1G*!; zIQk8CPu}h*dL}Q^peED6Ow6=i#Okxz!kX7;itDtKnw&Ka3#U)1ZdWElUgIuU9Cl9r zP~p^x+VELQDQ@F!{qeMAO{&RVYWFlIH~LLMm1Q*Q#;?BIxEBep+b-De+)VDCdbc*z zptJsVR6k1gF>SHyjn_Fd@hPq52~HNK-80YZ78p&dOtGRO;Zn$1XJAfJc^J&iXzQ>hyA~KSV?J z>|yLc7`^vBKJ!2>dX=u&D|;x46{_TVDn*mVr{>J*!_`9SXq_kd7R*SvmF85{IdddD zB1DM7hUp%W>hk_=I=hdshN|3@4UsuEsqr{EX}ho7qXp~@TZ4x~dKA7{KXxp0^mG65 z-o^Bt<|xr^{9SjH&i%4zcjnf85K(ze>x1|E)|X<*wQYe25Bz8?v-si50xXsl)dO-??196Og1S_3)^0oKDx>AYUoORpPO4{|HYD2JKD?FI%tDh zjw792+MUGM(Ohq1&XH*Nk(M=$ICipk3q8%EdfoSS=yh{k-nZ+eo0FXI?hQAYI0(-) z8n;Bd1+u5}V{mO@VZ<~?faso&1(B%~5|$XnS;$pED1VGxZ9ug1QNcSK8()dLZwbT96%96yfWhga_vjH9C-@*}K+o5;aPs z!fXd!_D#hJ%X=lvG0yltT`~A*9i#58r}TN!(%WC1O4rAgoJ`&pX(8N15Wz})`|8-z zvZ6MLuQIcxDQiP}Pt_gH$+C;##gp&es2ypTvq(O@IYDHMC~}&QC)G;e0@#tVJ5$AaPzycHCl<%{;>Xc0i7AgZ%pv1 zAI3}b`RP)HR`2-hQoTSuhyPVT%$vh!k6ejUayZ7fI(7IwPq~axdCUfHn_7A3ZQdSP zueJc5Sc@0Ub}#Bj#TVyiT9wM%2KTgn6Hie0n(92#A{KZ?em-vhi%U<%OL|H>3Ju~IVp#8dDZf+reukzEvB5FiU@CH0wK7j zexc{v2Y|c)ECCWkDi1RVvQXQ2vKxY_5-ccbI_PR*(A67*64WN%PN+Z(TVfg@ff%ah#jb??*LH+lxXNztR%^S_ zsGfiET8dh4jXH_G*!6BPy-uS|0Kvy1F`ogX$fj$q3&4;@Sw6L2J=8e9>Bf%G5iNE5 z?!5B}Q2cHL*`|B1Lb^@?5^?IdDTqYj;-}FM51h0t>oj_E z8m0CxNKl&U6E5}WLeP=w6`$D`;soklwI+YKUaQx7VK_AjVyMkc1I--O!1lnYSC@x+ zwO)PxboRp*hMK;iHO<=`iP4_n$#w8>HJuLd;TD2G0F}TSoCY}M z-9~``DjNebsM)*nz?Lnx?&o)e&sJgV@^1M*`YFjanrmLSFF%qbHUtTA>(d{%2r`B$ z&_9YhShb=@XG zy#hb7xaL~?2HE)1bm)7^m!Lq1oMNINhe#8|SwKXgzt(bPiTzPQybx|ylMu^BG7Oe9 z05d}HjzT5%SzyEATWjKXrzK(Q&-R7`$Z3FY6~Z^o?qINaSJ~xPp{S1#2^JNjsB@>D zcRgcUtM+oWI6^>Uxm#DS970)PfKELSjjeS&c{50>Z0Met$AQ5hmx)=0@~$6KH}B?0G|)03y-Y z$w_wo3(1%y3)0{EG{GLKzs@#P4`d!`@hlMFr#1^vl+^T&tBN8p%m_gOFNzX@x=uY@ zy98N8ak!)C+_}~`Ju=@YiSOL8g#{Mkw`$HBtJ_W+e}x85y3(l&;l0;q_=JWE{3=e> zTmMYO^r)?Cw`>?LnMw>8rJk4oB~#2R1vE+g|AW2z z4r(%9_eGyZ2q8e|T|%!)=v8<_lWssdmVkmFEueJNB!nV0bOh8;MT&%u6b(f|L`6YG z6b*_B3QAQJ#T#9Ft-JT^eebMu=KOiS^G@bXCX-BNl1cLWJqb4d%-kJI+b9a5ra;D|xXZ>^v6*)S{_ZKWGo zf_ra&2Dz;-J`;?q0imo0+0ThPv8juP@L&eNG`z7wXs*?5u3p#W%NfH;Ew|1n1t2wU^XmE7x)u3xOVOc`*xkAzMNn;_hcl zsE|0zPJ08m2U|jAL#Vrx06&xDEYFruNr-xqH#bsH2+WnmL;_zBg?gDKdR!{0DOW&T zYzfuP{^%5weK$^(L2d@q6Z#d$rEd{Ok~CcPlaH};)v0z}*89C`@e;)I0yM10_7IR6UJ zZj6(?xp`5J?DAGJFCg$l6NJ zG~BWEKr|V$mvs6XIZ!Ht5mH#M1wFxjLvsB(SB)MD^i^Ajis;dia@5LK=jSsxRZ#Ac zH$}X5RLJm<2j^iU=`%Xe>5a@|4B>+BTiUmWt8WHot`HjFA{cQiTWFN_LeD4xdsZ1-v05+vCjy~lp#(_EOrT+SG)v3=VX z#6iA$vr#|`rA6u`iL3N0Kq8HNAnqULxg*2g(&Sr8-n*Rx+I~<0pWZ;-BbPrW%Su`B zD^TQg$##+u?kwWOmvEdYtoqYuoJ=q0ViLX2WYZ)92Rd8(;lQJi&n_P}`I|OnNvpHn zznW`0cD`JJ_Ef`g0Y~5UL-iuO&Z_Fh0%RC;jgjYH!geMSMNs`Hv!vS%dJU_2-BB zikoMX*yFJ>is}3q1ysmBh5Dn(5oe`5NfxKNzYpl3YW@Z)0WuVyI}V1b>e7d_xPl z3aaruLWvNkB8$2tH=b&=m`-l|PZ(-m;n-gcRik4z(cZtD06LR=?c#ctl~!(b&Q;JDVSnpMX`*uvn0)1?)W9lC{8FITL8P z*v0CfVL@b1Rd05)Qr|kI&IV2aaBZSshS3KBinB4bzWur?AB&1M`v(hp^nS!md~|Ov zSmcgLy~S@KA5Apw;v}CZjDOddFK^vYrHaPyy!wDkK;KaI!ahDfD`UQV(jiqTy%T_Z z&Se&fO9G9QtxurbsZV`3yNIU&a;Ejg*8k6=!8x&`Xmzc5rkObIHa zsqKNigMC+hVdlQR)yJ7?Oh|I_9}Ja@9a>;%ap>|#p|s%>LKk@j(G89{2CqnW7YYv5 z$)`v;^JX0o@IoKr)na3)WYNDED(?|D{n>HEJav{){4WeO{a+ZW_aiojnrY9*P;Zow zHy-=8415#tS#__yW2wN#Q2kas)4hNbYz$Rv6=3o|2L52EFBu!V5)Gyb$`U^$IqI0V zZ4dKanIWYr2iC{Jl@1f=2njbdnJQOG;E|p26szPY)wlKM60!1{PoLg$QlXv;`}s|| z7Kq7Wuzwi-!BBIL{%DX3&-Yi+JgRAmGTN? z2IR%WB`57U(XzadJ?VMn?6*j)%I}K=ZB@eX_EV-9m4QL$$&d7lS?d-5#ZZSryJFZF zYMq|N43GFt3=~xuCZR|LL!YKLbm3|-OMWg*%QouNIE=3mzy0e!80uI!5$%HegQ3Q& z)*xQn{Rf7+$}#R;_7_8C1wx&$yH>ohV>hl)Lk>$n2XO{5sR|t+s2w266-0w6VdoJL z3xrr=6m{QV9+xc%970J$3vWB9fCMvmW-#q~9l;4Hx(l-W7j0$TBm57xd3~*eiDnOp1_SQ1G=YIR^Bb3h$2O~c*Op_Uh74tu<&*^rT9v| zy?Y@0yLP!~Jy>%2Tk0MrwH$GJNZ=A-{IJ$gs#`Ebk53j6(^YWg*X9RvaDs4zv1>_Q z(_=$*aeT_Y!b+a##a&C;vN7^|*OE6iHQ(gQT(ZLptEIPsY?L$h+xm1Q-uk&{=Thcc zbiJ^)>u1IYQS~u#U7%8|8HsSj_ZNRIyt;pD>EL&9SK`sEnuY#xb#j?o?Y^RGPSK@! zZl7tYt0KEY3?+GHRXhC-i%<9TN6$eCk5&P$2I1NzYbS{!6lwW{@t6wgI^llnUktS| z|LCdxl(H>)P&1Mj0u_^92FS5&43)ophW@@YPe^*n+o7RWOV+)$sB<|$D{-vNtg9uj z7U}W^B<7_b0QX=e%hV7p)ECK}&DMb)Sqx5sEDWB2o!~57f6&oxb18%KrD$2*Ki7##`+_d9V5*bNI?V!<{S`=A z*K~^$*RdR8O_-kDzb-1L1ob~$R0c(Og5@@;M%hy)d4xl=bWk85)G@!G7LnjA=6 z3ZYskyzQYP#-1+5c1k(3XD&30x56tBDdvWeu!Na({@uxa1;p)}310lrANNS&i-V2) z7r+!rsS~n%H~gj))lM|~7MVR7Y_@QL$ehr~gFYmwDhKTiX(6H2j~U%V&0w{Qh$;L> z{rJve+lg9H$8KveVJb+R%uhV*(5~U2RoBL)wI*SC2eG?{nvpJ9yHVIn^$TwrR2mT>avDv{pQHF9DfI_VOQxs+NuvUNTT6x(W2otcy*TBi=WT2ZHSEC5 z^V$_QhI;9n@Y{+~mn7^YN*zmt{@UMYTbb$6>ZBIc<{ zac|3qvtI{g&ZT-E`}xk`eEt|4Lv8teVCm%Voq2QN-EX5;cDKIld<{rgxW)Z?_gDAt zpT9IgZ}~tR4A7HY5DykS%m)@`fUo6(rLmB5K8PX%av>M87YjYj2i0RhkLN=7V_^sQ zVAc$nRxZ1ZkVA%#!=1swk;`!e3*X>{2Qc7sIdC?HdYAVPhT56Kc@~SX<3*$}5cAoH zY%JFmp5JnzPgb4T5-R6K^zv6tWHWx5wu}w2N;`mw3hzd-!~a39Zl4cmbIG? zQO{R5CK)@^G}H?s?~PTStq9Z-mT#qrdyByr{E+v16Y>`kU7g9t#!wT-(fpD8p7#9W zYy4zB^d&r6wpCzhoPV#DpbSz_kBy-UX9(`s658PsvThaXyddPHB~0cLc5f9venI$% zmWVKyNIc1iUd}mw5eqRvH))LQ#{gF_Usp6NkB(@v{ zs#myb*ChHbNPNl`Xl<1|=^}YBM{*!iDuQ3?YL3`lE$LcLi6^bnvJ~k#tv&NvdtOBD zS<;eTS=%$JC9~Bk`Mp)9WlaXGEx{4RZji+AXp8e}%VtK(inobMugjj+l2dFGQEihu zz9y&DCaf1Ff2dV{f140aTfs6?!LCivXvwNXU<=(1F-ec~fDAi7e>ZQlXN^P}DqS`fWuI6>MOssmR zHsVH`dg7}3pf>02D2)(?#(i!0BkjGu#J$h8Ip)^)I$-y`(}pdz?K4^3x26rd`*ly@HbJr*)pU=GM-^ z$%k~(4jE(?tmg!VVgF!+6SUL)Z#l1w5}f@pHWXaV>{4ho2{#nr)zgN z%I@N(#-&ZWC))P49eb~J*w3%qx1QP8dB$O-&0#=Sb5Pgudz9ndP0jn8jvP8pPdcz% zZi2HNoO<(4Z{0XQ=vw*m@rEFsKTX5G2-R8X@{In4QGZOs|H7#Fjl%l%dHP=%701R?D$5z5*jWi5}$c`ujBxu;K{$3eoEpLlwA zx(qMvz3Jzb`DCBlJm0!I>^FOBM%L%*mgJ&u2wd5htJ4gnmiY!1e6mo1}8 zd_8XY)cu&Aly#>+8%A~fuP`d(4~+V6W2j%l*YqQ{Vj{kGMf~yzZ}$*v`WK8k7!Wq- zIqV)-P#oAeBCZxA8cr4=;7+=bg=##6>O_Q0|4j_lAT~NSHoiOd?6+95L0o*vX`T`x zbcry5{b&kwBctbx{%Be;Y#$+fI!%OpA_7 zi|<8qdIa#pr; z)(msEW^x+i(rf>~sOjEC{uKtnP?3Fast#ZBijo%-llm@-`S&qY?;Ax&z8Co!6$iu@ zAAg<)H4-0+rsb8A<)6|@45iWW1mWl6=@;`N|7{HQc6`O%8x{AzS3EMh^zcUM1tSR{ zrsQE&$=Ub|ujNWpyz}P%eGIj?YVVIKE#qpvglePNORe+OY&Q7K^Fu{(m#u6Y2ZP_FRXDL#yswpQX2_bfDJHh5_OTBP>(~dLg zuukl->+5jZ={VTO;7(+Cn-JW0I{i$#0usA|`?|t*x*|=wqZ7O1`?}BWbdybbQWASE z^z~%#^yK{uL-p4%W&a7I3W5I5!l+70iYotvQ8oAN)7I9~(b4{^qUsqK85o%uo0^%J z1Ex63{gzhdR@N3)Ha2V$)y~n;*6E<_LA-;jn}eGN-rd8?P%Cr_OZ2#pI2iwX)mbt)`4H0)$V zWXPGA(Ab1C2}$v1&n1w^ag>y})C*A=w1}Ldu>A5f#g`K+YSKzC(Mn1Sii!)_DJUqU z<(FQ_rIWLoqSHDp|0*~ zO-)T@RVAH%nO<3OwJxW-Eqb8m)We&BvqQ(H#sbEtLPwv6-JLr<{w8K(A@0G4goles zlS^mW$DM_=OA~Du21iqw6KO+}S@&jXkKYzP|5Ws1rTFFNlDRMJqwK|U^Yk3^!K1qm z9z1;fcxrm;>C>mPfAiwMW^Qhd#bV9>PkHm^&BDUMyMN~Wf6a#vAC{JuK7Rc8>A&Uk z-+cLJ*8f{J{$_J?b8Cxz{K?n<-)wJhfB%2OKL5|h_a8rg?EKBof94-o|8@C~oBuP0 z`k&ALJ9_$mVbo-98R!0c<}R-`MytS?zGed7yXe(@cBFhp#hDV{O_07es_0F3;?+LGGjy}WVv-rsd2e&LjTip`=pKfO2@QE$V%r-VB<>H z%a~6q-K?m-PkVbB}t;r^YH1 zCK|drh)`}?9YPr_uMVRRXsnG0d4{gt7CYIrc1J39d2LkslL`0UE?OUV@5ioFC(VT3 zZD0)6jSEoN8?X8_)f?-pHdIZ&EpI#oIQMQ&T8V~jKC)GA-hAw6u(COYKd^Ue+RZa; z>xtLN=B=lPV^_AG`F?5|S8HO*ao>FhDcIL|{pP2(rj7rAQO8xQsgUvAR~4Hp-(HhA z_ieMNqT$=~>B`r)-((ql-hN9vu7|gYB8o&YZitc%MtDWHbEkmtse`pQ|IH5kJ?)lv{qTPZ)gpxiNV_ z^VjCIXT-0qnUgK-GS%2GzrL~3Gi-^$x(T3WNXFhXl<3gJIZOYO3VzFPM7obtx!Eh^dw#5@?E1KKALJeMM^Ju3Xu$XPWC%650{eb)0!m+9QjgGfDyWkyWY*o)0?nZ9Ed z!j&vQ$@A{GNAG$OBdeCr2#s_fdn0m-Ag^DyeMfCP>pa7dL*<0sgulc_>6oLEA}%t+ z;c#~>DH9NL{{cp2a`&=f)R=jWKQL+xChhVMH(rxT0HR4u&XUlpHW&;32aNjU{}V>N z=E_}9zEakC)k2TOku&}@D`)E(QMd{nZ`pkWYOjsy&p;eAR zv>Hlcjoa}sxWm;jS;AJ0s$gXy;vhzlFJ`2>18-nKEGrd%Ca6z)XwL&|@)37DS`dqY zWujBnCNXZZL<%C8a9fW01Cl6JLds~6-xgLnC> z$Y2-+BXNKULV8rf;I{LkCKZr<%iPHk^=G6;*1oJqfk9Lb zu}Osf2|6?r1BLptQ2Lu# z1#V7|kUSL3+r_6mKdTCTn*B<#Da@$#9Xvt2i9@R0`+m~yUD+6zhViQibG*+&9W2*UjnF_`!( zb154F*n!8z&_u4qSEoh|KC`5T3~cu^E8bL)4$vEgl6W`4$V-o{&5fb?pEv8&%fOig z6KE_^Lq9JEHi%so(19Zi|yGzemSzk7q=3M9uR+(v;FEA@iT)bo^W7yF5pTM zx%XXSg!t+UCU-1pB>Q{j*;`ILh_^W~E3yW#%M63qgI^ZNupTCxZBDdb+Q|6Y-=9a! z6g@3=cmHQ*or^iMNz#-DIs)iAhwuD=5XT%nG8~JJJ(+Z2 zD>OR*$gMq^9{?0?9W5y$y>x>u(czk`!(Et2HjjFM2v)~(+fJT-;~9@4##|JbGFYBHP6shykp<&X+y)pBe?xn1lyd zu2c^{I*BWjKmge$o-9cbISCIXaW_mRM2ls@tx`wzeS?Ccv}(NwDTj>R$$7$Q*(Ky+ z>$EnnEVB`K|H-Uz+sx>aP_NY3(Gp)oEgtm*;1hNc+)6^8ak1%i8Q;zZs9CJ->($j&FK$+Prdjg3x@Wsh_=azsBVj!g2%Sa&8~U-QLaxiPMhPDoCM}24E>Ge{o|HIFWGPFrBv#reU%@*cwVHP_h_)M) zukk#e>q7p|xZO;-rF>oQg0F~z_4GXT-~!X<1z)^E2R$=+RSO<17TClW4x|-uXyu|W z6gqz|l)7378!Xh}D)NXg8dEHS;)<*<6dnCuQsVR6V( zag>P7LtFsl5*MU%fUs+d(-)?XNvucqw$Qdyf(c{`#I)st(qR8nA9 z-ha1@aie@dyrS}Z`H*+T&EWC?FIs+Z#e{0v$ny&4EwBQHI4OSc;azJC9jd*{v^1l0 z7`?ZYorI&=Tq=m;;H0(8B<$@CPkkom3-3!$FH~5>=k4F#F+%*)WZ}NM?5Q*S)Y?5(wH^`{aSebjlQWtIO(H;d_37Ei8l3!$agqSkma-HBZ7I6sMN%&W5U|NFW zPKR64a26!Qc^X&)#GwJeoJo+Si*@+P>fz{0m-K6OBc{ae@pBF$(g zB|thds;$wLr!o*64IBh?Ct(%JW=iquodi4tAhEAxsTPRd5V*ba;i*TCgK6sJx(Lc%>@UD#SUB> z1GR8~?D6H)#X#lkIpZ_CqcagUc$l+#=a59F_$t&TvkAY$Az<3ci-P+QATHc6W#V91 zF`&$VIAD2#LSh0XxwHTn(zsQ41eVUI;m<%gVY-8i8}aDjaFyHt)ljxVU!N6_73nVc$;mfF2>`rF+$pAeXgb_TpHL4K;`*p@-b{Iu`=w2~Qnqh2wAX1|ZyXn7AcW=7y-uVX3eG?!#V+0ciibHJ0Q7#KVD84-k934vYpi{*8WCn;4HFW97{tMtcR(6p zJ_m@fy;#POZ!LV+4R*tK?tbITIMc(@bO^hWxyECftK*8MT7yHF<1=ntvGLs`8mBG* zSug>P``moU`4okD3b%R+TX?0({aRBEqB(wF0@I<#V0zWgKzr;h#J0_&I{4BPkeJ}Aj=F8 z$KG{eJ(8l0$zt5lW-#*)^;6? zl|powja%=&fSu^|dGOAj^{%Fz5pf-?0?a`Z-^1KsrxO6bqkzTUX)EcwJkyu8S@)72 zOk)hLU@l%1Dun727N2KwN-*wuWG^OxAacEnW?`JFAwGJ9#qIk`0_G4QK1e~uE>sTl zDhYs8PJl%xFUR2_abb&0GobbX$VDA;un{cEg1X$>Xy%2toNIc}#QrklNX!9b&wWw| zf5SHoPTlRUJOYg6Aar?q^eXo~-ag%Mz#I<7sOKGoe{^nVV131rM znrnYoU46)@jAb1@#d$3Y(pSORH^F&y4w3>O-d}j8`@6a>=i~i}PGFbOX)d!VPVDr` z{03jR-#2Lz;MwJH>l2RxgbE;1Z$2-(wCwQ^6e_XBt6JvLw-YBI#)7}w7!PxBt1h8exZhdwz!ZgX7Ar&DRnQ@~hh+2FHxUUsoya z1aLo9buJjHngNeG?=d#f$Br?Eb1q3Kls+XGSIBDgc9N;?i^-A&hsCV~7 zL#JD-ldYzTm7`_`p$9gsR49mFvUdsGrJ_88B>q73M z9_#2gJQY2ryFTTCCFnZY4j-8ki%Ox`UT~F9&%%PJi^E7OJSqkaNeOiWA`E}w5pNq->m29qjJam*ph=h~Z%lN($_TmM`*MWa`4&hp3p;Gcb1%7Wv)+==>~j#= z-M9H;GujHKx`wxUC8%zOJ0q>|$T!zo-#efrpvzlpzmtxezTLn*H={$%Q{IjHXtJEf ztMqE^u&@+7S|v*n5407E#h_J!Bn*zmf2i#~n%GAbnbtc{`_<{D^QA*i5;>K62+4dl zhJGnL4?LY*cAk8C9kO&d+AmY{j^XiagZDFUQfuFp_=LFB_8c!bXk!#m04Z z=Cz@nNL&-2EsGv-Dfa!1lUL5~?ykQ}lig#)3cX#{;Yu$F>)PH+c3vvO(V9$H(hR1J%UZ)(k(S z?sU(ae$@%m{;wMo5^u8Ll0M`twAd;uU2ob;?k>+ndL>oyG4}X=_+dJPM|T$gDq|+` z?4yh)c|CI(3JIRc+0sUw=1FTtUk{&{Yz{Btt#^)CL&@R2{L-bZv6Z`m=dNDXKtI60 zqN^9zUl3|qg$PNt;D#+J61)B&ieA%I*a=$*5|4(ydvp*HIQE(wQx6eiRPyX?9TJ`; z!uSv4L*M>^QG;66n^%&;pbiL@zTt=q2ggVw5}r>?6(lG^&0+qQBrz+v0-0xzKM65` zr^zzrwNQ&7-n0YoxK_XYTG(N(qQ?*vGLpwLC>=4z#^!7f#t-kj`U|7ZHl&3Ac(K52 zgVx*DsvQ7^1+PX8>U!LUwI*K@Lj4Dfs=*7*nM|#=oks2tm@3Eyeh0@R65_+Zi zX}3g0mDCCi-aaakk1s^W(UlC{kcbRYzd9%rd^zcnfOHjAuTYDN7iam~>ko{oqj7zL zTjMVKPjc%Q*#j78rj$QKS7WfycgUY>3XlLhb7Z?e2ce{b9YT2p%HaI927{{3r}d{R z`JxfV4qFyXm+NquQnxFoyo)5)*JWi0!$MK-6?tps5ut__mZ<vcp1<6C zamck+{kxq*edEwa_!wvbtQ~*Y)!$k2ai3m|AJS6A#aogBQRo2k1T!H0s3Gf__(HH6 z8xZ5U2TjD&U#uOtGo-`iaK*kJwN%<1@ zf_rZJ>9d;?mo#H;RZ%{NrQEtPfkZZSr^=6Q+~l+&K3wNMdYwv03j?jXOC`Y(C*Q$N zdJVyz;8PNnW`Q`Wi)1w_VbShKM1K%JFVcTk;@P&poK1uWVZy&@ z+3>a-7g>C)G*8tH*QRe1m4CLc_@GhfsrQN3&)ph2-i*JYra7quy-uRY*W>OUgKzW` zv!2KtyFKnUST#c+QN_wDhy7AdS9t5aZ>@Mf5#WIoDOcq$wXnywr9vio0cl?FgtzKhP!gu|0E9r z*TL)8*(mLrq9Fmhch)NUdh{=0_gD_tmgSJd#}9fMm%(>X+nrpL{mZFBJ2RpWuqgeX zAC7pwm_4+l=b6g#(#d+9A5xlYe`6)=9cf1vVgn`fB!$K7c9(;n$Hex(JF6b|@Wrcd z?o+G(uLn zpmCeER`wXjc|-tr4p~XFczJb+7B#4d&Mp?5_!Tp1kHZjni}?`Lm7@p8i}mSL&sf!E z_juoz%Ryh;E6+NfGB+*N1*KbH2N6!&$pDoYo0+ovsspKRDyRLrYNR?~E&Idcx7Xwh zhs3X^7Alv&1KUHT7YLlX#5$Y}A^8>b5>$T-jI?Dyr7^r4yg0K-<=3=%QFBgt9`G9Z za`Ie&6KC;hCH^0l>12jF+KG?McaF7*>SuA9gDf15u1bF^VM5JU!CBVCbr~8;xguB#7ljq%w)}!w;g2$l)0ScnM^s zF{VIpXN?Z!);*@k2}-;xMVSBznPqp!LgW|GaNB_=Z#$lvWIp2-d|sY0-fHwxM{=$l z$pfg>8#YPMil$ac&G8myGhhMGZg1Vp&2HZz^GJkpmgLDY@>N3~fkl#{RD~c3VlkF0 zSD*XPk~&Ywc?(LG!RH$m4hxWYjh1uX(uYMSE#ELQHZgoQ#Pm%9HBf~QjN;}+&^GG% zQf7*N0x+ry)yf6JU6}zQLyqvL?|7lD5CdedLc9z=`Qym9n#x_Y#1;XnER;Vv3Tjf{8*w78Zav%YDHWlgBFT^CB3{98NqR68uN67+c zFD^xd&EW~;V=ZaNe5lZA zi&w$KHCkm|ee#Q8$E%MV(-ukM8QBjOLEhw&M@ggiW_D3#i&-BM(`Q1{m8`R8lSb!E zFU<)_?Z+zC5lawxR)83FqulZ>CMP=-@t(kIEX6B8e_&oX{H!TsE!{5JHn&ha{j05! zg44L&G6^L{HOHoJGng4xRM81OLE1sMm^~ajFcszSoj?LD$vFKQ`38W636mCvUE6Vk zsf5WEDK~Feo?S(T^g>3DDP{kKhAcdV$B?3H@rc)uA|FJ)rNe(GFg{1FF;4;QLlnCCWc*;XP&YSneYc8 zSEfl<>%muv=|lW59GYT*g~dEC62k0<@2-x$B_a&7bC&9JKCRmFW4)5^8`n-weO|uu zm7$b|HkZdxAY22YrcaKCSpJ;MwdHw&6sL}|K-Yzy3#sHm^wLq7Tc7}R8Ub%XM7Rb# zhwC9y07pLo+?7!G;lwA0n`$!Y?r1!v25?c)7Ely}_(Ck&1t@$3pSt@OD-{I-piY`YoPM>#`$|lg*PJXPigeKWQC;ym0wR)S5PWEW@#$V6iy*K!jR}7 zWE|Nes^)Ql`xTWLJa1e+dZys)isu3rfimQMPs^DX^V&;uPTQ_*^zyps#`l%T*Fb<+ z1YO`GLXMCjyfY*()A6kPxx2rZBioZjuFc4T08;S^>ENcjAUa+4F3GE@hA+?C{wM$9Xr%S`w=MQhI>&MBuMSX_Ms4 zah0aCZ&uu~*MGfA=6=mksff~O>Mj?mXF|P=z}tH1!~jyqrPtt8r>k_R@#-zp@QnTM zlLg~E>lx5#EAre#^4vnQL{FUshFan<1&3QD8}jlK9+<-*iwxGC`yi9TVf~o&wV4!$ z9$1-eZmQyZGa77xft~U8n|i{WbeMOvf?1H*AI8F>XoN7`#J2y)%U||9>A6Q_&8=*6 zx(cl?0EpVdh!M%7s+aR}w$o{17xE1+6nb%q#9t^a>-=Ti-2Gy!T_ zg^~ulfn}%k5F>chqd3$PItp?ptMk{}f&09ZXr9N!(Y_SaUBu$kxa^skr?WlTF99jx zMINrT6IZzd-lbc9Ab<{uczvA6Sy{~a;$_z$mb-44>)rJ-?RLgC!XRztooz}LDE`AW z6&lnI{YW=3Esll&^VZg*c}CDY^JoP~9uCbfpv5orh$j5#{RPZXpIUy&L4N6Zei^WU zEEiH9C-4aNNhv;msVHA31~D|0KRooI_R&dSHh?-WXg(-uGdR)+2(@_$DFzFzst$GS zUhEDO?o1Z;t`zRSTXcl%cWGC+4K3n-LyehZF!)|5d`*PNFFLXZcKX7y*n{8}Ldoup zMA5svhT}>rQ#RNso0TUynoj~(o;hnyeKwq_TUpUwxpkclqwX8rV`8pqqUDzy@N{MV zRYiAB{}jzblPmm9;O94~$CDEkv$-n4%qYlRJtsNri%hl1+0%QfrOG#=QUUr z_7ofBb(QGNkQ~zcI45gb^hL*zQjMZI=;6*(Ct zVzKIQh}ec^EyN&9KN=%1YJIPR9P&wySSSASNZwyb$-qR(zg|yWTvzhkNW2kd?)SEV zsd&V7y$KNk$2SXpS>w9`Nv2bzRX2=pZRm-fi4Q(4zUb6Ix*B~Pl+dPZeCr50u1UY= zh}^R;`%jY0PLj;eZ;ncAI>#1&_Bd`fsp4T)WAwY8_6Aprh)}RihF^o|C(Ef$o;Lfo zA$M%c!Q@^^BWefsWrAC^}Qg%ERCQtB|(6!N@%dZy5-otb>i4p z@n>71uM4|9LWajP#B4S6yqfMn6v~E)GvMa!&!Db+ir8wT!|0~@!Q_X#ZItb&UlU({ zRepWr3*<#Jb0y%~=_JuOr^v8)u5I#x?IiVxtmLS3$B3Cm+tiY6JKwlV8$M}QwzE7d zDbKcZ9-cgVYkOmTJ1_Qg#uuN}?5KRt_|Ne8!qM%bw0K%bypi+wmh|mRa5<12Uv&Oc zdAC^aQfS+@=I@U!Y+B^@LVo2lWbH#_-Rt2QD&@!x@dQP0~pEJa4fb zlRugeJ5A>q&F6o-`uM%!VYz^bR=WYB>r01sqE_bEdMhch`y{FFA#%VxvEJajVeyZ$ zZ%A;BOnp!0$78)oziJzm*y%pSp0k5Xzf{W*|YmTa!;{(^-?@y zy7%((^UM1-E;p`fN$>b|^R>xxljYc(4_?3agq(ePlGO8MXYS*7`AMSi?VeeHx_5T^hVd% zirI>xwc00@T`%n~5IH70r?%9dHu-c%t?Yi>QlDY?kLGij{MRMZ_m7)R z{_Bz{qpdQkaIj1PH6x^It7U`IlMurPCk;)c4y6hDTKm1{7?cmgVrfxIJRfxfC60$W zGDhss!A}ufT5St<6s1!l9Tpt#3x`hz%0-V)_c+sJO>Nhhtn^2WvCIQ!jR!QoF3)zK z{_^>k$@c1-mdj3kT`MnoVxGMiZY*gz#-wodDb)w693K@v?kH<}`%S>bC!@@>o_4LS zoWWirfP@`&m6iO!uY-ld2vyDsD~VBkacYJqXaXV38ZR~i@L?+2q&8@hTUHhf#W~c= zy2JN*dCo=d8Y*?ZiQE5UTb_nP8Y$$xD!MA-8$PHgnizef+w<6Y4*ePT@BA=|BdWvY zbpUPafH)2=gPRnD`7NdDs&b||B!csbd=gaaE}rTQ_B?R;YE6RE<1K|G*9V>fXKicNz)*M8 zZGh8t`P;kmD41bgLz6%a87--G8z*sq5ov|9q*YcP*LCrtS#cB*QnO>rr~;Ci+LMnR zJZQF)S4?ci8(TP?IIrW}saE*RdwZx>0xP{Cx5epp3FsU0*)Kjh6-M=H-um@pN0aFv zUv^?Q!7*d@=u!L~14TcFdJ;sS|40x7c?kGWd)_bbJ$5AF+=)Bl1=0sn#pQ%XaFQV- zL<^KhoX`iHU4NVf(w?3t301sCun5Ru2=NC`IU{$_E?Yvozx7p9Nd*s6wne;L4RqQP=n~s5-Vj!7kZc?~-{l56g3@0csVXh2{NIwRy6G!8KI}>+x zp3Lj24DshPs7j`l&W2;=Tl~Bfkd-XzxXQ5jV@8CUnVS;pj5M>Kvgli3~I!G}z>6k!3IzfsEqJW?@G4vv60-+ZJf`Al5Q96Vwh$SE(RgoefsGz8*h$yI_ zK5^%H-@W#J*V=3EGsZb*oN<0wbL0<5M(%l!Ij{SBeXc>VXQYS8l5Fk#Y)L^mp@xSx zNBJ`oC)dPcjJClDt!T#DukmiRuJ$5|d=QPLi1$w!X^JJGQTJR= zAnC{RPn_{7URpV$pMJ~aI&uwpTW*wl6a&g{FQ{zjdZ)J2;KV-?VcJ<+?W#F@HtKLfYNE-OxMYal5CGEEmr-_-0t)G9 zWWXFY#&4fZ%MHceQ1hOjuXXRq5MJlD!@OF??q;Sv_c~fpXd~~bNEcJV5MC*yUJvVTit~ONc6GR}LK29Y z(zXsMkLI7PwbHYU+iWU~UP_@K(rbD@dDdJDI{TEqPq_ z%`_JnwElD;yAYoc*aku5I~C#^=FiO&FrJR#rNd=}LmRgzv@pqn3a!ihSDF2$2NQ%A zm;YKLUCri~*plg3%^sM!U7d?t^=zepO zz_IDto1oW+nCo}XCFnG-eNl*U{md1p5ih=U{jL>C&v~wBk$I}t2S0=y#dmwW;_sXZ zQ<&3x(~g{>qUZ+kN+(I#Q~v551C7{kw%kmbW%HN3_0g_#+V?h7*HA8f<4f;^>2qb`H{{Q~afrNa>=DBlWM>HR<_Myg zDMgKP>C{8W0Pqn~ilEQ5UsoP&E|`t$ZY#+&R=6{(tW^)%Y6e`BxZE05XD8J-%LsNC z8G72Q+4G*1-ucl~F=`Q9`K{;d_*TG$ipKSrx(6Ct?THBu&z1rRCN=Zno&C?Zq;2{R z-;v@aRUK2t3?6#f@;NEn_=RWMXAf;miW<=iZuCZfP~hUpOX;4y+?Nc7C}ZVy>6pFx8d<& zUw$fjE8EG~EEV^kZ78o$wZ^j_Aa2K`F7iW~&QdB7o{U&+b;4&2GTOa}kt_(8g?h=5 z#P6WL4||a|0d=RI9hr%dYP)+N|M2K~e)R$QhjC7sDNhKGnEub{K*YvHtp!9u+(_rW zFLLQ}WC^qHbwkAPnOWiYuX@!38wuCO8{g_xPk0v|k3AASrFAnDq*Q6`A1$26I(z z+FY%FdVI;lYR~q_Vv*OUBM$ad@hCi{Yd&~*$X;^c7@=s!dd=Er{$y<#=)Ba^ zB1veqWua^!%1^p+E%-}S#HTELuebOLKR0PWe0_xfPGGX|iN^`jM!s(lf*)mQ_%BT8I$A-`*;~!_nc1T=1Q%LXacMkBHA4p8km^hJ33I zLC$Dhdm0&cmF=J+e^6Uq%S_IVBqgpu2nz*>d(fZ&ALYDCDCL!Ps1!f32oc9ny?OdK zL(aYa)fPGXh_y(0vv;g_F^q&R+3+(p&xpJu500{1l0BxSoe}-zb?{%O2v%_L=xd#= zB{QoG{L$C0cf1jk0@)=5`1*{sX_hiS%{J%s2Q9d2qrA-rl<~<_07` zEcQ3?53(<;uhzP=Cu}?|ZKYA*II9Ti(`TsCys_Gml7Nntb$iH?3q!QDUexQ2M+c7L z^^=YEb|iW{U9?^aXkQP=A5esk-pIFH`juNFE=X_Koq`szkh1soMOORhhy%k zkGAc1sBa=ms1<9al~qFHl5^LqZfNG+ysj$lB}}ZMmO7Omzt)g>gmI>t??}iX{2cpu zVBFh^H)0_Pr6F%`Ru9~~#+S~gWXa!=Cx%%PS{-%O#;>AIuG!rD5D*Y>Qu*cyCAUJ_ zD}{yNRur>=%4~3N5i9E|JwpjR)g`+e`}Jr;#kKM~p3VERT~ZQ{3?vfITuEXRo7!D^DKF!AorbO75u+Wi~j_g9xK|sY$#C4PQ2>dR?x(JP%SK43X?r1&`v3W~k_O zsN^~ewgHf00a1cO9DY)2nt)zG9h|44c2(={Enk-=GWdyT77#p%FCJ$h=?#(U2P9Wm zaE2;kccFTm!m|#LTAhRj2G?zU=uK)Q&<=nNf}tM41m^pj?(c7&B(kN5jVKnOGY&5` zMH`PH z8$&u0C^haas9F~|GI+MKMQuv`S?jsM294!=Ep=uZxxs8T&VZY-zLw{2KiynwdGWm^ z?Mur`=vEl8brm!TqXS@qn!hny9ux|CPAztiB0RkkOT$ZSA3K%^5HuO!WMc(MSwnv`RANF|$7IzH81f~q{ zYIC8s3B_Njs6{}f853nmzTB$m@;ns12|#s)jyE(s!k ze=AsEs7bi}W7>H*rk!s&?b`;RRH#@;@~<=s?{9$e85YlP7B2u; zc84N-hs9~uf&HfNX5_%Fw|Ivdo#raVSPJ%uBM4WjxQe1X94Pmj0A&IMnE*ZmAa|T5 z%mVo9k;BdwjZ^NK;RvrxyuaQ-7!xm```KoD{FC^Av0j_H4reo^@S6YyFvoF*Q~^;S zkNObe)OKF|wmTEYj=4iVx&e@(ec5;&uCNhPIpF50;GL(5b#gB3j>IfFZ;p+Ut(}_o2{IG_;AVq@9u)x4;|4$ z00yorng~4nXNO00_m?z8-X2WU;k?J_%IkuOPGGrXTrfCD&fw9P#)ES3!F~RNKW|>) zFZ|+2))f>4iFY1^?R|#Tv?HSM_P^S&d)#(4T3A5{-@2|GCRtU7f`EX;Q^-3%+tfdw z4>u_0794;H68Ok0ZY*#l438A0^7}_~uZ!??W%K!{LosA-AHZ>)2{#!kW<3q6Lg1!Q zFbZrce-{7_@4SoY6r2b{>vrnA+kW36lJCfL8wJQL0#RM8siz@489I#@+YVhi$hlFG zFR45}J3pQQ!E^w3#@39|A(`z>B<>KRYe!;~g6z^ksO)rzACQ@*TBqxRS0ee=BM;AN z9X`wA-R_kByd$#GbNKNg(LgFo&JJG&D-#7Jx@|KxQb$`PXNxB+Nx*08@hJAEIEoD1M<7Q+6F5&H#8_ z$>bkm!80gFyzShJ#I$2hW zRx7&fZi!qTKyDQ3)~Lg9J-RPHWP9(x87%)D0uKYgy}Ney;JE^Q(bMm~Nt^%>R)8`L zmYzi`EW=Q?{Id)h;4DFn{=9|1FM7Bb5avWQ-|2*IZt+5H32*KQ?`fSE`09uph;Z7~ zB`1q`byY0V;2iWfH2V1z4N-eOOtK9d%G%c+;4akSVSJv&e|0RQs849mh3{emM`27| z9;UvaI^;+brBSWwXP!Pd>gUBv`dD4gqPT?^>cO5M!)o#DI(ZP!YAnw}bb3@ApX2~E zgTfz3N&PtPd0sEw?y)6}(s>I&vnFyB;!(^tzPX#fe(D%c^s!s49l6M(G!|%LTi}nu zi^)(}SHIK-Yc`6d_iMc1Y^Scg2Docy))lvxN4#ombuTjhP`2Uwta#+d0blDKEPeo6 z+xG`Fh-J1P7J-B<#1J-j%>L|b6#%YFL>>OIwkwzr>GWXZ)1WSCix7p67dQ{|XJLN> z35l`F_YcWUf8D>vx@iFfC+fc|z+E~RC$0lHB5-7;Q@?{j;f_j>wVsNdjUX%<5rz_- zU9`VEBjW1F>5>EfduQM()F$WAt_S0Mk^~+P_6;p?QGb`+iT=Ix$GKLetiF#`w{ag}NvK}uO{WSlIwT8e}Z|&aFn~@(p8Nd>2yZz_8XPrPY!Tv76!xUWK zmR0r|niwlUzWe7@Zzb`;T=Au<@bntf->Dt^<6~d)A)pZw}vvDW_rxYfM?vOPUpDZU6xOBweVT*PH+; z8#_YCkkj^|X6V6)cZJOEmsQ2&(Q zNK7qWiT!#iRhU~AlBIkbIg1-&aU$PCK2R_mD_6GZprK7sKZC2hvC-+R*{9I@#MXGD zYtEXViZK_pfa^bx+i@U4dn~$~&3!B(7}j``uBivlSi)V$ZZm7}8itQXf7b!})_3bl zv?op!9m-`BtsuWZJKb%ir=h3>P>B6q zGMZ^(ou3=EE-!1?s+U*qeO}O3^8A9_1xtQe>E0~q51b}0_3SHeZDm3s0}WQH7)4IZ zA{0s(J<5SmySv_K{AFOX)R!OAQ&y}LqFN+5J>dKBK|n8F1+FsMAus5k$$!!it^(L7 zneX}=Mx83!=*YcFtI4`(bL3p!mGU>b?+l-mI_gGr7F^wZBN<+rYPrfI{8!d;&a!RI@F1#aVYN{AhNV`5L(189HKwCR9(Yd|0+<=wnw1$NU+2u7W7^AKVek&$VMdBS&~bKkQ6Pd z`CRlzuQkt+j+m}S8PiP5ElL|ARRQXPPZ4ijrK^@unW@nkc4=g2o0bok|6&F#j|tUN zr)o*yEReQLnr=x|pe6$(K0TdQeY}dmpVQ4IxWB7T574bbdT%7Q46SpRmU~2J35mQbic}&fo3o{BsyErnyR25o^Iu zq9lt7esVR(r39VY_7-AMQ0GS1Le?Zs?OzLNRrY*u;lQ6_H2OgJM zo1{KW@p&YvfC$~lflp%cWtjt>QUGSa7yx^yPzidbSJl#!{6e8+jXPNO0p@L)pHQ2q z#W%etNvR11s#5dvNAM}#Dt;$@l7=9uip_%PnbR`hQs5t{S-xjjylS~D%Hc(Gw7PK* zKaLv`v>Nu6hA7up%Y%F zl*%8AMHxF<@SC$S8~6)8t|zX-;aSWjH5J@Yqbq?Xz{xS^l+G0O=z_1fzY`9nY-V=CF*$hJG?Gd zc=qaPu6A+&?YI6T#6CdcCeE2B9E&>Q^MDVd4bfJ?;5sVdd9TkxMX-;8}MGD-Zr-Tw?P z*J}?Qzya%K${<2>b9X-<+8?VC|9pP@NsscrpXeHHwlwRfqk%r#UccaogL>PaGJP-NKOh8%9m2yLR$hOKg(M z@jnSmk1y7?*KuG}C(`n}${%;HzuQWZNn8sN*n6PQ{t|LLasA-+{VdmuJ5@4C3#O-j z&fhZYtG|@=>HJ}frFZNf1CRMXr(gg5Mr3Sn>iWfRc6vRbp~`Oa(m&bX9$#l~)cyJE z{`pJ4KfnC>^WC36Wsm;=$beiY0Ad?(;W2=Z3=DDtifseE9s^~`pd(Ho)oqa0V~`dZ zEb9a|+y?VJ1{27TeMgARHss|ah%=c>qU|riteQ=`O%F0u(TOW)8`|&)8cv2icYwuj z!wyctsATxCJv?(8?luX}CnMJE5T)CQ*W(-;mHVMBcf&Tf%OkE>n;ZTZp1U}BH@Rok zY3tBuo+%vS!S-L1S;#k^kDa%sV5Row4}Pj zrIzx=pMQ}m(~^FpCHB5uI{SY3)!~$*zarv0l#92OsbAr#5i0C-rb_NtSiZJuELpYmE41RP>RH@@ z8xdR$9S5AY541->x+ByMGu7@!fCseI50cf#B0y7L)n#xR^AW(M4h`OIjkO5Cn+VN6 zZJM7V{%mU>{Cxi4egymX*Msv1aa^;%;hng#&p1AT--3}^eQjD&F2Ark+P^-FpPuGZ zofT8o(WyDFW2ghrh~(AU(aC+HV#}jbfblR+{DF&!NQ6-*+EnVOsrMDO>EZlCYXaZaBhA#NO_OHLRNKwIb?)qS z9@fDet`fk@emRWjf^tO}^LF6{c1=XOyf0cj}%?& zmN4r~UD(+u@yoj^SE6j%r>!e?pEGoAm(STY%q=wU+73(`PY6f|x!UF9>;`mqu0`2D z=(3+Ggb(XF41_u?MGdd)I=HAizS-TG?s5#LJAT>i-i>nd;@MRna0;L1Kch?HDuN=4 z?B=KKq{d0SMO*?!CL(%Z2EdLu#9XP6`=W>kf;`R?S zRYg^1cY4x%UZvdE)$ZF-XFWH=A~%kiy2#~z7m*kEPcv0k5GQ-g86#l+4>L7EPuc97 zcKg4XsaCSbi;5tIzW>uqRfpUXs&Lug0)lLT6D0v zuiN=GgVS!h=|UnM-vmc;Pw7u{Im(`>nm^XxRh;%pqVbz&k-3nPgRd4DWi&55(tYAS zRT=88+rFlfq30zFT+zJ>)B^}eK6R@ZI8irm*Anf0mMSDl2sm~XpwHm*@D&bQJI%hY z{htc zk8oN22*m~R@>BjfVF3f6p!u3$bBu5((DPk%V1G}b+mIOjpKK~M$jMi5QdscORRRCl zn4nuR=YGV5|9coUH8w8uR$T6nxP1NiqS*M-Tk#b?;;Zx%Zp0=u+)AhtiP4J{H24Rb zn*7vFw#VD*X>)Itzk`0z0}h+&%Z}!_sVhGOSM@KxiM{y#*2Pc%9!3QkP`KhKh+Yb6 zkHW`^uE$ZudZ|)-R9S;$#kgdd#Uu`!+RI^6*CJzqiKnkhd~mz*YB-U@rcVDGoBC8l z_{3hSuR&TsTv||X+P}i6Nqgy3gN)R;jLhDQ+`Wu^gUq71%+lV>ioMJ#gRF{@)U&=R z95&U+L)2VE;#pwgzAEQ!UEF?w_TSl5+1zu!xl6sd&-ZfI4D#OmD~uXIj%{jveW^5K7hQRm|;mij85?^moDR=$a^ zeBW33X}|Kzzrm!p0v7en@eXV8b3fJu_sh?G{M%9W5)vEsrqu#DD z{aHgWs=6!-Px48S=J%)2_V1pQqP3XNzHL6cd zsL#AzpZl}^Ut!cLqsAKvjSU>u^k-wcQB(K7hf!0W)$w@xM|#$U!0HzRqO9i{?A}kXX9?S3*E>2 zyS@K27&X?oQ|DI))ypsGe}z$h^;P{JVASQ_l)qursQ>q2RMX!N2qr_8i9g?=r)WzA=&HdQ1 zh(Q_rPkpUWML#=FU5UzGNWA(u>-xQl`qrjq&c)GE>lzws z>KZER8tHW{g*A00jOz01jLOQ&@{00nWu?{C*{v-XdV9`2x_4%o<+nKM|70e3^jYY` z<*2dMn90}ikKSFFe*d?eI{GHH?n&K$v8n%tr~Vh48n^S|`NXZZm-i`P9%=ht=GueQ zfDVU;z3s0b(&gM7>5&D(30U+in?_j8x!j@xdd+wU#)yw=O)Tb`9SnZ}0}Ix~GgG z>`cfvPjv@bqDE&s*o83Ii6;LY+a=&53SVDW6PNi0P}Ji)1i2CF{n>MAW^jhTJn*K* z&)~yRgP$6sOxTvbQt;%Vi``X_X6osQ+l#;~d`HNe`k=B#NLcS0*8vhpV~AvK#Tm*L zBh?ypEYowo<9j(J>61@Dh)4Rfr%iVQSm+qLr&5BL8kSxo`eu_WuR#ho7mX@vzygTr zz7i=Z89ehG2i2i>!JR2I^;#Uuis;MNM4@qyvocAO6kt>U&9qz=db@{#RpA^D2+Jbf z3aR&qt3!O!16h{SBGB&`O`r@R)zaVrKQEMOil3mUm?Q%^iUFUvZ?uB$0BSUq4>=tbda8)l`-V1Y!I)CLDwp{j~J&Tb?6^Qa+xFCV8 zTS%b_HNR>N+Z#qdr||4OT9s%Fr74<|fmYM623&i!yv3N=@6bO%8NwFwnkbmfxN##{IX1dyyg`2tRNM5 zfHjgbHW?!0DA(=yy-A`|ZE-PTa2z$+ag1jppd;=0q}8YBBMr=XuV);EjlkyEXmM7Zw#vT-l~L13Dwkf44_p)pk6M~1#4q+ zfTUXk>+*DnT_l%ywUS${E4FJXTE%_*6 zyK0icOVDQnF}OQuq9kUsXlbRNvs$| zJ%z=$m!Y7uD(GwwmwUeXgAkI==R!7+$8ylqJm0q(PW><)=};B5p~hv?9xz|i=62q# zrAXXC;1ixt-x{UL&G)S85Tk*m0;E2D8J|b7FCu5m%7NyGZ$E)eQ7j89faZ(Cz_Zw# zdZ)iAZpy1Fg^X{s&kH)+Ze8a0P3DEZuaPKm7GrN7IKNnDa=AKn=2^g`SseMwEvISq_> zu>&~x0DzDVzEF!@K5_W31-HiuB|6FbqmM5^f-XH@mVs>Dj`fI+#pha{qzB;DV33~+ z4%T$^836bI6VfwH#;zi5C_qgdk1aj!TR;+$l4QoAPah_2j&M7(fKiqp7Uu|TBrsPA z%8AaM#>KqT#~*zNC_5Af-VM^C09`3OoEf^YmY@>MrTT~PU0C>i))^fZsvE8-GW=i$GY%C+a=li_|^G^@j!7z()18JAtN5i@isApF*a zu2d5DFbU1&%x~!|JRB<#ojndGcK7Ctmt;%+xFo%h{m3JCY%b@iXx8+`B`A>MQIfkV zn)k}uX4xZkrsTp)4x8GWw`pMY#v|*FDCLvEj%hhsM)?!9u%_WbFrLMWoX)95!_f0PM?_`9T*b%@;p@Stuy=OG%!DSb-cOPbxkS z{XSd1wBP_DOK~X|j3`hOV_(r$y`XU%^P=~%PU#h+pm04KjDBXmu~?zG;R#bi%;C%e zi_${d23HQ=d8Dt9Bvyo-FZ{k;cr?Dq1L5czRCIi)=w!UT*M5P)ev$w2tIdK}f5HpT z^j!@Vvk8nZI44#dv2^78e*S60;<(b{Q?A7#nS}}a#S|N2qD?OKcuATVF~x?S-dB=i zXr76~$Ss&2vLuFqS%Ip+Crev^*F2sZGdsr6~N)A!n1v;)myahpyOmboO-&AO? zs?%)*QF;|@#z+CPhrk>gPnMQEHU|0p5a7AZwKi~8J@-j3atZ! z=+I|lc@?D3Uv5kxIAqS(s(0ILc#WT}pUf3_jWa6-|zD%ARQ>>SXZ!kMXCgRBLTF;!-b zv9Mw4@!&CjvxoFP04yEhQTn`VHDnbMmtbZdEsfS?aGiF7cy5S##LPuvEA z#90X3Bh=*puNl)0J;ZxlS=V zPvIcQY2cf&&QoNN4z|nuW2dEB*HO>ENmNJU7|2`~heUNWMr{WWq_OaH)^!^)Tq*&c z%&6Mxt5U$@^|GPdwcUXv_%)*zX+Vu*V}t58NA|2qW`Mv$J=eJ5kSIvP1vqWH1xW`{ z84XTZ&_F;AC$&jQJjAa*Q>(_R}IQW1y0iD+W33^CDBV81LdjsiAYEyFR}&3wSD3+=oT zutOB^a|BpeqAHdJP-0Jmro~`iQtymQRLS^&)OcX}K47(v?E@iTPy)=Crw2LRZ8P0X zSnfQ=>=eh{KZOVDVY)1soxdjTpTd+I8-ow{+;1|#AJ_&R#i2;Qq8)he5+uWb$ZYlkCh(dPRs9qF&(`}zFmmLA{m}o2FmX5ec9NZvVBp8)uT-w z48*#6E`vgOY-FaZlAGdIOz@dJ@O|;?>2%N&lPVb&2nVP+heh9nkr5($>0KiL%m+fF|`WE&PV2?>}0gmIpfFU-{0vGI^Hyd0q8 z0;ecNdx%^I@`hAFKL91{!m9K}`Rwp&A&is+Jl!5|FaqXe|0RdY+b|wK*!4OZA*HY83pmS}`_Hy{28;EAWe`24|7GVf-jiCHu%1hdEpVL3n-7jzGI4Sxzo9x&RNnEzJGE3 z`itv0Zo*G-0H(XjN?b)$;vMkt#-Z}iY^d}!FqOwfH+@k!Z|&;cs&vXy&;_`W=~8*# zt1sL&@-4vH6ZmVUc*lemaVGGlB)m}bBZf9)vh~^?3$ka-rbxWu=+_76%e)mM-p}s2 zCEzVi;#G2IdZixT>VI3d`NpU3CQ_A-3MRmeXAVtQNHRN2NuZ!dFgYwE^bstPy+Zv7 zG{Rqeo_l(8Ys>5a=7Zk#Gn0n+)JK4fla(GUpy>4dU&|Yp zE4ggEoFz!$Q`2wY{_jI_+3&gU;bm|$XG8FUTMOyrwPGXupF34q@WIwc05$GsgN}G{ z?hm4*P8vC}@5MdJuNEmhgu-kI{RmND0e_mzNc}t^Lx;#+#t%ILn6~=buL3JGTZZzcjL)0oZ3l@#9pEg$oE4{EU8^_6{OY#tDJ;=R0MMX)SL_R7@6uc z>95_PT{@&Lai^!^q^IUy-#}(4j(>V`p-br?K>-h^;btzJ`*85`2U-$5Xd3Tn2S3FF z2X*a$hd@&7@haSSS}*&R1ija%tRbDV2{ktuJ+C~;Q}d1cAq3Jl-1<#&dK#bD_tQ2= zn*ow1fru=~rY*#d2~t=Eozx#WYCmkX4Z7Dd2^gSIVSHRD;UO#?$S=YzW#*4be_Uyj zsJ=xhaei%;CuMpOB6f7$xxFQbvV z+r5zw(-E153NJ_=?KC{v`_ep8#`3$se3s-WKi~LjhwTIVuSc_nBb`n9D5Nr^hHEnk3T|C+u>W62vXERt(v@` zD=7bjViXAv^|I~Skoc} zFFFqcM#v?HUimzAJ<`8^nv0)$gnrp)uqq`-5vip>$bpCz`1m2@t;wTcc8LKA%T=^- zFsj2@5&4cNv=arKh~e@j{?%hjsH`dn_cpez$ zx7Y?k(a^6{3#oKnEe+n8Ma@17jJ+zC{Q1aaYt=fzK$ux5L)%W{*57QZ(~0n#*TTkw zl*N*&^Hpl-N3$9ZI)Mh{8g^IN^1PxihOWpDavKsc-wN#siV9q7kr<^NqOP;0NI;kK zk%1f=dyxqf0f(x&JMB|Pj0agzncrC5=imqcp zRPRpD^N%g{y`vWbZh2o}z0rGSTc>eswvfZ!fn$HXxpnH&AFeoJT-CR43*sN8gca4= zk-fg@GHC{W(Xg9cJ_$Mwy$Yx>x=NnZh^;>KkR!dTyWcc zsPSe}lV+S%^_1S2tx2-~VvX2}%7YwL&qxbo|L3q=McGlnK$XY{Wiv(LDb9jh$ry7w zO`ulAB4<%FgPNs19{Bo;>K1xURzyMnbmpWOLoSQA5O+FPY{<$qdj78B@|zT2v-jXk z^ zP&vql3b>Y;vePeN|G=8uuKJQ{l!CR2IkMnb-TjNd&Yw$KS?Dygfn2*1bIr<~-ka-# z<@V2TJHpmw;-LpMR1OS{ zQ-&%Gpb+6;F(rLNt!Y^JF5f6ZTRC|~2&m0VklioLAW}(GZbl@SOAMd(d2Ko`cIb3g zR9tuGlAW*Qs}$)+CHX4NzVa$2gGUTr8^4sw%g=SqkSO>;)yB3Xoka;sI;Fxx?N4N7 z@yTLCxYTDV3c1`tR8jG2x_PoDH(J#~YRACN^C`dLg+jik332>t&nb@G7vTIO>}~0E z#%e*tZxX@=Pt)GW22M^`E9(ye#r(tRby0Gt<-L*Vftk1-$XSEoeawjw>*9+FHoOrS zkQ$c_T|&%9PKF5-EnF)TN)2}X80&2J1ydnEHZ8>gS}!l^ zhE1KuzrL#SfcH2q9xe7>f>`>=NN0B-pHL-(g0#Z&J7Q)k?A{hoGS=W40f&0d_o`n0QV zcsB6Y;_H+^W&9nT7Nmj6f=j#bHw~*@(m_i46dsGoR|JRGCX0ilb4t76y3PS3@5Jbf0LwdRt~` zm1z2mQRzv1CjH!0m%&Of7&43QyQcot%ziuy|vr>@RiIW7^9 zPZG=h>ILGjf}J^ZE8g1g9@%=bIp0ui{ef+Xxw$SWjlX~C@g+8<{FHhC8Z*#3pwLw% z6*044HGPG`VN>no0b78S%xA^mpEm?m&7g21iuzcv&!gloID7Fh~MWab0^5Lc;-!7J-Bn}b= z7}fISY!hY3=7s!1Amvg1(Cl-!`rS-?!@WxEq_?TOS@js{IUAy+iaDzkqcWv_#@3aC zo;t46EZ~yPb_O)rLp}xaH+)|aPAax&uIJ}QZ=Obc7P}q23(RJgnZ#}oGOSn2%#p7! zsiV1mqVhLHPneHmj}o4w{-r3as~q#>%YNZ$b`=`8HZ6C}@W>hW&KqmxXN{cr9`Dn? z@tp%;Qptn-<=g2S7{dF->V7`vH(+yd{723AKNlwyx>(3dEZxEyRN#`M zE{d8YNe>4O3iReEN#;(Lum_*)-OY(Z&HF&o<4{(CY4eNS1>1nvff>(nx6Quf78u{Q z@J&`2gTKau%`(y7cPJZ-{^iI5lN>a`8f%n;#*;GS0Yr0Fo*x5$fd>R!}NKIcj7i%ID!h234G5{)CltKq2?hUa}a88f%i9 zL!yeX>B&JG=BbP3*4PHROZR20A$2*oKnLBcW~joKfx@AW)8MZSXat|+Wh@QT`(T42 z^x7I&AV8C&18?)ticV9DR!{_giZG5wz*rW{QM65H4^}T94z#wM9KBr9w~tE}Tve6J z0Dk`nP#}SXMX5qQpmhw8(~iQArLHt!9lLBDi5RqXGDDquY_51~l~-6)Dm!QBGGI`x zZ@6%5IL9N~xR+Yw!bu|oVFOl~z2JpqI)5NglnLiFW(w2Ix-kX4>nVMb@K9udfkAE- znR-eNZL*pocgKd;dPpHK*@80oY#Q*;0Qk_u2t&?^T>%V>CO={&k4=NvZ)+a1Rx;*9 zt*LP+M+y=Je?Ulv^TT`HWRs0-snx%(JjX!L+qp_`v@Sf)9FLJRfDr6~R#A?+c;p*+ zA@8by*q*hnDDUe)pqY&dTH9z70~hmfr1qkARp=Ymz*YZSygoqDj64yKF~~JbDjC@3 zm7%x+;P**J(Sb@n!#4}%lrYjA7~o$tV9H*;C<)ZNX>@A?t>nY6*el>tOX7~sKu^N| zgpUl_O{5>U%h;wY0dKc&Q&8dA4@^c{;XG!dJlzwwyBQ-?obzoHtI^Q1EWEfWT|P5T z=%a@PUKH{?(ws_0iU%G^^)XkPL=NMqk9^DzMCBw+u;B~4gFyz`R8B^Yn(?aF^xZUt zum}E1Wi~HvskuJb=F_iXI?QtPHH{F^>kuHq~+nV3&%a^433Y>Kd0D zB<1eOmc1us?vpU{RAah;Bn}uVm|#G zh8O_@kyC+K1Qwb3Qv2nP#zi61OOT463?6Og$j#TZ4`bQAwYo8Ll3<}=v7QYk){+;v7mr}^e$C2p(8EyE}=;gBovXRCNu#- z>4KG}QYw_r7=L`;TXKc2@ReGP5%~$;w*K`aNIqanVW4Js7=g zV{{8U$Bwmhk}k7YI)f@`aUPRs)`~!1%s#RJoF>NVB;7WcNi7(}w2YneEjWJ@#=Oqm zEqUJ1DGSv(bH&Y;n@8&!Lzy!Vtc-`ida?R$H)jffpA|pzmi)494$tAB>*WS`6_Tpn z3wU0TDs=?%8v{-D%*XX>5*qB53t8pPB}teq{NXARe; z(f|%nv;#Y84wA|yJ%JwyNjk{`>xwBZ!8T2!39A`P|PG6OJUUiW@TKmnL@}(l}j0FMdW`f=#{_ZM)bMvAhg3#n( zOC+3Q{{;}%k*IjY{E^{mI|AtN6Ub?H&XCBWvx)Dj&E|&LNsD##Z+3VI0|zJ|HVPn; zPWbS=m2*vHttC8PO$v-33mTXV*0hw4FnTI=_Cvu1O*g>4K^HKs&nO_JUO{)2$d^^LRDpR1`zI!gNIhY!iaZtzElI1ivfK6`1aB*pWe)% z-mw5X*6>Mb$YP>dnqxKBC2d^pU3hb{@O4J{-R)+e3M?n<Ur=#@SkuB8EaWeO5eKk!O)0!szN%AsNu zafr_%urF8rk+QK;Ngy%V*!A=Nd!hc{_I|i+d9yN*(vhT7!7wn6lN>O*KG8baikPXoK*<{bsgGOo zUz$al9N$BOuEf7bh}=&_-iOXVC10qAKb(rS~1&jl^ylR+d6l+pL|#h-F615 zZAaAC+>M4wUWic}5|Zz*Q@k8J?itMb`s>MO_PRGhj3>NZ_hi!na+%_C*|@q~7diTg z$$1buD#~qe1fGCcCGQ}u8+h3-A=cWPrZ;Y?Ol&l~kuUiSYieoI=XfB+thn1=tVW7i zq5()jvHZkMJMG=GVLM9eKhIy-o9^A_l~_{R|8A1G?N+m=torp*;hxv)Q2EZ#OT&A< zjA6oSdjT^01KxZ0Ztn$M*q`R#zZtfF$8$d{KP-%vydUv+KV)LV|2c2w#AMXt{aZEP ze5r*U=b65ZJlp^!Ut?)UsD=|g4l=^S@31T3^9A-}R5Hj1HO1+_>YD^_B&Ys`5ubqEcqSc_%y@;}dwJ>;pl+eovZav$> zu4by`QCEKJ+^gTUBVo|60ErvhoO-3q&jPfcAF;i9fLp$jPDC-cpy+-4rA?G7K#W6N zjB5nu)54qx5>3*pd%lP-WOsgJ9VIUKNWzl7P5M5N#t4y*^x^YCf_HYxz7>Odsm}y0#-TPQoQ}DtYb7PF7ju ztNE_ye33j;<1~MmtN2FSZ*6;igU+UUzrMBB5uK9vHDAf0M&~r=2sGJP-2&N0NErwB z^ZOy}l525RiH`%nfNn~}QxnxV_;ZrgmbR|v38NC=g#Oe5Iax_%pCocTl8>{pp%7`} zQkbUc`Q6nqXfatTrMh6TPR!K1RL8Mt_GnjobAgVms`&lU* zo44^2ePIeScWbj>FL%WLnOznKG>+p#>^(_rRVrhgpL}RZkB%fGzu%CM@!Y(a81s2O&ZdaY&$z@*02_c$$&xqs@AmMcFb!F}7PoIEv! z$@k5~N%&q)Zy!qq+{50Y5AE-77ZW>}>M#l13ZqU?9^?|YNzQ!Uh7$8ayZqn-CeIg2 zPY>@~D$^)mv?9^HObR{dKI;?p;vq_BEZ#e)x}2)K?2=>)Mz)&MJ7+Ng@%(UvqsF&(^mCqoXeN=xK1VG7#tbhq8zG>t1dWEb z{ZRv-KFN9$cXr2TSHObo`nE;t;!()-B^izODYtG#jyD3Q-lN|IzBr-%KH2b(PzqP# zx#sHmnc8=0H(3mI7UKnP>nsI)6t3&fJ}+PSQ51Sl=Tq+G+q$0%y+2GWacrD!zDd0P zb#bM*__p49-Girkfu&y>_m}yukLZ1S^!B#?_s%leb9cin^#Z@<(;D@+1_bXIYh_isv{${!mE{ZDr)01hR*1z00-F%r-yhVomLOkis;rxo#a9sJBVXTh;hjz*Sn z7!%-rW+Y>sRV+f~fMq^Bq;P9$#VYI3%Z_GB2!9K&el%!C@Gr~G3r_b%v@Z0-C-dP zI&WdjtbQFM>Dw!2akZu7v%RAq^`ugxL}MhVt#loEA*-QJ>gBx z0))7@}Ga^yoq1Wx480MaE@LHYfI*+3EJ8O z7=2{O=nHohzkZ&iHWL#*_CP7xZmNHpiC!k@>-i`3a|66=4N=9Yzi~0tg7-JX)IBOV zrZp4JheB!^-qe{9(FqiB*BhLL)~94s8lLjQln%X`T`~{sRP19JLQmNiVTQ@@>Ag^9uKTG z^}$D`#(CrQ)mB-k1XZUt|3fES9 z??3zQMvnfO;-obD`c`nmGGgXJL&@$iW1bTY6svCBBmNBdk4Q}r83VzPfg~;4}J4Mr~c_6$|Mxn6k7&@?e zFMT6c70Y}}AMOfU%8Kjtt_O`-;XWUk^9U7b30)^ZNnX;`G2IJ;T>E5|{qI@*#S$z{ z!+l1Rn?-PQ1_dIOyWiMgtQ!Z7(Y? z2^WSpvK?|22SdK7^4n!Tl|*SJVWGle;4maUMpcnI4z!Nszbdj**Xs9qWYBz2)7^CH z7NDR*Em?4~!!)UFD=o0(y0B+8A7_WNRFO1I7B%%UUpAx^#j&`|cZB3paG8LQn!w*M zB!{6*Rlmm=Uzp4M9YfuCzj?T%&;KV~sdX5#%2Wu7#-J0zY+1$3@{>5(hBIp_P1o&D z9<4Pfb90gw?p?0w1*&HY`JwXNc4}rRuFSIIY)yu=$gSr({anCSbAiuCm-Xw7uzxY0*y%ZXE>v zTY!3xX^5$D3Ca8tJzbVM)xJ<>MtgU*Le=?7i9z;c&lKwW^U z;hEO6B{`^O=dSXjCz$DWX?OxRKAFWs=+vqxxau5dh%qHPYmEuTW5)($jt6cJn7H(H zKvfiv%XZp5eiYWA(Q;C5c~Z0VB+e1TR%I=3g+1)Yb>Le@OHZ34xA^yo4yKTcer^|nihn2fpAacR z>a1|DCaA5`7UHVkjp$asII6nFxl#!f*l8oyI=(-n7&nfTVsF1YF)esD$oO^i#h1p_ za^eX^go`FY#X02{%@qszH405kKNrQ1x!YYVGIyVIExb;fC@j41R^iU2RyYwT`0411 zRb;;a^34fPLGU{%Fd6^Mmj4=PHMU4z_gf!iZiC+5 zGA$xeFZF&i7MdgA2Z8KEd3FVO;RDQV<=W=X8)p4jA^LjgRZNUK#V!XgybFl+t8LQt zIEC@R(dO{N?duPH&@yEfwX8$sYRUdsAnOquA)>9rzi(*kYkwx zvdPwE<75+d<-m|yys13(eZk1~lS2pJmpJON2CLLE9i4mH{vh`rt`Uz!f zfSB3!_Sp?xG4HBDDjSiM`UaTxrnX7X>rZ1{`ghD7GzGR$|3tY#cTB#|(5F#XvHy%> zmixNXdQr4p!=OcRzhA?1X#K$FBI)Wc&+~i|6MUkB>Ya-eUlhrWSQL%4`>e;|nUJ-k z0%xAn5@5T4WVYuBCxQ{@a~K8{a0^dghF=kf=fck&eg%jot&fSEdC42kcz|cWMgL#} zL|3q9127yyN?ejfytlBdD8_$?rI17}A<(4A2&YhtSnV6jY8qC+>6=ymOfL%fVI&Sp zuL875c*^WK&G~YgbAWLZC_2}0=N%zInSlw=E5_Z6GFIk7Q|9u%1@=>1!3ri4DqjZQnQKO}@?=|HE570Em92u#+gXWVHcih6VKiw?}BM zv6Am}Ar%Gb{gh5YTmgPIHDkR(<)N2np8@dFrUCQ^On3?cPVFF4Anb&^LF3uQx4>RJ zbIGI%)PzH*SJVR!uOiSPPOb+0q!yO5ippsg2de_Eg~oAJ0hy{WTsnjaO|kcp7`TwH zfY1vlf;u5hP!d*s&)IA&+ss9u+2hS-(+6_(08BOf*FX54HT&Uj-(=;{#IB<>eY%Ev*f$h0zh0iJzaS@h43%30+nY5>vSs+R9CA_vV(fFO~N z1SVPZiZqZ*2*=s*ZO)y_m%7ad$Ev0&$=#tcjbh|$TI5=T1~aM>(=3Tlu(R^Bvs7nJ53A*T50iJS+|s_#F|6Y1-LvUS0d+({Vj6+W5D-{UMSw(IYo|YdOKGu@1x0W}5g0o#n zUZ>vy_Lczf1w1=Z77kbItk@M@4iqw5o9)GmN_-a{@@COddh#?x{4L(<4xY(MP3Rq- z)v86TrY+S)MNL%wT!flxWsux8s;oEu+#Mk6G(eu6DjW6l!X4mvdeB4HN9CQ9EM`=V zcR{%EZ4C@9#;&5V=b-;hyOL_FFPc&1ZCCJHKMeZqqyGSduA#hP z#&HZ`wxBWf%>Xy9RvmQ=3mqus4!Q0PKu?k3^lFuVsE$p+sz0D7BnWhDl#IZ_A%To2 z0w?RVWX6jgP&x zj3tlv2C>|yTUd5gr*8v9Hi2T8?{xfDPX%**>HKvTDwQq?}kP-JiXgrr_4uDlGQrt&})KgQl`ISVkxg`gNOne|7?@fkP0ys_-kyEUGLZMvNa<4+gXmE;i20 zArzxi12E`oonY8OtxPeRwZc(a0#3&0$9N6zVMZ%IE{QleKo{4cjv{Wo6~Qr2cZ}Tz zuuv##PXTUGt?Qg=8!=OyAryaqJRD6m`q=K9m?oJ_@xRsvO9C|X<2i?XHzK)>)qx$d z*fJ7@1EbC4wR6iK_I%<2>D+dtQV34gw!NK_Q}!5SSZ#RSO7^vh0B&dJ2drnJ!HG8&mYI%FSj%QE_& zO4Ye60Z~$zQMLm6etlq+b->%+GsFDy&a;? zfeNi?#IRh65KDcmeXSGyqo!#n5unmvNqx zLYd{6DvE+|DFO#Cv`xr8el};vEEx$`JPg@4W}kal<*i-4BNHZb`R^)481+zO0nb#T zjl)wS{xK2@TJ8~r2t+F&UQuylVD+Hp8*0r|!pgF;~GbSYR=odu6iA{%@_4t~;nJzV|e&z9^bt;Nwe(i1Zcpjdz6q=mXbIEJxS9nfED4~q#cgfjFPV$zrrd-P<>;{_sYCspNw2d5O-5m3@j9kNjA+d{HR%|mJ|jioUS4-$oN0hU@PS~RT2H0OP$ z#F%u5kcpt+u^0ur~AFx z8HTJa3%Rc~?$Fl#^DULvyaVED;9?DsD`Mm9WG#^Tu`dl3N^5U1$2=}R% z0|HTsEyIUxU#(vnfKO{o{&6W!)UkLHo7kqY0JIeqAEUMl1}qzC%QVg|r;DgbD|e;U zKh@jVnEr4*gZ(sqIo)7sAri$qPTptdUF^;!T;bONrfjz%e_S|-8;hay?+WZG0_X+* zqG4JM;ou^O^__xvoWMI?od3xo55;yhfhr=VWJu?Iiaq8!0=M^}4(4C#DvrR}|E3ZM5N`pD*+o3I)`=~%z*tH-Gx>De3#J{7HXfJz@jxLO_f$a=Q1HOX zFN{*ebyG_LI}TH+;DU1{>A*D1m{NU1mIW7)r%JGycjR|P0okD@y5BQ1qIZ`?f&4>; zldAD&UByV-Fe9vT*1ybVCa84k0 zd{%B_$R`EoUuL#%nmwwguR9qaEgipSvSTr6?q6(bkH=KjVE>BTzM8zswlkwXxma(j z&^r42S>jj8YW>p}1x!9=l`&|pVmXS8?(lMD{`iwZyS#}iW`E-b^^=X|zYkE=P9jta z$0MENFi?cU3d428OU5iRRNV}yDU9fYpFzc|B>^v~l5qSZ<4}*&<&_tklUV$`5~L1t zm~9X6oTKCfNvWK=(>LXr_%2!EKeVWblE-|cBMsDqoEenSxGXa~sJR|fZOEMp8v-;E z%&^Q#L0}#yGDxn#xk}k&9d1lc0G2wzZ5^o0?i2}VTrSLIa}DD({+f4)#Oiy1;JH6e zU;0OaxfFapt6F?_63h3fEC$%U(zr>LkE*2I`QhOOq=M z$_nCUUK~Wt@=qiCUEp#M&;5;r_o{e!%=_>0swImzL;2!!|J(?#I~-ry1fKRu?iHA; zcqj4B#L$Ju+tTrmOH4<3qo{13-3vrK$Jg-ZqCxakwwxfz0xbM&0j~?+D4sXTSr($Z z6;kPxspjC&cdor9LH|X~tKL=>KSIitX>I88MF@lLJ#taHB}hESITs$jVSRfvFK$cQ za^yrq6ycAPtmVbV3wt|dnzZ6iFMNKfT$j(TFe_QuNp>FKV*(1k8+X@=Ai>Ruir6@G zg2dnZCaltCFQ7pnRTyMAaRw7yCiwmYR~0-Oy8FP{*9I%-TmOE=a@76&)t$Ry%un@j zS+$lBBwP^s2@dBRL_vKbD6AIesPI}!rOq`;X123HmI@oFsQhaNS+uQ7<#-HIW3SoP z{n3N#rG7Wdf@l9e(De8@X=ueGbNeP?&t!1~U-5L%^WH#u4BASsU=3L z4OnB3RL;_U;{gTytgt}UcQQ_{-}En8p7qh@!TNYVL$obRY5y7)KG-tqvgwfx`}M*( z-8h#^@3SVo!qyLM+D=$7|CbZ{zh1qq+9CD{u9|2cPW%)P$xB48oen#kVyp;JxGS`N z?y=s>>f2WLuF=_4m55p4^_$HZ(aTQ$y7LqFLKTWj*Sx}hzXgviI!{iv>L>nwzxCa| z{p<-ko2suzpRIhxesA*${Ld^)S@=Ng_GU`hpXHPD;X~HQ)ZkqAs~`krbHQXOAMpuxICdi^vo7Cmc-hM14PG9^Q7(S2vo^aWtu=gADt zh}NrUs3*GIoeT{mmieI>BWy}T$&3U<@oh9cOEEuz49m31Pe(Hql5_LOOy%V4duZl5 zbk=<`b2BmXA)2LgGozi%LbXYMiiQu9(+0`#iGbvnXx4dj!Yr9}5gkX*wOb<-K9kwD z$hW_v*?$pl?2*}lTkbS8f=TrZv>CyX*&XNq{n8H**A~YZ5wv#Z#T9l=C0kahW)9KK z17%t>m+mU!gerHeb%6tWkCrXBtu34S1a}P^=q%k#_2(&V;?d>c^$kpSod9}n@kRvR z#x(Pt-QpwIa>oZEPc$Rbwm36Y`NabH3spHvxA<991*%mMbQp zktI*t0d3W!SOcUk+5sH5rH)jj-R%B)v`ByZAsuK(3ki~W-y{=lcZ64y9rKr^CENW; z-Ijf#BA09TyP!p`@rPWw-CRZOa8Xud~FZl7DJ}YFK{rP;W z(B&zWYh0|B!CGHbwB)9=-g9W5JgXfR%wZYG`{<>%XSVjaY@IvV+{M;>iCntbQ{4gq zN*PnSon);#u5S%Hdi$?*iqGmdqxGM(Zcx+>{$}X+r5pU5FnGmwqA8}Xgm$sk$~dXr zjXzU73ONut4Wk#|ao(9mx&cO5jrYbO#?Fn#r@6;%G)zv98(rj*mhfyd zHQF`}%#pkqa>}}eUUp52pka17$Sj##I&IhN#x_m~Yc4g;Sukxbfv_M1>sId+6xmyF z5iN4n^%f`Z+5@?jv6ft$oER)mR~zV&q9}q1>4)X*4Y3+-1B}`8xGwVI#qMr9b26r# z*6rhe$9-lXGX3nmj!Nzn`gOZEPlwUKLy&G@Mzcr2kOt! zW&x*tspp)33QG1}+~5?{Tedal;hcPMWhw)V7Q4KoA>cA|wp!iZ_a?6cfdeykb)X3> zK;Us-k;lF9E3BH;QMEacLb-?nxae@wxI#vGwyOUV$2|TW1j{A?U@#Wge>{!e2 z^7&w$&Mk7|fZRGju7XdTii_?_&YU5kHzL|^MDN`oXnD}$Lp_q)J<|3(GPOK&Lp=-I zJxljI%eB0!L%r(Sy&Cttnzg(ig?e|kdsp(_P%3v3(c_-v@;-Dk{UBLxSKe;?NPb}}(P#$}+Fl*|V-sw=j^ZD00fi#E5YaTAz{Bh2q{#0HMXS$gi>MVBW zXV{%zkMA7q-vRzxHdU@8M(H3%RVP+6JXTjH_D2}+=sx{wijF7vHjBky$f6t~?hu^L1xZ8Mew^=9UK|z9vPQo1^(n7~J z{{Btd_RE^r)fXPcFZ13el&9TU{BN?UzcR&iv!wX5-qMh%+0+XI2XU_-JHBv;pIS_P zrkPgiob&o1>;HmH&73bVkI1PcT+`H5)9K7UM;{K<&6(;bY}PG)^xtPwi}?lr{1QZg zi}p3*tLLpzd)cqUqJfd+{QnnhYEe0tK+)S=63gKo=wWuC-u;`AH4$AkwCKZ{|8q7q zLZIek1j)1O{%h_A>YE2+hYb^S^fa<@zN_*5{|TG=mONb4Fc8_?t=TO6yID-XMJlRA zuDeC)cZ;fitLDFDQzeRncuf5)c&egXyo#C}2Oemnr6NWTGuz?`5&`u#C;dd!?|{FnIt&-n45vHf3S=by2= zyZiGeefvl3{o6P=IQaEHgWmpsZpX~&F>{(@f8O&`u7i8sr@SknYoGF+668J?xaN6& zF7&ux_qoWYy;C~tl%4FNw&8uF^QJgXbLXsK7`v%oE|f$$IR(5 zb9&629y6!M%;_<6dd!?2GpEPQ=`nM9%$y!Gr^n3cF>`v%oE|f$$IR(5b9&629y6!M z%;_<6dd!?2GpEPQ=`nM9%$y!Gr^n3cF>`v%oE|f$$IR(5b9&629y6!M%;_<6dd!?2 zGpEPQ=`nM9%$y!Gr^n3cF>`v%oE|f$$IR(5b9&629y6!M%;_<6dd!?2GpEPQ=`nM9 z%$)LfW(prOr^n3ce~URC`u~GDm6n&6Q&3P)Qc^;zsHmx_s%xleXldwZYwPIg>Yvav z#28?31~}uBMkYAZQ>LdZEX=GoZf#?E*8a@-3uiA}a5!)8Xn*$VMcb=aZLeKF zecjvKJ;cI0(kd|aOi;RQRLS|V0dJ3RCEYF_Ev0MSi;?alq~;@{D6GY?YxroyaHlQZgy67 zPFiMhLPq7Cw8pU1_TaSMu$&iBMI$lydXvkVa>_`h_sYu3NF-84MP*f0_5J%bb#?U* z8X6k^5fAH{$Yre^neCLj-9rhKSIN&`r@varo?p*>`z`O?_q_K%{Y`@1spVxeU)Z`#>bg*uCsQbl8 z@A&x3$;pYCnd#TBXXoeV-~QWp|Ni~LKV$KqL2v%6LEkSeEv>AqeERh1^ZzQ=*4Eb7 z*Z+%k`X2}WU*ze3(x?Bp|1bLK_Rh|K9HTR+|3py#WuX4Yo-U#OPwVtQTZe~-|7y}3 zfBtR!{%0Khe+TWq888~)FO!fNnM93+amim9BA53iA|xzI%$h3(QjqFi?}nNypJ$+q z?h2W=R1Ig#o~^$!+*17_AANnK#Ju(XSg}s<`n%!Qnpb6*SY~01w%UnGvut_Ck+!<2 z8k6O(_L+AQ?+LwTpjCrwDG!b{+`Bfhmvn^ zJAyYpjCDW$@sSeCB6_B$V{3URTjAQvp3a>w9!trx_iLB#Dz>jKrJx68ms2%nJ(kmS z&dZi-Ezb`kV+Aq?ka1k+xlU`0OV+JqS!u1UWZRg^efr-rr*$it+!h|`85_jhOro(} zl55tO?D7pYJoLZ8oR%NfS*iOE>dJ(LUW%*Hp?$U)s!SqMr|Y9Fom@$}E$#*b$JM#W7EgwJP_3X^Hr?1gK8-Rwi0Qrzn2 zzTmSpfV|PLH7FF;qx$smLT^e(e}Uj>O@o%M@5cKEvM;;M<%7MS{OX#tP-q}$jl4A2 z|GM)E!>F`7Zp`PqJ7Ff%xI1a3{cU&3=9JRUY5NPlKW7|nH2$2u687!UtnSCJBZ}=w z1`pM~cr7oFa6GzvdbIyf%nL=W8armW$`w{Rb9!t4|Cl-L{2Y;ivyiK6Q`1s@mUHWS z$-2d~TEnJ17_RboI!#-)*rOs!y5|ON_y>hi<+oRe){_KpOQaRe4 zzTkiKbM8jd(cZhTA4mHOi7HQjKDklREnSQkk6e5Bu9pSvQ8udgmTi%#b+l)0iCN)V z{{j#UfRg}>W)zUXCLU%*0`Uz|pn97GL@Eg)V@74Zv>AgOB|)`^sBDp&u_$;s?37tA zC=vy|<`l2sLuHvMw{k;7I5sTtJbt58!5}qS&K5S*Cvv!%NW;J@5Q%2}|6opGK2-5H z`Fi%}uHRO@HGYIAq#RWPk{w1Xcpnc9C`WFkIKeBCy0svlCD85haOYAHamg@~O8)+Z z0mVyO@v3jO(!)n9MfQiD8y;pRUh|+IolEuDti8#ax%k%g!hn6pLIyFlN>avr*y7T5 zmS6~0{z{-}+lkC`KeLzKW^J)tZj0d-rc}va7#=y_wVg|T=gep}!F>6TIKQX;TLCUP z6Ul)<-a4d-Vxsw|i@;97P|1p{ovN7&rjJNk`Sjw0S*mpo&G-QSeK_)_l@ zv=HEvm|822Logg^12&M2I}>&ZCgMTCBRi-jiIEe6bGwyhr|a$V-;5Ajdh?`so||)3 zn0ZJVr7KCTf>hB{55;$DLDK;1=k-%%YzVON=?xR=$aFi62tsryr;v0fE65=kIOf@wjsew*L6nBOn{-UCJkk0w*AQL;ev z&M_?=^fI3zL9URnaVaPqY{To_dVSEN#%N!S3AxJ;CTH834LtmAFhhW9vyb(oeE>>& zS1R66y3Bt9G-^>4UP%`)Jb)^mMNO6u*<*1>#+oHl;!e#~Faca4T-+0PPnD41B$Npp ziN0X+M?%1(-~ltU3kVvA;u!NV;or1`*a%TM9(JgJFKuQlLB~1HnL#wvR2SL*TyKLr z#YiAYgge{>jvg~(CT=RTsfRt>0|oZxfPa)`;pmP!E#cF-VNIRQ<75$Py1;N?v->@S z5#-Z!sr0L@q`d@~0fMDzX5oR{ZM_fe%myWD0Pw?JicsAZV`;+xpveLV3Mb(tWQ8t3 z5k_6XZWIRIQmE+_JTL_i3pF4nsiRTQiP}o2sq<@u4e%K##8|nV=EOl#y~Ja`T&sY7 z&fv0{VXp>Yy{_QATlRA0g%ir7!#e6H%LBba;w6pZ?s1v zAJ2t?XoV-vDxbVuo5IkGzAQ74VjeWG2aD{So%5q z!)1zqq8$UC8BPd}et-Z_5lm%)Ed%byFu`7JrC*LVfy!1e0~&DSRD3YB1k0*q9mS|^ z_*L$X0a@%CDZJ3}1K{547wZhDsOqDukM8WiJ_Bw7M3sVzo}XjZ2_w7&4h5V2HCX*6 z64$-HoHyAt8`#ej8>fSI5P_80-M`C7{`|=c`9S=f@lV*!J%B z<=ZAh&C3rl@3L+^27LWCOklw*K72RO_WColh~NjPpzw+fg#wdxk9a;NQS<6uO-$HphX_7Q=FHU`9{k%l$Oam!900PSu(0g|$0_a#0W20y z(f=%a5{{FJi2uxNMFs|&fJOo!DSIAp3e1ZF6byi3Uq_UEaW2!sq*Iuc@xXHcxRxeM zs1&FKf2aP-&4w?LPDHo`9;k|9({UwSs>Ohlq6XX%-P#UJNti3uZaxecmrri)QWy^@ z_ZuDYgWTY|6qYdx%p8GH-Goh$m}=s~Unj<-KaW;G`rprk1rI=I3}TMr0GECe^zU-) z#tl!!gj;a(#k&C39DoP67IO&^#xUshi!uJUOrRG6O4)P|D7Xuqj_)5tIETBbJi;gc zOz=3s>wP+l(IjM>q}0!)=s}T+0xhPvbYwkm}4*98Q<<#52^5?#F1-Xn0sm7_WUn)ht6Cl z{=5&|Q!^eimuEaZtR#19ve_>15xg*dsQ z`w>MDwK}rPoU(2KZVKqS+a>3 z39Lpm!T}&Z9~+5nGQjz8q5uXPk_l=PGDS%$Tks(BFGK#bT zO*SDmWXR8ahAWs`dd3VhPQl{4kei#3OKp&wC`RuCjIdMbmpY6Yy?|s037!K~N5i7X zU@Z)2;n(SJ zkY7M4=PvN34Wob;2{wWiB15bXu*~%seli#tSrx5a{?5MKAf%lC5>9{u4P1a&ZbH0? zmB#pr+>mNh8*`odN;ZuuL*^IK#&msoUFJzk6dEt}8P2Gp>*r-KHs zFk&Q}z@IMO6Al3Dkw7#_RING!bEdxh_N9B~0vLLM7`+959)>!BYM{E!JG86DhLP$4f(qR!fb--E`dZ55FEfue7ppUDu>xK+!%k*upe-P zOt42oPdQ;tY#4orKt%w9q7%dh4?-x7AD%&Bq{bmO3y@dC0HKA3ADy6+KdbeNFz)r(lLA#DyG_t4a1;sr z{#U7g*J-N}jNk(4R2QQL0HZ-+3<0T80m#aL6;egol14zJoHV$xYUEp z03b6wM3@A!B*qJkgUrbg(%YLd0T5COB=H4+A3^3PcLAq6%}Edwa*ZGvB8LE(0J>^6 znoiusy#K{$T2E#vKF!*VQ6t`09|z@kl_=uNM=tgtS(;-IV0Gd>rGRE6O#lYRfaJ$Z zWxC5p6~HeyfRf`a`Y5pKc#EVHnSchXEs$cI+WipiS_um3R(=5F6w8C{P6pg~ zD;D2&@&&`o`BtL<(0(^V&k#U{46?#M0vSJ=*@USEK=%1b>?@EGW{gXBnX7(vNo2KF zJ@9IAH>9e=pA5Oc%!smioDl_b^#j9J7h+Ar{fO?oTQgA%c$nJko#n*x=G_*Sio43eckmcu}$289o^G zrb`SzsE7cePWatp@jB_{*V+y78KnUtQoA0!oorC(=uW|iAzC&Bhu&xmF--$+m)zH* z3<^6n!dl1g6yW5o!= zX%>ua$}^y3*)~&~r6q`x$^e2tx?6?0Ie715y|2 z1ok&Mzp0cbK~CO;=)?^Qkszc2Kx>qV2#J2?AVF3PP#>fHV6fQoEtM66S^yTYydx=u z-@1j-!B=UOTIrNdY0=12(P*&b_)!1*AvS>-)6h1=NrGpg_EJfcTf;U#KWm|3R>WG@g9#r?U`5-)j)5){pvAK=sMHkc2l} z(j$Nfh)cp#Tr0%D{cZ0e$g&k;vh4FvnRxLx&^hRHxX4q`91yqk*^}FOB9OQ^z#doG z{UXq6<|ffE5s3Gyxs3y1N@k(QgRzXI)rX_=2E>);09MGYF9`e>2{Ija1B?*@hfaOC zCBhbod-1m#D6#Eu^c-;UIh$VwupjXXfn2_J^A%`+c5HBx|Ml{B=n8ZW5|U*(FVxdK z36xPHicA5-xId&SS79oMCs+%KZ-J`ZExIMM*yS#B9I=v%sLA=szYZw02*nJJ>MBMwR*a3Slq zTM2g!SUYPrX^UOhcHF?=ODq!fR+PA;{4zGAPRthU_vj0@^1Bq{yTtM{eLU!S`aAA^ zuqYY0w9YQG4Gr>Io#!BCzw3}}?R0Gg3VN|7|8g#S;Fg)cJNGQ!s#da1H7{4*>dG^=+?*GYrO}SkU$(r z7TIHq2MOCw``L8Qeg>L*t>!#ow;?;Y^W@;%)4Czpr{i>+xyE96Gm$f$PE2kx2C zhmi4`TWmF8jcwr4mDV`o{>D4YD?vnwV|EH-5HVeD_LW^A74-M~+^thz(jT+`(0+Ie z2cu5+WM$HG9<$4n@0tB#&uIkJF0$7SvTJTHNL?+bf89}TdGC6<6B^Jd-?HnP1vGs7 zig21ZZiVO%H*q|-7j<(FCJhP!u=}!JFb%}NkxqZRx7nRI@H$}o^neOckys^FQhho2 zV*okn`h%Cc4c#_MJ+Owm7fY+hgSS3kKQNv8689ZcS~}u}=r+cIDVML4kAh-lk@uGd{$`jq^< z{B)s`{bg&@)WGFl%8(?OB(V9G2=s1|UF>~vvc!1YoJ|_02a-Y+%#-6W1xPqp+Q-Wa zg3WUEflKYr%0p#No=m53dti2G0?_s~{W4^YMUp7U;z|~lHbgKJz5c1qO#C)PZL}!u zANqE$jM|_m^S4j&K~w)PMJ0)wzrEN6wD5L!44}pB6XNV&8M>SP94*FotpMTadS%<~ z*4prPZyv<^8dism{`X<^7vjlQSL^Rpq+GRVD49z+(Zb+8^P+-io}5WMod1|9z*p;d zPxBqEIzt;I-NC(jD~#L0`gvogqr+JfO(!RprM5rLkK%JRTE)9Omh@ zVdUG(Z^cs`i-*G7?#tkBf;qh66Sds0+^_9+7d_J0eIb3RE9I3OPyVcX=rfrfkMI{J z+MZ!;KhR^uKAHWu@@S`?^ReGYv@hKJ*;MH1+LQSDoY9xhJznuVraInCl>?-?`@8TKLMW=i-}ri)+SrNRrRbUwM770kcNy*}=h z)ECuCfh2gc0M(G9JF@-$)vqHp&t+c`nD@I8`LE&*dFaivDWn!m za(5~@$pAzeOA^L^>ksUCpH%v-MM9u+wJmnm{!ZS<)q&v0f2X3ivWxjjy(&KZ2Fv7M zPVr7r8?K{PDNI)mhNUDZR;BTnyRW4EchX!kjZh+=4c73Hr@+;wi5V1uI{E4}Rri*v zFdKA&CqhQ+GMPh`C@z&Y0+f3c{c(rCY(1xZYYa?s6%vz`p40&)@~8BkfuOrjOCSh_ z7)6LW4Oh=0i}_WRB4F=NO?z(bVwi?8gn|2br@TOHd_K6lz|CahlTFMr=yyGX?ZV*@ zkyU4#s47i@m=NQqGqgz@&aLiaob$U|uX2&*%1G@TIERfO8i8jbUgRW09ean;8nY4+ zULcGH5s9kwmNo%^3oy$RRLK_NJrEq`gCrI8;>gMfBYrhWsygltN8{TGn6i$EqH~)) z22l#-`hpf|O}L8xH%C3yt2$bYnBeT}g9EG|Sg0C$0VZmkD$1 zuj>|mTK^TF8vB&9(LGWzYyr)plB{wml!A9mmXth;MvkP z>%hL17kSm}6Vw6WcW$P=b62wmX^h%c^!!KUEu1%wlMOFsC0wym#ahc)=jQ5Vzp=F6 zHNjU=;CM02rkw1SfBDoSATu@6dK7u#qS*YIf*4EKe z!j8H{RAYi7*%<7L*`RAaTo?J=H)C;X2TIFoOzU);8@o{jN%uFk>3Q=~XGbIb3W&N% zAR*rFVM$5yPt&H~K)RnsnnoEsWjDh>(f9Tq+j}m&| zNxfER{5bQYYR8B{Q0{Qa;uq7NhRO1vC{~aD*>6$T2R|>#M8A0Z?&l-tDz*}n!&^e{ z|3Y;de=NP(Y|vh2H#@ZcS{}l1Ypg0@O4-#$VGB*TJ&F=G2RR{CT#K}WNmTXkH z=(6D0_~>Ew=A{zTw>F~F6z-=**}}$G&4lHL(3PzTXA}K20;>!)qk%PYb1U%s?uMeD zvNlQ*;2i3wr_JxNNtJvGxNLCd=#}(4S)Q6tD_C!!M}#z0YfgeY1g{?vwAm^GJ{Pr-|5FctUX~)4@?LOOYWfLlIKcnf*c-%M&EdDcU=5lsw_nHrY96;r_|D*p zs08t@iM6Es?ccmOSV4W&Y?;mwGwD9f#4}hB>{#EdV#$2zWZTl24z7fs$b9YKv6f==7J%ROKSB zc`ve{{FB+WM}>Iq6G6EO_un zJV)l4`$Y8knN00y0Sl{4Eg1Z4Li|rWWxIEHoU?C#n`jn5!a5?)8&bJ#DKc47-2N2l zwX9Se4Xs1vCQ*Nm0%j)2-jlF%Rv;O9kj<5Bq&$^7CbKw%luHyDX(PQlr|YlYTb@Pf zD5eNRKN|3&bI(n_+QgJUB}JJP=Ex3NU@-bg!cH0?yXgbwA-BK3WA zGTId=TbE=oNjn*rfYAZbFZP#&P&aU}b$tI8d2quvmoP)#j(%#kI4om})&Wo~Co|A% z+~^Q)ZF!J@En2&X&PTRf2be%@fx6`Q3s&O@jPa2dP{16dRXOG`mse7$$3_65T|ulX zz%_rGG#SP>J%V%vNn$9pN*epvh{s%NlFkILJV=ItNkyXg0p%3|BPAhXYxPfs2Teb( zYrB;uGhq;H9X`+B5S^UX2ZL;n0nD*Let$}y7m(kUmWD}-k%qA*q-oqVgz^IA{bBqN zU(9%!HL5&MUVwq#GC;|5pdU}nRmi7{VBC4q{}_(M z)r%=fif~j2RW1Z2xptQ~OW!7&TYH}TH3YOl25r#54{=nMQMwbN?*%MV+be@-luw{; zShI+}ZA&?prtuI5Dtsw=MV4Q@;z!T)>&XL+e(Uj=Q-DqJ{A5eMUngCD>)%->voDal z98EnF&H#OA$Y`X%8m+6>M09r`yOkyb$d*1#^G>kC$Rzt~By(Ri8+5lSVls=@$X|4Y zMW<7_$$a$}pNBaj2Is*K0jF|xtkW^GFVoWIeOaaRB8XE+xjb_GnKo-sB6uU$h}vpI zo1{&{($&kjc!@UJjYcZdI=M8PQ;kqIU%=-qT<&tlnK%&7C|SFR2WpGf&F9vt&)_AV zJ)J)`S#8-?ma*+G3Wf1V))~VMf&7?h9i*J*6;KXly8fhbn+K2(lguB7a&e?$?NNW- zK-{(4C3vJhbM>w8lO#!T&rH+yTO~(BfU3YNsF8~q?XG>kn;K5P~M1kBP8P)1=yNAi` zzpJ4nr+?QK8<4%}PeEBIQ7d1j6;1Hq-K)8*Jf)MkL$R+p8NWozjzGPG7MN?ulfNiMqU$D=RFR6WKE$}|~SM8BT? znwJS!$$JuOGNmR1_km=Pt;ar^XM83n%aXxqK#KXGHTUuuwmgHT>}d2nFE=qcLv-O8 zms^fJWgn2uLclUl8!ps0au>_M_*2HTDm$i|+*}6T*xf*Vd8AIO0xlgO_evhU+~T=< za)oj-CVd8*=w8x#Z=vx`L7#ikG({MYjj>JUqFLj(-WtGw14MfyeO9!A!b>{$ec&Bx z^c^y~LKH*sUIO#Z7jt_d^5rSoA@RJ)9@9v!S$z5egUZ!QUL7`%t>yYu^W^suS#TPZ zEh9BtZZjeSqjtf07K845c$@GFnG4JIKW zUJ@Vk@E;9`zz*-^)7w`3wCAU2&kgE;Nd^O1C(M6uKAN2t)7%(+jr58ep(4zUG@ZQ2 zGEnPjNE$waa>=6%3DhBjFSdD2=37ul$80F^M!sM?Y9+@O*r`9TPxQ>Y6#uIBze8HAiEw}LB3qwdq~^oF zkTW&tW%!ZLT{Gxz*I=Xhl%XjwsNnWsklju||EmU;d%7%7-6(7Nh6-4oij z^pBV0=*vPZWN{y5)$*fw-K_cCK>Xg>0ToLnbq|D?cA*DFU##;L|8a55SJgnY?IxdC zH(Y~&(p*`5R8MMVVOmW2{UiCzv-z6-(QgZRB`}_>r^&W6*E*A~`Q?6dnBhOa!!KHC zTa6X?jSQd?1u9(y`oasC1wBLE8wyV zSF6e|yZa56i@$tA;pb1ke!BTW^788&lNFf3dLZxHsm+yFftTOnpJ{xl(0SNt_fQ-a z^dTvzS0YeIsR?l2m;? zuAft|!vdgd7)8w%Bs(esC5OQ8hy0b@iLeV4{`|BUDFIfcqf6j;e7rOuS?Gfl=lhKR zvMHz>Dq)+9CW5)iq1d0|VkdSaRRv$l!VY9uk8)tux0mV!&IEHz(1JR4M2A8N3|>W7 zq&Rz+f*dVKeHZ^22gp28_^qZ7P+Nq*Cn*_L(i;TDfbkE)5O+bbLr9g|dpd%91}$o8 zJWX3$HP_z62Y{r4ZX^eD+%M_f5|z5EctQH8I~>Xgr};#j>WT0u4oa}EJ3H<}jjk&$ zmlx1T{^kt&xh{%-E1|&H(feMm|2NcL`^TBWNJojl5LxG9bI@IoBHag2rKebPV_Vi1 z*ql>!UJb~XMfJ!GcD@gCVGr|`ivr*Mais@6JN0#-AsI7$;*k&Fv1PUCO*p=??3rOO z&zhnF4XBqHaZ(QatO~S$?;!fN_G#8*W%U->ZNGf&!k;%!tK493{&Wg+^UF`lPodjq zRfwt>iritMnZ`%w&aeZYq{3(p!`GJbG7k^mes` z&8W4+>sOCdvQI8vRWRlL^PdY?v(PTYUBWp8++vVFCyjtCbzY~yY9og zzx;YV6&)LVB<1@3;MRAi`@zRggOT@-|7a=9!Qv;WHqTc?UM$e3vE{S6<#TT3uVTvQ zi_2v@L|wX--tCAkqbiC=+eCbktoHY9V#jU2z$wpP|DI|g{C7LH_iRkTiEv=>5$t{g z>TbBm>k#gr+iHN&`MV+N_*@A!uv}rM#W-w_B>ux&+~JP+5ncS4DgI|gTu2QF;KjA8 zJ$hm|A$ck2sl?u$}M<_=bFcOf%a^h@Z;;J*@g z!QzpZ7j6VmJn1_vf~DP49pdFT%0f9vCyXWYqe?K? zY!3b*2Z2(F-TyAzE~*HpY;TW%c#eOI%j{5_upk}2oo+Q7JvbybPY0Bg4i<5pL4Iu+SW=IPe3VGPi zsR)^U6*dZYj~KQB*LV4B@7x0)^1t>lqmVAZ{O7yHu5CUP6!$SR%=1k$*)fG+8Jqm2 z7Lfi<3a5P@MaYm#%MItG;&^v_vRWNRl|m6!aMmF+@1cuU@j4?GFJxytvyyh5Po0K+%f5+atk4=Ur

4RmB6|Wq5deA)eOrcS_-Rl;2%mXPK6FQOUihT?>o|2otM7~IMyEgi z4*Tz9;eh6A&)7eaRbQ??``CZEOJ5$@C|c@jyy_nLK;CS>_%wATGY#)xpL zl*Wzqdq#PBr7(JBAI8ETn+JW+H+*CL{u43O_nPBoJutK9rr!M6iN`1Ro}Z9mbyt5i zRIJas@>srhZ{gZwgP%*We+?X_@1N5eSaITMNu7^>eCl{};P0v52`Oiz7UmwGyAt{J z+2hlH{~Z544RBI>Y}Pb!E6@HM0A0smQ)~T)&5r?Uzes`Izf%MTaZvR-(r1&bI6mX| zP$T&vR8DKc^t#udsi;%Gi(3;_;v^6kF(^I(+r*znm5A`VC!)L4w>8QtxOnEDNbt7N zOnu++$YF*##6AZ(hE~xlVWRvr30p;a6~8rgL@KN;)xfIi`l->ODszJ3C6PI7A)4BE zQzF&Dr&<`*{#31VCN*lXnv*#%O8Af^eLVJIBxag1$>u4(0&xlZp|FR2&l#2u`-d*IU>~N{5$zTRiK7Pkinq5d;Cv z_z^!)q!YXm)*%?fliOpqPl@?b3pG%^zKQcJH5YH%l4Xi5)Iq|R?J|-yBnHn8P|GRJ z`7Ns>mz*z>o=zreyywacD|$r-vLV*Ud_#Bwrq>kghykN)mZ@r$v(n!J%Jt2h+jDCX za_0CaDBD)5uQ`ro-#U}3RK?@2TOCNV?5&JbZ=1}suYKuuI5l`F#SXr7}<2XSlemiHg8xTD?mdl zJfJN$pVRfuf6!gq=vbd{?&PaBYP^!KP|WKb3vUqChYXUWnZxhu8a{A#N6YYeBTR5c zYmQW38TGy}X?5)Q#sl7!1Q^uJe=Sr(mXP9>2DC8+<>j`{qGV#mB<=Tx6`gD2>2s9` zuq?P{RpYLK^R&B^#x%mZOG3SWX4MDZzvf~D`!**p7VVF1Se`nQOAo>v4q0hsB@oP+ zZ0JV~7And~Rs*@f=1(G;p}gSd=@gD^7Sq)ts zP_`i;NhHtG!6WVJ)Wx7x|4N?$S;M>A%G;D{F7NZUPB78U+lfZDOWYM2(NdG!$qpx1 zpqbINCz^NC3y(kePv|@|QVC;=jZ1tlraSI%>vhh3bp;i`6C=hydh5BzXRYfR6Hj9E z@IWDt_(_ZBPP==Rh$R^kPf9N5t`^^wnvfcw%WrMS$TZoYFd>+-@o42jX}AGJxA5?1 z%A=g>FTZ+yHIC1YPN8M;Rv_{rEE4}TBLXV&65*~!;oQBIB>QQJjiGyW%-%Ku<8iac z{kz@=@L^=u^|Kp_cKWfln=WH}kX;?-oYw6h6{@34(tgqW##Y4k5U{|vKMOZLIPg3k zkvb_K8eF=i*f~KMRhMk9sZ}Nv z#2Yo9367q7@aXTii+{%cB*2Oob|Yf^j!Z#m3M|cLQq<8@;U`X^wpq zaBIV%)BHc8E6(D|I8b&O#L^o!%eHyYlwh!udur!D_6$B~h1c5zK9~>AP^Z$6kca60 zkMn$`X_MEfO|+usutk$7mN?9w2lO9iVB-L9S1gU=&Kt+wwcry|TY~>Rx+@UI15ivX z9%TQXoIrHV5544MsAPJ{!Q-3=?blzr}YrM-KTIM#P|BY}ApPcl6@+C@y@tKbltyK6%96bO<~ z&^jyF@6kep@J~YJ-XvZ8QGD6Fz(2a+QmCmH!qj_%i``McKk}*KtZ9AMZ>K2f4L_g24o$3%f z+H|BdNu`izQ*GDk2~Pl6S{uUx>?ijvptEu=cj$lmTfRxd zu5UhDz#>=}p+}eQ;~<_xDd$1Y+)9iuG*4aFE%5yCS?iChja98l8ju(85{{d5N_w|u zGVJW<>2j;qPtwv=XvCO|C|;9p%fcdxuqB@S6>V5lYi(W4y^0Z;HkeC!WbxffV7}Xe zcb{MB47PB|ZTQndP|m$8hQkF53;KWVU7bw`bY95kqQ6vHMLFk7NkTw2vc`aSgNS#R zD&F};ed&$xvvcKsmAqOpQ_>XZ+{`cB(sobf;9WC;I|ll;f$MEyntT0DflB?Cw#by$ zu99Y~a4|k1Ca9{RO{ndm+*O)TJ$-cYPX?+4!b=0Li#kmbh-NA0(2kxQ0r$;s+`sea zl?AILmsivSaH}r4qOO-Lm(nbs8skiE_F&iojWDvm3+pkf5c*4#z9@CpKz3M z2`x%EnN^o9R`0kipQECX%Sy=6Qpht^Fg{tI=e(X{Uw>u;fD2g1EfU$yN8kV|x2r<2 zy+}dxF!u(7W0=eZ8{*D7?~p|k6H zu(n%)FX(EmAp|!^Z1uZV&2_?fsfcL+ z_vCv0y{`@34dd?LT3#s*H8T(!fbMoEu54pcrAaz*qX1-BxaEydx?26_+haArQ)o#I zbclN%P?-p*R%@C!wSSV)w7~7LP|@^;`ZcxvTz0eaVv@(3r!3{A)pKu863(xB9nL0QXquMX~oX(2v)^EL(ehMeB-=x z6cI?7Z3JU=sEWkq(u)J`^&3MQzlud{R^@NKE(@}cW{7Q2KA1u{VU3P7qVOC^gaJHK z0fHBUwk+>(`VU>jj=+bR!k@&`YskVOTXu0o(K*sj#mPM_Hg+WvhfU%h%NV-BIFN1a z_*cE&DG%RVv^;g^Agm?aA0RwTK`SxQjZ7Acm-5Sxhh3O-u%`N#+XQ&V1i;hkSQcV4 z%@7OO6q{#o8LNOxo5A;`A>RUR0svffD%_Lgtu!)MUGvu{2G<&yBa4ALy8-$69r<7j zWR!qJw{gn{!A`b)txAGUlE1zJgkVUbM9R_DciusgaNT!y7zx>^3if4iLV!pFFk}#b z9ApR=GT0#$q;wk0DhTP=V&TZdBGfwUnAm_xgYqIfK9XoF3EB$aYbB$IKn^k)twG`? z0_CZU)&Aj)3?f{IBz<>$H44Bvslw-&07Wu4WPzH2DoXmKW(^>p4l^Z`A^qPL$07v& zQ}t{s-m#`N4A60AjlmLIBd_HIaozsHmFd4MHUdQ$f`Ws)W&z?>dt%XK4W1#*;O|^n z#FC)k68A=p;FfyR1kH=;A){n*FLk*8o(4OJgGLaZ1M(tNd4F$h`Tzy@)de9;;$rjZ zU=kbw6bvAp4yFj~cOdZ$&cpE29c`BKhMJC@lEx5|6NWC1owvA5*n3H$!(6;`OyP|d z?7y$UPl1(Os;mZxxe-ZZBUp6On0-T)eWDW{&9E-*oFfpeCL)B15Z>Prq72eAH8Pys zY4sY23fN)|g`H7tiN`T1I1+mugV%$Ty_3kRL~(gA4i}-gNHOg$6FDve+<63C92Twy zFnDWNL>M2%r2_yvR7+sBSkSh_ajj~q>aJSq*{3?}Mj4zhh@2sW+pUZPLly7K;kumE zhW;Qm>dS zNA8D10Zh`{oy{Q1zcmuKe>xoa`Ct!OMhpxFmYEL28v$s?CniP^6PG7a!wl4R^A1NM zI$?*aD#GGo2qqlQx(YBC?>bYu&l`dlnd`DLV#4z};Y5;XFA3EOU>{&w*8py1M%WIN z{Cg&DPkMxX8D_7ULahK!X`pc0zI|!uUz;ve5rcOafa(PN3Ip&;lQ>v30LP#vIDx^7 zWWxNT7inad!d{n51`)@MFC?PmnT7q42zd&}1}|p~(fMtc?Z?PwxFP6g*M<1H_szoZ zR`K?e49*GSU0g_26ysnh99L-y_1J^eF?_!RIqS$AHI>=dqWZ-4?6vv`j};7mGsWr{ znyKdZvvft~_Jj~RyuLj|RdeWmINUe_FQE|>%!DdMAd3KkUcjJh6tSOLf`BkdU2Rhr zu)Ke$3#871Mn<0mwj)VNdF0>CPt6CI(76tDBM}pOL!?p%rJ?qf_+vFn$^0>s8b`G1 zAX=jjt;wAnoqC3G=y{<#V&n` ze+)YyIT(=Gqj@JddV|XtmZif9fi;Ij4naZ^dVla%Mu$XfNL>0MW(pw;7{hQO-hX>v zYXq=wA9C_+=zDg!6Z$TGCk=M1r)alX1ROnCJ1)GeUc9GJEUYW81O+`|3Jo$#z6T34 znAmWVk(9CVTP@?otxeFrVJ`XZMPP`LhM;5f8cr|5#pn;pNYl~3IbXvvmIxhW3gIB^ zuiu+bgc%f)?}w{Is}o@ZZ>X<YA6Tsl*z>islNH`mX)R6BHa zt}plg8Ouuh=O6MB?wa8rUM(H>!IYmNN`$k?6akWM%T4~*-dRK>GHg$yH}4}DHF zRLN7V_9c6B3gSEx@Y6#h@o*JaS@yOf3GjsEOFlP8$0nMg&r7SC0Fay{Og{8$<2r-+ z{6j`$0p82u%aas6TaM;>@FINT!)>>@l_ffNc&bdl;FPUM^2kOYhstdqyLhNvO@WI~oJG2ZdKS<@TodbDV@*9BWAhDf}h7rO1WA z*Gtz|HpfipG&K%|+N%LypVl|@|5MUl%n&P>hoqA}_rgP6| zfcuXv{{W7w=D|muCofTZ6NlPt{Wwb(8hOV`Iropf_NIFEaAfypD z%CbX}5)*WYhRJ-!L?$ewyGtIzNw8Y~o)5Y8KuP#R;L?xR-kF|JrK^cE@34E9uD%!f z^SSLFUkK(?<|#;@gb`QBp%hZoN6PvEgPQd8l4%8lqih z`|sJ?E~k9H%N2ryp4o;$vyfnD8W9S2r=mC>icbQk@I}-GK$;u>8^! zQfmy=&zi@TY3LI&vePbUTui>|qKaKPaa}8g<8j1(i~6HaV0|xUhhCO|;&Zz+-)p$q zMhEr>3&RlKT${+lBJ=DG5-la-lavJ3BC3{P`t#~Xhj*g`qCl%04j{?x5J}_tLuV^b zdoA=1P^Mj`n8jIR0d`R6A(iA5baj4K4jnVIe3y~l_tx{V)|E4eVIn(q`^oOT{4HqA8>s$@FqsH5T@G@~Z>=YWCeDZ^$ZzK+%wGw`%+;!4$Ha#u?F)vzI4&WL_;u9SG!O-?A`2F% zaW4&M<1#{ihsZmGPm=Xd0{hcQ@FF5qL#K(&QQipqXt`4nS&%=p+la{nC@SJt+AhN4 z&#wrbTbOc=3adqV-Vs9c;7suQroZm5oz&(&E5<3+``*5@2pxt_|Tx5gC#phq+Sm$(85Q}II@ z>T-ZUgNy=wTHojOk{@!+5HSrQh3a!j9Hr%A@xZc+qTdfoiF6m4zZOnm9GY_H-IpwL zY?F|8j32jt7Vu_2kw`59jQeM)fdxD)q0%dykUT1O6zTU|jOpa>bq+4T2U4SX<8a=D z6ZMTQinbJ>W07Iv-HD3^--}-;pjsbIvVPf>{-2?Q9UMJW$t#fCCnKV>RjqKm_R-y% zgKz-A=9xfc6UhISMOj@cA5@a|@8-A}tA0x_0A>6-rk_Ir9C0ji&F#zKi+;`s&nvTZ zo7YB{ zTKbs8xh~m{iZ0n!LyM_OMKc0N0L(q29d9HV;bB8HObJPPbo196jw5H1B^j!$Uil`I z(w25*@hdgt_$}AnE-MJH!zbAl5#^?349)cqg6P2< zOmq~&QNGsi!A56Ah|W`im`2PfK2d98QBvM(NN}78RW#2Xi4W}Iuqky95d5=d*>k)^ z7~enlB}(?%$nkri_~GmIn~RtEf3KkK9$x=7AGP9fWreLNdhBe)Zm#d3&_}rA=*Rxu z@}IxIgc}|v3yba7YX4bxk-TATD)yu4y1|;$d;3R^D-OC&$897B#4ddo+wQ%u^PM98 zJNUR_U)_#^VE}SJ%Kep@5M=GqzuSE15R;V{JrXQ>!TT*<>-faNse@|qTRYdof0f;~ zK$X~1r6T_NuU~k4X1e7T>mc(k>qnvQ(dF+s$j6Umj_=-1pnd+k5e$Iin^ky5g|0Rq zsK_0Dml2wl5o-m=gn%xx|Haq>93(+*hG2zOutA8Y5>igbR>l+$CTxT4@N6d1kl-qa z(GVL61a%65UI~$PotE{TmJG9%h-!u2+-4_zfL=2MYm;F$$?RWRV3~LTr4?SDC6j=c zB`)_C5fK@w_c$a+@+NcZra7zuoLC}fVE~79B}dCPdEA(|M50HR-|Cxua4aqfgpF68i?<$a|4JA5b4BJ7;gz{dL#Q@P3^tnnd7JCh%G8pv>C%?AnlL3H)x^JT7hg-fi#;1c58r(93NCp*!GU zf?$jt=z5zVrHyrqfJr9&N@~MoqYg6&*y6T>f;KE2^`n9yRKK%#?;qS2y4y?;?%O%g zBJ3qhqMx@2kIn3Nw~5RU)~5)f3!#UP2&3ay_jX%E*Jp$;K=zjHfS=pMj_icr6M(^~ zsN+x^Td*j67k4~?LxoAKSV~}bB}T?2B*G-CEhQCpC1b}W31L!pmQuRAQfA{)q%dh^ zOKFQ;X`XRuyD*ub7BX(TGRN!Uf}!Hx?Xq{rWdhaY9>V1!+vPfv^7?MUn|76*_Geot;N>utyPMzK3@j!lS|o zwTdb~W>m52YMy2U88ktmLk+&CMnK~=!`1iN)eSmSNa`Bz!!#_ym96(Q#?&;O&`NF{ znjO2E-W`gU!nLZ~wE{a7Le;g?!?a@@z1Qs z=<0eFVS4pw>83qBT{ZnKv{YY*zQV3P6D>IseiGY$@;O>!M%@4&X0Xt~5?|Ug_(nMO zxkGflR`l z87gZC5;Tmig&OH<2pH@eog)~VXz*Kf8lTxQwsYhYRmWWkGvRSC@#aHciZE4ZGYxd) z4b?Cc4K<6|N8a2wb80hTx56dnsl@M_0|^%SbNtDC)8{)a?Di}Il`U%{H0vD~aeJ0+ z5vu$Ig_)c)_vg;&?kHV4YxOe6VrHNHWrXz~{23V)tEK%DZzF7+T5UG@*mg9|8ibrZ z$^-q`KYJ5pQ)*)ynQNOqXPc^K%m0#v>9Sk@ZYSaNTRPG{9c9+KHIbPd!uyFcm^~15;&hfLOQ*o}-i#ewY`BqFjm2*zcE^1DpPD0+AKck%VVt@R+ z6)7DV>FTZOn)M&L&o4!?KnmCe`ip=bI0qpj#vAA~W5`py1yYv|+c1y0`C{ z0+F)^=Yj3!+L^u%1;Q>-=O*TyDarh%B(zU~u% z?XnwF;1&t1xGv`Id?BgeLdq)vcZtjSQCH09{AB`HH%+dNjHNdUV1nrU=HBS;ZXs<7 zpZkgc85r;!c;Sbga3vi}0}6W3`Ers4`O#ToGrUWR|DdGRoPPhsvL}OksWd>J= z@|{n>R7wbO7Y2Dc3Wp8*&p5xs^DDiqWvqt6QlsP;tcn08e1^{5eMbUr;akjdhAUE%Zr%=ZfN8{nXi$ow8mfoKY* z=I8mko*ROKF)_f{a}xhT%#;)okXYTM7Q2V&%;D-ouo5G6mwCXA}y0X$$q{ zM+bf?%qYa%0t)&u`Jugh9MOCT3}2;AN^NvXeQ!$BVM?1$YFBh>UvKKe!&IhD+DLTT zSZ~_%!?YQlf3oECh2Hd~!}JxMjL*>-OY_O$y?jyg{C+^eVZp1Y*4saJ;_9nt6pCO7 zQy{08-<`tmD#0)E|2C&FISQ=49Oa`Nf^M#6Os;NUuE9|*NjJ|VCeNZT&-y6OPB-5v zCf}_u-}5NnTesj`aW=nOW*|^7&h<8(F3&9(dg=NFjq9PM5;rL;f`}u50ATiI@8aUV z;_{BFN^rf%6tOxajp+4G~a8Qt=iG35(=^5)e%za_->0j8H*=_?R-iNSu z%*njW&HT*KJk8a7&Dp%o-TckrJkI5O&gs0)?flO1JkRy~%d@=C{rt}XJ?vuK|Rz(ebh<4)J^@= zQ9adFebrgL)m{D7VLjGmeb#Bc)@}XPaXr^{eb;%t*M0rhfj!uTeb|Y;*p2e5UqN|JlbM*bP^# zAH4hWz3JNXFF!Y_Vc`*xQPDB6aq$U>e6SQ6EGa$X#?4!XskF?T+`Kz8HVb|3^bpF9BmDkUZ zvZMSjILCJmj(qej`=m58dw6=`%gF}z&XrZmrS**;KYu~r|9}vYG=~QR>oMC|r{mdy{G{zz`&_c7VCJQ<{ z>7st2^f_m{Kl+c*0=XB3Ji&|h@%Ep}O2|s1k7fdV?0HQe_`L6Vc<=QCN^AV~gLM^e zYP<&Ty7t!He^>86)suU$zViL!kkz^Oz4Z@1Jfk8wC9E146RolQO2_*es-`+=(g*Xb z8mm9{W@`G5^)=Rfeoi+^kT~?Hc6PAL?%whKM-S&;GfwvA9eP~1_^#o?{8<0v`Y#`t z5u7`$n;Mp>@l5{_nO(pBE&rGF| z&60Ptl)8nT1r`uj7 z<)5SjM>`*$dO&Iug${+t`~sr+-^mG#-rcc^H^8G59U&rE)-?A@7yMD4kmLYk@K zY*B`T&unp~=iS+ooZz|HQhK!FTv^dgpSkj~lDl(vE9&Ov?lC$P=PPQ5edg~se7ZYd z*|a`4|A2{BT41yZ`7Ts-$=+M2-t5z!U#MZ3DlOIyIruI<9PzxjST`CxzgRyWt+doI zebaZTai-+n(xZjC`K8C~4y7+mYs0=@o_zmw@5|F)>+@fpK^SE=6DjP+ZpO-0uv_pt z3+z^cneuX*fTQ1XyU6K^BhmzusU{rtkj?E1xS6F&EAxl8WBua!QXFTYk)f9kGo=sy{IO8~<j)MG3ISjV#~4SRt0>w zy4qy*mgC5Y1p=k!?TXIJ@lJgOLfh)Q+Ep(tCs6Q(BAwbOIp&#ei>~q;D+$NZcaS&Cm|^M#B0!`_GW}g@px4DP^Lh5(a~5D_DPe zYyENRx7QuZeO0Spz9%%LeS4ht?McSBj*_**wxp@4sXoTq%=F^3%=LqZ_A|5AJBq)~ z&n= z(~Hq&7Wg{KBHOzrZjd=Oy+S0dptHY$~#kD7w(lRN>-OW9H4!WPRh_MJbq35Wpr)_I* zI5|0H?`SmaRo-8-5^j2~+BubEwC8*vxxMJ?ynh3$e&yA(RSivDT|I+SUI%^s{7uaC zKb@@|VzT>tJ0G`PaMZCG9Apg-zkJpaXt&$?-BehIdtT@@dsf5p{O6_9r+q&RvDa3= zWahauZ?8ACU1+7R8yWB0N75}UKfSax^W=DDYHIph?~3k<)rM#O>tESX@y_F8Q;YLU zCnz2dAD`QQ!0gIZs_(fξY!E?jIY{LixCzB#-uzmCx*GYa7FXf!>D? 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�aQOYm63r3h0juygtBU{+*)#tZ%l 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 Y-?r?^S^CG}yZI%j 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

Mo>XK?+6oB07?2VI|sT#WR&$ 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%0AVl7Y1h+ieu%%wSPWIZt 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 b(rw+^?cL&S-sp?S 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 F{|o*zO8o!; literal 0 HcmV?d00001 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. From c1834605320c2187833957b74c63654eb90f8053 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Wed, 10 Apr 2024 09:34:22 +0800 Subject: [PATCH 113/598] ci(github-actions): replace env with "with" for docpublish aciton this has been changed since 3.0 as well https://github.com/peaceiris/actions-gh-pages/issues/123 --- .github/workflows/docspublish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index 1001be8d9b..11f509b5b8 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -32,7 +32,7 @@ jobs: file: 'docs/README.md' - name: Push doc to Github Page uses: peaceiris/actions-gh-pages@v4 - env: + with: personal_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} publish_branch: gh-pages publish_dir: ./site From 5e2cc6c67a6d5d437db1c1a782d5aa4c6b7b0176 Mon Sep 17 00:00:00 2001 From: rockleona <34214497+rockleona@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:13:46 +0800 Subject: [PATCH 114/598] feat(cli): add config option to specify config file path Issue #656 --- commitizen/cli.py | 11 +++++++++-- commitizen/config/__init__.py | 24 +++++++++++++++++++++++- commitizen/exceptions.py | 6 ++++++ tests/test_cli.py | 10 ++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index a442803d7f..d96d675850 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -92,6 +92,10 @@ def __call__( ), "formatter_class": argparse.RawDescriptionHelpFormatter, "arguments": [ + { + "name": "--config", + "help": "specify file path if config file is not in root folder", + }, {"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..883c0ded33 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 from .base_config import BaseConfig from .json_config import JsonConfig @@ -10,10 +11,31 @@ 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() + + if filepath is not None: + given_cfg_path = Path(filepath) + + if not given_cfg_path.exists(): + raise ConfigFileNotFound() + + with open(given_cfg_path, "rb") as f: + given_cfg_data: bytes = f.read() + + given_cfg: TomlConfig | JsonConfig | YAMLConfig + + if "toml" in given_cfg_path.suffix: + given_cfg = TomlConfig(data=given_cfg_data, path=given_cfg_path) + elif "json" in given_cfg_path.suffix: + given_cfg = JsonConfig(data=given_cfg_data, path=given_cfg_path) + elif "yaml" in given_cfg_path.suffix: + given_cfg = YAMLConfig(data=given_cfg_data, path=given_cfg_path) + + return given_cfg + cfg_search_paths = [Path(".")] if git_project_root: cfg_search_paths.append(git_project_root) diff --git a/commitizen/exceptions.py b/commitizen/exceptions.py index 31b867b8f9..52c300a938 100644 --- a/commitizen/exceptions.py +++ b/commitizen/exceptions.py @@ -34,6 +34,7 @@ class ExitCode(enum.IntEnum): VERSION_PROVIDER_UNKNOWN = 27 VERSION_SCHEME_UNKNOWN = 28 CHANGELOG_FORMAT_UNKNOWN = 29 + CONFIG_FILE_NOT_FOUND = 30 class CommitizenException(Exception): @@ -189,3 +190,8 @@ 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." 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) From 85a5ec27d690f8b6e5c2556364631a6325768e04 Mon Sep 17 00:00:00 2001 From: rockleona <34214497+rockleona@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:54:33 +0800 Subject: [PATCH 115/598] test(test_conf.py): add a test case for --config option --- tests/test_conf.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_conf.py b/tests/test_conf.py index a12bcdd35d..12207271db 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -158,6 +158,15 @@ 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_not_in_root_folder(_, tmpdir): + with tmpdir.as_cwd(): + _not_root_path = tmpdir.mkdir("not_in_root") + p = tmpdir.join("./not_in_root/pyproject.toml") + p.write(PYPROJECT) + + cfg = config.read_cfg(filepath="./not_in_root/pyproject.toml") + assert cfg.settings == _settings + class TestTomlConfig: def test_init_empty_config_content(self, tmpdir): From 88ab61ded44178a65d03efadb00bdabfb1a09aeb Mon Sep 17 00:00:00 2001 From: rockleona <34214497+rockleona@users.noreply.github.com> Date: Mon, 1 Apr 2024 22:55:01 +0800 Subject: [PATCH 116/598] test(test_conf.py): add test case for specify yaml and json files --- tests/test_conf.py | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/tests/test_conf.py b/tests/test_conf.py index 12207271db..8d2a0233da 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -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", @@ -160,13 +181,30 @@ def test_load_empty_pyproject_toml_and_cz_toml_with_config(_, tmpdir): def test_load_pyproject_toml_not_in_root_folder(_, tmpdir): with tmpdir.as_cwd(): - _not_root_path = tmpdir.mkdir("not_in_root") - p = tmpdir.join("./not_in_root/pyproject.toml") - p.write(PYPROJECT) + _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_in_root_folder(_, 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_in_root_folder(_, 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=JSON_STR, path=_not_root_path) + assert cfg.settings == yaml_cfg_by_class._settings + class TestTomlConfig: def test_init_empty_config_content(self, tmpdir): From a1cfdb086fc7030c406b090115245799e7d97de4 Mon Sep 17 00:00:00 2001 From: rockleona <34214497+rockleona@users.noreply.github.com> Date: Mon, 1 Apr 2024 23:05:12 +0800 Subject: [PATCH 117/598] docs(README): add --config option in doc --- docs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/README.md b/docs/README.md index e48062e168..8822826595 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 specify file path if config file is not in root folder --debug use debug mode -n NAME, --name NAME use the given commitizen (default: cz_conventional_commits) -nr NO_RAISE, --no-raise NO_RAISE From a47bdd04fd121bc675fb57a374f91cc528529523 Mon Sep 17 00:00:00 2001 From: rockleona <34214497+rockleona@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:44:30 +0800 Subject: [PATCH 118/598] test(conf): add test case if config file is given in argument --- commitizen/cli.py | 2 +- commitizen/config/__init__.py | 44 +++++++++++++---------------------- commitizen/exceptions.py | 6 +++++ docs/README.md | 2 +- tests/test_conf.py | 18 ++++++++++---- 5 files changed, 37 insertions(+), 35 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index d96d675850..cf3d6c5eef 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -94,7 +94,7 @@ def __call__( "arguments": [ { "name": "--config", - "help": "specify file path if config file is not in root folder", + "help": "the path of configuration file", }, {"name": "--debug", "action": "store_true", "help": "use debug mode"}, { diff --git a/commitizen/config/__init__.py b/commitizen/config/__init__.py index 883c0ded33..a9395fca7d 100644 --- a/commitizen/config/__init__.py +++ b/commitizen/config/__init__.py @@ -3,7 +3,7 @@ from pathlib import Path from commitizen import defaults, git -from commitizen.exceptions import ConfigFileNotFound +from commitizen.exceptions import ConfigFileNotFound, ConfigFileIsEmpty from .base_config import BaseConfig from .json_config import JsonConfig @@ -14,37 +14,23 @@ def read_cfg(filepath: str | None = None) -> BaseConfig: conf = BaseConfig() - git_project_root = git.find_git_project_root() - if filepath is not None: - given_cfg_path = Path(filepath) - - if not given_cfg_path.exists(): + if not Path(filepath).exists(): raise ConfigFileNotFound() - with open(given_cfg_path, "rb") as f: - given_cfg_data: bytes = f.read() - - given_cfg: TomlConfig | JsonConfig | YAMLConfig - - if "toml" in given_cfg_path.suffix: - given_cfg = TomlConfig(data=given_cfg_data, path=given_cfg_path) - elif "json" in given_cfg_path.suffix: - given_cfg = JsonConfig(data=given_cfg_data, path=given_cfg_path) - elif "yaml" in given_cfg_path.suffix: - given_cfg = YAMLConfig(data=given_cfg_data, path=given_cfg_path) - - return given_cfg + 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_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 @@ -61,7 +47,9 @@ def read_cfg(filepath: str | None = None) -> 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 52c300a938..9cb1517680 100644 --- a/commitizen/exceptions.py +++ b/commitizen/exceptions.py @@ -35,6 +35,7 @@ class ExitCode(enum.IntEnum): VERSION_SCHEME_UNKNOWN = 28 CHANGELOG_FORMAT_UNKNOWN = 29 CONFIG_FILE_NOT_FOUND = 30 + CONFIG_FILE_IS_EMPTY = 31 class CommitizenException(Exception): @@ -195,3 +196,8 @@ class ChangelogFormatUnknown(CommitizenException): 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 8822826595..8c7dc51e48 100644 --- a/docs/README.md +++ b/docs/README.md @@ -107,7 +107,7 @@ For more information about the topic go to https://conventionalcommits.org/ optional arguments: -h, --help show this help message and exit - --config specify file path if config file is not in root folder + --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/tests/test_conf.py b/tests/test_conf.py index 8d2a0233da..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] @@ -179,7 +179,7 @@ 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_not_in_root_folder(_, tmpdir): + 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) @@ -187,7 +187,7 @@ def test_load_pyproject_toml_not_in_root_folder(_, tmpdir): cfg = config.read_cfg(filepath="./not_in_root/pyproject.toml") assert cfg.settings == _settings - def test_load_cz_json_not_in_root_folder(_, tmpdir): + 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) @@ -196,15 +196,23 @@ def test_load_cz_json_not_in_root_folder(_, tmpdir): 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_in_root_folder(_, tmpdir): + 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=JSON_STR, path=_not_root_path) + 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): From 7c0bc1591103b1f089aab9810fc2a201ccb0552b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 11 Apr 2024 15:13:46 +0000 Subject: [PATCH 119/598] =?UTF-8?q?bump:=20version=203.21.3=20=E2=86=92=20?= =?UTF-8?q?3.22.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) 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 a27d8610ec..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 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/pyproject.toml b/pyproject.toml index 3410a50aba..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" From ef19711f544fc65d60711837cb9995d5081ef75c Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 4 Apr 2024 18:20:18 +0800 Subject: [PATCH 120/598] ci(github-actions): unify yaml style --- .github/workflows/bumpversion.yml | 2 +- .github/workflows/docspublish.yml | 58 +++++++++++++-------------- .github/workflows/homebrewpublish.yml | 38 +++++++++--------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/.github/workflows/bumpversion.yml b/.github/workflows/bumpversion.yml index ed010b4158..ed0c8cffce 100644 --- a/.github/workflows/bumpversion.yml +++ b/.github/workflows/bumpversion.yml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - token: '${{ secrets.PERSONAL_ACCESS_TOKEN }}' + token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}" - name: Create bump and changelog uses: commitizen-tools/commitizen-action@master with: diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index 11f509b5b8..747e509dc3 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -9,32 +9,32 @@ jobs: publish-documentation: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - with: - token: '${{ secrets.PERSONAL_ACCESS_TOKEN }}' - fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install -U mkdocs mkdocs-material - - name: Build docs - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - python -m mkdocs build - - name: Generate Sponsors 💖 - uses: JamesIves/github-sponsors-readme-action@v1 - with: - token: ${{ secrets.PERSONAL_ACCESS_TOKEN_FOR_ORG }} - file: 'docs/README.md' - - name: Push doc to Github Page - 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" + - uses: actions/checkout@v4 + with: + token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}" + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + - name: Install dependencies + run: | + python -m pip install -U mkdocs mkdocs-material + - name: Build docs + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + python -m mkdocs build + - name: Generate Sponsors 💖 + uses: JamesIves/github-sponsors-readme-action@v1 + with: + token: ${{ secrets.PERSONAL_ACCESS_TOKEN_FOR_ORG }} + file: "docs/README.md" + - name: Push doc to Github Page + uses: peaceiris/actions-gh-pages@v2 + 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/.github/workflows/homebrewpublish.yml b/.github/workflows/homebrewpublish.yml index a2610229bc..84c2ca6ca0 100644 --- a/.github/workflows/homebrewpublish.yml +++ b/.github/workflows/homebrewpublish.yml @@ -11,22 +11,22 @@ jobs: runs-on: macos-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install -U commitizen - - name: Set Project version env variable - run: | - echo "project_version=$(cz version --project)" >> $GITHUB_ENV - - name: Update Homebrew formula - uses: dawidd6/action-homebrew-bump-formula@v3 - with: - token: ${{secrets.PERSONAL_ACCESS_TOKEN}} - formula: commitizen - tag: v${{ env.project_version }} - force: true + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + - name: Install dependencies + run: | + python -m pip install -U commitizen + - name: Set Project version env variable + run: | + echo "project_version=$(cz version --project)" >> $GITHUB_ENV + - name: Update Homebrew formula + uses: dawidd6/action-homebrew-bump-formula@v3 + with: + token: ${{secrets.PERSONAL_ACCESS_TOKEN}} + formula: commitizen + tag: v${{ env.project_version }} + force: true From aa658be9ab3bc07ecad7c440dc7fc2056e39675f Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 4 Apr 2024 18:21:13 +0800 Subject: [PATCH 121/598] ci(github-actions): unpin poetry as #7611 has been closed --- .github/workflows/pythonpackage.yml | 9 ++++----- .github/workflows/pythonpublish.yml | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index f5967f3a93..8ffa398611 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -1,13 +1,13 @@ name: Python package -on: [ workflow_dispatch, pull_request ] +on: [workflow_dispatch, pull_request] jobs: python-check: strategy: matrix: - python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] - platform: [ ubuntu-20.04, macos-latest, windows-latest ] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + platform: [ubuntu-20.04, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 @@ -19,8 +19,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - # pin poetry to 1.3.2 due to https://github.com/python-poetry/poetry/issues/7611 - python -m pip install -U pip poetry==1.3.2 + python -m pip install -U pip poetry poetry --version poetry install - name: Run tests and linters diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml index f31691a50b..e3b3aa6f30 100644 --- a/.github/workflows/pythonpublish.yml +++ b/.github/workflows/pythonpublish.yml @@ -3,7 +3,7 @@ name: Upload Python Package on: push: tags: - - 'v*' + - "v*" jobs: deploy: @@ -11,16 +11,15 @@ jobs: steps: - uses: actions/checkout@v4 with: - token: '${{ secrets.PERSONAL_ACCESS_TOKEN }}' + token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}" fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.x' + python-version: "3.x" - name: Install dependencies run: | - # pin poetry to 1.3.2 due to https://github.com/python-poetry/poetry/issues/7611 - python -m pip install -U pip poetry==1.3.2 mkdocs mkdocs-material + python -m pip install -U pip poetry mkdocs mkdocs-material poetry --version poetry install - name: Publish From fb151454f449eb76cd7bb032fb725aa2a268dbc4 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 4 Apr 2024 18:24:35 +0800 Subject: [PATCH 122/598] ci(scripts): fix ill-formated code when running formatters --- scripts/test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/test b/scripts/test index e2fa065142..08889af8b0 100755 --- a/scripts/test +++ b/scripts/test @@ -5,7 +5,7 @@ export PREFIX='poetry run python -m ' export REGEX='^(?![.]|venv).*' ${PREFIX}pytest -n 3 --dist=loadfile --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen tests/ -${PREFIX}black commitizen tests --check -${PREFIX}ruff commitizen/ tests/ +${PREFIX}black commitizen tests +${PREFIX}ruff check commitizen/ tests/ --fix ${PREFIX}mypy commitizen/ tests/ ${PREFIX}commitizen -nr 3 check --rev-range origin/master.. From a4c19c23d600a6834c2533b6131d05999782630d Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 4 Apr 2024 18:25:25 +0800 Subject: [PATCH 123/598] ci(github-actions): replace "./scripts/test" with pre-commit for unifying the checking process --- .github/workflows/pythonpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 8ffa398611..7d5f20577a 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -26,7 +26,7 @@ jobs: run: | git config --global user.email "action@github.com" git config --global user.name "GitHub Action" - ./scripts/test + poetry run pre-commit run --all-files shell: bash - name: Upload coverage to Codecov if: runner.os == 'Linux' From 18b471ad6d03d53b603ccf4ede645fa858b5200a Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sat, 6 Apr 2024 19:11:17 +0800 Subject: [PATCH 124/598] ci(github-actions): skip no-commit-to-branch in CI which causes false negative when bumping version --- .github/workflows/pythonpackage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 7d5f20577a..3b5d5305a3 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -26,13 +26,13 @@ jobs: run: | git config --global user.email "action@github.com" git config --global user.name "GitHub Action" - poetry run pre-commit run --all-files + SKIP=no-commit-to-branch,commitizen-branch poetry run pre-commit run --all-files --hook-stage pre-push shell: bash - name: Upload coverage to Codecov if: runner.os == 'Linux' uses: codecov/codecov-action@v4 with: - token: ${{secrets.CODECOV_TOKEN}} + token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.xml flags: unittests name: codecov-umbrella From bf98a9ba5571a35412f78990931b46ef10368a14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 01:38:29 +0000 Subject: [PATCH 125/598] build(deps-dev): bump ruff from 0.3.5 to 0.3.6 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.5 to 0.3.6. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.3.5...v0.3.6) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4cc8f16674..6c6c26d030 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1461,28 +1461,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.3.5" +version = "0.3.6" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {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"}, + {file = "ruff-0.3.6-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:732ef99984275534f9466fbc01121523caf72aa8c2bdeb36fd2edf2bc294a992"}, + {file = "ruff-0.3.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:93699d61116807edc5ca1cdf9d2d22cf8d93335d59e3ff0ca7aee62c1818a736"}, + {file = "ruff-0.3.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc4006cbc6c11fefc25f122d2eb4731d7a3d815dc74d67c54991cc3f99c90177"}, + {file = "ruff-0.3.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:878ef1a55ce931f3ca23b690b159cd0659f495a4c231a847b00ca55e4c688baf"}, + {file = "ruff-0.3.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecb87788284af96725643eae9ab3ac746d8cc09aad140268523b019f7ac3cd98"}, + {file = "ruff-0.3.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b2e79f8e1b6bd5411d7ddad3f2abff3f9d371beda29daef86400d416dedb7e02"}, + {file = "ruff-0.3.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf48ec2c4bfae7837dc325c431a2932dc23a1485e71c59591c1df471ba234e0e"}, + {file = "ruff-0.3.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c466a52c522e6a08df0af018f550902f154f5649ad09e7f0d43da766e7399ebc"}, + {file = "ruff-0.3.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28ccf3fb6d1162a73cd286c63a5e4d885f46a1f99f0b392924bc95ccbd18ea8f"}, + {file = "ruff-0.3.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b11e09439d9df6cc12d9f622065834654417c40216d271f639512d80e80e3e53"}, + {file = "ruff-0.3.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:647f1fb5128a3e24ce68878b8050bb55044c45bb3f3ae4710d4da9ca96ede5cb"}, + {file = "ruff-0.3.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2b0c4c70578ef1871a9ac5c85ed7a8c33470e976c73ba9211a111d2771b5f787"}, + {file = "ruff-0.3.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e3da499ded004d0b956ab04248b2ae17e54a67ffc81353514ac583af5959a255"}, + {file = "ruff-0.3.6-py3-none-win32.whl", hash = "sha256:4056480f5cf38ad278667c31b0ef334c29acdfcea617cb89c4ccbc7d96f1637f"}, + {file = "ruff-0.3.6-py3-none-win_amd64.whl", hash = "sha256:f1aa621beed533f46e9c7d6fe00e7f6e4570155b61d8f020387b72ace2b42e04"}, + {file = "ruff-0.3.6-py3-none-win_arm64.whl", hash = "sha256:7c8a2a0e0cab077a07465259ffe3b3c090e747ca8097c5dc4c36ca0fdaaac90d"}, + {file = "ruff-0.3.6.tar.gz", hash = "sha256:26071fb530038602b984e3bbe1443ef82a38450c4dcb1344a9caf67234ff9756"}, ] [[package]] From afb9d3ec2fff860b79a99597297b1b92fd22b702 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 12 Apr 2024 10:26:15 +0800 Subject: [PATCH 126/598] ci(github-actions): update peaceiris/actions-gh-pages to v4 --- .github/workflows/docspublish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index 747e509dc3..d95b464b40 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -31,7 +31,7 @@ jobs: token: ${{ secrets.PERSONAL_ACCESS_TOKEN_FOR_ORG }} file: "docs/README.md" - name: Push doc to Github Page - uses: peaceiris/actions-gh-pages@v2 + uses: peaceiris/actions-gh-pages@v4 with: personal_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} publish_branch: gh-pages From 46c5a5cac4da36aa81d1e2e8e6c5d5262aa600eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 01:59:09 +0000 Subject: [PATCH 127/598] build(deps-dev): bump idna from 3.6 to 3.7 Bumps [idna](https://github.com/kjd/idna) from 3.6 to 3.7. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) - [Commits](https://github.com/kjd/idna/compare/v3.6...v3.7) --- updated-dependencies: - dependency-name: idna dependency-type: indirect ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6c6c26d030..04b72c0aec 100644 --- a/poetry.lock +++ b/poetry.lock @@ -485,13 +485,13 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] From 8e36212d24610b9a5520183a4c2a0b87d8c82141 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 01:52:19 +0000 Subject: [PATCH 128/598] build(deps): bump argcomplete from 3.2.3 to 3.3.0 Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 3.2.3 to 3.3.0. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v3.2.3...v3.3.0) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 04b72c0aec..d43c069db1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,13 +13,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.2.3" +version = "3.3.0" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.2.3-py3-none-any.whl", hash = "sha256:c12355e0494c76a2a7b73e3a59b09024ca0ba1e279fb9ed6c1b82d5b74b6a70c"}, - {file = "argcomplete-3.2.3.tar.gz", hash = "sha256:bf7900329262e481be5a15f56f19736b376df6f82ed27576fa893652c5de6c23"}, + {file = "argcomplete-3.3.0-py3-none-any.whl", hash = "sha256:c168c3723482c031df3c207d4ba8fa702717ccb9fc0bfe4117166c1f537b4a54"}, + {file = "argcomplete-3.3.0.tar.gz", hash = "sha256:fd03ff4a5b9e6580569d34b273f741e85cd9e072f3feeeee3eba4891c70eda62"}, ] [package.extras] @@ -1820,4 +1820,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "5cd809db4e9dc8005ab2295ca7d182435021752953a7b1552bb81912b54df791" +content-hash = "abe023abef8eaadaffaa2b8725bc1958b6597cc8e07f0899cf751d5ce28cab82" diff --git a/pyproject.toml b/pyproject.toml index b6d766ef19..2014e323ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ packaging = ">=19" tomlkit = ">=0.5.3,<1.0.0" jinja2 = ">=2.10.3" pyyaml = ">=3.08" -argcomplete = ">=1.12.1,<3.3" +argcomplete = ">=1.12.1,<3.4" typing-extensions = { version = "^4.0.1", python = "<3.8" } charset-normalizer = ">=2.1.0,<4" # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility From e7a7c92b136c13f7bd97eb827004240802131e47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 08:26:27 +0000 Subject: [PATCH 129/598] build(deps-dev): bump black from 24.3.0 to 24.4.0 Bumps [black](https://github.com/psf/black) from 24.3.0 to 24.4.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/24.3.0...24.4.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/poetry.lock b/poetry.lock index d43c069db1..0e13e63fa2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -73,33 +73,33 @@ files = [ [[package]] name = "black" -version = "24.3.0" +version = "24.4.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"}, - {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"}, - {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"}, - {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"}, - {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"}, - {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"}, - {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"}, - {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"}, - {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"}, - {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"}, - {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"}, - {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"}, - {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"}, - {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"}, - {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"}, - {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"}, - {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"}, - {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"}, - {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"}, - {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, - {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, - {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, + {file = "black-24.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6ad001a9ddd9b8dfd1b434d566be39b1cd502802c8d38bbb1ba612afda2ef436"}, + {file = "black-24.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3a3a092b8b756c643fe45f4624dbd5a389f770a4ac294cf4d0fce6af86addaf"}, + {file = "black-24.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dae79397f367ac8d7adb6c779813328f6d690943f64b32983e896bcccd18cbad"}, + {file = "black-24.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:71d998b73c957444fb7c52096c3843875f4b6b47a54972598741fe9a7f737fcb"}, + {file = "black-24.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e5537f456a22cf5cfcb2707803431d2feeb82ab3748ade280d6ccd0b40ed2e8"}, + {file = "black-24.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64e60a7edd71fd542a10a9643bf369bfd2644de95ec71e86790b063aa02ff745"}, + {file = "black-24.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd5b4f76056cecce3e69b0d4c228326d2595f506797f40b9233424e2524c070"}, + {file = "black-24.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:64578cf99b6b46a6301bc28bdb89f9d6f9b592b1c5837818a177c98525dbe397"}, + {file = "black-24.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f95cece33329dc4aa3b0e1a771c41075812e46cf3d6e3f1dfe3d91ff09826ed2"}, + {file = "black-24.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4396ca365a4310beef84d446ca5016f671b10f07abdba3e4e4304218d2c71d33"}, + {file = "black-24.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d99dfdf37a2a00a6f7a8dcbd19edf361d056ee51093b2445de7ca09adac965"}, + {file = "black-24.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:21f9407063ec71c5580b8ad975653c66508d6a9f57bd008bb8691d273705adcd"}, + {file = "black-24.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:652e55bb722ca026299eb74e53880ee2315b181dfdd44dca98e43448620ddec1"}, + {file = "black-24.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7f2966b9b2b3b7104fca9d75b2ee856fe3fdd7ed9e47c753a4bb1a675f2caab8"}, + {file = "black-24.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bb9ca06e556a09f7f7177bc7cb604e5ed2d2df1e9119e4f7d2f1f7071c32e5d"}, + {file = "black-24.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4e71cdebdc8efeb6deaf5f2deb28325f8614d48426bed118ecc2dcaefb9ebf3"}, + {file = "black-24.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6644f97a7ef6f401a150cca551a1ff97e03c25d8519ee0bbc9b0058772882665"}, + {file = "black-24.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:75a2d0b4f5eb81f7eebc31f788f9830a6ce10a68c91fbe0fade34fff7a2836e6"}, + {file = "black-24.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb949f56a63c5e134dfdca12091e98ffb5fd446293ebae123d10fc1abad00b9e"}, + {file = "black-24.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:7852b05d02b5b9a8c893ab95863ef8986e4dda29af80bbbda94d7aee1abf8702"}, + {file = "black-24.4.0-py3-none-any.whl", hash = "sha256:74eb9b5420e26b42c00a3ff470dc0cd144b80a766128b1771d07643165e08d0e"}, + {file = "black-24.4.0.tar.gz", hash = "sha256:f07b69fda20578367eaebbd670ff8fc653ab181e1ff95d84497f9fa20e7d0641"}, ] [package.dependencies] From a0aee07f67e706a8cff90b591135eb0fe0793ca4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 08:48:36 +0000 Subject: [PATCH 130/598] build(deps-dev): bump ruff from 0.3.6 to 0.3.7 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.6 to 0.3.7. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.3.6...v0.3.7) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0e13e63fa2..33419080b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1461,28 +1461,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.3.6" +version = "0.3.7" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.3.6-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:732ef99984275534f9466fbc01121523caf72aa8c2bdeb36fd2edf2bc294a992"}, - {file = "ruff-0.3.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:93699d61116807edc5ca1cdf9d2d22cf8d93335d59e3ff0ca7aee62c1818a736"}, - {file = "ruff-0.3.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc4006cbc6c11fefc25f122d2eb4731d7a3d815dc74d67c54991cc3f99c90177"}, - {file = "ruff-0.3.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:878ef1a55ce931f3ca23b690b159cd0659f495a4c231a847b00ca55e4c688baf"}, - {file = "ruff-0.3.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecb87788284af96725643eae9ab3ac746d8cc09aad140268523b019f7ac3cd98"}, - {file = "ruff-0.3.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b2e79f8e1b6bd5411d7ddad3f2abff3f9d371beda29daef86400d416dedb7e02"}, - {file = "ruff-0.3.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf48ec2c4bfae7837dc325c431a2932dc23a1485e71c59591c1df471ba234e0e"}, - {file = "ruff-0.3.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c466a52c522e6a08df0af018f550902f154f5649ad09e7f0d43da766e7399ebc"}, - {file = "ruff-0.3.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28ccf3fb6d1162a73cd286c63a5e4d885f46a1f99f0b392924bc95ccbd18ea8f"}, - {file = "ruff-0.3.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b11e09439d9df6cc12d9f622065834654417c40216d271f639512d80e80e3e53"}, - {file = "ruff-0.3.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:647f1fb5128a3e24ce68878b8050bb55044c45bb3f3ae4710d4da9ca96ede5cb"}, - {file = "ruff-0.3.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2b0c4c70578ef1871a9ac5c85ed7a8c33470e976c73ba9211a111d2771b5f787"}, - {file = "ruff-0.3.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e3da499ded004d0b956ab04248b2ae17e54a67ffc81353514ac583af5959a255"}, - {file = "ruff-0.3.6-py3-none-win32.whl", hash = "sha256:4056480f5cf38ad278667c31b0ef334c29acdfcea617cb89c4ccbc7d96f1637f"}, - {file = "ruff-0.3.6-py3-none-win_amd64.whl", hash = "sha256:f1aa621beed533f46e9c7d6fe00e7f6e4570155b61d8f020387b72ace2b42e04"}, - {file = "ruff-0.3.6-py3-none-win_arm64.whl", hash = "sha256:7c8a2a0e0cab077a07465259ffe3b3c090e747ca8097c5dc4c36ca0fdaaac90d"}, - {file = "ruff-0.3.6.tar.gz", hash = "sha256:26071fb530038602b984e3bbe1443ef82a38450c4dcb1344a9caf67234ff9756"}, + {file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0e8377cccb2f07abd25e84fc5b2cbe48eeb0fea9f1719cad7caedb061d70e5ce"}, + {file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:15a4d1cc1e64e556fa0d67bfd388fed416b7f3b26d5d1c3e7d192c897e39ba4b"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d28bdf3d7dc71dd46929fafeec98ba89b7c3550c3f0978e36389b5631b793663"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:379b67d4f49774ba679593b232dcd90d9e10f04d96e3c8ce4a28037ae473f7bb"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c060aea8ad5ef21cdfbbe05475ab5104ce7827b639a78dd55383a6e9895b7c51"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ebf8f615dde968272d70502c083ebf963b6781aacd3079081e03b32adfe4d58a"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48098bd8f5c38897b03604f5428901b65e3c97d40b3952e38637b5404b739a2"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da8a4fda219bf9024692b1bc68c9cff4b80507879ada8769dc7e985755d662ea"}, + {file = "ruff-0.3.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c44e0149f1d8b48c4d5c33d88c677a4aa22fd09b1683d6a7ff55b816b5d074f"}, + {file = "ruff-0.3.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3050ec0af72b709a62ecc2aca941b9cd479a7bf2b36cc4562f0033d688e44fa1"}, + {file = "ruff-0.3.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a29cc38e4c1ab00da18a3f6777f8b50099d73326981bb7d182e54a9a21bb4ff7"}, + {file = "ruff-0.3.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b15cc59c19edca917f51b1956637db47e200b0fc5e6e1878233d3a938384b0b"}, + {file = "ruff-0.3.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e491045781b1e38b72c91247cf4634f040f8d0cb3e6d3d64d38dcf43616650b4"}, + {file = "ruff-0.3.7-py3-none-win32.whl", hash = "sha256:bc931de87593d64fad3a22e201e55ad76271f1d5bfc44e1a1887edd0903c7d9f"}, + {file = "ruff-0.3.7-py3-none-win_amd64.whl", hash = "sha256:5ef0e501e1e39f35e03c2acb1d1238c595b8bb36cf7a170e7c1df1b73da00e74"}, + {file = "ruff-0.3.7-py3-none-win_arm64.whl", hash = "sha256:789e144f6dc7019d1f92a812891c645274ed08af6037d11fc65fcbc183b7d59f"}, + {file = "ruff-0.3.7.tar.gz", hash = "sha256:d5c1aebee5162c2226784800ae031f660c350e7a3402c4d1f8ea4e97e232e3ba"}, ] [[package]] From 3015a76bff07980993f543bd3fc6920edfa58278 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 01:22:52 +0000 Subject: [PATCH 131/598] build(deps-dev): bump mkdocs-material from 9.5.17 to 9.5.18 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.17 to 9.5.18. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.17...9.5.18) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 33419080b8..4479975b01 100644 --- a/poetry.lock +++ b/poetry.lock @@ -779,13 +779,13 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp [[package]] name = "mkdocs-material" -version = "9.5.17" +version = "9.5.18" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.17-py3-none-any.whl", hash = "sha256:14a2a60119a785e70e765dd033e6211367aca9fc70230e577c1cf6a326949571"}, - {file = "mkdocs_material-9.5.17.tar.gz", hash = "sha256:06ae1275a72db1989cf6209de9e9ecdfbcfdbc24c58353877b2bb927dbe413e4"}, + {file = "mkdocs_material-9.5.18-py3-none-any.whl", hash = "sha256:1e0e27fc9fe239f9064318acf548771a4629d5fd5dfd45444fd80a953fe21eb4"}, + {file = "mkdocs_material-9.5.18.tar.gz", hash = "sha256:a43f470947053fa2405c33995f282d24992c752a50114f23f30da9d8d0c57e62"}, ] [package.dependencies] From 62c5cf2cd94730179096202da0cc297aa631dc73 Mon Sep 17 00:00:00 2001 From: Axel H Date: Thu, 18 Apr 2024 11:51:46 +0200 Subject: [PATCH 132/598] feat(bump): `version_files` now support glob patterns (fix #1067) (#1070) --- commitizen/bump.py | 39 +++++++---- commitizen/commands/bump.py | 65 +++++++------------ commitizen/commands/changelog.py | 6 +- commitizen/git.py | 4 +- docs/bump.md | 4 ++ tests/commands/test_bump_command.py | 10 +++ tests/test_bump_update_version_in_files.py | 18 +++++ .../test_update_version_in_globbed_files.toml | 3 + 8 files changed, 92 insertions(+), 57 deletions(-) create mode 100644 tests/test_bump_update_version_in_files/test_update_version_in_globbed_files.toml diff --git a/commitizen/bump.py b/commitizen/bump.py index f0e45e3432..2351dbd7ec 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -3,6 +3,7 @@ import os import re from collections import OrderedDict +from glob import iglob from string import Template from typing import cast @@ -53,23 +54,20 @@ def update_version_in_files( *, check_consistency: bool = False, encoding: str = encoding, -) -> None: +) -> list[str]: """Change old version to the new one in every file given. Note that this version is not the tag formatted one. So for example, your tag could look like `v1.0.0` while your version in the package like `1.0.0`. + + Returns the list of updated files. """ # TODO: separate check step and write step - for location in files: - drive, tail = os.path.splitdrive(location) - path, _, regex = tail.partition(":") - filepath = drive + path - if not regex: - regex = _version_to_regex(current_version) - + updated = [] + for path, regex in files_and_regexs(files, current_version): current_version_found, version_file = _bump_with_regex( - filepath, + path, current_version, new_version, regex, @@ -78,14 +76,33 @@ def update_version_in_files( if check_consistency and not current_version_found: raise CurrentVersionNotFoundError( - f"Current version {current_version} is not found in {location}.\n" + f"Current version {current_version} is not found in {path}.\n" "The version defined in commitizen configuration and the ones in " "version_files are possibly inconsistent." ) # Write the file out again - with smart_open(filepath, "w", encoding=encoding) as file: + with smart_open(path, "w", encoding=encoding) as file: file.write(version_file) + updated.append(path) + return updated + + +def files_and_regexs(patterns: list[str], version: str) -> list[tuple[str, str]]: + """ + Resolve all distinct files with their regexp from a list of glob patterns with optional regexp + """ + out = [] + for pattern in patterns: + drive, tail = os.path.splitdrive(pattern) + path, _, regex = tail.partition(":") + filepath = drive + path + if not regex: + regex = _version_to_regex(version) + + for path in iglob(filepath): + out.append((path, regex)) + return sorted(list(set(out))) def _bump_with_regex( diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index efbe1e0c3c..554e3c800b 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -1,12 +1,11 @@ from __future__ import annotations -import os import warnings from logging import getLogger import questionary -from commitizen import bump, cmd, factory, git, hooks, out +from commitizen import bump, factory, git, hooks, out from commitizen.commands.changelog import Changelog from commitizen.config import BaseConfig from commitizen.exceptions import ( @@ -286,56 +285,39 @@ def __call__(self) -> None: # noqa: C901 "The commits found are not eligible to be bumped" ) + files: list[str] = [] if self.changelog: + args = { + "unreleased_version": new_tag_version, + "template": self.template, + "extras": self.extras, + "incremental": True, + "dry_run": dry_run, + } if self.changelog_to_stdout: - changelog_cmd = Changelog( - self.config, - { - "unreleased_version": new_tag_version, - "template": self.template, - "extras": self.extras, - "incremental": True, - "dry_run": True, - }, - ) + changelog_cmd = Changelog(self.config, {**args, "dry_run": True}) try: changelog_cmd() except DryRunExit: pass - changelog_cmd = Changelog( - self.config, - { - "unreleased_version": new_tag_version, - "incremental": True, - "dry_run": dry_run, - "template": self.template, - "extras": self.extras, - "file_name": self.file_name, - }, - ) + + args["file_name"] = self.file_name + changelog_cmd = Changelog(self.config, args) changelog_cmd() - file_names = [] - for file_name in version_files: - drive, tail = os.path.splitdrive(file_name) - path, _, regex = tail.partition(":") - path = drive + path if path != "" else drive + regex - file_names.append(path) - git_add_changelog_and_version_files_command = ( - f"git add {changelog_cmd.file_name} " - f"{' '.join(name for name in file_names)}" - ) - c = cmd.run(git_add_changelog_and_version_files_command) + files.append(changelog_cmd.file_name) # Do not perform operations over files or git. if dry_run: raise DryRunExit() - bump.update_version_in_files( - str(current_version), - str(new_version), - version_files, - check_consistency=self.check_consistency, - encoding=self.encoding, + files.extend( + bump.update_version_in_files( + str(current_version), + str(new_version), + version_files, + check_consistency=self.check_consistency, + encoding=self.encoding, + ) ) provider.set_version(str(new_version)) @@ -358,12 +340,13 @@ def __call__(self) -> None: # noqa: C901 raise ExpectedExit() # FIXME: check if any changes have been staged + git.add(*files) c = git.commit(message, args=self._get_commit_args()) if self.retry and c.return_code != 0 and self.changelog: # Maybe pre-commit reformatted some files? Retry once logger.debug("1st git.commit error: %s", c.err) logger.info("1st commit attempt failed; retrying once") - cmd.run(git_add_changelog_and_version_files_command) + git.add(*files) c = git.commit(message, args=self._get_commit_args()) if c.return_code != 0: err = c.err.strip() or c.out diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 3fc204eba9..f1b69598f1 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -4,7 +4,7 @@ from difflib import SequenceMatcher from operator import itemgetter from pathlib import Path -from typing import Callable +from typing import Callable, cast from commitizen import bump, changelog, defaults, factory, git, out @@ -38,8 +38,8 @@ def __init__(self, config: BaseConfig, args): self.start_rev = args.get("start_rev") or self.config.settings.get( "changelog_start_rev" ) - self.file_name = args.get("file_name") or self.config.settings.get( - "changelog_file" + self.file_name = args.get("file_name") or cast( + str, self.config.settings.get("changelog_file") ) if not isinstance(self.file_name, str): raise NotAllowed( diff --git a/commitizen/git.py b/commitizen/git.py index 53e7335a3f..1f758889ed 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -98,8 +98,8 @@ def tag( return c -def add(args: str = "") -> cmd.Command: - c = cmd.run(f"git add {args}") +def add(*args: str) -> cmd.Command: + c = cmd.run(f"git add {' '.join(args)}") return c diff --git a/docs/bump.md b/docs/bump.md index 0e35083b0a..05843eeab5 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -474,6 +474,10 @@ In the example above, we can see the reference `"setup.py:version"`. This means that it will find a file `setup.py` and will only make a change in a line containing the `version` substring. +!!! note + Files can be specified using relative (to the execution) paths, absolute paths + or glob patterns. + --- ### `bump_message` diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 6cf8a8d00c..84faf9ee82 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -812,6 +812,16 @@ def test_bump_with_git_to_stdout_arg(mocker: MockFixture, capsys, changelog_path """, id="version in __init__.py with regex", ), + pytest.param( + "pyproject.toml", + "*.toml:^version", + """ +[tool.poetry] +name = "my_package" +version = "0.1.0" +""", + id="version in pyproject.toml with glob and regex", + ), ], ) @pytest.mark.parametrize( diff --git a/tests/test_bump_update_version_in_files.py b/tests/test_bump_update_version_in_files.py index 9a80d4cfd9..850b59c166 100644 --- a/tests/test_bump_update_version_in_files.py +++ b/tests/test_bump_update_version_in_files.py @@ -207,3 +207,21 @@ def test_multiplt_versions_to_bump( bump.update_version_in_files(old_version, new_version, [location], encoding="utf-8") with open(multiple_versions_to_update_poetry_lock, encoding="utf-8") as f: file_regression.check(f.read(), extension=".toml") + + +def test_update_version_in_globbed_files(commitizen_config_file, file_regression): + old_version = "1.2.3" + new_version = "2.0.0" + other = commitizen_config_file.dirpath("other.toml") + print(commitizen_config_file, other) + copyfile(commitizen_config_file, other) + + # Prepend full ppath as test assume absolute paths or cwd-relative + version_files = [commitizen_config_file.dirpath("*.toml")] + + bump.update_version_in_files( + old_version, new_version, version_files, encoding="utf-8" + ) + + for file in commitizen_config_file, other: + file_regression.check(file.read_text("utf-8"), extension=".toml") diff --git a/tests/test_bump_update_version_in_files/test_update_version_in_globbed_files.toml b/tests/test_bump_update_version_in_files/test_update_version_in_globbed_files.toml new file mode 100644 index 0000000000..bf82cfe859 --- /dev/null +++ b/tests/test_bump_update_version_in_files/test_update_version_in_globbed_files.toml @@ -0,0 +1,3 @@ +[tool.poetry] +name = "commitizen" +version = "2.0.0" From aad06020fa43255c239342d84d2d6dc7f0a44f42 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 18 Apr 2024 09:52:10 +0000 Subject: [PATCH 133/598] =?UTF-8?q?bump:=20version=203.22.0=20=E2=86=92=20?= =?UTF-8?q?3.23.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 20b8d08ec6..b232a86c72 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.22.0 # automatically updated by Commitizen + rev: v3.23.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index cf16e6a106..41db572536 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.23.0 (2024-04-18) + +### Feat + +- **bump**: `version_files` now support glob patterns (fix #1067) (#1070) + ## v3.22.0 (2024-04-11) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 659cac322f..dbea1a3912 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.22.0" +__version__ = "3.23.0" diff --git a/pyproject.toml b/pyproject.toml index 2014e323ba..66a73a310d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.22.0" +version = "3.23.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.22.0" +version = "3.23.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 2ad26e08e471ddb4943c6d84d1fc5c2e7327a8b3 Mon Sep 17 00:00:00 2001 From: Axel H Date: Thu, 18 Apr 2024 12:14:09 +0200 Subject: [PATCH 134/598] feat(schemes): adds support for SemVer 2.0 (dot in pre-releases) (fix #1025) (#1072) --- commitizen/version_schemes.py | 61 +++++++- docs/bump.md | 20 +-- docs/config.md | 3 +- pyproject.toml | 1 + tests/test_version_scheme_semver2.py | 211 +++++++++++++++++++++++++++ 5 files changed, 281 insertions(+), 15 deletions(-) create mode 100644 tests/test_version_scheme_semver2.py diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index ec04fde1e7..596aa94b2e 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -310,7 +310,7 @@ class SemVer(BaseVersion): """ Semantic Versioning (SemVer) scheme - See: https://semver.org/ + See: https://semver.org/spec/v1.0.0.html """ def __str__(self) -> str: @@ -324,9 +324,8 @@ def __str__(self) -> str: parts.append(".".join(str(x) for x in self.release)) # Pre-release - if self.pre: - pre = "".join(str(x) for x in self.pre) - parts.append(f"-{pre}") + if self.prerelease: + parts.append(f"-{self.prerelease}") # Post-release if self.post is not None: @@ -343,6 +342,60 @@ def __str__(self) -> str: return "".join(parts) +class SemVer2(SemVer): + """ + Semantic Versioning 2.0 (SemVer2) schema + + See: https://semver.org/spec/v2.0.0.html + """ + + _STD_PRELEASES = { + "a": "alpha", + "b": "beta", + } + + @property + def prerelease(self) -> str | None: + if self.is_prerelease and self.pre: + prerelease_type = self._STD_PRELEASES.get(self.pre[0], self.pre[0]) + return f"{prerelease_type}.{self.pre[1]}" + return None + + def __str__(self) -> str: + parts = [] + + # Epoch + if self.epoch != 0: + parts.append(f"{self.epoch}!") + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + # Pre-release identifiers + # See: https://semver.org/spec/v2.0.0.html#spec-item-9 + prerelease_parts = [] + if self.prerelease: + prerelease_parts.append(f"{self.prerelease}") + + # Post-release + if self.post is not None: + prerelease_parts.append(f"post.{self.post}") + + # Development release + if self.dev is not None: + prerelease_parts.append(f"dev.{self.dev}") + + if prerelease_parts: + parts.append("-") + parts.append(".".join(prerelease_parts)) + + # Local version segment + if self.local: + parts.append(f"+{self.local}") + + return "".join(parts) + + DEFAULT_SCHEME: VersionScheme = Pep440 SCHEMES_ENTRYPOINT = "commitizen.scheme" diff --git a/docs/bump.md b/docs/bump.md index 05843eeab5..6dad38219e 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -55,7 +55,7 @@ $ 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}] [--check-consistency] [--annotated-tag] [--gpg-sign] [--changelog-to-stdout] [--git-output-to-stderr] [--retry] [--major-version-zero] - [--prerelease-offset PRERELEASE_OFFSET] [--version-scheme {semver,pep440}] [--version-type {semver,pep440}] [--build-metadata BUILD_METADATA] + [--prerelease-offset PRERELEASE_OFFSET] [--version-scheme {pep440,semver,semver2}] [--version-type {pep440,semver,semver2}] [--build-metadata BUILD_METADATA] [MANUAL_VERSION] positional arguments: @@ -97,9 +97,9 @@ options: --major-version-zero keep major version at zero, even for breaking changes --prerelease-offset PRERELEASE_OFFSET start pre-releases with this offset - --version-scheme {semver,pep440} + --version-scheme {pep440,semver,semver2} choose version scheme - --version-type {semver,pep440} + --version-type {pep440,semver,semver2} Deprecated, use --version-scheme --build-metadata {BUILD_METADATA} additional metadata in the version string @@ -619,14 +619,14 @@ prerelease_offset = 1 Choose version scheme -| schemes | pep440 | semver | -| -------------- | -------------- | --------------- | -| non-prerelease | `0.1.0` | `0.1.0` | -| prerelease | `0.3.1a0` | `0.3.1-a0` | -| devrelease | `0.1.1.dev1` | `0.1.1-dev1` | -| dev and pre | `1.0.0a3.dev1` | `1.0.0-a3-dev1` | +| schemes | pep440 | semver | semver2 | +| -------------- | -------------- | --------------- | --------------------- | +| non-prerelease | `0.1.0` | `0.1.0` | `0.1.0` | +| prerelease | `0.3.1a0` | `0.3.1-a0` | `0.3.1-alpha.0` | +| devrelease | `0.1.1.dev1` | `0.1.1-dev1` | `0.1.1-dev.1` | +| dev and pre | `1.0.0a3.dev1` | `1.0.0-a3-dev1` | `1.0.0-alpha.3.dev.1` | -Options: `semver`, `pep440` +Options: `pep440`, `semver`, `semver2` Defaults to: `pep440` diff --git a/docs/config.md b/docs/config.md index d6ab12abcd..7ef8644fa2 100644 --- a/docs/config.md +++ b/docs/config.md @@ -40,7 +40,8 @@ Type: `str` Default: `pep440` -Select a version scheme from the following options [`pep440`, `semver`]. Useful for non-python projects. [Read more][version-scheme] +Select a version scheme from the following options [`pep440`, `semver`, `semver2`]. +Useful for non-python projects. [Read more][version-scheme] ### `tag_format` diff --git a/pyproject.toml b/pyproject.toml index 66a73a310d..96f630e869 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,6 +103,7 @@ scm = "commitizen.providers:ScmProvider" [tool.poetry.plugins."commitizen.scheme"] pep440 = "commitizen.version_schemes:Pep440" semver = "commitizen.version_schemes:SemVer" +semver2 = "commitizen.version_schemes:SemVer2" [tool.coverage] [tool.coverage.report] diff --git a/tests/test_version_scheme_semver2.py b/tests/test_version_scheme_semver2.py new file mode 100644 index 0000000000..d18a058a7c --- /dev/null +++ b/tests/test_version_scheme_semver2.py @@ -0,0 +1,211 @@ +import itertools +import random + +import pytest + +from commitizen.version_schemes import SemVer2, VersionProtocol + +simple_flow = [ + (("0.1.0", "PATCH", None, 0, None), "0.1.1"), + (("0.1.0", "PATCH", None, 0, 1), "0.1.1-dev.1"), + (("0.1.1", "MINOR", None, 0, None), "0.2.0"), + (("0.2.0", "MINOR", None, 0, None), "0.3.0"), + (("0.2.0", "MINOR", None, 0, 1), "0.3.0-dev.1"), + (("0.3.0", "PATCH", None, 0, None), "0.3.1"), + (("0.3.0", "PATCH", "alpha", 0, None), "0.3.1-alpha.0"), + (("0.3.1-alpha.0", None, "alpha", 0, None), "0.3.1-alpha.1"), + (("0.3.0", "PATCH", "alpha", 1, None), "0.3.1-alpha.1"), + (("0.3.1-alpha.0", None, "alpha", 1, None), "0.3.1-alpha.1"), + (("0.3.1-alpha.0", None, None, 0, None), "0.3.1"), + (("0.3.1", "PATCH", None, 0, None), "0.3.2"), + (("0.4.2", "MAJOR", "alpha", 0, None), "1.0.0-alpha.0"), + (("1.0.0-alpha.0", None, "alpha", 0, None), "1.0.0-alpha.1"), + (("1.0.0-alpha.1", None, "alpha", 0, None), "1.0.0-alpha.2"), + (("1.0.0-alpha.1", None, "alpha", 0, 1), "1.0.0-alpha.2.dev.1"), + (("1.0.0-alpha.2.dev.0", None, "alpha", 0, 1), "1.0.0-alpha.3.dev.1"), + (("1.0.0-alpha.2.dev.0", None, "alpha", 0, 0), "1.0.0-alpha.3.dev.0"), + (("1.0.0-alpha.1", None, "beta", 0, None), "1.0.0-beta.0"), + (("1.0.0-beta.0", None, "beta", 0, None), "1.0.0-beta.1"), + (("1.0.0-beta.1", None, "rc", 0, None), "1.0.0-rc.0"), + (("1.0.0-rc.0", None, "rc", 0, None), "1.0.0-rc.1"), + (("1.0.0-rc.0", None, "rc", 0, 1), "1.0.0-rc.1.dev.1"), + (("1.0.0-rc.0", "PATCH", None, 0, None), "1.0.0"), + (("1.0.0-alpha.3.dev.0", None, "beta", 0, None), "1.0.0-beta.0"), + (("1.0.0", "PATCH", None, 0, None), "1.0.1"), + (("1.0.1", "PATCH", None, 0, None), "1.0.2"), + (("1.0.2", "MINOR", None, 0, None), "1.1.0"), + (("1.1.0", "MINOR", None, 0, None), "1.2.0"), + (("1.2.0", "PATCH", None, 0, None), "1.2.1"), + (("1.2.1", "MAJOR", None, 0, None), "2.0.0"), +] + +local_versions = [ + (("4.5.0+0.1.0", "PATCH", None, 0, None), "4.5.0+0.1.1"), + (("4.5.0+0.1.1", "MINOR", None, 0, None), "4.5.0+0.2.0"), + (("4.5.0+0.2.0", "MAJOR", None, 0, None), "4.5.0+1.0.0"), +] + +# never bump backwards on pre-releases +linear_prerelease_cases = [ + (("0.1.1-beta.1", None, "alpha", 0, None), "0.1.1-beta.2"), + (("0.1.1-rc.0", None, "alpha", 0, None), "0.1.1-rc.1"), + (("0.1.1-rc.0", None, "beta", 0, None), "0.1.1-rc.1"), +] + +weird_cases = [ + (("1.1", "PATCH", None, 0, None), "1.1.1"), + (("1", "MINOR", None, 0, None), "1.1.0"), + (("1", "MAJOR", None, 0, None), "2.0.0"), + (("1-alpha.0", None, "alpha", 0, None), "1.0.0-alpha.1"), + (("1-alpha.0", None, "alpha", 1, None), "1.0.0-alpha.1"), + (("1", None, "beta", 0, None), "1.0.0-beta.0"), + (("1", None, "beta", 1, None), "1.0.0-beta.1"), + (("1-beta", None, "beta", 0, None), "1.0.0-beta.1"), + (("1.0.0-alpha.1", None, "alpha", 0, None), "1.0.0-alpha.2"), + (("1", None, "rc", 0, None), "1.0.0-rc.0"), + (("1.0.0-rc.1+e20d7b57f3eb", "PATCH", None, 0, None), "1.0.0"), +] + +# test driven development +tdd_cases = [ + (("0.1.1", "PATCH", None, 0, None), "0.1.2"), + (("0.1.1", "MINOR", None, 0, None), "0.2.0"), + (("2.1.1", "MAJOR", None, 0, None), "3.0.0"), + (("0.9.0", "PATCH", "alpha", 0, None), "0.9.1-alpha.0"), + (("0.9.0", "MINOR", "alpha", 0, None), "0.10.0-alpha.0"), + (("0.9.0", "MAJOR", "alpha", 0, None), "1.0.0-alpha.0"), + (("0.9.0", "MAJOR", "alpha", 1, None), "1.0.0-alpha.1"), + (("1.0.0-alpha.2", None, "beta", 0, None), "1.0.0-beta.0"), + (("1.0.0-alpha.2", None, "beta", 1, None), "1.0.0-beta.1"), + (("1.0.0-beta.1", None, "rc", 0, None), "1.0.0-rc.0"), + (("1.0.0-rc.1", None, "rc", 0, None), "1.0.0-rc.2"), + (("1.0.0-alpha.0", None, "rc", 0, None), "1.0.0-rc.0"), + (("1.0.0-alpha.1", None, "alpha", 0, None), "1.0.0-alpha.2"), +] + + +@pytest.mark.parametrize( + "test_input, expected", + itertools.chain(tdd_cases, weird_cases, simple_flow, linear_prerelease_cases), +) +def test_bump_semver_version(test_input, expected): + current_version = test_input[0] + increment = test_input[1] + prerelease = test_input[2] + prerelease_offset = test_input[3] + devrelease = test_input[4] + assert ( + str( + SemVer2(current_version).bump( + increment=increment, + prerelease=prerelease, + prerelease_offset=prerelease_offset, + devrelease=devrelease, + ) + ) + == expected + ) + + +@pytest.mark.parametrize("test_input,expected", local_versions) +def test_bump_semver_version_local(test_input, expected): + current_version = test_input[0] + increment = test_input[1] + prerelease = test_input[2] + prerelease_offset = test_input[3] + devrelease = test_input[4] + is_local_version = True + assert ( + str( + SemVer2(current_version).bump( + increment=increment, + prerelease=prerelease, + prerelease_offset=prerelease_offset, + devrelease=devrelease, + is_local_version=is_local_version, + ) + ) + == expected + ) + + +def test_semver_scheme_property(): + version = SemVer2("0.0.1") + assert version.scheme is SemVer2 + + +def test_semver_implement_version_protocol(): + assert isinstance(SemVer2("0.0.1"), VersionProtocol) + + +def test_semver_sortable(): + test_input = [x[0][0] for x in simple_flow] + test_input.extend([x[1] for x in simple_flow]) + # randomize + random_input = [SemVer2(x) for x in random.sample(test_input, len(test_input))] + assert len(random_input) == len(test_input) + sorted_result = [str(x) for x in sorted(random_input)] + assert sorted_result == [ + "0.1.0", + "0.1.0", + "0.1.1-dev.1", + "0.1.1", + "0.1.1", + "0.2.0", + "0.2.0", + "0.2.0", + "0.3.0-dev.1", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.1-alpha.0", + "0.3.1-alpha.0", + "0.3.1-alpha.0", + "0.3.1-alpha.0", + "0.3.1-alpha.1", + "0.3.1-alpha.1", + "0.3.1-alpha.1", + "0.3.1", + "0.3.1", + "0.3.1", + "0.3.2", + "0.4.2", + "1.0.0-alpha.0", + "1.0.0-alpha.0", + "1.0.0-alpha.1", + "1.0.0-alpha.1", + "1.0.0-alpha.1", + "1.0.0-alpha.1", + "1.0.0-alpha.2.dev.0", + "1.0.0-alpha.2.dev.0", + "1.0.0-alpha.2.dev.1", + "1.0.0-alpha.2", + "1.0.0-alpha.3.dev.0", + "1.0.0-alpha.3.dev.0", + "1.0.0-alpha.3.dev.1", + "1.0.0-beta.0", + "1.0.0-beta.0", + "1.0.0-beta.0", + "1.0.0-beta.1", + "1.0.0-beta.1", + "1.0.0-rc.0", + "1.0.0-rc.0", + "1.0.0-rc.0", + "1.0.0-rc.0", + "1.0.0-rc.1.dev.1", + "1.0.0-rc.1", + "1.0.0", + "1.0.0", + "1.0.1", + "1.0.1", + "1.0.2", + "1.0.2", + "1.1.0", + "1.1.0", + "1.2.0", + "1.2.0", + "1.2.1", + "1.2.1", + "2.0.0", + ] From a754230d41a1933fd4ba000014d841dd2a05c71d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 18 Apr 2024 10:14:32 +0000 Subject: [PATCH 135/598] =?UTF-8?q?bump:=20version=203.23.0=20=E2=86=92=20?= =?UTF-8?q?3.24.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b232a86c72..7cf5bb5857 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.23.0 # automatically updated by Commitizen + rev: v3.24.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 41db572536..aafb47ecc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.24.0 (2024-04-18) + +### Feat + +- **schemes**: adds support for SemVer 2.0 (dot in pre-releases) (fix #1025) (#1072) + ## v3.23.0 (2024-04-18) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index dbea1a3912..3e6d8c7b73 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.23.0" +__version__ = "3.24.0" diff --git a/pyproject.toml b/pyproject.toml index 96f630e869..d627f99250 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.23.0" +version = "3.24.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.23.0" +version = "3.24.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 99db128865880dff5a5db9bd70dbed7c563da30e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 01:26:46 +0000 Subject: [PATCH 136/598] build(deps-dev): bump ruff from 0.3.7 to 0.4.0 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.7 to 0.4.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.3.7...v0.4.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4479975b01..98e6f9d655 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1461,28 +1461,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.3.7" +version = "0.4.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0e8377cccb2f07abd25e84fc5b2cbe48eeb0fea9f1719cad7caedb061d70e5ce"}, - {file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:15a4d1cc1e64e556fa0d67bfd388fed416b7f3b26d5d1c3e7d192c897e39ba4b"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d28bdf3d7dc71dd46929fafeec98ba89b7c3550c3f0978e36389b5631b793663"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:379b67d4f49774ba679593b232dcd90d9e10f04d96e3c8ce4a28037ae473f7bb"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c060aea8ad5ef21cdfbbe05475ab5104ce7827b639a78dd55383a6e9895b7c51"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ebf8f615dde968272d70502c083ebf963b6781aacd3079081e03b32adfe4d58a"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48098bd8f5c38897b03604f5428901b65e3c97d40b3952e38637b5404b739a2"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da8a4fda219bf9024692b1bc68c9cff4b80507879ada8769dc7e985755d662ea"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c44e0149f1d8b48c4d5c33d88c677a4aa22fd09b1683d6a7ff55b816b5d074f"}, - {file = "ruff-0.3.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3050ec0af72b709a62ecc2aca941b9cd479a7bf2b36cc4562f0033d688e44fa1"}, - {file = "ruff-0.3.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a29cc38e4c1ab00da18a3f6777f8b50099d73326981bb7d182e54a9a21bb4ff7"}, - {file = "ruff-0.3.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b15cc59c19edca917f51b1956637db47e200b0fc5e6e1878233d3a938384b0b"}, - {file = "ruff-0.3.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e491045781b1e38b72c91247cf4634f040f8d0cb3e6d3d64d38dcf43616650b4"}, - {file = "ruff-0.3.7-py3-none-win32.whl", hash = "sha256:bc931de87593d64fad3a22e201e55ad76271f1d5bfc44e1a1887edd0903c7d9f"}, - {file = "ruff-0.3.7-py3-none-win_amd64.whl", hash = "sha256:5ef0e501e1e39f35e03c2acb1d1238c595b8bb36cf7a170e7c1df1b73da00e74"}, - {file = "ruff-0.3.7-py3-none-win_arm64.whl", hash = "sha256:789e144f6dc7019d1f92a812891c645274ed08af6037d11fc65fcbc183b7d59f"}, - {file = "ruff-0.3.7.tar.gz", hash = "sha256:d5c1aebee5162c2226784800ae031f660c350e7a3402c4d1f8ea4e97e232e3ba"}, + {file = "ruff-0.4.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:70b8c620cf2212744eabd6d69c4f839f2be0d8880d27beaeb0adb6aa0b316aa8"}, + {file = "ruff-0.4.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfa3e3ff53be05a8c5570c1585ea1e089f6b399ca99fcb78598d4a8234f248db"}, + {file = "ruff-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5616cca501d1d16b932b7e607d7e1fd1b8c8c51d6ee484b7940fc1adc5bea541"}, + {file = "ruff-0.4.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46eff08dd480b5d9b540846159fe134d70e3c45a3c913c600047cbf7f0e4e308"}, + {file = "ruff-0.4.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d546f511431fff2b17adcf7110f3b2c2c0c8d33b0e10e5fd27fd340bc617efc"}, + {file = "ruff-0.4.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c7b6b6b38e216036284c5779b6aa14acbf5664e3b5872533219cf93daf40ddfb"}, + {file = "ruff-0.4.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e1cf8b064bb2a6b4922af7274fe2dffcb552d96ba716b2fbe5e2c970ed7de18"}, + {file = "ruff-0.4.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9911c9046b94253e1fa844c0192bb764b86866a881502dee324686474d498c17"}, + {file = "ruff-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ca7a971c8f1a0b6f5ff4a819c0d1c2619536530bbd5a289af725d8b2ef1013d"}, + {file = "ruff-0.4.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:752e0f77f421141dd470a0b1bed4fd8f763aebabe32c80ed3580f740ef4ba807"}, + {file = "ruff-0.4.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:84f2a5dd8f33964d826c5377e094f7ce11e55e432cd42d3bf64efe4384224a03"}, + {file = "ruff-0.4.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0b20e7db4a672495320a8a18149b7febf4e4f97509a4657367144569ce0915fd"}, + {file = "ruff-0.4.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0b0eddd339e24dc4f7719b1cde4967f6b6bc0ad948cc183711ba8910f14aeafe"}, + {file = "ruff-0.4.0-py3-none-win32.whl", hash = "sha256:e70befd488271a2c28c80bd427f73d8855dd222fc549fa1e9967d287c5cfe781"}, + {file = "ruff-0.4.0-py3-none-win_amd64.whl", hash = "sha256:8584b9361900997ccf8d7aaa4dc4ab43e258a853ca7189d98ac929dc9ee50875"}, + {file = "ruff-0.4.0-py3-none-win_arm64.whl", hash = "sha256:fea4ec813c965e40af29ee627a1579ee1d827d77e81d54b85bdd7b42d1540cdd"}, + {file = "ruff-0.4.0.tar.gz", hash = "sha256:7457308d9ebf00d6a1c9a26aa755e477787a636c90b823f91cd7d4bea9e89260"}, ] [[package]] @@ -1820,4 +1820,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "abe023abef8eaadaffaa2b8725bc1958b6597cc8e07f0899cf751d5ce28cab82" +content-hash = "7749ae1f4f41db8c1a5333070a9b88a798dd6666535bbe1d96a6d15fa3f5ddd9" diff --git a/pyproject.toml b/pyproject.toml index d627f99250..d427aaa0f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,7 @@ pytest-xdist = "^3.1.0" # code formatter black = ">=23.11,<25.0" # linter -ruff = ">=0.1.6,<0.4.0" +ruff = ">=0.1.6,<0.5.0" pre-commit = ">=2.18,<4.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" From 5236aba3a745356a3c7843261629b3f516ec5f10 Mon Sep 17 00:00:00 2001 From: Smallfu666 Date: Sun, 21 Apr 2024 14:38:24 +0800 Subject: [PATCH 137/598] docs(getting_started): fix broken link #1008 --- docs/getting_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index afc2586412..e826a5e424 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -28,7 +28,7 @@ This command will bump your project's version, and it will create a tag. Because of the setting `update_changelog_on_bump`, bump will also create the **changelog**. You can also [update files](./bump.md#version_files). -You can configure the [version type](./bump.md#version-type) and [version provider](./config.md#version-providers). +You can configure the [version scheme](./bump.md#version_scheme) and [version provider](./config.md#version-providers). There are many more options available, please read the docs for the [bump command](./bump.md). From e5a81a26db4b11201932063960ac1209712f6dbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 01:21:55 +0000 Subject: [PATCH 138/598] build(deps-dev): bump ruff from 0.4.0 to 0.4.1 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.0 to 0.4.1. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.0...v0.4.1) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 98e6f9d655..57a068bc82 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1461,28 +1461,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.0" +version = "0.4.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:70b8c620cf2212744eabd6d69c4f839f2be0d8880d27beaeb0adb6aa0b316aa8"}, - {file = "ruff-0.4.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfa3e3ff53be05a8c5570c1585ea1e089f6b399ca99fcb78598d4a8234f248db"}, - {file = "ruff-0.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5616cca501d1d16b932b7e607d7e1fd1b8c8c51d6ee484b7940fc1adc5bea541"}, - {file = "ruff-0.4.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46eff08dd480b5d9b540846159fe134d70e3c45a3c913c600047cbf7f0e4e308"}, - {file = "ruff-0.4.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d546f511431fff2b17adcf7110f3b2c2c0c8d33b0e10e5fd27fd340bc617efc"}, - {file = "ruff-0.4.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c7b6b6b38e216036284c5779b6aa14acbf5664e3b5872533219cf93daf40ddfb"}, - {file = "ruff-0.4.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e1cf8b064bb2a6b4922af7274fe2dffcb552d96ba716b2fbe5e2c970ed7de18"}, - {file = "ruff-0.4.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9911c9046b94253e1fa844c0192bb764b86866a881502dee324686474d498c17"}, - {file = "ruff-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ca7a971c8f1a0b6f5ff4a819c0d1c2619536530bbd5a289af725d8b2ef1013d"}, - {file = "ruff-0.4.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:752e0f77f421141dd470a0b1bed4fd8f763aebabe32c80ed3580f740ef4ba807"}, - {file = "ruff-0.4.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:84f2a5dd8f33964d826c5377e094f7ce11e55e432cd42d3bf64efe4384224a03"}, - {file = "ruff-0.4.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0b20e7db4a672495320a8a18149b7febf4e4f97509a4657367144569ce0915fd"}, - {file = "ruff-0.4.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0b0eddd339e24dc4f7719b1cde4967f6b6bc0ad948cc183711ba8910f14aeafe"}, - {file = "ruff-0.4.0-py3-none-win32.whl", hash = "sha256:e70befd488271a2c28c80bd427f73d8855dd222fc549fa1e9967d287c5cfe781"}, - {file = "ruff-0.4.0-py3-none-win_amd64.whl", hash = "sha256:8584b9361900997ccf8d7aaa4dc4ab43e258a853ca7189d98ac929dc9ee50875"}, - {file = "ruff-0.4.0-py3-none-win_arm64.whl", hash = "sha256:fea4ec813c965e40af29ee627a1579ee1d827d77e81d54b85bdd7b42d1540cdd"}, - {file = "ruff-0.4.0.tar.gz", hash = "sha256:7457308d9ebf00d6a1c9a26aa755e477787a636c90b823f91cd7d4bea9e89260"}, + {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:2d9ef6231e3fbdc0b8c72404a1a0c46fd0dcea84efca83beb4681c318ea6a953"}, + {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9485f54a7189e6f7433e0058cf8581bee45c31a25cd69009d2a040d1bd4bfaef"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2921ac03ce1383e360e8a95442ffb0d757a6a7ddd9a5be68561a671e0e5807e"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eec8d185fe193ad053eda3a6be23069e0c8ba8c5d20bc5ace6e3b9e37d246d3f"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa27d9d72a94574d250f42b7640b3bd2edc4c58ac8ac2778a8c82374bb27984"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f1ee41580bff1a651339eb3337c20c12f4037f6110a36ae4a2d864c52e5ef954"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0926cefb57fc5fced629603fbd1a23d458b25418681d96823992ba975f050c2b"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c6e37f2e3cd74496a74af9a4fa67b547ab3ca137688c484749189bf3a686ceb"}, + {file = "ruff-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd703a5975ac1998c2cc5e9494e13b28f31e66c616b0a76e206de2562e0843c"}, + {file = "ruff-0.4.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b92f03b4aa9fa23e1799b40f15f8b95cdc418782a567d6c43def65e1bbb7f1cf"}, + {file = "ruff-0.4.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c859f294f8633889e7d77de228b203eb0e9a03071b72b5989d89a0cf98ee262"}, + {file = "ruff-0.4.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b34510141e393519a47f2d7b8216fec747ea1f2c81e85f076e9f2910588d4b64"}, + {file = "ruff-0.4.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6e68d248ed688b9d69fd4d18737edcbb79c98b251bba5a2b031ce2470224bdf9"}, + {file = "ruff-0.4.1-py3-none-win32.whl", hash = "sha256:b90506f3d6d1f41f43f9b7b5ff845aeefabed6d2494307bc7b178360a8805252"}, + {file = "ruff-0.4.1-py3-none-win_amd64.whl", hash = "sha256:c7d391e5936af5c9e252743d767c564670dc3889aff460d35c518ee76e4b26d7"}, + {file = "ruff-0.4.1-py3-none-win_arm64.whl", hash = "sha256:a1eaf03d87e6a7cd5e661d36d8c6e874693cb9bc3049d110bc9a97b350680c43"}, + {file = "ruff-0.4.1.tar.gz", hash = "sha256:d592116cdbb65f8b1b7e2a2b48297eb865f6bdc20641879aa9d7b9c11d86db79"}, ] [[package]] From 3dfbcc9a984ac90436a24e5e4fd6c443767a2b35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 01:22:47 +0000 Subject: [PATCH 139/598] build(deps-dev): bump mkdocs from 1.5.3 to 1.6.0 Bumps [mkdocs](https://github.com/mkdocs/mkdocs) from 1.5.3 to 1.6.0. - [Release notes](https://github.com/mkdocs/mkdocs/releases) - [Commits](https://github.com/mkdocs/mkdocs/compare/1.5.3...1.6.0) --- updated-dependencies: - dependency-name: mkdocs dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/poetry.lock b/poetry.lock index 57a068bc82..83258241f5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -748,44 +748,61 @@ files = [ [[package]] name = "mkdocs" -version = "1.5.3" +version = "1.6.0" description = "Project documentation with Markdown." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, - {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, + {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, + {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, ] [package.dependencies] click = ">=7.0" colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} ghp-import = ">=1.0" -importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} jinja2 = ">=2.11.1" -markdown = ">=3.2.1" +markdown = ">=3.3.6" markupsafe = ">=2.0.1" mergedeep = ">=1.3.4" +mkdocs-get-deps = ">=0.2.0" packaging = ">=20.5" pathspec = ">=0.11.1" -platformdirs = ">=2.2.0" pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" watchdog = ">=2.0" [package.extras] i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, + {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.18" +version = "9.5.2" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.18-py3-none-any.whl", hash = "sha256:1e0e27fc9fe239f9064318acf548771a4629d5fd5dfd45444fd80a953fe21eb4"}, - {file = "mkdocs_material-9.5.18.tar.gz", hash = "sha256:a43f470947053fa2405c33995f282d24992c752a50114f23f30da9d8d0c57e62"}, + {file = "mkdocs_material-9.5.2-py3-none-any.whl", hash = "sha256:6ed0fbf4682491766f0ec1acc955db6901c2fd424c7ab343964ef51b819741f5"}, + {file = "mkdocs_material-9.5.2.tar.gz", hash = "sha256:ca8b9cd2b3be53e858e5a1a45ac9668bd78d95d77a30288bb5ebc1a31db6184c"}, ] [package.dependencies] @@ -793,7 +810,7 @@ babel = ">=2.10,<3.0" colorama = ">=0.4,<1.0" jinja2 = ">=3.0,<4.0" markdown = ">=3.2,<4.0" -mkdocs = ">=1.5.3,<1.6.0" +mkdocs = ">=1.5.3,<2.0" mkdocs-material-extensions = ">=1.3,<2.0" paginate = ">=0.5,<1.0" pygments = ">=2.16,<3.0" @@ -802,8 +819,8 @@ regex = ">=2022.4" requests = ">=2.26,<3.0" [package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] -imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] [[package]] From ac07bdaa30155ef080ad6487c8ccc21067d0ceab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 01:17:23 +0000 Subject: [PATCH 140/598] build(deps-dev): bump mkdocs-material from 9.5.2 to 9.5.18 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.2 to 9.5.18. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.2...9.5.18) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 45 ++++++++++++++------------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/poetry.lock b/poetry.lock index 83258241f5..57a068bc82 100644 --- a/poetry.lock +++ b/poetry.lock @@ -748,61 +748,44 @@ files = [ [[package]] name = "mkdocs" -version = "1.6.0" +version = "1.5.3" description = "Project documentation with Markdown." optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, - {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, + {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, + {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, ] [package.dependencies] click = ">=7.0" colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} ghp-import = ">=1.0" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} jinja2 = ">=2.11.1" -markdown = ">=3.3.6" +markdown = ">=3.2.1" markupsafe = ">=2.0.1" mergedeep = ">=1.3.4" -mkdocs-get-deps = ">=0.2.0" packaging = ">=20.5" pathspec = ">=0.11.1" +platformdirs = ">=2.2.0" pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" watchdog = ">=2.0" [package.extras] i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] - -[[package]] -name = "mkdocs-get-deps" -version = "0.2.0" -description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, - {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} -mergedeep = ">=1.3.4" -platformdirs = ">=2.2.0" -pyyaml = ">=5.1" +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] [[package]] name = "mkdocs-material" -version = "9.5.2" +version = "9.5.18" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.2-py3-none-any.whl", hash = "sha256:6ed0fbf4682491766f0ec1acc955db6901c2fd424c7ab343964ef51b819741f5"}, - {file = "mkdocs_material-9.5.2.tar.gz", hash = "sha256:ca8b9cd2b3be53e858e5a1a45ac9668bd78d95d77a30288bb5ebc1a31db6184c"}, + {file = "mkdocs_material-9.5.18-py3-none-any.whl", hash = "sha256:1e0e27fc9fe239f9064318acf548771a4629d5fd5dfd45444fd80a953fe21eb4"}, + {file = "mkdocs_material-9.5.18.tar.gz", hash = "sha256:a43f470947053fa2405c33995f282d24992c752a50114f23f30da9d8d0c57e62"}, ] [package.dependencies] @@ -810,7 +793,7 @@ babel = ">=2.10,<3.0" colorama = ">=0.4,<1.0" jinja2 = ">=3.0,<4.0" markdown = ">=3.2,<4.0" -mkdocs = ">=1.5.3,<2.0" +mkdocs = ">=1.5.3,<1.6.0" mkdocs-material-extensions = ">=1.3,<2.0" paginate = ">=0.5,<1.0" pygments = ">=2.16,<3.0" @@ -819,8 +802,8 @@ regex = ">=2022.4" requests = ">=2.26,<3.0" [package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] -imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] [[package]] From 3a2a38d463828bb65236bf7f176bd2cffa31f7c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Apr 2024 01:37:01 +0000 Subject: [PATCH 141/598] build(deps-dev): bump mkdocs from 1.5.3 to 1.6.0 Bumps [mkdocs](https://github.com/mkdocs/mkdocs) from 1.5.3 to 1.6.0. - [Release notes](https://github.com/mkdocs/mkdocs/releases) - [Commits](https://github.com/mkdocs/mkdocs/compare/1.5.3...1.6.0) --- updated-dependencies: - dependency-name: mkdocs dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/poetry.lock b/poetry.lock index 57a068bc82..83258241f5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -748,44 +748,61 @@ files = [ [[package]] name = "mkdocs" -version = "1.5.3" +version = "1.6.0" description = "Project documentation with Markdown." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, - {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, + {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, + {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, ] [package.dependencies] click = ">=7.0" colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} ghp-import = ">=1.0" -importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} jinja2 = ">=2.11.1" -markdown = ">=3.2.1" +markdown = ">=3.3.6" markupsafe = ">=2.0.1" mergedeep = ">=1.3.4" +mkdocs-get-deps = ">=0.2.0" packaging = ">=20.5" pathspec = ">=0.11.1" -platformdirs = ">=2.2.0" pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" watchdog = ">=2.0" [package.extras] i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, + {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.18" +version = "9.5.2" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.18-py3-none-any.whl", hash = "sha256:1e0e27fc9fe239f9064318acf548771a4629d5fd5dfd45444fd80a953fe21eb4"}, - {file = "mkdocs_material-9.5.18.tar.gz", hash = "sha256:a43f470947053fa2405c33995f282d24992c752a50114f23f30da9d8d0c57e62"}, + {file = "mkdocs_material-9.5.2-py3-none-any.whl", hash = "sha256:6ed0fbf4682491766f0ec1acc955db6901c2fd424c7ab343964ef51b819741f5"}, + {file = "mkdocs_material-9.5.2.tar.gz", hash = "sha256:ca8b9cd2b3be53e858e5a1a45ac9668bd78d95d77a30288bb5ebc1a31db6184c"}, ] [package.dependencies] @@ -793,7 +810,7 @@ babel = ">=2.10,<3.0" colorama = ">=0.4,<1.0" jinja2 = ">=3.0,<4.0" markdown = ">=3.2,<4.0" -mkdocs = ">=1.5.3,<1.6.0" +mkdocs = ">=1.5.3,<2.0" mkdocs-material-extensions = ">=1.3,<2.0" paginate = ">=0.5,<1.0" pygments = ">=2.16,<3.0" @@ -802,8 +819,8 @@ regex = ">=2022.4" requests = ">=2.26,<3.0" [package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] -imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] [[package]] From 35b7c983ed075c20650e9bf629376151d4667884 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 01:41:13 +0000 Subject: [PATCH 142/598] build(deps-dev): bump black from 24.4.0 to 24.4.2 Bumps [black](https://github.com/psf/black) from 24.4.0 to 24.4.2. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/24.4.0...24.4.2) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/poetry.lock b/poetry.lock index 83258241f5..b33ec6cd80 100644 --- a/poetry.lock +++ b/poetry.lock @@ -73,33 +73,33 @@ files = [ [[package]] name = "black" -version = "24.4.0" +version = "24.4.2" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6ad001a9ddd9b8dfd1b434d566be39b1cd502802c8d38bbb1ba612afda2ef436"}, - {file = "black-24.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3a3a092b8b756c643fe45f4624dbd5a389f770a4ac294cf4d0fce6af86addaf"}, - {file = "black-24.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dae79397f367ac8d7adb6c779813328f6d690943f64b32983e896bcccd18cbad"}, - {file = "black-24.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:71d998b73c957444fb7c52096c3843875f4b6b47a54972598741fe9a7f737fcb"}, - {file = "black-24.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e5537f456a22cf5cfcb2707803431d2feeb82ab3748ade280d6ccd0b40ed2e8"}, - {file = "black-24.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64e60a7edd71fd542a10a9643bf369bfd2644de95ec71e86790b063aa02ff745"}, - {file = "black-24.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd5b4f76056cecce3e69b0d4c228326d2595f506797f40b9233424e2524c070"}, - {file = "black-24.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:64578cf99b6b46a6301bc28bdb89f9d6f9b592b1c5837818a177c98525dbe397"}, - {file = "black-24.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f95cece33329dc4aa3b0e1a771c41075812e46cf3d6e3f1dfe3d91ff09826ed2"}, - {file = "black-24.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4396ca365a4310beef84d446ca5016f671b10f07abdba3e4e4304218d2c71d33"}, - {file = "black-24.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d99dfdf37a2a00a6f7a8dcbd19edf361d056ee51093b2445de7ca09adac965"}, - {file = "black-24.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:21f9407063ec71c5580b8ad975653c66508d6a9f57bd008bb8691d273705adcd"}, - {file = "black-24.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:652e55bb722ca026299eb74e53880ee2315b181dfdd44dca98e43448620ddec1"}, - {file = "black-24.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7f2966b9b2b3b7104fca9d75b2ee856fe3fdd7ed9e47c753a4bb1a675f2caab8"}, - {file = "black-24.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bb9ca06e556a09f7f7177bc7cb604e5ed2d2df1e9119e4f7d2f1f7071c32e5d"}, - {file = "black-24.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4e71cdebdc8efeb6deaf5f2deb28325f8614d48426bed118ecc2dcaefb9ebf3"}, - {file = "black-24.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6644f97a7ef6f401a150cca551a1ff97e03c25d8519ee0bbc9b0058772882665"}, - {file = "black-24.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:75a2d0b4f5eb81f7eebc31f788f9830a6ce10a68c91fbe0fade34fff7a2836e6"}, - {file = "black-24.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb949f56a63c5e134dfdca12091e98ffb5fd446293ebae123d10fc1abad00b9e"}, - {file = "black-24.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:7852b05d02b5b9a8c893ab95863ef8986e4dda29af80bbbda94d7aee1abf8702"}, - {file = "black-24.4.0-py3-none-any.whl", hash = "sha256:74eb9b5420e26b42c00a3ff470dc0cd144b80a766128b1771d07643165e08d0e"}, - {file = "black-24.4.0.tar.gz", hash = "sha256:f07b69fda20578367eaebbd670ff8fc653ab181e1ff95d84497f9fa20e7d0641"}, + {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, + {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, + {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, + {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, + {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, + {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, + {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, + {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, + {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, + {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, + {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, + {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, + {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, + {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, + {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, + {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, + {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, + {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, + {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, + {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, + {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, + {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, ] [package.dependencies] From 2e6ec16b336ad0898ddeee79e39e40492ae3435e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 01:40:20 +0000 Subject: [PATCH 143/598] build(deps-dev): bump mkdocs-material from 9.5.2 to 9.5.19 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.2 to 9.5.19. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.2...9.5.19) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index b33ec6cd80..82674e65f9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -796,13 +796,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.2" +version = "9.5.19" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.2-py3-none-any.whl", hash = "sha256:6ed0fbf4682491766f0ec1acc955db6901c2fd424c7ab343964ef51b819741f5"}, - {file = "mkdocs_material-9.5.2.tar.gz", hash = "sha256:ca8b9cd2b3be53e858e5a1a45ac9668bd78d95d77a30288bb5ebc1a31db6184c"}, + {file = "mkdocs_material-9.5.19-py3-none-any.whl", hash = "sha256:ea96e150b6c95f5e4ffe47d78bb712c7bacdd91d2a0bec47f46b6fa0705a86ec"}, + {file = "mkdocs_material-9.5.19.tar.gz", hash = "sha256:7473e06e17e23af608a30ef583fdde8f36389dd3ef56b1d503eed54c89c9618c"}, ] [package.dependencies] @@ -810,7 +810,7 @@ babel = ">=2.10,<3.0" colorama = ">=0.4,<1.0" jinja2 = ">=3.0,<4.0" markdown = ">=3.2,<4.0" -mkdocs = ">=1.5.3,<2.0" +mkdocs = ">=1.6,<2.0" mkdocs-material-extensions = ">=1.3,<2.0" paginate = ">=0.5,<1.0" pygments = ">=2.16,<3.0" @@ -819,8 +819,8 @@ regex = ">=2022.4" requests = ">=2.26,<3.0" [package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] -imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] [[package]] From 8efbe9eca309ebacb634dbe7ff9c8eea1f168f47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 02:26:09 +0000 Subject: [PATCH 144/598] build(deps-dev): bump ruff from 0.4.1 to 0.4.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.1 to 0.4.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.1...v0.4.2) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 82674e65f9..a5d06d63f8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1478,28 +1478,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.1" +version = "0.4.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:2d9ef6231e3fbdc0b8c72404a1a0c46fd0dcea84efca83beb4681c318ea6a953"}, - {file = "ruff-0.4.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9485f54a7189e6f7433e0058cf8581bee45c31a25cd69009d2a040d1bd4bfaef"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2921ac03ce1383e360e8a95442ffb0d757a6a7ddd9a5be68561a671e0e5807e"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eec8d185fe193ad053eda3a6be23069e0c8ba8c5d20bc5ace6e3b9e37d246d3f"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa27d9d72a94574d250f42b7640b3bd2edc4c58ac8ac2778a8c82374bb27984"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f1ee41580bff1a651339eb3337c20c12f4037f6110a36ae4a2d864c52e5ef954"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0926cefb57fc5fced629603fbd1a23d458b25418681d96823992ba975f050c2b"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c6e37f2e3cd74496a74af9a4fa67b547ab3ca137688c484749189bf3a686ceb"}, - {file = "ruff-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd703a5975ac1998c2cc5e9494e13b28f31e66c616b0a76e206de2562e0843c"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b92f03b4aa9fa23e1799b40f15f8b95cdc418782a567d6c43def65e1bbb7f1cf"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c859f294f8633889e7d77de228b203eb0e9a03071b72b5989d89a0cf98ee262"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b34510141e393519a47f2d7b8216fec747ea1f2c81e85f076e9f2910588d4b64"}, - {file = "ruff-0.4.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6e68d248ed688b9d69fd4d18737edcbb79c98b251bba5a2b031ce2470224bdf9"}, - {file = "ruff-0.4.1-py3-none-win32.whl", hash = "sha256:b90506f3d6d1f41f43f9b7b5ff845aeefabed6d2494307bc7b178360a8805252"}, - {file = "ruff-0.4.1-py3-none-win_amd64.whl", hash = "sha256:c7d391e5936af5c9e252743d767c564670dc3889aff460d35c518ee76e4b26d7"}, - {file = "ruff-0.4.1-py3-none-win_arm64.whl", hash = "sha256:a1eaf03d87e6a7cd5e661d36d8c6e874693cb9bc3049d110bc9a97b350680c43"}, - {file = "ruff-0.4.1.tar.gz", hash = "sha256:d592116cdbb65f8b1b7e2a2b48297eb865f6bdc20641879aa9d7b9c11d86db79"}, + {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5"}, + {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa"}, + {file = "ruff-0.4.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e"}, + {file = "ruff-0.4.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd"}, + {file = "ruff-0.4.2-py3-none-win32.whl", hash = "sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe"}, + {file = "ruff-0.4.2-py3-none-win_amd64.whl", hash = "sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798"}, + {file = "ruff-0.4.2-py3-none-win_arm64.whl", hash = "sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf"}, + {file = "ruff-0.4.2.tar.gz", hash = "sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc"}, ] [[package]] From 1ddc0174eb3d086713a411c2bfe714309e17fcd0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 02:41:27 +0000 Subject: [PATCH 145/598] build(deps-dev): bump mypy from 1.9.0 to 1.10.0 Bumps [mypy](https://github.com/python/mypy) from 1.9.0 to 1.10.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/1.9.0...v1.10.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/poetry.lock b/poetry.lock index a5d06d63f8..9ac3f8345c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -836,38 +836,38 @@ files = [ [[package]] name = "mypy" -version = "1.9.0" +version = "1.10.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, - {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, - {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, - {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, - {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, - {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, - {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, - {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, - {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, - {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, - {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, - {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, - {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, - {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, - {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, - {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, - {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, - {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, - {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, - {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, - {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, - {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, - {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, - {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, - {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, - {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, - {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, + {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, + {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, + {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, + {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, + {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, + {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, + {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, + {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, + {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, + {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, + {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, + {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, + {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, + {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, + {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, + {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, + {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, ] [package.dependencies] From d6d4fe06f0f76c7f21332caafa4a3edfe5974179 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 01:29:46 +0000 Subject: [PATCH 146/598] build(deps-dev): bump pytest-xdist from 3.5.0 to 3.6.1 Bumps [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) from 3.5.0 to 3.6.1. - [Release notes](https://github.com/pytest-dev/pytest-xdist/releases) - [Changelog](https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-xdist/compare/v3.5.0...v3.6.1) --- updated-dependencies: - dependency-name: pytest-xdist dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9ac3f8345c..7861aa2023 100644 --- a/poetry.lock +++ b/poetry.lock @@ -396,13 +396,13 @@ test = ["pytest (>=6)"] [[package]] name = "execnet" -version = "2.0.2" +version = "2.1.1" description = "execnet: rapid multi-Python deployment" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"}, - {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"}, + {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, + {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, ] [package.extras] @@ -1208,18 +1208,18 @@ num = ["numpy", "pandas"] [[package]] name = "pytest-xdist" -version = "3.5.0" +version = "3.6.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-xdist-3.5.0.tar.gz", hash = "sha256:cbb36f3d67e0c478baa57fa4edc8843887e0f6cfc42d677530a36d7472b32d8a"}, - {file = "pytest_xdist-3.5.0-py3-none-any.whl", hash = "sha256:d075629c7e00b611df89f490a5063944bee7a4362a5ff11c7cc7824a03dfce24"}, + {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, + {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, ] [package.dependencies] -execnet = ">=1.1" -pytest = ">=6.2.0" +execnet = ">=2.1" +pytest = ">=7.0.0" [package.extras] psutil = ["psutil (>=3.0)"] From 5d00b18c4daa2be1c0168aa9198273640385d794 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 01:28:03 +0000 Subject: [PATCH 147/598] build(deps): bump decli from 0.6.1 to 0.6.2 Bumps decli from 0.6.1 to 0.6.2. --- updated-dependencies: - dependency-name: decli dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7861aa2023..d7467087a0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -332,13 +332,13 @@ toml = ["tomli"] [[package]] name = "decli" -version = "0.6.1" +version = "0.6.2" description = "Minimal, easy-to-use, declarative cli tool" optional = false python-versions = ">=3.7" files = [ - {file = "decli-0.6.1-py3-none-any.whl", hash = "sha256:7815ac58617764e1a200d7cadac6315fcaacc24d727d182f9878dd6378ccf869"}, - {file = "decli-0.6.1.tar.gz", hash = "sha256:ed88ccb947701e8e5509b7945fda56e150e2ac74a69f25d47ac85ef30ab0c0f0"}, + {file = "decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed"}, + {file = "decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f"}, ] [[package]] From 891daa38b0c7d0a1ffb0c82cc4b7a0ccd295280a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 01:26:36 +0000 Subject: [PATCH 148/598] build(deps-dev): bump pytest from 8.1.1 to 8.2.0 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.1.1 to 8.2.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.1.1...8.2.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index d7467087a0..fa2296e373 100644 --- a/poetry.lock +++ b/poetry.lock @@ -995,13 +995,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co [[package]] name = "pluggy" -version = "1.4.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] @@ -1100,13 +1100,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.1.1" +version = "8.2.0" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, - {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, + {file = "pytest-8.2.0-py3-none-any.whl", hash = "sha256:1733f0620f6cda4095bbf0d9ff8022486e91892245bb9e7d5542c018f612f233"}, + {file = "pytest-8.2.0.tar.gz", hash = "sha256:d507d4482197eac0ba2bae2e9babf0672eb333017bcedaa5fb1a3d42c1174b3f"}, ] [package.dependencies] @@ -1114,11 +1114,11 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.4,<2.0" +pluggy = ">=1.5,<2.0" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" From 9b459569eb313cbedc2ce708eb1730e46a3c3775 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 01:47:47 +0000 Subject: [PATCH 149/598] build(deps-dev): bump mkdocs-material from 9.5.19 to 9.5.20 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.19 to 9.5.20. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.19...9.5.20) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index fa2296e373..45b7faa212 100644 --- a/poetry.lock +++ b/poetry.lock @@ -796,13 +796,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.19" +version = "9.5.20" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.19-py3-none-any.whl", hash = "sha256:ea96e150b6c95f5e4ffe47d78bb712c7bacdd91d2a0bec47f46b6fa0705a86ec"}, - {file = "mkdocs_material-9.5.19.tar.gz", hash = "sha256:7473e06e17e23af608a30ef583fdde8f36389dd3ef56b1d503eed54c89c9618c"}, + {file = "mkdocs_material-9.5.20-py3-none-any.whl", hash = "sha256:ad0094a7597bcb5d0cc3e8e543a10927c2581f7f647b9bb4861600f583180f9b"}, + {file = "mkdocs_material-9.5.20.tar.gz", hash = "sha256:986eef0250d22f70fb06ce0f4eac64cc92bd797a589ec3892ce31fad976fe3da"}, ] [package.dependencies] From 88ef59bf4b5528fd25d9f85532f914ce401294b3 Mon Sep 17 00:00:00 2001 From: Yu-Sheng Li Date: Sun, 21 Apr 2024 14:32:15 +0800 Subject: [PATCH 150/598] feat: add an argument to limit the length of commit message --- commitizen/cli.py | 6 ++++++ commitizen/commands/commit.py | 4 +++- commitizen/cz/base.py | 12 ++++++++++- .../conventional_commits.py | 8 ++++---- commitizen/cz/customize/customize.py | 13 +++++++----- commitizen/cz/jira/jira.py | 6 ++++-- commitizen/defaults.py | 2 ++ commitizen/exceptions.py | 5 +++++ docs/commit.md | 10 ++++++++++ docs/customization.md | 6 ++++-- tests/conftest.py | 8 +++++--- tests/test_cz_base.py | 20 +++++++++++++++++-- 12 files changed, 80 insertions(+), 20 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index cf3d6c5eef..8b2d008e0e 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -154,6 +154,12 @@ def __call__( "action": "store_true", "help": "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.", }, + { + "name": ["-l", "--message-length-limit"], + "type": int, + "default": 0, + "help": "length limit of the commit message; 0 for no limit", + }, ], }, { diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 7591a28658..1f21b45571 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -61,7 +61,9 @@ def prompt_commit_questions(self) -> str: if not answers: raise NoAnswersError() - return cz.message(answers) + + message_length_limit: int = self.arguments.get("message_length_limit", 0) + return cz.message(answers, message_length_limit=message_length_limit) def __call__(self): dry_run: bool = self.arguments.get("dry_run") diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index bd116ceb02..9cbfe795db 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -9,6 +9,7 @@ from commitizen import git from commitizen.config.base_config import BaseConfig from commitizen.defaults import Questions +from commitizen.exceptions import CommitMessageLengthExceededError class MessageBuilderHook(Protocol): @@ -71,7 +72,7 @@ def questions(self) -> Questions: """Questions regarding the commit message.""" @abstractmethod - def message(self, answers: dict) -> str: + def message(self, answers: dict, message_length_limit: int) -> str: """Format your git message.""" @property @@ -105,3 +106,12 @@ def process_commit(self, commit: str) -> str: If not overwritten, it returns the first line of commit. """ return commit.split("\n")[0] + + def _check_message_length_limit( + self, message: str, message_length_limit: int + ) -> None: + message_len = len(message) + if message_length_limit > 0 and message_len > message_length_limit: + raise CommitMessageLengthExceededError( + f"Length of commit message exceeds limit ({message_len}/{message_length_limit})" + ) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 5f693963e7..50d6e94133 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -150,7 +150,7 @@ def questions(self) -> Questions: ] return questions - def message(self, answers: dict) -> str: + def message(self, answers: dict, message_length_limit: int = 0) -> str: prefix = answers["prefix"] scope = answers["scope"] subject = answers["subject"] @@ -167,9 +167,9 @@ def message(self, answers: dict) -> str: if footer: footer = f"\n\n{footer}" - message = f"{prefix}{scope}: {subject}{body}{footer}" - - return message + message = f"{prefix}{scope}: {subject}" + self._check_message_length_limit(message, message_length_limit) + return f"{message}{body}{footer}" def example(self) -> str: return ( diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index 5c3b4e76b4..0dc5b26794 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -61,12 +61,15 @@ def __init__(self, config: BaseConfig): def questions(self) -> Questions: return self.custom_settings.get("questions", [{}]) - def message(self, answers: dict) -> str: + def message(self, answers: dict, message_length_limit: int = 0) -> str: message_template = Template(self.custom_settings.get("message_template", "")) - if getattr(Template, "substitute", None): - return message_template.substitute(**answers) # type: ignore - else: - return message_template.render(**answers) + message: str = ( + message_template.substitute(**answers) # type: ignore + if getattr(Template, "substitute", None) + else message_template.render(**answers) + ) + self._check_message_length_limit(message, message_length_limit) + return message def example(self) -> str | None: return self.custom_settings.get("example") diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index a4fdcfa09e..6a727f78ed 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -44,8 +44,8 @@ def questions(self) -> Questions: ] return questions - def message(self, answers) -> str: - return " ".join( + def message(self, answers: dict, message_length_limit: int = 0) -> str: + message = " ".join( filter( bool, [ @@ -57,6 +57,8 @@ def message(self, answers) -> str: ], ) ) + self._check_message_length_limit(message, message_length_limit) + return message def example(self) -> str: return ( diff --git a/commitizen/defaults.py b/commitizen/defaults.py index a1651ebe88..cb35319168 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -57,6 +57,7 @@ class Settings(TypedDict, total=False): always_signoff: bool template: str | None extras: dict[str, Any] + message_length_limit: int name: str = "cz_conventional_commits" @@ -102,6 +103,7 @@ class Settings(TypedDict, total=False): "always_signoff": False, "template": None, # default provided by plugin "extras": {}, + "message_length_limit": 0, } MAJOR = "MAJOR" diff --git a/commitizen/exceptions.py b/commitizen/exceptions.py index 9cb1517680..bcdd0d1e3c 100644 --- a/commitizen/exceptions.py +++ b/commitizen/exceptions.py @@ -36,6 +36,7 @@ class ExitCode(enum.IntEnum): CHANGELOG_FORMAT_UNKNOWN = 29 CONFIG_FILE_NOT_FOUND = 30 CONFIG_FILE_IS_EMPTY = 31 + COMMIT_MESSAGE_LENGTH_LIMIT_EXCEEDED = 32 class CommitizenException(Exception): @@ -201,3 +202,7 @@ class ConfigFileNotFound(CommitizenException): class ConfigFileIsEmpty(CommitizenException): exit_code = ExitCode.CONFIG_FILE_IS_EMPTY message = "Config file is empty, please check your file path again." + + +class CommitMessageLengthExceededError(CommitizenException): + exit_code = ExitCode.COMMIT_MESSAGE_LENGTH_LIMIT_EXCEEDED diff --git a/docs/commit.md b/docs/commit.md index 54c792f743..fe6fb415c4 100644 --- a/docs/commit.md +++ b/docs/commit.md @@ -36,3 +36,13 @@ You can use `cz commit --retry` to reuse the last commit message when the previo To automatically retry when running `cz commit`, you can set the `retry_after_failure` configuration option to `true`. Running `cz commit --no-retry` makes commitizen ignore `retry_after_failure`, forcing a new commit message to be prompted. + +### Commit message length limit + +The argument `-l` (or `--message-length-limit`) followed by a positive number can limit the length of commit messages. +An exception would be raised when the message length exceeds the limit. +For example, `cz commit -l 72` will limit the length of commit messages to 72 characters. +By default the limit is set to 0, which means no limit on the length. + +Note that for `ConventionalCommitsCz`, the limit applies only from the prefix to the subject. +In other words, everything after the first line (the body and the footer) are not counted in the length. diff --git a/docs/customization.md b/docs/customization.md index 1fd1826e03..e7832e319f 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -227,9 +227,11 @@ class JiraCz(BaseCommitizen): ] return questions - def message(self, answers: dict) -> str: + def message(self, answers: dict, message_length_limit: int = 0) -> str: """Generate the message with the given answers.""" - return "{0} (#{1})".format(answers["title"], answers["issue"]) + message = "{0} (#{1})".format(answers["title"], answers["issue"]) + self._check_message_length_limit(message, message_length_limit) + return message def example(self) -> str: """Provide an example to help understand the style (OPTIONAL) diff --git a/tests/conftest.py b/tests/conftest.py index 76d2e53fb7..0431a39556 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -204,10 +204,12 @@ def questions(self) -> list: }, ] - def message(self, answers: dict) -> str: + def message(self, answers: dict, message_length_limit: int = 0) -> str: prefix = answers["prefix"] subject = answers.get("subject", "default message").trim() - return f"{prefix}: {subject}" + message = f"{prefix}: {subject}" + self._check_message_length_limit(message, message_length_limit) + return message @pytest.fixture() @@ -220,7 +222,7 @@ class MockPlugin(BaseCommitizen): def questions(self) -> defaults.Questions: return [] - def message(self, answers: dict) -> str: + def message(self, answers: dict, message_length_limit: int = 0) -> str: return "" diff --git a/tests/test_cz_base.py b/tests/test_cz_base.py index 891ee01167..3b903d80b8 100644 --- a/tests/test_cz_base.py +++ b/tests/test_cz_base.py @@ -1,14 +1,17 @@ import pytest from commitizen.cz.base import BaseCommitizen +from commitizen.exceptions import CommitMessageLengthExceededError class DummyCz(BaseCommitizen): def questions(self): return [{"type": "input", "name": "commit", "message": "Initial commit:\n"}] - def message(self, answers): - return answers["commit"] + def message(self, answers: dict, message_length_limit: int = 0): + message = answers["commit"] + self._check_message_length_limit(message, message_length_limit) + return message def test_base_raises_error(config): @@ -48,3 +51,16 @@ def test_process_commit(config): cz = DummyCz(config) message = cz.process_commit("test(test_scope): this is test msg") assert message == "test(test_scope): this is test msg" + + +def test_message_length_limit(config): + cz = DummyCz(config) + commit_message = "123456789" + message_length = len(commit_message) + assert cz.message({"commit": commit_message}) == commit_message + assert ( + cz.message({"commit": commit_message}, message_length_limit=message_length) + == commit_message + ) + with pytest.raises(CommitMessageLengthExceededError): + cz.message({"commit": commit_message}, message_length_limit=message_length - 1) From 8884a1faf608f27e0aef988dea6dd46ac3b5ee8b Mon Sep 17 00:00:00 2001 From: Yu-Sheng Li Date: Sun, 21 Apr 2024 16:58:26 +0800 Subject: [PATCH 151/598] fix: resolve test error by removing defaults --- commitizen/defaults.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index cb35319168..a1651ebe88 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -57,7 +57,6 @@ class Settings(TypedDict, total=False): always_signoff: bool template: str | None extras: dict[str, Any] - message_length_limit: int name: str = "cz_conventional_commits" @@ -103,7 +102,6 @@ class Settings(TypedDict, total=False): "always_signoff": False, "template": None, # default provided by plugin "extras": {}, - "message_length_limit": 0, } MAJOR = "MAJOR" From 432431ec0918a325cca7d9f4727c0e318a770d00 Mon Sep 17 00:00:00 2001 From: Yu-Sheng Li Date: Sun, 21 Apr 2024 22:18:57 +0800 Subject: [PATCH 152/598] refactor: check the length in Commit instead of Commitizen --- commitizen/commands/commit.py | 10 ++++++- commitizen/cz/base.py | 12 +-------- .../conventional_commits.py | 8 +++--- commitizen/cz/customize/customize.py | 13 ++++----- commitizen/cz/jira/jira.py | 6 ++--- commitizen/exceptions.py | 1 + docs/commit.md | 5 ++-- docs/customization.md | 6 ++--- tests/commands/test_commit_command.py | 27 +++++++++++++++++++ tests/conftest.py | 8 +++--- tests/test_cz_base.py | 20 ++------------ 11 files changed, 59 insertions(+), 57 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 1f21b45571..15f2cc903c 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -12,6 +12,7 @@ from commitizen.cz.utils import get_backup_file_path from commitizen.exceptions import ( CommitError, + CommitMessageLengthExceededError, CustomError, DryRunExit, NoAnswersError, @@ -62,8 +63,15 @@ def prompt_commit_questions(self) -> str: if not answers: raise NoAnswersError() + message = cz.message(answers) + message_len = len(message.partition("\n")[0]) message_length_limit: int = self.arguments.get("message_length_limit", 0) - return cz.message(answers, message_length_limit=message_length_limit) + if message_length_limit > 0 and message_len > message_length_limit: + raise CommitMessageLengthExceededError( + f"Length of commit message exceeds limit ({message_len}/{message_length_limit})" + ) + + return message def __call__(self): dry_run: bool = self.arguments.get("dry_run") diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 9cbfe795db..bd116ceb02 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -9,7 +9,6 @@ from commitizen import git from commitizen.config.base_config import BaseConfig from commitizen.defaults import Questions -from commitizen.exceptions import CommitMessageLengthExceededError class MessageBuilderHook(Protocol): @@ -72,7 +71,7 @@ def questions(self) -> Questions: """Questions regarding the commit message.""" @abstractmethod - def message(self, answers: dict, message_length_limit: int) -> str: + def message(self, answers: dict) -> str: """Format your git message.""" @property @@ -106,12 +105,3 @@ def process_commit(self, commit: str) -> str: If not overwritten, it returns the first line of commit. """ return commit.split("\n")[0] - - def _check_message_length_limit( - self, message: str, message_length_limit: int - ) -> None: - message_len = len(message) - if message_length_limit > 0 and message_len > message_length_limit: - raise CommitMessageLengthExceededError( - f"Length of commit message exceeds limit ({message_len}/{message_length_limit})" - ) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 50d6e94133..5f693963e7 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -150,7 +150,7 @@ def questions(self) -> Questions: ] return questions - def message(self, answers: dict, message_length_limit: int = 0) -> str: + def message(self, answers: dict) -> str: prefix = answers["prefix"] scope = answers["scope"] subject = answers["subject"] @@ -167,9 +167,9 @@ def message(self, answers: dict, message_length_limit: int = 0) -> str: if footer: footer = f"\n\n{footer}" - message = f"{prefix}{scope}: {subject}" - self._check_message_length_limit(message, message_length_limit) - return f"{message}{body}{footer}" + message = f"{prefix}{scope}: {subject}{body}{footer}" + + return message def example(self) -> str: return ( diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index 0dc5b26794..5c3b4e76b4 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -61,15 +61,12 @@ def __init__(self, config: BaseConfig): def questions(self) -> Questions: return self.custom_settings.get("questions", [{}]) - def message(self, answers: dict, message_length_limit: int = 0) -> str: + def message(self, answers: dict) -> str: message_template = Template(self.custom_settings.get("message_template", "")) - message: str = ( - message_template.substitute(**answers) # type: ignore - if getattr(Template, "substitute", None) - else message_template.render(**answers) - ) - self._check_message_length_limit(message, message_length_limit) - return message + if getattr(Template, "substitute", None): + return message_template.substitute(**answers) # type: ignore + else: + return message_template.render(**answers) def example(self) -> str | None: return self.custom_settings.get("example") diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index 6a727f78ed..b8fd056a71 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -44,8 +44,8 @@ def questions(self) -> Questions: ] return questions - def message(self, answers: dict, message_length_limit: int = 0) -> str: - message = " ".join( + def message(self, answers: dict) -> str: + return " ".join( filter( bool, [ @@ -57,8 +57,6 @@ def message(self, answers: dict, message_length_limit: int = 0) -> str: ], ) ) - self._check_message_length_limit(message, message_length_limit) - return message def example(self) -> str: return ( diff --git a/commitizen/exceptions.py b/commitizen/exceptions.py index bcdd0d1e3c..b0fc4e382d 100644 --- a/commitizen/exceptions.py +++ b/commitizen/exceptions.py @@ -206,3 +206,4 @@ class ConfigFileIsEmpty(CommitizenException): class CommitMessageLengthExceededError(CommitizenException): exit_code = ExitCode.COMMIT_MESSAGE_LENGTH_LIMIT_EXCEEDED + message = "Length of commit message exceeds the given limit." diff --git a/docs/commit.md b/docs/commit.md index fe6fb415c4..7e3c6268ca 100644 --- a/docs/commit.md +++ b/docs/commit.md @@ -44,5 +44,6 @@ An exception would be raised when the message length exceeds the limit. For example, `cz commit -l 72` will limit the length of commit messages to 72 characters. By default the limit is set to 0, which means no limit on the length. -Note that for `ConventionalCommitsCz`, the limit applies only from the prefix to the subject. -In other words, everything after the first line (the body and the footer) are not counted in the length. +Note that the limit applies only to the first line of message. +Specifically, for `ConventionalCommitsCz` the length only counts from the type of change to the subject, +while the body and the footer are not counted. diff --git a/docs/customization.md b/docs/customization.md index e7832e319f..1fd1826e03 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -227,11 +227,9 @@ class JiraCz(BaseCommitizen): ] return questions - def message(self, answers: dict, message_length_limit: int = 0) -> str: + def message(self, answers: dict) -> str: """Generate the message with the given answers.""" - message = "{0} (#{1})".format(answers["title"], answers["issue"]) - self._check_message_length_limit(message, message_length_limit) - return message + return "{0} (#{1})".format(answers["title"], answers["issue"]) def example(self) -> str: """Provide an example to help understand the style (OPTIONAL) diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 1930b2eaee..0e0a12751a 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -9,6 +9,7 @@ from commitizen.cz.utils import get_backup_file_path from commitizen.exceptions import ( CommitError, + CommitMessageLengthExceededError, CustomError, DryRunExit, NoAnswersError, @@ -379,3 +380,29 @@ def test_commit_command_with_extra_args(config, mocker: MockFixture): commands.Commit(config, {"extra_cli_args": "-- -extra-args1 -extra-arg2"})() commit_mock.assert_called_once_with(ANY, args="-- -extra-args1 -extra-arg2") success_mock.assert_called_once() + + +@pytest.mark.usefixtures("staging_is_clean") +def test_commit_command_with_message_length_limit(config, mocker: MockFixture): + prompt_mock = mocker.patch("questionary.prompt") + prefix = "feat" + subject = "random subject" + message_length = len(prefix) + len(": ") + len(subject) + prompt_mock.return_value = { + "prefix": prefix, + "subject": subject, + "scope": "", + "is_breaking_change": False, + "body": "random body", + "footer": "random footer", + } + + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) + success_mock = mocker.patch("commitizen.out.success") + + commands.Commit(config, {"message_length_limit": message_length})() + success_mock.assert_called_once() + + with pytest.raises(CommitMessageLengthExceededError): + commands.Commit(config, {"message_length_limit": message_length - 1})() diff --git a/tests/conftest.py b/tests/conftest.py index 0431a39556..76d2e53fb7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -204,12 +204,10 @@ def questions(self) -> list: }, ] - def message(self, answers: dict, message_length_limit: int = 0) -> str: + def message(self, answers: dict) -> str: prefix = answers["prefix"] subject = answers.get("subject", "default message").trim() - message = f"{prefix}: {subject}" - self._check_message_length_limit(message, message_length_limit) - return message + return f"{prefix}: {subject}" @pytest.fixture() @@ -222,7 +220,7 @@ class MockPlugin(BaseCommitizen): def questions(self) -> defaults.Questions: return [] - def message(self, answers: dict, message_length_limit: int = 0) -> str: + def message(self, answers: dict) -> str: return "" diff --git a/tests/test_cz_base.py b/tests/test_cz_base.py index 3b903d80b8..4ee1cc6eda 100644 --- a/tests/test_cz_base.py +++ b/tests/test_cz_base.py @@ -1,17 +1,14 @@ import pytest from commitizen.cz.base import BaseCommitizen -from commitizen.exceptions import CommitMessageLengthExceededError class DummyCz(BaseCommitizen): def questions(self): return [{"type": "input", "name": "commit", "message": "Initial commit:\n"}] - def message(self, answers: dict, message_length_limit: int = 0): - message = answers["commit"] - self._check_message_length_limit(message, message_length_limit) - return message + def message(self, answers: dict): + return answers["commit"] def test_base_raises_error(config): @@ -51,16 +48,3 @@ def test_process_commit(config): cz = DummyCz(config) message = cz.process_commit("test(test_scope): this is test msg") assert message == "test(test_scope): this is test msg" - - -def test_message_length_limit(config): - cz = DummyCz(config) - commit_message = "123456789" - message_length = len(commit_message) - assert cz.message({"commit": commit_message}) == commit_message - assert ( - cz.message({"commit": commit_message}, message_length_limit=message_length) - == commit_message - ) - with pytest.raises(CommitMessageLengthExceededError): - cz.message({"commit": commit_message}, message_length_limit=message_length - 1) From 83cf451c1489a326fd76bb7af3adc3e6f4669c80 Mon Sep 17 00:00:00 2001 From: Yu-Sheng Li Date: Fri, 26 Apr 2024 16:45:19 +0800 Subject: [PATCH 153/598] fix: strip the commit message for calculating length --- commitizen/commands/commit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 15f2cc903c..7a2a01c9cb 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -64,7 +64,7 @@ def prompt_commit_questions(self) -> str: raise NoAnswersError() message = cz.message(answers) - message_len = len(message.partition("\n")[0]) + message_len = len(message.partition("\n")[0].strip()) message_length_limit: int = self.arguments.get("message_length_limit", 0) if message_length_limit > 0 and message_len > message_length_limit: raise CommitMessageLengthExceededError( From 799dc6d2cc1496ef8f9883925e8870481c86dd7c Mon Sep 17 00:00:00 2001 From: Yu-Sheng Li Date: Fri, 26 Apr 2024 16:46:41 +0800 Subject: [PATCH 154/598] docs: emphasize the note on commit message length calculation --- docs/commit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/commit.md b/docs/commit.md index 7e3c6268ca..2c1b94f63e 100644 --- a/docs/commit.md +++ b/docs/commit.md @@ -44,6 +44,6 @@ An exception would be raised when the message length exceeds the limit. For example, `cz commit -l 72` will limit the length of commit messages to 72 characters. By default the limit is set to 0, which means no limit on the length. -Note that the limit applies only to the first line of message. +**Note that the limit applies only to the first line of the message.** Specifically, for `ConventionalCommitsCz` the length only counts from the type of change to the subject, while the body and the footer are not counted. From 106c294b1ee241eadf0a940a27425ccef8044c92 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Mon, 29 Apr 2024 10:05:20 +0800 Subject: [PATCH 155/598] refactor(commands/commit): replace comparison with chained comparison --- commitizen/commands/commit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 7a2a01c9cb..df28b2a5dd 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -66,7 +66,7 @@ def prompt_commit_questions(self) -> str: message = cz.message(answers) message_len = len(message.partition("\n")[0].strip()) message_length_limit: int = self.arguments.get("message_length_limit", 0) - if message_length_limit > 0 and message_len > message_length_limit: + if 0 < message_length_limit < message_len: raise CommitMessageLengthExceededError( f"Length of commit message exceeds limit ({message_len}/{message_length_limit})" ) From faff6a61f4f53585a965addd06156eedf0027643 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 30 Apr 2024 06:50:29 +0000 Subject: [PATCH 156/598] =?UTF-8?q?bump:=20version=203.24.0=20=E2=86=92=20?= =?UTF-8?q?3.25.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 16 ++++++++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7cf5bb5857..be1a106a30 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.24.0 # automatically updated by Commitizen + rev: v3.25.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index aafb47ecc3..d0df802fda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## v3.25.0 (2024-04-30) + +### Feat + +- add an argument to limit the length of commit message + +### Fix + +- strip the commit message for calculating length +- resolve test error by removing defaults + +### Refactor + +- **commands/commit**: replace comparison with chained comparison +- check the length in Commit instead of Commitizen + ## v3.24.0 (2024-04-18) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 3e6d8c7b73..e1609ca35c 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.24.0" +__version__ = "3.25.0" diff --git a/pyproject.toml b/pyproject.toml index d427aaa0f6..da57effff7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.24.0" +version = "3.25.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.24.0" +version = "3.25.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 26671545a3cc6b044fa5cfa93d31cc569786d933 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 02:01:41 +0000 Subject: [PATCH 157/598] build(deps-dev): bump mkdocs-material from 9.5.20 to 9.5.21 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.20 to 9.5.21. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.20...9.5.21) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 45b7faa212..d25e77ef70 100644 --- a/poetry.lock +++ b/poetry.lock @@ -796,13 +796,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.20" +version = "9.5.21" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.20-py3-none-any.whl", hash = "sha256:ad0094a7597bcb5d0cc3e8e543a10927c2581f7f647b9bb4861600f583180f9b"}, - {file = "mkdocs_material-9.5.20.tar.gz", hash = "sha256:986eef0250d22f70fb06ce0f4eac64cc92bd797a589ec3892ce31fad976fe3da"}, + {file = "mkdocs_material-9.5.21-py3-none-any.whl", hash = "sha256:210e1f179682cd4be17d5c641b2f4559574b9dea2f589c3f0e7c17c5bd1959bc"}, + {file = "mkdocs_material-9.5.21.tar.gz", hash = "sha256:049f82770f40559d3c2aa2259c562ea7257dbb4aaa9624323b5ef27b2d95a450"}, ] [package.dependencies] From 48e5c44d48dfad5651c769842bda288c352cc5e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 02:02:56 +0000 Subject: [PATCH 158/598] build(deps-dev): bump ruff from 0.4.2 to 0.4.3 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.2 to 0.4.3. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.2...v0.4.3) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index d25e77ef70..d9cfa4a079 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1478,28 +1478,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.2" +version = "0.4.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5"}, - {file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa"}, - {file = "ruff-0.4.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e"}, - {file = "ruff-0.4.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd"}, - {file = "ruff-0.4.2-py3-none-win32.whl", hash = "sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe"}, - {file = "ruff-0.4.2-py3-none-win_amd64.whl", hash = "sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798"}, - {file = "ruff-0.4.2-py3-none-win_arm64.whl", hash = "sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf"}, - {file = "ruff-0.4.2.tar.gz", hash = "sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc"}, + {file = "ruff-0.4.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b70800c290f14ae6fcbb41bbe201cf62dfca024d124a1f373e76371a007454ce"}, + {file = "ruff-0.4.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08a0d6a22918ab2552ace96adeaca308833873a4d7d1d587bb1d37bae8728eb3"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba1f14df3c758dd7de5b55fbae7e1c8af238597961e5fb628f3de446c3c40c5"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:819fb06d535cc76dfddbfe8d3068ff602ddeb40e3eacbc90e0d1272bb8d97113"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfc9e955e6dc6359eb6f82ea150c4f4e82b660e5b58d9a20a0e42ec3bb6342b"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:510a67d232d2ebe983fddea324dbf9d69b71c4d2dfeb8a862f4a127536dd4cfb"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9ff11cd9a092ee7680a56d21f302bdda14327772cd870d806610a3503d001f"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29efff25bf9ee685c2c8390563a5b5c006a3fee5230d28ea39f4f75f9d0b6f2f"}, + {file = "ruff-0.4.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b00e0bcccf0fc8d7186ed21e311dffd19761cb632241a6e4fe4477cc80ef6e"}, + {file = "ruff-0.4.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262f5635e2c74d80b7507fbc2fac28fe0d4fef26373bbc62039526f7722bca1b"}, + {file = "ruff-0.4.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7363691198719c26459e08cc17c6a3dac6f592e9ea3d2fa772f4e561b5fe82a3"}, + {file = "ruff-0.4.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eeb039f8428fcb6725bb63cbae92ad67b0559e68b5d80f840f11914afd8ddf7f"}, + {file = "ruff-0.4.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:927b11c1e4d0727ce1a729eace61cee88a334623ec424c0b1c8fe3e5f9d3c865"}, + {file = "ruff-0.4.3-py3-none-win32.whl", hash = "sha256:25cacda2155778beb0d064e0ec5a3944dcca9c12715f7c4634fd9d93ac33fd30"}, + {file = "ruff-0.4.3-py3-none-win_amd64.whl", hash = "sha256:7a1c3a450bc6539ef00da6c819fb1b76b6b065dec585f91456e7c0d6a0bbc725"}, + {file = "ruff-0.4.3-py3-none-win_arm64.whl", hash = "sha256:71ca5f8ccf1121b95a59649482470c5601c60a416bf189d553955b0338e34614"}, + {file = "ruff-0.4.3.tar.gz", hash = "sha256:ff0a3ef2e3c4b6d133fbedcf9586abfbe38d076041f2dc18ffb2c7e0485d5a07"}, ] [[package]] From 3d705a2236b04a79d66d2e2524914521361bc3c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 02:03:47 +0000 Subject: [PATCH 159/598] build(deps): bump jinja2 from 3.1.3 to 3.1.4 Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.4) --- updated-dependencies: - dependency-name: jinja2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d9cfa4a079..6041e917b3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -584,13 +584,13 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" -version = "3.1.3" +version = "3.1.4" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, - {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, ] [package.dependencies] From a2295eb9dbc0be4d91857fa61a68ca97e31908d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 01:07:12 +0000 Subject: [PATCH 160/598] build(deps): bump tomlkit from 0.12.4 to 0.12.5 Bumps [tomlkit](https://github.com/sdispater/tomlkit) from 0.12.4 to 0.12.5. - [Release notes](https://github.com/sdispater/tomlkit/releases) - [Changelog](https://github.com/python-poetry/tomlkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/sdispater/tomlkit/compare/0.12.4...0.12.5) --- updated-dependencies: - dependency-name: tomlkit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6041e917b3..2a32316848 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1575,13 +1575,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.4" +version = "0.12.5" description = "Style preserving TOML library" optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"}, - {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"}, + {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, + {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, ] [[package]] From 70938a4f65ea8e91e2907248438fb9ace26c695d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 01:28:05 +0000 Subject: [PATCH 161/598] build(deps-dev): bump ruff from 0.4.3 to 0.4.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.3 to 0.4.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.3...v0.4.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2a32316848..7a8aa525e1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1478,28 +1478,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.3" +version = "0.4.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b70800c290f14ae6fcbb41bbe201cf62dfca024d124a1f373e76371a007454ce"}, - {file = "ruff-0.4.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08a0d6a22918ab2552ace96adeaca308833873a4d7d1d587bb1d37bae8728eb3"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba1f14df3c758dd7de5b55fbae7e1c8af238597961e5fb628f3de446c3c40c5"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:819fb06d535cc76dfddbfe8d3068ff602ddeb40e3eacbc90e0d1272bb8d97113"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfc9e955e6dc6359eb6f82ea150c4f4e82b660e5b58d9a20a0e42ec3bb6342b"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:510a67d232d2ebe983fddea324dbf9d69b71c4d2dfeb8a862f4a127536dd4cfb"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9ff11cd9a092ee7680a56d21f302bdda14327772cd870d806610a3503d001f"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29efff25bf9ee685c2c8390563a5b5c006a3fee5230d28ea39f4f75f9d0b6f2f"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b00e0bcccf0fc8d7186ed21e311dffd19761cb632241a6e4fe4477cc80ef6e"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262f5635e2c74d80b7507fbc2fac28fe0d4fef26373bbc62039526f7722bca1b"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7363691198719c26459e08cc17c6a3dac6f592e9ea3d2fa772f4e561b5fe82a3"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eeb039f8428fcb6725bb63cbae92ad67b0559e68b5d80f840f11914afd8ddf7f"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:927b11c1e4d0727ce1a729eace61cee88a334623ec424c0b1c8fe3e5f9d3c865"}, - {file = "ruff-0.4.3-py3-none-win32.whl", hash = "sha256:25cacda2155778beb0d064e0ec5a3944dcca9c12715f7c4634fd9d93ac33fd30"}, - {file = "ruff-0.4.3-py3-none-win_amd64.whl", hash = "sha256:7a1c3a450bc6539ef00da6c819fb1b76b6b065dec585f91456e7c0d6a0bbc725"}, - {file = "ruff-0.4.3-py3-none-win_arm64.whl", hash = "sha256:71ca5f8ccf1121b95a59649482470c5601c60a416bf189d553955b0338e34614"}, - {file = "ruff-0.4.3.tar.gz", hash = "sha256:ff0a3ef2e3c4b6d133fbedcf9586abfbe38d076041f2dc18ffb2c7e0485d5a07"}, + {file = "ruff-0.4.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:29d44ef5bb6a08e235c8249294fa8d431adc1426bfda99ed493119e6f9ea1bf6"}, + {file = "ruff-0.4.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c4efe62b5bbb24178c950732ddd40712b878a9b96b1d02b0ff0b08a090cbd891"}, + {file = "ruff-0.4.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8e2f1e8fc12d07ab521a9005d68a969e167b589cbcaee354cb61e9d9de9c15"}, + {file = "ruff-0.4.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60ed88b636a463214905c002fa3eaab19795679ed55529f91e488db3fe8976ab"}, + {file = "ruff-0.4.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b90fc5e170fc71c712cc4d9ab0e24ea505c6a9e4ebf346787a67e691dfb72e85"}, + {file = "ruff-0.4.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8e7e6ebc10ef16dcdc77fd5557ee60647512b400e4a60bdc4849468f076f6eef"}, + {file = "ruff-0.4.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9ddb2c494fb79fc208cd15ffe08f32b7682519e067413dbaf5f4b01a6087bcd"}, + {file = "ruff-0.4.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c51c928a14f9f0a871082603e25a1588059b7e08a920f2f9fa7157b5bf08cfe9"}, + {file = "ruff-0.4.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5eb0a4bfd6400b7d07c09a7725e1a98c3b838be557fee229ac0f84d9aa49c36"}, + {file = "ruff-0.4.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b1867ee9bf3acc21778dcb293db504692eda5f7a11a6e6cc40890182a9f9e595"}, + {file = "ruff-0.4.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1aecced1269481ef2894cc495647392a34b0bf3e28ff53ed95a385b13aa45768"}, + {file = "ruff-0.4.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9da73eb616b3241a307b837f32756dc20a0b07e2bcb694fec73699c93d04a69e"}, + {file = "ruff-0.4.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:958b4ea5589706a81065e2a776237de2ecc3e763342e5cc8e02a4a4d8a5e6f95"}, + {file = "ruff-0.4.4-py3-none-win32.whl", hash = "sha256:cb53473849f011bca6e754f2cdf47cafc9c4f4ff4570003a0dad0b9b6890e876"}, + {file = "ruff-0.4.4-py3-none-win_amd64.whl", hash = "sha256:424e5b72597482543b684c11def82669cc6b395aa8cc69acc1858b5ef3e5daae"}, + {file = "ruff-0.4.4-py3-none-win_arm64.whl", hash = "sha256:39df0537b47d3b597293edbb95baf54ff5b49589eb7ff41926d8243caa995ea6"}, + {file = "ruff-0.4.4.tar.gz", hash = "sha256:f87ea42d5cdebdc6a69761a9d0bc83ae9b3b30d0ad78952005ba6568d6c022af"}, ] [[package]] From 01aaf35e1677dc8e0fbd3503d72049297fef9cde Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 01:34:13 +0000 Subject: [PATCH 162/598] build(deps-dev): bump mkdocs-material from 9.5.21 to 9.5.22 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.21 to 9.5.22. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.21...9.5.22) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7a8aa525e1..7d7f8e43d8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -796,13 +796,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.21" +version = "9.5.22" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.21-py3-none-any.whl", hash = "sha256:210e1f179682cd4be17d5c641b2f4559574b9dea2f589c3f0e7c17c5bd1959bc"}, - {file = "mkdocs_material-9.5.21.tar.gz", hash = "sha256:049f82770f40559d3c2aa2259c562ea7257dbb4aaa9624323b5ef27b2d95a450"}, + {file = "mkdocs_material-9.5.22-py3-none-any.whl", hash = "sha256:8c7a377d323567934e6cd46915e64dc209efceaec0dec1cf2202184f5649862c"}, + {file = "mkdocs_material-9.5.22.tar.gz", hash = "sha256:22a853a456ae8c581c4628159574d6fc7c71b2c7569dc9c3a82cc70432219599"}, ] [package.dependencies] From 4bd2525a42310d5896db3fb244a7bbe36e9e496f Mon Sep 17 00:00:00 2001 From: Norwid Behrnd Date: Tue, 14 May 2024 13:22:36 +0200 Subject: [PATCH 163/598] refactor: strip possessive from note about ci option A description of the commit option affecting the ci does not require a "our", nor "your". It doesn't relate to "a local" vs. "a remote repository", either. To ease conveying the intent,[1] the possessive is removed. [1] https://github.com/commitizen-tools/commitizen/issues/1095 Signed-off-by: Norwid Behrnd --- commitizen/cz/conventional_commits/conventional_commits.py | 2 +- docs/images/commit.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 5f693963e7..dcfd7bab89 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -102,7 +102,7 @@ def questions(self) -> Questions: { "value": "ci", "name": ( - "ci: Changes to our CI configuration files and " + "ci: Changes to CI configuration files and " "scripts (example scopes: GitLabCI)" ), "key": "c", diff --git a/docs/images/commit.yml b/docs/images/commit.yml index a239bc3aab..fd10ed777f 100644 --- a/docs/images/commit.yml +++ b/docs/images/commit.yml @@ -136,9 +136,9 @@ records: - delay: 209 content: "\e[?1l\e[6n" - delay: 7 - content: "\e[?2004h\e[?25l\e[0m\e[?7l\e[0m\e[J\e[0;38;5;67m?\e[0;1m Select the type of change you are committing \e[0m (Use arrow keys) \r\e[100C \e[0m\r\r\n\e[0m » fix: A bug fix. Correlates with PATCH in SemVer\e[0m\r\r\n\e[0m feat: A new feature. Correlates with MINOR in SemVer\e[0m\r\r\n\e[0m docs: Documentation only changes\e[0m\r\r\n\e[0m style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-\r\e[100Cc\e[0m\r\r\n\e[0m refactor: A code change that neither fixes a bug nor adds a feature\e[0m\r\r\n\e[0m perf: A code change that improves performance\e[0m\r\r\n\e[0m test: Adding missing or correcting existing tests\e[0m\r\r\n\e[0m build: Changes that affect the build system or external dependencies (example scopes: pip, docker\r\e[100C,\e[0m\r\r\n\e[0m ci: Changes to our CI configuration files and scripts (example scopes: GitLabCI) \r\e[100C \r\e[9A\e[64C\e[?7h\e[0m\e[?12l\e[?25h" + content: "\e[?2004h\e[?25l\e[0m\e[?7l\e[0m\e[J\e[0;38;5;67m?\e[0;1m Select the type of change you are committing \e[0m (Use arrow keys) \r\e[100C \e[0m\r\r\n\e[0m » fix: A bug fix. Correlates with PATCH in SemVer\e[0m\r\r\n\e[0m feat: A new feature. Correlates with MINOR in SemVer\e[0m\r\r\n\e[0m docs: Documentation only changes\e[0m\r\r\n\e[0m style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-\r\e[100Cc\e[0m\r\r\n\e[0m refactor: A code change that neither fixes a bug nor adds a feature\e[0m\r\r\n\e[0m perf: A code change that improves performance\e[0m\r\r\n\e[0m test: Adding missing or correcting existing tests\e[0m\r\r\n\e[0m build: Changes that affect the build system or external dependencies (example scopes: pip, docker\r\e[100C,\e[0m\r\r\n\e[0m ci: Changes to CI configuration files and scripts (example scopes: GitLabCI) \r\e[100C \r\e[9A\e[64C\e[?7h\e[0m\e[?12l\e[?25h" - delay: 17 - content: "\e[?25l\e[?7l\e[0m\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\e[0m ci: Changes to our CI configuration files and scripts (example scopes: GitLabCI)\e[0m\e[K\e[0m\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\e[0m \r\e[100C \r\e[19A\e[64C\e[?7h\e[0m\e[?12l\e[?25h" + content: "\e[?25l\e[?7l\e[0m\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\e[0m ci: Changes to CI configuration files and scripts (example scopes: GitLabCI)\e[0m\e[K\e[0m\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\e[0m \r\e[100C \r\e[19A\e[64C\e[?7h\e[0m\e[?12l\e[?25h" - delay: 647 content: "\e[?25l\e[?7l\e[0m\r\r\n\e[0m \e[0m\r\r\n\e[0m » \e[2A\e[61C\e[?7h\e[0m\e[?12l\e[?25h" - delay: 574 From 9d17f393228f6c60793b4929d910e3b1f0fcb1ad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 15 May 2024 02:32:09 +0000 Subject: [PATCH 164/598] =?UTF-8?q?bump:=20version=203.25.0=20=E2=86=92=20?= =?UTF-8?q?3.25.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index be1a106a30..a795a9300e 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.25.0 # automatically updated by Commitizen + rev: v3.25.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index d0df802fda..f10a35b917 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.25.1 (2024-05-15) + +### Refactor + +- strip possessive from note about ci option + ## v3.25.0 (2024-04-30) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index e1609ca35c..1d3669f91a 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.25.0" +__version__ = "3.25.1" diff --git a/pyproject.toml b/pyproject.toml index da57effff7..d17a8e63c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.25.0" +version = "3.25.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.25.0" +version = "3.25.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 9308cd7fd65c0fd1dab9c14095acde707320f8a5 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 25 Apr 2024 23:28:20 +0800 Subject: [PATCH 165/598] docs: fix missing links, reorganize documentation and replace command help messages with images --- docs/README.md | 2 +- docs/{ => commands}/bump.md | 66 ++----------------- docs/{ => commands}/changelog.md | 34 ++-------- docs/{ => commands}/check.md | 6 +- docs/{ => commands}/commit.md | 7 +- docs/{ => commands}/init.md | 8 ++- docs/config.md | 22 +++---- docs/contributing.md | 2 +- docs/customization.md | 4 +- docs/getting_started.md | 8 +-- docs/tutorials/auto_prepare_commit_message.md | 2 +- docs/tutorials/gitlab_ci.md | 2 +- mkdocs.yml | 10 +-- 13 files changed, 53 insertions(+), 120 deletions(-) rename docs/{ => commands}/bump.md (83%) rename docs/{ => commands}/changelog.md (76%) rename docs/{ => commands}/check.md (89%) rename docs/{ => commands}/commit.md (91%) rename docs/{ => commands}/init.md (86%) diff --git a/docs/README.md b/docs/README.md index 8c7dc51e48..b4fa13eb2c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -32,7 +32,7 @@ descriptive commits. ### Features - Command-line utility to create commits with your rules. Defaults: [Conventional commits][conventional_commits] -- Bump version automatically using [semantic versioning][semver] based on the commits. [Read More](./bump.md) +- Bump version automatically using [semantic versioning][semver] based on the commits. [Read More](./commands/bump.md) - Generate a changelog using [Keep a changelog][keepchangelog] - Update your project's version files automatically - Display information about your commit rules (commands: schema, example, info) diff --git a/docs/bump.md b/docs/commands/bump.md similarity index 83% rename from docs/bump.md rename to docs/commands/bump.md index 6dad38219e..5f5590e885 100644 --- a/docs/bump.md +++ b/docs/commands/bump.md @@ -1,4 +1,4 @@ -![Bump version](images/bump.gif) +![Bump version](../images/bump.gif) ## About @@ -50,60 +50,8 @@ Some examples of pep440: ## Usage -```bash -$ 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}] - [--check-consistency] [--annotated-tag] [--gpg-sign] [--changelog-to-stdout] [--git-output-to-stderr] [--retry] [--major-version-zero] - [--prerelease-offset PRERELEASE_OFFSET] [--version-scheme {pep440,semver,semver2}] [--version-type {pep440,semver,semver2}] [--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 - 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 - --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 - --prerelease-offset PRERELEASE_OFFSET - start pre-releases with this offset - --version-scheme {pep440,semver,semver2} - choose version scheme - --version-type {pep440,semver,semver2} - Deprecated, use --version-scheme - --build-metadata {BUILD_METADATA} - additional metadata in the version string -``` +![cz bump --help](../images/cli_help/cz_bump___help.svg) + ### `--files-only` @@ -306,7 +254,7 @@ Yes, you shouldn't have any issues. ### `--template` Provides your own changelog jinja template. -See [the template customization section](customization.md#customizing-the-changelog-template) +See [the template customization section](../customization.md#customizing-the-changelog-template) ### `--extra` @@ -316,7 +264,7 @@ Provides your own changelog extra variables by using the `extras` settings or th cz bump --changelog --extra key=value -e short="quoted value" ``` -See [the template customization section](customization.md#customizing-the-changelog-template). +See [the template customization section](../customization.md#customizing-the-changelog-template). ### `--build-metadata` @@ -388,7 +336,7 @@ cz --no-raise 3,4,5 ### Longer way -Check the list of [exit_codes](./exit_codes.md) and understand which one you have +Check the list of [exit_codes](../exit_codes.md) and understand which one you have to skip and why. Remember to document somewhere this, because you'll forget. @@ -637,7 +585,7 @@ version_scheme = "semver" ## Custom bump -Read the [customizing section](./customization.md). +Read the [customizing section](../customization.md). [pep440]: https://www.python.org/dev/peps/pep-0440/ [semver]: https://semver.org/ diff --git a/docs/changelog.md b/docs/commands/changelog.md similarity index 76% rename from docs/changelog.md rename to docs/commands/changelog.md index 029882c12b..cbf22b15a7 100644 --- a/docs/changelog.md +++ b/docs/commands/changelog.md @@ -11,33 +11,7 @@ update_changelog_on_bump = true ## Usage -```bash -$ cz changelog --help -usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] [--unreleased-version UNRELEASED_VERSION] [--incremental] [--start-rev START_REV] - [--template TEMPLATE] [--extra EXTRA] - [rev_range] - -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) - -optional arguments: - -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 - start rev of the changelog.If not set, it will generate changelog from the start - --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') -``` +![cz changelog --help](../images/cli_help/cz_changelog___help.svg) ### Examples @@ -195,7 +169,7 @@ changelog_merge_prerelease = true ### `template` Provides your own changelog jinja template by using the `template` settings or the `--template` parameter. -See [the template customization section](customization.md#customizing-the-changelog-template) +See [the template customization section](../customization.md#customizing-the-changelog-template) ### `extras` @@ -205,7 +179,7 @@ Provides your own changelog extra variables by using the `extras` settings or th cz changelog --extra key=value -e short="quoted value" ``` -See [the template customization section](customization.md#customizing-the-changelog-template) +See [the template customization section](../customization.md#customizing-the-changelog-template) ## Hooks @@ -218,4 +192,4 @@ Read more about hooks in the [customization page][customization] [keepachangelog]: https://keepachangelog.com/ [semver]: https://semver.org/ -[customization]: ./customization.md +[customization]: ../customization.md diff --git a/docs/check.md b/docs/commands/check.md similarity index 89% rename from docs/check.md rename to docs/commands/check.md index 1cd42c74a9..c31fd085ee 100644 --- a/docs/check.md +++ b/docs/commands/check.md @@ -5,10 +5,12 @@ This feature checks whether the commit message follows the given committing rules. And comment in git message will be ignored. If you want to setup an automatic check before every git commit, please refer to -[Automatically check message before commit](./tutorials/auto_check.md). +[Automatically check message before commit](../tutorials/auto_check.md). ## Usage +![cz check --help](../images/cli_help/cz_check___help.svg) + There are three mutually exclusive ways to use `cz check`: - with `--rev-range` to check a range of pre-existing commits @@ -54,7 +56,7 @@ $ cz check --commit-msg-file COMMIT_MSG_FILE ``` In this option, COMMIT_MSG_FILE is the path of the temporal file that contains the commit message. -This argument can be useful when cooperating with git hook, please check [Automatically check message before commit](./tutorials/auto_check.md) for more information about how to use this argument with git hook. +This argument can be useful when cooperating with git hook, please check [Automatically check message before commit](../tutorials/auto_check.md) for more information about how to use this argument with git hook. ### Allow Abort diff --git a/docs/commit.md b/docs/commands/commit.md similarity index 91% rename from docs/commit.md rename to docs/commands/commit.md index 2c1b94f63e..7760a2b88e 100644 --- a/docs/commit.md +++ b/docs/commands/commit.md @@ -1,4 +1,4 @@ -![Using commitizen cli](images/demo.gif) +![Using commitizen cli](../images/demo.gif) ## About @@ -7,13 +7,16 @@ In your terminal run `cz commit` or the shortcut `cz c` to generate a guided git You can run `cz commit --write-message-to-file COMMIT_MSG_FILE` to additionally save the generated message to a file. This can be combined with the `--dry-run` flag to only write the message to a file and not modify files and create a commit. A possible use -case for this is to [automatically prepare a commit message](./tutorials/auto_prepare_commit_message.md). +case for this is to [automatically prepare a commit message](../tutorials/auto_prepare_commit_message.md). !!! note To maintain platform compatibility, the `commit` command disable ANSI escaping in its output. In particular pre-commit hooks coloring will be deactivated as discussed in [commitizen-tools/commitizen#417](https://github.com/commitizen-tools/commitizen/issues/417). +## Usage + +![cz commit --help](../images/cli_help/cz_commit___help.svg) ### git options diff --git a/docs/init.md b/docs/commands/init.md similarity index 86% rename from docs/init.md rename to docs/commands/init.md index 778a79f529..01e1db6be8 100644 --- a/docs/init.md +++ b/docs/commands/init.md @@ -1,4 +1,8 @@ -![Bump version](images/init.gif) +## Usage + +![cz init --help](../images/cli_help/cz_init___help.svg) + +## Example To start using commitizen, the recommended approach is to run @@ -6,6 +10,8 @@ To start using commitizen, the recommended approach is to run cz init ``` +![init](../images/init.gif) + This command will ask you for information about the project and will configure the selected file type (`pyproject.toml`, `.cz.toml`, etc.). diff --git a/docs/config.md b/docs/config.md index 7ef8644fa2..398c045339 100644 --- a/docs/config.md +++ b/docs/config.md @@ -384,17 +384,17 @@ setup( ) ``` -[version_files]: bump.md#version_files -[tag_format]: bump.md#tag_format -[bump_message]: bump.md#bump_message -[major-version-zero]: bump.md#-major-version-zero -[prerelease-offset]: bump.md#-prerelease_offset -[retry_after_failure]: commit.md#retry -[allow_abort]: check.md#allow-abort -[version-scheme]: bump.md#version-scheme -[pre_bump_hooks]: bump.md#pre_bump_hooks -[post_bump_hooks]: bump.md#post_bump_hooks -[allowed_prefixes]: check.md#allowed-prefixes +[version_files]: commands/bump.md#version_files +[tag_format]: commands/bump.md#tag_format +[bump_message]: commands/bump.md#bump_message +[major-version-zero]: commands/bump.md#-major-version-zero +[prerelease-offset]: commands/bump.md#-prerelease_offset +[retry_after_failure]: commands/commit.md#retry +[allow_abort]: commands/check.md#allow-abort +[version-scheme]: commands/bump.md#version-scheme +[pre_bump_hooks]: commands/bump.md#pre_bump_hooks +[post_bump_hooks]: commands/bump.md#post_bump_hooks +[allowed_prefixes]: commands/check.md#allowed-prefixes [additional-features]: https://github.com/tmbo/questionary#additional-features [customization]: customization.md [shortcuts]: customization.md#shortcut-keys diff --git a/docs/contributing.md b/docs/contributing.md index 77ee1f44fe..a41843d753 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -105,4 +105,4 @@ flowchart TD ``` -[conventional-commmits]: https://www.conventionalcommits.org/ +[conventional-commits]: https://www.conventionalcommits.org/ diff --git a/docs/customization.md b/docs/customization.md index 1fd1826e03..e8f233fce1 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -193,7 +193,7 @@ The basic steps are: 3. Create a python package using `setup.py`, `poetry`, etc 4. Expose the class as a `commitizen.plugin` entrypoint -Check an [example](convcomms) on how to configure `BaseCommitizen`. +Check an [example][convcomms] on how to configure `BaseCommitizen`. You can also automate the steps above through [cookiecutter](https://cookiecutter.readthedocs.io/en/1.7.0/). @@ -372,7 +372,7 @@ class StrangeCommitizen(BaseCommitizen): return full_changelog ``` -[changelog-des]: ./changelog.md#description +[changelog-des]: ./commands/changelog.md#description ### Raise Customize Exception diff --git a/docs/getting_started.md b/docs/getting_started.md index e826a5e424..7ceba2bb65 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -27,10 +27,10 @@ cz bump This command will bump your project's version, and it will create a tag. Because of the setting `update_changelog_on_bump`, bump will also create the **changelog**. -You can also [update files](./bump.md#version_files). -You can configure the [version scheme](./bump.md#version_scheme) and [version provider](./config.md#version-providers). +You can also [update files](./commands/bump.md#version_files). +You can configure the [version scheme](./commands/bump.md#version_scheme) and [version provider](./config.md#version-providers). -There are many more options available, please read the docs for the [bump command](./bump.md). +There are many more options available, please read the docs for the [bump command](./commands/bump.md). ### Committing @@ -116,4 +116,4 @@ Note that pre-commit discourages using `master` as a revision, and the above com pre-commit autoupdate ``` -Read more about the `check` command [here](check.md). +Read more about the `check` command [here](commands/check.md). diff --git a/docs/tutorials/auto_prepare_commit_message.md b/docs/tutorials/auto_prepare_commit_message.md index 80a1b211d7..3011142679 100644 --- a/docs/tutorials/auto_prepare_commit_message.md +++ b/docs/tutorials/auto_prepare_commit_message.md @@ -7,7 +7,7 @@ squash) so that the complete git history adheres to the commit message conventio without ever having to call `cz commit`. To automatically prepare a commit message prior to committing, you can -use a [prepare-commit-msg Git hook](prepare-commit-msg-docs): +use a [prepare-commit-msg Git hook][prepare-commit-msg-docs]: > This hook is invoked by git-commit right after preparing the > default log message, and before the editor is started. diff --git a/docs/tutorials/gitlab_ci.md b/docs/tutorials/gitlab_ci.md index 7b6e2032df..de1336b675 100644 --- a/docs/tutorials/gitlab_ci.md +++ b/docs/tutorials/gitlab_ci.md @@ -10,7 +10,7 @@ _Goal_: Bump a new version every time that a change occurs on the `master` branc 2. A developer creates a merge request (MR) against `master` branch 3. When the `MR` is merged into master, the 2 stages of the CI are executed 4. For simplification, we store the software version in a file called `VERSION`. You can use any file that you want as `commitizen` supports it. -5. The commit message executed automatically by the `CI` must include `[skip-ci]` in the message; otherwise, the process will generate a loop. You can define the message structure in [commitizen](../bump.md) as well. +5. The commit message executed automatically by the `CI` must include `[skip-ci]` in the message; otherwise, the process will generate a loop. You can define the message structure in [commitizen](../commands/bump.md) as well. ### Gitlab Configuration diff --git a/mkdocs.yml b/mkdocs.yml index 1f76605153..f80e427981 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,11 +33,11 @@ nav: - Introduction: "README.md" - Getting Started: "getting_started.md" - Commands: - - Init: "init.md" - - Commit: "commit.md" - - Bump: "bump.md" - - Check: "check.md" - - Changelog: "changelog.md" + - Init: "commands/init.md" + - Commit: "commands/commit.md" + - Bump: "commands/bump.md" + - Check: "commands/check.md" + - Changelog: "commands/changelog.md" - Configuration: "config.md" - Customization: "customization.md" - Tutorials: From 3e57007bf1f882a6ed34717c68d3a265e16dcf7a Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 25 Apr 2024 23:44:51 +0800 Subject: [PATCH 166/598] docs: initial documentation for undocumented commands --- docs/commands/example.md | 5 +++++ docs/commands/info.md | 5 +++++ docs/commands/ls.md | 3 +++ docs/commands/schema.md | 5 +++++ docs/commands/version.md | 5 +++++ mkdocs.yml | 15 ++++++++++----- 6 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 docs/commands/example.md create mode 100644 docs/commands/info.md create mode 100644 docs/commands/ls.md create mode 100644 docs/commands/schema.md create mode 100644 docs/commands/version.md diff --git a/docs/commands/example.md b/docs/commands/example.md new file mode 100644 index 0000000000..8243453916 --- /dev/null +++ b/docs/commands/example.md @@ -0,0 +1,5 @@ +Show commit example + +## Usage + +![cz example --help](../images/cli_help/cz_example___help.svg) diff --git a/docs/commands/info.md b/docs/commands/info.md new file mode 100644 index 0000000000..5f816ba88d --- /dev/null +++ b/docs/commands/info.md @@ -0,0 +1,5 @@ +Show information about the cz + +## Usage + +![cz info --help](../images/cli_help/cz_info___help.svg) diff --git a/docs/commands/ls.md b/docs/commands/ls.md new file mode 100644 index 0000000000..f255ca5444 --- /dev/null +++ b/docs/commands/ls.md @@ -0,0 +1,3 @@ +## Usage + +![cz ls --help](../images/cli_help/cz_ls___help.svg) diff --git a/docs/commands/schema.md b/docs/commands/schema.md new file mode 100644 index 0000000000..bd6fa85195 --- /dev/null +++ b/docs/commands/schema.md @@ -0,0 +1,5 @@ +Show commit schema + +## Usage + +![cz schema --help](../images/cli_help/cz_schema___help.svg) diff --git a/docs/commands/version.md b/docs/commands/version.md new file mode 100644 index 0000000000..9a8176b45f --- /dev/null +++ b/docs/commands/version.md @@ -0,0 +1,5 @@ +Get the version of the installed commitizen or the current project (default: installed commitizen) + +## Usage + +![cz version --help](../images/cli_help/cz_version___help.svg) diff --git a/mkdocs.yml b/mkdocs.yml index f80e427981..a0fb57fde2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,11 +33,16 @@ nav: - Introduction: "README.md" - Getting Started: "getting_started.md" - Commands: - - Init: "commands/init.md" - - Commit: "commands/commit.md" - - Bump: "commands/bump.md" - - Check: "commands/check.md" - - Changelog: "commands/changelog.md" + - init: "commands/init.md" + - commit: "commands/commit.md" + - bump: "commands/bump.md" + - check: "commands/check.md" + - changelog: "commands/changelog.md" + - example: "commands/example.md" + - info: "commands/info.md" + - ls: "commands/ls.md" + - schema: "commands/schema.md" + - version: "commands/version.md" - Configuration: "config.md" - Customization: "customization.md" - Tutorials: From f1ece99dc9ca142268b912671b04dfdfe5addb3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 01:46:55 +0000 Subject: [PATCH 167/598] build(deps-dev): bump mkdocs-material from 9.5.22 to 9.5.23 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.22 to 9.5.23. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.22...9.5.23) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7d7f8e43d8..b6313ee09e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -796,13 +796,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.22" +version = "9.5.23" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.22-py3-none-any.whl", hash = "sha256:8c7a377d323567934e6cd46915e64dc209efceaec0dec1cf2202184f5649862c"}, - {file = "mkdocs_material-9.5.22.tar.gz", hash = "sha256:22a853a456ae8c581c4628159574d6fc7c71b2c7569dc9c3a82cc70432219599"}, + {file = "mkdocs_material-9.5.23-py3-none-any.whl", hash = "sha256:ffd08a5beaef3cd135aceb58ded8b98bbbbf2b70e5b656f6a14a63c917d9b001"}, + {file = "mkdocs_material-9.5.23.tar.gz", hash = "sha256:4627fc3f15de2cba2bde9debc2fd59b9888ef494beabfe67eb352e23d14bf288"}, ] [package.dependencies] From ce2128fe18174d806c80493cba20b816bd6b09cc Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Fri, 17 May 2024 14:12:25 -0300 Subject: [PATCH 168/598] feat(ci/cd): automates the generation of CLI screenshots --- .../workflows/generate_cli_screenshots.yml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/generate_cli_screenshots.yml diff --git a/.github/workflows/generate_cli_screenshots.yml b/.github/workflows/generate_cli_screenshots.yml new file mode 100644 index 0000000000..7bbc8b16d9 --- /dev/null +++ b/.github/workflows/generate_cli_screenshots.yml @@ -0,0 +1,39 @@ +name: Generate CLI screenshots + +on: + pull_request: + types: + - closed + +jobs: + generate_cli_screenshots: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}" + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Install dependencies + run: | + python -m pip install -U pip poetry + poetry --version + poetry install + + - name: Generate CLI screenshots + run: | + poetry run python scripts/gen_cli_help_screenshots.py + + - name: Commit and push CLI screenshots + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add docs/images/cli_help + git commit -m "docs(cli/screenshots) update CLI screenshots" + git push From c2bbc92202e9080adcdf8fa2e99c9e4406a1f684 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 18 May 2024 11:11:37 +0000 Subject: [PATCH 169/598] =?UTF-8?q?bump:=20version=203.25.1=20=E2=86=92=20?= =?UTF-8?q?3.26.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a795a9300e..d3c9a02544 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.25.1 # automatically updated by Commitizen + rev: v3.26.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index f10a35b917..e99491f1cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.26.0 (2024-05-18) + +### Feat + +- **ci/cd**: automates the generation of CLI screenshots + ## v3.25.1 (2024-05-15) ### Refactor diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 1d3669f91a..1e6bdc4260 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.25.1" +__version__ = "3.26.0" diff --git a/pyproject.toml b/pyproject.toml index d17a8e63c7..beb7b87308 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.25.1" +version = "3.26.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.25.1" +version = "3.26.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From f5cc52846bd9cddcff1110f76eba9441ec8c627b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 01:23:34 +0000 Subject: [PATCH 170/598] build(deps-dev): bump pytest from 8.2.0 to 8.2.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.0 to 8.2.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.2.0...8.2.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index b6313ee09e..2e16545b02 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1100,13 +1100,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.2.0" +version = "8.2.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.0-py3-none-any.whl", hash = "sha256:1733f0620f6cda4095bbf0d9ff8022486e91892245bb9e7d5542c018f612f233"}, - {file = "pytest-8.2.0.tar.gz", hash = "sha256:d507d4482197eac0ba2bae2e9babf0672eb333017bcedaa5fb1a3d42c1174b3f"}, + {file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"}, + {file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"}, ] [package.dependencies] From 37522866e4788deb12b2ef1c426662400b0ebac8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 20 May 2024 13:58:43 +0000 Subject: [PATCH 171/598] docs(cli/screenshots) update CLI screenshots --- docs/images/cli_help/cz___help.svg | 172 +++++----- docs/images/cli_help/cz_bump___help.svg | 336 +++++++++---------- docs/images/cli_help/cz_changelog___help.svg | 180 +++++----- docs/images/cli_help/cz_check___help.svg | 4 +- docs/images/cli_help/cz_commit___help.svg | 103 +++--- docs/images/cli_help/cz_example___help.svg | 4 +- docs/images/cli_help/cz_info___help.svg | 4 +- docs/images/cli_help/cz_init___help.svg | 4 +- docs/images/cli_help/cz_ls___help.svg | 4 +- docs/images/cli_help/cz_schema___help.svg | 4 +- docs/images/cli_help/cz_version___help.svg | 4 +- 11 files changed, 418 insertions(+), 401 deletions(-) diff --git a/docs/images/cli_help/cz___help.svg b/docs/images/cli_help/cz___help.svg index 07b23d558f..22a9e4d0e7 100644 --- a/docs/images/cli_help/cz___help.svg +++ b/docs/images/cli_help/cz___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - - - - - $ 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) - + + + + + $ cz --help +usage: cz [-h][--config CONFIG][--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 +  --config 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 +                        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 index 18d402f16e..5b71728ccf 100644 --- a/docs/images/cli_help/cz_bump___help.svg +++ b/docs/images/cli_help/cz_bump___help.svg @@ -19,261 +19,261 @@ font-weight: 700; } - .terminal-2106414123-matrix { + .terminal-908877803-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2106414123-title { + .terminal-908877803-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2106414123-r1 { fill: #c5c8c6 } -.terminal-2106414123-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-2106414123-r3 { fill: #68a0b3;font-weight: bold } -.terminal-2106414123-r4 { fill: #98a84b } + .terminal-908877803-r1 { fill: #c5c8c6 } +.terminal-908877803-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-908877803-r3 { fill: #68a0b3;font-weight: bold } +.terminal-908877803-r4 { fill: #98a84b } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -284,89 +284,89 @@ - - - - - $ 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 - + + + + + $ 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 {pep440,semver,semver2}] +[--version-type {pep440,semver,semver2}] +[--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 {pep440,semver,semver2} +                        choose version scheme +  --version-type {pep440,semver,semver2} +                        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 index 4f236ea467..a7d277df44 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -19,144 +19,144 @@ font-weight: 700; } - .terminal-3815852825-matrix { + .terminal-37245177-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-3815852825-title { + .terminal-37245177-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-3815852825-r1 { fill: #c5c8c6 } -.terminal-3815852825-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-3815852825-r3 { fill: #68a0b3;font-weight: bold } -.terminal-3815852825-r4 { fill: #98a84b } + .terminal-37245177-r1 { fill: #c5c8c6 } +.terminal-37245177-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-37245177-r3 { fill: #68a0b3;font-weight: bold } +.terminal-37245177-r4 { fill: #98a84b } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -167,50 +167,50 @@ - - - - - $ 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') - + + + + + $ 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 {semver,semver2,pep440}] +[--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 {semver,semver2,pep440} +                        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 index 82dab7282e..427d91e414 100644 --- a/docs/images/cli_help/cz_check___help.svg +++ b/docs/images/cli_help/cz_check___help.svg @@ -116,9 +116,9 @@ - + - + $ cz check --help usage: cz check [-h] diff --git a/docs/images/cli_help/cz_commit___help.svg b/docs/images/cli_help/cz_commit___help.svg index e29f55607d..deb871fce9 100644 --- a/docs/images/cli_help/cz_commit___help.svg +++ b/docs/images/cli_help/cz_commit___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + - + - - - - - $ 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. - + + + + + $ cz commit --help +usage: cz commit [-h][--retry][--no-retry][--dry-run] +[--write-message-to-file FILE_PATH][-s][-a] +[-l MESSAGE_LENGTH_LIMIT] + +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. +  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit + diff --git a/docs/images/cli_help/cz_example___help.svg b/docs/images/cli_help/cz_example___help.svg index a3fee0064a..e142dd4f9b 100644 --- a/docs/images/cli_help/cz_example___help.svg +++ b/docs/images/cli_help/cz_example___help.svg @@ -63,9 +63,9 @@ - + - + $ cz example --help usage: cz example [-h] diff --git a/docs/images/cli_help/cz_info___help.svg b/docs/images/cli_help/cz_info___help.svg index 02c2f313df..8059ec466c 100644 --- a/docs/images/cli_help/cz_info___help.svg +++ b/docs/images/cli_help/cz_info___help.svg @@ -63,9 +63,9 @@ - + - + $ cz info --help usage: cz info [-h] diff --git a/docs/images/cli_help/cz_init___help.svg b/docs/images/cli_help/cz_init___help.svg index b296b79d76..6bcd577160 100644 --- a/docs/images/cli_help/cz_init___help.svg +++ b/docs/images/cli_help/cz_init___help.svg @@ -63,9 +63,9 @@ - + - + $ cz init --help usage: cz init [-h] diff --git a/docs/images/cli_help/cz_ls___help.svg b/docs/images/cli_help/cz_ls___help.svg index 7e95d4c8dc..390f5bbb42 100644 --- a/docs/images/cli_help/cz_ls___help.svg +++ b/docs/images/cli_help/cz_ls___help.svg @@ -63,9 +63,9 @@ - + - + $ cz ls --help usage: cz ls [-h] diff --git a/docs/images/cli_help/cz_schema___help.svg b/docs/images/cli_help/cz_schema___help.svg index 201778bdfd..443634428d 100644 --- a/docs/images/cli_help/cz_schema___help.svg +++ b/docs/images/cli_help/cz_schema___help.svg @@ -63,9 +63,9 @@ - + - + $ cz schema --help usage: cz schema [-h] diff --git a/docs/images/cli_help/cz_version___help.svg b/docs/images/cli_help/cz_version___help.svg index 0a7dc85397..0d14aaffa1 100644 --- a/docs/images/cli_help/cz_version___help.svg +++ b/docs/images/cli_help/cz_version___help.svg @@ -78,9 +78,9 @@ - + - + $ cz version --help usage: cz version [-h][-r | -p | -c | -v] From b62456a61a95351c285a8ca340670e65f96fbda9 Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Mon, 20 May 2024 09:53:26 -0300 Subject: [PATCH 172/598] ci(workflow): move 'generate_cli_screenshots' steps to 'docspublish' Since the purpose is to updated the CLI screenshots on Github Pages, combining this two workflows makes sense. --- .github/workflows/docspublish.yml | 31 +++++++++++++++ .../workflows/generate_cli_screenshots.yml | 39 ------------------- 2 files changed, 31 insertions(+), 39 deletions(-) delete mode 100644 .github/workflows/generate_cli_screenshots.yml diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index d95b464b40..1ac8e7f5e3 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -6,13 +6,44 @@ on: - master jobs: + update-cli-screenshots: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + - name: Install dependencies + run: | + python -m pip install -U pip poetry + poetry --version + poetry install + - name: Update CLI screenshots + run: | + poetry run python scripts/gen_cli_help_screenshots.py + - name: Commit and push updated CLI screenshots + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add docs/images/cli_help + git commit -m "docs(cli/screenshots) update CLI screenshots" -m "[skip ci]" + git push + publish-documentation: runs-on: ubuntu-latest + needs: update-cli-screenshots steps: - uses: actions/checkout@v4 with: token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}" fetch-depth: 0 + - name: Pull latest changes + run: | + git pull origin master - name: Set up Python uses: actions/setup-python@v5 with: diff --git a/.github/workflows/generate_cli_screenshots.yml b/.github/workflows/generate_cli_screenshots.yml deleted file mode 100644 index 7bbc8b16d9..0000000000 --- a/.github/workflows/generate_cli_screenshots.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Generate CLI screenshots - -on: - pull_request: - types: - - closed - -jobs: - generate_cli_screenshots: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}" - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.x" - - - name: Install dependencies - run: | - python -m pip install -U pip poetry - poetry --version - poetry install - - - name: Generate CLI screenshots - run: | - poetry run python scripts/gen_cli_help_screenshots.py - - - name: Commit and push CLI screenshots - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git add docs/images/cli_help - git commit -m "docs(cli/screenshots) update CLI screenshots" - git push From e6e97dcdbeb993d7e10b9fdfd55525a00ade22e2 Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Mon, 20 May 2024 11:38:18 -0300 Subject: [PATCH 173/598] ci: exclude *.svg files from trailing whitespace hook --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d3c9a02544..163e7a0ab3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,6 +21,7 @@ repos: exclude: "tests/((commands|data)/|test_).+" - id: trailing-whitespace args: [ --markdown-linebreak-ext=md ] + exclude: '\.svg$' - id: debug-statements - id: no-commit-to-branch - id: check-merge-conflict From 59270b96e6b7e2f8121ea6d6025634ecfa64ae18 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Tue, 21 May 2024 00:04:23 +0800 Subject: [PATCH 174/598] ci(docpublish): reword cli screenshot generation commit message --- .github/workflows/docspublish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index 1ac8e7f5e3..4ac9a3a4a4 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -30,7 +30,7 @@ jobs: git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" git add docs/images/cli_help - git commit -m "docs(cli/screenshots) update CLI screenshots" -m "[skip ci]" + git commit -m "docs(cli/screenshots): update CLI screenshots" -m "[skip ci]" git push publish-documentation: From 7eafdfa3f53709fba80a21663c7788062e5457dd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 20 May 2024 16:16:25 +0000 Subject: [PATCH 175/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz_bump___help.svg | 332 +++++++++---------- docs/images/cli_help/cz_changelog___help.svg | 176 +++++----- 2 files changed, 254 insertions(+), 254 deletions(-) diff --git a/docs/images/cli_help/cz_bump___help.svg b/docs/images/cli_help/cz_bump___help.svg index 5b71728ccf..6d217d3958 100644 --- a/docs/images/cli_help/cz_bump___help.svg +++ b/docs/images/cli_help/cz_bump___help.svg @@ -19,261 +19,261 @@ font-weight: 700; } - .terminal-908877803-matrix { + .terminal-1103912939-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-908877803-title { + .terminal-1103912939-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-908877803-r1 { fill: #c5c8c6 } -.terminal-908877803-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-908877803-r3 { fill: #68a0b3;font-weight: bold } -.terminal-908877803-r4 { fill: #98a84b } + .terminal-1103912939-r1 { fill: #c5c8c6 } +.terminal-1103912939-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-1103912939-r3 { fill: #68a0b3;font-weight: bold } +.terminal-1103912939-r4 { fill: #98a84b } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -285,88 +285,88 @@ - + - - $ 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 {pep440,semver,semver2}] -[--version-type {pep440,semver,semver2}] -[--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 {pep440,semver,semver2} -                        choose version scheme -  --version-type {pep440,semver,semver2} -                        Deprecated, use --version-scheme -  --build-metadata BUILD_METADATA -                        Add additional build-metadata to the version-number - + + $ 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 {semver2,pep440,semver}] +[--version-type {semver2,pep440,semver}] +[--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 {semver2,pep440,semver} +                        choose version scheme +  --version-type {semver2,pep440,semver} +                        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 index a7d277df44..88f12bdbfa 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -19,144 +19,144 @@ font-weight: 700; } - .terminal-37245177-matrix { + .terminal-4187574521-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-37245177-title { + .terminal-4187574521-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-37245177-r1 { fill: #c5c8c6 } -.terminal-37245177-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-37245177-r3 { fill: #68a0b3;font-weight: bold } -.terminal-37245177-r4 { fill: #98a84b } + .terminal-4187574521-r1 { fill: #c5c8c6 } +.terminal-4187574521-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-4187574521-r3 { fill: #68a0b3;font-weight: bold } +.terminal-4187574521-r4 { fill: #98a84b } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -168,49 +168,49 @@ - + - - $ 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 {semver,semver2,pep440}] -[--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 {semver,semver2,pep440} -                        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') - + + $ 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 {semver,pep440,semver2}] +[--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 {semver,pep440,semver2} +                        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') + From a9f86bedec00d068481896584ee3d4d90ec92f9b Mon Sep 17 00:00:00 2001 From: Stefanie Molin <24376333+stefmolin@users.noreply.github.com> Date: Mon, 20 May 2024 11:06:30 -0400 Subject: [PATCH 176/598] style: add py.typed file --- commitizen/py.typed | 0 pyproject.toml | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 commitizen/py.typed diff --git a/commitizen/py.typed b/commitizen/py.typed new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pyproject.toml b/pyproject.toml index beb7b87308..82d8fb197b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,10 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", ] +packages = [ + {include = "commitizen"}, + {include = "commitizen/py.typed"}, +] [tool.poetry.dependencies] python = ">=3.8" From 796a160bc4b0d07dfd26a1d200930ba93584e74c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 20 May 2024 18:27:27 +0000 Subject: [PATCH 177/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz_changelog___help.svg | 176 +++++++++---------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/docs/images/cli_help/cz_changelog___help.svg b/docs/images/cli_help/cz_changelog___help.svg index 88f12bdbfa..32d9037665 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -19,144 +19,144 @@ font-weight: 700; } - .terminal-4187574521-matrix { + .terminal-4119023865-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4187574521-title { + .terminal-4119023865-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4187574521-r1 { fill: #c5c8c6 } -.terminal-4187574521-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-4187574521-r3 { fill: #68a0b3;font-weight: bold } -.terminal-4187574521-r4 { fill: #98a84b } + .terminal-4119023865-r1 { fill: #c5c8c6 } +.terminal-4119023865-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-4119023865-r3 { fill: #68a0b3;font-weight: bold } +.terminal-4119023865-r4 { fill: #98a84b } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -168,49 +168,49 @@ - + - - $ 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 {semver,pep440,semver2}] -[--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 {semver,pep440,semver2} -                        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') - + + $ 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 {semver2,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 {semver2,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') + From bd4755fe39ee98b8c0b4e54683451ec22db05c46 Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Thu, 16 May 2024 15:37:33 -0300 Subject: [PATCH 178/598] fix(cli/commands): add description for subcommands --- commitizen/cli.py | 21 ++++- tests/commands/test_bump_command.py | 12 +++ ...shows_description_when_use_help_option.txt | 79 +++++++++++++++++++ tests/commands/test_changelog_command.py | 12 +++ ...shows_description_when_use_help_option.txt | 40 ++++++++++ tests/commands/test_check_command.py | 12 +++ ...shows_description_when_use_help_option.txt | 22 ++++++ tests/commands/test_commit_command.py | 15 +++- ...shows_description_when_use_help_option.txt | 20 +++++ tests/commands/test_example_command.py | 17 ++++ ...shows_description_when_use_help_option.txt | 6 ++ tests/commands/test_info_command.py | 17 ++++ ...shows_description_when_use_help_option.txt | 6 ++ tests/commands/test_init_command.py | 15 +++- ...shows_description_when_use_help_option.txt | 6 ++ tests/commands/test_ls_command.py | 17 ++++ ...shows_description_when_use_help_option.txt | 6 ++ tests/commands/test_schema_command.py | 17 ++++ ...shows_description_when_use_help_option.txt | 6 ++ tests/commands/test_version_command.py | 14 +++- ...shows_description_when_use_help_option.txt | 12 +++ 21 files changed, 368 insertions(+), 4 deletions(-) create mode 100644 tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_example_command.py create mode 100644 tests/commands/test_example_command/test_example_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_info_command.py create mode 100644 tests/commands/test_info_command/test_info_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_init_command/test_init_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_ls_command.py create mode 100644 tests/commands/test_ls_command/test_ls_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_schema_command.py create mode 100644 tests/commands/test_schema_command/test_schema_command_shows_description_when_use_help_option.txt create mode 100644 tests/commands/test_version_command/test_version_command_shows_description_when_use_help_option.txt diff --git a/commitizen/cli.py b/commitizen/cli.py index 8b2d008e0e..1d1ebe1f68 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -114,11 +114,13 @@ def __call__( "commands": [ { "name": ["init"], + "description": "init commitizen configuration", "help": "init commitizen configuration", "func": commands.Init, }, { "name": ["commit", "c"], + "description": "create new commit", "help": "create new commit", "func": commands.Commit, "arguments": [ @@ -164,22 +166,31 @@ def __call__( }, { "name": "ls", + "description": "show available commitizens", "help": "show available commitizens", "func": commands.ListCz, }, { "name": "example", + "description": "show commit example", "help": "show commit example", "func": commands.Example, }, { "name": "info", + "description": "show information about the cz", "help": "show information about the cz", "func": commands.Info, }, - {"name": "schema", "help": "show commit schema", "func": commands.Schema}, + { + "name": "schema", + "description": "show commit schema", + "help": "show commit schema", + "func": commands.Schema, + }, { "name": "bump", + "description": "bump semantic version based on the git log", "help": "bump semantic version based on the git log", "func": commands.Bump, "arguments": [ @@ -346,6 +357,9 @@ def __call__( }, { "name": ["changelog", "ch"], + "description": ( + "generate changelog (note that it will overwrite existing file)" + ), "help": ( "generate changelog (note that it will overwrite existing file)" ), @@ -416,6 +430,7 @@ def __call__( }, { "name": ["check"], + "description": "validates that a commit message matches the commitizen schema", "help": "validates that a commit message matches the commitizen schema", "func": commands.Check, "arguments": [ @@ -455,6 +470,10 @@ def __call__( }, { "name": ["version"], + "description": ( + "get the version of the installed commitizen or the current project" + " (default: installed commitizen)" + ), "help": ( "get the version of the installed commitizen or the current project" " (default: installed commitizen)" diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 84faf9ee82..ad7f4db64e 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1449,3 +1449,15 @@ def test_bump_changelog_contains_increment_only(mocker, tmp_commitizen_project, assert "3.0.0" in out assert "2.0.0" not in out + + +def test_bump_command_shows_description_when_use_help_option( + mocker: MockFixture, capsys, file_regression +): + testargs = ["cz", "bump", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..de76f2efcf --- /dev/null +++ b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt @@ -0,0 +1,79 @@ +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 {pep440,semver,semver2}] + [--version-type {pep440,semver,semver2}] + [--build-metadata BUILD_METADATA] + [MANUAL_VERSION] + +bump semantic version based on the git log + +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 {pep440,semver,semver2} + choose version scheme + --version-type {pep440,semver,semver2} + Deprecated, use --version-scheme + --build-metadata BUILD_METADATA + Add additional build-metadata to the version-number diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 4596724158..6f8919d71f 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -1637,3 +1637,15 @@ def test_export_changelog_template_from_plugin( assert target.exists() assert target.read_text() == tpl + + +def test_changelog_command_shows_description_when_use_help_option( + mocker: MockFixture, capsys, file_regression +): + testargs = ["cz", "changelog", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt b/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..dae438ca24 --- /dev/null +++ b/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt @@ -0,0 +1,40 @@ +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,semver2}] + [--export-template EXPORT_TEMPLATE] [--template TEMPLATE] + [--extra EXTRA] + [rev_range] + +generate changelog (note that it will overwrite existing file) + +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,semver2} + 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/tests/commands/test_check_command.py b/tests/commands/test_check_command.py index e328f8d346..bd65e75b7c 100644 --- a/tests/commands/test_check_command.py +++ b/tests/commands/test_check_command.py @@ -414,3 +414,15 @@ def test_check_conventional_commit_succeed_with_git_diff(mocker, capsys): cli.main() out, _ = capsys.readouterr() assert "Commit validation: successful!" in out + + +def test_check_command_shows_description_when_use_help_option( + mocker: MockFixture, capsys, file_regression +): + testargs = ["cz", "check", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt b/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..56e42388dc --- /dev/null +++ b/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt @@ -0,0 +1,22 @@ +usage: cz check [-h] + [--commit-msg-file COMMIT_MSG_FILE | --rev-range REV_RANGE | -m MESSAGE] + [--allow-abort] [--allowed-prefixes [ALLOWED_PREFIXES ...]] + +validates that a commit message matches the commitizen schema + +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/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 0e0a12751a..da54e7b6eb 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -1,10 +1,11 @@ import os +import sys import pytest from pytest_mock import MockFixture from unittest.mock import ANY -from commitizen import cmd, commands +from commitizen import cli, cmd, commands from commitizen.cz.exceptions import CzException from commitizen.cz.utils import get_backup_file_path from commitizen.exceptions import ( @@ -406,3 +407,15 @@ def test_commit_command_with_message_length_limit(config, mocker: MockFixture): with pytest.raises(CommitMessageLengthExceededError): commands.Commit(config, {"message_length_limit": message_length - 1})() + + +def test_commit_command_shows_description_when_use_help_option( + mocker: MockFixture, capsys, file_regression +): + testargs = ["cz", "commit", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..ebdb68446e --- /dev/null +++ b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt @@ -0,0 +1,20 @@ +usage: cz commit [-h] [--retry] [--no-retry] [--dry-run] + [--write-message-to-file FILE_PATH] [-s] [-a] + [-l MESSAGE_LENGTH_LIMIT] + +create new commit + +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. + -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT + length limit of the commit message; 0 for no limit diff --git a/tests/commands/test_example_command.py b/tests/commands/test_example_command.py new file mode 100644 index 0000000000..43fdd96f5a --- /dev/null +++ b/tests/commands/test_example_command.py @@ -0,0 +1,17 @@ +import pytest +import sys +from commitizen import cli + +from pytest_mock import MockerFixture + + +def test_example_command_shows_description_when_use_help_option( + mocker: MockerFixture, capsys, file_regression +): + testargs = ["cz", "example", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_example_command/test_example_command_shows_description_when_use_help_option.txt b/tests/commands/test_example_command/test_example_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..b9bf7f84fc --- /dev/null +++ b/tests/commands/test_example_command/test_example_command_shows_description_when_use_help_option.txt @@ -0,0 +1,6 @@ +usage: cz example [-h] + +show commit example + +options: + -h, --help show this help message and exit diff --git a/tests/commands/test_info_command.py b/tests/commands/test_info_command.py new file mode 100644 index 0000000000..4a5f0d4f73 --- /dev/null +++ b/tests/commands/test_info_command.py @@ -0,0 +1,17 @@ +import pytest +import sys +from commitizen import cli + +from pytest_mock import MockerFixture + + +def test_info_command_shows_description_when_use_help_option( + mocker: MockerFixture, capsys, file_regression +): + testargs = ["cz", "info", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_info_command/test_info_command_shows_description_when_use_help_option.txt b/tests/commands/test_info_command/test_info_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..99b1ba8a4a --- /dev/null +++ b/tests/commands/test_info_command/test_info_command_shows_description_when_use_help_option.txt @@ -0,0 +1,6 @@ +usage: cz info [-h] + +show information about the cz + +options: + -h, --help show this help message and exit diff --git a/tests/commands/test_init_command.py b/tests/commands/test_init_command.py index 1814acb135..a3f8a8d739 100644 --- a/tests/commands/test_init_command.py +++ b/tests/commands/test_init_command.py @@ -2,13 +2,14 @@ import json import os +import sys from typing import Any import pytest import yaml from pytest_mock import MockFixture -from commitizen import commands +from commitizen import cli, commands from commitizen.__version__ import __version__ from commitizen.exceptions import InitFailedError, NoAnswersError @@ -251,3 +252,15 @@ def test_pre_commit_exec_failed( with tmpdir.as_cwd(): with pytest.raises(InitFailedError): commands.Init(config)() + + +def test_init_command_shows_description_when_use_help_option( + mocker: MockFixture, capsys, file_regression +): + testargs = ["cz", "init", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_init_command/test_init_command_shows_description_when_use_help_option.txt b/tests/commands/test_init_command/test_init_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..0f72042f88 --- /dev/null +++ b/tests/commands/test_init_command/test_init_command_shows_description_when_use_help_option.txt @@ -0,0 +1,6 @@ +usage: cz init [-h] + +init commitizen configuration + +options: + -h, --help show this help message and exit diff --git a/tests/commands/test_ls_command.py b/tests/commands/test_ls_command.py new file mode 100644 index 0000000000..7fc4620e22 --- /dev/null +++ b/tests/commands/test_ls_command.py @@ -0,0 +1,17 @@ +import pytest +import sys +from commitizen import cli + +from pytest_mock import MockerFixture + + +def test_ls_command_shows_description_when_use_help_option( + mocker: MockerFixture, capsys, file_regression +): + testargs = ["cz", "ls", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_ls_command/test_ls_command_shows_description_when_use_help_option.txt b/tests/commands/test_ls_command/test_ls_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..5fa8fe1f79 --- /dev/null +++ b/tests/commands/test_ls_command/test_ls_command_shows_description_when_use_help_option.txt @@ -0,0 +1,6 @@ +usage: cz ls [-h] + +show available commitizens + +options: + -h, --help show this help message and exit diff --git a/tests/commands/test_schema_command.py b/tests/commands/test_schema_command.py new file mode 100644 index 0000000000..13e6c319bb --- /dev/null +++ b/tests/commands/test_schema_command.py @@ -0,0 +1,17 @@ +import pytest +import sys +from commitizen import cli + +from pytest_mock import MockerFixture + + +def test_schema_command_shows_description_when_use_help_option( + mocker: MockerFixture, capsys, file_regression +): + testargs = ["cz", "schema", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_schema_command/test_schema_command_shows_description_when_use_help_option.txt b/tests/commands/test_schema_command/test_schema_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..6666db4d41 --- /dev/null +++ b/tests/commands/test_schema_command/test_schema_command_shows_description_when_use_help_option.txt @@ -0,0 +1,6 @@ +usage: cz schema [-h] + +show commit schema + +options: + -h, --help show this help message and exit diff --git a/tests/commands/test_version_command.py b/tests/commands/test_version_command.py index 3f9de50d00..0a6109311c 100644 --- a/tests/commands/test_version_command.py +++ b/tests/commands/test_version_command.py @@ -4,7 +4,7 @@ import pytest from pytest_mock import MockerFixture -from commitizen import commands +from commitizen import cli, commands from commitizen.__version__ import __version__ from commitizen.config.base_config import BaseConfig @@ -106,3 +106,15 @@ def test_version_use_version_provider( get_provider.assert_called_once() mock.get_version.assert_called_once() mock.set_version.assert_not_called() + + +def test_version_command_shows_description_when_use_help_option( + mocker: MockerFixture, capsys, file_regression +): + testargs = ["cz", "version", "--help"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(SystemExit): + cli.main() + + out, _ = capsys.readouterr() + file_regression.check(out, extension=".txt") diff --git a/tests/commands/test_version_command/test_version_command_shows_description_when_use_help_option.txt b/tests/commands/test_version_command/test_version_command_shows_description_when_use_help_option.txt new file mode 100644 index 0000000000..c461b10bcd --- /dev/null +++ b/tests/commands/test_version_command/test_version_command_shows_description_when_use_help_option.txt @@ -0,0 +1,12 @@ +usage: cz version [-h] [-r | -p | -c | -v] + +get the version of the installed commitizen or the current project (default: +installed commitizen) + +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 From 4a9f971c3d1f8cf5cc8dac7db1228c1b8d30d3d3 Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Thu, 16 May 2024 15:57:09 -0300 Subject: [PATCH 179/598] refactor(tests/commands): move "other" tests for the correspondent file --- tests/commands/test_example_command.py | 8 +++++++- tests/commands/test_info_command.py | 8 +++++++- tests/commands/test_ls_command.py | 8 +++++++- tests/commands/test_other_commands.py | 27 -------------------------- tests/commands/test_schema_command.py | 8 +++++++- 5 files changed, 28 insertions(+), 31 deletions(-) delete mode 100644 tests/commands/test_other_commands.py diff --git a/tests/commands/test_example_command.py b/tests/commands/test_example_command.py index 43fdd96f5a..93d9368f58 100644 --- a/tests/commands/test_example_command.py +++ b/tests/commands/test_example_command.py @@ -1,10 +1,16 @@ import pytest import sys -from commitizen import cli +from commitizen import cli, commands from pytest_mock import MockerFixture +def test_example(config, mocker: MockerFixture): + write_mock = mocker.patch("commitizen.out.write") + commands.Example(config)() + write_mock.assert_called_once() + + def test_example_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): diff --git a/tests/commands/test_info_command.py b/tests/commands/test_info_command.py index 4a5f0d4f73..b9c8e10d3b 100644 --- a/tests/commands/test_info_command.py +++ b/tests/commands/test_info_command.py @@ -1,10 +1,16 @@ import pytest import sys -from commitizen import cli +from commitizen import cli, commands from pytest_mock import MockerFixture +def test_info(config, mocker: MockerFixture): + write_mock = mocker.patch("commitizen.out.write") + commands.Info(config)() + write_mock.assert_called_once() + + def test_info_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): diff --git a/tests/commands/test_ls_command.py b/tests/commands/test_ls_command.py index 7fc4620e22..e2a311fc76 100644 --- a/tests/commands/test_ls_command.py +++ b/tests/commands/test_ls_command.py @@ -1,10 +1,16 @@ import pytest import sys -from commitizen import cli +from commitizen import cli, commands from pytest_mock import MockerFixture +def test_list_cz(config, mocker: MockerFixture): + write_mock = mocker.patch("commitizen.out.write") + commands.ListCz(config)() + write_mock.assert_called_once() + + def test_ls_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): diff --git a/tests/commands/test_other_commands.py b/tests/commands/test_other_commands.py deleted file mode 100644 index 3f7f855d54..0000000000 --- a/tests/commands/test_other_commands.py +++ /dev/null @@ -1,27 +0,0 @@ -from pytest_mock import MockFixture - -from commitizen import commands - - -def test_example(config, mocker: MockFixture): - write_mock = mocker.patch("commitizen.out.write") - commands.Example(config)() - write_mock.assert_called_once() - - -def test_info(config, mocker: MockFixture): - write_mock = mocker.patch("commitizen.out.write") - commands.Info(config)() - write_mock.assert_called_once() - - -def test_schema(config, mocker: MockFixture): - write_mock = mocker.patch("commitizen.out.write") - commands.Schema(config)() - write_mock.assert_called_once() - - -def test_list_cz(config, mocker: MockFixture): - write_mock = mocker.patch("commitizen.out.write") - commands.ListCz(config)() - write_mock.assert_called_once() diff --git a/tests/commands/test_schema_command.py b/tests/commands/test_schema_command.py index 13e6c319bb..fd0693dcfe 100644 --- a/tests/commands/test_schema_command.py +++ b/tests/commands/test_schema_command.py @@ -1,10 +1,16 @@ import pytest import sys -from commitizen import cli +from commitizen import cli, commands from pytest_mock import MockerFixture +def test_schema(config, mocker: MockerFixture): + write_mock = mocker.patch("commitizen.out.write") + commands.Schema(config)() + write_mock.assert_called_once() + + def test_schema_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): From 4636e50978d849e2fc971de536ba25f40de7267f Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Mon, 20 May 2024 15:09:18 -0300 Subject: [PATCH 180/598] refactor(KNOWN_SCHEMES): replace set comprehension for list comprehension Set is an unordered structure, so every call the order changes. Because the unordered behavior we can't use `file_regression` to test the command output. --- commitizen/version_schemes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 596aa94b2e..26a19ec1b1 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -401,7 +401,7 @@ def __str__(self) -> str: SCHEMES_ENTRYPOINT = "commitizen.scheme" """Schemes entrypoints group""" -KNOWN_SCHEMES = {ep.name for ep in metadata.entry_points(group=SCHEMES_ENTRYPOINT)} +KNOWN_SCHEMES = [ep.name for ep in metadata.entry_points(group=SCHEMES_ENTRYPOINT)] """All known registered version schemes""" From 8f4dbe949af10798fbfd8ba42b4f8c6ae8ce99f0 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Mon, 20 May 2024 15:42:50 -0400 Subject: [PATCH 181/598] test(commands): add skip_if_below_py_3_10 as the message of argument changes in python 3.10 Optional arguments -> options --- tests/commands/test_bump_command.py | 3 ++- tests/commands/test_changelog_command.py | 2 ++ tests/commands/test_check_command.py | 3 ++- tests/commands/test_commit_command.py | 3 +++ tests/commands/test_example_command.py | 3 +++ tests/commands/test_info_command.py | 2 ++ tests/commands/test_init_command.py | 3 +++ tests/commands/test_ls_command.py | 3 +++ tests/commands/test_schema_command.py | 3 +++ tests/commands/test_version_command.py | 2 ++ tests/utils.py | 9 +++++++++ 11 files changed, 34 insertions(+), 2 deletions(-) diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index ad7f4db64e..b20f75169a 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -29,7 +29,7 @@ NoVersionSpecifiedError, ) from commitizen.changelog_formats import ChangelogFormat -from tests.utils import create_file_and_commit, create_tag +from tests.utils import create_file_and_commit, create_tag, skip_below_py_3_10 @pytest.mark.parametrize( @@ -1451,6 +1451,7 @@ def test_bump_changelog_contains_increment_only(mocker, tmp_commitizen_project, assert "2.0.0" not in out +@skip_below_py_3_10 def test_bump_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 6f8919d71f..67f10a8ac0 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -31,6 +31,7 @@ merge_branch, switch_branch, wait_for_tag, + skip_below_py_3_10, ) @@ -1639,6 +1640,7 @@ def test_export_changelog_template_from_plugin( assert target.read_text() == tpl +@skip_below_py_3_10 def test_changelog_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_check_command.py b/tests/commands/test_check_command.py index bd65e75b7c..47bdafd651 100644 --- a/tests/commands/test_check_command.py +++ b/tests/commands/test_check_command.py @@ -12,7 +12,7 @@ InvalidCommitMessageError, NoCommitsFoundError, ) -from tests.utils import create_file_and_commit +from tests.utils import create_file_and_commit, skip_below_py_3_10 COMMIT_LOG = [ "refactor: A code change that neither fixes a bug nor adds a feature", @@ -416,6 +416,7 @@ def test_check_conventional_commit_succeed_with_git_diff(mocker, capsys): assert "Commit validation: successful!" in out +@skip_below_py_3_10 def test_check_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index da54e7b6eb..2085278757 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -20,6 +20,8 @@ NothingToCommitError, ) +from tests.utils import skip_below_py_3_10 + @pytest.fixture def staging_is_clean(mocker: MockFixture, tmp_git_project): @@ -409,6 +411,7 @@ def test_commit_command_with_message_length_limit(config, mocker: MockFixture): commands.Commit(config, {"message_length_limit": message_length - 1})() +@skip_below_py_3_10 def test_commit_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_example_command.py b/tests/commands/test_example_command.py index 93d9368f58..e0c2141453 100644 --- a/tests/commands/test_example_command.py +++ b/tests/commands/test_example_command.py @@ -4,6 +4,8 @@ from pytest_mock import MockerFixture +from tests.utils import skip_below_py_3_10 + def test_example(config, mocker: MockerFixture): write_mock = mocker.patch("commitizen.out.write") @@ -11,6 +13,7 @@ def test_example(config, mocker: MockerFixture): write_mock.assert_called_once() +@skip_below_py_3_10 def test_example_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): diff --git a/tests/commands/test_info_command.py b/tests/commands/test_info_command.py index b9c8e10d3b..6221630acc 100644 --- a/tests/commands/test_info_command.py +++ b/tests/commands/test_info_command.py @@ -3,6 +3,7 @@ from commitizen import cli, commands from pytest_mock import MockerFixture +from tests.utils import skip_below_py_3_10 def test_info(config, mocker: MockerFixture): @@ -11,6 +12,7 @@ def test_info(config, mocker: MockerFixture): write_mock.assert_called_once() +@skip_below_py_3_10 def test_info_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): diff --git a/tests/commands/test_init_command.py b/tests/commands/test_init_command.py index a3f8a8d739..a263e73a8e 100644 --- a/tests/commands/test_init_command.py +++ b/tests/commands/test_init_command.py @@ -13,6 +13,8 @@ from commitizen.__version__ import __version__ from commitizen.exceptions import InitFailedError, NoAnswersError +from tests.utils import skip_below_py_3_10 + class FakeQuestion: def __init__(self, expected_return): @@ -254,6 +256,7 @@ def test_pre_commit_exec_failed( commands.Init(config)() +@skip_below_py_3_10 def test_init_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_ls_command.py b/tests/commands/test_ls_command.py index e2a311fc76..d783305fc0 100644 --- a/tests/commands/test_ls_command.py +++ b/tests/commands/test_ls_command.py @@ -4,6 +4,8 @@ from pytest_mock import MockerFixture +from tests.utils import skip_below_py_3_10 + def test_list_cz(config, mocker: MockerFixture): write_mock = mocker.patch("commitizen.out.write") @@ -11,6 +13,7 @@ def test_list_cz(config, mocker: MockerFixture): write_mock.assert_called_once() +@skip_below_py_3_10 def test_ls_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): diff --git a/tests/commands/test_schema_command.py b/tests/commands/test_schema_command.py index fd0693dcfe..f69638dba3 100644 --- a/tests/commands/test_schema_command.py +++ b/tests/commands/test_schema_command.py @@ -4,6 +4,8 @@ from pytest_mock import MockerFixture +from tests.utils import skip_below_py_3_10 + def test_schema(config, mocker: MockerFixture): write_mock = mocker.patch("commitizen.out.write") @@ -11,6 +13,7 @@ def test_schema(config, mocker: MockerFixture): write_mock.assert_called_once() +@skip_below_py_3_10 def test_schema_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): diff --git a/tests/commands/test_version_command.py b/tests/commands/test_version_command.py index 0a6109311c..f7d38c202d 100644 --- a/tests/commands/test_version_command.py +++ b/tests/commands/test_version_command.py @@ -7,6 +7,7 @@ from commitizen import cli, commands from commitizen.__version__ import __version__ from commitizen.config.base_config import BaseConfig +from tests.utils import skip_below_py_3_10 def test_version_for_showing_project_version(config, capsys): @@ -108,6 +109,7 @@ def test_version_use_version_provider( mock.set_version.assert_not_called() +@skip_below_py_3_10 def test_version_command_shows_description_when_use_help_option( mocker: MockerFixture, capsys, file_regression ): diff --git a/tests/utils.py b/tests/utils.py index 08d4414ba3..39fb0a17fa 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -2,12 +2,21 @@ import time import uuid +import sys from pathlib import Path + +import pytest from deprecated import deprecated from commitizen import cmd, exceptions, git +skip_below_py_3_10 = pytest.mark.skipif( + sys.version_info < (3, 10), + reason="The output meesage of argparse is different between Python 3.10 and lower than Python 3.10", +) + + class FakeCommand: def __init__(self, out=None, err=None, return_code=0): self.out = out From ae73429f38be340652319a0130f8b1d6aac29d4c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 22 May 2024 02:58:25 +0000 Subject: [PATCH 182/598] =?UTF-8?q?bump:=20version=203.26.0=20=E2=86=92=20?= =?UTF-8?q?3.26.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 11 +++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 163e7a0ab3..f80bf93bb9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,7 @@ repos: exclude: "poetry.lock" - repo: https://github.com/commitizen-tools/commitizen - rev: v3.26.0 # automatically updated by Commitizen + rev: v3.26.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index e99491f1cf..b851d3ab12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## v3.26.1 (2024-05-22) + +### Fix + +- **cli/commands**: add description for subcommands + +### Refactor + +- **KNOWN_SCHEMES**: replace set comprehension for list comprehension +- **tests/commands**: move "other" tests for the correspondent file + ## v3.26.0 (2024-05-18) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 1e6bdc4260..2fb3eb449b 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.26.0" +__version__ = "3.26.1" diff --git a/pyproject.toml b/pyproject.toml index 82d8fb197b..20d08b020f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.26.0" +version = "3.26.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.26.0" +version = "3.26.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From c18c6a63434efc85fa4f82b0abc25063ce361cdb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 22 May 2024 02:58:59 +0000 Subject: [PATCH 183/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz_bump___help.svg | 346 ++++++++++--------- docs/images/cli_help/cz_changelog___help.svg | 190 +++++----- docs/images/cli_help/cz_check___help.svg | 122 ++++--- docs/images/cli_help/cz_commit___help.svg | 108 +++--- docs/images/cli_help/cz_example___help.svg | 50 +-- docs/images/cli_help/cz_info___help.svg | 50 +-- docs/images/cli_help/cz_init___help.svg | 50 +-- docs/images/cli_help/cz_ls___help.svg | 50 +-- docs/images/cli_help/cz_schema___help.svg | 50 +-- docs/images/cli_help/cz_version___help.svg | 74 ++-- 10 files changed, 587 insertions(+), 503 deletions(-) diff --git a/docs/images/cli_help/cz_bump___help.svg b/docs/images/cli_help/cz_bump___help.svg index 6d217d3958..96db25a964 100644 --- a/docs/images/cli_help/cz_bump___help.svg +++ b/docs/images/cli_help/cz_bump___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + - + - + - - $ 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 {semver2,pep440,semver}] -[--version-type {semver2,pep440,semver}] -[--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 {semver2,pep440,semver} -                        choose version scheme -  --version-type {semver2,pep440,semver} -                        Deprecated, use --version-scheme -  --build-metadata BUILD_METADATA -                        Add additional build-metadata to the version-number - + + $ 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 {pep440,semver,semver2}] +[--version-type {pep440,semver,semver2}] +[--build-metadata BUILD_METADATA] +[MANUAL_VERSION] + +bump semantic version based on the git log + +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 {pep440,semver,semver2} +                        choose version scheme +  --version-type {pep440,semver,semver2} +                        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 index 32d9037665..8cb3fcf2fe 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + - + - + - - $ 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 {semver2,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 {semver2,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') - + + $ 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,semver2}] +[--export-template EXPORT_TEMPLATE][--template TEMPLATE] +[--extra EXTRA] + + +generate changelog (note that it will overwrite existing file) + +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,semver2} +                        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 index 427d91e414..df1af46637 100644 --- a/docs/images/cli_help/cz_check___help.svg +++ b/docs/images/cli_help/cz_check___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + - + - + - - $ 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 - + + $ 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 ...]] + +validates that a commit message matches the commitizen schema + +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 index deb871fce9..1b7c98953c 100644 --- a/docs/images/cli_help/cz_commit___help.svg +++ b/docs/images/cli_help/cz_commit___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + - + - + - - $ cz commit --help -usage: cz commit [-h][--retry][--no-retry][--dry-run] -[--write-message-to-file FILE_PATH][-s][-a] -[-l MESSAGE_LENGTH_LIMIT] - -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. -  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit - + + $ cz commit --help +usage: cz commit [-h][--retry][--no-retry][--dry-run] +[--write-message-to-file FILE_PATH][-s][-a] +[-l MESSAGE_LENGTH_LIMIT] + +create new commit + +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. +  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit + diff --git a/docs/images/cli_help/cz_example___help.svg b/docs/images/cli_help/cz_example___help.svg index e142dd4f9b..9fe4fd659a 100644 --- a/docs/images/cli_help/cz_example___help.svg +++ b/docs/images/cli_help/cz_example___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + + + + + + + - + - + - - $ cz example --help -usage: cz example [-h] - -options: -  -h, --help  show this help message and exit - + + $ cz example --help +usage: cz example [-h] + +show commit example + +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 index 8059ec466c..b8827e34c2 100644 --- a/docs/images/cli_help/cz_info___help.svg +++ b/docs/images/cli_help/cz_info___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + + + + + + + - + - + - - $ cz info --help -usage: cz info [-h] - -options: -  -h, --help  show this help message and exit - + + $ cz info --help +usage: cz info [-h] + +show information about the cz + +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 index 6bcd577160..41a950ebdb 100644 --- a/docs/images/cli_help/cz_init___help.svg +++ b/docs/images/cli_help/cz_init___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + + + + + + + - + - + - - $ cz init --help -usage: cz init [-h] - -options: -  -h, --help  show this help message and exit - + + $ cz init --help +usage: cz init [-h] + +init commitizen configuration + +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 index 390f5bbb42..3ec3532ef1 100644 --- a/docs/images/cli_help/cz_ls___help.svg +++ b/docs/images/cli_help/cz_ls___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + + + + + + + - + - + - - $ cz ls --help -usage: cz ls [-h] - -options: -  -h, --help  show this help message and exit - + + $ cz ls --help +usage: cz ls [-h] + +show available commitizens + +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 index 443634428d..afe8982e9a 100644 --- a/docs/images/cli_help/cz_schema___help.svg +++ b/docs/images/cli_help/cz_schema___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + + + + + + + - + - + - - $ cz schema --help -usage: cz schema [-h] - -options: -  -h, --help  show this help message and exit - + + $ cz schema --help +usage: cz schema [-h] + +show commit schema + +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 index 0d14aaffa1..c7777db4df 100644 --- a/docs/images/cli_help/cz_version___help.svg +++ b/docs/images/cli_help/cz_version___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + - + - + - - $ 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 - + + $ cz version --help +usage: cz version [-h][-r | -p | -c | -v] + +get the version of the installed commitizen or the current project (default: +installed commitizen) + +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 + From ee14038b3647ea160f16065d39dc80a6c1206e5b Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Tue, 21 May 2024 14:15:42 -0400 Subject: [PATCH 184/598] docs: fix a few typos in CHANGELOG.md and .pre-commit-hooks.yaml Signed-off-by: Yaroslav Halchenko --- .pre-commit-hooks.yaml | 2 +- CHANGELOG.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 619e58622b..2a3a088484 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,7 +1,7 @@ - id: commitizen name: commitizen check description: > - Check whether the current commit message follows commiting rules. Allow + Check whether the current commit message follows committing rules. Allow empty commit messages by default, because they typically indicate to Git that the commit should be aborted. entry: cz check diff --git a/CHANGELOG.md b/CHANGELOG.md index b851d3ab12..15bb75490f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -784,7 +784,7 @@ ### Fix -- **check**: filter out comment messege when checking +- **check**: filter out comment message when checking ## v2.20.2 (2021-12-14) @@ -1035,7 +1035,7 @@ ### Fix -- prevent prerelase from creating a bump when there are no commits +- prevent prerelease from creating a bump when there are no commits ## v2.8.0 (2020-11-15) @@ -1522,7 +1522,7 @@ - new config system where each config type has its own class - **config**: add type annotation to config property -- **config**: fix wrongly type annoated functions +- **config**: fix wrongly type annotated functions - **config/ini_config**: move deprecation warning into class initialization - **config**: use add_path instead of directly assigning _path - **all**: replace all the _settings invoke with settings.update From 3761124d5d2b2434625d66466ef676cfa765909e Mon Sep 17 00:00:00 2001 From: Tim Tsai Date: Tue, 21 May 2024 10:41:54 -0400 Subject: [PATCH 185/598] fix(base.py): add encoding when open changlelog_file #1110 --- commitizen/changelog_formats/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commitizen/changelog_formats/base.py b/commitizen/changelog_formats/base.py index d0dfd9ec55..7c802d63d4 100644 --- a/commitizen/changelog_formats/base.py +++ b/commitizen/changelog_formats/base.py @@ -24,6 +24,7 @@ def __init__(self, config: BaseConfig): # Constructor needs to be redefined because `Protocol` prevent instantiation by default # See: https://bugs.python.org/issue44807 self.config = config + self.encoding = self.config.settings["encoding"] @property def version_parser(self) -> Pattern: @@ -33,7 +34,7 @@ def get_metadata(self, filepath: str) -> Metadata: if not os.path.isfile(filepath): return Metadata() - with open(filepath) as changelog_file: + with open(filepath, encoding=self.encoding) as changelog_file: return self.get_metadata_from_file(changelog_file) def get_metadata_from_file(self, file: IO[Any]) -> Metadata: From 642fe8c9cced6896d2f8d7af9b1a3a3adedd162d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 22 May 2024 03:02:21 +0000 Subject: [PATCH 186/598] =?UTF-8?q?bump:=20version=203.26.1=20=E2=86=92=20?= =?UTF-8?q?3.26.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f80bf93bb9..3017978009 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,7 @@ repos: exclude: "poetry.lock" - repo: https://github.com/commitizen-tools/commitizen - rev: v3.26.1 # automatically updated by Commitizen + rev: v3.26.2 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 15bb75490f..b73d8c09e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.26.2 (2024-05-22) + +### Fix + +- **base.py**: add encoding when open changlelog_file + ## v3.26.1 (2024-05-22) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 2fb3eb449b..b09545868b 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.26.1" +__version__ = "3.26.2" diff --git a/pyproject.toml b/pyproject.toml index 20d08b020f..22eece6bce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.26.1" +version = "3.26.2" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.26.1" +version = "3.26.2" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 4bf8ca65a2c6f5c4a6a09a86f9c76babed4a5ff3 Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Mon, 20 May 2024 18:34:43 -0300 Subject: [PATCH 187/598] feat(config_files): add suport for "cz.toml" config file --- commitizen/defaults.py | 1 + docs/commands/bump.md | 4 ++-- docs/config.md | 6 +++--- docs/faq.md | 2 +- docs/getting_started.md | 2 +- tests/test_conf.py | 27 ++++++++++++++++++++------- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index a1651ebe88..75162619de 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -67,6 +67,7 @@ class Settings(TypedDict, total=False): "cz.json", ".cz.yaml", "cz.yaml", + "cz.toml", ] encoding: str = "utf-8" diff --git a/docs/commands/bump.md b/docs/commands/bump.md index 5f5590e885..4d370a6a1f 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -408,7 +408,7 @@ regarding if the file is present or not in `version_files`. Some examples -`pyproject.toml` or `.cz.toml` +`pyproject.toml`, `.cz.toml` or `cz.toml` ```toml [tool.commitizen] @@ -441,7 +441,7 @@ defaults to: `bump: version $current_version → $new_version` Some examples -`pyproject.toml` or `.cz.toml` +`pyproject.toml`, `.cz.toml` or `cz.toml` ```toml [tool.commitizen] diff --git a/docs/config.md b/docs/config.md index 398c045339..210b5d7ff8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -227,11 +227,11 @@ Provide extra variables to the changelog template. [Read more][template-customiz ## Configuration file -### pyproject.toml or .cz.toml +### pyproject.toml, .cz.toml or cz.toml Default and recommended configuration format for a project. For a **python** project, we recommend adding an entry to your `pyproject.toml`. -You can also create a `.cz.toml` file at the root of your project folder. +You can also create a `.cz.toml` or `cz.toml` file at the root of your project folder. Example configuration: @@ -339,7 +339,7 @@ Commitizen provides some version providers for some well known formats: !!! note The `scm` provider is meant to be used with `setuptools-scm` or any packager `*-scm` plugin. -An example in your `.cz.toml` would look like this: +An example in your `.cz.toml` or `cz.toml` would look like this: ```toml [tool.commitizen] diff --git a/docs/faq.md b/docs/faq.md index 060de78c30..4bcb2bc7cf 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -57,7 +57,7 @@ They differ a bit in design, not sure if cz-js does any of this, but these are s - create custom rules, version bumps and changelog generation, by default we use the popular conventional commits (I think cz-js allows this). - single package, install one thing and it will work (cz-js is a monorepo, but you have to install different dependencies AFAIK) - pre-commit integration -- works on any language project, as long as you create the `.cz.toml` file. +- works on any language project, as long as you create the `.cz.toml` or `cz.toml` file. Where do they cross paths? diff --git a/docs/getting_started.md b/docs/getting_started.md index 7ceba2bb65..81da513e0b 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -8,7 +8,7 @@ The assistant utility will help you set up everything cz init ``` -Alternatively, create a file `.cz.toml` in your project's directory. +Alternatively, create a file `.cz.toml` or `cz.toml` in your project's directory. ```toml [tool.commitizen] diff --git a/tests/test_conf.py b/tests/test_conf.py index 786f12b36b..2a5e727d8d 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -214,19 +214,30 @@ def test_load_empty_pyproject_toml_from_config_argument(_, tmpdir): config.read_cfg(filepath="./not_in_root/pyproject.toml") +@pytest.mark.parametrize( + "config_file, exception_string", + [ + (".cz.toml", r"\.cz\.toml"), + ("cz.toml", r"cz\.toml"), + ("pyproject.toml", r"pyproject\.toml"), + ], + ids=[".cz.toml", "cz.toml", "pyproject.toml"], +) class TestTomlConfig: - def test_init_empty_config_content(self, tmpdir): - path = tmpdir.mkdir("commitizen").join(".cz.toml") + def test_init_empty_config_content(self, tmpdir, config_file, exception_string): + path = tmpdir.mkdir("commitizen").join(config_file) toml_config = config.TomlConfig(data="", path=path) toml_config.init_empty_config_content() with open(path, encoding="utf-8") as toml_file: assert toml_file.read() == "[tool.commitizen]\n" - def test_init_empty_config_content_with_existing_content(self, tmpdir): + def test_init_empty_config_content_with_existing_content( + self, tmpdir, config_file, exception_string + ): existing_content = "[tool.black]\n" "line-length = 88\n" - path = tmpdir.mkdir("commitizen").join(".cz.toml") + path = tmpdir.mkdir("commitizen").join(config_file) path.write(existing_content) toml_config = config.TomlConfig(data="", path=path) toml_config.init_empty_config_content() @@ -234,11 +245,13 @@ def test_init_empty_config_content_with_existing_content(self, tmpdir): with open(path, encoding="utf-8") as toml_file: assert toml_file.read() == existing_content + "\n[tool.commitizen]\n" - def test_init_with_invalid_config_content(self, tmpdir): + def test_init_with_invalid_config_content( + self, tmpdir, config_file, exception_string + ): existing_content = "invalid toml content" - path = tmpdir.mkdir("commitizen").join(".cz.toml") + path = tmpdir.mkdir("commitizen").join(config_file) - with pytest.raises(InvalidConfigurationError, match=r"\.cz\.toml"): + with pytest.raises(InvalidConfigurationError, match=exception_string): config.TomlConfig(data=existing_content, path=path) From 912fda84908a851425eb80b580b2aa35ae252158 Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Tue, 21 May 2024 10:43:04 -0300 Subject: [PATCH 188/598] test: extend tests for 'TestJsonConfig' and 'TestYamlConfig' --- tests/test_conf.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/tests/test_conf.py b/tests/test_conf.py index 2a5e727d8d..ac49362979 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -255,35 +255,53 @@ def test_init_with_invalid_config_content( config.TomlConfig(data=existing_content, path=path) +@pytest.mark.parametrize( + "config_file, exception_string", + [ + (".cz.json", r"\.cz\.json"), + ("cz.json", r"cz\.json"), + ], + ids=[".cz.json", "cz.json"], +) class TestJsonConfig: - def test_init_empty_config_content(self, tmpdir): - path = tmpdir.mkdir("commitizen").join(".cz.json") + def test_init_empty_config_content(self, tmpdir, config_file, exception_string): + path = tmpdir.mkdir("commitizen").join(config_file) json_config = config.JsonConfig(data="{}", path=path) json_config.init_empty_config_content() with open(path, encoding="utf-8") as json_file: assert json.load(json_file) == {"commitizen": {}} - def test_init_with_invalid_config_content(self, tmpdir): + def test_init_with_invalid_config_content( + self, tmpdir, config_file, exception_string + ): existing_content = "invalid json content" - path = tmpdir.mkdir("commitizen").join(".cz.json") + path = tmpdir.mkdir("commitizen").join(config_file) - with pytest.raises(InvalidConfigurationError, match=r"\.cz\.json"): + with pytest.raises(InvalidConfigurationError, match=exception_string): config.JsonConfig(data=existing_content, path=path) +@pytest.mark.parametrize( + "config_file, exception_string", + [ + (".cz.yaml", r"\.cz\.yaml"), + ("cz.yaml", r"cz\.yaml"), + ], + ids=[".cz.yaml", "cz.yaml"], +) class TestYamlConfig: - def test_init_empty_config_content(self, tmpdir): - path = tmpdir.mkdir("commitizen").join(".cz.yaml") + def test_init_empty_config_content(self, tmpdir, config_file, exception_string): + path = tmpdir.mkdir("commitizen").join(config_file) yaml_config = config.YAMLConfig(data="{}", path=path) yaml_config.init_empty_config_content() with open(path) as yaml_file: assert yaml.safe_load(yaml_file) == {"commitizen": {}} - def test_init_with_invalid_content(self, tmpdir): + def test_init_with_invalid_content(self, tmpdir, config_file, exception_string): existing_content = "invalid: .cz.yaml: content: maybe?" - path = tmpdir.mkdir("commitizen").join(".cz.yaml") + path = tmpdir.mkdir("commitizen").join(config_file) - with pytest.raises(InvalidConfigurationError, match=r"\.cz\.yaml"): + with pytest.raises(InvalidConfigurationError, match=exception_string): config.YAMLConfig(data=existing_content, path=path) From e9aa5d979ea6fd14dcf59c6bd3836bef17d386c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 22 May 2024 03:06:04 +0000 Subject: [PATCH 189/598] =?UTF-8?q?bump:=20version=203.26.2=20=E2=86=92=20?= =?UTF-8?q?3.27.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3017978009..350a7a95b2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,7 @@ repos: exclude: "poetry.lock" - repo: https://github.com/commitizen-tools/commitizen - rev: v3.26.2 # automatically updated by Commitizen + rev: v3.27.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index b73d8c09e6..496d9f5fba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.27.0 (2024-05-22) + +### Feat + +- **config_files**: add suport for "cz.toml" config file + ## v3.26.2 (2024-05-22) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index b09545868b..62bfee6c53 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.26.2" +__version__ = "3.27.0" diff --git a/pyproject.toml b/pyproject.toml index 22eece6bce..523f271c77 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.26.2" +version = "3.27.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.26.2" +version = "3.27.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From f8e37a0769e50c68b6a6380c847baea99a68e9d0 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Mon, 20 May 2024 15:57:55 -0400 Subject: [PATCH 190/598] build: add I into ruff lint and add "ruff check --fix" to format script to enable import sorting --- pyproject.toml | 11 ++++++++++- scripts/format | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 523f271c77..29f1eeddef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -149,7 +149,16 @@ addopts = "--strict-markers" line-length = 88 [tool.ruff.lint] -select = ["E", "F", "UP"] +select = [ + # pycodestyle + "E", + # Pyflakes + "F", + # pyupgrade + "UP", + # isort + "I", +] ignore = [ "E501", "D1", diff --git a/scripts/format b/scripts/format index e1282f598d..2aafc4f6e2 100755 --- a/scripts/format +++ b/scripts/format @@ -5,5 +5,7 @@ export PREFIX="poetry run python -m " set -x +# This is needed for running import sorting +${PREFIX}ruff check --fix commitizen tests ${PREFIX}ruff format commitizen tests ${PREFIX}black commitizen tests From 5a0053c83a8c56d0be3b17a5a6a71ca7552ed64f Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Mon, 20 May 2024 15:58:24 -0400 Subject: [PATCH 191/598] style: sort import --- commitizen/changelog_formats/__init__.py | 3 +-- commitizen/changelog_formats/restructuredtext.py | 2 +- commitizen/commands/bump.py | 4 ++-- commitizen/commands/changelog.py | 7 +++---- commitizen/commands/commit.py | 1 - commitizen/commands/init.py | 1 + commitizen/config/__init__.py | 2 +- commitizen/config/json_config.py | 2 +- commitizen/config/toml_config.py | 1 + commitizen/config/yaml_config.py | 2 +- commitizen/cz/utils.py | 4 ++-- commitizen/defaults.py | 4 +--- commitizen/providers/__init__.py | 1 - commitizen/providers/cargo_provider.py | 1 - commitizen/providers/commitizen_provider.py | 1 - commitizen/providers/composer_provider.py | 1 - commitizen/providers/npm_provider.py | 1 - commitizen/providers/pep621_provider.py | 1 - commitizen/providers/poetry_provider.py | 1 - commitizen/providers/scm_provider.py | 6 ++---- tests/commands/test_bump_command.py | 2 +- tests/commands/test_changelog_command.py | 4 ++-- tests/commands/test_commit_command.py | 3 +-- tests/commands/test_example_command.py | 4 ++-- tests/commands/test_info_command.py | 5 +++-- tests/commands/test_init_command.py | 1 - tests/commands/test_ls_command.py | 4 ++-- tests/commands/test_schema_command.py | 4 ++-- tests/conftest.py | 6 +++--- tests/providers/test_base_provider.py | 1 - tests/providers/test_cargo_provider.py | 1 - tests/providers/test_commitizen_provider.py | 2 -- tests/providers/test_composer_provider.py | 1 - tests/providers/test_npm_provider.py | 1 - tests/providers/test_pep621_provider.py | 1 - tests/providers/test_poetry_provider.py | 1 - tests/providers/test_scm_provider.py | 1 - tests/test_changelog.py | 3 +-- tests/test_changelog_format_asciidoc.py | 3 +-- tests/test_changelog_format_markdown.py | 3 +-- tests/test_changelog_format_restructuredtext.py | 2 +- tests/test_changelog_format_textile.py | 3 +-- tests/test_changelog_formats.py | 3 ++- tests/test_cli.py | 4 ++-- tests/test_conf.py | 2 +- tests/test_git.py | 4 ++-- tests/test_version_schemes.py | 2 +- tests/utils.py | 3 +-- 48 files changed, 47 insertions(+), 73 deletions(-) diff --git a/commitizen/changelog_formats/__init__.py b/commitizen/changelog_formats/__init__.py index 85df4b5144..b91579ee71 100644 --- a/commitizen/changelog_formats/__init__.py +++ b/commitizen/changelog_formats/__init__.py @@ -5,9 +5,8 @@ import importlib_metadata as metadata from commitizen.changelog import Metadata -from commitizen.exceptions import ChangelogFormatUnknown from commitizen.config.base_config import BaseConfig - +from commitizen.exceptions import ChangelogFormatUnknown CHANGELOG_FORMAT_ENTRYPOINT = "commitizen.changelog_format" TEMPLATE_EXTENSION = "j2" diff --git a/commitizen/changelog_formats/restructuredtext.py b/commitizen/changelog_formats/restructuredtext.py index a252fe1514..37acf81ef3 100644 --- a/commitizen/changelog_formats/restructuredtext.py +++ b/commitizen/changelog_formats/restructuredtext.py @@ -3,7 +3,7 @@ import re import sys from itertools import zip_longest -from typing import IO, TYPE_CHECKING, Any, Union, Tuple +from typing import IO, TYPE_CHECKING, Any, Tuple, Union from commitizen.changelog import Metadata diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 554e3c800b..8497384665 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -6,6 +6,7 @@ import questionary from commitizen import bump, factory, git, hooks, out +from commitizen.changelog_formats import get_changelog_format from commitizen.commands.changelog import Changelog from commitizen.config import BaseConfig from commitizen.exceptions import ( @@ -21,13 +22,12 @@ NotAllowed, NoVersionSpecifiedError, ) -from commitizen.changelog_formats import get_changelog_format from commitizen.providers import get_provider from commitizen.version_schemes import ( - get_version_scheme, Increment, InvalidVersion, Prerelease, + get_version_scheme, ) logger = getLogger("commitizen") diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index f1b69598f1..bda7a1844f 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -7,9 +7,10 @@ from typing import Callable, cast from commitizen import bump, changelog, defaults, factory, git, out - +from commitizen.changelog_formats import get_changelog_format from commitizen.config import BaseConfig -from commitizen.cz.base import MessageBuilderHook, ChangelogReleaseHook +from commitizen.cz.base import ChangelogReleaseHook, MessageBuilderHook +from commitizen.cz.utils import strip_local_version from commitizen.exceptions import ( DryRunExit, NoCommitsFoundError, @@ -18,10 +19,8 @@ NotAGitProjectError, NotAllowed, ) -from commitizen.changelog_formats import get_changelog_format from commitizen.git import GitTag, smart_open from commitizen.version_schemes import get_version_scheme -from commitizen.cz.utils import strip_local_version class Changelog: diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index df28b2a5dd..0816b2e508 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -3,7 +3,6 @@ import contextlib import os - import questionary from commitizen import factory, git, out diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 9775ec7fc8..ffc5e3eb3b 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -6,6 +6,7 @@ import questionary import yaml + from commitizen import cmd, factory, out from commitizen.__version__ import __version__ from commitizen.config import BaseConfig, JsonConfig, TomlConfig, YAMLConfig diff --git a/commitizen/config/__init__.py b/commitizen/config/__init__.py index a9395fca7d..f3720bb1b3 100644 --- a/commitizen/config/__init__.py +++ b/commitizen/config/__init__.py @@ -3,7 +3,7 @@ from pathlib import Path from commitizen import defaults, git -from commitizen.exceptions import ConfigFileNotFound, ConfigFileIsEmpty +from commitizen.exceptions import ConfigFileIsEmpty, ConfigFileNotFound from .base_config import BaseConfig from .json_config import JsonConfig diff --git a/commitizen/config/json_config.py b/commitizen/config/json_config.py index cf554922d6..b6a07f4ced 100644 --- a/commitizen/config/json_config.py +++ b/commitizen/config/json_config.py @@ -2,8 +2,8 @@ import json from pathlib import Path -from commitizen.exceptions import InvalidConfigurationError +from commitizen.exceptions import InvalidConfigurationError from commitizen.git import smart_open from .base_config import BaseConfig diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index d45860d650..813389cbcf 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -6,6 +6,7 @@ from tomlkit import exceptions, parse, table from commitizen.exceptions import InvalidConfigurationError + from .base_config import BaseConfig diff --git a/commitizen/config/yaml_config.py b/commitizen/config/yaml_config.py index 396e2eba11..2bb6fe3af8 100644 --- a/commitizen/config/yaml_config.py +++ b/commitizen/config/yaml_config.py @@ -4,8 +4,8 @@ import yaml -from commitizen.git import smart_open from commitizen.exceptions import InvalidConfigurationError +from commitizen.git import smart_open from .base_config import BaseConfig diff --git a/commitizen/cz/utils.py b/commitizen/cz/utils.py index 4df2edf39c..7bc89673c6 100644 --- a/commitizen/cz/utils.py +++ b/commitizen/cz/utils.py @@ -1,9 +1,9 @@ -import re import os +import re import tempfile -from commitizen.cz import exceptions from commitizen import git +from commitizen.cz import exceptions def required_validator(answer, msg=None): diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 75162619de..e4363f4ab0 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -2,9 +2,7 @@ import pathlib from collections import OrderedDict -from typing import Any, Iterable, MutableMapping - -from typing import TypedDict +from typing import Any, Iterable, MutableMapping, TypedDict # Type Questions = Iterable[MutableMapping[str, Any]] diff --git a/commitizen/providers/__init__.py b/commitizen/providers/__init__.py index 51302d2b37..a177b29961 100644 --- a/commitizen/providers/__init__.py +++ b/commitizen/providers/__init__.py @@ -6,7 +6,6 @@ from commitizen.config.base_config import BaseConfig from commitizen.exceptions import VersionProviderUnknown - from commitizen.providers.base_provider import VersionProvider from commitizen.providers.cargo_provider import CargoProvider from commitizen.providers.commitizen_provider import CommitizenProvider diff --git a/commitizen/providers/cargo_provider.py b/commitizen/providers/cargo_provider.py index f64c003edd..cee687c15b 100644 --- a/commitizen/providers/cargo_provider.py +++ b/commitizen/providers/cargo_provider.py @@ -2,7 +2,6 @@ import tomlkit - from commitizen.providers.base_provider import TomlProvider diff --git a/commitizen/providers/commitizen_provider.py b/commitizen/providers/commitizen_provider.py index fd0cdb3ebf..a1da25ff72 100644 --- a/commitizen/providers/commitizen_provider.py +++ b/commitizen/providers/commitizen_provider.py @@ -1,6 +1,5 @@ from __future__ import annotations - from commitizen.providers.base_provider import VersionProvider diff --git a/commitizen/providers/composer_provider.py b/commitizen/providers/composer_provider.py index ef36af5a72..495357d8f0 100644 --- a/commitizen/providers/composer_provider.py +++ b/commitizen/providers/composer_provider.py @@ -1,6 +1,5 @@ from __future__ import annotations - from commitizen.providers.base_provider import JsonProvider diff --git a/commitizen/providers/npm_provider.py b/commitizen/providers/npm_provider.py index f625c3c6c3..12900ff7de 100644 --- a/commitizen/providers/npm_provider.py +++ b/commitizen/providers/npm_provider.py @@ -4,7 +4,6 @@ from pathlib import Path from typing import Any, ClassVar - from commitizen.providers.base_provider import VersionProvider diff --git a/commitizen/providers/pep621_provider.py b/commitizen/providers/pep621_provider.py index b6d32f1a63..0b8b5c4b87 100644 --- a/commitizen/providers/pep621_provider.py +++ b/commitizen/providers/pep621_provider.py @@ -1,6 +1,5 @@ from __future__ import annotations - from commitizen.providers.base_provider import TomlProvider diff --git a/commitizen/providers/poetry_provider.py b/commitizen/providers/poetry_provider.py index d301131115..7aa28f56d9 100644 --- a/commitizen/providers/poetry_provider.py +++ b/commitizen/providers/poetry_provider.py @@ -2,7 +2,6 @@ import tomlkit - from commitizen.providers.base_provider import TomlProvider diff --git a/commitizen/providers/scm_provider.py b/commitizen/providers/scm_provider.py index 37329d07a5..00df3e4153 100644 --- a/commitizen/providers/scm_provider.py +++ b/commitizen/providers/scm_provider.py @@ -3,17 +3,15 @@ import re from typing import Callable - from commitizen.git import get_tags +from commitizen.providers.base_provider import VersionProvider from commitizen.version_schemes import ( - get_version_scheme, InvalidVersion, Version, VersionProtocol, + get_version_scheme, ) -from commitizen.providers.base_provider import VersionProvider - class ScmProvider(VersionProvider): """ diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index b20f75169a..a0271c322e 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -12,6 +12,7 @@ import commitizen.commands.bump as bump from commitizen import cli, cmd, git, hooks +from commitizen.changelog_formats import ChangelogFormat from commitizen.cz.base import BaseCommitizen from commitizen.exceptions import ( BumpTagFailedError, @@ -28,7 +29,6 @@ NotAllowed, NoVersionSpecifiedError, ) -from commitizen.changelog_formats import ChangelogFormat from tests.utils import create_file_and_commit, create_tag, skip_below_py_3_10 diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 67f10a8ac0..4694d33305 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -11,6 +11,7 @@ from commitizen import __file__ as commitizen_init from commitizen import cli, git +from commitizen.changelog_formats import ChangelogFormat from commitizen.commands.changelog import Changelog from commitizen.config.base_config import BaseConfig from commitizen.cz.base import BaseCommitizen @@ -22,16 +23,15 @@ NotAGitProjectError, NotAllowed, ) -from commitizen.changelog_formats import ChangelogFormat from tests.utils import ( create_branch, create_file_and_commit, create_tag, get_current_branch, merge_branch, + skip_below_py_3_10, switch_branch, wait_for_tag, - skip_below_py_3_10, ) diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 2085278757..8ae7568a9d 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -1,9 +1,9 @@ import os import sys +from unittest.mock import ANY import pytest from pytest_mock import MockFixture -from unittest.mock import ANY from commitizen import cli, cmd, commands from commitizen.cz.exceptions import CzException @@ -19,7 +19,6 @@ NotAllowed, NothingToCommitError, ) - from tests.utils import skip_below_py_3_10 diff --git a/tests/commands/test_example_command.py b/tests/commands/test_example_command.py index e0c2141453..0521679f1c 100644 --- a/tests/commands/test_example_command.py +++ b/tests/commands/test_example_command.py @@ -1,9 +1,9 @@ -import pytest import sys -from commitizen import cli, commands +import pytest from pytest_mock import MockerFixture +from commitizen import cli, commands from tests.utils import skip_below_py_3_10 diff --git a/tests/commands/test_info_command.py b/tests/commands/test_info_command.py index 6221630acc..2bd1553679 100644 --- a/tests/commands/test_info_command.py +++ b/tests/commands/test_info_command.py @@ -1,8 +1,9 @@ -import pytest import sys -from commitizen import cli, commands +import pytest from pytest_mock import MockerFixture + +from commitizen import cli, commands from tests.utils import skip_below_py_3_10 diff --git a/tests/commands/test_init_command.py b/tests/commands/test_init_command.py index a263e73a8e..ea18e89a2b 100644 --- a/tests/commands/test_init_command.py +++ b/tests/commands/test_init_command.py @@ -12,7 +12,6 @@ from commitizen import cli, commands from commitizen.__version__ import __version__ from commitizen.exceptions import InitFailedError, NoAnswersError - from tests.utils import skip_below_py_3_10 diff --git a/tests/commands/test_ls_command.py b/tests/commands/test_ls_command.py index d783305fc0..7225d2a85c 100644 --- a/tests/commands/test_ls_command.py +++ b/tests/commands/test_ls_command.py @@ -1,9 +1,9 @@ -import pytest import sys -from commitizen import cli, commands +import pytest from pytest_mock import MockerFixture +from commitizen import cli, commands from tests.utils import skip_below_py_3_10 diff --git a/tests/commands/test_schema_command.py b/tests/commands/test_schema_command.py index f69638dba3..5e571721c5 100644 --- a/tests/commands/test_schema_command.py +++ b/tests/commands/test_schema_command.py @@ -1,9 +1,9 @@ -import pytest import sys -from commitizen import cli, commands +import pytest from pytest_mock import MockerFixture +from commitizen import cli, commands from tests.utils import skip_below_py_3_10 diff --git a/tests/conftest.py b/tests/conftest.py index 76d2e53fb7..cc306ac6d4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,13 +10,13 @@ from pytest_mock import MockerFixture from commitizen import cmd, defaults -from commitizen.config import BaseConfig -from commitizen.cz import registry -from commitizen.cz.base import BaseCommitizen from commitizen.changelog_formats import ( ChangelogFormat, get_changelog_format, ) +from commitizen.config import BaseConfig +from commitizen.cz import registry +from commitizen.cz.base import BaseCommitizen from tests.utils import create_file_and_commit SIGNER = "GitHub Action" diff --git a/tests/providers/test_base_provider.py b/tests/providers/test_base_provider.py index 09a2bd71cd..482bd698ea 100644 --- a/tests/providers/test_base_provider.py +++ b/tests/providers/test_base_provider.py @@ -1,6 +1,5 @@ from __future__ import annotations - import pytest from commitizen.config.base_config import BaseConfig diff --git a/tests/providers/test_cargo_provider.py b/tests/providers/test_cargo_provider.py index cde868deb5..646ef3a53d 100644 --- a/tests/providers/test_cargo_provider.py +++ b/tests/providers/test_cargo_provider.py @@ -9,7 +9,6 @@ from commitizen.providers import get_provider from commitizen.providers.cargo_provider import CargoProvider - CARGO_TOML = """\ [package] name = "whatever" diff --git a/tests/providers/test_commitizen_provider.py b/tests/providers/test_commitizen_provider.py index 887adf3d12..b8df60da93 100644 --- a/tests/providers/test_commitizen_provider.py +++ b/tests/providers/test_commitizen_provider.py @@ -2,11 +2,9 @@ from typing import TYPE_CHECKING - from commitizen.config.base_config import BaseConfig from commitizen.providers.commitizen_provider import CommitizenProvider - if TYPE_CHECKING: from pytest_mock import MockerFixture diff --git a/tests/providers/test_composer_provider.py b/tests/providers/test_composer_provider.py index ce72ae4703..45cbc8afa4 100644 --- a/tests/providers/test_composer_provider.py +++ b/tests/providers/test_composer_provider.py @@ -9,7 +9,6 @@ from commitizen.providers import get_provider from commitizen.providers.composer_provider import ComposerProvider - COMPOSER_JSON = """\ { "name": "whatever", diff --git a/tests/providers/test_npm_provider.py b/tests/providers/test_npm_provider.py index 2e5ceb42d5..bc9399916d 100644 --- a/tests/providers/test_npm_provider.py +++ b/tests/providers/test_npm_provider.py @@ -9,7 +9,6 @@ from commitizen.providers import get_provider from commitizen.providers.npm_provider import NpmProvider - NPM_PACKAGE_JSON = """\ { "name": "whatever", diff --git a/tests/providers/test_pep621_provider.py b/tests/providers/test_pep621_provider.py index 9e82213294..16bb479cc4 100644 --- a/tests/providers/test_pep621_provider.py +++ b/tests/providers/test_pep621_provider.py @@ -9,7 +9,6 @@ from commitizen.providers import get_provider from commitizen.providers.pep621_provider import Pep621Provider - PEP621_TOML = """\ [project] version = "0.1.0" diff --git a/tests/providers/test_poetry_provider.py b/tests/providers/test_poetry_provider.py index 9e327db6ad..e26e2a44fb 100644 --- a/tests/providers/test_poetry_provider.py +++ b/tests/providers/test_poetry_provider.py @@ -9,7 +9,6 @@ from commitizen.providers import get_provider from commitizen.providers.poetry_provider import PoetryProvider - POETRY_TOML = """\ [tool.poetry] version = "0.1.0" diff --git a/tests/providers/test_scm_provider.py b/tests/providers/test_scm_provider.py index 9611dd9ee0..01e7ab9943 100644 --- a/tests/providers/test_scm_provider.py +++ b/tests/providers/test_scm_provider.py @@ -1,6 +1,5 @@ from __future__ import annotations - import pytest from commitizen.config.base_config import BaseConfig diff --git a/tests/test_changelog.py b/tests/test_changelog.py index d382a67f30..20d59488d3 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,5 +1,4 @@ import re - from pathlib import Path from typing import Optional @@ -7,11 +6,11 @@ from jinja2 import FileSystemLoader from commitizen import changelog, git +from commitizen.changelog_formats import ChangelogFormat from commitizen.cz.conventional_commits.conventional_commits import ( ConventionalCommitsCz, ) from commitizen.exceptions import InvalidConfigurationError -from commitizen.changelog_formats import ChangelogFormat COMMITS_DATA = [ { diff --git a/tests/test_changelog_format_asciidoc.py b/tests/test_changelog_format_asciidoc.py index df9c28f9d7..89740d2147 100644 --- a/tests/test_changelog_format_asciidoc.py +++ b/tests/test_changelog_format_asciidoc.py @@ -5,9 +5,8 @@ import pytest from commitizen.changelog import Metadata -from commitizen.config.base_config import BaseConfig from commitizen.changelog_formats.asciidoc import AsciiDoc - +from commitizen.config.base_config import BaseConfig CHANGELOG_A = """ = Changelog diff --git a/tests/test_changelog_format_markdown.py b/tests/test_changelog_format_markdown.py index 2e1ee69977..ab7c65453c 100644 --- a/tests/test_changelog_format_markdown.py +++ b/tests/test_changelog_format_markdown.py @@ -5,9 +5,8 @@ import pytest from commitizen.changelog import Metadata -from commitizen.config.base_config import BaseConfig from commitizen.changelog_formats.markdown import Markdown - +from commitizen.config.base_config import BaseConfig CHANGELOG_A = """ # Changelog diff --git a/tests/test_changelog_format_restructuredtext.py b/tests/test_changelog_format_restructuredtext.py index 7c5969f51d..46a11ebcdf 100644 --- a/tests/test_changelog_format_restructuredtext.py +++ b/tests/test_changelog_format_restructuredtext.py @@ -7,8 +7,8 @@ import pytest from commitizen.changelog import Metadata -from commitizen.config.base_config import BaseConfig from commitizen.changelog_formats.restructuredtext import RestructuredText +from commitizen.config.base_config import BaseConfig if TYPE_CHECKING: from _pytest.mark.structures import ParameterSet diff --git a/tests/test_changelog_format_textile.py b/tests/test_changelog_format_textile.py index 5176243ba0..e382e1c746 100644 --- a/tests/test_changelog_format_textile.py +++ b/tests/test_changelog_format_textile.py @@ -5,9 +5,8 @@ import pytest from commitizen.changelog import Metadata -from commitizen.config.base_config import BaseConfig from commitizen.changelog_formats.textile import Textile - +from commitizen.config.base_config import BaseConfig CHANGELOG_A = """ h1. Changelog diff --git a/tests/test_changelog_formats.py b/tests/test_changelog_formats.py index 7da87f16ca..dec23720dc 100644 --- a/tests/test_changelog_formats.py +++ b/tests/test_changelog_formats.py @@ -1,14 +1,15 @@ from __future__ import annotations import pytest + from commitizen import defaults -from commitizen.config.base_config import BaseConfig from commitizen.changelog_formats import ( KNOWN_CHANGELOG_FORMATS, ChangelogFormat, get_changelog_format, guess_changelog_format, ) +from commitizen.config.base_config import BaseConfig from commitizen.exceptions import ChangelogFormatUnknown diff --git a/tests/test_cli.py b/tests/test_cli.py index 345f0b1b00..1c87bc022b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -8,11 +8,11 @@ from commitizen import cli from commitizen.exceptions import ( + ConfigFileNotFound, ExpectedExit, + InvalidCommandArgumentError, NoCommandFoundError, NotAGitProjectError, - InvalidCommandArgumentError, - ConfigFileNotFound, ) diff --git a/tests/test_conf.py b/tests/test_conf.py index ac49362979..1cbbc57aca 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, ConfigFileIsEmpty +from commitizen.exceptions import ConfigFileIsEmpty, InvalidConfigurationError PYPROJECT = """ [tool.commitizen] diff --git a/tests/test_git.py b/tests/test_git.py index 8af332d214..6ada76be6d 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -6,14 +6,14 @@ import shutil import pytest -from commitizen import cmd, exceptions, git from pytest_mock import MockFixture +from commitizen import cmd, exceptions, git from tests.utils import ( FakeCommand, + create_branch, create_file_and_commit, create_tag, - create_branch, switch_branch, ) diff --git a/tests/test_version_schemes.py b/tests/test_version_schemes.py index e30c780283..985b371f7b 100644 --- a/tests/test_version_schemes.py +++ b/tests/test_version_schemes.py @@ -1,8 +1,8 @@ from __future__ import annotations +import importlib_metadata as metadata import pytest from pytest_mock import MockerFixture -import importlib_metadata as metadata from commitizen.config.base_config import BaseConfig from commitizen.exceptions import VersionSchemeUnknown diff --git a/tests/utils.py b/tests/utils.py index 39fb0a17fa..971ff91820 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,8 +1,8 @@ from __future__ import annotations +import sys import time import uuid -import sys from pathlib import Path import pytest @@ -10,7 +10,6 @@ from commitizen import cmd, exceptions, git - skip_below_py_3_10 = pytest.mark.skipif( sys.version_info < (3, 10), reason="The output meesage of argparse is different between Python 3.10 and lower than Python 3.10", From 901ff2014cbc21150e0d90fb0ce2402b9aae463f Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Tue, 21 May 2024 10:18:40 -0400 Subject: [PATCH 192/598] build: remove black and use only ruff --- poetry.lock | 700 ++++++++++++++++++++++--------------------------- pyproject.toml | 2 - scripts/format | 1 - scripts/test | 1 - 4 files changed, 318 insertions(+), 386 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2e16545b02..6f2e254319 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,14 +1,14 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "appnope" -version = "0.1.3" +version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, ] [[package]] @@ -45,13 +45,13 @@ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "babel" -version = "2.14.0" +version = "2.15.0" description = "Internationalization utilities" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, - {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, + {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, + {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, ] [package.dependencies] @@ -71,61 +71,15 @@ files = [ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] -[[package]] -name = "black" -version = "24.4.2" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, - {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, - {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, - {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, - {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, - {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, - {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, - {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, - {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, - {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, - {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, - {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, - {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, - {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, - {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, - {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, - {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, - {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, - {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, - {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, - {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, - {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - [[package]] name = "certifi" -version = "2023.11.17" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] @@ -265,63 +219,63 @@ files = [ [[package]] name = "coverage" -version = "7.3.3" +version = "7.5.1" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d874434e0cb7b90f7af2b6e3309b0733cde8ec1476eb47db148ed7deeb2a9494"}, - {file = "coverage-7.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee6621dccce8af666b8c4651f9f43467bfbf409607c604b840b78f4ff3619aeb"}, - {file = "coverage-7.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1367aa411afb4431ab58fd7ee102adb2665894d047c490649e86219327183134"}, - {file = "coverage-7.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f0f8f0c497eb9c9f18f21de0750c8d8b4b9c7000b43996a094290b59d0e7523"}, - {file = "coverage-7.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db0338c4b0951d93d547e0ff8d8ea340fecf5885f5b00b23be5aa99549e14cfd"}, - {file = "coverage-7.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d31650d313bd90d027f4be7663dfa2241079edd780b56ac416b56eebe0a21aab"}, - {file = "coverage-7.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9437a4074b43c177c92c96d051957592afd85ba00d3e92002c8ef45ee75df438"}, - {file = "coverage-7.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9e17d9cb06c13b4f2ef570355fa45797d10f19ca71395910b249e3f77942a837"}, - {file = "coverage-7.3.3-cp310-cp310-win32.whl", hash = "sha256:eee5e741b43ea1b49d98ab6e40f7e299e97715af2488d1c77a90de4a663a86e2"}, - {file = "coverage-7.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:593efa42160c15c59ee9b66c5f27a453ed3968718e6e58431cdfb2d50d5ad284"}, - {file = "coverage-7.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8c944cf1775235c0857829c275c777a2c3e33032e544bcef614036f337ac37bb"}, - {file = "coverage-7.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eda7f6e92358ac9e1717ce1f0377ed2b9320cea070906ece4e5c11d172a45a39"}, - {file = "coverage-7.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c854c1d2c7d3e47f7120b560d1a30c1ca221e207439608d27bc4d08fd4aeae8"}, - {file = "coverage-7.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:222b038f08a7ebed1e4e78ccf3c09a1ca4ac3da16de983e66520973443b546bc"}, - {file = "coverage-7.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff4800783d85bff132f2cc7d007426ec698cdce08c3062c8d501ad3f4ea3d16c"}, - {file = "coverage-7.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fc200cec654311ca2c3f5ab3ce2220521b3d4732f68e1b1e79bef8fcfc1f2b97"}, - {file = "coverage-7.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:307aecb65bb77cbfebf2eb6e12009e9034d050c6c69d8a5f3f737b329f4f15fb"}, - {file = "coverage-7.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ffb0eacbadb705c0a6969b0adf468f126b064f3362411df95f6d4f31c40d31c1"}, - {file = "coverage-7.3.3-cp311-cp311-win32.whl", hash = "sha256:79c32f875fd7c0ed8d642b221cf81feba98183d2ff14d1f37a1bbce6b0347d9f"}, - {file = "coverage-7.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:243576944f7c1a1205e5cd658533a50eba662c74f9be4c050d51c69bd4532936"}, - {file = "coverage-7.3.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a2ac4245f18057dfec3b0074c4eb366953bca6787f1ec397c004c78176a23d56"}, - {file = "coverage-7.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f9191be7af41f0b54324ded600e8ddbcabea23e1e8ba419d9a53b241dece821d"}, - {file = "coverage-7.3.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31c0b1b8b5a4aebf8fcd227237fc4263aa7fa0ddcd4d288d42f50eff18b0bac4"}, - {file = "coverage-7.3.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee453085279df1bac0996bc97004771a4a052b1f1e23f6101213e3796ff3cb85"}, - {file = "coverage-7.3.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1191270b06ecd68b1d00897b2daddb98e1719f63750969614ceb3438228c088e"}, - {file = "coverage-7.3.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:007a7e49831cfe387473e92e9ff07377f6121120669ddc39674e7244350a6a29"}, - {file = "coverage-7.3.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:af75cf83c2d57717a8493ed2246d34b1f3398cb8a92b10fd7a1858cad8e78f59"}, - {file = "coverage-7.3.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:811ca7373da32f1ccee2927dc27dc523462fd30674a80102f86c6753d6681bc6"}, - {file = "coverage-7.3.3-cp312-cp312-win32.whl", hash = "sha256:733537a182b5d62184f2a72796eb6901299898231a8e4f84c858c68684b25a70"}, - {file = "coverage-7.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:e995efb191f04b01ced307dbd7407ebf6e6dc209b528d75583277b10fd1800ee"}, - {file = "coverage-7.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fbd8a5fe6c893de21a3c6835071ec116d79334fbdf641743332e442a3466f7ea"}, - {file = "coverage-7.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:50c472c1916540f8b2deef10cdc736cd2b3d1464d3945e4da0333862270dcb15"}, - {file = "coverage-7.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e9223a18f51d00d3ce239c39fc41410489ec7a248a84fab443fbb39c943616c"}, - {file = "coverage-7.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f501e36ac428c1b334c41e196ff6bd550c0353c7314716e80055b1f0a32ba394"}, - {file = "coverage-7.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:475de8213ed95a6b6283056d180b2442eee38d5948d735cd3d3b52b86dd65b92"}, - {file = "coverage-7.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:afdcc10c01d0db217fc0a64f58c7edd635b8f27787fea0a3054b856a6dff8717"}, - {file = "coverage-7.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:fff0b2f249ac642fd735f009b8363c2b46cf406d3caec00e4deeb79b5ff39b40"}, - {file = "coverage-7.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a1f76cfc122c9e0f62dbe0460ec9cc7696fc9a0293931a33b8870f78cf83a327"}, - {file = "coverage-7.3.3-cp38-cp38-win32.whl", hash = "sha256:757453848c18d7ab5d5b5f1827293d580f156f1c2c8cef45bfc21f37d8681069"}, - {file = "coverage-7.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:ad2453b852a1316c8a103c9c970db8fbc262f4f6b930aa6c606df9b2766eee06"}, - {file = "coverage-7.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b15e03b8ee6a908db48eccf4e4e42397f146ab1e91c6324da44197a45cb9132"}, - {file = "coverage-7.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:89400aa1752e09f666cc48708eaa171eef0ebe3d5f74044b614729231763ae69"}, - {file = "coverage-7.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c59a3e59fb95e6d72e71dc915e6d7fa568863fad0a80b33bc7b82d6e9f844973"}, - {file = "coverage-7.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ede881c7618f9cf93e2df0421ee127afdfd267d1b5d0c59bcea771cf160ea4a"}, - {file = "coverage-7.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3bfd2c2f0e5384276e12b14882bf2c7621f97c35320c3e7132c156ce18436a1"}, - {file = "coverage-7.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7f3bad1a9313401ff2964e411ab7d57fb700a2d5478b727e13f156c8f89774a0"}, - {file = "coverage-7.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:65d716b736f16e250435473c5ca01285d73c29f20097decdbb12571d5dfb2c94"}, - {file = "coverage-7.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a702e66483b1fe602717020a0e90506e759c84a71dbc1616dd55d29d86a9b91f"}, - {file = "coverage-7.3.3-cp39-cp39-win32.whl", hash = "sha256:7fbf3f5756e7955174a31fb579307d69ffca91ad163467ed123858ce0f3fd4aa"}, - {file = "coverage-7.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cad9afc1644b979211989ec3ff7d82110b2ed52995c2f7263e7841c846a75348"}, - {file = "coverage-7.3.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:d299d379b676812e142fb57662a8d0d810b859421412b4d7af996154c00c31bb"}, - {file = "coverage-7.3.3.tar.gz", hash = "sha256:df04c64e58df96b4427db8d0559e95e2df3138c9916c96f9f6a4dd220db2fdb7"}, + {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"}, + {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"}, + {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"}, + {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"}, + {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"}, + {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"}, + {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"}, + {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"}, + {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"}, + {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"}, + {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"}, + {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"}, + {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"}, + {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"}, + {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"}, + {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"}, + {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"}, + {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"}, + {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"}, + {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"}, + {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"}, + {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"}, + {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"}, + {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"}, + {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"}, + {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"}, + {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"}, + {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"}, + {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"}, + {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"}, + {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"}, + {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, ] [package.dependencies] @@ -382,13 +336,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.2.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, + {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [package.extras] @@ -424,29 +378,29 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "filelock" -version = "3.13.1" +version = "3.14.0" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, + {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"}, + {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] [[package]] name = "freezegun" -version = "1.3.1" +version = "1.5.1" description = "Let your Python tests travel through time" optional = false python-versions = ">=3.7" files = [ - {file = "freezegun-1.3.1-py3-none-any.whl", hash = "sha256:065e77a12624d05531afa87ade12a0b9bdb53495c4573893252a055b545ce3ea"}, - {file = "freezegun-1.3.1.tar.gz", hash = "sha256:48984397b3b58ef5dfc645d6a304b0060f612bcecfdaaf45ce8aff0077a6cb6a"}, + {file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"}, + {file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"}, ] [package.dependencies] @@ -471,13 +425,13 @@ dev = ["flake8", "markdown", "twine", "wheel"] [[package]] name = "identify" -version = "2.5.33" +version = "2.5.36" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.33-py2.py3-none-any.whl", hash = "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34"}, - {file = "identify-2.5.33.tar.gz", hash = "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d"}, + {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, + {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, ] [package.extras] @@ -601,13 +555,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "markdown" -version = "3.5.1" +version = "3.6" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "Markdown-3.5.1-py3-none-any.whl", hash = "sha256:5874b47d4ee3f0b14d764324d2c94c03ea66bee56f2d929da9f2508d65e722dc"}, - {file = "Markdown-3.5.1.tar.gz", hash = "sha256:b65d7beb248dc22f2e8a31fb706d93798093c308dc1aba295aedeb9d41a813bd"}, + {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, + {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, ] [package.dependencies] @@ -643,82 +597,82 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] name = "matplotlib-inline" -version = "0.1.6" +version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, - {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, ] [package.dependencies] @@ -796,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.23" +version = "9.5.24" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.23-py3-none-any.whl", hash = "sha256:ffd08a5beaef3cd135aceb58ded8b98bbbbf2b70e5b656f6a14a63c917d9b001"}, - {file = "mkdocs_material-9.5.23.tar.gz", hash = "sha256:4627fc3f15de2cba2bde9debc2fd59b9888ef494beabfe67eb352e23d14bf288"}, + {file = "mkdocs_material-9.5.24-py3-none-any.whl", hash = "sha256:e12cd75954c535b61e716f359cf2a5056bf4514889d17161fdebd5df4b0153c6"}, + {file = "mkdocs_material-9.5.24.tar.gz", hash = "sha256:02d5aaba0ee755e707c3ef6e748f9acb7b3011187c0ea766db31af8905078a34"}, ] [package.dependencies] @@ -929,18 +883,18 @@ files = [ [[package]] name = "parso" -version = "0.8.3" +version = "0.8.4" description = "A Python Parser" optional = false python-versions = ">=3.6" files = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, + {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, + {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, ] [package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["docopt", "pytest"] [[package]] name = "pathspec" @@ -980,18 +934,19 @@ files = [ [[package]] name = "platformdirs" -version = "4.1.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, - {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "pluggy" @@ -1067,32 +1022,31 @@ tests = ["pytest"] [[package]] name = "pygments" -version = "2.17.2" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] -plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pymdown-extensions" -version = "10.5" +version = "10.8.1" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.5-py3-none-any.whl", hash = "sha256:1f0ca8bb5beff091315f793ee17683bc1390731f6ac4c5eb01e27464b80fe879"}, - {file = "pymdown_extensions-10.5.tar.gz", hash = "sha256:1b60f1e462adbec5a1ed79dac91f666c9c0d241fa294de1989f29d20096cfd0b"}, + {file = "pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"}, + {file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"}, ] [package.dependencies] -markdown = ">=3.5" +markdown = ">=3.6" pyyaml = "*" [package.extras] @@ -1228,13 +1182,13 @@ testing = ["filelock"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -1242,13 +1196,13 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2023.3.post1" +version = "2024.1" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"}, - {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] [[package]] @@ -1263,7 +1217,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1271,16 +1224,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -1297,7 +1242,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -1305,7 +1249,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -1341,110 +1284,101 @@ prompt_toolkit = ">=2.0,<=3.0.36" [[package]] name = "regex" -version = "2023.10.3" +version = "2024.5.15" description = "Alternative regular expression module, to replace re." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "regex-2023.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc"}, - {file = "regex-2023.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915"}, - {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29"}, - {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8"}, - {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b"}, - {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee"}, - {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55"}, - {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be"}, - {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5"}, - {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767"}, - {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff"}, - {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a"}, - {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a"}, - {file = "regex-2023.10.3-cp310-cp310-win32.whl", hash = "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec"}, - {file = "regex-2023.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353"}, - {file = "regex-2023.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e"}, - {file = "regex-2023.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051"}, - {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964"}, - {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc"}, - {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b"}, - {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac"}, - {file = "regex-2023.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58"}, - {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a"}, - {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e"}, - {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0"}, - {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6"}, - {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54"}, - {file = "regex-2023.10.3-cp311-cp311-win32.whl", hash = "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2"}, - {file = "regex-2023.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c"}, - {file = "regex-2023.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037"}, - {file = "regex-2023.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f"}, - {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41"}, - {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e"}, - {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c"}, - {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841"}, - {file = "regex-2023.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9"}, - {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420"}, - {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9"}, - {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f"}, - {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292"}, - {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a"}, - {file = "regex-2023.10.3-cp312-cp312-win32.whl", hash = "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a"}, - {file = "regex-2023.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b"}, - {file = "regex-2023.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293"}, - {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d"}, - {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b"}, - {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0"}, - {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3"}, - {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf"}, - {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991"}, - {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302"}, - {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971"}, - {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11"}, - {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597"}, - {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb"}, - {file = "regex-2023.10.3-cp37-cp37m-win32.whl", hash = "sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a"}, - {file = "regex-2023.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed"}, - {file = "regex-2023.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533"}, - {file = "regex-2023.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a"}, - {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4"}, - {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368"}, - {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab"}, - {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94"}, - {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07"}, - {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c"}, - {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039"}, - {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863"}, - {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f"}, - {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711"}, - {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4"}, - {file = "regex-2023.10.3-cp38-cp38-win32.whl", hash = "sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d"}, - {file = "regex-2023.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b"}, - {file = "regex-2023.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af"}, - {file = "regex-2023.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930"}, - {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e"}, - {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14"}, - {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d"}, - {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52"}, - {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b"}, - {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588"}, - {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa"}, - {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af"}, - {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528"}, - {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca"}, - {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48"}, - {file = "regex-2023.10.3-cp39-cp39-win32.whl", hash = "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd"}, - {file = "regex-2023.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988"}, - {file = "regex-2023.10.3.tar.gz", hash = "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f"}, + {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a81e3cfbae20378d75185171587cbf756015ccb14840702944f014e0d93ea09f"}, + {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b59138b219ffa8979013be7bc85bb60c6f7b7575df3d56dc1e403a438c7a3f6"}, + {file = "regex-2024.5.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0bd000c6e266927cb7a1bc39d55be95c4b4f65c5be53e659537537e019232b1"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eaa7ddaf517aa095fa8da0b5015c44d03da83f5bd49c87961e3c997daed0de7"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba68168daedb2c0bab7fd7e00ced5ba90aebf91024dea3c88ad5063c2a562cca"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e8d717bca3a6e2064fc3a08df5cbe366369f4b052dcd21b7416e6d71620dca1"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1337b7dbef9b2f71121cdbf1e97e40de33ff114801263b275aafd75303bd62b5"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9ebd0a36102fcad2f03696e8af4ae682793a5d30b46c647eaf280d6cfb32796"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9efa1a32ad3a3ea112224897cdaeb6aa00381627f567179c0314f7b65d354c62"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1595f2d10dff3d805e054ebdc41c124753631b6a471b976963c7b28543cf13b0"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b802512f3e1f480f41ab5f2cfc0e2f761f08a1f41092d6718868082fc0d27143"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a0981022dccabca811e8171f913de05720590c915b033b7e601f35ce4ea7019f"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:19068a6a79cf99a19ccefa44610491e9ca02c2be3305c7760d3831d38a467a6f"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1b5269484f6126eee5e687785e83c6b60aad7663dafe842b34691157e5083e53"}, + {file = "regex-2024.5.15-cp310-cp310-win32.whl", hash = "sha256:ada150c5adfa8fbcbf321c30c751dc67d2f12f15bd183ffe4ec7cde351d945b3"}, + {file = "regex-2024.5.15-cp310-cp310-win_amd64.whl", hash = "sha256:ac394ff680fc46b97487941f5e6ae49a9f30ea41c6c6804832063f14b2a5a145"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f5b1dff3ad008dccf18e652283f5e5339d70bf8ba7c98bf848ac33db10f7bc7a"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c6a2b494a76983df8e3d3feea9b9ffdd558b247e60b92f877f93a1ff43d26656"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a32b96f15c8ab2e7d27655969a23895eb799de3665fa94349f3b2fbfd547236f"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10002e86e6068d9e1c91eae8295ef690f02f913c57db120b58fdd35a6bb1af35"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec54d5afa89c19c6dd8541a133be51ee1017a38b412b1321ccb8d6ddbeb4cf7d"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10e4ce0dca9ae7a66e6089bb29355d4432caed736acae36fef0fdd7879f0b0cb"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e507ff1e74373c4d3038195fdd2af30d297b4f0950eeda6f515ae3d84a1770f"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1f059a4d795e646e1c37665b9d06062c62d0e8cc3c511fe01315973a6542e40"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0721931ad5fe0dda45d07f9820b90b2148ccdd8e45bb9e9b42a146cb4f695649"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:833616ddc75ad595dee848ad984d067f2f31be645d603e4d158bba656bbf516c"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:287eb7f54fc81546346207c533ad3c2c51a8d61075127d7f6d79aaf96cdee890"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:19dfb1c504781a136a80ecd1fff9f16dddf5bb43cec6871778c8a907a085bb3d"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:119af6e56dce35e8dfb5222573b50c89e5508d94d55713c75126b753f834de68"}, + {file = "regex-2024.5.15-cp311-cp311-win32.whl", hash = "sha256:1c1c174d6ec38d6c8a7504087358ce9213d4332f6293a94fbf5249992ba54efa"}, + {file = "regex-2024.5.15-cp311-cp311-win_amd64.whl", hash = "sha256:9e717956dcfd656f5055cc70996ee2cc82ac5149517fc8e1b60261b907740201"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:632b01153e5248c134007209b5c6348a544ce96c46005d8456de1d552455b014"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e64198f6b856d48192bf921421fdd8ad8eb35e179086e99e99f711957ffedd6e"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68811ab14087b2f6e0fc0c2bae9ad689ea3584cad6917fc57be6a48bbd012c49"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ec0c2fea1e886a19c3bee0cd19d862b3aa75dcdfb42ebe8ed30708df64687a"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0c0c0003c10f54a591d220997dd27d953cd9ccc1a7294b40a4be5312be8797b"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2431b9e263af1953c55abbd3e2efca67ca80a3de8a0437cb58e2421f8184717a"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a605586358893b483976cffc1723fb0f83e526e8f14c6e6614e75919d9862cf"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391d7f7f1e409d192dba8bcd42d3e4cf9e598f3979cdaed6ab11288da88cb9f2"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9ff11639a8d98969c863d4617595eb5425fd12f7c5ef6621a4b74b71ed8726d5"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4eee78a04e6c67e8391edd4dad3279828dd66ac4b79570ec998e2155d2e59fd5"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8fe45aa3f4aa57faabbc9cb46a93363edd6197cbc43523daea044e9ff2fea83e"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d0a3d8d6acf0c78a1fff0e210d224b821081330b8524e3e2bc5a68ef6ab5803d"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c486b4106066d502495b3025a0a7251bf37ea9540433940a23419461ab9f2a80"}, + {file = "regex-2024.5.15-cp312-cp312-win32.whl", hash = "sha256:c49e15eac7c149f3670b3e27f1f28a2c1ddeccd3a2812cba953e01be2ab9b5fe"}, + {file = "regex-2024.5.15-cp312-cp312-win_amd64.whl", hash = "sha256:673b5a6da4557b975c6c90198588181029c60793835ce02f497ea817ff647cb2"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:87e2a9c29e672fc65523fb47a90d429b70ef72b901b4e4b1bd42387caf0d6835"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3bea0ba8b73b71b37ac833a7f3fd53825924165da6a924aec78c13032f20850"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bfc4f82cabe54f1e7f206fd3d30fda143f84a63fe7d64a81558d6e5f2e5aaba9"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5bb9425fe881d578aeca0b2b4b3d314ec88738706f66f219c194d67179337cb"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64c65783e96e563103d641760664125e91bd85d8e49566ee560ded4da0d3e704"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf2430df4148b08fb4324b848672514b1385ae3807651f3567871f130a728cc3"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5397de3219a8b08ae9540c48f602996aa6b0b65d5a61683e233af8605c42b0f2"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:455705d34b4154a80ead722f4f185b04c4237e8e8e33f265cd0798d0e44825fa"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2b6f1b3bb6f640c1a92be3bbfbcb18657b125b99ecf141fb3310b5282c7d4ed"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3ad070b823ca5890cab606c940522d05d3d22395d432f4aaaf9d5b1653e47ced"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5b5467acbfc153847d5adb21e21e29847bcb5870e65c94c9206d20eb4e99a384"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e6662686aeb633ad65be2a42b4cb00178b3fbf7b91878f9446075c404ada552f"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:2b4c884767504c0e2401babe8b5b7aea9148680d2e157fa28f01529d1f7fcf67"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3cd7874d57f13bf70078f1ff02b8b0aa48d5b9ed25fc48547516c6aba36f5741"}, + {file = "regex-2024.5.15-cp38-cp38-win32.whl", hash = "sha256:e4682f5ba31f475d58884045c1a97a860a007d44938c4c0895f41d64481edbc9"}, + {file = "regex-2024.5.15-cp38-cp38-win_amd64.whl", hash = "sha256:d99ceffa25ac45d150e30bd9ed14ec6039f2aad0ffa6bb87a5936f5782fc1569"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13cdaf31bed30a1e1c2453ef6015aa0983e1366fad2667657dbcac7b02f67133"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cac27dcaa821ca271855a32188aa61d12decb6fe45ffe3e722401fe61e323cd1"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7dbe2467273b875ea2de38ded4eba86cbcbc9a1a6d0aa11dcf7bd2e67859c435"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f18a9a3513a99c4bef0e3efd4c4a5b11228b48aa80743be822b71e132ae4f5"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d347a741ea871c2e278fde6c48f85136c96b8659b632fb57a7d1ce1872547600"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1878b8301ed011704aea4c806a3cadbd76f84dece1ec09cc9e4dc934cfa5d4da"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4babf07ad476aaf7830d77000874d7611704a7fcf68c9c2ad151f5d94ae4bfc4"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35cb514e137cb3488bce23352af3e12fb0dbedd1ee6e60da053c69fb1b29cc6c"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cdd09d47c0b2efee9378679f8510ee6955d329424c659ab3c5e3a6edea696294"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:72d7a99cd6b8f958e85fc6ca5b37c4303294954eac1376535b03c2a43eb72629"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a094801d379ab20c2135529948cb84d417a2169b9bdceda2a36f5f10977ebc16"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c0c18345010870e58238790a6779a1219b4d97bd2e77e1140e8ee5d14df071aa"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:16093f563098448ff6b1fa68170e4acbef94e6b6a4e25e10eae8598bb1694b5d"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e38a7d4e8f633a33b4c7350fbd8bad3b70bf81439ac67ac38916c4a86b465456"}, + {file = "regex-2024.5.15-cp39-cp39-win32.whl", hash = "sha256:71a455a3c584a88f654b64feccc1e25876066c4f5ef26cd6dd711308aa538694"}, + {file = "regex-2024.5.15-cp39-cp39-win_amd64.whl", hash = "sha256:cab12877a9bdafde5500206d1020a584355a97884dfd388af3699e9137bf7388"}, + {file = "regex-2024.5.15.tar.gz", hash = "sha256:d3ee02d9e5f482cc8309134a91eeaacbdd2261ba111b0fef3748eeb4913e6a2c"}, ] [[package]] name = "requests" -version = "2.31.0" +version = "2.32.1" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.1-py3-none-any.whl", hash = "sha256:21ac9465cdf8c1650fe1ecde8a71669a93d4e6f147550483a2967d08396a56a5"}, + {file = "requests-2.32.1.tar.gz", hash = "sha256:eb97e87e64c79e64e5b8ac75cee9dd1f97f49e289b083ee6be96268930725685"}, ] [package.dependencies] @@ -1504,19 +1438,18 @@ files = [ [[package]] name = "setuptools" -version = "69.0.2" +version = "70.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, - {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, + {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, + {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -1586,18 +1519,18 @@ files = [ [[package]] name = "traitlets" -version = "5.14.0" +version = "5.14.3" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" files = [ - {file = "traitlets-5.14.0-py3-none-any.whl", hash = "sha256:f14949d23829023013c47df20b4a76ccd1a85effb786dc060f34de7948361b33"}, - {file = "traitlets-5.14.0.tar.gz", hash = "sha256:fcdaa8ac49c04dfa0ed3ee3384ef6dfdb5d6f3741502be247279407679296772"}, + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "types-deprecated" @@ -1656,29 +1589,30 @@ files = [ [[package]] name = "urllib3" -version = "2.1.0" +version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, - {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.25.0" +version = "20.26.2" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, - {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, + {file = "virtualenv-20.26.2-py3-none-any.whl", hash = "sha256:a624db5e94f01ad993d476b9ee5346fdf7b9de43ccaee0e0197012dc838a0e9b"}, + {file = "virtualenv-20.26.2.tar.gz", hash = "sha256:82bf0f4eebbb78d36ddaee0283d43fe5736b53880b8a8cdcd37390a07ac3741c"}, ] [package.dependencies] @@ -1687,43 +1621,45 @@ filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "watchdog" -version = "3.0.0" +version = "4.0.0" description = "Filesystem events monitoring" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, - {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, - {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, - {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, - {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, - {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, - {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, - {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, - {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, + {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, + {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, + {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, + {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, + {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, + {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, + {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, ] [package.extras] @@ -1731,13 +1667,13 @@ watchmedo = ["PyYAML (>=3.10)"] [[package]] name = "wcwidth" -version = "0.2.12" +version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.12-py2.py3-none-any.whl", hash = "sha256:f26ec43d96c8cbfed76a5075dac87680124fa84e0855195a6184da9c187f133c"}, - {file = "wcwidth-0.2.12.tar.gz", hash = "sha256:f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02"}, + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, ] [[package]] @@ -1821,20 +1757,20 @@ files = [ [[package]] name = "zipp" -version = "3.17.0" +version = "3.18.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, + {file = "zipp-3.18.2-py3-none-any.whl", hash = "sha256:dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e"}, + {file = "zipp-3.18.2.tar.gz", hash = "sha256:6278d9ddbcfb1f1089a88fde84481528b07b0e10474e09dcfe53dad4069fa059"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "7749ae1f4f41db8c1a5333070a9b88a798dd6666535bbe1d96a6d15fa3f5ddd9" +content-hash = "f3966e7e19f4a5dae0b4500519ef776affe8b9e23609847f45794ece75d2c543" diff --git a/pyproject.toml b/pyproject.toml index 29f1eeddef..95a29693b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,8 +63,6 @@ pytest-mock = "^3.10" pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" -# code formatter -black = ">=23.11,<25.0" # linter ruff = ">=0.1.6,<0.5.0" pre-commit = ">=2.18,<4.0" diff --git a/scripts/format b/scripts/format index 2aafc4f6e2..0ffe29ba4f 100755 --- a/scripts/format +++ b/scripts/format @@ -8,4 +8,3 @@ set -x # This is needed for running import sorting ${PREFIX}ruff check --fix commitizen tests ${PREFIX}ruff format commitizen tests -${PREFIX}black commitizen tests diff --git a/scripts/test b/scripts/test index 08889af8b0..894228b41f 100755 --- a/scripts/test +++ b/scripts/test @@ -5,7 +5,6 @@ export PREFIX='poetry run python -m ' export REGEX='^(?![.]|venv).*' ${PREFIX}pytest -n 3 --dist=loadfile --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen tests/ -${PREFIX}black commitizen tests ${PREFIX}ruff check commitizen/ tests/ --fix ${PREFIX}mypy commitizen/ tests/ ${PREFIX}commitizen -nr 3 check --rev-range origin/master.. From 86d6aeacca823f68345960224c40e1d6672e814b Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Tue, 21 May 2024 23:09:36 -0400 Subject: [PATCH 193/598] docs(CHANGELOG): fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 496d9f5fba..c3a3ecc5e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### Feat -- **config_files**: add suport for "cz.toml" config file +- **config_files**: add support for "cz.toml" config file ## v3.26.2 (2024-05-22) From a87c108c942d1e895e569b004e2d59504bc58a84 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Tue, 21 May 2024 13:50:43 -0400 Subject: [PATCH 194/598] style: move codespell configuration to pyproject.toml So people could just run "codespell" without pre-commit and have centralized configuration for tools (the others are already in pyproject.toml) Signed-off-by: Yaroslav Halchenko --- .pre-commit-config.yaml | 4 ++-- pyproject.toml | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 350a7a95b2..49e108f2b5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,10 +41,10 @@ repos: hooks: - id: codespell name: Run codespell to check for common misspellings in files + # config section is within pyproject.toml language: python types: [ text ] - args: [ "--write-changes", "--ignore-words-list", "asend" ] - exclude: "poetry.lock" + args: [ "--write-changes" ] - repo: https://github.com/commitizen-tools/commitizen rev: v3.27.0 # automatically updated by Commitizen diff --git a/pyproject.toml b/pyproject.toml index 95a29693b6..a4158614c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -181,3 +181,9 @@ warn_unused_configs = true [[tool.mypy.overrides]] module = "py.*" # Legacy pytest dependencies ignore_missing_imports = true + +[tool.codespell] +# Ref: https://github.com/codespell-project/codespell#using-a-config-file +skip = '.git*,*.svg,*.lock' +check-hidden = true +ignore-words-list = 'asend' From 26dc450a23ebd5503c8a3229db7afae2e7c30388 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 22 May 2024 11:58:11 -0400 Subject: [PATCH 195/598] ci: add tomli as additional dependency for codespell since config now is in pyproject.toml Signed-off-by: Yaroslav Halchenko --- .pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 49e108f2b5..d0149b5fae 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,6 +45,8 @@ repos: language: python types: [ text ] args: [ "--write-changes" ] + additional_dependencies: + - tomli - repo: https://github.com/commitizen-tools/commitizen rev: v3.27.0 # automatically updated by Commitizen From 8f88d56b86ab79da69f2629d6fc5e284f6588953 Mon Sep 17 00:00:00 2001 From: Marcos Martins Date: Wed, 22 May 2024 09:42:00 -0300 Subject: [PATCH 196/598] ci: skip 'update-cli-screenshots' if no changes --- .github/workflows/docspublish.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index 4ac9a3a4a4..f318b86858 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -30,8 +30,13 @@ jobs: git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" git add docs/images/cli_help - git commit -m "docs(cli/screenshots): update CLI screenshots" -m "[skip ci]" - git push + + if [[ -n "$(git status --porcelain)" ]]; then + git commit -m "docs(cli/screenshots): update CLI screenshots" -m "[skip ci]" + git push + else + echo "No changes to commit. Skipping." + fi publish-documentation: runs-on: ubuntu-latest From 8cc46cd50185a69fdc6ce3ac54c4959c9b32c152 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 May 2024 01:52:03 +0000 Subject: [PATCH 197/598] build(deps-dev): bump ruff from 0.4.4 to 0.4.5 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.4 to 0.4.5. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.4...v0.4.5) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6f2e254319..bd61f32665 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.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" @@ -1217,6 +1217,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1224,8 +1225,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -1242,6 +1251,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -1249,6 +1259,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -1412,28 +1423,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.4" +version = "0.4.5" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:29d44ef5bb6a08e235c8249294fa8d431adc1426bfda99ed493119e6f9ea1bf6"}, - {file = "ruff-0.4.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c4efe62b5bbb24178c950732ddd40712b878a9b96b1d02b0ff0b08a090cbd891"}, - {file = "ruff-0.4.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8e2f1e8fc12d07ab521a9005d68a969e167b589cbcaee354cb61e9d9de9c15"}, - {file = "ruff-0.4.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60ed88b636a463214905c002fa3eaab19795679ed55529f91e488db3fe8976ab"}, - {file = "ruff-0.4.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b90fc5e170fc71c712cc4d9ab0e24ea505c6a9e4ebf346787a67e691dfb72e85"}, - {file = "ruff-0.4.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8e7e6ebc10ef16dcdc77fd5557ee60647512b400e4a60bdc4849468f076f6eef"}, - {file = "ruff-0.4.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9ddb2c494fb79fc208cd15ffe08f32b7682519e067413dbaf5f4b01a6087bcd"}, - {file = "ruff-0.4.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c51c928a14f9f0a871082603e25a1588059b7e08a920f2f9fa7157b5bf08cfe9"}, - {file = "ruff-0.4.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5eb0a4bfd6400b7d07c09a7725e1a98c3b838be557fee229ac0f84d9aa49c36"}, - {file = "ruff-0.4.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b1867ee9bf3acc21778dcb293db504692eda5f7a11a6e6cc40890182a9f9e595"}, - {file = "ruff-0.4.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1aecced1269481ef2894cc495647392a34b0bf3e28ff53ed95a385b13aa45768"}, - {file = "ruff-0.4.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9da73eb616b3241a307b837f32756dc20a0b07e2bcb694fec73699c93d04a69e"}, - {file = "ruff-0.4.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:958b4ea5589706a81065e2a776237de2ecc3e763342e5cc8e02a4a4d8a5e6f95"}, - {file = "ruff-0.4.4-py3-none-win32.whl", hash = "sha256:cb53473849f011bca6e754f2cdf47cafc9c4f4ff4570003a0dad0b9b6890e876"}, - {file = "ruff-0.4.4-py3-none-win_amd64.whl", hash = "sha256:424e5b72597482543b684c11def82669cc6b395aa8cc69acc1858b5ef3e5daae"}, - {file = "ruff-0.4.4-py3-none-win_arm64.whl", hash = "sha256:39df0537b47d3b597293edbb95baf54ff5b49589eb7ff41926d8243caa995ea6"}, - {file = "ruff-0.4.4.tar.gz", hash = "sha256:f87ea42d5cdebdc6a69761a9d0bc83ae9b3b30d0ad78952005ba6568d6c022af"}, + {file = "ruff-0.4.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8f58e615dec58b1a6b291769b559e12fdffb53cc4187160a2fc83250eaf54e96"}, + {file = "ruff-0.4.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:84dd157474e16e3a82745d2afa1016c17d27cb5d52b12e3d45d418bcc6d49264"}, + {file = "ruff-0.4.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f483ad9d50b00e7fd577f6d0305aa18494c6af139bce7319c68a17180087f4"}, + {file = "ruff-0.4.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63fde3bf6f3ad4e990357af1d30e8ba2730860a954ea9282c95fc0846f5f64af"}, + {file = "ruff-0.4.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e3ba4620dee27f76bbcad97067766026c918ba0f2d035c2fc25cbdd04d9c97"}, + {file = "ruff-0.4.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:441dab55c568e38d02bbda68a926a3d0b54f5510095c9de7f95e47a39e0168aa"}, + {file = "ruff-0.4.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1169e47e9c4136c997f08f9857ae889d614c5035d87d38fda9b44b4338909cdf"}, + {file = "ruff-0.4.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:755ac9ac2598a941512fc36a9070a13c88d72ff874a9781493eb237ab02d75df"}, + {file = "ruff-0.4.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4b02a65985be2b34b170025a8b92449088ce61e33e69956ce4d316c0fe7cce0"}, + {file = "ruff-0.4.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:75a426506a183d9201e7e5664de3f6b414ad3850d7625764106f7b6d0486f0a1"}, + {file = "ruff-0.4.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6e1b139b45e2911419044237d90b60e472f57285950e1492c757dfc88259bb06"}, + {file = "ruff-0.4.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6f29a8221d2e3d85ff0c7b4371c0e37b39c87732c969b4d90f3dad2e721c5b1"}, + {file = "ruff-0.4.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d6ef817124d72b54cc923f3444828ba24fa45c3164bc9e8f1813db2f3d3a8a11"}, + {file = "ruff-0.4.5-py3-none-win32.whl", hash = "sha256:aed8166c18b1a169a5d3ec28a49b43340949e400665555b51ee06f22813ef062"}, + {file = "ruff-0.4.5-py3-none-win_amd64.whl", hash = "sha256:b0b03c619d2b4350b4a27e34fd2ac64d0dabe1afbf43de57d0f9d8a05ecffa45"}, + {file = "ruff-0.4.5-py3-none-win_arm64.whl", hash = "sha256:9d15de3425f53161b3f5a5658d4522e4eee5ea002bf2ac7aa380743dd9ad5fba"}, + {file = "ruff-0.4.5.tar.gz", hash = "sha256:286eabd47e7d4d521d199cab84deca135557e6d1e0f0d01c29e757c3cb151b54"}, ] [[package]] From 2115e39e7bbc927b8d5800c5f1f91a58e17a3cd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 May 2024 01:38:11 +0000 Subject: [PATCH 198/598] build(deps): bump typing-extensions from 4.11.0 to 4.12.0 Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.11.0 to 4.12.0. - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.11.0...4.12.0) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index bd61f32665..46636b212b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1589,13 +1589,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.11.0" +version = "4.12.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, + {file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"}, + {file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"}, ] [[package]] From 673045d7e6e20f571c60cafb7c9693197016243d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 01:08:58 +0000 Subject: [PATCH 199/598] build(deps-dev): bump mkdocs-material from 9.5.24 to 9.5.25 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.24 to 9.5.25. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.24...9.5.25) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 46636b212b..661d21d856 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.24" +version = "9.5.25" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.24-py3-none-any.whl", hash = "sha256:e12cd75954c535b61e716f359cf2a5056bf4514889d17161fdebd5df4b0153c6"}, - {file = "mkdocs_material-9.5.24.tar.gz", hash = "sha256:02d5aaba0ee755e707c3ef6e748f9acb7b3011187c0ea766db31af8905078a34"}, + {file = "mkdocs_material-9.5.25-py3-none-any.whl", hash = "sha256:68fdab047a0b9bfbefe79ce267e8a7daaf5128bcf7867065fcd201ee335fece1"}, + {file = "mkdocs_material-9.5.25.tar.gz", hash = "sha256:d0662561efb725b712207e0ee01f035ca15633f29a64628e24f01ec99d7078f4"}, ] [package.dependencies] From 4975b38a504acc9e68163efae4dbc226fce2b34b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 May 2024 01:32:24 +0000 Subject: [PATCH 200/598] build(deps-dev): bump ruff from 0.4.5 to 0.4.6 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.5 to 0.4.6. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.5...v0.4.6) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 661d21d856..2a664373c3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,28 +1423,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.5" +version = "0.4.6" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8f58e615dec58b1a6b291769b559e12fdffb53cc4187160a2fc83250eaf54e96"}, - {file = "ruff-0.4.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:84dd157474e16e3a82745d2afa1016c17d27cb5d52b12e3d45d418bcc6d49264"}, - {file = "ruff-0.4.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f483ad9d50b00e7fd577f6d0305aa18494c6af139bce7319c68a17180087f4"}, - {file = "ruff-0.4.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63fde3bf6f3ad4e990357af1d30e8ba2730860a954ea9282c95fc0846f5f64af"}, - {file = "ruff-0.4.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e3ba4620dee27f76bbcad97067766026c918ba0f2d035c2fc25cbdd04d9c97"}, - {file = "ruff-0.4.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:441dab55c568e38d02bbda68a926a3d0b54f5510095c9de7f95e47a39e0168aa"}, - {file = "ruff-0.4.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1169e47e9c4136c997f08f9857ae889d614c5035d87d38fda9b44b4338909cdf"}, - {file = "ruff-0.4.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:755ac9ac2598a941512fc36a9070a13c88d72ff874a9781493eb237ab02d75df"}, - {file = "ruff-0.4.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4b02a65985be2b34b170025a8b92449088ce61e33e69956ce4d316c0fe7cce0"}, - {file = "ruff-0.4.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:75a426506a183d9201e7e5664de3f6b414ad3850d7625764106f7b6d0486f0a1"}, - {file = "ruff-0.4.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6e1b139b45e2911419044237d90b60e472f57285950e1492c757dfc88259bb06"}, - {file = "ruff-0.4.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6f29a8221d2e3d85ff0c7b4371c0e37b39c87732c969b4d90f3dad2e721c5b1"}, - {file = "ruff-0.4.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d6ef817124d72b54cc923f3444828ba24fa45c3164bc9e8f1813db2f3d3a8a11"}, - {file = "ruff-0.4.5-py3-none-win32.whl", hash = "sha256:aed8166c18b1a169a5d3ec28a49b43340949e400665555b51ee06f22813ef062"}, - {file = "ruff-0.4.5-py3-none-win_amd64.whl", hash = "sha256:b0b03c619d2b4350b4a27e34fd2ac64d0dabe1afbf43de57d0f9d8a05ecffa45"}, - {file = "ruff-0.4.5-py3-none-win_arm64.whl", hash = "sha256:9d15de3425f53161b3f5a5658d4522e4eee5ea002bf2ac7aa380743dd9ad5fba"}, - {file = "ruff-0.4.5.tar.gz", hash = "sha256:286eabd47e7d4d521d199cab84deca135557e6d1e0f0d01c29e757c3cb151b54"}, + {file = "ruff-0.4.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ef995583a038cd4a7edf1422c9e19118e2511b8ba0b015861b4abd26ec5367c5"}, + {file = "ruff-0.4.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:602ebd7ad909eab6e7da65d3c091547781bb06f5f826974a53dbe563d357e53c"}, + {file = "ruff-0.4.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f9ced5cbb7510fd7525448eeb204e0a22cabb6e99a3cb160272262817d49786"}, + {file = "ruff-0.4.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04a80acfc862e0e1630c8b738e70dcca03f350bad9e106968a8108379e12b31f"}, + {file = "ruff-0.4.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be47700ecb004dfa3fd4dcdddf7322d4e632de3c06cd05329d69c45c0280e618"}, + {file = "ruff-0.4.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1ff930d6e05f444090a0139e4e13e1e2e1f02bd51bb4547734823c760c621e79"}, + {file = "ruff-0.4.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f13410aabd3b5776f9c5699f42b37a3a348d65498c4310589bc6e5c548dc8a2f"}, + {file = "ruff-0.4.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0cf5cc02d3ae52dfb0c8a946eb7a1d6ffe4d91846ffc8ce388baa8f627e3bd50"}, + {file = "ruff-0.4.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea3424793c29906407e3cf417f28fc33f689dacbbadfb52b7e9a809dd535dcef"}, + {file = "ruff-0.4.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1fa8561489fadf483ffbb091ea94b9c39a00ed63efacd426aae2f197a45e67fc"}, + {file = "ruff-0.4.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4d5b914818d8047270308fe3e85d9d7f4a31ec86c6475c9f418fbd1624d198e0"}, + {file = "ruff-0.4.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4f02284335c766678778475e7698b7ab83abaf2f9ff0554a07b6f28df3b5c259"}, + {file = "ruff-0.4.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3a6a0a4f4b5f54fff7c860010ab3dd81425445e37d35701a965c0248819dde7a"}, + {file = "ruff-0.4.6-py3-none-win32.whl", hash = "sha256:9018bf59b3aa8ad4fba2b1dc0299a6e4e60a4c3bc62bbeaea222679865453062"}, + {file = "ruff-0.4.6-py3-none-win_amd64.whl", hash = "sha256:a769ae07ac74ff1a019d6bd529426427c3e30d75bdf1e08bb3d46ac8f417326a"}, + {file = "ruff-0.4.6-py3-none-win_arm64.whl", hash = "sha256:735a16407a1a8f58e4c5b913ad6102722e80b562dd17acb88887685ff6f20cf6"}, + {file = "ruff-0.4.6.tar.gz", hash = "sha256:a797a87da50603f71e6d0765282098245aca6e3b94b7c17473115167d8dfb0b7"}, ] [[package]] From db9fa79efcf60a0d89987fde241d2e299bd2b3cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 01:12:23 +0000 Subject: [PATCH 201/598] build(deps): bump typing-extensions from 4.12.0 to 4.12.1 Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.12.0 to 4.12.1. - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.12.0...4.12.1) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2a664373c3..689bf607bd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1589,13 +1589,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.12.0" +version = "4.12.1" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"}, - {file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"}, + {file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"}, + {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, ] [[package]] From 3ae4de89c024a1e0f0f8a9a430cee899c36f09aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 01:11:39 +0000 Subject: [PATCH 202/598] build(deps-dev): bump ruff from 0.4.6 to 0.4.7 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.6 to 0.4.7. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.6...v0.4.7) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 689bf607bd..eaca1b96ce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,28 +1423,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.6" +version = "0.4.7" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ef995583a038cd4a7edf1422c9e19118e2511b8ba0b015861b4abd26ec5367c5"}, - {file = "ruff-0.4.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:602ebd7ad909eab6e7da65d3c091547781bb06f5f826974a53dbe563d357e53c"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f9ced5cbb7510fd7525448eeb204e0a22cabb6e99a3cb160272262817d49786"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04a80acfc862e0e1630c8b738e70dcca03f350bad9e106968a8108379e12b31f"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be47700ecb004dfa3fd4dcdddf7322d4e632de3c06cd05329d69c45c0280e618"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1ff930d6e05f444090a0139e4e13e1e2e1f02bd51bb4547734823c760c621e79"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f13410aabd3b5776f9c5699f42b37a3a348d65498c4310589bc6e5c548dc8a2f"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0cf5cc02d3ae52dfb0c8a946eb7a1d6ffe4d91846ffc8ce388baa8f627e3bd50"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea3424793c29906407e3cf417f28fc33f689dacbbadfb52b7e9a809dd535dcef"}, - {file = "ruff-0.4.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1fa8561489fadf483ffbb091ea94b9c39a00ed63efacd426aae2f197a45e67fc"}, - {file = "ruff-0.4.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4d5b914818d8047270308fe3e85d9d7f4a31ec86c6475c9f418fbd1624d198e0"}, - {file = "ruff-0.4.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4f02284335c766678778475e7698b7ab83abaf2f9ff0554a07b6f28df3b5c259"}, - {file = "ruff-0.4.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3a6a0a4f4b5f54fff7c860010ab3dd81425445e37d35701a965c0248819dde7a"}, - {file = "ruff-0.4.6-py3-none-win32.whl", hash = "sha256:9018bf59b3aa8ad4fba2b1dc0299a6e4e60a4c3bc62bbeaea222679865453062"}, - {file = "ruff-0.4.6-py3-none-win_amd64.whl", hash = "sha256:a769ae07ac74ff1a019d6bd529426427c3e30d75bdf1e08bb3d46ac8f417326a"}, - {file = "ruff-0.4.6-py3-none-win_arm64.whl", hash = "sha256:735a16407a1a8f58e4c5b913ad6102722e80b562dd17acb88887685ff6f20cf6"}, - {file = "ruff-0.4.6.tar.gz", hash = "sha256:a797a87da50603f71e6d0765282098245aca6e3b94b7c17473115167d8dfb0b7"}, + {file = "ruff-0.4.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e089371c67892a73b6bb1525608e89a2aca1b77b5440acf7a71dda5dac958f9e"}, + {file = "ruff-0.4.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:10f973d521d910e5f9c72ab27e409e839089f955be8a4c8826601a6323a89753"}, + {file = "ruff-0.4.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59c3d110970001dfa494bcd95478e62286c751126dfb15c3c46e7915fc49694f"}, + {file = "ruff-0.4.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa9773c6c00f4958f73b317bc0fd125295110c3776089f6ef318f4b775f0abe4"}, + {file = "ruff-0.4.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07fc80bbb61e42b3b23b10fda6a2a0f5a067f810180a3760c5ef1b456c21b9db"}, + {file = "ruff-0.4.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:fa4dafe3fe66d90e2e2b63fa1591dd6e3f090ca2128daa0be33db894e6c18648"}, + {file = "ruff-0.4.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7c0083febdec17571455903b184a10026603a1de078428ba155e7ce9358c5f6"}, + {file = "ruff-0.4.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad1b20e66a44057c326168437d680a2166c177c939346b19c0d6b08a62a37589"}, + {file = "ruff-0.4.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbf5d818553add7511c38b05532d94a407f499d1a76ebb0cad0374e32bc67202"}, + {file = "ruff-0.4.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:50e9651578b629baec3d1513b2534de0ac7ed7753e1382272b8d609997e27e83"}, + {file = "ruff-0.4.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8874a9df7766cb956b218a0a239e0a5d23d9e843e4da1e113ae1d27ee420877a"}, + {file = "ruff-0.4.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b9de9a6e49f7d529decd09381c0860c3f82fa0b0ea00ea78409b785d2308a567"}, + {file = "ruff-0.4.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:13a1768b0691619822ae6d446132dbdfd568b700ecd3652b20d4e8bc1e498f78"}, + {file = "ruff-0.4.7-py3-none-win32.whl", hash = "sha256:769e5a51df61e07e887b81e6f039e7ed3573316ab7dd9f635c5afaa310e4030e"}, + {file = "ruff-0.4.7-py3-none-win_amd64.whl", hash = "sha256:9e3ab684ad403a9ed1226894c32c3ab9c2e0718440f6f50c7c5829932bc9e054"}, + {file = "ruff-0.4.7-py3-none-win_arm64.whl", hash = "sha256:10f2204b9a613988e3484194c2c9e96a22079206b22b787605c255f130db5ed7"}, + {file = "ruff-0.4.7.tar.gz", hash = "sha256:2331d2b051dc77a289a653fcc6a42cce357087c5975738157cd966590b18b5e1"}, ] [[package]] From 85fc472aca565af3c89bdb6233deefec3796697c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 01:54:02 +0000 Subject: [PATCH 203/598] build(deps-dev): bump pytest from 8.2.1 to 8.2.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.1 to 8.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.2.1...8.2.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index eaca1b96ce..21b93bd1ad 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1054,13 +1054,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.2.1" +version = "8.2.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"}, - {file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"}, + {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, + {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, ] [package.dependencies] From 7fce6670fdc44f994243babf37ba873f8c6ae587 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 01:18:56 +0000 Subject: [PATCH 204/598] build(deps-dev): bump ruff from 0.4.7 to 0.4.8 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.7 to 0.4.8. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.7...v0.4.8) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 21b93bd1ad..a481869ff6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,28 +1423,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.7" +version = "0.4.8" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e089371c67892a73b6bb1525608e89a2aca1b77b5440acf7a71dda5dac958f9e"}, - {file = "ruff-0.4.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:10f973d521d910e5f9c72ab27e409e839089f955be8a4c8826601a6323a89753"}, - {file = "ruff-0.4.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59c3d110970001dfa494bcd95478e62286c751126dfb15c3c46e7915fc49694f"}, - {file = "ruff-0.4.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa9773c6c00f4958f73b317bc0fd125295110c3776089f6ef318f4b775f0abe4"}, - {file = "ruff-0.4.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07fc80bbb61e42b3b23b10fda6a2a0f5a067f810180a3760c5ef1b456c21b9db"}, - {file = "ruff-0.4.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:fa4dafe3fe66d90e2e2b63fa1591dd6e3f090ca2128daa0be33db894e6c18648"}, - {file = "ruff-0.4.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7c0083febdec17571455903b184a10026603a1de078428ba155e7ce9358c5f6"}, - {file = "ruff-0.4.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad1b20e66a44057c326168437d680a2166c177c939346b19c0d6b08a62a37589"}, - {file = "ruff-0.4.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbf5d818553add7511c38b05532d94a407f499d1a76ebb0cad0374e32bc67202"}, - {file = "ruff-0.4.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:50e9651578b629baec3d1513b2534de0ac7ed7753e1382272b8d609997e27e83"}, - {file = "ruff-0.4.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8874a9df7766cb956b218a0a239e0a5d23d9e843e4da1e113ae1d27ee420877a"}, - {file = "ruff-0.4.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b9de9a6e49f7d529decd09381c0860c3f82fa0b0ea00ea78409b785d2308a567"}, - {file = "ruff-0.4.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:13a1768b0691619822ae6d446132dbdfd568b700ecd3652b20d4e8bc1e498f78"}, - {file = "ruff-0.4.7-py3-none-win32.whl", hash = "sha256:769e5a51df61e07e887b81e6f039e7ed3573316ab7dd9f635c5afaa310e4030e"}, - {file = "ruff-0.4.7-py3-none-win_amd64.whl", hash = "sha256:9e3ab684ad403a9ed1226894c32c3ab9c2e0718440f6f50c7c5829932bc9e054"}, - {file = "ruff-0.4.7-py3-none-win_arm64.whl", hash = "sha256:10f2204b9a613988e3484194c2c9e96a22079206b22b787605c255f130db5ed7"}, - {file = "ruff-0.4.7.tar.gz", hash = "sha256:2331d2b051dc77a289a653fcc6a42cce357087c5975738157cd966590b18b5e1"}, + {file = "ruff-0.4.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7663a6d78f6adb0eab270fa9cf1ff2d28618ca3a652b60f2a234d92b9ec89066"}, + {file = "ruff-0.4.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eeceb78da8afb6de0ddada93112869852d04f1cd0f6b80fe464fd4e35c330913"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aad360893e92486662ef3be0a339c5ca3c1b109e0134fcd37d534d4be9fb8de3"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:284c2e3f3396fb05f5f803c9fffb53ebbe09a3ebe7dda2929ed8d73ded736deb"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7354f921e3fbe04d2a62d46707e569f9315e1a613307f7311a935743c51a764"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:72584676164e15a68a15778fd1b17c28a519e7a0622161eb2debdcdabdc71883"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9678d5c9b43315f323af2233a04d747409d1e3aa6789620083a82d1066a35199"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704977a658131651a22b5ebeb28b717ef42ac6ee3b11e91dc87b633b5d83142b"}, + {file = "ruff-0.4.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05f8d6f0c3cce5026cecd83b7a143dcad503045857bc49662f736437380ad45"}, + {file = "ruff-0.4.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ea874950daca5697309d976c9afba830d3bf0ed66887481d6bca1673fc5b66a"}, + {file = "ruff-0.4.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fc95aac2943ddf360376be9aa3107c8cf9640083940a8c5bd824be692d2216dc"}, + {file = "ruff-0.4.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:384154a1c3f4bf537bac69f33720957ee49ac8d484bfc91720cc94172026ceed"}, + {file = "ruff-0.4.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e9d5ce97cacc99878aa0d084c626a15cd21e6b3d53fd6f9112b7fc485918e1fa"}, + {file = "ruff-0.4.8-py3-none-win32.whl", hash = "sha256:6d795d7639212c2dfd01991259460101c22aabf420d9b943f153ab9d9706e6a9"}, + {file = "ruff-0.4.8-py3-none-win_amd64.whl", hash = "sha256:e14a3a095d07560a9d6769a72f781d73259655919d9b396c650fc98a8157555d"}, + {file = "ruff-0.4.8-py3-none-win_arm64.whl", hash = "sha256:14019a06dbe29b608f6b7cbcec300e3170a8d86efaddb7b23405cb7f7dcaf780"}, + {file = "ruff-0.4.8.tar.gz", hash = "sha256:16d717b1d57b2e2fd68bd0bf80fb43931b79d05a7131aa477d66fc40fbd86268"}, ] [[package]] From 9c3db89f294e47eda06e85bced9b43e6a4a43d69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:01:35 +0000 Subject: [PATCH 205/598] build(deps): bump packaging from 24.0 to 24.1 Bumps [packaging](https://github.com/pypa/packaging) from 24.0 to 24.1. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/24.0...24.1) --- updated-dependencies: - dependency-name: packaging dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index a481869ff6..334339f82f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -862,13 +862,13 @@ setuptools = "*" [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] From 26c823df2172892f3058face1f1b95314c6a8357 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:02:27 +0000 Subject: [PATCH 206/598] build(deps): bump typing-extensions from 4.12.1 to 4.12.2 Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.12.1 to 4.12.2. - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.12.1...4.12.2) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 334339f82f..78485e278a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1589,13 +1589,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.12.1" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"}, - {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] From 2e953c8f41412aab112727b97d2cabd8a74b7a98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jun 2024 01:52:01 +0000 Subject: [PATCH 207/598] build(deps-dev): bump mkdocs-material from 9.5.25 to 9.5.26 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.25 to 9.5.26. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.25...9.5.26) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 78485e278a..6d462c9ac0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.25" +version = "9.5.26" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.25-py3-none-any.whl", hash = "sha256:68fdab047a0b9bfbefe79ce267e8a7daaf5128bcf7867065fcd201ee335fece1"}, - {file = "mkdocs_material-9.5.25.tar.gz", hash = "sha256:d0662561efb725b712207e0ee01f035ca15633f29a64628e24f01ec99d7078f4"}, + {file = "mkdocs_material-9.5.26-py3-none-any.whl", hash = "sha256:5d01fb0aa1c7946a1e3ae8689aa2b11a030621ecb54894e35aabb74c21016312"}, + {file = "mkdocs_material-9.5.26.tar.gz", hash = "sha256:56aeb91d94cffa43b6296fa4fbf0eb7c840136e563eecfd12c2d9e92e50ba326"}, ] [package.dependencies] From c0fcc183a46f104c6eefaae2aab2f0af11c2a681 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:35:51 +0000 Subject: [PATCH 208/598] build(deps-dev): bump urllib3 from 2.2.1 to 2.2.2 Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.1 to 2.2.2. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2) --- updated-dependencies: - dependency-name: urllib3 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6d462c9ac0..562a967856 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1600,13 +1600,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] From dbe14fed97e0c0f18c39096314b1a88129d8df2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jun 2024 01:16:34 +0000 Subject: [PATCH 209/598] build(deps): bump importlib-metadata from 7.1.0 to 7.2.0 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 7.1.0 to 7.2.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v7.1.0...v7.2.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 562a967856..261c3e3612 100644 --- a/poetry.lock +++ b/poetry.lock @@ -450,22 +450,22 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.1.0" +version = "7.2.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, - {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, + {file = "importlib_metadata-7.2.0-py3-none-any.whl", hash = "sha256:04e4aad329b8b948a5711d394fa8759cb80f009225441b4f2a02bd4d8e5f426c"}, + {file = "importlib_metadata-7.2.0.tar.gz", hash = "sha256:3ff4519071ed42740522d494d04819b666541b9752c43012f85afb2cc220fcc6"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "iniconfig" From 05446014a76d5b844dc5436e4a7bce1fdfe3033e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jun 2024 01:15:55 +0000 Subject: [PATCH 210/598] build(deps-dev): bump ruff from 0.4.8 to 0.4.10 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.8 to 0.4.10. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.8...v0.4.10) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 261c3e3612..f161ab93e2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,28 +1423,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.8" +version = "0.4.10" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7663a6d78f6adb0eab270fa9cf1ff2d28618ca3a652b60f2a234d92b9ec89066"}, - {file = "ruff-0.4.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eeceb78da8afb6de0ddada93112869852d04f1cd0f6b80fe464fd4e35c330913"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aad360893e92486662ef3be0a339c5ca3c1b109e0134fcd37d534d4be9fb8de3"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:284c2e3f3396fb05f5f803c9fffb53ebbe09a3ebe7dda2929ed8d73ded736deb"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7354f921e3fbe04d2a62d46707e569f9315e1a613307f7311a935743c51a764"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:72584676164e15a68a15778fd1b17c28a519e7a0622161eb2debdcdabdc71883"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9678d5c9b43315f323af2233a04d747409d1e3aa6789620083a82d1066a35199"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704977a658131651a22b5ebeb28b717ef42ac6ee3b11e91dc87b633b5d83142b"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05f8d6f0c3cce5026cecd83b7a143dcad503045857bc49662f736437380ad45"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ea874950daca5697309d976c9afba830d3bf0ed66887481d6bca1673fc5b66a"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fc95aac2943ddf360376be9aa3107c8cf9640083940a8c5bd824be692d2216dc"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:384154a1c3f4bf537bac69f33720957ee49ac8d484bfc91720cc94172026ceed"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e9d5ce97cacc99878aa0d084c626a15cd21e6b3d53fd6f9112b7fc485918e1fa"}, - {file = "ruff-0.4.8-py3-none-win32.whl", hash = "sha256:6d795d7639212c2dfd01991259460101c22aabf420d9b943f153ab9d9706e6a9"}, - {file = "ruff-0.4.8-py3-none-win_amd64.whl", hash = "sha256:e14a3a095d07560a9d6769a72f781d73259655919d9b396c650fc98a8157555d"}, - {file = "ruff-0.4.8-py3-none-win_arm64.whl", hash = "sha256:14019a06dbe29b608f6b7cbcec300e3170a8d86efaddb7b23405cb7f7dcaf780"}, - {file = "ruff-0.4.8.tar.gz", hash = "sha256:16d717b1d57b2e2fd68bd0bf80fb43931b79d05a7131aa477d66fc40fbd86268"}, + {file = "ruff-0.4.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c2c4d0859305ac5a16310eec40e4e9a9dec5dcdfbe92697acd99624e8638dac"}, + {file = "ruff-0.4.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a79489607d1495685cdd911a323a35871abfb7a95d4f98fc6f85e799227ac46e"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1dd1681dfa90a41b8376a61af05cc4dc5ff32c8f14f5fe20dba9ff5deb80cd6"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c75c53bb79d71310dc79fb69eb4902fba804a81f374bc86a9b117a8d077a1784"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18238c80ee3d9100d3535d8eb15a59c4a0753b45cc55f8bf38f38d6a597b9739"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d8f71885bce242da344989cae08e263de29752f094233f932d4f5cfb4ef36a81"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:330421543bd3222cdfec481e8ff3460e8702ed1e58b494cf9d9e4bf90db52b9d"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e9b6fb3a37b772628415b00c4fc892f97954275394ed611056a4b8a2631365e"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f54c481b39a762d48f64d97351048e842861c6662d63ec599f67d515cb417f6"}, + {file = "ruff-0.4.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:67fe086b433b965c22de0b4259ddfe6fa541c95bf418499bedb9ad5fb8d1c631"}, + {file = "ruff-0.4.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:acfaaab59543382085f9eb51f8e87bac26bf96b164839955f244d07125a982ef"}, + {file = "ruff-0.4.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3cea07079962b2941244191569cf3a05541477286f5cafea638cd3aa94b56815"}, + {file = "ruff-0.4.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:338a64ef0748f8c3a80d7f05785930f7965d71ca260904a9321d13be24b79695"}, + {file = "ruff-0.4.10-py3-none-win32.whl", hash = "sha256:ffe3cd2f89cb54561c62e5fa20e8f182c0a444934bf430515a4b422f1ab7b7ca"}, + {file = "ruff-0.4.10-py3-none-win_amd64.whl", hash = "sha256:67f67cef43c55ffc8cc59e8e0b97e9e60b4837c8f21e8ab5ffd5d66e196e25f7"}, + {file = "ruff-0.4.10-py3-none-win_arm64.whl", hash = "sha256:dd1fcee327c20addac7916ca4e2653fbbf2e8388d8a6477ce5b4e986b68ae6c0"}, + {file = "ruff-0.4.10.tar.gz", hash = "sha256:3aa4f2bc388a30d346c56524f7cacca85945ba124945fe489952aadb6b5cd804"}, ] [[package]] From 1590cdf31493c971d6f62f5f68219fad561c4b8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 01:44:53 +0000 Subject: [PATCH 211/598] build(deps): bump importlib-metadata from 7.2.0 to 7.2.1 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 7.2.0 to 7.2.1. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v7.2.0...v7.2.1) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index f161ab93e2..332d8e0b57 100644 --- a/poetry.lock +++ b/poetry.lock @@ -450,13 +450,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.2.0" +version = "7.2.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.2.0-py3-none-any.whl", hash = "sha256:04e4aad329b8b948a5711d394fa8759cb80f009225441b4f2a02bd4d8e5f426c"}, - {file = "importlib_metadata-7.2.0.tar.gz", hash = "sha256:3ff4519071ed42740522d494d04819b666541b9752c43012f85afb2cc220fcc6"}, + {file = "importlib_metadata-7.2.1-py3-none-any.whl", hash = "sha256:ffef94b0b66046dd8ea2d619b701fe978d9264d38f3998bc4c27ec3b146a87c8"}, + {file = "importlib_metadata-7.2.1.tar.gz", hash = "sha256:509ecb2ab77071db5137c655e24ceb3eee66e7bbc6574165d0d114d9fc4bbe68"}, ] [package.dependencies] From 98b297c0752f608466ec91932f6ae7780b6492c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 01:42:09 +0000 Subject: [PATCH 212/598] build(deps-dev): bump mypy from 1.10.0 to 1.10.1 Bumps [mypy](https://github.com/python/mypy) from 1.10.0 to 1.10.1. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.10.0...v1.10.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/poetry.lock b/poetry.lock index 332d8e0b57..74e95e27a3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -790,38 +790,38 @@ files = [ [[package]] name = "mypy" -version = "1.10.0" +version = "1.10.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, - {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, - {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, - {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, - {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, - {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, - {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, - {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, - {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, - {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, - {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, - {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, - {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, - {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, - {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, - {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, - {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, - {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, - {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, + {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, + {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, + {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, + {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, + {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, + {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, + {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, + {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, + {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, + {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, + {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, + {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, + {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, + {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, + {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, + {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, + {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, ] [package.dependencies] From db470b224efa5008b7da5c2d15b1e7faf6131aef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 01:51:34 +0000 Subject: [PATCH 213/598] build(deps): bump argcomplete from 3.3.0 to 3.4.0 Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v3.3.0...v3.4.0) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 74e95e27a3..5f23a584c6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,13 +13,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.3.0" +version = "3.4.0" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.3.0-py3-none-any.whl", hash = "sha256:c168c3723482c031df3c207d4ba8fa702717ccb9fc0bfe4117166c1f537b4a54"}, - {file = "argcomplete-3.3.0.tar.gz", hash = "sha256:fd03ff4a5b9e6580569d34b273f741e85cd9e072f3feeeee3eba4891c70eda62"}, + {file = "argcomplete-3.4.0-py3-none-any.whl", hash = "sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5"}, + {file = "argcomplete-3.4.0.tar.gz", hash = "sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f"}, ] [package.extras] @@ -1784,4 +1784,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "f3966e7e19f4a5dae0b4500519ef776affe8b9e23609847f45794ece75d2c543" +content-hash = "ae23361204d1cc38d6ea93cceaa273548efffef705c09120767bb4e79196181a" diff --git a/pyproject.toml b/pyproject.toml index a4158614c9..090e9ba42b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ packaging = ">=19" tomlkit = ">=0.5.3,<1.0.0" jinja2 = ">=2.10.3" pyyaml = ">=3.08" -argcomplete = ">=1.12.1,<3.4" +argcomplete = ">=1.12.1,<3.5" typing-extensions = { version = "^4.0.1", python = "<3.8" } charset-normalizer = ">=2.1.0,<4" # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility From 363d4e6f9b7b98a8728287c4e7dec883bd101833 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 01:50:48 +0000 Subject: [PATCH 214/598] build(deps-dev): bump mkdocs-material from 9.5.26 to 9.5.27 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.26 to 9.5.27. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.26...9.5.27) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5f23a584c6..91ce69f45e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.26" +version = "9.5.27" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.26-py3-none-any.whl", hash = "sha256:5d01fb0aa1c7946a1e3ae8689aa2b11a030621ecb54894e35aabb74c21016312"}, - {file = "mkdocs_material-9.5.26.tar.gz", hash = "sha256:56aeb91d94cffa43b6296fa4fbf0eb7c840136e563eecfd12c2d9e92e50ba326"}, + {file = "mkdocs_material-9.5.27-py3-none-any.whl", hash = "sha256:af8cc263fafa98bb79e9e15a8c966204abf15164987569bd1175fd66a7705182"}, + {file = "mkdocs_material-9.5.27.tar.gz", hash = "sha256:a7d4a35f6d4a62b0c43a0cfe7e987da0980c13587b5bc3c26e690ad494427ec0"}, ] [package.dependencies] From 927cbcb6b407620fadb75581212040aa07c3658d Mon Sep 17 00:00:00 2001 From: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> Date: Wed, 26 Jun 2024 22:31:00 +0200 Subject: [PATCH 215/598] build(deps): remove `importlib_metadata` for Python >=3.10 --- commitizen/changelog_formats/__init__.py | 6 +++++- commitizen/cz/__init__.py | 6 +++++- commitizen/providers/__init__.py | 6 +++++- commitizen/version_schemes.py | 6 +++++- poetry.lock | 2 +- pyproject.toml | 2 +- tests/test_factory.py | 6 +++++- tests/test_version_schemes.py | 8 +++++++- 8 files changed, 34 insertions(+), 8 deletions(-) diff --git a/commitizen/changelog_formats/__init__.py b/commitizen/changelog_formats/__init__.py index b91579ee71..782bfb24cb 100644 --- a/commitizen/changelog_formats/__init__.py +++ b/commitizen/changelog_formats/__init__.py @@ -1,8 +1,12 @@ from __future__ import annotations +import sys from typing import ClassVar, Protocol -import importlib_metadata as metadata +if sys.version_info >= (3, 10): + from importlib import metadata +else: + import importlib_metadata as metadata from commitizen.changelog import Metadata from commitizen.config.base_config import BaseConfig diff --git a/commitizen/cz/__init__.py b/commitizen/cz/__init__.py index f889dbd842..04603a9ec4 100644 --- a/commitizen/cz/__init__.py +++ b/commitizen/cz/__init__.py @@ -2,10 +2,14 @@ import importlib import pkgutil +import sys import warnings from typing import Iterable -import importlib_metadata as metadata +if sys.version_info >= (3, 10): + from importlib import metadata +else: + import importlib_metadata as metadata from commitizen.cz.base import BaseCommitizen diff --git a/commitizen/providers/__init__.py b/commitizen/providers/__init__.py index a177b29961..3fd4ab1bfd 100644 --- a/commitizen/providers/__init__.py +++ b/commitizen/providers/__init__.py @@ -1,8 +1,12 @@ from __future__ import annotations +import sys from typing import cast -import importlib_metadata as metadata +if sys.version_info >= (3, 10): + from importlib import metadata +else: + import importlib_metadata as metadata from commitizen.config.base_config import BaseConfig from commitizen.exceptions import VersionProviderUnknown diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 26a19ec1b1..346287a065 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -15,7 +15,11 @@ runtime_checkable, ) -import importlib_metadata as metadata +if sys.version_info >= (3, 10): + from importlib import metadata +else: + import importlib_metadata as metadata + from packaging.version import InvalidVersion # noqa: F401: Rexpose the common exception from packaging.version import Version as _BaseVersion diff --git a/poetry.lock b/poetry.lock index 91ce69f45e..e15e2e851c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1784,4 +1784,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "ae23361204d1cc38d6ea93cceaa273548efffef705c09120767bb4e79196181a" +content-hash = "5c50eb89395cfaea68afc05bf419017823990724552f6d6fa25d426122fc9525" diff --git a/pyproject.toml b/pyproject.toml index 090e9ba42b..8ee0cd46aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ argcomplete = ">=1.12.1,<3.5" typing-extensions = { version = "^4.0.1", python = "<3.8" } charset-normalizer = ">=2.1.0,<4" # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility -importlib_metadata = { version = ">=4.13,<8"} +importlib_metadata = { version = ">=4.13,<8", python = "<3.10"} [tool.poetry.group.dev.dependencies] # dev tool diff --git a/tests/test_factory.py b/tests/test_factory.py index 0ac8c0b275..390742f467 100644 --- a/tests/test_factory.py +++ b/tests/test_factory.py @@ -1,7 +1,11 @@ import sys from textwrap import dedent -import importlib_metadata as metadata +if sys.version_info >= (3, 10): + from importlib import metadata +else: + import importlib_metadata as metadata + import pytest from commitizen import BaseCommitizen, defaults, factory diff --git a/tests/test_version_schemes.py b/tests/test_version_schemes.py index 985b371f7b..686c0bfde1 100644 --- a/tests/test_version_schemes.py +++ b/tests/test_version_schemes.py @@ -1,6 +1,12 @@ from __future__ import annotations -import importlib_metadata as metadata +import sys + +if sys.version_info >= (3, 10): + from importlib import metadata +else: + import importlib_metadata as metadata + import pytest from pytest_mock import MockerFixture From 1039b40429774b7f7e302c96e4c6361d6ba8181d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 02:03:27 +0000 Subject: [PATCH 216/598] build(deps): bump importlib-metadata from 7.2.1 to 8.0.0 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 7.2.1 to 8.0.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v7.2.1...v8.0.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index e15e2e851c..c5b5324d5f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -450,13 +450,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.2.1" +version = "8.0.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.2.1-py3-none-any.whl", hash = "sha256:ffef94b0b66046dd8ea2d619b701fe978d9264d38f3998bc4c27ec3b146a87c8"}, - {file = "importlib_metadata-7.2.1.tar.gz", hash = "sha256:509ecb2ab77071db5137c655e24ceb3eee66e7bbc6574165d0d114d9fc4bbe68"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] @@ -1784,4 +1784,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "5c50eb89395cfaea68afc05bf419017823990724552f6d6fa25d426122fc9525" +content-hash = "099b3d500de134efa6a2a2c130f1de534c0a4e9a7e99b7929a8abac7f1f57ee7" diff --git a/pyproject.toml b/pyproject.toml index 8ee0cd46aa..83d3bc532a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ argcomplete = ">=1.12.1,<3.5" typing-extensions = { version = "^4.0.1", python = "<3.8" } charset-normalizer = ">=2.1.0,<4" # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility -importlib_metadata = { version = ">=4.13,<8", python = "<3.10"} +importlib_metadata = { version = ">=8.0.0,<9", python = "<3.10"} [tool.poetry.group.dev.dependencies] # dev tool From 72cc6020a98d76ebf2d68b90b2749a60d0b9f270 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 02:14:36 +0000 Subject: [PATCH 217/598] build(deps-dev): bump ruff from 0.4.10 to 0.5.0 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.10 to 0.5.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.4.10...0.5.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 39 ++++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index c5b5324d5f..9e5ed1cf73 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,28 +1423,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.4.10" +version = "0.5.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c2c4d0859305ac5a16310eec40e4e9a9dec5dcdfbe92697acd99624e8638dac"}, - {file = "ruff-0.4.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a79489607d1495685cdd911a323a35871abfb7a95d4f98fc6f85e799227ac46e"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1dd1681dfa90a41b8376a61af05cc4dc5ff32c8f14f5fe20dba9ff5deb80cd6"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c75c53bb79d71310dc79fb69eb4902fba804a81f374bc86a9b117a8d077a1784"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18238c80ee3d9100d3535d8eb15a59c4a0753b45cc55f8bf38f38d6a597b9739"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d8f71885bce242da344989cae08e263de29752f094233f932d4f5cfb4ef36a81"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:330421543bd3222cdfec481e8ff3460e8702ed1e58b494cf9d9e4bf90db52b9d"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e9b6fb3a37b772628415b00c4fc892f97954275394ed611056a4b8a2631365e"}, - {file = "ruff-0.4.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f54c481b39a762d48f64d97351048e842861c6662d63ec599f67d515cb417f6"}, - {file = "ruff-0.4.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:67fe086b433b965c22de0b4259ddfe6fa541c95bf418499bedb9ad5fb8d1c631"}, - {file = "ruff-0.4.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:acfaaab59543382085f9eb51f8e87bac26bf96b164839955f244d07125a982ef"}, - {file = "ruff-0.4.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3cea07079962b2941244191569cf3a05541477286f5cafea638cd3aa94b56815"}, - {file = "ruff-0.4.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:338a64ef0748f8c3a80d7f05785930f7965d71ca260904a9321d13be24b79695"}, - {file = "ruff-0.4.10-py3-none-win32.whl", hash = "sha256:ffe3cd2f89cb54561c62e5fa20e8f182c0a444934bf430515a4b422f1ab7b7ca"}, - {file = "ruff-0.4.10-py3-none-win_amd64.whl", hash = "sha256:67f67cef43c55ffc8cc59e8e0b97e9e60b4837c8f21e8ab5ffd5d66e196e25f7"}, - {file = "ruff-0.4.10-py3-none-win_arm64.whl", hash = "sha256:dd1fcee327c20addac7916ca4e2653fbbf2e8388d8a6477ce5b4e986b68ae6c0"}, - {file = "ruff-0.4.10.tar.gz", hash = "sha256:3aa4f2bc388a30d346c56524f7cacca85945ba124945fe489952aadb6b5cd804"}, + {file = "ruff-0.5.0-py3-none-linux_armv6l.whl", hash = "sha256:ee770ea8ab38918f34e7560a597cc0a8c9a193aaa01bfbd879ef43cb06bd9c4c"}, + {file = "ruff-0.5.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38f3b8327b3cb43474559d435f5fa65dacf723351c159ed0dc567f7ab735d1b6"}, + {file = "ruff-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7594f8df5404a5c5c8f64b8311169879f6cf42142da644c7e0ba3c3f14130370"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:adc7012d6ec85032bc4e9065110df205752d64010bed5f958d25dbee9ce35de3"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d505fb93b0fabef974b168d9b27c3960714d2ecda24b6ffa6a87ac432905ea38"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dc5cfd3558f14513ed0d5b70ce531e28ea81a8a3b1b07f0f48421a3d9e7d80a"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:db3ca35265de239a1176d56a464b51557fce41095c37d6c406e658cf80bbb362"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1a321c4f68809fddd9b282fab6a8d8db796b270fff44722589a8b946925a2a8"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c4dfcd8d34b143916994b3876b63d53f56724c03f8c1a33a253b7b1e6bf2a7d"}, + {file = "ruff-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81e5facfc9f4a674c6a78c64d38becfbd5e4f739c31fcd9ce44c849f1fad9e4c"}, + {file = "ruff-0.5.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e589e27971c2a3efff3fadafb16e5aef7ff93250f0134ec4b52052b673cf988d"}, + {file = "ruff-0.5.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2ffbc3715a52b037bcb0f6ff524a9367f642cdc5817944f6af5479bbb2eb50e"}, + {file = "ruff-0.5.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cd096e23c6a4f9c819525a437fa0a99d1c67a1b6bb30948d46f33afbc53596cf"}, + {file = "ruff-0.5.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:46e193b36f2255729ad34a49c9a997d506e58f08555366b2108783b3064a0e1e"}, + {file = "ruff-0.5.0-py3-none-win32.whl", hash = "sha256:49141d267100f5ceff541b4e06552e98527870eafa1acc9dec9139c9ec5af64c"}, + {file = "ruff-0.5.0-py3-none-win_amd64.whl", hash = "sha256:e9118f60091047444c1b90952736ee7b1792910cab56e9b9a9ac20af94cd0440"}, + {file = "ruff-0.5.0-py3-none-win_arm64.whl", hash = "sha256:ed5c4df5c1fb4518abcb57725b576659542bdbe93366f4f329e8f398c4b71178"}, + {file = "ruff-0.5.0.tar.gz", hash = "sha256:eb641b5873492cf9bd45bc9c5ae5320648218e04386a5f0c264ad6ccce8226a1"}, ] [[package]] @@ -1784,4 +1785,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "099b3d500de134efa6a2a2c130f1de534c0a4e9a7e99b7929a8abac7f1f57ee7" +content-hash = "dc743cceaf8c8d472ebd6f824feb5955c09b64b24f84d916fc910def5f7637b5" diff --git a/pyproject.toml b/pyproject.toml index 83d3bc532a..4558e42570 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" # linter -ruff = ">=0.1.6,<0.5.0" +ruff = ">=0.5.0,<0.6.0" pre-commit = ">=2.18,<4.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" From 974de65ef67ebe8f0bb32f5fcb1b1cc1a5ce3f8c Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Mon, 1 Jul 2024 09:43:29 +0800 Subject: [PATCH 218/598] test(cli): change type comparison to use is --- tests/test_cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 1c87bc022b..a91e633128 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -88,7 +88,7 @@ def test_commitizen_excepthook(capsys): with pytest.raises(SystemExit) as excinfo: cli.commitizen_excepthook(NotAGitProjectError, NotAGitProjectError(), "") - assert excinfo.type == SystemExit + assert excinfo.type is SystemExit assert excinfo.value.code == NotAGitProjectError.exit_code @@ -101,7 +101,7 @@ def test_commitizen_debug_excepthook(capsys): debug=True, ) - assert excinfo.type == SystemExit + assert excinfo.type is SystemExit assert excinfo.value.code == NotAGitProjectError.exit_code assert "NotAGitProjectError" in str(excinfo.traceback[0]) @@ -132,7 +132,7 @@ def test_commitizen_excepthook_no_raises(capsys): no_raise=[NotAGitProjectError.exit_code], ) - assert excinfo.type == SystemExit + assert excinfo.type is SystemExit assert excinfo.value.code == 0 From d9a83155d8b58e96f91fa7c8740dc9295d352885 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jul 2024 01:16:50 +0000 Subject: [PATCH 219/598] build(deps-dev): bump mkdocs-material from 9.5.27 to 9.5.28 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.27 to 9.5.28. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.27...9.5.28) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9e5ed1cf73..fa5cbb021f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.27" +version = "9.5.28" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.27-py3-none-any.whl", hash = "sha256:af8cc263fafa98bb79e9e15a8c966204abf15164987569bd1175fd66a7705182"}, - {file = "mkdocs_material-9.5.27.tar.gz", hash = "sha256:a7d4a35f6d4a62b0c43a0cfe7e987da0980c13587b5bc3c26e690ad494427ec0"}, + {file = "mkdocs_material-9.5.28-py3-none-any.whl", hash = "sha256:ff48b11b2a9f705dd210409ec3b418ab443dd36d96915bcba45a41f10ea27bfd"}, + {file = "mkdocs_material-9.5.28.tar.gz", hash = "sha256:9cba305283ad1600e3d0a67abe72d7a058b54793b47be39930911a588fe0336b"}, ] [package.dependencies] From 63cd0ebdadf19b6cf51525675274158f876c43e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Jul 2024 02:06:39 +0000 Subject: [PATCH 220/598] build(deps-dev): bump certifi from 2024.2.2 to 2024.7.4 Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.2.2 to 2024.7.4. - [Commits](https://github.com/certifi/python-certifi/compare/2024.02.02...2024.07.04) --- updated-dependencies: - dependency-name: certifi dependency-type: indirect ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index fa5cbb021f..04763e736e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "appnope" @@ -73,13 +73,13 @@ files = [ [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] From 34a96224d0e4f6267db0e5ec16b91d973372652a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:28:40 +0000 Subject: [PATCH 221/598] build(deps-dev): bump zipp from 3.18.2 to 3.19.1 Bumps [zipp](https://github.com/jaraco/zipp) from 3.18.2 to 3.19.1. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.18.2...v3.19.1) --- updated-dependencies: - dependency-name: zipp dependency-type: indirect ... Signed-off-by: dependabot[bot] --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 04763e736e..65d8f40ad7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1769,18 +1769,18 @@ files = [ [[package]] name = "zipp" -version = "3.18.2" +version = "3.19.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.18.2-py3-none-any.whl", hash = "sha256:dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e"}, - {file = "zipp-3.18.2.tar.gz", hash = "sha256:6278d9ddbcfb1f1089a88fde84481528b07b0e10474e09dcfe53dad4069fa059"}, + {file = "zipp-3.19.1-py3-none-any.whl", hash = "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091"}, + {file = "zipp-3.19.1.tar.gz", hash = "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" From dd9e352e33bee0e1e129576f7f48d4da32600b4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 01:55:05 +0000 Subject: [PATCH 222/598] build(deps): bump tomlkit from 0.12.5 to 0.13.0 Bumps [tomlkit](https://github.com/sdispater/tomlkit) from 0.12.5 to 0.13.0. - [Release notes](https://github.com/sdispater/tomlkit/releases) - [Changelog](https://github.com/python-poetry/tomlkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/sdispater/tomlkit/compare/0.12.5...0.13.0) --- updated-dependencies: - dependency-name: tomlkit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 65d8f40ad7..03f038d0fc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1520,13 +1520,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.5" +version = "0.13.0" description = "Style preserving TOML library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, - {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, + {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, + {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, ] [[package]] From 997db8e9d2c71254ea2cc1070306fe3acee8f1cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 01:24:17 +0000 Subject: [PATCH 223/598] build(deps-dev): bump ruff from 0.5.0 to 0.5.1 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.0 to 0.5.1. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.0...0.5.1) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 03f038d0fc..391d35c55b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,29 +1423,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.5.0" +version = "0.5.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.0-py3-none-linux_armv6l.whl", hash = "sha256:ee770ea8ab38918f34e7560a597cc0a8c9a193aaa01bfbd879ef43cb06bd9c4c"}, - {file = "ruff-0.5.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38f3b8327b3cb43474559d435f5fa65dacf723351c159ed0dc567f7ab735d1b6"}, - {file = "ruff-0.5.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7594f8df5404a5c5c8f64b8311169879f6cf42142da644c7e0ba3c3f14130370"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:adc7012d6ec85032bc4e9065110df205752d64010bed5f958d25dbee9ce35de3"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d505fb93b0fabef974b168d9b27c3960714d2ecda24b6ffa6a87ac432905ea38"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dc5cfd3558f14513ed0d5b70ce531e28ea81a8a3b1b07f0f48421a3d9e7d80a"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:db3ca35265de239a1176d56a464b51557fce41095c37d6c406e658cf80bbb362"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b1a321c4f68809fddd9b282fab6a8d8db796b270fff44722589a8b946925a2a8"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c4dfcd8d34b143916994b3876b63d53f56724c03f8c1a33a253b7b1e6bf2a7d"}, - {file = "ruff-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81e5facfc9f4a674c6a78c64d38becfbd5e4f739c31fcd9ce44c849f1fad9e4c"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e589e27971c2a3efff3fadafb16e5aef7ff93250f0134ec4b52052b673cf988d"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2ffbc3715a52b037bcb0f6ff524a9367f642cdc5817944f6af5479bbb2eb50e"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cd096e23c6a4f9c819525a437fa0a99d1c67a1b6bb30948d46f33afbc53596cf"}, - {file = "ruff-0.5.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:46e193b36f2255729ad34a49c9a997d506e58f08555366b2108783b3064a0e1e"}, - {file = "ruff-0.5.0-py3-none-win32.whl", hash = "sha256:49141d267100f5ceff541b4e06552e98527870eafa1acc9dec9139c9ec5af64c"}, - {file = "ruff-0.5.0-py3-none-win_amd64.whl", hash = "sha256:e9118f60091047444c1b90952736ee7b1792910cab56e9b9a9ac20af94cd0440"}, - {file = "ruff-0.5.0-py3-none-win_arm64.whl", hash = "sha256:ed5c4df5c1fb4518abcb57725b576659542bdbe93366f4f329e8f398c4b71178"}, - {file = "ruff-0.5.0.tar.gz", hash = "sha256:eb641b5873492cf9bd45bc9c5ae5320648218e04386a5f0c264ad6ccce8226a1"}, + {file = "ruff-0.5.1-py3-none-linux_armv6l.whl", hash = "sha256:6ecf968fcf94d942d42b700af18ede94b07521bd188aaf2cd7bc898dd8cb63b6"}, + {file = "ruff-0.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:204fb0a472f00f2e6280a7c8c7c066e11e20e23a37557d63045bf27a616ba61c"}, + {file = "ruff-0.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d235968460e8758d1e1297e1de59a38d94102f60cafb4d5382033c324404ee9d"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38beace10b8d5f9b6bdc91619310af6d63dd2019f3fb2d17a2da26360d7962fa"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e478d2f09cf06add143cf8c4540ef77b6599191e0c50ed976582f06e588c994"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0368d765eec8247b8550251c49ebb20554cc4e812f383ff9f5bf0d5d94190b0"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a9a9a1b582e37669b0138b7c1d9d60b9edac880b80eb2baba6d0e566bdeca4d"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd9f723e16003623423affabcc0a807a66552ee6a29f90eddad87a40c750b78"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be9fd62c1e99539da05fcdc1e90d20f74aec1b7a1613463ed77870057cd6bd96"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c4c2112e9883a40967827d5c24803525145e7dab315497fae149764979ac7929"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dfaf11c8a116394da3b65cd4b36de30d8552fa45b8119b9ef5ca6638ab964fa3"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d7ceb9b2fe700ee09a0c6b192c5ef03c56eb82a0514218d8ff700f6ade004108"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bac6288e82f6296f82ed5285f597713acb2a6ae26618ffc6b429c597b392535c"}, + {file = "ruff-0.5.1-py3-none-win32.whl", hash = "sha256:5c441d9c24ec09e1cb190a04535c5379b36b73c4bc20aa180c54812c27d1cca4"}, + {file = "ruff-0.5.1-py3-none-win_amd64.whl", hash = "sha256:b1789bf2cd3d1b5a7d38397cac1398ddf3ad7f73f4de01b1e913e2abc7dfc51d"}, + {file = "ruff-0.5.1-py3-none-win_arm64.whl", hash = "sha256:2875b7596a740cbbd492f32d24be73e545a4ce0a3daf51e4f4e609962bfd3cd2"}, + {file = "ruff-0.5.1.tar.gz", hash = "sha256:3164488aebd89b1745b47fd00604fb4358d774465f20d1fcd907f9c0fc1b0655"}, ] [[package]] From 9a89ae52aaac856e09c9bec82647373998ca19f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 01:23:48 +0000 Subject: [PATCH 224/598] build(deps-dev): bump ruff from 0.5.1 to 0.5.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.1 to 0.5.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.1...0.5.2) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 391d35c55b..a48ffe1471 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,29 +1423,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.5.1" +version = "0.5.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.1-py3-none-linux_armv6l.whl", hash = "sha256:6ecf968fcf94d942d42b700af18ede94b07521bd188aaf2cd7bc898dd8cb63b6"}, - {file = "ruff-0.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:204fb0a472f00f2e6280a7c8c7c066e11e20e23a37557d63045bf27a616ba61c"}, - {file = "ruff-0.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d235968460e8758d1e1297e1de59a38d94102f60cafb4d5382033c324404ee9d"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38beace10b8d5f9b6bdc91619310af6d63dd2019f3fb2d17a2da26360d7962fa"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e478d2f09cf06add143cf8c4540ef77b6599191e0c50ed976582f06e588c994"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0368d765eec8247b8550251c49ebb20554cc4e812f383ff9f5bf0d5d94190b0"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a9a9a1b582e37669b0138b7c1d9d60b9edac880b80eb2baba6d0e566bdeca4d"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd9f723e16003623423affabcc0a807a66552ee6a29f90eddad87a40c750b78"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be9fd62c1e99539da05fcdc1e90d20f74aec1b7a1613463ed77870057cd6bd96"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c4c2112e9883a40967827d5c24803525145e7dab315497fae149764979ac7929"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dfaf11c8a116394da3b65cd4b36de30d8552fa45b8119b9ef5ca6638ab964fa3"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d7ceb9b2fe700ee09a0c6b192c5ef03c56eb82a0514218d8ff700f6ade004108"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bac6288e82f6296f82ed5285f597713acb2a6ae26618ffc6b429c597b392535c"}, - {file = "ruff-0.5.1-py3-none-win32.whl", hash = "sha256:5c441d9c24ec09e1cb190a04535c5379b36b73c4bc20aa180c54812c27d1cca4"}, - {file = "ruff-0.5.1-py3-none-win_amd64.whl", hash = "sha256:b1789bf2cd3d1b5a7d38397cac1398ddf3ad7f73f4de01b1e913e2abc7dfc51d"}, - {file = "ruff-0.5.1-py3-none-win_arm64.whl", hash = "sha256:2875b7596a740cbbd492f32d24be73e545a4ce0a3daf51e4f4e609962bfd3cd2"}, - {file = "ruff-0.5.1.tar.gz", hash = "sha256:3164488aebd89b1745b47fd00604fb4358d774465f20d1fcd907f9c0fc1b0655"}, + {file = "ruff-0.5.2-py3-none-linux_armv6l.whl", hash = "sha256:7bab8345df60f9368d5f4594bfb8b71157496b44c30ff035d1d01972e764d3be"}, + {file = "ruff-0.5.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1aa7acad382ada0189dbe76095cf0a36cd0036779607c397ffdea16517f535b1"}, + {file = "ruff-0.5.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:aec618d5a0cdba5592c60c2dee7d9c865180627f1a4a691257dea14ac1aa264d"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b62adc5ce81780ff04077e88bac0986363e4a3260ad3ef11ae9c14aa0e67ef"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc42ebf56ede83cb080a50eba35a06e636775649a1ffd03dc986533f878702a3"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15c6e9f88c67ffa442681365d11df38afb11059fc44238e71a9d9f1fd51de70"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d3de9a5960f72c335ef00763d861fc5005ef0644cb260ba1b5a115a102157251"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe5a968ae933e8f7627a7b2fc8893336ac2be0eb0aace762d3421f6e8f7b7f83"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a04f54a9018f75615ae52f36ea1c5515e356e5d5e214b22609ddb546baef7132"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed02fb52e3741f0738db5f93e10ae0fb5c71eb33a4f2ba87c9a2fa97462a649"}, + {file = "ruff-0.5.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3cf8fe659f6362530435d97d738eb413e9f090e7e993f88711b0377fbdc99f60"}, + {file = "ruff-0.5.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:237a37e673e9f3cbfff0d2243e797c4862a44c93d2f52a52021c1a1b0899f846"}, + {file = "ruff-0.5.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2a2949ce7c1cbd8317432ada80fe32156df825b2fd611688814c8557824ef060"}, + {file = "ruff-0.5.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:481af57c8e99da92ad168924fd82220266043c8255942a1cb87958b108ac9335"}, + {file = "ruff-0.5.2-py3-none-win32.whl", hash = "sha256:f1aea290c56d913e363066d83d3fc26848814a1fed3d72144ff9c930e8c7c718"}, + {file = "ruff-0.5.2-py3-none-win_amd64.whl", hash = "sha256:8532660b72b5d94d2a0a7a27ae7b9b40053662d00357bb2a6864dd7e38819084"}, + {file = "ruff-0.5.2-py3-none-win_arm64.whl", hash = "sha256:73439805c5cb68f364d826a5c5c4b6c798ded6b7ebaa4011f01ce6c94e4d5583"}, + {file = "ruff-0.5.2.tar.gz", hash = "sha256:2c0df2d2de685433794a14d8d2e240df619b748fbe3367346baa519d8e6f1ca2"}, ] [[package]] From 458345eb2ff0f48e5f7bfac008a729978ebf1e17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 01:24:09 +0000 Subject: [PATCH 225/598] build(deps-dev): bump mkdocs-material from 9.5.28 to 9.5.29 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.28 to 9.5.29. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.28...9.5.29) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index a48ffe1471..384d060b63 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.28" +version = "9.5.29" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.28-py3-none-any.whl", hash = "sha256:ff48b11b2a9f705dd210409ec3b418ab443dd36d96915bcba45a41f10ea27bfd"}, - {file = "mkdocs_material-9.5.28.tar.gz", hash = "sha256:9cba305283ad1600e3d0a67abe72d7a058b54793b47be39930911a588fe0336b"}, + {file = "mkdocs_material-9.5.29-py3-none-any.whl", hash = "sha256:afc1f508e2662ded95f0a35a329e8a5acd73ee88ca07ba73836eb6fcdae5d8b4"}, + {file = "mkdocs_material-9.5.29.tar.gz", hash = "sha256:3e977598ec15a4ddad5c4dfc9e08edab6023edb51e88f0729bd27be77e3d322a"}, ] [package.dependencies] From be744f9688e562148b9107f53727eb147ab37fef Mon Sep 17 00:00:00 2001 From: Jakob Widauer Date: Wed, 10 Jul 2024 00:33:37 +0200 Subject: [PATCH 226/598] feat: add argument to limit length of commit message in checks --- commitizen/cli.py | 6 +++++ commitizen/commands/check.py | 5 ++++ docs/commands/check.md | 10 ++++++++ tests/commands/test_check_command.py | 25 +++++++++++++++++++ ...shows_description_when_use_help_option.txt | 3 +++ 5 files changed, 49 insertions(+) diff --git a/commitizen/cli.py b/commitizen/cli.py index 1d1ebe1f68..00be6daf15 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -466,6 +466,12 @@ def __call__( "If the message starts by one of these prefixes, " "the message won't be checked against the regex", }, + { + "name": ["-l", "--message-length-limit"], + "type": int, + "default": 0, + "help": "length limit of the commit message; 0 for no limit", + }, ], }, { diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index 6e98f8cb3f..13b8555b6d 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -31,6 +31,7 @@ def __init__(self, config: BaseConfig, arguments: dict[str, Any], cwd=os.getcwd( self.allow_abort: bool = bool( arguments.get("allow_abort", config.settings["allow_abort"]) ) + self.max_msg_length: int = arguments.get("message_length_limit", 0) # we need to distinguish between None and [], which is a valid value @@ -145,4 +146,8 @@ def validate_commit_message(self, commit_msg: str, pattern: str) -> bool: if any(map(commit_msg.startswith, self.allowed_prefixes)): return True + if self.max_msg_length: + msg_len = len(commit_msg.partition("\n")[0].strip()) + if msg_len > self.max_msg_length: + return False return bool(re.match(pattern, commit_msg)) diff --git a/docs/commands/check.md b/docs/commands/check.md index c31fd085ee..751a47aa2f 100644 --- a/docs/commands/check.md +++ b/docs/commands/check.md @@ -75,3 +75,13 @@ By default, the the following prefixes are allowed: `Merge`, `Revert`, `Pull Req ```bash cz check --message MESSAGE --allowed-prefixes 'Merge' 'Revert' 'Custom Prefix' ``` + +### Commit message length limit + +The argument `-l` (or `--message-length-limmit`) followed by a positive number, can limit the length of commit messages. +For example, `cz check --message MESSAGE -l 3` would fail the check, since `MESSAGE` is more than 3 characters long. +By default, the limit is set to 0, which means no limit on the length. + +**Note that the limit applies only to the first line of the message.*** +Specifically, for `ConventionalCommitsCz` the length only counts from the type of change to the subject, +while the body, and the footer are not counted. diff --git a/tests/commands/test_check_command.py b/tests/commands/test_check_command.py index 47bdafd651..328ebd78a9 100644 --- a/tests/commands/test_check_command.py +++ b/tests/commands/test_check_command.py @@ -427,3 +427,28 @@ def test_check_command_shows_description_when_use_help_option( out, _ = capsys.readouterr() file_regression.check(out, extension=".txt") + + +def test_check_command_with_message_length_limit(config, mocker: MockFixture): + success_mock = mocker.patch("commitizen.out.success") + message = "fix(scope): some commit message" + check_cmd = commands.Check( + config=config, + arguments={"message": message, "message_length_limit": len(message) + 1}, + ) + + check_cmd() + success_mock.assert_called_once() + + +def test_check_command_with_message_length_limit_exceeded(config, mocker: MockFixture): + error_mock = mocker.patch("commitizen.out.error") + message = "fix(scope): some commit message" + check_cmd = commands.Check( + config=config, + arguments={"message": message, "message_length_limit": len(message) - 1}, + ) + + with pytest.raises(InvalidCommitMessageError): + check_cmd() + error_mock.assert_called_once() diff --git a/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt b/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt index 56e42388dc..74b9df7196 100644 --- a/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt @@ -1,6 +1,7 @@ usage: cz check [-h] [--commit-msg-file COMMIT_MSG_FILE | --rev-range REV_RANGE | -m MESSAGE] [--allow-abort] [--allowed-prefixes [ALLOWED_PREFIXES ...]] + [-l MESSAGE_LENGTH_LIMIT] validates that a commit message matches the commitizen schema @@ -20,3 +21,5 @@ options: allowed commit message prefixes. If the message starts by one of these prefixes, the message won't be checked against the regex + -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT + length limit of the commit message; 0 for no limit From 545f14348514ac1adf3d84d46755ef56f082756b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 17 Jul 2024 13:48:59 +0000 Subject: [PATCH 227/598] =?UTF-8?q?bump:=20version=203.27.0=20=E2=86=92=20?= =?UTF-8?q?3.28.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d0149b5fae..8d0cf55529 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v3.27.0 # automatically updated by Commitizen + rev: v3.28.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index c3a3ecc5e1..5ec2dd2d8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.28.0 (2024-07-17) + +### Feat + +- add argument to limit length of commit message in checks + ## v3.27.0 (2024-05-22) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 62bfee6c53..87dca02966 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.27.0" +__version__ = "3.28.0" diff --git a/pyproject.toml b/pyproject.toml index 4558e42570..643fb17d2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.27.0" +version = "3.28.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.27.0" +version = "3.28.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 1f1e30f90056c181941ee100d82ee52457aa6edf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 17 Jul 2024 13:49:35 +0000 Subject: [PATCH 228/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz_check___help.svg | 134 ++++++++++++----------- 1 file changed, 73 insertions(+), 61 deletions(-) diff --git a/docs/images/cli_help/cz_check___help.svg b/docs/images/cli_help/cz_check___help.svg index df1af46637..922a6458a6 100644 --- a/docs/images/cli_help/cz_check___help.svg +++ b/docs/images/cli_help/cz_check___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + - + - + - - $ 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 ...]] - -validates that a commit message matches the commitizen schema - -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 - + + $ 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 ...]] +[-l MESSAGE_LENGTH_LIMIT] + +validates that a commit message matches the commitizen schema + +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 +  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit + From 8f2f4e094af092277377c8b8890bbc6d9fa01e39 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jul 2024 01:29:58 +0000 Subject: [PATCH 229/598] build(deps-dev): bump ruff from 0.5.2 to 0.5.3 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.2 to 0.5.3. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.2...0.5.3) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 384d060b63..1153cedfd3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,29 +1423,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.5.2" +version = "0.5.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.2-py3-none-linux_armv6l.whl", hash = "sha256:7bab8345df60f9368d5f4594bfb8b71157496b44c30ff035d1d01972e764d3be"}, - {file = "ruff-0.5.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1aa7acad382ada0189dbe76095cf0a36cd0036779607c397ffdea16517f535b1"}, - {file = "ruff-0.5.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:aec618d5a0cdba5592c60c2dee7d9c865180627f1a4a691257dea14ac1aa264d"}, - {file = "ruff-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b62adc5ce81780ff04077e88bac0986363e4a3260ad3ef11ae9c14aa0e67ef"}, - {file = "ruff-0.5.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc42ebf56ede83cb080a50eba35a06e636775649a1ffd03dc986533f878702a3"}, - {file = "ruff-0.5.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15c6e9f88c67ffa442681365d11df38afb11059fc44238e71a9d9f1fd51de70"}, - {file = "ruff-0.5.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d3de9a5960f72c335ef00763d861fc5005ef0644cb260ba1b5a115a102157251"}, - {file = "ruff-0.5.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe5a968ae933e8f7627a7b2fc8893336ac2be0eb0aace762d3421f6e8f7b7f83"}, - {file = "ruff-0.5.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a04f54a9018f75615ae52f36ea1c5515e356e5d5e214b22609ddb546baef7132"}, - {file = "ruff-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed02fb52e3741f0738db5f93e10ae0fb5c71eb33a4f2ba87c9a2fa97462a649"}, - {file = "ruff-0.5.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3cf8fe659f6362530435d97d738eb413e9f090e7e993f88711b0377fbdc99f60"}, - {file = "ruff-0.5.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:237a37e673e9f3cbfff0d2243e797c4862a44c93d2f52a52021c1a1b0899f846"}, - {file = "ruff-0.5.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2a2949ce7c1cbd8317432ada80fe32156df825b2fd611688814c8557824ef060"}, - {file = "ruff-0.5.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:481af57c8e99da92ad168924fd82220266043c8255942a1cb87958b108ac9335"}, - {file = "ruff-0.5.2-py3-none-win32.whl", hash = "sha256:f1aea290c56d913e363066d83d3fc26848814a1fed3d72144ff9c930e8c7c718"}, - {file = "ruff-0.5.2-py3-none-win_amd64.whl", hash = "sha256:8532660b72b5d94d2a0a7a27ae7b9b40053662d00357bb2a6864dd7e38819084"}, - {file = "ruff-0.5.2-py3-none-win_arm64.whl", hash = "sha256:73439805c5cb68f364d826a5c5c4b6c798ded6b7ebaa4011f01ce6c94e4d5583"}, - {file = "ruff-0.5.2.tar.gz", hash = "sha256:2c0df2d2de685433794a14d8d2e240df619b748fbe3367346baa519d8e6f1ca2"}, + {file = "ruff-0.5.3-py3-none-linux_armv6l.whl", hash = "sha256:b12424d9db7347fa63c5ed9af010003338c63c629fb9c9c6adb2aa4f5699729b"}, + {file = "ruff-0.5.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8d72c5684bbd4ed304a9a955ee2e67f57b35f6193222ade910cca8a805490e3"}, + {file = "ruff-0.5.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d2fc2cdb85ccac1e816cc9d5d8cedefd93661bd957756d902543af32a6b04a71"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf4bc751240b2fab5d19254571bcacb315c7b0b00bf3c912d52226a82bbec073"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc697ec874fdd7c7ba0a85ec76ab38f8595224868d67f097c5ffc21136e72fcd"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e791d34d3557a3819b3704bc1f087293c821083fa206812842fa363f6018a192"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:76bb5a87fd397520b91a83eae8a2f7985236d42dd9459f09eef58e7f5c1d8316"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8cfc7a26422c78e94f1ec78ec02501bbad2df5834907e75afe474cc6b83a8c1"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96066c4328a49fce2dd40e80f7117987369feec30ab771516cf95f1cc2db923c"}, + {file = "ruff-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03bfe9ab5bdc0b08470c3b261643ad54ea86edc32b64d1e080892d7953add3ad"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7704582a026fa02cca83efd76671a98ee6eb412c4230209efe5e2a006c06db62"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:08058d077e21b856d32ebf483443390e29dc44d927608dc8f092ff6776519da9"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:77d49484429ed7c7e6e2e75a753f153b7b58f875bdb4158ad85af166a1ec1822"}, + {file = "ruff-0.5.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:642cbff6cbfa38d2566d8db086508d6f472edb136cbfcc4ea65997745368c29e"}, + {file = "ruff-0.5.3-py3-none-win32.whl", hash = "sha256:eafc45dd8bdc37a00b28e68cc038daf3ca8c233d73fea276dcd09defb1352841"}, + {file = "ruff-0.5.3-py3-none-win_amd64.whl", hash = "sha256:cbaec2ddf4f78e5e9ecf5456ea0f496991358a1d883862ed0b9e947e2b6aea93"}, + {file = "ruff-0.5.3-py3-none-win_arm64.whl", hash = "sha256:05fbd2cb404775d6cd7f2ff49504e2d20e13ef95fa203bd1ab22413af70d420b"}, + {file = "ruff-0.5.3.tar.gz", hash = "sha256:2a3eb4f1841771fa5b67a56be9c2d16fd3cc88e378bd86aaeaec2f7e6bcdd0a2"}, ] [[package]] From 2212a30753d7db47ea9bbf8abea03a5882632e34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 01:58:12 +0000 Subject: [PATCH 230/598] build(deps-dev): bump pytest from 8.2.2 to 8.3.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.2 to 8.3.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.2.2...8.3.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1153cedfd3..f274910486 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1054,13 +1054,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.2.2" +version = "8.3.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, - {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, + {file = "pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c"}, + {file = "pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6"}, ] [package.dependencies] @@ -1068,7 +1068,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.5,<2.0" +pluggy = ">=1.5,<2" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] From 1f89fce78c9720aa25210873851f047d63678476 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 01:59:30 +0000 Subject: [PATCH 231/598] build(deps-dev): bump mypy from 1.10.1 to 1.11.0 Bumps [mypy](https://github.com/python/mypy) from 1.10.1 to 1.11.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.10.1...v1.11) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/poetry.lock b/poetry.lock index f274910486..38ef5928b0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -790,44 +790,44 @@ files = [ [[package]] name = "mypy" -version = "1.10.1" +version = "1.11.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, - {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, - {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, - {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, - {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, - {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, - {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, - {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, - {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, - {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, - {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, - {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, - {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, - {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, - {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, - {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, - {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, - {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, - {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, - {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, - {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, - {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, - {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, - {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, - {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, - {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, - {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, + {file = "mypy-1.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3824187c99b893f90c845bab405a585d1ced4ff55421fdf5c84cb7710995229"}, + {file = "mypy-1.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96f8dbc2c85046c81bcddc246232d500ad729cb720da4e20fce3b542cab91287"}, + {file = "mypy-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a5d8d8dd8613a3e2be3eae829ee891b6b2de6302f24766ff06cb2875f5be9c6"}, + {file = "mypy-1.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72596a79bbfb195fd41405cffa18210af3811beb91ff946dbcb7368240eed6be"}, + {file = "mypy-1.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:35ce88b8ed3a759634cb4eb646d002c4cef0a38f20565ee82b5023558eb90c00"}, + {file = "mypy-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98790025861cb2c3db8c2f5ad10fc8c336ed2a55f4daf1b8b3f877826b6ff2eb"}, + {file = "mypy-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25bcfa75b9b5a5f8d67147a54ea97ed63a653995a82798221cca2a315c0238c1"}, + {file = "mypy-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bea2a0e71c2a375c9fa0ede3d98324214d67b3cbbfcbd55ac8f750f85a414e3"}, + {file = "mypy-1.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2b3d36baac48e40e3064d2901f2fbd2a2d6880ec6ce6358825c85031d7c0d4d"}, + {file = "mypy-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8e2e43977f0e09f149ea69fd0556623919f816764e26d74da0c8a7b48f3e18a"}, + {file = "mypy-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d44c1e44a8be986b54b09f15f2c1a66368eb43861b4e82573026e04c48a9e20"}, + {file = "mypy-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cea3d0fb69637944dd321f41bc896e11d0fb0b0aa531d887a6da70f6e7473aba"}, + {file = "mypy-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a83ec98ae12d51c252be61521aa5731f5512231d0b738b4cb2498344f0b840cd"}, + {file = "mypy-1.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7b73a856522417beb78e0fb6d33ef89474e7a622db2653bc1285af36e2e3e3d"}, + {file = "mypy-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2268d9fcd9686b61ab64f077be7ffbc6fbcdfb4103e5dd0cc5eaab53a8886c2"}, + {file = "mypy-1.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:940bfff7283c267ae6522ef926a7887305945f716a7704d3344d6d07f02df850"}, + {file = "mypy-1.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:14f9294528b5f5cf96c721f231c9f5b2733164e02c1c018ed1a0eff8a18005ac"}, + {file = "mypy-1.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7b54c27783991399046837df5c7c9d325d921394757d09dbcbf96aee4649fe9"}, + {file = "mypy-1.11.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65f190a6349dec29c8d1a1cd4aa71284177aee5949e0502e6379b42873eddbe7"}, + {file = "mypy-1.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbe286303241fea8c2ea5466f6e0e6a046a135a7e7609167b07fd4e7baf151bf"}, + {file = "mypy-1.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:104e9c1620c2675420abd1f6c44bab7dd33cc85aea751c985006e83dcd001095"}, + {file = "mypy-1.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f006e955718ecd8d159cee9932b64fba8f86ee6f7728ca3ac66c3a54b0062abe"}, + {file = "mypy-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:becc9111ca572b04e7e77131bc708480cc88a911adf3d0239f974c034b78085c"}, + {file = "mypy-1.11.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6801319fe76c3f3a3833f2b5af7bd2c17bb93c00026a2a1b924e6762f5b19e13"}, + {file = "mypy-1.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1a184c64521dc549324ec6ef7cbaa6b351912be9cb5edb803c2808a0d7e85ac"}, + {file = "mypy-1.11.0-py3-none-any.whl", hash = "sha256:56913ec8c7638b0091ef4da6fcc9136896914a9d60d54670a75880c3e5b99ace"}, + {file = "mypy-1.11.0.tar.gz", hash = "sha256:93743608c7348772fdc717af4aeee1997293a1ad04bc0ea6efa15bf65385c538"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.1.0" +typing-extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] From a3903fb8b7b1b159a88a4b1b3fe9e0e32ed32a0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 01:58:39 +0000 Subject: [PATCH 232/598] build(deps-dev): bump ruff from 0.5.3 to 0.5.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.3 to 0.5.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.3...0.5.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 38ef5928b0..a75844b727 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,29 +1423,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.5.3" +version = "0.5.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.3-py3-none-linux_armv6l.whl", hash = "sha256:b12424d9db7347fa63c5ed9af010003338c63c629fb9c9c6adb2aa4f5699729b"}, - {file = "ruff-0.5.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8d72c5684bbd4ed304a9a955ee2e67f57b35f6193222ade910cca8a805490e3"}, - {file = "ruff-0.5.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d2fc2cdb85ccac1e816cc9d5d8cedefd93661bd957756d902543af32a6b04a71"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf4bc751240b2fab5d19254571bcacb315c7b0b00bf3c912d52226a82bbec073"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc697ec874fdd7c7ba0a85ec76ab38f8595224868d67f097c5ffc21136e72fcd"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e791d34d3557a3819b3704bc1f087293c821083fa206812842fa363f6018a192"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:76bb5a87fd397520b91a83eae8a2f7985236d42dd9459f09eef58e7f5c1d8316"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8cfc7a26422c78e94f1ec78ec02501bbad2df5834907e75afe474cc6b83a8c1"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96066c4328a49fce2dd40e80f7117987369feec30ab771516cf95f1cc2db923c"}, - {file = "ruff-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03bfe9ab5bdc0b08470c3b261643ad54ea86edc32b64d1e080892d7953add3ad"}, - {file = "ruff-0.5.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7704582a026fa02cca83efd76671a98ee6eb412c4230209efe5e2a006c06db62"}, - {file = "ruff-0.5.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:08058d077e21b856d32ebf483443390e29dc44d927608dc8f092ff6776519da9"}, - {file = "ruff-0.5.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:77d49484429ed7c7e6e2e75a753f153b7b58f875bdb4158ad85af166a1ec1822"}, - {file = "ruff-0.5.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:642cbff6cbfa38d2566d8db086508d6f472edb136cbfcc4ea65997745368c29e"}, - {file = "ruff-0.5.3-py3-none-win32.whl", hash = "sha256:eafc45dd8bdc37a00b28e68cc038daf3ca8c233d73fea276dcd09defb1352841"}, - {file = "ruff-0.5.3-py3-none-win_amd64.whl", hash = "sha256:cbaec2ddf4f78e5e9ecf5456ea0f496991358a1d883862ed0b9e947e2b6aea93"}, - {file = "ruff-0.5.3-py3-none-win_arm64.whl", hash = "sha256:05fbd2cb404775d6cd7f2ff49504e2d20e13ef95fa203bd1ab22413af70d420b"}, - {file = "ruff-0.5.3.tar.gz", hash = "sha256:2a3eb4f1841771fa5b67a56be9c2d16fd3cc88e378bd86aaeaec2f7e6bcdd0a2"}, + {file = "ruff-0.5.4-py3-none-linux_armv6l.whl", hash = "sha256:82acef724fc639699b4d3177ed5cc14c2a5aacd92edd578a9e846d5b5ec18ddf"}, + {file = "ruff-0.5.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:da62e87637c8838b325e65beee485f71eb36202ce8e3cdbc24b9fcb8b99a37be"}, + {file = "ruff-0.5.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e98ad088edfe2f3b85a925ee96da652028f093d6b9b56b76fc242d8abb8e2059"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c55efbecc3152d614cfe6c2247a3054cfe358cefbf794f8c79c8575456efe19"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9b85eaa1f653abd0a70603b8b7008d9e00c9fa1bbd0bf40dad3f0c0bdd06793"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0cf497a47751be8c883059c4613ba2f50dd06ec672692de2811f039432875278"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:09c14ed6a72af9ccc8d2e313d7acf7037f0faff43cde4b507e66f14e812e37f7"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:628f6b8f97b8bad2490240aa84f3e68f390e13fabc9af5c0d3b96b485921cd60"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3520a00c0563d7a7a7c324ad7e2cde2355733dafa9592c671fb2e9e3cd8194c1"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93789f14ca2244fb91ed481456f6d0bb8af1f75a330e133b67d08f06ad85b516"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:029454e2824eafa25b9df46882f7f7844d36fd8ce51c1b7f6d97e2615a57bbcc"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9492320eed573a13a0bc09a2957f17aa733fff9ce5bf00e66e6d4a88ec33813f"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6e1f62a92c645e2919b65c02e79d1f61e78a58eddaebca6c23659e7c7cb4ac7"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768fa9208df2bec4b2ce61dbc7c2ddd6b1be9fb48f1f8d3b78b3332c7d71c1ff"}, + {file = "ruff-0.5.4-py3-none-win32.whl", hash = "sha256:e1e7393e9c56128e870b233c82ceb42164966f25b30f68acbb24ed69ce9c3a4e"}, + {file = "ruff-0.5.4-py3-none-win_amd64.whl", hash = "sha256:58b54459221fd3f661a7329f177f091eb35cf7a603f01d9eb3eb11cc348d38c4"}, + {file = "ruff-0.5.4-py3-none-win_arm64.whl", hash = "sha256:bd53da65f1085fb5b307c38fd3c0829e76acf7b2a912d8d79cadcdb4875c1eb7"}, + {file = "ruff-0.5.4.tar.gz", hash = "sha256:2795726d5f71c4f4e70653273d1c23a8182f07dd8e48c12de5d867bfb7557eed"}, ] [[package]] From 185b27806f7506500539572df3ea820dc27ea900 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 02:02:13 +0000 Subject: [PATCH 233/598] build(deps-dev): bump mkdocs-material from 9.5.29 to 9.5.30 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.29 to 9.5.30. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.29...9.5.30) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index a75844b727..abaeaf4f01 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.29" +version = "9.5.30" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.29-py3-none-any.whl", hash = "sha256:afc1f508e2662ded95f0a35a329e8a5acd73ee88ca07ba73836eb6fcdae5d8b4"}, - {file = "mkdocs_material-9.5.29.tar.gz", hash = "sha256:3e977598ec15a4ddad5c4dfc9e08edab6023edb51e88f0729bd27be77e3d322a"}, + {file = "mkdocs_material-9.5.30-py3-none-any.whl", hash = "sha256:fc070689c5250a180e9b9d79d8491ef9a3a7acb240db0728728d6c31eeb131d4"}, + {file = "mkdocs_material-9.5.30.tar.gz", hash = "sha256:3fd417dd42d679e3ba08b9e2d72cd8b8af142cc4a3969676ad6b00993dd182ec"}, ] [package.dependencies] From ba5a19992b49a1055d82ed479c9e87facabaf2ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 02:02:36 +0000 Subject: [PATCH 234/598] build(deps): bump importlib-metadata from 8.0.0 to 8.1.0 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 8.0.0 to 8.1.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v8.0.0...v8.1.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index abaeaf4f01..ccf35f3b48 100644 --- a/poetry.lock +++ b/poetry.lock @@ -450,13 +450,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "8.0.0" +version = "8.1.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, - {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, + {file = "importlib_metadata-8.1.0-py3-none-any.whl", hash = "sha256:3cd29f739ed65973840b068e3132135ce954c254d48b5b640484467ef7ab3c8c"}, + {file = "importlib_metadata-8.1.0.tar.gz", hash = "sha256:fcdcb1d5ead7bdf3dd32657bb94ebe9d2aabfe89a19782ddc32da5041d6ebfb4"}, ] [package.dependencies] From c858803e95a5872559979caea1d97ecc76110cbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jul 2024 01:15:50 +0000 Subject: [PATCH 235/598] build(deps-dev): bump types-pyyaml Bumps [types-pyyaml](https://github.com/python/typeshed) from 6.0.12.20240311 to 6.0.12.20240724. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-pyyaml dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index ccf35f3b48..544fecb492 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1568,13 +1568,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.20240311" +version = "6.0.12.20240724" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.20240311.tar.gz", hash = "sha256:a9e0f0f88dc835739b0c1ca51ee90d04ca2a897a71af79de9aec5f38cb0a5342"}, - {file = "types_PyYAML-6.0.12.20240311-py3-none-any.whl", hash = "sha256:b845b06a1c7e54b8e5b4c683043de0d9caf205e7434b3edc678ff2411979b8f6"}, + {file = "types-PyYAML-6.0.12.20240724.tar.gz", hash = "sha256:cf7b31ae67e0c5b2919c703d2affc415485099d3fe6666a6912f040fd05cb67f"}, + {file = "types_PyYAML-6.0.12.20240724-py3-none-any.whl", hash = "sha256:e5becec598f3aa3a2ddf671de4a75fa1c6856fbf73b2840286c9d50fae2d5d48"}, ] [[package]] From e9458b954b8013eae9374107656424bfb97f5b8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jul 2024 01:15:07 +0000 Subject: [PATCH 236/598] build(deps): bump importlib-metadata from 8.1.0 to 8.2.0 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 8.1.0 to 8.2.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v8.1.0...v8.2.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 544fecb492..0073624b02 100644 --- a/poetry.lock +++ b/poetry.lock @@ -450,13 +450,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "8.1.0" +version = "8.2.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.1.0-py3-none-any.whl", hash = "sha256:3cd29f739ed65973840b068e3132135ce954c254d48b5b640484467ef7ab3c8c"}, - {file = "importlib_metadata-8.1.0.tar.gz", hash = "sha256:fcdcb1d5ead7bdf3dd32657bb94ebe9d2aabfe89a19782ddc32da5041d6ebfb4"}, + {file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"}, + {file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"}, ] [package.dependencies] From f32093a7b6a5c29f911bd88ddb3defeb9b081a0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 02:01:23 +0000 Subject: [PATCH 237/598] build(deps-dev): bump ruff from 0.5.4 to 0.5.5 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.4 to 0.5.5. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.4...0.5.5) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0073624b02..cf8d4735e0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,29 +1423,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.5.4" +version = "0.5.5" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.4-py3-none-linux_armv6l.whl", hash = "sha256:82acef724fc639699b4d3177ed5cc14c2a5aacd92edd578a9e846d5b5ec18ddf"}, - {file = "ruff-0.5.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:da62e87637c8838b325e65beee485f71eb36202ce8e3cdbc24b9fcb8b99a37be"}, - {file = "ruff-0.5.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e98ad088edfe2f3b85a925ee96da652028f093d6b9b56b76fc242d8abb8e2059"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c55efbecc3152d614cfe6c2247a3054cfe358cefbf794f8c79c8575456efe19"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9b85eaa1f653abd0a70603b8b7008d9e00c9fa1bbd0bf40dad3f0c0bdd06793"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0cf497a47751be8c883059c4613ba2f50dd06ec672692de2811f039432875278"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:09c14ed6a72af9ccc8d2e313d7acf7037f0faff43cde4b507e66f14e812e37f7"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:628f6b8f97b8bad2490240aa84f3e68f390e13fabc9af5c0d3b96b485921cd60"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3520a00c0563d7a7a7c324ad7e2cde2355733dafa9592c671fb2e9e3cd8194c1"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93789f14ca2244fb91ed481456f6d0bb8af1f75a330e133b67d08f06ad85b516"}, - {file = "ruff-0.5.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:029454e2824eafa25b9df46882f7f7844d36fd8ce51c1b7f6d97e2615a57bbcc"}, - {file = "ruff-0.5.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9492320eed573a13a0bc09a2957f17aa733fff9ce5bf00e66e6d4a88ec33813f"}, - {file = "ruff-0.5.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6e1f62a92c645e2919b65c02e79d1f61e78a58eddaebca6c23659e7c7cb4ac7"}, - {file = "ruff-0.5.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768fa9208df2bec4b2ce61dbc7c2ddd6b1be9fb48f1f8d3b78b3332c7d71c1ff"}, - {file = "ruff-0.5.4-py3-none-win32.whl", hash = "sha256:e1e7393e9c56128e870b233c82ceb42164966f25b30f68acbb24ed69ce9c3a4e"}, - {file = "ruff-0.5.4-py3-none-win_amd64.whl", hash = "sha256:58b54459221fd3f661a7329f177f091eb35cf7a603f01d9eb3eb11cc348d38c4"}, - {file = "ruff-0.5.4-py3-none-win_arm64.whl", hash = "sha256:bd53da65f1085fb5b307c38fd3c0829e76acf7b2a912d8d79cadcdb4875c1eb7"}, - {file = "ruff-0.5.4.tar.gz", hash = "sha256:2795726d5f71c4f4e70653273d1c23a8182f07dd8e48c12de5d867bfb7557eed"}, + {file = "ruff-0.5.5-py3-none-linux_armv6l.whl", hash = "sha256:605d589ec35d1da9213a9d4d7e7a9c761d90bba78fc8790d1c5e65026c1b9eaf"}, + {file = "ruff-0.5.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00817603822a3e42b80f7c3298c8269e09f889ee94640cd1fc7f9329788d7bf8"}, + {file = "ruff-0.5.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:187a60f555e9f865a2ff2c6984b9afeffa7158ba6e1eab56cb830404c942b0f3"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe26fc46fa8c6e0ae3f47ddccfbb136253c831c3289bba044befe68f467bfb16"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad25dd9c5faac95c8e9efb13e15803cd8bbf7f4600645a60ffe17c73f60779b"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f70737c157d7edf749bcb952d13854e8f745cec695a01bdc6e29c29c288fc36e"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:cfd7de17cef6ab559e9f5ab859f0d3296393bc78f69030967ca4d87a541b97a0"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a09b43e02f76ac0145f86a08e045e2ea452066f7ba064fd6b0cdccb486f7c3e7"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0b856cb19c60cd40198be5d8d4b556228e3dcd545b4f423d1ad812bfdca5884"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3687d002f911e8a5faf977e619a034d159a8373514a587249cc00f211c67a091"}, + {file = "ruff-0.5.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ac9dc814e510436e30d0ba535f435a7f3dc97f895f844f5b3f347ec8c228a523"}, + {file = "ruff-0.5.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:af9bdf6c389b5add40d89b201425b531e0a5cceb3cfdcc69f04d3d531c6be74f"}, + {file = "ruff-0.5.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d40a8533ed545390ef8315b8e25c4bb85739b90bd0f3fe1280a29ae364cc55d8"}, + {file = "ruff-0.5.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cab904683bf9e2ecbbe9ff235bfe056f0eba754d0168ad5407832928d579e7ab"}, + {file = "ruff-0.5.5-py3-none-win32.whl", hash = "sha256:696f18463b47a94575db635ebb4c178188645636f05e934fdf361b74edf1bb2d"}, + {file = "ruff-0.5.5-py3-none-win_amd64.whl", hash = "sha256:50f36d77f52d4c9c2f1361ccbfbd09099a1b2ea5d2b2222c586ab08885cf3445"}, + {file = "ruff-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3191317d967af701f1b73a31ed5788795936e423b7acce82a2b63e26eb3e89d6"}, + {file = "ruff-0.5.5.tar.gz", hash = "sha256:cc5516bdb4858d972fbc31d246bdb390eab8df1a26e2353be2dbc0c2d7f5421a"}, ] [[package]] From 6f7ed3817ec686e82df0f01df6e74bdb4cfa062e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 02:01:45 +0000 Subject: [PATCH 238/598] build(deps-dev): bump pytest from 8.3.1 to 8.3.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.1 to 8.3.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.1...8.3.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index cf8d4735e0..f8525e3f38 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1054,13 +1054,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.3.1" +version = "8.3.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c"}, - {file = "pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6"}, + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, ] [package.dependencies] From b07b70bbf71e23cef7b569691a97d42e86615d3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 01:49:30 +0000 Subject: [PATCH 239/598] build(deps-dev): bump mypy from 1.11.0 to 1.11.1 Bumps [mypy](https://github.com/python/mypy) from 1.11.0 to 1.11.1. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.11...v1.11.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/poetry.lock b/poetry.lock index f8525e3f38..5bfcc493c2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -790,38 +790,38 @@ files = [ [[package]] name = "mypy" -version = "1.11.0" +version = "1.11.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3824187c99b893f90c845bab405a585d1ced4ff55421fdf5c84cb7710995229"}, - {file = "mypy-1.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96f8dbc2c85046c81bcddc246232d500ad729cb720da4e20fce3b542cab91287"}, - {file = "mypy-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a5d8d8dd8613a3e2be3eae829ee891b6b2de6302f24766ff06cb2875f5be9c6"}, - {file = "mypy-1.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72596a79bbfb195fd41405cffa18210af3811beb91ff946dbcb7368240eed6be"}, - {file = "mypy-1.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:35ce88b8ed3a759634cb4eb646d002c4cef0a38f20565ee82b5023558eb90c00"}, - {file = "mypy-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98790025861cb2c3db8c2f5ad10fc8c336ed2a55f4daf1b8b3f877826b6ff2eb"}, - {file = "mypy-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25bcfa75b9b5a5f8d67147a54ea97ed63a653995a82798221cca2a315c0238c1"}, - {file = "mypy-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bea2a0e71c2a375c9fa0ede3d98324214d67b3cbbfcbd55ac8f750f85a414e3"}, - {file = "mypy-1.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2b3d36baac48e40e3064d2901f2fbd2a2d6880ec6ce6358825c85031d7c0d4d"}, - {file = "mypy-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8e2e43977f0e09f149ea69fd0556623919f816764e26d74da0c8a7b48f3e18a"}, - {file = "mypy-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d44c1e44a8be986b54b09f15f2c1a66368eb43861b4e82573026e04c48a9e20"}, - {file = "mypy-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cea3d0fb69637944dd321f41bc896e11d0fb0b0aa531d887a6da70f6e7473aba"}, - {file = "mypy-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a83ec98ae12d51c252be61521aa5731f5512231d0b738b4cb2498344f0b840cd"}, - {file = "mypy-1.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7b73a856522417beb78e0fb6d33ef89474e7a622db2653bc1285af36e2e3e3d"}, - {file = "mypy-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2268d9fcd9686b61ab64f077be7ffbc6fbcdfb4103e5dd0cc5eaab53a8886c2"}, - {file = "mypy-1.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:940bfff7283c267ae6522ef926a7887305945f716a7704d3344d6d07f02df850"}, - {file = "mypy-1.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:14f9294528b5f5cf96c721f231c9f5b2733164e02c1c018ed1a0eff8a18005ac"}, - {file = "mypy-1.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7b54c27783991399046837df5c7c9d325d921394757d09dbcbf96aee4649fe9"}, - {file = "mypy-1.11.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65f190a6349dec29c8d1a1cd4aa71284177aee5949e0502e6379b42873eddbe7"}, - {file = "mypy-1.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbe286303241fea8c2ea5466f6e0e6a046a135a7e7609167b07fd4e7baf151bf"}, - {file = "mypy-1.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:104e9c1620c2675420abd1f6c44bab7dd33cc85aea751c985006e83dcd001095"}, - {file = "mypy-1.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f006e955718ecd8d159cee9932b64fba8f86ee6f7728ca3ac66c3a54b0062abe"}, - {file = "mypy-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:becc9111ca572b04e7e77131bc708480cc88a911adf3d0239f974c034b78085c"}, - {file = "mypy-1.11.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6801319fe76c3f3a3833f2b5af7bd2c17bb93c00026a2a1b924e6762f5b19e13"}, - {file = "mypy-1.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1a184c64521dc549324ec6ef7cbaa6b351912be9cb5edb803c2808a0d7e85ac"}, - {file = "mypy-1.11.0-py3-none-any.whl", hash = "sha256:56913ec8c7638b0091ef4da6fcc9136896914a9d60d54670a75880c3e5b99ace"}, - {file = "mypy-1.11.0.tar.gz", hash = "sha256:93743608c7348772fdc717af4aeee1997293a1ad04bc0ea6efa15bf65385c538"}, + {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, + {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, + {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, + {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, + {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, + {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, + {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, + {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, + {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, + {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, + {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, + {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, + {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, + {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, + {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, + {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, + {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, + {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, + {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, + {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, + {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, + {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, + {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, ] [package.dependencies] From 87df5bb64faf5483294d3246f81e48e95565cf52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 01:42:52 +0000 Subject: [PATCH 240/598] build(deps-dev): bump ruff from 0.5.5 to 0.5.6 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.5 to 0.5.6. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.5...0.5.6) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5bfcc493c2..300c7ceeb8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1423,29 +1423,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.5.5" +version = "0.5.6" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.5-py3-none-linux_armv6l.whl", hash = "sha256:605d589ec35d1da9213a9d4d7e7a9c761d90bba78fc8790d1c5e65026c1b9eaf"}, - {file = "ruff-0.5.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00817603822a3e42b80f7c3298c8269e09f889ee94640cd1fc7f9329788d7bf8"}, - {file = "ruff-0.5.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:187a60f555e9f865a2ff2c6984b9afeffa7158ba6e1eab56cb830404c942b0f3"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe26fc46fa8c6e0ae3f47ddccfbb136253c831c3289bba044befe68f467bfb16"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad25dd9c5faac95c8e9efb13e15803cd8bbf7f4600645a60ffe17c73f60779b"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f70737c157d7edf749bcb952d13854e8f745cec695a01bdc6e29c29c288fc36e"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:cfd7de17cef6ab559e9f5ab859f0d3296393bc78f69030967ca4d87a541b97a0"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a09b43e02f76ac0145f86a08e045e2ea452066f7ba064fd6b0cdccb486f7c3e7"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0b856cb19c60cd40198be5d8d4b556228e3dcd545b4f423d1ad812bfdca5884"}, - {file = "ruff-0.5.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3687d002f911e8a5faf977e619a034d159a8373514a587249cc00f211c67a091"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ac9dc814e510436e30d0ba535f435a7f3dc97f895f844f5b3f347ec8c228a523"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:af9bdf6c389b5add40d89b201425b531e0a5cceb3cfdcc69f04d3d531c6be74f"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d40a8533ed545390ef8315b8e25c4bb85739b90bd0f3fe1280a29ae364cc55d8"}, - {file = "ruff-0.5.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cab904683bf9e2ecbbe9ff235bfe056f0eba754d0168ad5407832928d579e7ab"}, - {file = "ruff-0.5.5-py3-none-win32.whl", hash = "sha256:696f18463b47a94575db635ebb4c178188645636f05e934fdf361b74edf1bb2d"}, - {file = "ruff-0.5.5-py3-none-win_amd64.whl", hash = "sha256:50f36d77f52d4c9c2f1361ccbfbd09099a1b2ea5d2b2222c586ab08885cf3445"}, - {file = "ruff-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3191317d967af701f1b73a31ed5788795936e423b7acce82a2b63e26eb3e89d6"}, - {file = "ruff-0.5.5.tar.gz", hash = "sha256:cc5516bdb4858d972fbc31d246bdb390eab8df1a26e2353be2dbc0c2d7f5421a"}, + {file = "ruff-0.5.6-py3-none-linux_armv6l.whl", hash = "sha256:a0ef5930799a05522985b9cec8290b185952f3fcd86c1772c3bdbd732667fdcd"}, + {file = "ruff-0.5.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b652dc14f6ef5d1552821e006f747802cc32d98d5509349e168f6bf0ee9f8f42"}, + {file = "ruff-0.5.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:80521b88d26a45e871f31e4b88938fd87db7011bb961d8afd2664982dfc3641a"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9bc8f328a9f1309ae80e4d392836e7dbc77303b38ed4a7112699e63d3b066ab"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d394940f61f7720ad371ddedf14722ee1d6250fd8d020f5ea5a86e7be217daf"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111a99cdb02f69ddb2571e2756e017a1496c2c3a2aeefe7b988ddab38b416d36"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e395daba77a79f6dc0d07311f94cc0560375ca20c06f354c7c99af3bf4560c5d"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c476acb43c3c51e3c614a2e878ee1589655fa02dab19fe2db0423a06d6a5b1b6"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2ff8003f5252fd68425fd53d27c1f08b201d7ed714bb31a55c9ac1d4c13e2eb"}, + {file = "ruff-0.5.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c94e084ba3eaa80c2172918c2ca2eb2230c3f15925f4ed8b6297260c6ef179ad"}, + {file = "ruff-0.5.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f77c1c3aa0669fb230b06fb24ffa3e879391a3ba3f15e3d633a752da5a3e670"}, + {file = "ruff-0.5.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f908148c93c02873210a52cad75a6eda856b2cbb72250370ce3afef6fb99b1ed"}, + {file = "ruff-0.5.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:563a7ae61ad284187d3071d9041c08019975693ff655438d8d4be26e492760bd"}, + {file = "ruff-0.5.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:94fe60869bfbf0521e04fd62b74cbca21cbc5beb67cbb75ab33fe8c174f54414"}, + {file = "ruff-0.5.6-py3-none-win32.whl", hash = "sha256:e6a584c1de6f8591c2570e171cc7ce482bb983d49c70ddf014393cd39e9dfaed"}, + {file = "ruff-0.5.6-py3-none-win_amd64.whl", hash = "sha256:d7fe7dccb1a89dc66785d7aa0ac283b2269712d8ed19c63af908fdccca5ccc1a"}, + {file = "ruff-0.5.6-py3-none-win_arm64.whl", hash = "sha256:57c6c0dd997b31b536bff49b9eee5ed3194d60605a4427f735eeb1f9c1b8d264"}, + {file = "ruff-0.5.6.tar.gz", hash = "sha256:07c9e3c2a8e1fe377dd460371c3462671a728c981c3205a5217291422209f642"}, ] [[package]] From 0c01bfb98db5c1baca862aa5bfcf7f24033e3988 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 01:42:28 +0000 Subject: [PATCH 241/598] build(deps-dev): bump mkdocs-material from 9.5.30 to 9.5.31 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.30 to 9.5.31. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.30...9.5.31) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 300c7ceeb8..9ab78f9254 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.30" +version = "9.5.31" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.30-py3-none-any.whl", hash = "sha256:fc070689c5250a180e9b9d79d8491ef9a3a7acb240db0728728d6c31eeb131d4"}, - {file = "mkdocs_material-9.5.30.tar.gz", hash = "sha256:3fd417dd42d679e3ba08b9e2d72cd8b8af142cc4a3969676ad6b00993dd182ec"}, + {file = "mkdocs_material-9.5.31-py3-none-any.whl", hash = "sha256:1b1f49066fdb3824c1e96d6bacd2d4375de4ac74580b47e79ff44c4d835c5fcb"}, + {file = "mkdocs_material-9.5.31.tar.gz", hash = "sha256:31833ec664772669f5856f4f276bf3fdf0e642a445e64491eda459249c3a1ca8"}, ] [package.dependencies] From 1b3a5070a0e8f969ba63f38ac0d7d982367a87bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 01:28:28 +0000 Subject: [PATCH 242/598] build(deps): bump argcomplete from 3.4.0 to 3.5.0 Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v3.4.0...v3.5.0) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9ab78f9254..8facb05de2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,13 +13,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.4.0" +version = "3.5.0" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.4.0-py3-none-any.whl", hash = "sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5"}, - {file = "argcomplete-3.4.0.tar.gz", hash = "sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f"}, + {file = "argcomplete-3.5.0-py3-none-any.whl", hash = "sha256:d4bcf3ff544f51e16e54228a7ac7f486ed70ebf2ecfe49a63a91171c76bf029b"}, + {file = "argcomplete-3.5.0.tar.gz", hash = "sha256:4349400469dccfb7950bb60334a680c58d88699bff6159df61251878dc6bf74b"}, ] [package.extras] @@ -1785,4 +1785,4 @@ test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-it [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "dc743cceaf8c8d472ebd6f824feb5955c09b64b24f84d916fc910def5f7637b5" +content-hash = "e1f15a3d1a61d77edf402dbb01fd18dbf23d1c39988307356726037da5ad00c4" diff --git a/pyproject.toml b/pyproject.toml index 643fb17d2d..ebce3037ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ packaging = ">=19" tomlkit = ">=0.5.3,<1.0.0" jinja2 = ">=2.10.3" pyyaml = ">=3.08" -argcomplete = ">=1.12.1,<3.5" +argcomplete = ">=1.12.1,<3.6" typing-extensions = { version = "^4.0.1", python = "<3.8" } charset-normalizer = ">=2.1.0,<4" # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility From 4becd3c450fc81b38ef5595bf66551a2081f48d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 01:28:47 +0000 Subject: [PATCH 243/598] build(deps): bump pyyaml from 6.0.1 to 6.0.2 Bumps [pyyaml](https://github.com/yaml/pyyaml) from 6.0.1 to 6.0.2. - [Release notes](https://github.com/yaml/pyyaml/releases) - [Changelog](https://github.com/yaml/pyyaml/blob/main/CHANGES) - [Commits](https://github.com/yaml/pyyaml/compare/6.0.1...6.0.2) --- updated-dependencies: - dependency-name: pyyaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 108 ++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8facb05de2..f3d302d194 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1207,62 +1207,64 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] From f0aa3a7df46fa628b2c675f40795ab6b2d83b332 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Aug 2024 01:15:02 +0000 Subject: [PATCH 244/598] build(deps-dev): bump types-pyyaml Bumps [types-pyyaml](https://github.com/python/typeshed) from 6.0.12.20240724 to 6.0.12.20240808. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-pyyaml dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index f3d302d194..932282bd86 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1570,13 +1570,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.20240724" +version = "6.0.12.20240808" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.20240724.tar.gz", hash = "sha256:cf7b31ae67e0c5b2919c703d2affc415485099d3fe6666a6912f040fd05cb67f"}, - {file = "types_PyYAML-6.0.12.20240724-py3-none-any.whl", hash = "sha256:e5becec598f3aa3a2ddf671de4a75fa1c6856fbf73b2840286c9d50fae2d5d48"}, + {file = "types-PyYAML-6.0.12.20240808.tar.gz", hash = "sha256:b8f76ddbd7f65440a8bda5526a9607e4c7a322dc2f8e1a8c405644f9a6f4b9af"}, + {file = "types_PyYAML-6.0.12.20240808-py3-none-any.whl", hash = "sha256:deda34c5c655265fc517b546c902aa6eed2ef8d3e921e4765fe606fe2afe8d35"}, ] [[package]] From 72ce1da176b82a8213b4062948d0815eb43d3e85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Aug 2024 01:15:28 +0000 Subject: [PATCH 245/598] build(deps-dev): bump ruff from 0.5.6 to 0.5.7 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.6 to 0.5.7. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.6...0.5.7) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 932282bd86..2544df7c0d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.5.6" +version = "0.5.7" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.6-py3-none-linux_armv6l.whl", hash = "sha256:a0ef5930799a05522985b9cec8290b185952f3fcd86c1772c3bdbd732667fdcd"}, - {file = "ruff-0.5.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b652dc14f6ef5d1552821e006f747802cc32d98d5509349e168f6bf0ee9f8f42"}, - {file = "ruff-0.5.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:80521b88d26a45e871f31e4b88938fd87db7011bb961d8afd2664982dfc3641a"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9bc8f328a9f1309ae80e4d392836e7dbc77303b38ed4a7112699e63d3b066ab"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d394940f61f7720ad371ddedf14722ee1d6250fd8d020f5ea5a86e7be217daf"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111a99cdb02f69ddb2571e2756e017a1496c2c3a2aeefe7b988ddab38b416d36"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e395daba77a79f6dc0d07311f94cc0560375ca20c06f354c7c99af3bf4560c5d"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c476acb43c3c51e3c614a2e878ee1589655fa02dab19fe2db0423a06d6a5b1b6"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2ff8003f5252fd68425fd53d27c1f08b201d7ed714bb31a55c9ac1d4c13e2eb"}, - {file = "ruff-0.5.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c94e084ba3eaa80c2172918c2ca2eb2230c3f15925f4ed8b6297260c6ef179ad"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f77c1c3aa0669fb230b06fb24ffa3e879391a3ba3f15e3d633a752da5a3e670"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f908148c93c02873210a52cad75a6eda856b2cbb72250370ce3afef6fb99b1ed"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:563a7ae61ad284187d3071d9041c08019975693ff655438d8d4be26e492760bd"}, - {file = "ruff-0.5.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:94fe60869bfbf0521e04fd62b74cbca21cbc5beb67cbb75ab33fe8c174f54414"}, - {file = "ruff-0.5.6-py3-none-win32.whl", hash = "sha256:e6a584c1de6f8591c2570e171cc7ce482bb983d49c70ddf014393cd39e9dfaed"}, - {file = "ruff-0.5.6-py3-none-win_amd64.whl", hash = "sha256:d7fe7dccb1a89dc66785d7aa0ac283b2269712d8ed19c63af908fdccca5ccc1a"}, - {file = "ruff-0.5.6-py3-none-win_arm64.whl", hash = "sha256:57c6c0dd997b31b536bff49b9eee5ed3194d60605a4427f735eeb1f9c1b8d264"}, - {file = "ruff-0.5.6.tar.gz", hash = "sha256:07c9e3c2a8e1fe377dd460371c3462671a728c981c3205a5217291422209f642"}, + {file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"}, + {file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"}, + {file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"}, + {file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"}, + {file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"}, + {file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"}, + {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, ] [[package]] From 9e18b632a8d4b88e2202378923575df80c9162f0 Mon Sep 17 00:00:00 2001 From: Marcel Blijleven Date: Tue, 30 Jul 2024 13:10:58 +0200 Subject: [PATCH 246/598] feat(bump): add functionality to write the next version to stdout Adds a --get-next flag which determines the next version and writes it to stdout. --- commitizen/cli.py | 6 ++ commitizen/commands/bump.py | 31 ++++++++-- commitizen/exceptions.py | 4 ++ docs/commands/bump.md | 15 +++++ tests/commands/test_bump_command.py | 61 +++++++++++++++++++ ...shows_description_when_use_help_option.txt | 3 +- 6 files changed, 115 insertions(+), 5 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 00be6daf15..3c529e4210 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -353,6 +353,12 @@ def __call__( "help": "Add additional build-metadata to the version-number", "default": None, }, + { + "name": ["--get-next"], + "action": "store_true", + "help": "Determine the next version and write to stdout", + "default": False, + }, ], }, { diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 8497384665..a3682df8f3 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -14,6 +14,7 @@ BumpTagFailedError, DryRunExit, ExpectedExit, + GetNextExit, InvalidManualVersion, NoCommitsFoundError, NoneIncrementExit, @@ -159,6 +160,7 @@ def __call__(self) -> None: # noqa: C901 manual_version = self.arguments["manual_version"] build_metadata = self.arguments["build_metadata"] increment_mode: str = self.arguments["increment_mode"] + get_next: bool = self.arguments["get_next"] if manual_version: if increment: @@ -190,6 +192,9 @@ def __call__(self) -> None: # noqa: C901 "--prerelease-offset cannot be combined with MANUAL_VERSION" ) + if get_next: + raise NotAllowed("--get-next cannot be combined with MANUAL_VERSION") + if major_version_zero: if not current_version.release[0] == 0: raise NotAllowed( @@ -202,6 +207,18 @@ def __call__(self) -> None: # noqa: C901 "--local-version cannot be combined with --build-metadata" ) + # If user specified changelog_to_stdout, they probably want the + # changelog to be generated as well, this is the most intuitive solution + self.changelog = self.changelog or bool(self.changelog_to_stdout) + + if get_next: + if self.changelog: + raise NotAllowed( + "--changelog or --changelog-to-stdout is not allowed with --get-next" + ) + # Setting dry_run to prevent any unwanted changes to the repo or files + self.dry_run = True + current_tag_version: str = bump.normalize_tag( current_version, tag_format=tag_format, @@ -210,10 +227,6 @@ def __call__(self) -> None: # noqa: C901 is_initial = self.is_initial_tag(current_tag_version, is_yes) - # If user specified changelog_to_stdout, they probably want the - # changelog to be generated as well, this is the most intuitive solution - self.changelog = self.changelog or bool(self.changelog_to_stdout) - if manual_version: try: new_version = self.scheme(manual_version) @@ -266,6 +279,16 @@ def __call__(self) -> None: # noqa: C901 current_version, new_version, bump_commit_message ) + if get_next: + if increment is None and new_tag_version == current_tag_version: + raise NoneIncrementExit( + "[NO_COMMITS_TO_BUMP]\n" + "The commits found are not eligible to be bumped" + ) + + out.write(str(new_version)) + raise GetNextExit() + # Report found information information = f"{message}\n" f"tag to create: {new_tag_version}\n" if increment: diff --git a/commitizen/exceptions.py b/commitizen/exceptions.py index b0fc4e382d..c96803b5fb 100644 --- a/commitizen/exceptions.py +++ b/commitizen/exceptions.py @@ -67,6 +67,10 @@ class DryRunExit(ExpectedExit): pass +class GetNextExit(ExpectedExit): + pass + + class NoneIncrementExit(CommitizenException): exit_code = ExitCode.NO_INCREMENT diff --git a/docs/commands/bump.md b/docs/commands/bump.md index 4d370a6a1f..1bd85025bb 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -285,6 +285,21 @@ You should normally not use this functionality, but if you decide to do, keep in * Version `1.2.3+a`, and `1.2.3+b` are the same version! Tools should not use the string after `+` for version calculation. This is probably not a guarantee (example in helm) even tho it is in the spec. * It might be problematic having the metadata in place when doing upgrades depending on what tool you use. +### `--get-next` + +Provides a way to determine the next version and write it to stdout. This parameter is not compatible with `--changelog` +and `manual version`. + +```bash +cz bump --get-next +``` + +Will output the next version, e.g. `1.2.3`. This can be useful for determining the next version based in CI for non +production environments/builds. + +It will raise a `NoneIncrementExit` if the commits found are not eligible for a version bump. +See [avoid raising errors](#avoid-raising-errors) for information on suppressing this exit. + ## Avoid raising errors Some situations from commitizen raise an exit code different than 0. diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index a0271c322e..90bca62070 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -21,6 +21,7 @@ DryRunExit, ExitCode, ExpectedExit, + GetNextExit, InvalidManualVersion, NoCommitsFoundError, NoneIncrementExit, @@ -1462,3 +1463,63 @@ def test_bump_command_shows_description_when_use_help_option( out, _ = capsys.readouterr() file_regression.check(out, extension=".txt") + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_get_next(mocker: MockFixture, capsys): + create_file_and_commit("feat: new file") + + testargs = ["cz", "bump", "--yes", "--get-next"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(GetNextExit): + cli.main() + + out, _ = capsys.readouterr() + assert "0.2.0" in out + + tag_exists = git.tag_exist("0.2.0") + assert tag_exists is False + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_get_next__changelog_is_not_allowed(mocker: MockFixture): + create_file_and_commit("feat: new file") + + testargs = ["cz", "bump", "--yes", "--get-next", "--changelog"] + mocker.patch.object(sys, "argv", testargs) + + with pytest.raises(NotAllowed): + cli.main() + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_get_next__changelog_to_stdout_is_not_allowed(mocker: MockFixture): + create_file_and_commit("feat: new file") + + testargs = ["cz", "bump", "--yes", "--get-next", "--changelog-to-stdout"] + mocker.patch.object(sys, "argv", testargs) + + with pytest.raises(NotAllowed): + cli.main() + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_get_next__manual_version_is_not_allowed(mocker: MockFixture): + create_file_and_commit("feat: new file") + + testargs = ["cz", "bump", "--yes", "--get-next", "0.2.1"] + mocker.patch.object(sys, "argv", testargs) + + with pytest.raises(NotAllowed): + cli.main() + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_get_next__no_eligible_commits_raises(mocker: MockFixture): + create_file_and_commit("chore: new commit") + + testargs = ["cz", "bump", "--yes", "--get-next"] + mocker.patch.object(sys, "argv", testargs) + + with pytest.raises(NoneIncrementExit): + cli.main() diff --git a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt index de76f2efcf..7c3f8ac805 100644 --- a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt @@ -10,7 +10,7 @@ usage: cz bump [-h] [--dry-run] [--files-only] [--local-version] [--changelog] [--file-name FILE_NAME] [--prerelease-offset PRERELEASE_OFFSET] [--version-scheme {pep440,semver,semver2}] [--version-type {pep440,semver,semver2}] - [--build-metadata BUILD_METADATA] + [--build-metadata BUILD_METADATA] [--get-next] [MANUAL_VERSION] bump semantic version based on the git log @@ -77,3 +77,4 @@ options: Deprecated, use --version-scheme --build-metadata BUILD_METADATA Add additional build-metadata to the version-number + --get-next Determine the next version and write to stdout From d6e394a8e4949b832a15ac18466b99e46daa63d1 Mon Sep 17 00:00:00 2001 From: Marcel Blijleven Date: Thu, 1 Aug 2024 22:01:54 +0200 Subject: [PATCH 247/598] docs(bump): add comparison between --get-next and --dry-run --- docs/commands/bump.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/commands/bump.md b/docs/commands/bump.md index 1bd85025bb..fabae48940 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -297,8 +297,26 @@ cz bump --get-next Will output the next version, e.g. `1.2.3`. This can be useful for determining the next version based in CI for non production environments/builds. -It will raise a `NoneIncrementExit` if the commits found are not eligible for a version bump. -See [avoid raising errors](#avoid-raising-errors) for information on suppressing this exit. +This behavior differs from the `--dry-run` flag. The `--dry-run` flag provides a more detailed output and can also show +the changes as they would appear in the changelog file. + +The following output is the result of `cz bump --dry-run`: + +``` +bump: version 3.28.0 → 3.29.0 +tag to create: v3.29.0 +increment detected: MINOR +``` + +The following output is the result of `cz bump --get-next`: + +``` +3.29.0 +``` + +The `--get-next` flag will raise a `NoneIncrementExit` if the found commits are not eligible for a version bump. + +For information on how to suppress this exit, see [avoid raising errors](#avoid-raising-errors). ## Avoid raising errors From b84a83b483a6db3d5a8d17091a8189bc13d63234 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sun, 11 Aug 2024 10:40:11 +0800 Subject: [PATCH 248/598] docs(bump): reword "--get-next" description --- docs/commands/bump.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/commands/bump.md b/docs/commands/bump.md index fabae48940..efb5b0881d 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -294,7 +294,7 @@ and `manual version`. cz bump --get-next ``` -Will output the next version, e.g. `1.2.3`. This can be useful for determining the next version based in CI for non +Will output the next version, e.g., `1.2.3`. This can be useful for determining the next version based on CI for non production environments/builds. This behavior differs from the `--dry-run` flag. The `--dry-run` flag provides a more detailed output and can also show From d7e01aa9b0cfe3c1b732e66d523bbd0656221127 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 11 Aug 2024 14:09:19 +0000 Subject: [PATCH 249/598] =?UTF-8?q?bump:=20version=203.28.0=20=E2=86=92=20?= =?UTF-8?q?3.29.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8d0cf55529..6cdbcc90e6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v3.28.0 # automatically updated by Commitizen + rev: v3.29.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ec2dd2d8e..b621d9e5dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v3.29.0 (2024-08-11) + +### Feat + +- **bump**: add functionality to write the next version to stdout + ## v3.28.0 (2024-07-17) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 87dca02966..c13e81a875 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.28.0" +__version__ = "3.29.0" diff --git a/pyproject.toml b/pyproject.toml index ebce3037ff..f3574a1826 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.28.0" +version = "3.29.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.28.0" +version = "3.29.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From b3add85acc37e2a277473452922f1dd36500ee05 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 11 Aug 2024 14:09:52 +0000 Subject: [PATCH 250/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz_bump___help.svg | 350 ++++++++++++------------ 1 file changed, 177 insertions(+), 173 deletions(-) diff --git a/docs/images/cli_help/cz_bump___help.svg b/docs/images/cli_help/cz_bump___help.svg index 96db25a964..7af2aa8c27 100644 --- a/docs/images/cli_help/cz_bump___help.svg +++ b/docs/images/cli_help/cz_bump___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - - $ 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 {pep440,semver,semver2}] -[--version-type {pep440,semver,semver2}] -[--build-metadata BUILD_METADATA] -[MANUAL_VERSION] - -bump semantic version based on the git log - -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 {pep440,semver,semver2} -                        choose version scheme -  --version-type {pep440,semver,semver2} -                        Deprecated, use --version-scheme -  --build-metadata BUILD_METADATA -                        Add additional build-metadata to the version-number - + + $ 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 {pep440,semver,semver2}] +[--version-type {pep440,semver,semver2}] +[--build-metadata BUILD_METADATA][--get-next] +[MANUAL_VERSION] + +bump semantic version based on the git log + +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 {pep440,semver,semver2} +                        choose version scheme +  --version-type {pep440,semver,semver2} +                        Deprecated, use --version-scheme +  --build-metadata BUILD_METADATA +                        Add additional build-metadata to the version-number +  --get-next            Determine the next version and write to stdout + From 6a01e9734440d24dfcd4cee66ccee924cf72370f Mon Sep 17 00:00:00 2001 From: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> Date: Wed, 26 Jun 2024 21:52:35 +0200 Subject: [PATCH 251/598] ci(github-actions): add "3.13-dev" to Python tests (#1145) --- .github/workflows/pythonpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 3b5d5305a3..f0a517686f 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -6,7 +6,7 @@ jobs: python-check: strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev"] platform: [ubuntu-20.04, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: From 8335f6bb1746ffef1e1702ed89b5440c7e3cfa12 Mon Sep 17 00:00:00 2001 From: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> Date: Thu, 8 Aug 2024 23:17:44 +0200 Subject: [PATCH 252/598] test: fix typo --- tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index 971ff91820..efd3c38570 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -12,7 +12,7 @@ skip_below_py_3_10 = pytest.mark.skipif( sys.version_info < (3, 10), - reason="The output meesage of argparse is different between Python 3.10 and lower than Python 3.10", + reason="The output message of argparse is different between Python 3.10 and lower than Python 3.10", ) From b06c8b603b079d5a397b3036cf617e28c8eb8702 Mon Sep 17 00:00:00 2001 From: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> Date: Thu, 8 Aug 2024 23:26:01 +0200 Subject: [PATCH 253/598] test: update tests with less redundant output generated by argparse --help in Python 3.13 --- tests/commands/test_bump_command.py | 4 ++-- ...command_shows_description_when_use_help_option.txt | 11 +++++------ tests/commands/test_changelog_command.py | 4 ++-- ...command_shows_description_when_use_help_option.txt | 5 ++--- tests/commands/test_check_command.py | 4 ++-- ...command_shows_description_when_use_help_option.txt | 4 ++-- tests/commands/test_commit_command.py | 4 ++-- ...command_shows_description_when_use_help_option.txt | 2 +- tests/utils.py | 5 +++++ 9 files changed, 23 insertions(+), 20 deletions(-) diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 90bca62070..81273764dd 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -30,7 +30,7 @@ NotAllowed, NoVersionSpecifiedError, ) -from tests.utils import create_file_and_commit, create_tag, skip_below_py_3_10 +from tests.utils import create_file_and_commit, create_tag, skip_below_py_3_13 @pytest.mark.parametrize( @@ -1452,7 +1452,7 @@ def test_bump_changelog_contains_increment_only(mocker, tmp_commitizen_project, assert "2.0.0" not in out -@skip_below_py_3_10 +@skip_below_py_3_13 def test_bump_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt index 7c3f8ac805..ab73bd4491 100644 --- a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt @@ -33,9 +33,9 @@ options: --bump-message BUMP_MESSAGE template used to create the release commit, useful when working with CI - --prerelease {alpha,beta,rc}, -pr {alpha,beta,rc} + --prerelease, -pr {alpha,beta,rc} choose type of prerelease - --devrelease DEVRELEASE, -d DEVRELEASE + --devrelease, -d DEVRELEASE specify non-negative integer for dev. release --increment {MAJOR,MINOR,PATCH} manually specify the desired increment @@ -53,7 +53,7 @@ options: 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 + --annotated-tag-message, -atm ANNOTATED_TAG_MESSAGE create annotated tag message --gpg-sign, -s sign tag instead of lightweight one --changelog-to-stdout @@ -62,11 +62,10 @@ options: 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 + --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') + --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 diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 4694d33305..3d9a5c5c48 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -29,7 +29,7 @@ create_tag, get_current_branch, merge_branch, - skip_below_py_3_10, + skip_below_py_3_13, switch_branch, wait_for_tag, ) @@ -1640,7 +1640,7 @@ def test_export_changelog_template_from_plugin( assert target.read_text() == tpl -@skip_below_py_3_10 +@skip_below_py_3_13 def test_changelog_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt b/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt index dae438ca24..461eb2edd6 100644 --- a/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt @@ -33,8 +33,7 @@ options: --export-template EXPORT_TEMPLATE Export the changelog template into this file instead of rendering it - --template TEMPLATE, -t 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') + --extra, -e EXTRA a changelog extra variable (in the form 'key=value') diff --git a/tests/commands/test_check_command.py b/tests/commands/test_check_command.py index 328ebd78a9..57bfe3f10a 100644 --- a/tests/commands/test_check_command.py +++ b/tests/commands/test_check_command.py @@ -12,7 +12,7 @@ InvalidCommitMessageError, NoCommitsFoundError, ) -from tests.utils import create_file_and_commit, skip_below_py_3_10 +from tests.utils import create_file_and_commit, skip_below_py_3_13 COMMIT_LOG = [ "refactor: A code change that neither fixes a bug nor adds a feature", @@ -416,7 +416,7 @@ def test_check_conventional_commit_succeed_with_git_diff(mocker, capsys): assert "Commit validation: successful!" in out -@skip_below_py_3_10 +@skip_below_py_3_13 def test_check_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt b/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt index 74b9df7196..2ccf97270e 100644 --- a/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt @@ -13,7 +13,7 @@ options: MSG_FILE=$1 --rev-range REV_RANGE a range of git rev to check. e.g, master..HEAD - -m MESSAGE, --message MESSAGE + -m, --message MESSAGE commit message that needs to be checked --allow-abort allow empty commit messages, which typically abort a commit @@ -21,5 +21,5 @@ options: allowed commit message prefixes. If the message starts by one of these prefixes, the message won't be checked against the regex - -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT + -l, --message-length-limit MESSAGE_LENGTH_LIMIT length limit of the commit message; 0 for no limit diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 8ae7568a9d..03ff51c42c 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -19,7 +19,7 @@ NotAllowed, NothingToCommitError, ) -from tests.utils import skip_below_py_3_10 +from tests.utils import skip_below_py_3_13 @pytest.fixture @@ -410,7 +410,7 @@ def test_commit_command_with_message_length_limit(config, mocker: MockFixture): commands.Commit(config, {"message_length_limit": message_length - 1})() -@skip_below_py_3_10 +@skip_below_py_3_13 def test_commit_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression ): diff --git a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt index ebdb68446e..92f3cf5e87 100644 --- a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt @@ -16,5 +16,5 @@ options: -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. - -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT + -l, --message-length-limit MESSAGE_LENGTH_LIMIT length limit of the commit message; 0 for no limit diff --git a/tests/utils.py b/tests/utils.py index efd3c38570..5e26b2d70a 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -15,6 +15,11 @@ reason="The output message of argparse is different between Python 3.10 and lower than Python 3.10", ) +skip_below_py_3_13 = pytest.mark.skipif( + sys.version_info < (3, 13), + reason="The output message of argparse is different between Python 3.13 and lower than Python 3.13", +) + class FakeCommand: def __init__(self, out=None, err=None, return_code=0): From 01fd0426677b4db07988103d3a0ebd0d10763886 Mon Sep 17 00:00:00 2001 From: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> Date: Fri, 9 Aug 2024 00:24:53 +0200 Subject: [PATCH 254/598] test: skip test on Python 3.13 due to incompatible pre-commit hook `mirrors-prettier` --- tests/test_bump_create_commit_message.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/test_bump_create_commit_message.py b/tests/test_bump_create_commit_message.py index 517c7a0459..0002659396 100644 --- a/tests/test_bump_create_commit_message.py +++ b/tests/test_bump_create_commit_message.py @@ -24,7 +24,19 @@ def test_create_tag(test_input, expected): assert new_tag == expected -@pytest.mark.parametrize("retry", (True, False)) +@pytest.mark.parametrize( + "retry", + ( + pytest.param( + True, + marks=pytest.mark.skipif( + sys.version_info >= (3, 13), + reason="mirrors-prettier is not supported with Python 3.13 or higher", + ), + ), + False, + ), +) @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_pre_commit_changelog(mocker: MockFixture, freezer, retry): freezer.move_to("2022-04-01") From ac6d5a45d5c400a3e87914b34cebf772627ecbe9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 01:43:52 +0000 Subject: [PATCH 255/598] build(deps): bump tomlkit from 0.13.0 to 0.13.2 Bumps [tomlkit](https://github.com/sdispater/tomlkit) from 0.13.0 to 0.13.2. - [Release notes](https://github.com/sdispater/tomlkit/releases) - [Changelog](https://github.com/python-poetry/tomlkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/sdispater/tomlkit/compare/0.13.0...0.13.2) --- updated-dependencies: - dependency-name: tomlkit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2544df7c0d..147d365c49 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1522,13 +1522,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.13.0" +version = "0.13.2" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" files = [ - {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, - {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, + {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, + {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, ] [[package]] From b39b0676a32777601d8201c8219c2a03570e9c35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:21:25 +0000 Subject: [PATCH 256/598] build(deps-dev): bump ruff from 0.5.7 to 0.6.0 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.5.7 to 0.6.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.5.7...0.6.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 40 ++++++++++++++++++++-------------------- pyproject.toml | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index 147d365c49..57aa375d6b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.5.7" +version = "0.6.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"}, - {file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"}, - {file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"}, - {file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"}, - {file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"}, - {file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"}, - {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, + {file = "ruff-0.6.0-py3-none-linux_armv6l.whl", hash = "sha256:92dcce923e5df265781e5fc76f9a1edad52201a7aafe56e586b90988d5239013"}, + {file = "ruff-0.6.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:31b90ff9dc79ed476c04e957ba7e2b95c3fceb76148f2079d0d68a908d2cfae7"}, + {file = "ruff-0.6.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d834a9ec9f8287dd6c3297058b3a265ed6b59233db22593379ee38ebc4b9768"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2089267692696aba342179471831a085043f218706e642564812145df8b8d0d"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa62b423ee4bbd8765f2c1dbe8f6aac203e0583993a91453dc0a449d465c84da"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7344e1a964b16b1137ea361d6516ce4ee61a0403fa94252a1913ecc1311adcae"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:487f3a35c3f33bf82be212ce15dc6278ea854e35573a3f809442f73bec8b2760"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75db409984077a793cf344d499165298a6f65449e905747ac65983b12e3e64b1"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84908bd603533ecf1db456d8fc2665d1f4335d722e84bc871d3bbd2d1116c272"}, + {file = "ruff-0.6.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f1749a0aef3ec41ed91a0e2127a6ae97d2e2853af16dbd4f3c00d7a3af726c5"}, + {file = "ruff-0.6.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:016fea751e2bcfbbd2f8cb19b97b37b3fd33148e4df45b526e87096f4e17354f"}, + {file = "ruff-0.6.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6ae80f141b53b2e36e230017e64f5ea2def18fac14334ffceaae1b780d70c4f7"}, + {file = "ruff-0.6.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eaaaf33ea4b3f63fd264d6a6f4a73fa224bbfda4b438ffea59a5340f4afa2bb5"}, + {file = "ruff-0.6.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7667ddd1fc688150a7ca4137140867584c63309695a30016880caf20831503a0"}, + {file = "ruff-0.6.0-py3-none-win32.whl", hash = "sha256:ae48365aae60d40865a412356f8c6f2c0be1c928591168111eaf07eaefa6bea3"}, + {file = "ruff-0.6.0-py3-none-win_amd64.whl", hash = "sha256:774032b507c96f0c803c8237ce7d2ef3934df208a09c40fa809c2931f957fe5e"}, + {file = "ruff-0.6.0-py3-none-win_arm64.whl", hash = "sha256:a5366e8c3ae6b2dc32821749b532606c42e609a99b0ae1472cf601da931a048c"}, + {file = "ruff-0.6.0.tar.gz", hash = "sha256:272a81830f68f9bd19d49eaf7fa01a5545c5a2e86f32a9935bb0e4bb9a1db5b8"}, ] [[package]] @@ -1787,4 +1787,4 @@ test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-it [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "e1f15a3d1a61d77edf402dbb01fd18dbf23d1c39988307356726037da5ad00c4" +content-hash = "67940b1bdb20630081a00248b6a51f093a44a2da76048873c722c97689a2a31c" diff --git a/pyproject.toml b/pyproject.toml index f3574a1826..79c2f849b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" # linter -ruff = ">=0.5.0,<0.6.0" +ruff = ">=0.5.0,<0.7.0" pre-commit = ">=2.18,<4.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" From f8d66e60e97af4c4d7adcdb6307f44509ff79865 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 01:35:33 +0000 Subject: [PATCH 257/598] build(deps-dev): bump ruff from 0.6.0 to 0.6.1 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.0 to 0.6.1. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.0...0.6.1) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 57aa375d6b..0a16298ccb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.0" +version = "0.6.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.0-py3-none-linux_armv6l.whl", hash = "sha256:92dcce923e5df265781e5fc76f9a1edad52201a7aafe56e586b90988d5239013"}, - {file = "ruff-0.6.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:31b90ff9dc79ed476c04e957ba7e2b95c3fceb76148f2079d0d68a908d2cfae7"}, - {file = "ruff-0.6.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d834a9ec9f8287dd6c3297058b3a265ed6b59233db22593379ee38ebc4b9768"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2089267692696aba342179471831a085043f218706e642564812145df8b8d0d"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa62b423ee4bbd8765f2c1dbe8f6aac203e0583993a91453dc0a449d465c84da"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7344e1a964b16b1137ea361d6516ce4ee61a0403fa94252a1913ecc1311adcae"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:487f3a35c3f33bf82be212ce15dc6278ea854e35573a3f809442f73bec8b2760"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75db409984077a793cf344d499165298a6f65449e905747ac65983b12e3e64b1"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84908bd603533ecf1db456d8fc2665d1f4335d722e84bc871d3bbd2d1116c272"}, - {file = "ruff-0.6.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f1749a0aef3ec41ed91a0e2127a6ae97d2e2853af16dbd4f3c00d7a3af726c5"}, - {file = "ruff-0.6.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:016fea751e2bcfbbd2f8cb19b97b37b3fd33148e4df45b526e87096f4e17354f"}, - {file = "ruff-0.6.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6ae80f141b53b2e36e230017e64f5ea2def18fac14334ffceaae1b780d70c4f7"}, - {file = "ruff-0.6.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eaaaf33ea4b3f63fd264d6a6f4a73fa224bbfda4b438ffea59a5340f4afa2bb5"}, - {file = "ruff-0.6.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7667ddd1fc688150a7ca4137140867584c63309695a30016880caf20831503a0"}, - {file = "ruff-0.6.0-py3-none-win32.whl", hash = "sha256:ae48365aae60d40865a412356f8c6f2c0be1c928591168111eaf07eaefa6bea3"}, - {file = "ruff-0.6.0-py3-none-win_amd64.whl", hash = "sha256:774032b507c96f0c803c8237ce7d2ef3934df208a09c40fa809c2931f957fe5e"}, - {file = "ruff-0.6.0-py3-none-win_arm64.whl", hash = "sha256:a5366e8c3ae6b2dc32821749b532606c42e609a99b0ae1472cf601da931a048c"}, - {file = "ruff-0.6.0.tar.gz", hash = "sha256:272a81830f68f9bd19d49eaf7fa01a5545c5a2e86f32a9935bb0e4bb9a1db5b8"}, + {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, + {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, + {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, + {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, + {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, + {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, + {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, + {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, + {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, ] [[package]] From 44a79f5d3e04610baff4e5591753b20fc75cb985 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 01:19:17 +0000 Subject: [PATCH 258/598] build(deps-dev): bump mkdocs-material from 9.5.31 to 9.5.32 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.31 to 9.5.32. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.31...9.5.32) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0a16298ccb..c474cf6680 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.31" +version = "9.5.32" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.31-py3-none-any.whl", hash = "sha256:1b1f49066fdb3824c1e96d6bacd2d4375de4ac74580b47e79ff44c4d835c5fcb"}, - {file = "mkdocs_material-9.5.31.tar.gz", hash = "sha256:31833ec664772669f5856f4f276bf3fdf0e642a445e64491eda459249c3a1ca8"}, + {file = "mkdocs_material-9.5.32-py3-none-any.whl", hash = "sha256:f3704f46b63d31b3cd35c0055a72280bed825786eccaf19c655b44e0cd2c6b3f"}, + {file = "mkdocs_material-9.5.32.tar.gz", hash = "sha256:38ed66e6d6768dde4edde022554553e48b2db0d26d1320b19e2e2b9da0be1120"}, ] [package.dependencies] From 8696fba70fb02bd4b9081cd2e7492c03871f5785 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 01:18:39 +0000 Subject: [PATCH 259/598] build(deps): bump importlib-metadata from 8.2.0 to 8.3.0 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 8.2.0 to 8.3.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v8.2.0...v8.3.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index c474cf6680..d37a121e27 100644 --- a/poetry.lock +++ b/poetry.lock @@ -450,13 +450,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "8.2.0" +version = "8.3.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"}, - {file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"}, + {file = "importlib_metadata-8.3.0-py3-none-any.whl", hash = "sha256:42817a4a0be5845d22c6e212db66a94ad261e2318d80b3e0d363894a79df2b67"}, + {file = "importlib_metadata-8.3.0.tar.gz", hash = "sha256:9c8fa6e8ea0f9516ad5c8db9246a731c948193c7754d3babb0114a05b27dd364"}, ] [package.dependencies] From 1847e1db01e29f5454137fbd6b546420aa9080bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 01:32:28 +0000 Subject: [PATCH 260/598] build(deps): bump importlib-metadata from 8.3.0 to 8.4.0 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 8.3.0 to 8.4.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v8.3.0...v8.4.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d37a121e27..c953605cf2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -450,13 +450,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "8.3.0" +version = "8.4.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.3.0-py3-none-any.whl", hash = "sha256:42817a4a0be5845d22c6e212db66a94ad261e2318d80b3e0d363894a79df2b67"}, - {file = "importlib_metadata-8.3.0.tar.gz", hash = "sha256:9c8fa6e8ea0f9516ad5c8db9246a731c948193c7754d3babb0114a05b27dd364"}, + {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, + {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, ] [package.dependencies] From 43299877e9210d19f45e8fe1ecfc4e6183eff962 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 01:13:21 +0000 Subject: [PATCH 261/598] build(deps-dev): bump types-python-dateutil Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.9.0.20240316 to 2.9.0.20240821. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-python-dateutil dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index c953605cf2..46e0de015b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1559,13 +1559,13 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.9.0.20240316" +version = "2.9.0.20240821" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, - {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, + {file = "types-python-dateutil-2.9.0.20240821.tar.gz", hash = "sha256:9649d1dcb6fef1046fb18bebe9ea2aa0028b160918518c34589a46045f6ebd98"}, + {file = "types_python_dateutil-2.9.0.20240821-py3-none-any.whl", hash = "sha256:f5889fcb4e63ed4aaa379b44f93c32593d50b9a94c9a60a0c854d8cc3511cd57"}, ] [[package]] From 54e16156d8158969aa019068bb438e2ff89881ca Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Sun, 18 Aug 2024 14:23:15 +0200 Subject: [PATCH 262/598] docs(readme): fix 'pip install Commitizen' to 'commitizen' Signed-off-by: Adrian DC --- docs/README.md | 2 +- docs/tutorials/gitlab_ci.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index b4fa13eb2c..8c760be235 100644 --- a/docs/README.md +++ b/docs/README.md @@ -49,7 +49,7 @@ descriptive commits. To make commitizen available in your system ```bash -pip install --user -U Commitizen +pip install --user -U commitizen ``` ### Python project diff --git a/docs/tutorials/gitlab_ci.md b/docs/tutorials/gitlab_ci.md index de1336b675..d29bf994bd 100644 --- a/docs/tutorials/gitlab_ci.md +++ b/docs/tutorials/gitlab_ci.md @@ -79,7 +79,7 @@ auto-bump: - "which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )" - eval `ssh-agent -s` - echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add - > /dev/null # add ssh key - - pip3 install -U Commitizen # install commitizen + - pip3 install -U commitizen # install commitizen - mkdir -p ~/.ssh - chmod 700 ~/.ssh - echo "$SSH_PUBLIC_KEY" >> ~/.ssh/id_rsa.pub From 737c24cc0a168de3e64588616338f76cd7af384f Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Thu, 22 Aug 2024 02:21:37 +0200 Subject: [PATCH 263/598] docs(readme): document 'pipx' alternative installation steps Issue: #1113 --- Signed-off-by: Adrian DC --- docs/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 8c760be235..3f729ebcbc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -46,7 +46,15 @@ descriptive commits. ## Installation -To make commitizen available in your system +Install commitizen in your system using `pipx` (Recommended, ): + +```bash +pipx ensurepath +pipx install commitizen +pipx upgrade commitizen +``` + +Install commitizen using `pip` with `--user` flag: ```bash pip install --user -U commitizen From 9f085a1933d2d2993856e34f51d0782e7bd99076 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2024 01:05:39 +0000 Subject: [PATCH 264/598] build(deps-dev): bump ruff from 0.6.1 to 0.6.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.1 to 0.6.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.1...0.6.2) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 46e0de015b..e9db8f1e9f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.1" +version = "0.6.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, - {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, - {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, - {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, - {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, - {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, - {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, + {file = "ruff-0.6.2-py3-none-linux_armv6l.whl", hash = "sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c"}, + {file = "ruff-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570"}, + {file = "ruff-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56"}, + {file = "ruff-0.6.2-py3-none-win32.whl", hash = "sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da"}, + {file = "ruff-0.6.2-py3-none-win_amd64.whl", hash = "sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2"}, + {file = "ruff-0.6.2-py3-none-win_arm64.whl", hash = "sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9"}, + {file = "ruff-0.6.2.tar.gz", hash = "sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be"}, ] [[package]] From 3333275afbd08516ef01a4ca660d8ec8d5698ff3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 01:32:47 +0000 Subject: [PATCH 265/598] build(deps-dev): bump mypy from 1.11.1 to 1.11.2 Bumps [mypy](https://github.com/python/mypy) from 1.11.1 to 1.11.2. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.11.1...v1.11.2) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/poetry.lock b/poetry.lock index e9db8f1e9f..cf1b3596b1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -790,38 +790,38 @@ files = [ [[package]] name = "mypy" -version = "1.11.1" +version = "1.11.2" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, - {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, - {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, - {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, - {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, - {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, - {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, - {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, - {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, - {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, - {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, - {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, - {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, - {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, - {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, - {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, - {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, - {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, - {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, + {file = "mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a"}, + {file = "mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef"}, + {file = "mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383"}, + {file = "mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8"}, + {file = "mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7"}, + {file = "mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385"}, + {file = "mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca"}, + {file = "mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104"}, + {file = "mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4"}, + {file = "mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6"}, + {file = "mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318"}, + {file = "mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36"}, + {file = "mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987"}, + {file = "mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca"}, + {file = "mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70"}, + {file = "mypy-1.11.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b"}, + {file = "mypy-1.11.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86"}, + {file = "mypy-1.11.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce"}, + {file = "mypy-1.11.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1"}, + {file = "mypy-1.11.2-cp38-cp38-win_amd64.whl", hash = "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b"}, + {file = "mypy-1.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6"}, + {file = "mypy-1.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70"}, + {file = "mypy-1.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"}, + {file = "mypy-1.11.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d"}, + {file = "mypy-1.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24"}, + {file = "mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12"}, + {file = "mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79"}, ] [package.dependencies] From ef57d1491d3681fe2a8a62dff5a822b2263c2e0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 01:33:16 +0000 Subject: [PATCH 266/598] build(deps-dev): bump mkdocs-material from 9.5.32 to 9.5.33 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.32 to 9.5.33. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.32...9.5.33) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index cf1b3596b1..bb5fc1a348 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.32" +version = "9.5.33" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.32-py3-none-any.whl", hash = "sha256:f3704f46b63d31b3cd35c0055a72280bed825786eccaf19c655b44e0cd2c6b3f"}, - {file = "mkdocs_material-9.5.32.tar.gz", hash = "sha256:38ed66e6d6768dde4edde022554553e48b2db0d26d1320b19e2e2b9da0be1120"}, + {file = "mkdocs_material-9.5.33-py3-none-any.whl", hash = "sha256:dbc79cf0fdc6e2c366aa987de8b0c9d4e2bb9f156e7466786ba2fd0f9bf7ffca"}, + {file = "mkdocs_material-9.5.33.tar.gz", hash = "sha256:d23a8b5e3243c9b2f29cdfe83051104a8024b767312dc8fde05ebe91ad55d89d"}, ] [package.dependencies] From 7c02669c59d201d1d83ae31810aba5207d81d23d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Aug 2024 01:09:54 +0000 Subject: [PATCH 267/598] build(deps-dev): bump rich from 13.7.1 to 13.8.0 Bumps [rich](https://github.com/Textualize/rich) from 13.7.1 to 13.8.0. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.7.1...v13.8.0) --- updated-dependencies: - dependency-name: rich dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index bb5fc1a348..18d5623d51 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1406,13 +1406,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.7.1" +version = "13.8.0" 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"}, + {file = "rich-13.8.0-py3-none-any.whl", hash = "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc"}, + {file = "rich-13.8.0.tar.gz", hash = "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"}, ] [package.dependencies] From 100936b86380c2e16989da67fa71102cc5ba401e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 01:08:48 +0000 Subject: [PATCH 268/598] build(deps-dev): bump ruff from 0.6.2 to 0.6.3 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.2 to 0.6.3. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.2...0.6.3) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 18d5623d51..ca1417dab8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.2" +version = "0.6.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.2-py3-none-linux_armv6l.whl", hash = "sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c"}, - {file = "ruff-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570"}, - {file = "ruff-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1"}, - {file = "ruff-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1"}, - {file = "ruff-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23"}, - {file = "ruff-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a"}, - {file = "ruff-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c"}, - {file = "ruff-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56"}, - {file = "ruff-0.6.2-py3-none-win32.whl", hash = "sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da"}, - {file = "ruff-0.6.2-py3-none-win_amd64.whl", hash = "sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2"}, - {file = "ruff-0.6.2-py3-none-win_arm64.whl", hash = "sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9"}, - {file = "ruff-0.6.2.tar.gz", hash = "sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be"}, + {file = "ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3"}, + {file = "ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc"}, + {file = "ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8"}, + {file = "ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521"}, + {file = "ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb"}, + {file = "ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82"}, + {file = "ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983"}, ] [[package]] From d90c8a86ce4ee39ff2d90e858f4fb48bca8508bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 01:29:43 +0000 Subject: [PATCH 269/598] build(deps-dev): bump mkdocs from 1.6.0 to 1.6.1 Bumps [mkdocs](https://github.com/mkdocs/mkdocs) from 1.6.0 to 1.6.1. - [Release notes](https://github.com/mkdocs/mkdocs/releases) - [Commits](https://github.com/mkdocs/mkdocs/compare/1.6.0...1.6.1) --- updated-dependencies: - dependency-name: mkdocs dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index ca1417dab8..8e2cfedfea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -702,13 +702,13 @@ files = [ [[package]] name = "mkdocs" -version = "1.6.0" +version = "1.6.1" description = "Project documentation with Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, - {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, + {file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"}, + {file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"}, ] [package.dependencies] From d874e7174a42eea808fd7c34328ca575ea6e5d47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 01:30:12 +0000 Subject: [PATCH 270/598] build(deps-dev): bump mkdocs-material from 9.5.33 to 9.5.34 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.33 to 9.5.34. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.33...9.5.34) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8e2cfedfea..ecdbbaf9f3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,13 +750,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.33" +version = "9.5.34" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.33-py3-none-any.whl", hash = "sha256:dbc79cf0fdc6e2c366aa987de8b0c9d4e2bb9f156e7466786ba2fd0f9bf7ffca"}, - {file = "mkdocs_material-9.5.33.tar.gz", hash = "sha256:d23a8b5e3243c9b2f29cdfe83051104a8024b767312dc8fde05ebe91ad55d89d"}, + {file = "mkdocs_material-9.5.34-py3-none-any.whl", hash = "sha256:54caa8be708de2b75167fd4d3b9f3d949579294f49cb242515d4653dbee9227e"}, + {file = "mkdocs_material-9.5.34.tar.gz", hash = "sha256:1e60ddf716cfb5679dfd65900b8a25d277064ed82d9a53cd5190e3f894df7840"}, ] [package.dependencies] From 74f66d194dcaf15a522f5c834374f58abc468d4e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Sep 2024 01:55:01 +0000 Subject: [PATCH 271/598] build(deps-dev): bump ruff from 0.6.3 to 0.6.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.3 to 0.6.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.3...0.6.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index ecdbbaf9f3..9792958a2d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.3" +version = "0.6.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3"}, - {file = "ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc"}, - {file = "ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1"}, - {file = "ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1"}, - {file = "ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672"}, - {file = "ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1"}, - {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384"}, - {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a"}, - {file = "ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500"}, - {file = "ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470"}, - {file = "ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f"}, - {file = "ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5"}, - {file = "ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351"}, - {file = "ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8"}, - {file = "ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521"}, - {file = "ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb"}, - {file = "ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82"}, - {file = "ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983"}, + {file = "ruff-0.6.4-py3-none-linux_armv6l.whl", hash = "sha256:c4b153fc152af51855458e79e835fb6b933032921756cec9af7d0ba2aa01a258"}, + {file = "ruff-0.6.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bedff9e4f004dad5f7f76a9d39c4ca98af526c9b1695068198b3bda8c085ef60"}, + {file = "ruff-0.6.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d02a4127a86de23002e694d7ff19f905c51e338c72d8e09b56bfb60e1681724f"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7862f42fc1a4aca1ea3ffe8a11f67819d183a5693b228f0bb3a531f5e40336fc"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eebe4ff1967c838a1a9618a5a59a3b0a00406f8d7eefee97c70411fefc353617"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:932063a03bac394866683e15710c25b8690ccdca1cf192b9a98260332ca93408"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:50e30b437cebef547bd5c3edf9ce81343e5dd7c737cb36ccb4fe83573f3d392e"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c44536df7b93a587de690e124b89bd47306fddd59398a0fb12afd6133c7b3818"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ea086601b22dc5e7693a78f3fcfc460cceabfdf3bdc36dc898792aba48fbad6"}, + {file = "ruff-0.6.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b52387d3289ccd227b62102c24714ed75fbba0b16ecc69a923a37e3b5e0aaaa"}, + {file = "ruff-0.6.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0308610470fcc82969082fc83c76c0d362f562e2f0cdab0586516f03a4e06ec6"}, + {file = "ruff-0.6.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:803b96dea21795a6c9d5bfa9e96127cc9c31a1987802ca68f35e5c95aed3fc0d"}, + {file = "ruff-0.6.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:66dbfea86b663baab8fcae56c59f190caba9398df1488164e2df53e216248baa"}, + {file = "ruff-0.6.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:34d5efad480193c046c86608dbba2bccdc1c5fd11950fb271f8086e0c763a5d1"}, + {file = "ruff-0.6.4-py3-none-win32.whl", hash = "sha256:f0f8968feea5ce3777c0d8365653d5e91c40c31a81d95824ba61d871a11b8523"}, + {file = "ruff-0.6.4-py3-none-win_amd64.whl", hash = "sha256:549daccee5227282289390b0222d0fbee0275d1db6d514550d65420053021a58"}, + {file = "ruff-0.6.4-py3-none-win_arm64.whl", hash = "sha256:ac4b75e898ed189b3708c9ab3fc70b79a433219e1e87193b4f2b77251d058d14"}, + {file = "ruff-0.6.4.tar.gz", hash = "sha256:ac3b5bfbee99973f80aa1b7cbd1c9cbce200883bdd067300c22a6cc1c7fba212"}, ] [[package]] From 31975566eb02c5f373224c86c3e4bf3f687f9075 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 01:16:49 +0000 Subject: [PATCH 272/598] build(deps-dev): bump types-python-dateutil Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.9.0.20240821 to 2.9.0.20240906. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-python-dateutil dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9792958a2d..a61503d276 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1559,13 +1559,13 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.9.0.20240821" +version = "2.9.0.20240906" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.9.0.20240821.tar.gz", hash = "sha256:9649d1dcb6fef1046fb18bebe9ea2aa0028b160918518c34589a46045f6ebd98"}, - {file = "types_python_dateutil-2.9.0.20240821-py3-none-any.whl", hash = "sha256:f5889fcb4e63ed4aaa379b44f93c32593d50b9a94c9a60a0c854d8cc3511cd57"}, + {file = "types-python-dateutil-2.9.0.20240906.tar.gz", hash = "sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e"}, + {file = "types_python_dateutil-2.9.0.20240906-py3-none-any.whl", hash = "sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6"}, ] [[package]] From d6547c12b1abaddc2cb9cd743f4e424c328e6773 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Wed, 11 Sep 2024 22:47:21 -0700 Subject: [PATCH 273/598] test(check): Python 3.13 help text format has been changed. Change the test accordingly --- ...check_command_shows_description_when_use_help_option.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt b/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt index 2ccf97270e..85f42f6d2a 100644 --- a/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_check_command/test_check_command_shows_description_when_use_help_option.txt @@ -1,6 +1,6 @@ -usage: cz check [-h] - [--commit-msg-file COMMIT_MSG_FILE | --rev-range REV_RANGE | -m MESSAGE] - [--allow-abort] [--allowed-prefixes [ALLOWED_PREFIXES ...]] +usage: cz check [-h] [--commit-msg-file COMMIT_MSG_FILE | + --rev-range REV_RANGE | -m MESSAGE] [--allow-abort] + [--allowed-prefixes [ALLOWED_PREFIXES ...]] [-l MESSAGE_LENGTH_LIMIT] validates that a commit message matches the commitizen schema From 6a5c1b132755668f1363293e704f10ff14b02687 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 02:01:06 +0000 Subject: [PATCH 274/598] build(deps-dev): bump ruff from 0.6.4 to 0.6.5 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.4 to 0.6.5. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.4...0.6.5) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index a61503d276..470b07fd1c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.4" +version = "0.6.5" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.4-py3-none-linux_armv6l.whl", hash = "sha256:c4b153fc152af51855458e79e835fb6b933032921756cec9af7d0ba2aa01a258"}, - {file = "ruff-0.6.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bedff9e4f004dad5f7f76a9d39c4ca98af526c9b1695068198b3bda8c085ef60"}, - {file = "ruff-0.6.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d02a4127a86de23002e694d7ff19f905c51e338c72d8e09b56bfb60e1681724f"}, - {file = "ruff-0.6.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7862f42fc1a4aca1ea3ffe8a11f67819d183a5693b228f0bb3a531f5e40336fc"}, - {file = "ruff-0.6.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eebe4ff1967c838a1a9618a5a59a3b0a00406f8d7eefee97c70411fefc353617"}, - {file = "ruff-0.6.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:932063a03bac394866683e15710c25b8690ccdca1cf192b9a98260332ca93408"}, - {file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:50e30b437cebef547bd5c3edf9ce81343e5dd7c737cb36ccb4fe83573f3d392e"}, - {file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c44536df7b93a587de690e124b89bd47306fddd59398a0fb12afd6133c7b3818"}, - {file = "ruff-0.6.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ea086601b22dc5e7693a78f3fcfc460cceabfdf3bdc36dc898792aba48fbad6"}, - {file = "ruff-0.6.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b52387d3289ccd227b62102c24714ed75fbba0b16ecc69a923a37e3b5e0aaaa"}, - {file = "ruff-0.6.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0308610470fcc82969082fc83c76c0d362f562e2f0cdab0586516f03a4e06ec6"}, - {file = "ruff-0.6.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:803b96dea21795a6c9d5bfa9e96127cc9c31a1987802ca68f35e5c95aed3fc0d"}, - {file = "ruff-0.6.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:66dbfea86b663baab8fcae56c59f190caba9398df1488164e2df53e216248baa"}, - {file = "ruff-0.6.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:34d5efad480193c046c86608dbba2bccdc1c5fd11950fb271f8086e0c763a5d1"}, - {file = "ruff-0.6.4-py3-none-win32.whl", hash = "sha256:f0f8968feea5ce3777c0d8365653d5e91c40c31a81d95824ba61d871a11b8523"}, - {file = "ruff-0.6.4-py3-none-win_amd64.whl", hash = "sha256:549daccee5227282289390b0222d0fbee0275d1db6d514550d65420053021a58"}, - {file = "ruff-0.6.4-py3-none-win_arm64.whl", hash = "sha256:ac4b75e898ed189b3708c9ab3fc70b79a433219e1e87193b4f2b77251d058d14"}, - {file = "ruff-0.6.4.tar.gz", hash = "sha256:ac3b5bfbee99973f80aa1b7cbd1c9cbce200883bdd067300c22a6cc1c7fba212"}, + {file = "ruff-0.6.5-py3-none-linux_armv6l.whl", hash = "sha256:7e4e308f16e07c95fc7753fc1aaac690a323b2bb9f4ec5e844a97bb7fbebd748"}, + {file = "ruff-0.6.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:932cd69eefe4daf8c7d92bd6689f7e8182571cb934ea720af218929da7bd7d69"}, + {file = "ruff-0.6.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3a8d42d11fff8d3143ff4da41742a98f8f233bf8890e9fe23077826818f8d680"}, + {file = "ruff-0.6.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a50af6e828ee692fb10ff2dfe53f05caecf077f4210fae9677e06a808275754f"}, + {file = "ruff-0.6.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:794ada3400a0d0b89e3015f1a7e01f4c97320ac665b7bc3ade24b50b54cb2972"}, + {file = "ruff-0.6.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:381413ec47f71ce1d1c614f7779d88886f406f1fd53d289c77e4e533dc6ea200"}, + {file = "ruff-0.6.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:52e75a82bbc9b42e63c08d22ad0ac525117e72aee9729a069d7c4f235fc4d276"}, + {file = "ruff-0.6.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09c72a833fd3551135ceddcba5ebdb68ff89225d30758027280968c9acdc7810"}, + {file = "ruff-0.6.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:800c50371bdcb99b3c1551d5691e14d16d6f07063a518770254227f7f6e8c178"}, + {file = "ruff-0.6.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e25ddd9cd63ba1f3bd51c1f09903904a6adf8429df34f17d728a8fa11174253"}, + {file = "ruff-0.6.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7291e64d7129f24d1b0c947ec3ec4c0076e958d1475c61202497c6aced35dd19"}, + {file = "ruff-0.6.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9ad7dfbd138d09d9a7e6931e6a7e797651ce29becd688be8a0d4d5f8177b4b0c"}, + {file = "ruff-0.6.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:005256d977021790cc52aa23d78f06bb5090dc0bfbd42de46d49c201533982ae"}, + {file = "ruff-0.6.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:482c1e6bfeb615eafc5899127b805d28e387bd87db38b2c0c41d271f5e58d8cc"}, + {file = "ruff-0.6.5-py3-none-win32.whl", hash = "sha256:cf4d3fa53644137f6a4a27a2b397381d16454a1566ae5335855c187fbf67e4f5"}, + {file = "ruff-0.6.5-py3-none-win_amd64.whl", hash = "sha256:3e42a57b58e3612051a636bc1ac4e6b838679530235520e8f095f7c44f706ff9"}, + {file = "ruff-0.6.5-py3-none-win_arm64.whl", hash = "sha256:51935067740773afdf97493ba9b8231279e9beef0f2a8079188c4776c25688e0"}, + {file = "ruff-0.6.5.tar.gz", hash = "sha256:4d32d87fab433c0cf285c3683dd4dae63be05fd7a1d65b3f5bf7cdd05a6b96fb"}, ] [[package]] From 7e881da545ec976fc803af67b0ad0f5c509ab1f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:44:00 +0000 Subject: [PATCH 275/598] build(deps-dev): bump pytest from 8.3.2 to 8.3.3 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.2 to 8.3.3. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.2...8.3.3) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 470b07fd1c..7da50be4d3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1054,13 +1054,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.3.2" +version = "8.3.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, - {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, + {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, + {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, ] [package.dependencies] From 620b9757004f07c3620a59bf3388c48321dfaafd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:44:37 +0000 Subject: [PATCH 276/598] build(deps-dev): bump rich from 13.8.0 to 13.8.1 Bumps [rich](https://github.com/Textualize/rich) from 13.8.0 to 13.8.1. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.8.0...v13.8.1) --- updated-dependencies: - dependency-name: rich dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7da50be4d3..b900f88911 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1406,13 +1406,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.8.0" +version = "13.8.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.8.0-py3-none-any.whl", hash = "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc"}, - {file = "rich-13.8.0.tar.gz", hash = "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"}, + {file = "rich-13.8.1-py3-none-any.whl", hash = "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06"}, + {file = "rich-13.8.1.tar.gz", hash = "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a"}, ] [package.dependencies] From a4ef250c2f41e9f8a51d55e49dbccf596a826d77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 01:28:03 +0000 Subject: [PATCH 277/598] build(deps-dev): bump types-pyyaml Bumps [types-pyyaml](https://github.com/python/typeshed) from 6.0.12.20240808 to 6.0.12.20240917. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-pyyaml dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index b900f88911..4145f4d30d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1570,13 +1570,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.20240808" +version = "6.0.12.20240917" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.20240808.tar.gz", hash = "sha256:b8f76ddbd7f65440a8bda5526a9607e4c7a322dc2f8e1a8c405644f9a6f4b9af"}, - {file = "types_PyYAML-6.0.12.20240808-py3-none-any.whl", hash = "sha256:deda34c5c655265fc517b546c902aa6eed2ef8d3e921e4765fe606fe2afe8d35"}, + {file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"}, + {file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"}, ] [[package]] From 90a454aa8209577cc1c488e79d3cd17f5e5bbb91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:44:52 +0000 Subject: [PATCH 278/598] build(deps): bump importlib-metadata from 8.4.0 to 8.5.0 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 8.4.0 to 8.5.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v8.4.0...v8.5.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4145f4d30d..94ec30294f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -450,22 +450,26 @@ files = [ [[package]] name = "importlib-metadata" -version = "8.4.0" +version = "8.5.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, - {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, + {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, + {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, ] [package.dependencies] -zipp = ">=0.5" +zipp = ">=3.20" [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] [[package]] name = "iniconfig" @@ -1771,18 +1775,22 @@ files = [ [[package]] name = "zipp" -version = "3.19.1" +version = "3.20.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.19.1-py3-none-any.whl", hash = "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091"}, - {file = "zipp-3.19.1.tar.gz", hash = "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f"}, + {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, + {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] [metadata] lock-version = "2.0" From 31212bac3ee59b33050feec25bf60c567e740267 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 02:03:22 +0000 Subject: [PATCH 279/598] build(deps-dev): bump mkdocs-material from 9.5.34 to 9.5.35 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.34 to 9.5.35. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.34...9.5.35) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 94ec30294f..8a3aaed388 100644 --- a/poetry.lock +++ b/poetry.lock @@ -754,13 +754,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.34" +version = "9.5.35" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.34-py3-none-any.whl", hash = "sha256:54caa8be708de2b75167fd4d3b9f3d949579294f49cb242515d4653dbee9227e"}, - {file = "mkdocs_material-9.5.34.tar.gz", hash = "sha256:1e60ddf716cfb5679dfd65900b8a25d277064ed82d9a53cd5190e3f894df7840"}, + {file = "mkdocs_material-9.5.35-py3-none-any.whl", hash = "sha256:44e069d87732d29f4a2533ae0748fa0e67e270043270c71f04d0fba11a357b24"}, + {file = "mkdocs_material-9.5.35.tar.gz", hash = "sha256:0d233d7db067ac896bf22ee7950eebf2b1eaf26c155bb27382bf4174021cc117"}, ] [package.dependencies] From d151e9e02b1ea167aadde29bc6682e0b39d1fece Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 01:10:14 +0000 Subject: [PATCH 280/598] build(deps-dev): bump ruff from 0.6.5 to 0.6.7 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.5 to 0.6.7. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.5...0.6.7) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8a3aaed388..abd8c7d0bb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1429,29 +1429,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.5" +version = "0.6.7" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.5-py3-none-linux_armv6l.whl", hash = "sha256:7e4e308f16e07c95fc7753fc1aaac690a323b2bb9f4ec5e844a97bb7fbebd748"}, - {file = "ruff-0.6.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:932cd69eefe4daf8c7d92bd6689f7e8182571cb934ea720af218929da7bd7d69"}, - {file = "ruff-0.6.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3a8d42d11fff8d3143ff4da41742a98f8f233bf8890e9fe23077826818f8d680"}, - {file = "ruff-0.6.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a50af6e828ee692fb10ff2dfe53f05caecf077f4210fae9677e06a808275754f"}, - {file = "ruff-0.6.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:794ada3400a0d0b89e3015f1a7e01f4c97320ac665b7bc3ade24b50b54cb2972"}, - {file = "ruff-0.6.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:381413ec47f71ce1d1c614f7779d88886f406f1fd53d289c77e4e533dc6ea200"}, - {file = "ruff-0.6.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:52e75a82bbc9b42e63c08d22ad0ac525117e72aee9729a069d7c4f235fc4d276"}, - {file = "ruff-0.6.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09c72a833fd3551135ceddcba5ebdb68ff89225d30758027280968c9acdc7810"}, - {file = "ruff-0.6.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:800c50371bdcb99b3c1551d5691e14d16d6f07063a518770254227f7f6e8c178"}, - {file = "ruff-0.6.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e25ddd9cd63ba1f3bd51c1f09903904a6adf8429df34f17d728a8fa11174253"}, - {file = "ruff-0.6.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7291e64d7129f24d1b0c947ec3ec4c0076e958d1475c61202497c6aced35dd19"}, - {file = "ruff-0.6.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9ad7dfbd138d09d9a7e6931e6a7e797651ce29becd688be8a0d4d5f8177b4b0c"}, - {file = "ruff-0.6.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:005256d977021790cc52aa23d78f06bb5090dc0bfbd42de46d49c201533982ae"}, - {file = "ruff-0.6.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:482c1e6bfeb615eafc5899127b805d28e387bd87db38b2c0c41d271f5e58d8cc"}, - {file = "ruff-0.6.5-py3-none-win32.whl", hash = "sha256:cf4d3fa53644137f6a4a27a2b397381d16454a1566ae5335855c187fbf67e4f5"}, - {file = "ruff-0.6.5-py3-none-win_amd64.whl", hash = "sha256:3e42a57b58e3612051a636bc1ac4e6b838679530235520e8f095f7c44f706ff9"}, - {file = "ruff-0.6.5-py3-none-win_arm64.whl", hash = "sha256:51935067740773afdf97493ba9b8231279e9beef0f2a8079188c4776c25688e0"}, - {file = "ruff-0.6.5.tar.gz", hash = "sha256:4d32d87fab433c0cf285c3683dd4dae63be05fd7a1d65b3f5bf7cdd05a6b96fb"}, + {file = "ruff-0.6.7-py3-none-linux_armv6l.whl", hash = "sha256:08277b217534bfdcc2e1377f7f933e1c7957453e8a79764d004e44c40db923f2"}, + {file = "ruff-0.6.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c6707a32e03b791f4448dc0dce24b636cbcdee4dd5607adc24e5ee73fd86c00a"}, + {file = "ruff-0.6.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:533d66b7774ef224e7cf91506a7dafcc9e8ec7c059263ec46629e54e7b1f90ab"}, + {file = "ruff-0.6.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17a86aac6f915932d259f7bec79173e356165518859f94649d8c50b81ff087e9"}, + {file = "ruff-0.6.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3f8822defd260ae2460ea3832b24d37d203c3577f48b055590a426a722d50ef"}, + {file = "ruff-0.6.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ba4efe5c6dbbb58be58dd83feedb83b5e95c00091bf09987b4baf510fee5c99"}, + {file = "ruff-0.6.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:525201b77f94d2b54868f0cbe5edc018e64c22563da6c5c2e5c107a4e85c1c0d"}, + {file = "ruff-0.6.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8854450839f339e1049fdbe15d875384242b8e85d5c6947bb2faad33c651020b"}, + {file = "ruff-0.6.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f0b62056246234d59cbf2ea66e84812dc9ec4540518e37553513392c171cb18"}, + {file = "ruff-0.6.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b1462fa56c832dc0cea5b4041cfc9c97813505d11cce74ebc6d1aae068de36b"}, + {file = "ruff-0.6.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:02b083770e4cdb1495ed313f5694c62808e71764ec6ee5db84eedd82fd32d8f5"}, + {file = "ruff-0.6.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c05fd37013de36dfa883a3854fae57b3113aaa8abf5dea79202675991d48624"}, + {file = "ruff-0.6.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f49c9caa28d9bbfac4a637ae10327b3db00f47d038f3fbb2195c4d682e925b14"}, + {file = "ruff-0.6.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a0e1655868164e114ba43a908fd2d64a271a23660195017c17691fb6355d59bb"}, + {file = "ruff-0.6.7-py3-none-win32.whl", hash = "sha256:a939ca435b49f6966a7dd64b765c9df16f1faed0ca3b6f16acdf7731969deb35"}, + {file = "ruff-0.6.7-py3-none-win_amd64.whl", hash = "sha256:590445eec5653f36248584579c06252ad2e110a5d1f32db5420de35fb0e1c977"}, + {file = "ruff-0.6.7-py3-none-win_arm64.whl", hash = "sha256:b28f0d5e2f771c1fe3c7a45d3f53916fc74a480698c4b5731f0bea61e52137c8"}, + {file = "ruff-0.6.7.tar.gz", hash = "sha256:44e52129d82266fa59b587e2cd74def5637b730a69c4542525dfdecfaae38bd5"}, ] [[package]] From ee41af27f88c9e718c2a3e18ed7c8c10ef290d25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 01:09:43 +0000 Subject: [PATCH 281/598] build(deps-dev): bump mkdocs-material from 9.5.35 to 9.5.36 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.35 to 9.5.36. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.35...9.5.36) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index abd8c7d0bb..393b8b3222 100644 --- a/poetry.lock +++ b/poetry.lock @@ -754,13 +754,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.35" +version = "9.5.36" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.35-py3-none-any.whl", hash = "sha256:44e069d87732d29f4a2533ae0748fa0e67e270043270c71f04d0fba11a357b24"}, - {file = "mkdocs_material-9.5.35.tar.gz", hash = "sha256:0d233d7db067ac896bf22ee7950eebf2b1eaf26c155bb27382bf4174021cc117"}, + {file = "mkdocs_material-9.5.36-py3-none-any.whl", hash = "sha256:36734c1fd9404bea74236242ba3359b267fc930c7233b9fd086b0898825d0ac9"}, + {file = "mkdocs_material-9.5.36.tar.gz", hash = "sha256:140456f761320f72b399effc073fa3f8aac744c77b0970797c201cae2f6c967f"}, ] [package.dependencies] From 88f1e218e31f8a2d1c968fe50d38bd9f42828480 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Sep 2024 01:44:36 +0000 Subject: [PATCH 282/598] build(deps-dev): bump mkdocs-material from 9.5.36 to 9.5.37 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.36 to 9.5.37. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.36...9.5.37) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 393b8b3222..0b371d1a9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -754,13 +754,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.36" +version = "9.5.37" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.36-py3-none-any.whl", hash = "sha256:36734c1fd9404bea74236242ba3359b267fc930c7233b9fd086b0898825d0ac9"}, - {file = "mkdocs_material-9.5.36.tar.gz", hash = "sha256:140456f761320f72b399effc073fa3f8aac744c77b0970797c201cae2f6c967f"}, + {file = "mkdocs_material-9.5.37-py3-none-any.whl", hash = "sha256:6e8a986abad77be5edec3dd77cf1ddf2480963fb297a8e971f87a82fd464b070"}, + {file = "mkdocs_material-9.5.37.tar.gz", hash = "sha256:2c31607431ec234db124031255b0a9d4f3e1c3ecc2c47ad97ecfff0460471941"}, ] [package.dependencies] From db095386563cce8460ca8a0663067de3c15bc52d Mon Sep 17 00:00:00 2001 From: grahamhar Date: Mon, 26 Feb 2024 20:50:59 +0000 Subject: [PATCH 283/598] fix(changelog): handle custom tag_format in changelog generation When the tag_format does not follow the allowed schemas patterns then changlog generation fails. --- commitizen/changelog.py | 33 +++++++++++++++++------ commitizen/changelog_formats/base.py | 22 ++++++++++++++- commitizen/commands/changelog.py | 9 +++---- commitizen/providers/scm_provider.py | 6 +++++ docs/tutorials/monorepo_guidance.md | 40 ++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 docs/tutorials/monorepo_guidance.md diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 12d52f7b08..7da4c7a4df 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -93,16 +93,34 @@ def tag_included_in_changelog( return True -def get_version_tags(scheme: type[BaseVersion], tags: list[GitTag]) -> list[GitTag]: +def get_version_tags( + scheme: type[BaseVersion], tags: list[GitTag], tag_format: str +) -> list[GitTag]: valid_tags: list[GitTag] = [] + TAG_FORMAT_REGEXS = { + "$version": str(scheme.parser.pattern), + "$major": r"(?P\d+)", + "$minor": r"(?P\d+)", + "$patch": r"(?P\d+)", + "$prerelease": r"(?P\w+\d+)?", + "$devrelease": r"(?P\.dev\d+)?", + "${version}": str(scheme.parser.pattern), + "${major}": r"(?P\d+)", + "${minor}": r"(?P\d+)", + "${patch}": r"(?P\d+)", + "${prerelease}": r"(?P\w+\d+)?", + "${devrelease}": r"(?P\.dev\d+)?", + } + tag_format_regex = tag_format + for pattern, regex in TAG_FORMAT_REGEXS.items(): + tag_format_regex = tag_format_regex.replace(pattern, regex) for tag in tags: - try: - scheme(tag.name) - except InvalidVersion: - out.warn(f"InvalidVersion {tag}") - else: + if re.match(tag_format_regex, tag.name): valid_tags.append(tag) - + else: + out.warn( + f"InvalidVersion {tag.name} doesn't match configured tag format {tag_format}" + ) return valid_tags @@ -351,7 +369,6 @@ def get_oldest_and_newest_rev( oldest, newest = version.split("..") except ValueError: newest = version - newest_tag = normalize_tag(newest, tag_format=tag_format, scheme=scheme) oldest_tag = None diff --git a/commitizen/changelog_formats/base.py b/commitizen/changelog_formats/base.py index 7c802d63d4..807b3658cb 100644 --- a/commitizen/changelog_formats/base.py +++ b/commitizen/changelog_formats/base.py @@ -25,10 +25,30 @@ def __init__(self, config: BaseConfig): # See: https://bugs.python.org/issue44807 self.config = config self.encoding = self.config.settings["encoding"] + self.tag_format = self.config.settings.get("tag_format") @property def version_parser(self) -> Pattern: - return get_version_scheme(self.config).parser + version_regex = get_version_scheme(self.config).parser.pattern + if self.tag_format != "$version": + TAG_FORMAT_REGEXS = { + "$version": version_regex, + "$major": "(?P\d+)", + "$minor": "(?P\d+)", + "$patch": "(?P\d+)", + "$prerelease": "(?P\w+\d+)?", + "$devrelease": "(?P\.dev\d+)?", + "${version}": version_regex, + "${major}": "(?P\d+)", + "${minor}": "(?P\d+)", + "${patch}": "(?P\d+)", + "${prerelease}": "(?P\w+\d+)?", + "${devrelease}": "(?P\.dev\d+)?", + } + version_regex = self.tag_format + for pattern, regex in TAG_FORMAT_REGEXS.items(): + version_regex = version_regex.replace(pattern, regex) + return rf"{version_regex}" def get_metadata(self, filepath: str) -> Metadata: if not os.path.isfile(filepath): diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index bda7a1844f..25e644aaef 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -168,8 +168,10 @@ def __call__(self): # Don't continue if no `file_name` specified. assert self.file_name - tags = changelog.get_version_tags(self.scheme, git.get_tags()) or [] - + tags = ( + changelog.get_version_tags(self.scheme, git.get_tags(), self.tag_format) + or [] + ) end_rev = "" if self.incremental: changelog_meta = self.changelog_format.get_metadata(self.file_name) @@ -182,7 +184,6 @@ def __call__(self): start_rev = self._find_incremental_rev( strip_local_version(latest_tag_version), tags ) - if self.rev_range: start_rev, end_rev = changelog.get_oldest_and_newest_rev( tags, @@ -190,13 +191,11 @@ def __call__(self): tag_format=self.tag_format, scheme=self.scheme, ) - commits = git.get_commits(start=start_rev, end=end_rev, args="--topo-order") if not commits and ( self.current_version is None or not self.current_version.is_prerelease ): raise NoCommitsFoundError("No commits found") - tree = changelog.generate_tree_from_commits( commits, tags, diff --git a/commitizen/providers/scm_provider.py b/commitizen/providers/scm_provider.py index 00df3e4153..26ca593d27 100644 --- a/commitizen/providers/scm_provider.py +++ b/commitizen/providers/scm_provider.py @@ -29,6 +29,12 @@ class ScmProvider(VersionProvider): "$patch": r"(?P\d+)", "$prerelease": r"(?P\w+\d+)?", "$devrelease": r"(?P\.dev\d+)?", + "${version}": r"(?P.+)", + "${major}": r"(?P\d+)", + "${minor}": r"(?P\d+)", + "${patch}": r"(?P\d+)", + "${prerelease}": r"(?P\w+\d+)?", + "${devrelease}": r"(?P\.dev\d+)?", } def _tag_format_matcher(self) -> Callable[[str], VersionProtocol | None]: diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md new file mode 100644 index 0000000000..5bb334d725 --- /dev/null +++ b/docs/tutorials/monorepo_guidance.md @@ -0,0 +1,40 @@ +# Configuring commitizen in a monorepo + +This tutorial assumes the monorepo layout is designed with multiple components that can be released independently of each other, +some suggested layouts: + +``` +library-a + .cz.toml +library-b + .cz.toml +``` + +``` +src + library-b + .cz.toml + library-z + .cz.toml +``` + +Each component will have its own changelog, commits will need to use scopes so only relevant commits are included in the +appropriate change log for a given component. Example config and commit for `library-b` + +```toml +[tool.commitizen] +name = "cz_customize" +version = "0.0.0" +tag_format = "${version}-library-b" # the component name can be a prefix or suffix with or without a separator +update_changelog_on_bump = true + +[tool.commitizen.customize] +changelog_pattern = "^(feat|fix)\\(library-b\\)(!)?:" #the pattern on types can be a wild card or any types you wish to include +``` + +example commit message for the above + +`fix:(library-b) Some awesome message` + +If the above is followed and the `cz bump --changelog` is run in the directory containing the component the changelog +should be generated in the same directory with only commits scoped to the component. From b0237119b0579fe3f5e42e31d2d9997954045da1 Mon Sep 17 00:00:00 2001 From: grahamhar Date: Sat, 2 Mar 2024 14:03:36 +0000 Subject: [PATCH 284/598] test(changelog): handle custom tag_format in changelog generation --- tests/commands/test_changelog_command.py | 114 +++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 3d9a5c5c48..5c7a8a9faa 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -1523,6 +1523,120 @@ def test_changelog_template_extras_precedance( assert changelog.read_text() == "from-command - from-config - from-plugin" +@pytest.mark.usefixtures("tmp_commitizen_project") +@pytest.mark.freeze_time("2021-06-11") +def test_changelog_only_tag_matching_tag_format_included_prefix( + mocker: MockFixture, + changelog_path: Path, + config_path: Path, +): + with open(config_path, "a", encoding="utf-8") as f: + f.write('\ntag_format = "custom${version}"\n') + create_file_and_commit("feat: new file") + git.tag("v0.2.0") + create_file_and_commit("feat: another new file") + git.tag("0.2.0") + git.tag("random0.2.0") + testargs = ["cz", "bump", "--changelog", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + wait_for_tag() + create_file_and_commit("feat: another new file") + cli.main() + with open(changelog_path) as f: + out = f.read() + assert out.startswith("## custom0.3.0 (2021-06-11)") + assert "## v0.2.0 (2021-06-11)" not in out + assert "## 0.2.0 (2021-06-11)" not in out + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_changelog_only_tag_matching_tag_format_included_prefix_sep( + mocker: MockFixture, + changelog_path: Path, + config_path: Path, +): + with open(config_path, "a", encoding="utf-8") as f: + f.write('\ntag_format = "custom-${version}"\n') + create_file_and_commit("feat: new file") + git.tag("v0.2.0") + create_file_and_commit("feat: another new file") + git.tag("0.2.0") + git.tag("random0.2.0") + wait_for_tag() + testargs = ["cz", "bump", "--changelog", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + with open(changelog_path) as f: + out = f.read() + create_file_and_commit("feat: new version another new file") + create_file_and_commit("feat: new version some new file") + testargs = ["cz", "bump", "--changelog"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + with open(changelog_path) as f: + out = f.read() + assert out.startswith("## custom-0.3.0") + assert "## v0.2.0" not in out + assert "## 0.2.0" not in out + + +@pytest.mark.usefixtures("tmp_commitizen_project") +@pytest.mark.freeze_time("2021-06-11") +def test_changelog_only_tag_matching_tag_format_included_suffix( + mocker: MockFixture, + changelog_path: Path, + config_path: Path, +): + with open(config_path, "a", encoding="utf-8") as f: + f.write('\ntag_format = "${version}custom"\n') + create_file_and_commit("feat: new file") + git.tag("v0.2.0") + create_file_and_commit("feat: another new file") + git.tag("0.2.0") + git.tag("random0.2.0") + testargs = ["cz", "bump", "--changelog", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + wait_for_tag() + create_file_and_commit("feat: another new file") + cli.main() + wait_for_tag() + with open(changelog_path) as f: + out = f.read() + assert out.startswith("## 0.3.0custom (2021-06-11)") + assert "## v0.2.0 (2021-06-11)" not in out + assert "## 0.2.0 (2021-06-11)" not in out + + +@pytest.mark.usefixtures("tmp_commitizen_project") +@pytest.mark.freeze_time("2021-06-11") +def test_changelog_only_tag_matching_tag_format_included_suffix_sep( + mocker: MockFixture, + changelog_path: Path, + config_path: Path, +): + with open(config_path, "a", encoding="utf-8") as f: + f.write('\ntag_format = "${version}-custom"\n') + create_file_and_commit("feat: new file") + git.tag("v0.2.0") + create_file_and_commit("feat: another new file") + git.tag("0.2.0") + git.tag("random0.2.0") + testargs = ["cz", "bump", "--changelog", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + wait_for_tag() + create_file_and_commit("feat: another new file") + cli.main() + wait_for_tag() + with open(changelog_path) as f: + out = f.read() + assert out.startswith("## 0.3.0-custom (2021-06-11)") + assert "## v0.2.0 (2021-06-11)" not in out + assert "## 0.2.0 (2021-06-11)" not in out + + def test_changelog_template_extra_quotes( mocker: MockFixture, tmp_commitizen_project: Path, From 12c3f311f52b87b8d607b2e12319dca18fe466a4 Mon Sep 17 00:00:00 2001 From: grahamhar Date: Mon, 1 Apr 2024 18:38:40 +0100 Subject: [PATCH 285/598] fix(changelog): Handle tag format without version pattern --- commitizen/changelog.py | 4 +- commitizen/changelog_formats/asciidoc.py | 14 +++- commitizen/changelog_formats/base.py | 40 +++++------ commitizen/changelog_formats/markdown.py | 16 ++++- .../changelog_formats/restructuredtext.py | 24 +++++-- commitizen/changelog_formats/textile.py | 16 ++++- tests/test_changelog_format_asciidoc.py | 61 +++++++++++++++++ tests/test_changelog_format_markdown.py | 67 +++++++++++++++++++ .../test_changelog_format_restructuredtext.py | 66 ++++++++++++++++++ tests/test_changelog_format_textile.py | 55 +++++++++++++++ 10 files changed, 333 insertions(+), 30 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 7da4c7a4df..fc9d567002 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -98,13 +98,13 @@ def get_version_tags( ) -> list[GitTag]: valid_tags: list[GitTag] = [] TAG_FORMAT_REGEXS = { - "$version": str(scheme.parser.pattern), + "$version": scheme.parser.pattern, "$major": r"(?P\d+)", "$minor": r"(?P\d+)", "$patch": r"(?P\d+)", "$prerelease": r"(?P\w+\d+)?", "$devrelease": r"(?P\.dev\d+)?", - "${version}": str(scheme.parser.pattern), + "${version}": scheme.parser.pattern, "${major}": r"(?P\d+)", "${minor}": r"(?P\d+)", "${patch}": r"(?P\d+)", diff --git a/commitizen/changelog_formats/asciidoc.py b/commitizen/changelog_formats/asciidoc.py index d738926f6e..bca7464b06 100644 --- a/commitizen/changelog_formats/asciidoc.py +++ b/commitizen/changelog_formats/asciidoc.py @@ -18,7 +18,19 @@ def parse_version_from_title(self, line: str) -> str | None: matches = list(re.finditer(self.version_parser, m.group("title"))) if not matches: return None - return matches[-1].group("version") + if "version" in matches[-1].groupdict(): + return matches[-1].group("version") + partial_matches = matches[-1].groupdict() + try: + partial_version = f"{partial_matches['major']}.{partial_matches['minor']}.{partial_matches['patch']}" + except KeyError: + return None + + if partial_matches.get("prerelease"): + partial_version += f"-{partial_matches['prerelease']}" + if partial_matches.get("devrelease"): + partial_version += f"{partial_matches['devrelease']}" + return partial_version def parse_title_level(self, line: str) -> int | None: m = self.RE_TITLE.match(line) diff --git a/commitizen/changelog_formats/base.py b/commitizen/changelog_formats/base.py index 807b3658cb..8c41c7136a 100644 --- a/commitizen/changelog_formats/base.py +++ b/commitizen/changelog_formats/base.py @@ -1,6 +1,7 @@ from __future__ import annotations import os +import re from abc import ABCMeta from re import Pattern from typing import IO, Any, ClassVar @@ -25,30 +26,29 @@ def __init__(self, config: BaseConfig): # See: https://bugs.python.org/issue44807 self.config = config self.encoding = self.config.settings["encoding"] - self.tag_format = self.config.settings.get("tag_format") + self.tag_format = self.config.settings["tag_format"] @property def version_parser(self) -> Pattern: + tag_regex: str = self.tag_format version_regex = get_version_scheme(self.config).parser.pattern - if self.tag_format != "$version": - TAG_FORMAT_REGEXS = { - "$version": version_regex, - "$major": "(?P\d+)", - "$minor": "(?P\d+)", - "$patch": "(?P\d+)", - "$prerelease": "(?P\w+\d+)?", - "$devrelease": "(?P\.dev\d+)?", - "${version}": version_regex, - "${major}": "(?P\d+)", - "${minor}": "(?P\d+)", - "${patch}": "(?P\d+)", - "${prerelease}": "(?P\w+\d+)?", - "${devrelease}": "(?P\.dev\d+)?", - } - version_regex = self.tag_format - for pattern, regex in TAG_FORMAT_REGEXS.items(): - version_regex = version_regex.replace(pattern, regex) - return rf"{version_regex}" + TAG_FORMAT_REGEXS = { + "$version": version_regex, + "$major": r"(?P\d+)", + "$minor": r"(?P\d+)", + "$patch": r"(?P\d+)", + "$prerelease": r"(?P\w+\d+)?", + "$devrelease": r"(?P\.dev\d+)?", + "${version}": version_regex, + "${major}": r"(?P\d+)", + "${minor}": r"(?P\d+)", + "${patch}": r"(?P\d+)", + "${prerelease}": r"(?P\w+\d+)?", + "${devrelease}": r"(?P\.dev\d+)?", + } + for pattern, regex in TAG_FORMAT_REGEXS.items(): + tag_regex = tag_regex.replace(pattern, regex) + return re.compile(tag_regex) def get_metadata(self, filepath: str) -> Metadata: if not os.path.isfile(filepath): diff --git a/commitizen/changelog_formats/markdown.py b/commitizen/changelog_formats/markdown.py index a5a0f42de3..2e9aa23663 100644 --- a/commitizen/changelog_formats/markdown.py +++ b/commitizen/changelog_formats/markdown.py @@ -19,7 +19,21 @@ def parse_version_from_title(self, line: str) -> str | None: m = re.search(self.version_parser, m.group("title")) if not m: return None - return m.group("version") + if "version" in m.groupdict(): + return m.group("version") + matches = m.groupdict() + try: + partial_version = ( + f"{matches['major']}.{matches['minor']}.{matches['patch']}" + ) + except KeyError: + return None + + if matches.get("prerelease"): + partial_version += f"-{matches['prerelease']}" + if matches.get("devrelease"): + partial_version += f"{matches['devrelease']}" + return partial_version def parse_title_level(self, line: str) -> int | None: m = self.RE_TITLE.match(line) diff --git a/commitizen/changelog_formats/restructuredtext.py b/commitizen/changelog_formats/restructuredtext.py index 37acf81ef3..be07322c9b 100644 --- a/commitizen/changelog_formats/restructuredtext.py +++ b/commitizen/changelog_formats/restructuredtext.py @@ -46,7 +46,6 @@ def get_metadata_from_file(self, file: IO[Any]) -> Metadata: third = third.strip().lower() title: str | None = None kind: TitleKind | None = None - if self.is_overlined_title(first, second, third): title = second kind = (first[0], third[0]) @@ -67,10 +66,25 @@ def get_metadata_from_file(self, file: IO[Any]) -> Metadata: # Try to find the latest release done m = re.search(self.version_parser, title) if m: - version = m.group("version") - meta.latest_version = version - meta.latest_version_position = index - break # there's no need for more info + matches = m.groupdict() + if "version" in matches: + version = m.group("version") + meta.latest_version = version + meta.latest_version_position = index + break # there's no need for more info + try: + partial_version = ( + f"{matches['major']}.{matches['minor']}.{matches['patch']}" + ) + if matches.get("prerelease"): + partial_version += f"-{matches['prerelease']}" + if matches.get("devrelease"): + partial_version += f"{matches['devrelease']}" + meta.latest_version = partial_version + meta.latest_version_position = index + break + except KeyError: + pass if meta.unreleased_start is not None and meta.unreleased_end is None: meta.unreleased_end = ( meta.latest_version_position if meta.latest_version else index + 1 diff --git a/commitizen/changelog_formats/textile.py b/commitizen/changelog_formats/textile.py index 80118cdb3c..4f34b522fa 100644 --- a/commitizen/changelog_formats/textile.py +++ b/commitizen/changelog_formats/textile.py @@ -16,7 +16,21 @@ def parse_version_from_title(self, line: str) -> str | None: m = re.search(self.version_parser, line) if not m: return None - return m.group("version") + if "version" in m.groupdict(): + return m.group("version") + matches = m.groupdict() + try: + partial_version = ( + f"{matches['major']}.{matches['minor']}.{matches['patch']}" + ) + except KeyError: + return None + + if matches.get("prerelease"): + partial_version += f"-{matches['prerelease']}" + if matches.get("devrelease"): + partial_version += f"{matches['devrelease']}" + return partial_version def parse_title_level(self, line: str) -> int | None: m = self.RE_TITLE.match(line) diff --git a/tests/test_changelog_format_asciidoc.py b/tests/test_changelog_format_asciidoc.py index 89740d2147..0c5930df46 100644 --- a/tests/test_changelog_format_asciidoc.py +++ b/tests/test_changelog_format_asciidoc.py @@ -72,12 +72,42 @@ unreleased_start=1, ) +CHANGELOG_E = """ += Changelog + +All notable changes to this project will be documented in this file. + +The format is based on https://keepachangelog.com/en/1.0.0/[Keep a Changelog], +and this project adheres to https://semver.org/spec/v2.0.0.html[Semantic Versioning]. + +== [Unreleased] +* Start using "changelog" over "change log" since it's the common usage. + +== [{tag_formatted_version}] - 2017-06-20 +=== Added +* New visual identity by https://github.com/tylerfortune8[@tylerfortune8]. +* Version navigation. +""".strip() + +EXPECTED_E = Metadata( + latest_version="1.0.0", + latest_version_position=10, + unreleased_end=10, + unreleased_start=7, +) + @pytest.fixture def format(config: BaseConfig) -> AsciiDoc: return AsciiDoc(config) +@pytest.fixture +def format_with_tags(config: BaseConfig, request) -> AsciiDoc: + config.settings["tag_format"] = request.param + return AsciiDoc(config) + + VERSIONS_EXAMPLES = [ ("== [1.0.0] - 2017-06-20", "1.0.0"), ( @@ -135,3 +165,34 @@ def test_get_matadata( changelog.write_text(content) assert format.get_metadata(str(changelog)) == expected + + +@pytest.mark.parametrize( + "format_with_tags, tag_string, expected, ", + ( + pytest.param("${version}-example", "1.0.0-example", "1.0.0"), + pytest.param("${version}example", "1.0.0example", "1.0.0"), + pytest.param("example${version}", "example1.0.0", "1.0.0"), + pytest.param("example-${version}", "example-1.0.0", "1.0.0"), + pytest.param("example-${major}-${minor}-${patch}", "example-1-0-0", "1.0.0"), + pytest.param("example-${major}-${minor}", "example-1-0-0", None), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}-example", + "1-0-0-rc1-example", + "1.0.0-rc1", + ), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}${devrelease}-example", + "1-0-0-a1.dev1-example", + "1.0.0-a1.dev1", + ), + ), + indirect=["format_with_tags"], +) +def test_get_metadata_custom_tag_format( + tmp_path: Path, format_with_tags: AsciiDoc, tag_string: str, expected: Metadata +): + content = CHANGELOG_E.format(tag_formatted_version=tag_string) + changelog = tmp_path / format_with_tags.default_changelog_file + changelog.write_text(content) + assert format_with_tags.get_metadata(str(changelog)).latest_version == expected diff --git a/tests/test_changelog_format_markdown.py b/tests/test_changelog_format_markdown.py index ab7c65453c..52612b8e2b 100644 --- a/tests/test_changelog_format_markdown.py +++ b/tests/test_changelog_format_markdown.py @@ -72,12 +72,42 @@ unreleased_start=1, ) +CHANGELOG_E = """ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] +- Start using "changelog" over "change log" since it's the common usage. + +## {tag_formatted_version} - 2017-06-20 +### Added +- New visual identity by [@tylerfortune8](https://github.com/tylerfortune8). +- Version navigation. +""".strip() + +EXPECTED_E = Metadata( + latest_version="1.0.0", + latest_version_position=10, + unreleased_end=10, + unreleased_start=7, +) + @pytest.fixture def format(config: BaseConfig) -> Markdown: return Markdown(config) +@pytest.fixture +def format_with_tags(config: BaseConfig, request) -> Markdown: + config.settings["tag_format"] = request.param + return Markdown(config) + + VERSIONS_EXAMPLES = [ ("## [1.0.0] - 2017-06-20", "1.0.0"), ( @@ -135,3 +165,40 @@ def test_get_matadata( changelog.write_text(content) assert format.get_metadata(str(changelog)) == expected + + +@pytest.mark.parametrize( + "format_with_tags, tag_string, expected, ", + ( + pytest.param("${version}-example", "1.0.0-example", "1.0.0"), + pytest.param("${version}example", "1.0.0example", "1.0.0"), + pytest.param("example${version}", "example1.0.0", "1.0.0"), + pytest.param("example-${version}", "example-1.0.0", "1.0.0"), + pytest.param("example-${major}-${minor}-${patch}", "example-1-0-0", "1.0.0"), + pytest.param("example-${major}-${minor}", "example-1-0-0", None), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}-example", + "1-0-0-rc1-example", + "1.0.0-rc1", + ), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}-example", + "1-0-0-a1-example", + "1.0.0-a1", + ), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}${devrelease}-example", + "1-0-0-a1.dev1-example", + "1.0.0-a1.dev1", + ), + ), + indirect=["format_with_tags"], +) +def test_get_metadata_custom_tag_format( + tmp_path: Path, format_with_tags: Markdown, tag_string: str, expected: Metadata +): + content = CHANGELOG_E.format(tag_formatted_version=tag_string) + changelog = tmp_path / format_with_tags.default_changelog_file + changelog.write_text(content) + + assert format_with_tags.get_metadata(str(changelog)).latest_version == expected diff --git a/tests/test_changelog_format_restructuredtext.py b/tests/test_changelog_format_restructuredtext.py index 46a11ebcdf..11356ae28f 100644 --- a/tests/test_changelog_format_restructuredtext.py +++ b/tests/test_changelog_format_restructuredtext.py @@ -273,12 +273,39 @@ def case( """, ) +CHANGELOG = """ +Changelog + ######### + + All notable changes to this project will be documented in this file. + + The format is based on `Keep a Changelog `, + and this project adheres to `Semantic Versioning `. + + Unreleased + ========== + * Start using "changelog" over "change log" since it's the common usage. + + {tag_formatted_version} - 2017-06-20 + {underline} + Added + ----- + * New visual identity by `@tylerfortune8 `. + * Version navigation. +""".strip() + @pytest.fixture def format(config: BaseConfig) -> RestructuredText: return RestructuredText(config) +@pytest.fixture +def format_with_tags(config: BaseConfig, request) -> RestructuredText: + config.settings["tag_format"] = request.param + return RestructuredText(config) + + @pytest.mark.parametrize("content, expected", CASES) def test_get_matadata( tmp_path: Path, format: RestructuredText, content: str, expected: Metadata @@ -308,3 +335,42 @@ def test_is_overlined_title(format: RestructuredText, text: str, expected: bool) _, first, second, third = dedent(text).splitlines() assert format.is_overlined_title(first, second, third) is expected + + +@pytest.mark.parametrize( + "format_with_tags, tag_string, expected, ", + ( + pytest.param("${version}-example", "1.0.0-example", "1.0.0"), + pytest.param("${version}", "1.0.0", "1.0.0"), + pytest.param("${version}example", "1.0.0example", "1.0.0"), + pytest.param("example${version}", "example1.0.0", "1.0.0"), + pytest.param("example-${version}", "example-1.0.0", "1.0.0"), + pytest.param("example-${major}-${minor}-${patch}", "example-1-0-0", "1.0.0"), + pytest.param("example-${major}-${minor}", "example-1-0-0", None), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}-example", + "1-0-0-rc1-example", + "1.0.0-rc1", + ), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}${devrelease}-example", + "1-0-0-a1.dev1-example", + "1.0.0-a1.dev1", + ), + ), + indirect=["format_with_tags"], +) +def test_get_metadata_custom_tag_format( + tmp_path: Path, + format_with_tags: RestructuredText, + tag_string: str, + expected: Metadata, +): + content = CHANGELOG.format( + tag_formatted_version=tag_string, + underline="=" * len(tag_string) + "=============", + ) + changelog = tmp_path / format_with_tags.default_changelog_file + changelog.write_text(content) + + assert format_with_tags.get_metadata(str(changelog)).latest_version == expected diff --git a/tests/test_changelog_format_textile.py b/tests/test_changelog_format_textile.py index e382e1c746..3fac5c1756 100644 --- a/tests/test_changelog_format_textile.py +++ b/tests/test_changelog_format_textile.py @@ -72,12 +72,35 @@ unreleased_start=1, ) +CHANGELOG_E = """ +h1. Changelog + +All notable changes to this project will be documented in this file. + +The format is based on "Keep a Changelog":https://keepachangelog.com/en/1.0.0/, +and this project adheres to "Semantic Versioning":https://semver.org/spec/v2.0.0.html. + +h2. [Unreleased] +- Start using "changelog" over "change log" since it's the common usage. + +h2. [{tag_formatted_version}] - 2017-06-20 +h3. Added +* New visual identity by [@tylerfortune8](https://github.com/tylerfortune8). +* Version navigation. +""".strip() + @pytest.fixture def format(config: BaseConfig) -> Textile: return Textile(config) +@pytest.fixture +def format_with_tags(config: BaseConfig, request) -> Textile: + config.settings["tag_format"] = request.param + return Textile(config) + + VERSIONS_EXAMPLES = [ ("h2. [1.0.0] - 2017-06-20", "1.0.0"), ( @@ -135,3 +158,35 @@ def test_get_matadata( changelog.write_text(content) assert format.get_metadata(str(changelog)) == expected + + +@pytest.mark.parametrize( + "format_with_tags, tag_string, expected, ", + ( + pytest.param("${version}-example", "1.0.0-example", "1.0.0"), + pytest.param("${version}example", "1.0.0example", "1.0.0"), + pytest.param("example${version}", "example1.0.0", "1.0.0"), + pytest.param("example-${version}", "example-1.0.0", "1.0.0"), + pytest.param("example-${major}-${minor}-${patch}", "example-1-0-0", "1.0.0"), + pytest.param("example-${major}-${minor}", "example-1-0-0", None), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}-example", + "1-0-0-rc1-example", + "1.0.0-rc1", + ), + pytest.param( + "${major}-${minor}-${patch}-${prerelease}${devrelease}-example", + "1-0-0-a1.dev1-example", + "1.0.0-a1.dev1", + ), + ), + indirect=["format_with_tags"], +) +def test_get_metadata_custom_tag_format( + tmp_path: Path, format_with_tags: Textile, tag_string: str, expected: Metadata +): + content = CHANGELOG_E.format(tag_formatted_version=tag_string) + changelog = tmp_path / format_with_tags.default_changelog_file + changelog.write_text(content) + + assert format_with_tags.get_metadata(str(changelog)).latest_version == expected From ca3865f143fc116d10ef2a12ed677ba43158c9ae Mon Sep 17 00:00:00 2001 From: grahamhar Date: Sat, 20 Apr 2024 11:21:18 +0100 Subject: [PATCH 286/598] fix(changelog): Factorized TAG_FORMAT_REGEXES --- commitizen/changelog.py | 16 ++-------------- commitizen/changelog_formats/base.py | 16 ++-------------- commitizen/defaults.py | 17 +++++++++++++++++ commitizen/providers/scm_provider.py | 16 ++-------------- 4 files changed, 23 insertions(+), 42 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index fc9d567002..32a66c47eb 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -44,6 +44,7 @@ from commitizen import out from commitizen.bump import normalize_tag from commitizen.cz.base import ChangelogReleaseHook +from commitizen.defaults import get_tag_regexes from commitizen.exceptions import InvalidConfigurationError, NoCommitsFoundError from commitizen.git import GitCommit, GitTag from commitizen.version_schemes import ( @@ -97,20 +98,7 @@ def get_version_tags( scheme: type[BaseVersion], tags: list[GitTag], tag_format: str ) -> list[GitTag]: valid_tags: list[GitTag] = [] - TAG_FORMAT_REGEXS = { - "$version": scheme.parser.pattern, - "$major": r"(?P\d+)", - "$minor": r"(?P\d+)", - "$patch": r"(?P\d+)", - "$prerelease": r"(?P\w+\d+)?", - "$devrelease": r"(?P\.dev\d+)?", - "${version}": scheme.parser.pattern, - "${major}": r"(?P\d+)", - "${minor}": r"(?P\d+)", - "${patch}": r"(?P\d+)", - "${prerelease}": r"(?P\w+\d+)?", - "${devrelease}": r"(?P\.dev\d+)?", - } + TAG_FORMAT_REGEXS = get_tag_regexes(scheme.parser.pattern) tag_format_regex = tag_format for pattern, regex in TAG_FORMAT_REGEXS.items(): tag_format_regex = tag_format_regex.replace(pattern, regex) diff --git a/commitizen/changelog_formats/base.py b/commitizen/changelog_formats/base.py index 8c41c7136a..415c404c91 100644 --- a/commitizen/changelog_formats/base.py +++ b/commitizen/changelog_formats/base.py @@ -9,6 +9,7 @@ from commitizen.changelog import Metadata from commitizen.config.base_config import BaseConfig from commitizen.version_schemes import get_version_scheme +from commitizen.defaults import get_tag_regexes from . import ChangelogFormat @@ -32,20 +33,7 @@ def __init__(self, config: BaseConfig): def version_parser(self) -> Pattern: tag_regex: str = self.tag_format version_regex = get_version_scheme(self.config).parser.pattern - TAG_FORMAT_REGEXS = { - "$version": version_regex, - "$major": r"(?P\d+)", - "$minor": r"(?P\d+)", - "$patch": r"(?P\d+)", - "$prerelease": r"(?P\w+\d+)?", - "$devrelease": r"(?P\.dev\d+)?", - "${version}": version_regex, - "${major}": r"(?P\d+)", - "${minor}": r"(?P\d+)", - "${patch}": r"(?P\d+)", - "${prerelease}": r"(?P\w+\d+)?", - "${devrelease}": r"(?P\.dev\d+)?", - } + TAG_FORMAT_REGEXS = get_tag_regexes(version_regex) for pattern, regex in TAG_FORMAT_REGEXS.items(): tag_regex = tag_regex.replace(pattern, regex) return re.compile(tag_regex) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index e4363f4ab0..0f857f264a 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -132,3 +132,20 @@ class Settings(TypedDict, total=False): ) change_type_order = ["BREAKING CHANGE", "Feat", "Fix", "Refactor", "Perf"] bump_message = "bump: version $current_version → $new_version" + + +def get_tag_regexes(version_regex: str) -> dict[str | Any, str | Any]: + return { + "$version": version_regex, + "$major": r"(?P\d+)", + "$minor": r"(?P\d+)", + "$patch": r"(?P\d+)", + "$prerelease": r"(?P\w+\d+)?", + "$devrelease": r"(?P\.dev\d+)?", + "${version}": version_regex, + "${major}": r"(?P\d+)", + "${minor}": r"(?P\d+)", + "${patch}": r"(?P\d+)", + "${prerelease}": r"(?P\w+\d+)?", + "${devrelease}": r"(?P\.dev\d+)?", + } diff --git a/commitizen/providers/scm_provider.py b/commitizen/providers/scm_provider.py index 26ca593d27..33e470cfc6 100644 --- a/commitizen/providers/scm_provider.py +++ b/commitizen/providers/scm_provider.py @@ -3,6 +3,7 @@ import re from typing import Callable +from commitizen.defaults import get_tag_regexes from commitizen.git import get_tags from commitizen.providers.base_provider import VersionProvider from commitizen.version_schemes import ( @@ -22,20 +23,7 @@ class ScmProvider(VersionProvider): It is meant for `setuptools-scm` or any package manager `*-scm` provider. """ - TAG_FORMAT_REGEXS = { - "$version": r"(?P.+)", - "$major": r"(?P\d+)", - "$minor": r"(?P\d+)", - "$patch": r"(?P\d+)", - "$prerelease": r"(?P\w+\d+)?", - "$devrelease": r"(?P\.dev\d+)?", - "${version}": r"(?P.+)", - "${major}": r"(?P\d+)", - "${minor}": r"(?P\d+)", - "${patch}": r"(?P\d+)", - "${prerelease}": r"(?P\w+\d+)?", - "${devrelease}": r"(?P\.dev\d+)?", - } + TAG_FORMAT_REGEXS = get_tag_regexes(r"(?P.+)") def _tag_format_matcher(self) -> Callable[[str], VersionProtocol | None]: version_scheme = get_version_scheme(self.config) From 76f7fcb86f3298cc861488e6a64d5720bb462883 Mon Sep 17 00:00:00 2001 From: grahamhar Date: Sat, 20 Apr 2024 11:23:52 +0100 Subject: [PATCH 287/598] docs(bump): Document the use of tag_format variables with curly brackets --- docs/commands/bump.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/commands/bump.md b/docs/commands/bump.md index efb5b0881d..ed00193241 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -414,18 +414,24 @@ In your `pyproject.toml` or `.cz.toml` tag_format = "v$major.$minor.$patch$prerelease" ``` -The variables must be preceded by a `$` sign. Default is `$version`. +The variables must be preceded by a `$` sign and optionally can be wrapped in `{}` . Default is `$version`. Supported variables: -| Variable | Description | -| ------------- | ------------------------------------------- | -| `$version` | full generated version | -| `$major` | MAJOR increment | -| `$minor` | MINOR increment | -| `$patch` | PATCH increment | -| `$prerelease` | Prerelease (alpha, beta, release candidate) | -| `$devrelease` | Development release | +| Variable | Description | +|-----------------|---------------------------------------------| +| `$version` | full generated version | +| `$major` | MAJOR increment | +| `$minor` | MINOR increment | +| `$patch` | PATCH increment | +| `$prerelease` | Prerelease (alpha, beta, release candidate) | +| `$devrelease` | Development release | +| `${version}` | full generated version | +| `${major}` | MAJOR increment | +| `${minor}` | MINOR increment | +| `${patch}` | PATCH increment | +| `${prerelease}` | Prerelease (alpha, beta, release candidate) | +| `${devrelease}` | Development release | --- From 916b5aa675f2219a3ca773602907274783e18686 Mon Sep 17 00:00:00 2001 From: Graham Hargreaves Date: Sat, 27 Apr 2024 12:45:29 +0100 Subject: [PATCH 288/598] refactor: Use format strings Co-authored-by: Wei Lee --- commitizen/changelog_formats/asciidoc.py | 4 ++-- commitizen/changelog_formats/base.py | 2 +- commitizen/changelog_formats/markdown.py | 4 ++-- .../changelog_formats/restructuredtext.py | 8 +++++-- commitizen/changelog_formats/textile.py | 17 ++++++++------ commitizen/defaults.py | 4 +++- docs/commands/bump.md | 22 +++++++------------ docs/tutorials/monorepo_guidance.md | 21 +++++++++--------- tests/commands/test_changelog_command.py | 2 ++ 9 files changed, 45 insertions(+), 39 deletions(-) diff --git a/commitizen/changelog_formats/asciidoc.py b/commitizen/changelog_formats/asciidoc.py index bca7464b06..6007a56d16 100644 --- a/commitizen/changelog_formats/asciidoc.py +++ b/commitizen/changelog_formats/asciidoc.py @@ -27,9 +27,9 @@ def parse_version_from_title(self, line: str) -> str | None: return None if partial_matches.get("prerelease"): - partial_version += f"-{partial_matches['prerelease']}" + partial_version = f"{partial_version}-{partial_matches['prerelease']}" if partial_matches.get("devrelease"): - partial_version += f"{partial_matches['devrelease']}" + partial_version = f"{partial_version}{partial_matches['devrelease']}" return partial_version def parse_title_level(self, line: str) -> int | None: diff --git a/commitizen/changelog_formats/base.py b/commitizen/changelog_formats/base.py index 415c404c91..53527a060c 100644 --- a/commitizen/changelog_formats/base.py +++ b/commitizen/changelog_formats/base.py @@ -8,8 +8,8 @@ from commitizen.changelog import Metadata from commitizen.config.base_config import BaseConfig -from commitizen.version_schemes import get_version_scheme from commitizen.defaults import get_tag_regexes +from commitizen.version_schemes import get_version_scheme from . import ChangelogFormat diff --git a/commitizen/changelog_formats/markdown.py b/commitizen/changelog_formats/markdown.py index 2e9aa23663..29c1cce54a 100644 --- a/commitizen/changelog_formats/markdown.py +++ b/commitizen/changelog_formats/markdown.py @@ -30,9 +30,9 @@ def parse_version_from_title(self, line: str) -> str | None: return None if matches.get("prerelease"): - partial_version += f"-{matches['prerelease']}" + partial_version = f"{partial_version}-{matches['prerelease']}" if matches.get("devrelease"): - partial_version += f"{matches['devrelease']}" + partial_version = f"{partial_version}{matches['devrelease']}" return partial_version def parse_title_level(self, line: str) -> int | None: diff --git a/commitizen/changelog_formats/restructuredtext.py b/commitizen/changelog_formats/restructuredtext.py index be07322c9b..09d032400c 100644 --- a/commitizen/changelog_formats/restructuredtext.py +++ b/commitizen/changelog_formats/restructuredtext.py @@ -77,9 +77,13 @@ def get_metadata_from_file(self, file: IO[Any]) -> Metadata: f"{matches['major']}.{matches['minor']}.{matches['patch']}" ) if matches.get("prerelease"): - partial_version += f"-{matches['prerelease']}" + partial_version = ( + f"{partial_version}-{matches['prerelease']}" + ) if matches.get("devrelease"): - partial_version += f"{matches['devrelease']}" + partial_version = ( + f"{partial_version}{matches['devrelease']}" + ) meta.latest_version = partial_version meta.latest_version_position = index break diff --git a/commitizen/changelog_formats/textile.py b/commitizen/changelog_formats/textile.py index 4f34b522fa..8750f0056c 100644 --- a/commitizen/changelog_formats/textile.py +++ b/commitizen/changelog_formats/textile.py @@ -19,17 +19,20 @@ def parse_version_from_title(self, line: str) -> str | None: if "version" in m.groupdict(): return m.group("version") matches = m.groupdict() - try: - partial_version = ( - f"{matches['major']}.{matches['minor']}.{matches['patch']}" - ) - except KeyError: + if not all( + [ + version_segment in matches + for version_segment in ("major", "minor", "patch") + ] + ): return None + partial_version = f"{matches['major']}.{matches['minor']}.{matches['patch']}" + if matches.get("prerelease"): - partial_version += f"-{matches['prerelease']}" + partial_version = f"{partial_version}-{matches['prerelease']}" if matches.get("devrelease"): - partial_version += f"{matches['devrelease']}" + partial_version = f"{partial_version}{matches['devrelease']}" return partial_version def parse_title_level(self, line: str) -> int | None: diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 0f857f264a..2d092d5004 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -134,7 +134,9 @@ class Settings(TypedDict, total=False): bump_message = "bump: version $current_version → $new_version" -def get_tag_regexes(version_regex: str) -> dict[str | Any, str | Any]: +def get_tag_regexes( + version_regex: str, +) -> dict[str, str]: return { "$version": version_regex, "$major": r"(?P\d+)", diff --git a/docs/commands/bump.md b/docs/commands/bump.md index ed00193241..afb43230e4 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -418,20 +418,14 @@ The variables must be preceded by a `$` sign and optionally can be wrapped in `{ Supported variables: -| Variable | Description | -|-----------------|---------------------------------------------| -| `$version` | full generated version | -| `$major` | MAJOR increment | -| `$minor` | MINOR increment | -| `$patch` | PATCH increment | -| `$prerelease` | Prerelease (alpha, beta, release candidate) | -| `$devrelease` | Development release | -| `${version}` | full generated version | -| `${major}` | MAJOR increment | -| `${minor}` | MINOR increment | -| `${patch}` | PATCH increment | -| `${prerelease}` | Prerelease (alpha, beta, release candidate) | -| `${devrelease}` | Development release | +| Variable | Description | +|--------------------------------|---------------------------------------------| +| `$version`, `${version}` | full generated version | +| `$major`, `${major}` | MAJOR increment | +| `$minor`, `${minor}` | MINOR increment | +| `$patch`, `${patch}` | PATCH increment | +| `$prerelease`, `${prerelease}` | Prerelease (alpha, beta, release candidate) | +| `$devrelease`, ${devrelease}` | Development release | --- diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index 5bb334d725..c4345d6bc2 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -1,21 +1,22 @@ # Configuring commitizen in a monorepo -This tutorial assumes the monorepo layout is designed with multiple components that can be released independently of each other, -some suggested layouts: +This tutorial assumes the monorepo layout is designed with multiple components that can be released independently of each +other, it also assumes that conventional commits with scopes are in use. Some suggested layouts: ``` -library-a - .cz.toml -library-b - .cz.toml +. +├── library-b +│   └── .cz.toml +└── library-z + └── .cz.toml ``` ``` src - library-b - .cz.toml - library-z - .cz.toml +├── library-b +│   └── .cz.toml +└── library-z + └── .cz.toml ``` Each component will have its own changelog, commits will need to use scopes so only relevant commits are included in the diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 5c7a8a9faa..bc0d6c6a28 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -1597,9 +1597,11 @@ def test_changelog_only_tag_matching_tag_format_included_suffix( git.tag("random0.2.0") testargs = ["cz", "bump", "--changelog", "--yes"] mocker.patch.object(sys, "argv", testargs) + # bump to 0.2.0custom cli.main() wait_for_tag() create_file_and_commit("feat: another new file") + # bump to 0.3.0custom cli.main() wait_for_tag() with open(changelog_path) as f: From a3498aba5e94c9f7c4acb529b5e7eb6df65fd053 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 26 Sep 2024 12:08:26 +0000 Subject: [PATCH 289/598] =?UTF-8?q?bump:=20version=203.29.0=20=E2=86=92=20?= =?UTF-8?q?3.29.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 12 ++++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6cdbcc90e6..9b5027b93d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v3.29.0 # automatically updated by Commitizen + rev: v3.29.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index b621d9e5dc..fd591be06d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## v3.29.1 (2024-09-26) + +### Fix + +- **changelog**: Factorized TAG_FORMAT_REGEXES +- **changelog**: Handle tag format without version pattern +- **changelog**: handle custom tag_format in changelog generation + +### Refactor + +- Use format strings + ## v3.29.0 (2024-08-11) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index c13e81a875..ca267c56e1 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.29.0" +__version__ = "3.29.1" diff --git a/pyproject.toml b/pyproject.toml index 79c2f849b3..35a5f119a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.29.0" +version = "3.29.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.29.0" +version = "3.29.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 41ca7304968f65305b939348f697d62699c79282 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 01:38:52 +0000 Subject: [PATCH 290/598] build(deps-dev): bump mkdocs-material from 9.5.37 to 9.5.38 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.37 to 9.5.38. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.37...9.5.38) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0b371d1a9c..e2202c2fa4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -754,13 +754,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.37" +version = "9.5.38" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.37-py3-none-any.whl", hash = "sha256:6e8a986abad77be5edec3dd77cf1ddf2480963fb297a8e971f87a82fd464b070"}, - {file = "mkdocs_material-9.5.37.tar.gz", hash = "sha256:2c31607431ec234db124031255b0a9d4f3e1c3ecc2c47ad97ecfff0460471941"}, + {file = "mkdocs_material-9.5.38-py3-none-any.whl", hash = "sha256:d4779051d52ba9f1e7e344b34de95449c7c366c212b388e4a2db9a3db043c228"}, + {file = "mkdocs_material-9.5.38.tar.gz", hash = "sha256:1843c5171ad6b489550aeaf7358e5b7128cc03ddcf0fb4d91d19aa1e691a63b8"}, ] [package.dependencies] From 881695784114ecfa92517d63dfc9e970f3e7dc86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 01:38:06 +0000 Subject: [PATCH 291/598] build(deps-dev): bump ruff from 0.6.7 to 0.6.8 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.7 to 0.6.8. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.7...0.6.8) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index e2202c2fa4..81dbf204e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1429,29 +1429,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.7" +version = "0.6.8" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.7-py3-none-linux_armv6l.whl", hash = "sha256:08277b217534bfdcc2e1377f7f933e1c7957453e8a79764d004e44c40db923f2"}, - {file = "ruff-0.6.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c6707a32e03b791f4448dc0dce24b636cbcdee4dd5607adc24e5ee73fd86c00a"}, - {file = "ruff-0.6.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:533d66b7774ef224e7cf91506a7dafcc9e8ec7c059263ec46629e54e7b1f90ab"}, - {file = "ruff-0.6.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17a86aac6f915932d259f7bec79173e356165518859f94649d8c50b81ff087e9"}, - {file = "ruff-0.6.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3f8822defd260ae2460ea3832b24d37d203c3577f48b055590a426a722d50ef"}, - {file = "ruff-0.6.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ba4efe5c6dbbb58be58dd83feedb83b5e95c00091bf09987b4baf510fee5c99"}, - {file = "ruff-0.6.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:525201b77f94d2b54868f0cbe5edc018e64c22563da6c5c2e5c107a4e85c1c0d"}, - {file = "ruff-0.6.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8854450839f339e1049fdbe15d875384242b8e85d5c6947bb2faad33c651020b"}, - {file = "ruff-0.6.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f0b62056246234d59cbf2ea66e84812dc9ec4540518e37553513392c171cb18"}, - {file = "ruff-0.6.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b1462fa56c832dc0cea5b4041cfc9c97813505d11cce74ebc6d1aae068de36b"}, - {file = "ruff-0.6.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:02b083770e4cdb1495ed313f5694c62808e71764ec6ee5db84eedd82fd32d8f5"}, - {file = "ruff-0.6.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c05fd37013de36dfa883a3854fae57b3113aaa8abf5dea79202675991d48624"}, - {file = "ruff-0.6.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f49c9caa28d9bbfac4a637ae10327b3db00f47d038f3fbb2195c4d682e925b14"}, - {file = "ruff-0.6.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a0e1655868164e114ba43a908fd2d64a271a23660195017c17691fb6355d59bb"}, - {file = "ruff-0.6.7-py3-none-win32.whl", hash = "sha256:a939ca435b49f6966a7dd64b765c9df16f1faed0ca3b6f16acdf7731969deb35"}, - {file = "ruff-0.6.7-py3-none-win_amd64.whl", hash = "sha256:590445eec5653f36248584579c06252ad2e110a5d1f32db5420de35fb0e1c977"}, - {file = "ruff-0.6.7-py3-none-win_arm64.whl", hash = "sha256:b28f0d5e2f771c1fe3c7a45d3f53916fc74a480698c4b5731f0bea61e52137c8"}, - {file = "ruff-0.6.7.tar.gz", hash = "sha256:44e52129d82266fa59b587e2cd74def5637b730a69c4542525dfdecfaae38bd5"}, + {file = "ruff-0.6.8-py3-none-linux_armv6l.whl", hash = "sha256:77944bca110ff0a43b768f05a529fecd0706aac7bcce36d7f1eeb4cbfca5f0f2"}, + {file = "ruff-0.6.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27b87e1801e786cd6ede4ada3faa5e254ce774de835e6723fd94551464c56b8c"}, + {file = "ruff-0.6.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd48f945da2a6334f1793d7f701725a76ba93bf3d73c36f6b21fb04d5338dcf5"}, + {file = "ruff-0.6.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:677e03c00f37c66cea033274295a983c7c546edea5043d0c798833adf4cf4c6f"}, + {file = "ruff-0.6.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9f1476236b3eacfacfc0f66aa9e6cd39f2a624cb73ea99189556015f27c0bdeb"}, + {file = "ruff-0.6.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f5a2f17c7d32991169195d52a04c95b256378bbf0de8cb98478351eb70d526f"}, + {file = "ruff-0.6.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5fd0d4b7b1457c49e435ee1e437900ced9b35cb8dc5178921dfb7d98d65a08d0"}, + {file = "ruff-0.6.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8034b19b993e9601f2ddf2c517451e17a6ab5cdb1c13fdff50c1442a7171d87"}, + {file = "ruff-0.6.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cfb227b932ba8ef6e56c9f875d987973cd5e35bc5d05f5abf045af78ad8e098"}, + {file = "ruff-0.6.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ef0411eccfc3909269fed47c61ffebdcb84a04504bafa6b6df9b85c27e813b0"}, + {file = "ruff-0.6.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:007dee844738c3d2e6c24ab5bc7d43c99ba3e1943bd2d95d598582e9c1b27750"}, + {file = "ruff-0.6.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ce60058d3cdd8490e5e5471ef086b3f1e90ab872b548814e35930e21d848c9ce"}, + {file = "ruff-0.6.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1085c455d1b3fdb8021ad534379c60353b81ba079712bce7a900e834859182fa"}, + {file = "ruff-0.6.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:70edf6a93b19481affd287d696d9e311388d808671bc209fb8907b46a8c3af44"}, + {file = "ruff-0.6.8-py3-none-win32.whl", hash = "sha256:792213f7be25316f9b46b854df80a77e0da87ec66691e8f012f887b4a671ab5a"}, + {file = "ruff-0.6.8-py3-none-win_amd64.whl", hash = "sha256:ec0517dc0f37cad14a5319ba7bba6e7e339d03fbf967a6d69b0907d61be7a263"}, + {file = "ruff-0.6.8-py3-none-win_arm64.whl", hash = "sha256:8d3bb2e3fbb9875172119021a13eed38849e762499e3cfde9588e4b4d70968dc"}, + {file = "ruff-0.6.8.tar.gz", hash = "sha256:a5bf44b1aa0adaf6d9d20f86162b34f7c593bfedabc51239953e446aefc8ce18"}, ] [[package]] From 4db164f627027df8275fbb8446e2907882f7569a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:51:33 +0000 Subject: [PATCH 292/598] build(deps-dev): bump mkdocs-material from 9.5.38 to 9.5.39 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.38 to 9.5.39. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.38...9.5.39) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 81dbf204e6..b80dedcb45 100644 --- a/poetry.lock +++ b/poetry.lock @@ -754,13 +754,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.38" +version = "9.5.39" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.38-py3-none-any.whl", hash = "sha256:d4779051d52ba9f1e7e344b34de95449c7c366c212b388e4a2db9a3db043c228"}, - {file = "mkdocs_material-9.5.38.tar.gz", hash = "sha256:1843c5171ad6b489550aeaf7358e5b7128cc03ddcf0fb4d91d19aa1e691a63b8"}, + {file = "mkdocs_material-9.5.39-py3-none-any.whl", hash = "sha256:0f2f68c8db89523cb4a59705cd01b4acd62b2f71218ccb67e1e004e560410d2b"}, + {file = "mkdocs_material-9.5.39.tar.gz", hash = "sha256:25faa06142afa38549d2b781d475a86fb61de93189f532b88e69bf11e5e5c3be"}, ] [package.dependencies] From 15f08123fb8faadb0d0d6d7be06bcd67f5dda360 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 01:08:42 +0000 Subject: [PATCH 293/598] build(deps-dev): bump rich from 13.8.1 to 13.9.1 Bumps [rich](https://github.com/Textualize/rich) from 13.8.1 to 13.9.1. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.8.1...v13.9.1) --- updated-dependencies: - dependency-name: rich dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index b80dedcb45..45f45e2d6b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1410,19 +1410,19 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.8.1" +version = "13.9.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" files = [ - {file = "rich-13.8.1-py3-none-any.whl", hash = "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06"}, - {file = "rich-13.8.1.tar.gz", hash = "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a"}, + {file = "rich-13.9.1-py3-none-any.whl", hash = "sha256:b340e739f30aa58921dc477b8adaa9ecdb7cecc217be01d93730ee1bc8aa83be"}, + {file = "rich-13.9.1.tar.gz", hash = "sha256:097cffdf85db1babe30cc7deba5ab3a29e1b9885047dab24c57e9a7f8a9c1466"}, ] [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\""} +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] From eafcef63a6ff813162695dd120964dd3a61b37b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 01:24:22 +0000 Subject: [PATCH 294/598] build(deps-dev): bump types-python-dateutil Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.9.0.20240906 to 2.9.0.20241003. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-python-dateutil dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 45f45e2d6b..6d1b22b2d6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1563,13 +1563,13 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.9.0.20240906" +version = "2.9.0.20241003" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.9.0.20240906.tar.gz", hash = "sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e"}, - {file = "types_python_dateutil-2.9.0.20240906-py3-none-any.whl", hash = "sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6"}, + {file = "types-python-dateutil-2.9.0.20241003.tar.gz", hash = "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446"}, + {file = "types_python_dateutil-2.9.0.20241003-py3-none-any.whl", hash = "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d"}, ] [[package]] From 1f857754d4ded507f9d35fdeb8e6fe2e7afea6bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 01:29:58 +0000 Subject: [PATCH 295/598] build(deps-dev): bump rich from 13.9.1 to 13.9.2 Bumps [rich](https://github.com/Textualize/rich) from 13.9.1 to 13.9.2. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.9.1...v13.9.2) --- updated-dependencies: - dependency-name: rich dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6d1b22b2d6..08fae00d1c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1410,13 +1410,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.9.1" +version = "13.9.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" files = [ - {file = "rich-13.9.1-py3-none-any.whl", hash = "sha256:b340e739f30aa58921dc477b8adaa9ecdb7cecc217be01d93730ee1bc8aa83be"}, - {file = "rich-13.9.1.tar.gz", hash = "sha256:097cffdf85db1babe30cc7deba5ab3a29e1b9885047dab24c57e9a7f8a9c1466"}, + {file = "rich-13.9.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"}, + {file = "rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c"}, ] [package.dependencies] From 1c14b02e1057e67ae2f89388e447eeefe4feb962 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 01:30:23 +0000 Subject: [PATCH 296/598] build(deps-dev): bump ruff from 0.6.8 to 0.6.9 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.8 to 0.6.9. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.8...0.6.9) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 08fae00d1c..66127b1df5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1429,29 +1429,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.8" +version = "0.6.9" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.8-py3-none-linux_armv6l.whl", hash = "sha256:77944bca110ff0a43b768f05a529fecd0706aac7bcce36d7f1eeb4cbfca5f0f2"}, - {file = "ruff-0.6.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27b87e1801e786cd6ede4ada3faa5e254ce774de835e6723fd94551464c56b8c"}, - {file = "ruff-0.6.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd48f945da2a6334f1793d7f701725a76ba93bf3d73c36f6b21fb04d5338dcf5"}, - {file = "ruff-0.6.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:677e03c00f37c66cea033274295a983c7c546edea5043d0c798833adf4cf4c6f"}, - {file = "ruff-0.6.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9f1476236b3eacfacfc0f66aa9e6cd39f2a624cb73ea99189556015f27c0bdeb"}, - {file = "ruff-0.6.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f5a2f17c7d32991169195d52a04c95b256378bbf0de8cb98478351eb70d526f"}, - {file = "ruff-0.6.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5fd0d4b7b1457c49e435ee1e437900ced9b35cb8dc5178921dfb7d98d65a08d0"}, - {file = "ruff-0.6.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8034b19b993e9601f2ddf2c517451e17a6ab5cdb1c13fdff50c1442a7171d87"}, - {file = "ruff-0.6.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cfb227b932ba8ef6e56c9f875d987973cd5e35bc5d05f5abf045af78ad8e098"}, - {file = "ruff-0.6.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ef0411eccfc3909269fed47c61ffebdcb84a04504bafa6b6df9b85c27e813b0"}, - {file = "ruff-0.6.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:007dee844738c3d2e6c24ab5bc7d43c99ba3e1943bd2d95d598582e9c1b27750"}, - {file = "ruff-0.6.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ce60058d3cdd8490e5e5471ef086b3f1e90ab872b548814e35930e21d848c9ce"}, - {file = "ruff-0.6.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1085c455d1b3fdb8021ad534379c60353b81ba079712bce7a900e834859182fa"}, - {file = "ruff-0.6.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:70edf6a93b19481affd287d696d9e311388d808671bc209fb8907b46a8c3af44"}, - {file = "ruff-0.6.8-py3-none-win32.whl", hash = "sha256:792213f7be25316f9b46b854df80a77e0da87ec66691e8f012f887b4a671ab5a"}, - {file = "ruff-0.6.8-py3-none-win_amd64.whl", hash = "sha256:ec0517dc0f37cad14a5319ba7bba6e7e339d03fbf967a6d69b0907d61be7a263"}, - {file = "ruff-0.6.8-py3-none-win_arm64.whl", hash = "sha256:8d3bb2e3fbb9875172119021a13eed38849e762499e3cfde9588e4b4d70968dc"}, - {file = "ruff-0.6.8.tar.gz", hash = "sha256:a5bf44b1aa0adaf6d9d20f86162b34f7c593bfedabc51239953e446aefc8ce18"}, + {file = "ruff-0.6.9-py3-none-linux_armv6l.whl", hash = "sha256:064df58d84ccc0ac0fcd63bc3090b251d90e2a372558c0f057c3f75ed73e1ccd"}, + {file = "ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec"}, + {file = "ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645d7d8761f915e48a00d4ecc3686969761df69fb561dd914a773c1a8266e14e"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eae02b700763e3847595b9d2891488989cac00214da7f845f4bcf2989007d577"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d5ccc9e58112441de8ad4b29dcb7a86dc25c5f770e3c06a9d57e0e5eba48829"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:417b81aa1c9b60b2f8edc463c58363075412866ae4e2b9ab0f690dc1e87ac1b5"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c866b631f5fbce896a74a6e4383407ba7507b815ccc52bcedabb6810fdb3ef7"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b118afbb3202f5911486ad52da86d1d52305b59e7ef2031cea3425142b97d6f"}, + {file = "ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa"}, + {file = "ruff-0.6.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ef0cc774b00fec123f635ce5c547dac263f6ee9fb9cc83437c5904183b55ceb"}, + {file = "ruff-0.6.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:12edd2af0c60fa61ff31cefb90aef4288ac4d372b4962c2864aeea3a1a2460c0"}, + {file = "ruff-0.6.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:55bb01caeaf3a60b2b2bba07308a02fca6ab56233302406ed5245180a05c5625"}, + {file = "ruff-0.6.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:925d26471fa24b0ce5a6cdfab1bb526fb4159952385f386bdcc643813d472039"}, + {file = "ruff-0.6.9-py3-none-win32.whl", hash = "sha256:eb61ec9bdb2506cffd492e05ac40e5bc6284873aceb605503d8494180d6fc84d"}, + {file = "ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117"}, + {file = "ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93"}, + {file = "ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2"}, ] [[package]] From ebb6a2cb9ab4f0ee26f5dfeee3adc63c6e893e4c Mon Sep 17 00:00:00 2001 From: Santiago Fraire Willemoes Date: Fri, 27 Sep 2024 09:15:12 +0200 Subject: [PATCH 297/598] docs: improve monorepo docs --- docs/tutorials/monorepo_guidance.md | 56 ++++++++++++++++++++++++----- mkdocs.yml | 1 + 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index c4345d6bc2..78e37fd71f 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -3,7 +3,7 @@ This tutorial assumes the monorepo layout is designed with multiple components that can be released independently of each other, it also assumes that conventional commits with scopes are in use. Some suggested layouts: -``` +```sh . ├── library-b │   └── .cz.toml @@ -11,7 +11,7 @@ other, it also assumes that conventional commits with scopes are in use. Some su └── .cz.toml ``` -``` +```sh src ├── library-b │   └── .cz.toml @@ -19,23 +19,61 @@ src └── .cz.toml ``` -Each component will have its own changelog, commits will need to use scopes so only relevant commits are included in the -appropriate change log for a given component. Example config and commit for `library-b` +Sample `.cz.toml` for each component: ```toml +# library-b/.cz.toml [tool.commitizen] name = "cz_customize" version = "0.0.0" tag_format = "${version}-library-b" # the component name can be a prefix or suffix with or without a separator update_changelog_on_bump = true +``` + +```toml +# library-z/.cz.toml +[tool.commitizen] +name = "cz_customize" +version = "0.0.0" +tag_format = "${version}-library-z" +update_changelog_on_bump = true +``` + +And finally, to bump each of these: + +```sh +cz --config library-b/.cz.toml bump --yes +cz --config library-z/.cz.toml bump --yes +``` + +## Changelog per component + +In order to filter the correct commits for each component, you'll have to come up with a strategy. + +For example: + +- Trigger the pipeline based on the changed path, which can have some downsides, as you'll rely on the developer not including files from other files + - [github actions](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore) uses `path` + - [Jenkins](https://www.jenkins.io/doc/book/pipeline/syntax/#built-in-conditions) uses `changeset` + - [Gitlab](https://docs.gitlab.com/ee/ci/yaml/#ruleschanges) uses `rules:changes` +- Filter certain pattern of the commit message (recommended) + + +### Example with scope in conventional commits + +For this example, to include the message in the changelog, we will require commits to use a specific scope. +This way, only relevant commits will be included in the appropriate change log for a given component, and any other commit will be ignored. + +Example config and commit for `library-b`: + +```toml [tool.commitizen.customize] changelog_pattern = "^(feat|fix)\\(library-b\\)(!)?:" #the pattern on types can be a wild card or any types you wish to include ``` -example commit message for the above +A commit message looking like this, would be included: -`fix:(library-b) Some awesome message` - -If the above is followed and the `cz bump --changelog` is run in the directory containing the component the changelog -should be generated in the same directory with only commits scoped to the component. +``` +fix:(library-b) Some awesome message +``` diff --git a/mkdocs.yml b/mkdocs.yml index a0fb57fde2..f6a7eaa421 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -53,6 +53,7 @@ nav: - Github Actions: "tutorials/github_actions.md" - Jenkins pipeline: "tutorials/jenkins_pipeline.md" - Developmental releases: "tutorials/dev_releases.md" + - Monorepo support: "tutorials/monorepo_guidance.md" - FAQ: "faq.md" - Exit Codes: "exit_codes.md" - Third-Party Commitizen Templates: "third-party-commitizen.md" From d755de919631c755dfe36340e87db63a287d501b Mon Sep 17 00:00:00 2001 From: Santiago Fraire Willemoes Date: Mon, 7 Oct 2024 11:27:20 +0200 Subject: [PATCH 298/598] docs: update docs/tutorials/monorepo_guidance.md Co-authored-by: Wei Lee --- docs/tutorials/monorepo_guidance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index 78e37fd71f..a943b70bb5 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -3,7 +3,7 @@ This tutorial assumes the monorepo layout is designed with multiple components that can be released independently of each other, it also assumes that conventional commits with scopes are in use. Some suggested layouts: -```sh +```shell-session . ├── library-b │   └── .cz.toml From 5aeb1df34bf3f72af6c3140e12e9ea186d59db90 Mon Sep 17 00:00:00 2001 From: Santiago Fraire Willemoes Date: Mon, 7 Oct 2024 11:27:29 +0200 Subject: [PATCH 299/598] docs: update docs/tutorials/monorepo_guidance.md Co-authored-by: Wei Lee --- docs/tutorials/monorepo_guidance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index a943b70bb5..ba6d70fd82 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -11,7 +11,7 @@ other, it also assumes that conventional commits with scopes are in use. Some su └── .cz.toml ``` -```sh +```shell-session src ├── library-b │   └── .cz.toml From fad5e828d53342a9e34f3662def842bc88fefdc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 01:38:16 +0000 Subject: [PATCH 300/598] build(deps): bump argcomplete from 3.5.0 to 3.5.1 Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 3.5.0 to 3.5.1. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v3.5.0...v3.5.1) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 66127b1df5..1e62dc1b07 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,13 +13,13 @@ files = [ [[package]] name = "argcomplete" -version = "3.5.0" +version = "3.5.1" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.5.0-py3-none-any.whl", hash = "sha256:d4bcf3ff544f51e16e54228a7ac7f486ed70ebf2ecfe49a63a91171c76bf029b"}, - {file = "argcomplete-3.5.0.tar.gz", hash = "sha256:4349400469dccfb7950bb60334a680c58d88699bff6159df61251878dc6bf74b"}, + {file = "argcomplete-3.5.1-py3-none-any.whl", hash = "sha256:1a1d148bdaa3e3b93454900163403df41448a248af01b6e849edc5ac08e6c363"}, + {file = "argcomplete-3.5.1.tar.gz", hash = "sha256:eb1ee355aa2557bd3d0145de7b06b2a45b0ce461e1e7813f5d066039ab4177b4"}, ] [package.extras] From a54bf542012257a338edb54ca16d11ba6beef0ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 01:55:53 +0000 Subject: [PATCH 301/598] build(deps): bump charset-normalizer from 3.3.2 to 3.4.0 Bumps [charset-normalizer](https://github.com/Ousret/charset_normalizer) from 3.3.2 to 3.4.0. - [Release notes](https://github.com/Ousret/charset_normalizer/releases) - [Changelog](https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md) - [Commits](https://github.com/Ousret/charset_normalizer/compare/3.3.2...3.4.0) --- updated-dependencies: - dependency-name: charset-normalizer dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 197 ++++++++++++++++++++++++++++------------------------ 1 file changed, 106 insertions(+), 91 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1e62dc1b07..bee73ac15c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -95,101 +95,116 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, ] [[package]] From 1a1ddd2fde4054f40d1f5c9ecc31272b9a9903a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 01:49:45 +0000 Subject: [PATCH 302/598] build(deps-dev): bump mkdocs-material from 9.5.39 to 9.5.40 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.39 to 9.5.40. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.39...9.5.40) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index bee73ac15c..79d260ca50 100644 --- a/poetry.lock +++ b/poetry.lock @@ -769,13 +769,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.39" +version = "9.5.40" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.39-py3-none-any.whl", hash = "sha256:0f2f68c8db89523cb4a59705cd01b4acd62b2f71218ccb67e1e004e560410d2b"}, - {file = "mkdocs_material-9.5.39.tar.gz", hash = "sha256:25faa06142afa38549d2b781d475a86fb61de93189f532b88e69bf11e5e5c3be"}, + {file = "mkdocs_material-9.5.40-py3-none-any.whl", hash = "sha256:8e7a16ada34e79a7b6459ff2602584222f522c738b6a023d1bea853d5049da6f"}, + {file = "mkdocs_material-9.5.40.tar.gz", hash = "sha256:b69d70e667ec51fc41f65e006a3184dd00d95b2439d982cb1586e4c018943156"}, ] [package.dependencies] From 59c7e7bf70e859be0c7ba19ebac153a3d4bf740a Mon Sep 17 00:00:00 2001 From: Kimoon Han Date: Mon, 14 Oct 2024 20:09:17 +0900 Subject: [PATCH 303/598] docs: update README to include conda --- docs/README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 3f729ebcbc..9a071d5676 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,6 +3,7 @@ [![PyPI Package latest release](https://img.shields.io/pypi/v/commitizen.svg?style=flat-square)](https://pypi.org/project/commitizen/) [![PyPI Package download count (per month)](https://img.shields.io/pypi/dm/commitizen?style=flat-square)](https://pypi.org/project/commitizen/) [![Supported versions](https://img.shields.io/pypi/pyversions/commitizen.svg?style=flat-square)](https://pypi.org/project/commitizen/) +[![Conda Version](https://img.shields.io/conda/vn/conda-forge/commitizen?style=flat-square)](https://anaconda.org/conda-forge/commitizen) [![homebrew](https://img.shields.io/homebrew/v/commitizen?color=teal&style=flat-square)](https://formulae.brew.sh/formula/commitizen) [![Codecov](https://img.shields.io/codecov/c/github/commitizen-tools/commitizen.svg?style=flat-square)](https://codecov.io/gh/commitizen-tools/commitizen) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?style=flat-square&logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) @@ -62,19 +63,27 @@ pip install --user -U commitizen ### Python project -You can add it to your local project using one of these: +You can add it to your local project using one of the following. + +With `pip`: ```bash pip install -U commitizen ``` -for Poetry >= 1.2.0: +With `conda`: + +```bash +conda install -c conda-forge commitizen +``` + +With Poetry >= 1.2.0: ```bash poetry add commitizen --group dev ``` -for Poetry < 1.2.0: +With Poetry < 1.2.0: ```bash poetry add commitizen --dev From c95404b7845cd661d78e19d0b248b07055526884 Mon Sep 17 00:00:00 2001 From: gbaian10 Date: Mon, 14 Oct 2024 02:45:20 +0800 Subject: [PATCH 304/598] docs: `Allowed Prefixes` default value typo https://commitizen-tools.github.io/commitizen/config/#allowed_prefixes --- docs/commands/check.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/commands/check.md b/docs/commands/check.md index 751a47aa2f..e45ecd86c8 100644 --- a/docs/commands/check.md +++ b/docs/commands/check.md @@ -70,7 +70,7 @@ permit them. Since `git commit` accepts an `--allow-empty-message` flag (primari ### Allowed Prefixes If the commit message starts by some specific prefixes, `cz check` returns `True` without checkign the regex. -By default, the the following prefixes are allowed: `Merge`, `Revert`, `Pull Request`, `fixup!` and `squash!`. +By default, the the following prefixes are allowed: `Merge`, `Revert`, `Pull request`, `fixup!` and `squash!`. ```bash cz check --message MESSAGE --allowed-prefixes 'Merge' 'Revert' 'Custom Prefix' From 00d2d967337c7357dbd5043c42db5aa647644c45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 01:20:55 +0000 Subject: [PATCH 305/598] build(deps-dev): bump mypy from 1.11.2 to 1.12.0 Bumps [mypy](https://github.com/python/mypy) from 1.11.2 to 1.12.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.11.2...v1.12.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 61 +++++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/poetry.lock b/poetry.lock index 79d260ca50..63ea1dab1d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -809,38 +809,43 @@ files = [ [[package]] name = "mypy" -version = "1.11.2" +version = "1.12.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a"}, - {file = "mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef"}, - {file = "mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383"}, - {file = "mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8"}, - {file = "mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7"}, - {file = "mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385"}, - {file = "mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca"}, - {file = "mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104"}, - {file = "mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4"}, - {file = "mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6"}, - {file = "mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318"}, - {file = "mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36"}, - {file = "mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987"}, - {file = "mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca"}, - {file = "mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70"}, - {file = "mypy-1.11.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b"}, - {file = "mypy-1.11.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86"}, - {file = "mypy-1.11.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce"}, - {file = "mypy-1.11.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1"}, - {file = "mypy-1.11.2-cp38-cp38-win_amd64.whl", hash = "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b"}, - {file = "mypy-1.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6"}, - {file = "mypy-1.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70"}, - {file = "mypy-1.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"}, - {file = "mypy-1.11.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d"}, - {file = "mypy-1.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24"}, - {file = "mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12"}, - {file = "mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79"}, + {file = "mypy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4397081e620dc4dc18e2f124d5e1d2c288194c2c08df6bdb1db31c38cd1fe1ed"}, + {file = "mypy-1.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:684a9c508a283f324804fea3f0effeb7858eb03f85c4402a967d187f64562469"}, + {file = "mypy-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cabe4cda2fa5eca7ac94854c6c37039324baaa428ecbf4de4567279e9810f9e"}, + {file = "mypy-1.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:060a07b10e999ac9e7fa249ce2bdcfa9183ca2b70756f3bce9df7a92f78a3c0a"}, + {file = "mypy-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:0eff042d7257f39ba4ca06641d110ca7d2ad98c9c1fb52200fe6b1c865d360ff"}, + {file = "mypy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b86de37a0da945f6d48cf110d5206c5ed514b1ca2614d7ad652d4bf099c7de7"}, + {file = "mypy-1.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20c7c5ce0c1be0b0aea628374e6cf68b420bcc772d85c3c974f675b88e3e6e57"}, + {file = "mypy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a64ee25f05fc2d3d8474985c58042b6759100a475f8237da1f4faf7fcd7e6309"}, + {file = "mypy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:faca7ab947c9f457a08dcb8d9a8664fd438080e002b0fa3e41b0535335edcf7f"}, + {file = "mypy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:5bc81701d52cc8767005fdd2a08c19980de9ec61a25dbd2a937dfb1338a826f9"}, + {file = "mypy-1.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8462655b6694feb1c99e433ea905d46c478041a8b8f0c33f1dab00ae881b2164"}, + {file = "mypy-1.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:923ea66d282d8af9e0f9c21ffc6653643abb95b658c3a8a32dca1eff09c06475"}, + {file = "mypy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ebf9e796521f99d61864ed89d1fb2926d9ab6a5fab421e457cd9c7e4dd65aa9"}, + {file = "mypy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e478601cc3e3fa9d6734d255a59c7a2e5c2934da4378f3dd1e3411ea8a248642"}, + {file = "mypy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:c72861b7139a4f738344faa0e150834467521a3fba42dc98264e5aa9507dd601"}, + {file = "mypy-1.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52b9e1492e47e1790360a43755fa04101a7ac72287b1a53ce817f35899ba0521"}, + {file = "mypy-1.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:48d3e37dd7d9403e38fa86c46191de72705166d40b8c9f91a3de77350daa0893"}, + {file = "mypy-1.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f106db5ccb60681b622ac768455743ee0e6a857724d648c9629a9bd2ac3f721"}, + {file = "mypy-1.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:233e11b3f73ee1f10efada2e6da0f555b2f3a5316e9d8a4a1224acc10e7181d3"}, + {file = "mypy-1.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:4ae8959c21abcf9d73aa6c74a313c45c0b5a188752bf37dace564e29f06e9c1b"}, + {file = "mypy-1.12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eafc1b7319b40ddabdc3db8d7d48e76cfc65bbeeafaa525a4e0fa6b76175467f"}, + {file = "mypy-1.12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9b9ce1ad8daeb049c0b55fdb753d7414260bad8952645367e70ac91aec90e07e"}, + {file = "mypy-1.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfe012b50e1491d439172c43ccb50db66d23fab714d500b57ed52526a1020bb7"}, + {file = "mypy-1.12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2c40658d4fa1ab27cb53d9e2f1066345596af2f8fe4827defc398a09c7c9519b"}, + {file = "mypy-1.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:dee78a8b9746c30c1e617ccb1307b351ded57f0de0d287ca6276378d770006c0"}, + {file = "mypy-1.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b5df6c8a8224f6b86746bda716bbe4dbe0ce89fd67b1fa4661e11bfe38e8ec8"}, + {file = "mypy-1.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5feee5c74eb9749e91b77f60b30771563327329e29218d95bedbe1257e2fe4b0"}, + {file = "mypy-1.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:77278e8c6ffe2abfba6db4125de55f1024de9a323be13d20e4f73b8ed3402bd1"}, + {file = "mypy-1.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:dcfb754dea911039ac12434d1950d69a2f05acd4d56f7935ed402be09fad145e"}, + {file = "mypy-1.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:06de0498798527451ffb60f68db0d368bd2bae2bbfb5237eae616d4330cc87aa"}, + {file = "mypy-1.12.0-py3-none-any.whl", hash = "sha256:fd313226af375d52e1e36c383f39bf3836e1f192801116b31b090dfcd3ec5266"}, + {file = "mypy-1.12.0.tar.gz", hash = "sha256:65a22d87e757ccd95cbbf6f7e181e6caa87128255eb2b6be901bb71b26d8a99d"}, ] [package.dependencies] From a9aacec7e84b67f0bd894e8e952b1074a3c0da20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 01:11:26 +0000 Subject: [PATCH 306/598] ci(deps): bump dawidd6/action-homebrew-bump-formula from 3 to 4 Bumps [dawidd6/action-homebrew-bump-formula](https://github.com/dawidd6/action-homebrew-bump-formula) from 3 to 4. - [Release notes](https://github.com/dawidd6/action-homebrew-bump-formula/releases) - [Commits](https://github.com/dawidd6/action-homebrew-bump-formula/compare/v3...v4) --- updated-dependencies: - dependency-name: dawidd6/action-homebrew-bump-formula dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/homebrewpublish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/homebrewpublish.yml b/.github/workflows/homebrewpublish.yml index 84c2ca6ca0..443a13b1ba 100644 --- a/.github/workflows/homebrewpublish.yml +++ b/.github/workflows/homebrewpublish.yml @@ -24,7 +24,7 @@ jobs: run: | echo "project_version=$(cz version --project)" >> $GITHUB_ENV - name: Update Homebrew formula - uses: dawidd6/action-homebrew-bump-formula@v3 + uses: dawidd6/action-homebrew-bump-formula@v4 with: token: ${{secrets.PERSONAL_ACCESS_TOKEN}} formula: commitizen From e1784c633e5efdb00f019d5d833b528d2f6d0826 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 02:00:35 +0000 Subject: [PATCH 307/598] build(deps-dev): bump mkdocs-material from 9.5.40 to 9.5.41 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.40 to 9.5.41. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.40...9.5.41) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 63ea1dab1d..4259c11698 100644 --- a/poetry.lock +++ b/poetry.lock @@ -769,13 +769,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.40" +version = "9.5.41" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.40-py3-none-any.whl", hash = "sha256:8e7a16ada34e79a7b6459ff2602584222f522c738b6a023d1bea853d5049da6f"}, - {file = "mkdocs_material-9.5.40.tar.gz", hash = "sha256:b69d70e667ec51fc41f65e006a3184dd00d95b2439d982cb1586e4c018943156"}, + {file = "mkdocs_material-9.5.41-py3-none-any.whl", hash = "sha256:990bc138c33342b5b73e7545915ebc0136e501bfbd8e365735144f5120891d83"}, + {file = "mkdocs_material-9.5.41.tar.gz", hash = "sha256:30fa5d459b4b8130848ecd8e1c908878345d9d8268f7ddbc31eebe88d462d97b"}, ] [package.dependencies] From 16b80d34c552f02c51f6edba15383f299d3344c2 Mon Sep 17 00:00:00 2001 From: Dimitri Masson <5263585+dhmmasson@users.noreply.github.com> Date: Mon, 14 Oct 2024 19:53:49 +0000 Subject: [PATCH 308/598] docs(third-party-commitizen): add commitizen-deno-provider to the third party docs --- docs/third-party-commitizen.md | 40 +++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/docs/third-party-commitizen.md b/docs/third-party-commitizen.md index dbbd879434..61a1cb3d58 100644 --- a/docs/third-party-commitizen.md +++ b/docs/third-party-commitizen.md @@ -5,7 +5,7 @@ are available as PyPI packages (installable with `pip`). ### [Conventional JIRA](https://pypi.org/project/conventional-JIRA/) -Just like *conventional commit* format, but the scope has been restricted to a +Just like _conventional commit_ format, but the scope has been restricted to a JIRA issue format, i.e. `project-issueNumber`. This standardises scopes in a meaningful way. @@ -18,6 +18,7 @@ pip install conventional-JIRA ### [GitHub JIRA Conventional](https://pypi.org/project/cz-github-jira-conventional/) This plugin extends the commitizen tools by: + - requiring a JIRA issue id in the commit message - creating links to GitHub commits in the CHANGELOG.md - creating links to JIRA issues in the CHANGELOG.md @@ -32,7 +33,7 @@ For installation instructions (configuration and pre-commit) please visit https: ### [cz-emoji](https://github.com/adam-grant-hendry/cz-emoji) -*conventional commit* format, but with emojis +_conventional commit_ format, but with emojis ### Installation @@ -64,10 +65,9 @@ pip install cz-conventional-gitmoji cz --name cz_gitmoji commit ``` - ### [Commitizen emoji](https://pypi.org/project/commitizen-emoji/) (Unmaintained) -Just like *conventional commit* format, but with emojis and optionally time spent and related tasks. +Just like _conventional commit_ format, but with emojis and optionally time spent and related tasks. It can be installed with `pip install commitizen-emoji`. @@ -75,7 +75,7 @@ Usage: `cz --name cz_commitizen_emoji commit`. ### [Conventional Legacy (cz_legacy)][1] -An extension of the *conventional commit* format to include user-specified +An extension of the _conventional commit_ format to include user-specified legacy change types in the `CHANGELOG` while preventing the legacy change types from being used in new commit messages @@ -83,4 +83,32 @@ from being used in new commit messages See the [README][1] for instructions on configuration - [1]: https://pypi.org/project/cz_legacy +[1]: https://pypi.org/project/cz_legacy + +### [commitizen-deno-provider](https://pypi.org/project/commitizen-deno-provider/) + +A provider for Deno projects. The provider updates the version in deno.json, deno.lock and jsr.json files. + +#### Installation + + +``` +pip install commitizen-deno-provider +``` + +#### Usage + +Add `deno-provider` to your configuration file. + +Example for `.cz.yaml`: + +```yml +--- +commitizen: + major_version_zero: true + name: cz_conventional_commits + tag_format: $version + update_changelog_on_bump: true + version_provider: deno-provider + version_scheme: semver +``` From e8215699ac742fc198684dee52c0eb4a0b4b2072 Mon Sep 17 00:00:00 2001 From: Dimitri Masson <5263585+dhmmasson@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:13:41 +0000 Subject: [PATCH 309/598] docs(third-party-commitizen): update deno-provider code block syntax highlighting --- docs/third-party-commitizen.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/third-party-commitizen.md b/docs/third-party-commitizen.md index 61a1cb3d58..245e35a1da 100644 --- a/docs/third-party-commitizen.md +++ b/docs/third-party-commitizen.md @@ -87,12 +87,12 @@ See the [README][1] for instructions on configuration ### [commitizen-deno-provider](https://pypi.org/project/commitizen-deno-provider/) -A provider for Deno projects. The provider updates the version in deno.json, deno.lock and jsr.json files. +A provider for Deno projects. The provider updates the version in deno.json and jsr.json files. #### Installation -``` +```sh pip install commitizen-deno-provider ``` @@ -102,7 +102,7 @@ Add `deno-provider` to your configuration file. Example for `.cz.yaml`: -```yml +```yaml --- commitizen: major_version_zero: true From 1d5f2955c407540130f437b98c0a54a388ee2b5e Mon Sep 17 00:00:00 2001 From: Dimitri Masson <5263585+dhmmasson@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:28:26 +0000 Subject: [PATCH 310/598] docs(third-party-commitizen): uniformize the third party page - Create a top level heading for provider to mirror the template heading - Uniformize the installation/usage sub-heading for each template/provider - Uniformize the code-block syntax highlighting --- docs/third-party-commitizen.md | 45 +++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/docs/third-party-commitizen.md b/docs/third-party-commitizen.md index 245e35a1da..1c8ef8a183 100644 --- a/docs/third-party-commitizen.md +++ b/docs/third-party-commitizen.md @@ -9,7 +9,7 @@ Just like _conventional commit_ format, but the scope has been restricted to a JIRA issue format, i.e. `project-issueNumber`. This standardises scopes in a meaningful way. -### Installation +#### Installation ```sh pip install conventional-JIRA @@ -23,25 +23,25 @@ This plugin extends the commitizen tools by: - creating links to GitHub commits in the CHANGELOG.md - creating links to JIRA issues in the CHANGELOG.md -### Installation +#### Installation ```sh pip install cz-github-jira-conventional ``` -For installation instructions (configuration and pre-commit) please visit https://github.com/apheris/cz-github-jira-conventional +For installation instructions (configuration and pre-commit) please visit [https://github.com/apheris/cz-github-jira-conventional](https://github.com/apheris/cz-github-jira-conventional) ### [cz-emoji](https://github.com/adam-grant-hendry/cz-emoji) _conventional commit_ format, but with emojis -### Installation +#### Installation ```sh pip install cz-emoji ``` -### Usage +#### Usage ```sh cz --name cz_emoji commit @@ -53,15 +53,15 @@ cz --name cz_emoji commit Includes a pre-commit hook that automatically adds the correct gitmoji to the commit message based on the conventional type. -### Installation +#### Installation -```bash +```sh pip install cz-conventional-gitmoji ``` -### Usage +#### Usage -```bash +```sh cz --name cz_gitmoji commit ``` @@ -69,9 +69,17 @@ cz --name cz_gitmoji commit Just like _conventional commit_ format, but with emojis and optionally time spent and related tasks. -It can be installed with `pip install commitizen-emoji`. +#### Installation + +```sh +pip install commitizen-emoji +``` -Usage: `cz --name cz_commitizen_emoji commit`. +#### Usage + +```sh +cz --name cz_commitizen_emoji commit +``` ### [Conventional Legacy (cz_legacy)][1] @@ -79,19 +87,28 @@ An extension of the _conventional commit_ format to include user-specified legacy change types in the `CHANGELOG` while preventing the legacy change types from being used in new commit messages -`cz_legacy` can be installed with `pip install cz_legacy` +#### Installation + +```sh +pip install cz_legacy +``` + +#### Usage See the [README][1] for instructions on configuration [1]: https://pypi.org/project/cz_legacy +## Third-Party Commitizen Providers + +Commitizen can read and write version from different sources. In addition to the native providers, some alternative version sources are available as PyPI packages (installable with `pip`). + ### [commitizen-deno-provider](https://pypi.org/project/commitizen-deno-provider/) -A provider for Deno projects. The provider updates the version in deno.json and jsr.json files. +A provider for **Deno** projects. The provider updates the version in deno.json and jsr.json files. #### Installation - ```sh pip install commitizen-deno-provider ``` From 36cfcab746fd9a5c1bc495332fc3dcd11db967ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 01:08:39 +0000 Subject: [PATCH 311/598] build(deps-dev): bump ruff from 0.6.9 to 0.7.0 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.9 to 0.7.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.9...0.7.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 40 ++++++++++++++++++++-------------------- pyproject.toml | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4259c11698..131b803d13 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1449,29 +1449,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.9" +version = "0.7.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.9-py3-none-linux_armv6l.whl", hash = "sha256:064df58d84ccc0ac0fcd63bc3090b251d90e2a372558c0f057c3f75ed73e1ccd"}, - {file = "ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec"}, - {file = "ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645d7d8761f915e48a00d4ecc3686969761df69fb561dd914a773c1a8266e14e"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eae02b700763e3847595b9d2891488989cac00214da7f845f4bcf2989007d577"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d5ccc9e58112441de8ad4b29dcb7a86dc25c5f770e3c06a9d57e0e5eba48829"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:417b81aa1c9b60b2f8edc463c58363075412866ae4e2b9ab0f690dc1e87ac1b5"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c866b631f5fbce896a74a6e4383407ba7507b815ccc52bcedabb6810fdb3ef7"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b118afbb3202f5911486ad52da86d1d52305b59e7ef2031cea3425142b97d6f"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa"}, - {file = "ruff-0.6.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ef0cc774b00fec123f635ce5c547dac263f6ee9fb9cc83437c5904183b55ceb"}, - {file = "ruff-0.6.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:12edd2af0c60fa61ff31cefb90aef4288ac4d372b4962c2864aeea3a1a2460c0"}, - {file = "ruff-0.6.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:55bb01caeaf3a60b2b2bba07308a02fca6ab56233302406ed5245180a05c5625"}, - {file = "ruff-0.6.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:925d26471fa24b0ce5a6cdfab1bb526fb4159952385f386bdcc643813d472039"}, - {file = "ruff-0.6.9-py3-none-win32.whl", hash = "sha256:eb61ec9bdb2506cffd492e05ac40e5bc6284873aceb605503d8494180d6fc84d"}, - {file = "ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117"}, - {file = "ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93"}, - {file = "ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2"}, + {file = "ruff-0.7.0-py3-none-linux_armv6l.whl", hash = "sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628"}, + {file = "ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737"}, + {file = "ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11"}, + {file = "ruff-0.7.0-py3-none-win32.whl", hash = "sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec"}, + {file = "ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2"}, + {file = "ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e"}, + {file = "ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b"}, ] [[package]] @@ -1815,4 +1815,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "67940b1bdb20630081a00248b6a51f093a44a2da76048873c722c97689a2a31c" +content-hash = "9f70911e2e4764b623fece710f5c545e7313fa9e5a03fdeec8266faf3c5b7c26" diff --git a/pyproject.toml b/pyproject.toml index 35a5f119a5..997136f6e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" # linter -ruff = ">=0.5.0,<0.7.0" +ruff = ">=0.5.0,<0.8.0" pre-commit = ">=2.18,<4.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" From 4968868b7d036eda01fd2d1fec738115a6e88941 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 01:37:05 +0000 Subject: [PATCH 312/598] build(deps-dev): bump mypy from 1.12.0 to 1.12.1 Bumps [mypy](https://github.com/python/mypy) from 1.12.0 to 1.12.1. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.12.0...v1.12.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 66 ++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/poetry.lock b/poetry.lock index 131b803d13..d039066213 100644 --- a/poetry.lock +++ b/poetry.lock @@ -809,43 +809,43 @@ files = [ [[package]] name = "mypy" -version = "1.12.0" +version = "1.12.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4397081e620dc4dc18e2f124d5e1d2c288194c2c08df6bdb1db31c38cd1fe1ed"}, - {file = "mypy-1.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:684a9c508a283f324804fea3f0effeb7858eb03f85c4402a967d187f64562469"}, - {file = "mypy-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cabe4cda2fa5eca7ac94854c6c37039324baaa428ecbf4de4567279e9810f9e"}, - {file = "mypy-1.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:060a07b10e999ac9e7fa249ce2bdcfa9183ca2b70756f3bce9df7a92f78a3c0a"}, - {file = "mypy-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:0eff042d7257f39ba4ca06641d110ca7d2ad98c9c1fb52200fe6b1c865d360ff"}, - {file = "mypy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b86de37a0da945f6d48cf110d5206c5ed514b1ca2614d7ad652d4bf099c7de7"}, - {file = "mypy-1.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20c7c5ce0c1be0b0aea628374e6cf68b420bcc772d85c3c974f675b88e3e6e57"}, - {file = "mypy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a64ee25f05fc2d3d8474985c58042b6759100a475f8237da1f4faf7fcd7e6309"}, - {file = "mypy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:faca7ab947c9f457a08dcb8d9a8664fd438080e002b0fa3e41b0535335edcf7f"}, - {file = "mypy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:5bc81701d52cc8767005fdd2a08c19980de9ec61a25dbd2a937dfb1338a826f9"}, - {file = "mypy-1.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8462655b6694feb1c99e433ea905d46c478041a8b8f0c33f1dab00ae881b2164"}, - {file = "mypy-1.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:923ea66d282d8af9e0f9c21ffc6653643abb95b658c3a8a32dca1eff09c06475"}, - {file = "mypy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ebf9e796521f99d61864ed89d1fb2926d9ab6a5fab421e457cd9c7e4dd65aa9"}, - {file = "mypy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e478601cc3e3fa9d6734d255a59c7a2e5c2934da4378f3dd1e3411ea8a248642"}, - {file = "mypy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:c72861b7139a4f738344faa0e150834467521a3fba42dc98264e5aa9507dd601"}, - {file = "mypy-1.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52b9e1492e47e1790360a43755fa04101a7ac72287b1a53ce817f35899ba0521"}, - {file = "mypy-1.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:48d3e37dd7d9403e38fa86c46191de72705166d40b8c9f91a3de77350daa0893"}, - {file = "mypy-1.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f106db5ccb60681b622ac768455743ee0e6a857724d648c9629a9bd2ac3f721"}, - {file = "mypy-1.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:233e11b3f73ee1f10efada2e6da0f555b2f3a5316e9d8a4a1224acc10e7181d3"}, - {file = "mypy-1.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:4ae8959c21abcf9d73aa6c74a313c45c0b5a188752bf37dace564e29f06e9c1b"}, - {file = "mypy-1.12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eafc1b7319b40ddabdc3db8d7d48e76cfc65bbeeafaa525a4e0fa6b76175467f"}, - {file = "mypy-1.12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9b9ce1ad8daeb049c0b55fdb753d7414260bad8952645367e70ac91aec90e07e"}, - {file = "mypy-1.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfe012b50e1491d439172c43ccb50db66d23fab714d500b57ed52526a1020bb7"}, - {file = "mypy-1.12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2c40658d4fa1ab27cb53d9e2f1066345596af2f8fe4827defc398a09c7c9519b"}, - {file = "mypy-1.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:dee78a8b9746c30c1e617ccb1307b351ded57f0de0d287ca6276378d770006c0"}, - {file = "mypy-1.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b5df6c8a8224f6b86746bda716bbe4dbe0ce89fd67b1fa4661e11bfe38e8ec8"}, - {file = "mypy-1.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5feee5c74eb9749e91b77f60b30771563327329e29218d95bedbe1257e2fe4b0"}, - {file = "mypy-1.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:77278e8c6ffe2abfba6db4125de55f1024de9a323be13d20e4f73b8ed3402bd1"}, - {file = "mypy-1.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:dcfb754dea911039ac12434d1950d69a2f05acd4d56f7935ed402be09fad145e"}, - {file = "mypy-1.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:06de0498798527451ffb60f68db0d368bd2bae2bbfb5237eae616d4330cc87aa"}, - {file = "mypy-1.12.0-py3-none-any.whl", hash = "sha256:fd313226af375d52e1e36c383f39bf3836e1f192801116b31b090dfcd3ec5266"}, - {file = "mypy-1.12.0.tar.gz", hash = "sha256:65a22d87e757ccd95cbbf6f7e181e6caa87128255eb2b6be901bb71b26d8a99d"}, + {file = "mypy-1.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3d7d4371829184e22fda4015278fbfdef0327a4b955a483012bd2d423a788801"}, + {file = "mypy-1.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f59f1dfbf497d473201356966e353ef09d4daec48caeacc0254db8ef633a28a5"}, + {file = "mypy-1.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b947097fae68004b8328c55161ac9db7d3566abfef72d9d41b47a021c2fba6b1"}, + {file = "mypy-1.12.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96af62050971c5241afb4701c15189ea9507db89ad07794a4ee7b4e092dc0627"}, + {file = "mypy-1.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:d90da248f4c2dba6c44ddcfea94bb361e491962f05f41990ff24dbd09969ce20"}, + {file = "mypy-1.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1230048fec1380faf240be6385e709c8570604d2d27ec6ca7e573e3bc09c3735"}, + {file = "mypy-1.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:02dcfe270c6ea13338210908f8cadc8d31af0f04cee8ca996438fe6a97b4ec66"}, + {file = "mypy-1.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5a437c9102a6a252d9e3a63edc191a3aed5f2fcb786d614722ee3f4472e33f6"}, + {file = "mypy-1.12.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:186e0c8346efc027ee1f9acf5ca734425fc4f7dc2b60144f0fbe27cc19dc7931"}, + {file = "mypy-1.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:673ba1140a478b50e6d265c03391702fa11a5c5aff3f54d69a62a48da32cb811"}, + {file = "mypy-1.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9fb83a7be97c498176fb7486cafbb81decccaef1ac339d837c377b0ce3743a7f"}, + {file = "mypy-1.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:389e307e333879c571029d5b93932cf838b811d3f5395ed1ad05086b52148fb0"}, + {file = "mypy-1.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94b2048a95a21f7a9ebc9fbd075a4fcd310410d078aa0228dbbad7f71335e042"}, + {file = "mypy-1.12.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5932370ccf7ebf83f79d1c157a5929d7ea36313027b0d70a488493dc1b179"}, + {file = "mypy-1.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:19bf51f87a295e7ab2894f1d8167622b063492d754e69c3c2fed6563268cb42a"}, + {file = "mypy-1.12.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d34167d43613ffb1d6c6cdc0cc043bb106cac0aa5d6a4171f77ab92a3c758bcc"}, + {file = "mypy-1.12.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:427878aa54f2e2c5d8db31fa9010c599ed9f994b3b49e64ae9cd9990c40bd635"}, + {file = "mypy-1.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5fcde63ea2c9f69d6be859a1e6dd35955e87fa81de95bc240143cf00de1f7f81"}, + {file = "mypy-1.12.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d54d840f6c052929f4a3d2aab2066af0f45a020b085fe0e40d4583db52aab4e4"}, + {file = "mypy-1.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:20db6eb1ca3d1de8ece00033b12f793f1ea9da767334b7e8c626a4872090cf02"}, + {file = "mypy-1.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b16fe09f9c741d85a2e3b14a5257a27a4f4886c171d562bc5a5e90d8591906b8"}, + {file = "mypy-1.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0dcc1e843d58f444fce19da4cce5bd35c282d4bde232acdeca8279523087088a"}, + {file = "mypy-1.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e10ba7de5c616e44ad21005fa13450cd0de7caaa303a626147d45307492e4f2d"}, + {file = "mypy-1.12.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0e6fe449223fa59fbee351db32283838a8fee8059e0028e9e6494a03802b4004"}, + {file = "mypy-1.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:dc6e2a2195a290a7fd5bac3e60b586d77fc88e986eba7feced8b778c373f9afe"}, + {file = "mypy-1.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:de5b2a8988b4e1269a98beaf0e7cc71b510d050dce80c343b53b4955fff45f19"}, + {file = "mypy-1.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843826966f1d65925e8b50d2b483065c51fc16dc5d72647e0236aae51dc8d77e"}, + {file = "mypy-1.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fe20f89da41a95e14c34b1ddb09c80262edcc295ad891f22cc4b60013e8f78d"}, + {file = "mypy-1.12.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8135ffec02121a75f75dc97c81af7c14aa4ae0dda277132cfcd6abcd21551bfd"}, + {file = "mypy-1.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:a7b76fa83260824300cc4834a3ab93180db19876bce59af921467fd03e692810"}, + {file = "mypy-1.12.1-py3-none-any.whl", hash = "sha256:ce561a09e3bb9863ab77edf29ae3a50e65685ad74bba1431278185b7e5d5486e"}, + {file = "mypy-1.12.1.tar.gz", hash = "sha256:f5b3936f7a6d0e8280c9bdef94c7ce4847f5cdfc258fbb2c29a8c1711e8bb96d"}, ] [package.dependencies] From 29d6e64bfed337aeb734714a019dd38473457690 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 01:36:14 +0000 Subject: [PATCH 313/598] build(deps-dev): bump mkdocs-material from 9.5.41 to 9.5.42 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.41 to 9.5.42. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.41...9.5.42) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d039066213..38e07d51f1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -769,13 +769,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.41" +version = "9.5.42" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.41-py3-none-any.whl", hash = "sha256:990bc138c33342b5b73e7545915ebc0136e501bfbd8e365735144f5120891d83"}, - {file = "mkdocs_material-9.5.41.tar.gz", hash = "sha256:30fa5d459b4b8130848ecd8e1c908878345d9d8268f7ddbc31eebe88d462d97b"}, + {file = "mkdocs_material-9.5.42-py3-none-any.whl", hash = "sha256:452a7c5d21284b373f36b981a2cbebfff59263feebeede1bc28652e9c5bbe316"}, + {file = "mkdocs_material-9.5.42.tar.gz", hash = "sha256:92779b5e9b5934540c574c11647131d217dc540dce72b05feeda088c8eb1b8f2"}, ] [package.dependencies] From af3553b2a5b92bb2afab3f068d47fdcabe0857a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 01:17:32 +0000 Subject: [PATCH 314/598] build(deps-dev): bump rich from 13.9.2 to 13.9.3 Bumps [rich](https://github.com/Textualize/rich) from 13.9.2 to 13.9.3. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.9.2...v13.9.3) --- updated-dependencies: - dependency-name: rich dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 38e07d51f1..77d7277d7c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1430,13 +1430,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.9.2" +version = "13.9.3" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" files = [ - {file = "rich-13.9.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"}, - {file = "rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c"}, + {file = "rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283"}, + {file = "rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e"}, ] [package.dependencies] From e5aaec47b51c44285de67b3302438fc7e411d20a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 01:18:07 +0000 Subject: [PATCH 315/598] build(deps-dev): bump mypy from 1.12.1 to 1.13.0 Bumps [mypy](https://github.com/python/mypy) from 1.12.1 to 1.13.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.12.1...v1.13.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 67 +++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/poetry.lock b/poetry.lock index 77d7277d7c..93f9915ac9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -809,43 +809,43 @@ files = [ [[package]] name = "mypy" -version = "1.12.1" +version = "1.13.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3d7d4371829184e22fda4015278fbfdef0327a4b955a483012bd2d423a788801"}, - {file = "mypy-1.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f59f1dfbf497d473201356966e353ef09d4daec48caeacc0254db8ef633a28a5"}, - {file = "mypy-1.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b947097fae68004b8328c55161ac9db7d3566abfef72d9d41b47a021c2fba6b1"}, - {file = "mypy-1.12.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96af62050971c5241afb4701c15189ea9507db89ad07794a4ee7b4e092dc0627"}, - {file = "mypy-1.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:d90da248f4c2dba6c44ddcfea94bb361e491962f05f41990ff24dbd09969ce20"}, - {file = "mypy-1.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1230048fec1380faf240be6385e709c8570604d2d27ec6ca7e573e3bc09c3735"}, - {file = "mypy-1.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:02dcfe270c6ea13338210908f8cadc8d31af0f04cee8ca996438fe6a97b4ec66"}, - {file = "mypy-1.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5a437c9102a6a252d9e3a63edc191a3aed5f2fcb786d614722ee3f4472e33f6"}, - {file = "mypy-1.12.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:186e0c8346efc027ee1f9acf5ca734425fc4f7dc2b60144f0fbe27cc19dc7931"}, - {file = "mypy-1.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:673ba1140a478b50e6d265c03391702fa11a5c5aff3f54d69a62a48da32cb811"}, - {file = "mypy-1.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9fb83a7be97c498176fb7486cafbb81decccaef1ac339d837c377b0ce3743a7f"}, - {file = "mypy-1.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:389e307e333879c571029d5b93932cf838b811d3f5395ed1ad05086b52148fb0"}, - {file = "mypy-1.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94b2048a95a21f7a9ebc9fbd075a4fcd310410d078aa0228dbbad7f71335e042"}, - {file = "mypy-1.12.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5932370ccf7ebf83f79d1c157a5929d7ea36313027b0d70a488493dc1b179"}, - {file = "mypy-1.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:19bf51f87a295e7ab2894f1d8167622b063492d754e69c3c2fed6563268cb42a"}, - {file = "mypy-1.12.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d34167d43613ffb1d6c6cdc0cc043bb106cac0aa5d6a4171f77ab92a3c758bcc"}, - {file = "mypy-1.12.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:427878aa54f2e2c5d8db31fa9010c599ed9f994b3b49e64ae9cd9990c40bd635"}, - {file = "mypy-1.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5fcde63ea2c9f69d6be859a1e6dd35955e87fa81de95bc240143cf00de1f7f81"}, - {file = "mypy-1.12.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d54d840f6c052929f4a3d2aab2066af0f45a020b085fe0e40d4583db52aab4e4"}, - {file = "mypy-1.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:20db6eb1ca3d1de8ece00033b12f793f1ea9da767334b7e8c626a4872090cf02"}, - {file = "mypy-1.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b16fe09f9c741d85a2e3b14a5257a27a4f4886c171d562bc5a5e90d8591906b8"}, - {file = "mypy-1.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0dcc1e843d58f444fce19da4cce5bd35c282d4bde232acdeca8279523087088a"}, - {file = "mypy-1.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e10ba7de5c616e44ad21005fa13450cd0de7caaa303a626147d45307492e4f2d"}, - {file = "mypy-1.12.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0e6fe449223fa59fbee351db32283838a8fee8059e0028e9e6494a03802b4004"}, - {file = "mypy-1.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:dc6e2a2195a290a7fd5bac3e60b586d77fc88e986eba7feced8b778c373f9afe"}, - {file = "mypy-1.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:de5b2a8988b4e1269a98beaf0e7cc71b510d050dce80c343b53b4955fff45f19"}, - {file = "mypy-1.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843826966f1d65925e8b50d2b483065c51fc16dc5d72647e0236aae51dc8d77e"}, - {file = "mypy-1.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fe20f89da41a95e14c34b1ddb09c80262edcc295ad891f22cc4b60013e8f78d"}, - {file = "mypy-1.12.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8135ffec02121a75f75dc97c81af7c14aa4ae0dda277132cfcd6abcd21551bfd"}, - {file = "mypy-1.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:a7b76fa83260824300cc4834a3ab93180db19876bce59af921467fd03e692810"}, - {file = "mypy-1.12.1-py3-none-any.whl", hash = "sha256:ce561a09e3bb9863ab77edf29ae3a50e65685ad74bba1431278185b7e5d5486e"}, - {file = "mypy-1.12.1.tar.gz", hash = "sha256:f5b3936f7a6d0e8280c9bdef94c7ce4847f5cdfc258fbb2c29a8c1711e8bb96d"}, + {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, + {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, + {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, + {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, + {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, + {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, + {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, + {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, + {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, + {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, + {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, + {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, + {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, + {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, + {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, + {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, + {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, + {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, + {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, + {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, + {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, + {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, + {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, + {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, + {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, + {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, + {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, + {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, + {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, + {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, + {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, + {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, ] [package.dependencies] @@ -855,6 +855,7 @@ typing-extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] install-types = ["pip"] mypyc = ["setuptools (>=50)"] reports = ["lxml"] From 78dc765f057025b2f87ace7e39ab383844e01e50 Mon Sep 17 00:00:00 2001 From: Arne Schwerdt Date: Thu, 17 Oct 2024 17:40:21 +0200 Subject: [PATCH 316/598] docs(commit): add multiline option `questions` content table --- docs/customization.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/customization.md b/docs/customization.md index e8f233fce1..c6829b5daf 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -168,14 +168,15 @@ commitizen: #### Detailed `questions` content -| Parameter | Type | Default | Description | -| --------- | ------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `type` | `str` | `None` | The type of questions. Valid type: `list`, `input` and etc. [See More][different-question-types] | -| `name` | `str` | `None` | The key for the value answered by user. It's used in `message_template` | -| `message` | `str` | `None` | Detail description for the question. | -| `choices` | `list` | `None` | (OPTIONAL) The choices when `type = list`. Either use a list of values or a list of dictionaries with `name` and `value` keys. Keyboard shortcuts can be defined via `key`. See examples above. | -| `default` | `Any` | `None` | (OPTIONAL) The default value for this question. | -| `filter` | `str` | `None` | (Optional) Validator for user's answer. **(Work in Progress)** | +| Parameter | Type | Default | Description | +| ----------- | ------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | `str` | `None` | The type of questions. Valid type: `list`, `input` and etc. [See More][different-question-types] | +| `name` | `str` | `None` | The key for the value answered by user. It's used in `message_template` | +| `message` | `str` | `None` | Detail description for the question. | +| `choices` | `list` | `None` | (OPTIONAL) The choices when `type = list`. Either use a list of values or a list of dictionaries with `name` and `value` keys. Keyboard shortcuts can be defined via `key`. See examples above. | +| `default` | `Any` | `None` | (OPTIONAL) The default value for this question. | +| `filter` | `str` | `None` | (Optional) Validator for user's answer. **(Work in Progress)** | +| `multiline` | `bool` | `False` | (OPTIONAL) Enable multiline support when `type = input`. | [different-question-types]: https://github.com/tmbo/questionary#different-question-types #### Shortcut keys From 2f6b7ccf30da38dcd76af01f6498c54918d4d985 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Wed, 23 Oct 2024 09:41:18 +0800 Subject: [PATCH 317/598] docs(customization): Unify capitalization --- docs/customization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/customization.md b/docs/customization.md index c6829b5daf..3ba0bf6f3c 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -175,7 +175,7 @@ commitizen: | `message` | `str` | `None` | Detail description for the question. | | `choices` | `list` | `None` | (OPTIONAL) The choices when `type = list`. Either use a list of values or a list of dictionaries with `name` and `value` keys. Keyboard shortcuts can be defined via `key`. See examples above. | | `default` | `Any` | `None` | (OPTIONAL) The default value for this question. | -| `filter` | `str` | `None` | (Optional) Validator for user's answer. **(Work in Progress)** | +| `filter` | `str` | `None` | (OPTIONAL) Validator for user's answer. **(Work in Progress)** | | `multiline` | `bool` | `False` | (OPTIONAL) Enable multiline support when `type = input`. | [different-question-types]: https://github.com/tmbo/questionary#different-question-types From 08a259d2de99138035c08af35ec515fb8455aa83 Mon Sep 17 00:00:00 2001 From: josix Date: Tue, 15 Oct 2024 19:04:42 +0800 Subject: [PATCH 318/598] feat(commands/commit): add force-edit functionality after answering questions refactor: remove redundant return None Co-authored-by: Wei Lee Update test_commit_command.py Co-authored-by: Wei Lee --- commitizen/cli.py | 6 + commitizen/commands/commit.py | 24 ++++ commitizen/git.py | 7 ++ docs/contributing.md | 2 +- docs/images/cli_help/cz_commit___help.svg | 112 +++++++++--------- tests/commands/test_commit_command.py | 30 +++++ ...shows_description_when_use_help_option.txt | 3 +- tests/test_git.py | 20 ++++ 8 files changed, 148 insertions(+), 56 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 3c529e4210..e911b6da58 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -156,6 +156,12 @@ def __call__( "action": "store_true", "help": "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.", }, + { + "name": ["-e", "--edit"], + "action": "store_true", + "default": False, + "help": "edit the commit message before committing", + }, { "name": ["-l", "--message-length-limit"], "type": int, diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 0816b2e508..c955d02a51 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -2,6 +2,9 @@ import contextlib import os +import shutil +import subprocess +import tempfile import questionary @@ -72,9 +75,27 @@ def prompt_commit_questions(self) -> str: return message + def manual_edit(self, message: str) -> str: + editor = git.get_core_editor() + if editor is None: + raise RuntimeError("No 'editor' value given and no default available.") + exec_path = shutil.which(editor) + if exec_path is None: + raise RuntimeError(f"Editor '{editor}' not found.") + with tempfile.NamedTemporaryFile(mode="w", delete=False) as file: + file.write(message) + file_path = file.name + argv = [exec_path, file_path] + subprocess.call(argv) + with open(file_path) as temp_file: + message = temp_file.read().strip() + file.unlink() + return message + def __call__(self): dry_run: bool = self.arguments.get("dry_run") write_message_to_file: bool = self.arguments.get("write_message_to_file") + manual_edit: bool = self.arguments.get("edit") is_all: bool = self.arguments.get("all") if is_all: @@ -101,6 +122,9 @@ def __call__(self): else: m = self.prompt_commit_questions() + if manual_edit: + m = self.manual_edit(m) + out.info(f"\n{m}\n") if write_message_to_file: diff --git a/commitizen/git.py b/commitizen/git.py index 1f758889ed..7de8e1f1c8 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -271,6 +271,13 @@ def get_eol_style() -> EOLTypes: return map["native"] +def get_core_editor() -> str | None: + c = cmd.run("git var GIT_EDITOR") + if c.out: + return c.out.strip() + return None + + def smart_open(*args, **kargs): """Open a file with the EOL style determined from Git.""" return open(*args, newline=get_eol_style().get_eol_for_open(), **kargs) diff --git a/docs/contributing.md b/docs/contributing.md index a41843d753..a49196277e 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -22,7 +22,7 @@ If you're a first-time contributor, you can check the issues with [good first is (We use [CodeCov](https://codecov.io/) to ensure our test coverage does not drop.) 7. Use [commitizen](https://github.com/commitizen-tools/commitizen) to do git commit. We follow [conventional commits](https://www.conventionalcommits.org/). 8. Run `./scripts/format` and `./scripts/test` to ensure you follow the coding style and the tests pass. -9. Optionally, update the `./docs/README.md`. +9. Optionally, update the `./docs/README.md` or `docs/images/cli_help` (through running `scripts/gen_cli_help_screenshots.py`). 9. **Do not** update the `CHANGELOG.md`, it will be automatically created after merging to `master`. 10. **Do not** update the versions in the project, they will be automatically updated. 10. If your changes are about documentation. Run `poetry run mkdocs serve` to serve documentation locally and check whether there is any warning or error. diff --git a/docs/images/cli_help/cz_commit___help.svg b/docs/images/cli_help/cz_commit___help.svg index 1b7c98953c..452e419908 100644 --- a/docs/images/cli_help/cz_commit___help.svg +++ b/docs/images/cli_help/cz_commit___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - - $ cz commit --help -usage: cz commit [-h][--retry][--no-retry][--dry-run] -[--write-message-to-file FILE_PATH][-s][-a] -[-l MESSAGE_LENGTH_LIMIT] - -create new commit - -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. -  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit - + + $ cz commit --help +usage: cz commit [-h][--retry][--no-retry][--dry-run] +[--write-message-to-file FILE_PATH][-s][-a][-e] +[-l MESSAGE_LENGTH_LIMIT] + +create new commit + +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. +  -e, --edit            edit the commit message before committing +  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit + diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 03ff51c42c..91a75e0970 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -410,6 +410,36 @@ def test_commit_command_with_message_length_limit(config, mocker: MockFixture): commands.Commit(config, {"message_length_limit": message_length - 1})() +@pytest.mark.usefixtures("staging_is_clean") +@pytest.mark.parametrize("editor", ["vim", None]) +def test_manual_edit(editor, config, mocker: MockFixture, tmp_path): + mocker.patch("commitizen.git.get_core_editor", return_value=editor) + subprocess_mock = mocker.patch("subprocess.call") + + mocker.patch("shutil.which", return_value=editor) + + test_message = "Initial commit message" + temp_file = tmp_path / "temp_commit_message" + temp_file.write_text(test_message) + + mock_temp_file = mocker.patch("tempfile.NamedTemporaryFile") + mock_temp_file.return_value.__enter__.return_value.name = str(temp_file) + + commit_cmd = commands.Commit(config, {"edit": True}) + + if editor is None: + with pytest.raises(RuntimeError): + commit_cmd.manual_edit(test_message) + else: + edited_message = commit_cmd.manual_edit(test_message) + + subprocess_mock.assert_called_once_with(["vim", str(temp_file)]) + + assert edited_message == test_message.strip() + + temp_file.unlink() + + @skip_below_py_3_13 def test_commit_command_shows_description_when_use_help_option( mocker: MockFixture, capsys, file_regression diff --git a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt index 92f3cf5e87..955b3d8fd7 100644 --- a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt @@ -1,5 +1,5 @@ usage: cz commit [-h] [--retry] [--no-retry] [--dry-run] - [--write-message-to-file FILE_PATH] [-s] [-a] + [--write-message-to-file FILE_PATH] [-s] [-a] [-e] [-l MESSAGE_LENGTH_LIMIT] create new commit @@ -16,5 +16,6 @@ options: -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. + -e, --edit edit the commit message before committing -l, --message-length-limit MESSAGE_LENGTH_LIMIT length limit of the commit message; 0 for no limit diff --git a/tests/test_git.py b/tests/test_git.py index 6ada76be6d..8bf995e8a8 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -283,6 +283,26 @@ def test_eoltypes_get_eol_for_open(): assert git.EOLTypes.get_eol_for_open(git.EOLTypes.CRLF) == "\r\n" +def test_get_core_editor(mocker): + mocker.patch.dict(os.environ, {"GIT_EDITOR": "nano"}) + assert git.get_core_editor() == "nano" + + mocker.patch.dict(os.environ, clear=True) + mocker.patch( + "commitizen.cmd.run", + return_value=cmd.Command( + out="vim", err="", stdout=b"", stderr=b"", return_code=0 + ), + ) + assert git.get_core_editor() == "vim" + + mocker.patch( + "commitizen.cmd.run", + return_value=cmd.Command(out="", err="", stdout=b"", stderr=b"", return_code=1), + ) + assert git.get_core_editor() is None + + def test_create_tag_with_message(tmp_commitizen_project): with tmp_commitizen_project.as_cwd(): create_file_and_commit("feat(test): test") From bfe422faef54a78ff8c0ce5dea0da053159c9f9d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 23 Oct 2024 13:51:04 +0000 Subject: [PATCH 319/598] =?UTF-8?q?bump:=20version=203.29.1=20=E2=86=92=20?= =?UTF-8?q?3.30.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 10 ++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9b5027b93d..a83ba0dcf6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v3.29.1 # automatically updated by Commitizen + rev: v3.30.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index fd591be06d..b93413fd4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v3.30.0 (2024-10-23) + +### Feat + +- **commands/commit**: add force-edit functionality after answering questions + +### Refactor + +- remove redundant return None + ## v3.29.1 (2024-09-26) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index ca267c56e1..1df56e3df4 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.29.1" +__version__ = "3.30.0" diff --git a/pyproject.toml b/pyproject.toml index 997136f6e2..c4230d8edf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.29.1" +version = "3.30.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.29.1" +version = "3.30.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From a368e75a4ce958992bc3570748d5b8342136783a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2024 01:28:42 +0000 Subject: [PATCH 320/598] build(deps-dev): bump ruff from 0.7.0 to 0.7.1 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.0 to 0.7.1. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.7.0...0.7.1) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 93f9915ac9..255a6a0356 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1450,29 +1450,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.7.0" +version = "0.7.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.0-py3-none-linux_armv6l.whl", hash = "sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628"}, - {file = "ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737"}, - {file = "ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11"}, - {file = "ruff-0.7.0-py3-none-win32.whl", hash = "sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec"}, - {file = "ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2"}, - {file = "ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e"}, - {file = "ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b"}, + {file = "ruff-0.7.1-py3-none-linux_armv6l.whl", hash = "sha256:cb1bc5ed9403daa7da05475d615739cc0212e861b7306f314379d958592aaa89"}, + {file = "ruff-0.7.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27c1c52a8d199a257ff1e5582d078eab7145129aa02721815ca8fa4f9612dc35"}, + {file = "ruff-0.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:588a34e1ef2ea55b4ddfec26bbe76bc866e92523d8c6cdec5e8aceefeff02d99"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94fc32f9cdf72dc75c451e5f072758b118ab8100727168a3df58502b43a599ca"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:985818742b833bffa543a84d1cc11b5e6871de1b4e0ac3060a59a2bae3969250"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32f1e8a192e261366c702c5fb2ece9f68d26625f198a25c408861c16dc2dea9c"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:699085bf05819588551b11751eff33e9ca58b1b86a6843e1b082a7de40da1565"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344cc2b0814047dc8c3a8ff2cd1f3d808bb23c6658db830d25147339d9bf9ea7"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4316bbf69d5a859cc937890c7ac7a6551252b6a01b1d2c97e8fc96e45a7c8b4a"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5c121b46abde94a505175524e51891f829414e093cd8326d6e741ecfc0a9112"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8422104078324ea250886954e48f1373a8fe7de59283d747c3a7eca050b4e378"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:56aad830af8a9db644e80098fe4984a948e2b6fc2e73891538f43bbe478461b8"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:658304f02f68d3a83c998ad8bf91f9b4f53e93e5412b8f2388359d55869727fd"}, + {file = "ruff-0.7.1-py3-none-win32.whl", hash = "sha256:b517a2011333eb7ce2d402652ecaa0ac1a30c114fbbd55c6b8ee466a7f600ee9"}, + {file = "ruff-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307"}, + {file = "ruff-0.7.1-py3-none-win_arm64.whl", hash = "sha256:19aa200ec824c0f36d0c9114c8ec0087082021732979a359d6f3c390a6ff2a37"}, + {file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"}, ] [[package]] From ffb26fb524e46916736bd08cab49c1dd663d7111 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 01:50:54 +0000 Subject: [PATCH 321/598] build(deps-dev): bump mkdocs-material from 9.5.42 to 9.5.43 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.42 to 9.5.43. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.42...9.5.43) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 255a6a0356..f54f032e0c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -769,13 +769,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.42" +version = "9.5.43" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.42-py3-none-any.whl", hash = "sha256:452a7c5d21284b373f36b981a2cbebfff59263feebeede1bc28652e9c5bbe316"}, - {file = "mkdocs_material-9.5.42.tar.gz", hash = "sha256:92779b5e9b5934540c574c11647131d217dc540dce72b05feeda088c8eb1b8f2"}, + {file = "mkdocs_material-9.5.43-py3-none-any.whl", hash = "sha256:4aae0664c456fd12837a3192e0225c17960ba8bf55d7f0a7daef7e4b0b914a34"}, + {file = "mkdocs_material-9.5.43.tar.gz", hash = "sha256:83be7ff30b65a1e4930dfa4ab911e75780a3afc9583d162692e434581cb46979"}, ] [package.dependencies] From d785b3c2c92ff5c6d4d796b28ace1c7dd8b563fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 01:17:32 +0000 Subject: [PATCH 322/598] build(deps-dev): bump ruff from 0.7.1 to 0.7.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.1 to 0.7.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.7.1...0.7.2) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index f54f032e0c..8c852e59db 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1450,29 +1450,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.7.1" +version = "0.7.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.1-py3-none-linux_armv6l.whl", hash = "sha256:cb1bc5ed9403daa7da05475d615739cc0212e861b7306f314379d958592aaa89"}, - {file = "ruff-0.7.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27c1c52a8d199a257ff1e5582d078eab7145129aa02721815ca8fa4f9612dc35"}, - {file = "ruff-0.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:588a34e1ef2ea55b4ddfec26bbe76bc866e92523d8c6cdec5e8aceefeff02d99"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94fc32f9cdf72dc75c451e5f072758b118ab8100727168a3df58502b43a599ca"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:985818742b833bffa543a84d1cc11b5e6871de1b4e0ac3060a59a2bae3969250"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32f1e8a192e261366c702c5fb2ece9f68d26625f198a25c408861c16dc2dea9c"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:699085bf05819588551b11751eff33e9ca58b1b86a6843e1b082a7de40da1565"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344cc2b0814047dc8c3a8ff2cd1f3d808bb23c6658db830d25147339d9bf9ea7"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4316bbf69d5a859cc937890c7ac7a6551252b6a01b1d2c97e8fc96e45a7c8b4a"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5c121b46abde94a505175524e51891f829414e093cd8326d6e741ecfc0a9112"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8422104078324ea250886954e48f1373a8fe7de59283d747c3a7eca050b4e378"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:56aad830af8a9db644e80098fe4984a948e2b6fc2e73891538f43bbe478461b8"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:658304f02f68d3a83c998ad8bf91f9b4f53e93e5412b8f2388359d55869727fd"}, - {file = "ruff-0.7.1-py3-none-win32.whl", hash = "sha256:b517a2011333eb7ce2d402652ecaa0ac1a30c114fbbd55c6b8ee466a7f600ee9"}, - {file = "ruff-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307"}, - {file = "ruff-0.7.1-py3-none-win_arm64.whl", hash = "sha256:19aa200ec824c0f36d0c9114c8ec0087082021732979a359d6f3c390a6ff2a37"}, - {file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"}, + {file = "ruff-0.7.2-py3-none-linux_armv6l.whl", hash = "sha256:b73f873b5f52092e63ed540adefc3c36f1f803790ecf2590e1df8bf0a9f72cb8"}, + {file = "ruff-0.7.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5b813ef26db1015953daf476202585512afd6a6862a02cde63f3bafb53d0b2d4"}, + {file = "ruff-0.7.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:853277dbd9675810c6826dad7a428d52a11760744508340e66bf46f8be9701d9"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21aae53ab1490a52bf4e3bf520c10ce120987b047c494cacf4edad0ba0888da2"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccc7e0fc6e0cb3168443eeadb6445285abaae75142ee22b2b72c27d790ab60ba"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd77877a4e43b3a98e5ef4715ba3862105e299af0c48942cc6d51ba3d97dc859"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e00163fb897d35523c70d71a46fbaa43bf7bf9af0f4534c53ea5b96b2e03397b"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3c54b538633482dc342e9b634d91168fe8cc56b30a4b4f99287f4e339103e88"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b792468e9804a204be221b14257566669d1db5c00d6bb335996e5cd7004ba80"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dba53ed84ac19ae4bfb4ea4bf0172550a2285fa27fbb13e3746f04c80f7fa088"}, + {file = "ruff-0.7.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b19fafe261bf741bca2764c14cbb4ee1819b67adb63ebc2db6401dcd652e3748"}, + {file = "ruff-0.7.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28bd8220f4d8f79d590db9e2f6a0674f75ddbc3847277dd44ac1f8d30684b828"}, + {file = "ruff-0.7.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9fd67094e77efbea932e62b5d2483006154794040abb3a5072e659096415ae1e"}, + {file = "ruff-0.7.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:576305393998b7bd6c46018f8104ea3a9cb3fa7908c21d8580e3274a3b04b691"}, + {file = "ruff-0.7.2-py3-none-win32.whl", hash = "sha256:fa993cfc9f0ff11187e82de874dfc3611df80852540331bc85c75809c93253a8"}, + {file = "ruff-0.7.2-py3-none-win_amd64.whl", hash = "sha256:dd8800cbe0254e06b8fec585e97554047fb82c894973f7ff18558eee33d1cb88"}, + {file = "ruff-0.7.2-py3-none-win_arm64.whl", hash = "sha256:bb8368cd45bba3f57bb29cbb8d64b4a33f8415d0149d2655c5c8539452ce7760"}, + {file = "ruff-0.7.2.tar.gz", hash = "sha256:2b14e77293380e475b4e3a7a368e14549288ed2931fce259a6f99978669e844f"}, ] [[package]] From fc929208abe0ceda456f7203a61f28ea0afef9ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 01:18:08 +0000 Subject: [PATCH 323/598] build(deps-dev): bump rich from 13.9.3 to 13.9.4 Bumps [rich](https://github.com/Textualize/rich) from 13.9.3 to 13.9.4. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.9.3...v13.9.4) --- updated-dependencies: - dependency-name: rich dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8c852e59db..2bd5a56b56 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1431,13 +1431,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.9.3" +version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" files = [ - {file = "rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283"}, - {file = "rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e"}, + {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, + {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, ] [package.dependencies] From 7dd33eadc0f5d1a3dbcf9e92598510bf7c4a9ce4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 01:29:54 +0000 Subject: [PATCH 324/598] build(deps-dev): bump mkdocs-material from 9.5.43 to 9.5.44 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.43 to 9.5.44. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.43...9.5.44) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2bd5a56b56..5da51c321a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -769,13 +769,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.43" +version = "9.5.44" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.43-py3-none-any.whl", hash = "sha256:4aae0664c456fd12837a3192e0225c17960ba8bf55d7f0a7daef7e4b0b914a34"}, - {file = "mkdocs_material-9.5.43.tar.gz", hash = "sha256:83be7ff30b65a1e4930dfa4ab911e75780a3afc9583d162692e434581cb46979"}, + {file = "mkdocs_material-9.5.44-py3-none-any.whl", hash = "sha256:47015f9c167d58a5ff5e682da37441fc4d66a1c79334bfc08d774763cacf69ca"}, + {file = "mkdocs_material-9.5.44.tar.gz", hash = "sha256:f3a6c968e524166b3f3ed1fb97d3ed3e0091183b0545cedf7156a2a6804c56c0"}, ] [package.dependencies] From c49e7a250ef0af6fe09cdd7f4ef3fa36efaf0f91 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 5 Apr 2024 23:24:40 +0800 Subject: [PATCH 325/598] refactor(cz_customize): return empty string for info, example, schema and schema_pattern if not provided --- commitizen/cz/base.py | 10 +++++----- commitizen/cz/customize/customize.py | 16 ++++++++-------- commitizen/exceptions.py | 2 +- docs/customization.md | 10 +++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index bd116ceb02..70929e2f83 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -61,7 +61,7 @@ class BaseCommitizen(metaclass=ABCMeta): template_loader: BaseLoader = PackageLoader("commitizen", "templates") template_extras: dict[str, Any] = {} - def __init__(self, config: BaseConfig): + def __init__(self, config: BaseConfig) -> None: self.config = config if not self.config.settings.get("style"): self.config.settings.update({"style": BaseCommitizen.default_style_config}) @@ -83,19 +83,19 @@ def style(self): ] ) - def example(self) -> str | None: + def example(self) -> str: """Example of the commit message.""" raise NotImplementedError("Not Implemented yet") - def schema(self) -> str | None: + def schema(self) -> str: """Schema definition of the commit message.""" raise NotImplementedError("Not Implemented yet") - def schema_pattern(self) -> str | None: + def schema_pattern(self) -> str: """Regex matching the schema used for message validation.""" raise NotImplementedError("Not Implemented yet") - def info(self) -> str | None: + def info(self) -> str: """Information about the standardized commit message.""" raise NotImplementedError("Not Implemented yet") diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index 5c3b4e76b4..b7f49f28db 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -68,16 +68,16 @@ def message(self, answers: dict) -> str: else: return message_template.render(**answers) - def example(self) -> str | None: - return self.custom_settings.get("example") + def example(self) -> str: + return self.custom_settings.get("example") or "" - def schema_pattern(self) -> str | None: - return self.custom_settings.get("schema_pattern") + def schema_pattern(self) -> str: + return self.custom_settings.get("schema_pattern") or "" - def schema(self) -> str | None: - return self.custom_settings.get("schema") + def schema(self) -> str: + return self.custom_settings.get("schema") or "" - def info(self) -> str | None: + def info(self) -> str: info_path = self.custom_settings.get("info_path") info = self.custom_settings.get("info") if info_path: @@ -86,4 +86,4 @@ def info(self) -> str | None: return content elif info: return info - return None + return "" diff --git a/commitizen/exceptions.py b/commitizen/exceptions.py index c96803b5fb..29733b624b 100644 --- a/commitizen/exceptions.py +++ b/commitizen/exceptions.py @@ -42,7 +42,7 @@ class ExitCode(enum.IntEnum): class CommitizenException(Exception): def __init__(self, *args, **kwargs): self.output_method = kwargs.get("output_method") or out.error - self.exit_code = self.__class__.exit_code + self.exit_code: ExitCode = self.__class__.exit_code if args: self.message = args[0] elif hasattr(self.__class__, "message"): diff --git a/docs/customization.md b/docs/customization.md index 3ba0bf6f3c..16ba588f10 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -151,11 +151,11 @@ commitizen: | ------------------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `questions` | `Questions` | `None` | Questions regarding the commit message. Detailed below. The type `Questions` is an alias to `Iterable[MutableMapping[str, Any]]` which is defined in `commitizen.defaults`. It expects a list of dictionaries. | | `message_template` | `str` | `None` | The template for generating message from the given answers. `message_template` should either follow [Jinja2][jinja2] formatting specification, and all the variables in this template should be defined in `name` in `questions` | -| `example` | `str` | `None` | (OPTIONAL) Provide an example to help understand the style. Used by `cz example`. | -| `schema` | `str` | `None` | (OPTIONAL) Show the schema used. Used by `cz schema`. | -| `schema_pattern` | `str` | `None` | (OPTIONAL) The regular expression used to do commit message validation. Used by `cz check`. | -| `info_path` | `str` | `None` | (OPTIONAL) The path to the file that contains explanation of the commit rules. Used by `cz info`. If not provided `cz info`, will load `info` instead. | -| `info` | `str` | `None` | (OPTIONAL) Explanation of the commit rules. Used by `cz info`. | +| `example` | `str` | `""` | (OPTIONAL) Provide an example to help understand the style. Used by `cz example`. | +| `schema` | `str` | `""` | (OPTIONAL) Show the schema used. Used by `cz schema`. | +| `schema_pattern` | `str` | `""` | (OPTIONAL) The regular expression used to do commit message validation. Used by `cz check`. | +| `info_path` | `str` | `""` | (OPTIONAL) The path to the file that contains explanation of the commit rules. Used by `cz info`. If not provided `cz info`, will load `info` instead. | +| `info` | `str` | `""` | (OPTIONAL) Explanation of the commit rules. Used by `cz info`. | | `bump_map` | `dict` | `None` | (OPTIONAL) Dictionary mapping the extracted information to a `SemVer` increment type (`MAJOR`, `MINOR`, `PATCH`) | | `bump_pattern` | `str` | `None` | (OPTIONAL) Regex to extract information from commit (subject and body) | | `change_type_order`| `str` | `None` | (OPTIONAL) List of strings used to order the Changelog. All other types will be sorted alphabetically. Default is `["BREAKING CHANGE", "Feat", "Fix", "Refactor", "Perf"]` | From 632ab4ff6cfbebac94223f04988c42d5d7b56b69 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 5 Apr 2024 23:28:32 +0800 Subject: [PATCH 326/598] refactor(defaults): disallow style as None --- commitizen/defaults.py | 2 +- tests/test_cz_customize.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 2d092d5004..996c243196 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -45,7 +45,7 @@ class Settings(TypedDict, total=False): changelog_merge_prerelease: bool update_changelog_on_bump: bool use_shortcuts: bool - style: list[tuple[str, str]] | None + style: list[tuple[str, str]] customize: CzSettings major_version_zero: bool pre_bump_hooks: list[str] | None diff --git a/tests/test_cz_customize.py b/tests/test_cz_customize.py index 20a17b3d9c..210c8b6774 100644 --- a/tests/test_cz_customize.py +++ b/tests/test_cz_customize.py @@ -564,7 +564,7 @@ def test_info_with_info_path(tmpdir, config_info): def test_info_without_info(config_without_info): cz = CustomizeCommitsCz(config_without_info) - assert cz.info() is None + assert cz.info() == "" def test_commit_parser(config): From c8af618ba97b6cc42b797d865acee91f02e0e25f Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 5 Apr 2024 23:36:23 +0800 Subject: [PATCH 327/598] refactor(cli): replace magic number 0 with ExitCode.EXPECTED_EXIT --- commitizen/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index e911b6da58..df082467f6 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -547,7 +547,7 @@ def commitizen_excepthook( original_excepthook(type, value, traceback) exit_code = value.exit_code if exit_code in no_raise: - exit_code = 0 + exit_code = ExitCode.EXPECTED_EXIT sys.exit(exit_code) else: original_excepthook(type, value, traceback) From 82db67dab1f18a9e257d5d533a4e1dbbfd6a9e6d Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 5 Apr 2024 23:53:48 +0800 Subject: [PATCH 328/598] style(check): fix mypy issues --- commitizen/commands/check.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index 13b8555b6d..e22155cf78 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -54,7 +54,7 @@ def _valid_command_argument(self): for arg in (self.commit_msg_file, self.commit_msg, self.rev_range) ) if num_exclusive_args_provided == 0 and not sys.stdin.isatty(): - self.commit_msg: str | None = sys.stdin.read() + self.commit_msg = sys.stdin.read() elif num_exclusive_args_provided != 1: raise InvalidCommandArgumentError( "Only one of --rev-range, --message, and --commit-msg-file is permitted by check command! " @@ -107,7 +107,9 @@ def _get_commits(self): return [git.GitCommit(rev="", title="", body=msg)] # Get commit messages from git log (--rev-range) - return git.get_commits(end=self.rev_range) + if self.rev_range: + return git.get_commits(end=self.rev_range) + return git.get_commits() @staticmethod def _filter_comments(msg: str) -> str: From 1806fe8a288048a1a2cb9c764ecf9de530d20b10 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sun, 10 Nov 2024 11:05:42 +0800 Subject: [PATCH 329/598] style(mypy): rewrite import to avoid unnecessary type ignore --- commitizen/cz/customize/customize.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index b7f49f28db..d53ae29f1b 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -1,9 +1,14 @@ from __future__ import annotations -try: +from typing import TYPE_CHECKING + +if TYPE_CHECKING: from jinja2 import Template -except ImportError: - from string import Template # type: ignore +else: + try: + from jinja2 import Template + except ImportError: + from string import Template from commitizen import defaults From 665aa59a2794b47de0cae6fe51886d6366268194 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 10 Nov 2024 03:22:52 +0000 Subject: [PATCH 330/598] =?UTF-8?q?bump:=20version=203.30.0=20=E2=86=92=20?= =?UTF-8?q?3.30.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 8 ++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a83ba0dcf6..c53fb361ec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v3.30.0 # automatically updated by Commitizen + rev: v3.30.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index b93413fd4e..3bbc280c46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v3.30.1 (2024-11-10) + +### Refactor + +- **cli**: replace magic number 0 with ExitCode.EXPECTED_EXIT +- **defaults**: disallow style as None +- **cz_customize**: return empty string for info, example, schema and schema_pattern if not provided + ## v3.30.0 (2024-10-23) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 1df56e3df4..677d3b117e 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.30.0" +__version__ = "3.30.1" diff --git a/pyproject.toml b/pyproject.toml index c4230d8edf..66d17eb3c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.30.0" +version = "3.30.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.30.0" +version = "3.30.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From e75b83767e2c7373793c1ae503d55dade8daee26 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sun, 10 Nov 2024 11:16:03 +0800 Subject: [PATCH 331/598] build(pre-commit): migrate pre-commit config When running `pre-commit run --all-files`, the following error was encountered. ``` [WARNING] hook id `commitizen-branch` uses deprecated stage names (push) which will be removed in a future version. run: `pre-commit migrate-config` to automatically fix this. [WARNING] hook id `linter and test` uses deprecated stage names (push) which will be removed in a future version. run: `pre-commit migrate-config` to automatically fix this. [WARNING] top-level `default_stages` uses deprecated stage names (commit, push) which will be removed in a future version. run: `pre-commit migrate-config` to automatically fix this. ``` This commit only only migrates the pre-commit config to the latest version. --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c53fb361ec..195d92096d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,8 +4,8 @@ default_install_hook_types: - pre-push default_stages: - - commit - - push + - pre-commit + - pre-push repos: - repo: meta @@ -55,7 +55,7 @@ repos: - id: commitizen-branch stages: - post-commit - - push + - pre-push - repo: local hooks: @@ -70,6 +70,6 @@ repos: name: linter and test language: system pass_filenames: false - stages: [ push ] + stages: [ pre-push ] entry: ./scripts/test types: [ python ] From f41a88e6562952caa915f4c6246ff34acb8018bd Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sun, 10 Nov 2024 11:25:47 +0800 Subject: [PATCH 332/598] ci(github-actions): use 3.13 instead of 3.13-dev as Python 3.13 has already been released --- .github/workflows/pythonpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index f0a517686f..24728e45dd 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -6,7 +6,7 @@ jobs: python-check: strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13-dev"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] platform: [ubuntu-20.04, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: From e4cab6cb598cba8418a60fbc310129ce81731c47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 01:53:21 +0000 Subject: [PATCH 333/598] build(deps): bump packaging from 24.1 to 24.2 Bumps [packaging](https://github.com/pypa/packaging) from 24.1 to 24.2. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/24.1...24.2) --- updated-dependencies: - dependency-name: packaging dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5da51c321a..9c849bb9fb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -887,13 +887,13 @@ setuptools = "*" [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] From 4d6f610fcf1a3a41864c333f215e8631a0cf7f1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 01:52:54 +0000 Subject: [PATCH 334/598] build(deps-dev): bump ruff from 0.7.2 to 0.7.3 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.2 to 0.7.3. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.7.2...0.7.3) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9c849bb9fb..42dabc2e01 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1450,29 +1450,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.7.2" +version = "0.7.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.2-py3-none-linux_armv6l.whl", hash = "sha256:b73f873b5f52092e63ed540adefc3c36f1f803790ecf2590e1df8bf0a9f72cb8"}, - {file = "ruff-0.7.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5b813ef26db1015953daf476202585512afd6a6862a02cde63f3bafb53d0b2d4"}, - {file = "ruff-0.7.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:853277dbd9675810c6826dad7a428d52a11760744508340e66bf46f8be9701d9"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21aae53ab1490a52bf4e3bf520c10ce120987b047c494cacf4edad0ba0888da2"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccc7e0fc6e0cb3168443eeadb6445285abaae75142ee22b2b72c27d790ab60ba"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd77877a4e43b3a98e5ef4715ba3862105e299af0c48942cc6d51ba3d97dc859"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e00163fb897d35523c70d71a46fbaa43bf7bf9af0f4534c53ea5b96b2e03397b"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3c54b538633482dc342e9b634d91168fe8cc56b30a4b4f99287f4e339103e88"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b792468e9804a204be221b14257566669d1db5c00d6bb335996e5cd7004ba80"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dba53ed84ac19ae4bfb4ea4bf0172550a2285fa27fbb13e3746f04c80f7fa088"}, - {file = "ruff-0.7.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b19fafe261bf741bca2764c14cbb4ee1819b67adb63ebc2db6401dcd652e3748"}, - {file = "ruff-0.7.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28bd8220f4d8f79d590db9e2f6a0674f75ddbc3847277dd44ac1f8d30684b828"}, - {file = "ruff-0.7.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9fd67094e77efbea932e62b5d2483006154794040abb3a5072e659096415ae1e"}, - {file = "ruff-0.7.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:576305393998b7bd6c46018f8104ea3a9cb3fa7908c21d8580e3274a3b04b691"}, - {file = "ruff-0.7.2-py3-none-win32.whl", hash = "sha256:fa993cfc9f0ff11187e82de874dfc3611df80852540331bc85c75809c93253a8"}, - {file = "ruff-0.7.2-py3-none-win_amd64.whl", hash = "sha256:dd8800cbe0254e06b8fec585e97554047fb82c894973f7ff18558eee33d1cb88"}, - {file = "ruff-0.7.2-py3-none-win_arm64.whl", hash = "sha256:bb8368cd45bba3f57bb29cbb8d64b4a33f8415d0149d2655c5c8539452ce7760"}, - {file = "ruff-0.7.2.tar.gz", hash = "sha256:2b14e77293380e475b4e3a7a368e14549288ed2931fce259a6f99978669e844f"}, + {file = "ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344"}, + {file = "ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0"}, + {file = "ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2"}, + {file = "ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d"}, + {file = "ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2"}, + {file = "ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2"}, + {file = "ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16"}, + {file = "ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc"}, + {file = "ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088"}, + {file = "ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c"}, + {file = "ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313"}, ] [[package]] From d017869164ea746ffab774c2b706602e61c3fb25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 01:22:30 +0000 Subject: [PATCH 335/598] ci(deps): bump codecov/codecov-action from 4 to 5 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4...v5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/pythonpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 24728e45dd..3a7907fa5b 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -30,7 +30,7 @@ jobs: shell: bash - name: Upload coverage to Codecov if: runner.os == 'Linux' - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./coverage.xml From 26be522194cc1710f31f328a62dbf320c27c680a Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Tue, 13 Aug 2024 12:04:02 +0200 Subject: [PATCH 336/598] fix(commit): resolve 'always_signoff' configuration and '-s' CLI issues If 'always_signoff' is enabled in configurations, or '-s' is used alone on the CLI, the following errors arise due to 'git commit' argument failures : > signoff mechanic is deprecated, please use `cz commit -- -s` instead. > fatal: /tmp/...: '/tmp/... is outside repository at '...' Signed-off-by: Adrian DC --- commitizen/commands/commit.py | 6 +++--- tests/commands/test_commit_command.py | 29 +++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index c955d02a51..1c7278ddfa 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -138,13 +138,13 @@ def __call__(self): self.arguments.get("signoff") or self.config.settings["always_signoff"] ) + extra_args = self.arguments.get("extra_cli_args", "") + if signoff: out.warn( "signoff mechanic is deprecated, please use `cz commit -- -s` instead." ) - extra_args = self.arguments.get("extra_cli_args", "--") + " -s" - else: - extra_args = self.arguments.get("extra_cli_args", "") + extra_args = f"{extra_args} -s".strip() c = git.commit(m, args=extra_args) diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 91a75e0970..85959abe33 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -260,7 +260,7 @@ def test_commit_command_with_signoff_option(config, mocker: MockFixture): commands.Commit(config, {"signoff": True})() - commit_mock.assert_called_once_with(ANY, args="-- -s") + commit_mock.assert_called_once_with(ANY, args="-s") success_mock.assert_called_once() @@ -283,7 +283,32 @@ def test_commit_command_with_always_signoff_enabled(config, mocker: MockFixture) config.settings["always_signoff"] = True commands.Commit(config, {})() - commit_mock.assert_called_once_with(ANY, args="-- -s") + commit_mock.assert_called_once_with(ANY, args="-s") + success_mock.assert_called_once() + + +@pytest.mark.usefixtures("staging_is_clean") +def test_commit_command_with_gpgsign_and_always_signoff_enabled( + config, mocker: MockFixture +): + prompt_mock = mocker.patch("questionary.prompt") + prompt_mock.return_value = { + "prefix": "feat", + "subject": "user created", + "scope": "", + "is_breaking_change": False, + "body": "", + "footer": "", + } + + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) + success_mock = mocker.patch("commitizen.out.success") + + config.settings["always_signoff"] = True + commands.Commit(config, {"extra_cli_args": "-S"})() + + commit_mock.assert_called_once_with(ANY, args="-S -s") success_mock.assert_called_once() From 18e4928bdcfc156e9f1e39291c9b1faaab8d7f71 Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Tue, 13 Aug 2024 12:07:48 +0200 Subject: [PATCH 337/598] fix(commit): avoid warnings with 'always_signoff' configuration Signed-off-by: Adrian DC --- commitizen/commands/commit.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 1c7278ddfa..9b13a020b6 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -134,9 +134,8 @@ def __call__(self): if dry_run: raise DryRunExit() - signoff: bool = ( - self.arguments.get("signoff") or self.config.settings["always_signoff"] - ) + always_signoff: bool = self.config.settings["always_signoff"] + signoff: bool = self.arguments.get("signoff") extra_args = self.arguments.get("extra_cli_args", "") @@ -144,6 +143,8 @@ def __call__(self): out.warn( "signoff mechanic is deprecated, please use `cz commit -- -s` instead." ) + + if always_signoff or signoff: extra_args = f"{extra_args} -s".strip() c = git.commit(m, args=extra_args) From 02dd9d0557deab04d911723acb16e3ca929060cb Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Fri, 23 Aug 2024 00:55:16 +0200 Subject: [PATCH 338/598] docs(gettings_started): migrate to 'cz commmit -- -s' syntaxes Signed-off-by: Adrian DC --- docs/getting_started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 81da513e0b..378b819192 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -51,13 +51,13 @@ cz c Run in the terminal ```bash -cz commit --signoff +cz commit -- --signoff ``` or the shortcut ```bash -cz commit -s +cz commit -- -s ``` ### Get project version From 9aa307688ec99098c60dbf2b2d5eaad1b6ae0ac7 Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Fri, 23 Aug 2024 01:03:23 +0200 Subject: [PATCH 339/598] feat(commitizen): document '--' double dash in '--help' Signed-off-by: Adrian DC --- commitizen/cli.py | 6 ++++++ ...ommit_command_shows_description_when_use_help_option.txt | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index df082467f6..1e0b1c6276 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -168,6 +168,12 @@ def __call__( "default": 0, "help": "length limit of the commit message; 0 for no limit", }, + { + "name": ["--"], + "action": "store_true", + "dest": "double_dash", + "help": "Positional arguments separator (recommended)", + }, ], }, { diff --git a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt index 955b3d8fd7..dd1f53f3da 100644 --- a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt @@ -1,6 +1,6 @@ usage: cz commit [-h] [--retry] [--no-retry] [--dry-run] [--write-message-to-file FILE_PATH] [-s] [-a] [-e] - [-l MESSAGE_LENGTH_LIMIT] + [-l MESSAGE_LENGTH_LIMIT] [--] create new commit @@ -19,3 +19,4 @@ options: -e, --edit edit the commit message before committing -l, --message-length-limit MESSAGE_LENGTH_LIMIT length limit of the commit message; 0 for no limit + -- Positional arguments separator (recommended) From 9c891d6a2bc35372c5588e5ba2cbec6404959a3d Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Sat, 17 Aug 2024 00:25:55 +0200 Subject: [PATCH 340/598] test(conftest): disable 'safe.directory' Git config for container bound sources Details: The git sources folder ownership may be detected as dubious if running in a container with sources mounted to work on fixes and tests, breaking 'test_find_git_project_root' and 'test_get_commits_with_signature' > commitizen.exceptions.GitCommandError: fatal: detected dubious ownership in repository at '...' --- Signed-off-by: Adrian DC --- tests/conftest.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index cc306ac6d4..95f3df3b20 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -35,12 +35,19 @@ def git_sandbox(monkeypatch: pytest.MonkeyPatch, tmp_path: Path): gitconfig = tmp_path / ".git" / "config" if not gitconfig.parent.exists(): gitconfig.parent.mkdir() + monkeypatch.setenv("GIT_CONFIG_GLOBAL", str(gitconfig)) + r = cmd.run(f"git config --file {gitconfig} user.name {SIGNER}") assert r.return_code == 0, r.err r = cmd.run(f"git config --file {gitconfig} user.email {SIGNER_MAIL}") assert r.return_code == 0, r.err - cmd.run("git config --global init.defaultBranch master") + + r = cmd.run(f"git config --file {gitconfig} safe.directory '*'") + assert r.return_code == 0, r.err + + r = cmd.run("git config --global init.defaultBranch master") + assert r.return_code == 0, r.err @pytest.fixture From d3f092d98dc7585ce9cb3295bafb942ca5be1886 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 16 Nov 2024 07:59:08 +0000 Subject: [PATCH 341/598] =?UTF-8?q?bump:=20version=203.30.1=20=E2=86=92=20?= =?UTF-8?q?3.31.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 11 +++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 195d92096d..7765ffe359 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v3.30.1 # automatically updated by Commitizen + rev: v3.31.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bbc280c46..d728143c42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## v3.31.0 (2024-11-16) + +### Feat + +- **commitizen**: document '--' double dash in '--help' + +### Fix + +- **commit**: avoid warnings with 'always_signoff' configuration +- **commit**: resolve 'always_signoff' configuration and '-s' CLI issues + ## v3.30.1 (2024-11-10) ### Refactor diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 677d3b117e..0cba0fb82a 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.30.1" +__version__ = "3.31.0" diff --git a/pyproject.toml b/pyproject.toml index 66d17eb3c9..15943c93de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.30.1" +version = "3.31.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.30.1" +version = "3.31.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From a9d35d161323713d6e2f44f07c907659b663319b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 16 Nov 2024 07:59:44 +0000 Subject: [PATCH 342/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz_commit___help.svg | 116 +++++++++++----------- 1 file changed, 60 insertions(+), 56 deletions(-) diff --git a/docs/images/cli_help/cz_commit___help.svg b/docs/images/cli_help/cz_commit___help.svg index 452e419908..0346c40588 100644 --- a/docs/images/cli_help/cz_commit___help.svg +++ b/docs/images/cli_help/cz_commit___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - - $ cz commit --help -usage: cz commit [-h][--retry][--no-retry][--dry-run] -[--write-message-to-file FILE_PATH][-s][-a][-e] -[-l MESSAGE_LENGTH_LIMIT] - -create new commit - -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. -  -e, --edit            edit the commit message before committing -  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit - + + $ cz commit --help +usage: cz commit [-h][--retry][--no-retry][--dry-run] +[--write-message-to-file FILE_PATH][-s][-a][-e] +[-l MESSAGE_LENGTH_LIMIT][--] + +create new commit + +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. +  -e, --edit            edit the commit message before committing +  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit +  --                    Positional arguments separator (recommended) + From f63a4acc931e9441a8ce11f4eba29044988cc2c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 01:08:31 +0000 Subject: [PATCH 343/598] build(deps-dev): bump ruff from 0.7.3 to 0.7.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.3 to 0.7.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.7.3...0.7.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 42dabc2e01..44e51dba5b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1450,29 +1450,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.7.3" +version = "0.7.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344"}, - {file = "ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0"}, - {file = "ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16"}, - {file = "ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc"}, - {file = "ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088"}, - {file = "ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c"}, - {file = "ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313"}, + {file = "ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478"}, + {file = "ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63"}, + {file = "ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a"}, + {file = "ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac"}, + {file = "ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6"}, + {file = "ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f"}, + {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"}, ] [[package]] From 58a0acb5fcccaaf83a8525b91124cd2160090bc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 01:08:49 +0000 Subject: [PATCH 344/598] build(deps-dev): bump deprecated from 1.2.14 to 1.2.15 Bumps [deprecated](https://github.com/laurent-laporte-pro/deprecated) from 1.2.14 to 1.2.15. - [Release notes](https://github.com/laurent-laporte-pro/deprecated/releases) - [Changelog](https://github.com/laurent-laporte-pro/deprecated/blob/master/CHANGELOG.rst) - [Commits](https://github.com/laurent-laporte-pro/deprecated/compare/v1.2.14...v1.2.15) --- updated-dependencies: - dependency-name: deprecated dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 44e51dba5b..0a0655707f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -323,20 +323,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "distlib" From 3e21ac576e76cd45103f3dcbcde216a9394a6247 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 01:09:08 +0000 Subject: [PATCH 345/598] build(deps-dev): bump types-deprecated Bumps [types-deprecated](https://github.com/python/typeshed) from 1.2.9.20240311 to 1.2.15.20241117. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-deprecated dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0a0655707f..63a14ff2bf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1573,13 +1573,13 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "types-deprecated" -version = "1.2.9.20240311" +version = "1.2.15.20241117" description = "Typing stubs for Deprecated" optional = false python-versions = ">=3.8" files = [ - {file = "types-Deprecated-1.2.9.20240311.tar.gz", hash = "sha256:0680e89989a8142707de8103f15d182445a533c1047fd9b7e8c5459101e9b90a"}, - {file = "types_Deprecated-1.2.9.20240311-py3-none-any.whl", hash = "sha256:d7793aaf32ff8f7e49a8ac781de4872248e0694c4b75a7a8a186c51167463f9d"}, + {file = "types-Deprecated-1.2.15.20241117.tar.gz", hash = "sha256:924002c8b7fddec51ba4949788a702411a2e3636cd9b2a33abd8ee119701d77e"}, + {file = "types_Deprecated-1.2.15.20241117-py3-none-any.whl", hash = "sha256:a0cc5e39f769fc54089fd8e005416b55d74aa03f6964d2ed1a0b0b2e28751884"}, ] [[package]] From 1c44c753e12569209c7fc528fa93c865aae557ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 01:41:52 +0000 Subject: [PATCH 346/598] build(deps-dev): bump mkdocs-material from 9.5.44 to 9.5.45 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.44 to 9.5.45. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.44...9.5.45) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 63a14ff2bf..0863fa0b7e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -769,13 +769,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.44" +version = "9.5.45" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.44-py3-none-any.whl", hash = "sha256:47015f9c167d58a5ff5e682da37441fc4d66a1c79334bfc08d774763cacf69ca"}, - {file = "mkdocs_material-9.5.44.tar.gz", hash = "sha256:f3a6c968e524166b3f3ed1fb97d3ed3e0091183b0545cedf7156a2a6804c56c0"}, + {file = "mkdocs_material-9.5.45-py3-none-any.whl", hash = "sha256:a9be237cfd0be14be75f40f1726d83aa3a81ce44808dc3594d47a7a592f44547"}, + {file = "mkdocs_material-9.5.45.tar.gz", hash = "sha256:286489cf0beca4a129d91d59d6417419c63bceed1ce5cd0ec1fc7e1ebffb8189"}, ] [package.dependencies] From 64cb9b6ce76a248bae662eda6efe3c254af0f044 Mon Sep 17 00:00:00 2001 From: "Axel H." Date: Tue, 26 Nov 2024 01:00:20 +0100 Subject: [PATCH 347/598] build(python)!: Drop support for Python 3.8 (EOL) and expose support for 3.13 --- .github/workflows/pythonpackage.yml | 2 +- docs/README.md | 2 +- docs/tutorials/gitlab_ci.md | 2 +- poetry.lock | 895 +++++++++++++--------------- pyproject.toml | 6 +- 5 files changed, 435 insertions(+), 472 deletions(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 3a7907fa5b..4f99a595c7 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -6,7 +6,7 @@ jobs: python-check: strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] platform: [ubuntu-20.04, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: diff --git a/docs/README.md b/docs/README.md index 9a071d5676..128602dfb3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,7 +41,7 @@ descriptive commits. ## Requirements -[Python](https://www.python.org/downloads/) `3.8+` +[Python](https://www.python.org/downloads/) `3.9+` [Git][gitscm] `1.8.5.2+` diff --git a/docs/tutorials/gitlab_ci.md b/docs/tutorials/gitlab_ci.md index d29bf994bd..85abb3fe6d 100644 --- a/docs/tutorials/gitlab_ci.md +++ b/docs/tutorials/gitlab_ci.md @@ -74,7 +74,7 @@ test: auto-bump: stage: auto-bump - image: python:3.8 + image: python:3.9 before_script: - "which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )" - eval `ssh-agent -s` diff --git a/poetry.lock b/poetry.lock index 0863fa0b7e..ad3607415b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,15 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "appnope" -version = "0.1.4" -description = "Disable App Nap on macOS >= 10.9" -optional = false -python-versions = ">=3.6" -files = [ - {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, - {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, -] +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "argcomplete" @@ -45,41 +34,27 @@ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "babel" -version = "2.15.0" +version = "2.16.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" files = [ - {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, - {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} - [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -optional = false -python-versions = "*" -files = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] - [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -234,63 +209,73 @@ files = [ [[package]] name = "coverage" -version = "7.5.1" +version = "7.6.8" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.8" -files = [ - {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"}, - {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"}, - {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"}, - {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"}, - {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"}, - {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"}, - {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"}, - {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"}, - {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"}, - {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"}, - {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"}, - {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"}, - {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"}, - {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, +python-versions = ">=3.9" +files = [ + {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed"}, + {file = "coverage-7.6.8-cp310-cp310-win32.whl", hash = "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e"}, + {file = "coverage-7.6.8-cp310-cp310-win_amd64.whl", hash = "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0"}, + {file = "coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801"}, + {file = "coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443"}, + {file = "coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad"}, + {file = "coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b"}, + {file = "coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146"}, + {file = "coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b"}, + {file = "coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71"}, + {file = "coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ac47fa29d8d41059ea3df65bd3ade92f97ee4910ed638e87075b8e8ce69599e"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:24eda3a24a38157eee639ca9afe45eefa8d2420d49468819ac5f88b10de84f4c"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c81ed2820b9023a9a90717020315e63b17b18c274a332e3b6437d7ff70abe0"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd55f8fc8fa494958772a2a7302b0354ab16e0b9272b3c3d83cdb5bec5bd1779"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f39e2f3530ed1626c66e7493be7a8423b023ca852aacdc91fb30162c350d2a92"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:716a78a342679cd1177bc8c2fe957e0ab91405bd43a17094324845200b2fddf4"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177f01eeaa3aee4a5ffb0d1439c5952b53d5010f86e9d2667963e632e30082cc"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:912e95017ff51dc3d7b6e2be158dedc889d9a5cc3382445589ce554f1a34c0ea"}, + {file = "coverage-7.6.8-cp39-cp39-win32.whl", hash = "sha256:4db3ed6a907b555e57cc2e6f14dc3a4c2458cdad8919e40b5357ab9b6db6c43e"}, + {file = "coverage-7.6.8-cp39-cp39-win_amd64.whl", hash = "sha256:428ac484592f780e8cd7b6b14eb568f7c85460c92e2a37cb0c0e5186e1a0d076"}, + {file = "coverage-7.6.8-pp39.pp310-none-any.whl", hash = "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce"}, + {file = "coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc"}, ] [package.dependencies] @@ -340,24 +325,24 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", " [[package]] name = "distlib" -version = "0.3.8" +version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, - {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, + {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, + {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, ] [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -379,13 +364,13 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "executing" -version = "2.0.1" +version = "2.1.0" description = "Get the currently executing AST node of a frame, and other information" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, - {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, + {file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"}, + {file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"}, ] [package.extras] @@ -393,19 +378,19 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "filelock" -version = "3.14.0" +version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"}, - {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"}, + {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, + {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] -typing = ["typing-extensions (>=4.8)"] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] +typing = ["typing-extensions (>=4.12.2)"] [[package]] name = "freezegun" @@ -440,13 +425,13 @@ dev = ["flake8", "markdown", "twine", "wheel"] [[package]] name = "identify" -version = "2.5.36" +version = "2.6.3" description = "File identification library for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, - {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, + {file = "identify-2.6.3-py2.py3-none-any.whl", hash = "sha256:9edba65473324c2ea9684b1f944fe3191db3345e50b6d04571d10ed164f8d7bd"}, + {file = "identify-2.6.3.tar.gz", hash = "sha256:62f5dae9b5fef52c84cc188514e9ea4f3f636b1d8799ab5ebc475471f9e47a02"}, ] [package.extras] @@ -454,15 +439,18 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.7" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "importlib-metadata" version = "8.5.0" @@ -499,24 +487,22 @@ files = [ [[package]] name = "ipython" -version = "8.12.3" +version = "8.18.0" description = "IPython: Productive Interactive Computing" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, - {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, + {file = "ipython-8.18.0-py3-none-any.whl", hash = "sha256:d538a7a98ad9b7e018926447a5f35856113a85d08fd68a165d7871ab5175f6e0"}, + {file = "ipython-8.18.0.tar.gz", hash = "sha256:4feb61210160f75e229ce932dbf8b719bff37af123c0b985fd038b14233daa16"}, ] [package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" pygments = ">=2.4.0" stack-data = "*" @@ -524,36 +510,36 @@ traitlets = ">=5" typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "jedi" -version = "0.19.1" +version = "0.19.2" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" files = [ - {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, - {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, + {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, + {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, ] [package.dependencies] -parso = ">=0.8.3,<0.9.0" +parso = ">=0.8.4,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] [[package]] name = "jinja2" @@ -574,13 +560,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "markdown" -version = "3.6" +version = "3.7" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, - {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, + {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, + {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, ] [package.dependencies] @@ -616,71 +602,72 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] @@ -769,13 +756,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.45" +version = "9.5.46" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.45-py3-none-any.whl", hash = "sha256:a9be237cfd0be14be75f40f1726d83aa3a81ce44808dc3594d47a7a592f44547"}, - {file = "mkdocs_material-9.5.45.tar.gz", hash = "sha256:286489cf0beca4a129d91d59d6417419c63bceed1ce5cd0ec1fc7e1ebffb8189"}, + {file = "mkdocs_material-9.5.46-py3-none-any.whl", hash = "sha256:98f0a2039c62e551a68aad0791a8d41324ff90c03a6e6cea381a384b84908b83"}, + {file = "mkdocs_material-9.5.46.tar.gz", hash = "sha256:ae2043f4238e572f9a40e0b577f50400d6fc31e2fef8ea141800aebf3bd273d7"}, ] [package.dependencies] @@ -873,18 +860,15 @@ files = [ [[package]] name = "nodeenv" -version = "1.8.0" +version = "1.9.1" description = "Node.js virtual environment builder" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, - {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] -[package.dependencies] -setuptools = "*" - [[package]] name = "packaging" version = "24.2" @@ -898,14 +882,19 @@ files = [ [[package]] name = "paginate" -version = "0.5.6" +version = "0.5.7" description = "Divides large result sets into pages for easier browsing" optional = false python-versions = "*" files = [ - {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, + {file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"}, + {file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"}, ] +[package.extras] +dev = ["pytest", "tox"] +lint = ["black"] + [[package]] name = "parso" version = "0.8.4" @@ -946,32 +935,21 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -optional = false -python-versions = "*" -files = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] - [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -990,13 +968,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.5.0" +version = "3.8.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, - {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, + {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, + {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, ] [package.dependencies] @@ -1033,13 +1011,13 @@ files = [ [[package]] name = "pure-eval" -version = "0.2.2" +version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = false python-versions = "*" files = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, + {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, + {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, ] [package.extras] @@ -1061,13 +1039,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pymdown-extensions" -version = "10.8.1" +version = "10.12" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"}, - {file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"}, + {file = "pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77"}, + {file = "pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7"}, ] [package.dependencies] @@ -1219,17 +1197,6 @@ files = [ [package.dependencies] six = ">=1.5" -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - [[package]] name = "pyyaml" version = "6.0.2" @@ -1322,101 +1289,116 @@ prompt_toolkit = ">=2.0,<=3.0.36" [[package]] name = "regex" -version = "2024.5.15" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a81e3cfbae20378d75185171587cbf756015ccb14840702944f014e0d93ea09f"}, - {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b59138b219ffa8979013be7bc85bb60c6f7b7575df3d56dc1e403a438c7a3f6"}, - {file = "regex-2024.5.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0bd000c6e266927cb7a1bc39d55be95c4b4f65c5be53e659537537e019232b1"}, - {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eaa7ddaf517aa095fa8da0b5015c44d03da83f5bd49c87961e3c997daed0de7"}, - {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba68168daedb2c0bab7fd7e00ced5ba90aebf91024dea3c88ad5063c2a562cca"}, - {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e8d717bca3a6e2064fc3a08df5cbe366369f4b052dcd21b7416e6d71620dca1"}, - {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1337b7dbef9b2f71121cdbf1e97e40de33ff114801263b275aafd75303bd62b5"}, - {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9ebd0a36102fcad2f03696e8af4ae682793a5d30b46c647eaf280d6cfb32796"}, - {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9efa1a32ad3a3ea112224897cdaeb6aa00381627f567179c0314f7b65d354c62"}, - {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1595f2d10dff3d805e054ebdc41c124753631b6a471b976963c7b28543cf13b0"}, - {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b802512f3e1f480f41ab5f2cfc0e2f761f08a1f41092d6718868082fc0d27143"}, - {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a0981022dccabca811e8171f913de05720590c915b033b7e601f35ce4ea7019f"}, - {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:19068a6a79cf99a19ccefa44610491e9ca02c2be3305c7760d3831d38a467a6f"}, - {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1b5269484f6126eee5e687785e83c6b60aad7663dafe842b34691157e5083e53"}, - {file = "regex-2024.5.15-cp310-cp310-win32.whl", hash = "sha256:ada150c5adfa8fbcbf321c30c751dc67d2f12f15bd183ffe4ec7cde351d945b3"}, - {file = "regex-2024.5.15-cp310-cp310-win_amd64.whl", hash = "sha256:ac394ff680fc46b97487941f5e6ae49a9f30ea41c6c6804832063f14b2a5a145"}, - {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f5b1dff3ad008dccf18e652283f5e5339d70bf8ba7c98bf848ac33db10f7bc7a"}, - {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c6a2b494a76983df8e3d3feea9b9ffdd558b247e60b92f877f93a1ff43d26656"}, - {file = "regex-2024.5.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a32b96f15c8ab2e7d27655969a23895eb799de3665fa94349f3b2fbfd547236f"}, - {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10002e86e6068d9e1c91eae8295ef690f02f913c57db120b58fdd35a6bb1af35"}, - {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec54d5afa89c19c6dd8541a133be51ee1017a38b412b1321ccb8d6ddbeb4cf7d"}, - {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10e4ce0dca9ae7a66e6089bb29355d4432caed736acae36fef0fdd7879f0b0cb"}, - {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e507ff1e74373c4d3038195fdd2af30d297b4f0950eeda6f515ae3d84a1770f"}, - {file = "regex-2024.5.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1f059a4d795e646e1c37665b9d06062c62d0e8cc3c511fe01315973a6542e40"}, - {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0721931ad5fe0dda45d07f9820b90b2148ccdd8e45bb9e9b42a146cb4f695649"}, - {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:833616ddc75ad595dee848ad984d067f2f31be645d603e4d158bba656bbf516c"}, - {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:287eb7f54fc81546346207c533ad3c2c51a8d61075127d7f6d79aaf96cdee890"}, - {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:19dfb1c504781a136a80ecd1fff9f16dddf5bb43cec6871778c8a907a085bb3d"}, - {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:119af6e56dce35e8dfb5222573b50c89e5508d94d55713c75126b753f834de68"}, - {file = "regex-2024.5.15-cp311-cp311-win32.whl", hash = "sha256:1c1c174d6ec38d6c8a7504087358ce9213d4332f6293a94fbf5249992ba54efa"}, - {file = "regex-2024.5.15-cp311-cp311-win_amd64.whl", hash = "sha256:9e717956dcfd656f5055cc70996ee2cc82ac5149517fc8e1b60261b907740201"}, - {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:632b01153e5248c134007209b5c6348a544ce96c46005d8456de1d552455b014"}, - {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e64198f6b856d48192bf921421fdd8ad8eb35e179086e99e99f711957ffedd6e"}, - {file = "regex-2024.5.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68811ab14087b2f6e0fc0c2bae9ad689ea3584cad6917fc57be6a48bbd012c49"}, - {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ec0c2fea1e886a19c3bee0cd19d862b3aa75dcdfb42ebe8ed30708df64687a"}, - {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0c0c0003c10f54a591d220997dd27d953cd9ccc1a7294b40a4be5312be8797b"}, - {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2431b9e263af1953c55abbd3e2efca67ca80a3de8a0437cb58e2421f8184717a"}, - {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a605586358893b483976cffc1723fb0f83e526e8f14c6e6614e75919d9862cf"}, - {file = "regex-2024.5.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391d7f7f1e409d192dba8bcd42d3e4cf9e598f3979cdaed6ab11288da88cb9f2"}, - {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9ff11639a8d98969c863d4617595eb5425fd12f7c5ef6621a4b74b71ed8726d5"}, - {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4eee78a04e6c67e8391edd4dad3279828dd66ac4b79570ec998e2155d2e59fd5"}, - {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8fe45aa3f4aa57faabbc9cb46a93363edd6197cbc43523daea044e9ff2fea83e"}, - {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d0a3d8d6acf0c78a1fff0e210d224b821081330b8524e3e2bc5a68ef6ab5803d"}, - {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c486b4106066d502495b3025a0a7251bf37ea9540433940a23419461ab9f2a80"}, - {file = "regex-2024.5.15-cp312-cp312-win32.whl", hash = "sha256:c49e15eac7c149f3670b3e27f1f28a2c1ddeccd3a2812cba953e01be2ab9b5fe"}, - {file = "regex-2024.5.15-cp312-cp312-win_amd64.whl", hash = "sha256:673b5a6da4557b975c6c90198588181029c60793835ce02f497ea817ff647cb2"}, - {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:87e2a9c29e672fc65523fb47a90d429b70ef72b901b4e4b1bd42387caf0d6835"}, - {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3bea0ba8b73b71b37ac833a7f3fd53825924165da6a924aec78c13032f20850"}, - {file = "regex-2024.5.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bfc4f82cabe54f1e7f206fd3d30fda143f84a63fe7d64a81558d6e5f2e5aaba9"}, - {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5bb9425fe881d578aeca0b2b4b3d314ec88738706f66f219c194d67179337cb"}, - {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64c65783e96e563103d641760664125e91bd85d8e49566ee560ded4da0d3e704"}, - {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf2430df4148b08fb4324b848672514b1385ae3807651f3567871f130a728cc3"}, - {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5397de3219a8b08ae9540c48f602996aa6b0b65d5a61683e233af8605c42b0f2"}, - {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:455705d34b4154a80ead722f4f185b04c4237e8e8e33f265cd0798d0e44825fa"}, - {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2b6f1b3bb6f640c1a92be3bbfbcb18657b125b99ecf141fb3310b5282c7d4ed"}, - {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3ad070b823ca5890cab606c940522d05d3d22395d432f4aaaf9d5b1653e47ced"}, - {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5b5467acbfc153847d5adb21e21e29847bcb5870e65c94c9206d20eb4e99a384"}, - {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e6662686aeb633ad65be2a42b4cb00178b3fbf7b91878f9446075c404ada552f"}, - {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:2b4c884767504c0e2401babe8b5b7aea9148680d2e157fa28f01529d1f7fcf67"}, - {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3cd7874d57f13bf70078f1ff02b8b0aa48d5b9ed25fc48547516c6aba36f5741"}, - {file = "regex-2024.5.15-cp38-cp38-win32.whl", hash = "sha256:e4682f5ba31f475d58884045c1a97a860a007d44938c4c0895f41d64481edbc9"}, - {file = "regex-2024.5.15-cp38-cp38-win_amd64.whl", hash = "sha256:d99ceffa25ac45d150e30bd9ed14ec6039f2aad0ffa6bb87a5936f5782fc1569"}, - {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13cdaf31bed30a1e1c2453ef6015aa0983e1366fad2667657dbcac7b02f67133"}, - {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cac27dcaa821ca271855a32188aa61d12decb6fe45ffe3e722401fe61e323cd1"}, - {file = "regex-2024.5.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7dbe2467273b875ea2de38ded4eba86cbcbc9a1a6d0aa11dcf7bd2e67859c435"}, - {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f18a9a3513a99c4bef0e3efd4c4a5b11228b48aa80743be822b71e132ae4f5"}, - {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d347a741ea871c2e278fde6c48f85136c96b8659b632fb57a7d1ce1872547600"}, - {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1878b8301ed011704aea4c806a3cadbd76f84dece1ec09cc9e4dc934cfa5d4da"}, - {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4babf07ad476aaf7830d77000874d7611704a7fcf68c9c2ad151f5d94ae4bfc4"}, - {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35cb514e137cb3488bce23352af3e12fb0dbedd1ee6e60da053c69fb1b29cc6c"}, - {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cdd09d47c0b2efee9378679f8510ee6955d329424c659ab3c5e3a6edea696294"}, - {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:72d7a99cd6b8f958e85fc6ca5b37c4303294954eac1376535b03c2a43eb72629"}, - {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a094801d379ab20c2135529948cb84d417a2169b9bdceda2a36f5f10977ebc16"}, - {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c0c18345010870e58238790a6779a1219b4d97bd2e77e1140e8ee5d14df071aa"}, - {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:16093f563098448ff6b1fa68170e4acbef94e6b6a4e25e10eae8598bb1694b5d"}, - {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e38a7d4e8f633a33b4c7350fbd8bad3b70bf81439ac67ac38916c4a86b465456"}, - {file = "regex-2024.5.15-cp39-cp39-win32.whl", hash = "sha256:71a455a3c584a88f654b64feccc1e25876066c4f5ef26cd6dd711308aa538694"}, - {file = "regex-2024.5.15-cp39-cp39-win_amd64.whl", hash = "sha256:cab12877a9bdafde5500206d1020a584355a97884dfd388af3699e9137bf7388"}, - {file = "regex-2024.5.15.tar.gz", hash = "sha256:d3ee02d9e5f482cc8309134a91eeaacbdd2261ba111b0fef3748eeb4913e6a2c"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] name = "requests" -version = "2.32.1" +version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" files = [ - {file = "requests-2.32.1-py3-none-any.whl", hash = "sha256:21ac9465cdf8c1650fe1ecde8a71669a93d4e6f147550483a2967d08396a56a5"}, - {file = "requests-2.32.1.tar.gz", hash = "sha256:eb97e87e64c79e64e5b8ac75cee9dd1f97f49e289b083ee6be96268930725685"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -1475,21 +1457,6 @@ files = [ {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"}, ] -[[package]] -name = "setuptools" -version = "70.0.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, - {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] - [[package]] name = "six" version = "1.16.0" @@ -1522,13 +1489,13 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] [[package]] name = "termcolor" -version = "2.4.0" +version = "2.5.0" description = "ANSI color formatting for output in terminal" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"}, - {file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"}, + {file = "termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8"}, + {file = "termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f"}, ] [package.extras] @@ -1536,13 +1503,13 @@ tests = ["pytest", "pytest-cov"] [[package]] name = "tomli" -version = "2.0.1" +version = "2.1.0" description = "A lil' TOML parser" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, + {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, ] [[package]] @@ -1628,13 +1595,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.2" +version = "2.2.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, ] [package.extras] @@ -1645,13 +1612,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.26.2" +version = "20.27.1" description = "Virtual Python Environment builder" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "virtualenv-20.26.2-py3-none-any.whl", hash = "sha256:a624db5e94f01ad993d476b9ee5346fdf7b9de43ccaee0e0197012dc838a0e9b"}, - {file = "virtualenv-20.26.2.tar.gz", hash = "sha256:82bf0f4eebbb78d36ddaee0283d43fe5736b53880b8a8cdcd37390a07ac3741c"}, + {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, + {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, ] [package.dependencies] @@ -1665,40 +1632,41 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess [[package]] name = "watchdog" -version = "4.0.0" +version = "6.0.0" description = "Filesystem events monitoring" optional = false -python-versions = ">=3.8" -files = [ - {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, - {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, - {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, - {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, - {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, - {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, - {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, - {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, - {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, - {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, +python-versions = ">=3.9" +files = [ + {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c"}, + {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881"}, + {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11"}, + {file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa"}, + {file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2"}, + {file = "watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a"}, + {file = "watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680"}, + {file = "watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f"}, + {file = "watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282"}, ] [package.extras] @@ -1717,92 +1685,87 @@ files = [ [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] name = "zipp" -version = "3.20.2" +version = "3.21.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, - {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, + {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, + {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, ] [package.extras] @@ -1815,5 +1778,5 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" -python-versions = ">=3.8" -content-hash = "9f70911e2e4764b623fece710f5c545e7313fa9e5a03fdeec8266faf3c5b7c26" +python-versions = ">=3.9" +content-hash = "a26dd45789ef8d0cc79465fe620060d29bde139d45a70885a80c413dd668dc81" diff --git a/pyproject.toml b/pyproject.toml index 15943c93de..d4f1f55b5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,11 +25,11 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", ] packages = [ @@ -38,7 +38,7 @@ packages = [ ] [tool.poetry.dependencies] -python = ">=3.8" +python = ">=3.9" questionary = "^2.0" decli = "^0.6.0" colorama = "^0.4.1" @@ -48,7 +48,7 @@ tomlkit = ">=0.5.3,<1.0.0" jinja2 = ">=2.10.3" pyyaml = ">=3.08" argcomplete = ">=1.12.1,<3.6" -typing-extensions = { version = "^4.0.1", python = "<3.8" } +typing-extensions = { version = "^4.0.1", python = "<3.11" } charset-normalizer = ">=2.1.0,<4" # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility importlib_metadata = { version = ">=8.0.0,<9", python = "<3.10"} From 76efedd776e04c9604a1d54fef389a292cbf7768 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 26 Nov 2024 01:36:55 +0000 Subject: [PATCH 348/598] =?UTF-8?q?bump:=20version=203.31.0=20=E2=86=92=20?= =?UTF-8?q?4.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 2 ++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7765ffe359..52049e967f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v3.31.0 # automatically updated by Commitizen + rev: v4.0.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index d728143c42..c6556ab016 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## v4.0.0 (2024-11-26) + ## v3.31.0 (2024-11-16) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 0cba0fb82a..ce1305bf4e 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.31.0" +__version__ = "4.0.0" diff --git a/pyproject.toml b/pyproject.toml index d4f1f55b5b..b15581952e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.31.0" +version = "4.0.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.31.0" +version = "4.0.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 7e23626055328f00c3582cf78c6e64913e95621a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 01:27:09 +0000 Subject: [PATCH 349/598] build(deps-dev): bump ruff from 0.7.4 to 0.8.0 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.4 to 0.8.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.7.4...0.8.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 46 +++++++++++++++++++++++----------------------- pyproject.toml | 2 +- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/poetry.lock b/poetry.lock index ad3607415b..05909045e3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1432,29 +1432,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.7.4" +version = "0.8.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478"}, - {file = "ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63"}, - {file = "ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a"}, - {file = "ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac"}, - {file = "ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6"}, - {file = "ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f"}, - {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"}, + {file = "ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea"}, + {file = "ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b"}, + {file = "ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426"}, + {file = "ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468"}, + {file = "ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f"}, + {file = "ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6"}, + {file = "ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44"}, ] [[package]] @@ -1612,13 +1612,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.27.1" +version = "20.27.2" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, - {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, + {file = "virtualenv-20.27.2-py3-none-any.whl", hash = "sha256:a9ebd6adbf08c99583133b61e7491f8a4bc8d5fb34361abaa5ede3fff903a0f0"}, + {file = "virtualenv-20.27.2.tar.gz", hash = "sha256:99c89daeeaf15918880c73c99f41dc05eb39055e43231a4d76fc6b9fc2cf019d"}, ] [package.dependencies] @@ -1779,4 +1779,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9" -content-hash = "a26dd45789ef8d0cc79465fe620060d29bde139d45a70885a80c413dd668dc81" +content-hash = "7e04dd9aa4799765e49b74f26cd66a1d5a8cf334d9b3eabf35d89c4660d518c2" diff --git a/pyproject.toml b/pyproject.toml index b15581952e..2662b80040 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" # linter -ruff = ">=0.5.0,<0.8.0" +ruff = ">=0.5.0,<0.9.0" pre-commit = ">=2.18,<4.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" From bb2f8a79afc586f782f3728aa09665dcc509fbb3 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Tue, 26 Nov 2024 09:36:45 +0800 Subject: [PATCH 350/598] style: fix ruff warned style --- commitizen/changelog.py | 3 ++- commitizen/changelog_formats/restructuredtext.py | 4 ++-- commitizen/cli.py | 3 ++- commitizen/cz/__init__.py | 2 +- commitizen/cz/base.py | 3 ++- commitizen/defaults.py | 3 ++- commitizen/version_schemes.py | 3 +-- tests/conftest.py | 2 +- tests/providers/conftest.py | 2 +- 9 files changed, 14 insertions(+), 11 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 32a66c47eb..7f300354b6 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -29,9 +29,10 @@ import re from collections import OrderedDict, defaultdict +from collections.abc import Iterable from dataclasses import dataclass from datetime import date -from typing import TYPE_CHECKING, Iterable +from typing import TYPE_CHECKING from jinja2 import ( BaseLoader, diff --git a/commitizen/changelog_formats/restructuredtext.py b/commitizen/changelog_formats/restructuredtext.py index 09d032400c..8bcf9a4a4f 100644 --- a/commitizen/changelog_formats/restructuredtext.py +++ b/commitizen/changelog_formats/restructuredtext.py @@ -3,7 +3,7 @@ import re import sys from itertools import zip_longest -from typing import IO, TYPE_CHECKING, Any, Tuple, Union +from typing import IO, TYPE_CHECKING, Any, Union from commitizen.changelog import Metadata @@ -18,7 +18,7 @@ # Can't use `|` operator and native type because of https://bugs.python.org/issue42233 only fixed in 3.10 -TitleKind: TypeAlias = Union[str, Tuple[str, str]] +TitleKind: TypeAlias = Union[str, tuple[str, str]] class RestructuredText(BaseFormat): diff --git a/commitizen/cli.py b/commitizen/cli.py index 1e0b1c6276..2ee7d41eba 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -3,11 +3,12 @@ import argparse import logging import sys +from collections.abc import Sequence from copy import deepcopy from functools import partial from pathlib import Path from types import TracebackType -from typing import Any, Sequence +from typing import Any import argcomplete from decli import cli diff --git a/commitizen/cz/__init__.py b/commitizen/cz/__init__.py index 04603a9ec4..cb17fe32cd 100644 --- a/commitizen/cz/__init__.py +++ b/commitizen/cz/__init__.py @@ -4,7 +4,7 @@ import pkgutil import sys import warnings -from typing import Iterable +from collections.abc import Iterable if sys.version_info >= (3, 10): from importlib import metadata diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 70929e2f83..43455a74ca 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -1,7 +1,8 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod -from typing import Any, Callable, Iterable, Protocol +from collections.abc import Iterable +from typing import Any, Callable, Protocol from jinja2 import BaseLoader, PackageLoader from prompt_toolkit.styles import Style, merge_styles diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 996c243196..d776e38d7a 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -2,7 +2,8 @@ import pathlib from collections import OrderedDict -from typing import Any, Iterable, MutableMapping, TypedDict +from collections.abc import Iterable, MutableMapping +from typing import Any, TypedDict # Type Questions = Iterable[MutableMapping[str, Any]] diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 346287a065..554864e3bf 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -10,7 +10,6 @@ ClassVar, Literal, Protocol, - Type, cast, runtime_checkable, ) @@ -150,7 +149,7 @@ def bump( # With PEP 440 and SemVer semantic, Scheme is the type, Version is an instance Version: TypeAlias = VersionProtocol -VersionScheme: TypeAlias = Type[VersionProtocol] +VersionScheme: TypeAlias = type[VersionProtocol] class BaseVersion(_BaseVersion): diff --git a/tests/conftest.py b/tests/conftest.py index 95f3df3b20..1e6bc15f0c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,8 +3,8 @@ import os import re import tempfile +from collections.abc import Iterator from pathlib import Path -from typing import Iterator import pytest from pytest_mock import MockerFixture diff --git a/tests/providers/conftest.py b/tests/providers/conftest.py index b4432ca524..f73cdb72a5 100644 --- a/tests/providers/conftest.py +++ b/tests/providers/conftest.py @@ -1,8 +1,8 @@ from __future__ import annotations import os +from collections.abc import Iterator from pathlib import Path -from typing import Iterator import pytest From 42e639902a341d2db39c9fdd6dc2020240b2e7f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 01:54:32 +0000 Subject: [PATCH 351/598] build(deps-dev): bump pytest-cov from 5.0.0 to 6.0.0 Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 5.0.0 to 6.0.0. - [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-cov/compare/v5.0.0...v6.0.0) --- updated-dependencies: - dependency-name: pytest-cov dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- poetry.lock | 18 +++++++++--------- pyproject.toml | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index 05909045e3..fec1cca1c4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1079,17 +1079,17 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments [[package]] name = "pytest-cov" -version = "5.0.0" +version = "6.0.0" description = "Pytest plugin for measuring coverage." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, - {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, + {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, + {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, ] [package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} +coverage = {version = ">=7.5", extras = ["toml"]} pytest = ">=4.6" [package.extras] @@ -1612,13 +1612,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.27.2" +version = "20.27.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.27.2-py3-none-any.whl", hash = "sha256:a9ebd6adbf08c99583133b61e7491f8a4bc8d5fb34361abaa5ede3fff903a0f0"}, - {file = "virtualenv-20.27.2.tar.gz", hash = "sha256:99c89daeeaf15918880c73c99f41dc05eb39055e43231a4d76fc6b9fc2cf019d"}, + {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, + {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, ] [package.dependencies] @@ -1779,4 +1779,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9" -content-hash = "7e04dd9aa4799765e49b74f26cd66a1d5a8cf334d9b3eabf35d89c4660d518c2" +content-hash = "67d0ae972c7570988ffe085a48e959f140575f959535bc087e0ea57dc74d83c3" diff --git a/pyproject.toml b/pyproject.toml index 2662b80040..3153af36ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,7 +58,7 @@ importlib_metadata = { version = ">=8.0.0,<9", python = "<3.10"} ipython = "^8.0" # test pytest = ">=7.2,<9.0" -pytest-cov = ">=4,<6" +pytest-cov = ">=4,<7" pytest-mock = "^3.10" pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" From a6b84d101a202a8225d6c9824e6308021b0fb141 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 01:54:52 +0000 Subject: [PATCH 352/598] build(deps-dev): bump pre-commit from 3.8.0 to 4.0.1 Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.8.0 to 4.0.1. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v3.8.0...v4.0.1) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 +++--- pyproject.toml | 77 +++++++++++++++++++++++--------------------------- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/poetry.lock b/poetry.lock index fec1cca1c4..0f146aba25 100644 --- a/poetry.lock +++ b/poetry.lock @@ -968,13 +968,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.8.0" +version = "4.0.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" files = [ - {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, - {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, + {file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"}, + {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, ] [package.dependencies] @@ -1779,4 +1779,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9" -content-hash = "67d0ae972c7570988ffe085a48e959f140575f959535bc087e0ea57dc74d83c3" +content-hash = "36ac305c62f5139da82126a1b3bc71f86320af1abab5c473b3c0d21c81e214bd" diff --git a/pyproject.toml b/pyproject.toml index 3153af36ca..8737b86f28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,9 +2,9 @@ version = "4.0.0" tag_format = "v$version" version_files = [ - "pyproject.toml:version", - "commitizen/__version__.py", - ".pre-commit-config.yaml:rev:.+Commitizen", + "pyproject.toml:version", + "commitizen/__version__.py", + ".pre-commit-config.yaml:rev:.+Commitizen", ] [tool.poetry] @@ -32,10 +32,7 @@ classifiers = [ "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", ] -packages = [ - {include = "commitizen"}, - {include = "commitizen/py.typed"}, -] +packages = [{ include = "commitizen" }, { include = "commitizen/py.typed" }] [tool.poetry.dependencies] python = ">=3.9" @@ -51,7 +48,7 @@ argcomplete = ">=1.12.1,<3.6" typing-extensions = { version = "^4.0.1", python = "<3.11" } charset-normalizer = ">=2.1.0,<4" # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility -importlib_metadata = { version = ">=8.0.0,<9", python = "<3.10"} +importlib_metadata = { version = ">=8.0.0,<9", python = "<3.10" } [tool.poetry.group.dev.dependencies] # dev tool @@ -65,7 +62,7 @@ pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" # linter ruff = ">=0.5.0,<0.9.0" -pre-commit = ">=2.18,<4.0" +pre-commit = ">=2.18,<5.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" types-termcolor = "^0.1.1" @@ -108,33 +105,33 @@ semver = "commitizen.version_schemes:SemVer" semver2 = "commitizen.version_schemes:SemVer2" [tool.coverage] - [tool.coverage.report] - show_missing = true - exclude_lines = [ - # Have to re-enable the standard pragma - 'pragma: no cover', - - # Don't complain about missing debug-only code: - 'def __repr__', - 'if self\.debug', - - # Don't complain if tests don't hit defensive assertion code: - 'raise AssertionError', - 'raise NotImplementedError', - - # Don't complain if non-runnable code isn't run: - 'if 0:', - 'if __name__ == .__main__.:', - 'if TYPE_CHECKING:', - ] - omit = [ - 'env/*', - 'venv/*', - '.venv/*', - '*/virtualenv/*', - '*/virtualenvs/*', - '*/tests/*', - ] +[tool.coverage.report] +show_missing = true +exclude_lines = [ + # Have to re-enable the standard pragma + 'pragma: no cover', + + # Don't complain about missing debug-only code: + 'def __repr__', + 'if self\.debug', + + # Don't complain if tests don't hit defensive assertion code: + 'raise AssertionError', + 'raise NotImplementedError', + + # Don't complain if non-runnable code isn't run: + 'if 0:', + 'if __name__ == .__main__.:', + 'if TYPE_CHECKING:', +] +omit = [ + 'env/*', + 'venv/*', + '.venv/*', + '*/virtualenv/*', + '*/virtualenvs/*', + '*/tests/*', +] [build-system] requires = ["poetry_core>=1.0.0"] @@ -157,11 +154,7 @@ select = [ # isort "I", ] -ignore = [ - "E501", - "D1", - "D415" -] +ignore = ["E501", "D1", "D415"] [tool.ruff.lint.isort] known-first-party = ["commitizen", "tests"] @@ -179,7 +172,7 @@ warn_unused_ignores = true warn_unused_configs = true [[tool.mypy.overrides]] -module = "py.*" # Legacy pytest dependencies +module = "py.*" # Legacy pytest dependencies ignore_missing_imports = true [tool.codespell] From 69403dd9ccacc3e7bdce3a43d6e77a80ab41be41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 01:36:39 +0000 Subject: [PATCH 353/598] build(deps-dev): bump mkdocs-material from 9.5.46 to 9.5.47 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.46 to 9.5.47. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.46...9.5.47) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0f146aba25..116dfbaa3b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "argcomplete" @@ -756,13 +756,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.46" +version = "9.5.47" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.46-py3-none-any.whl", hash = "sha256:98f0a2039c62e551a68aad0791a8d41324ff90c03a6e6cea381a384b84908b83"}, - {file = "mkdocs_material-9.5.46.tar.gz", hash = "sha256:ae2043f4238e572f9a40e0b577f50400d6fc31e2fef8ea141800aebf3bd273d7"}, + {file = "mkdocs_material-9.5.47-py3-none-any.whl", hash = "sha256:53fb9c9624e7865da6ec807d116cd7be24b3cb36ab31b1d1d1a9af58c56009a2"}, + {file = "mkdocs_material-9.5.47.tar.gz", hash = "sha256:fc3b7a8e00ad896660bd3a5cc12ca0cb28bdc2bcbe2a946b5714c23ac91b0ede"}, ] [package.dependencies] From 6436b155b735c6f6f5a40ff99b4beee1eb0481b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 01:36:59 +0000 Subject: [PATCH 354/598] build(deps-dev): bump pytest from 8.3.3 to 8.3.4 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.3 to 8.3.4. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.3...8.3.4) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 116dfbaa3b..348b686cac 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1057,13 +1057,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] From 619575faf2724dc6f28214cc7d3264fc2e3717e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 01:37:29 +0000 Subject: [PATCH 355/598] build(deps-dev): bump ruff from 0.8.0 to 0.8.1 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.8.0 to 0.8.1. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.8.0...0.8.1) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 348b686cac..16ef1b4a9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1432,29 +1432,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.8.0" +version = "0.8.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea"}, - {file = "ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b"}, - {file = "ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c"}, - {file = "ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2"}, - {file = "ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70"}, - {file = "ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd"}, - {file = "ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426"}, - {file = "ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468"}, - {file = "ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f"}, - {file = "ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6"}, - {file = "ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44"}, + {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"}, + {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"}, + {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"}, + {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"}, + {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"}, + {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"}, + {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"}, ] [[package]] From 26152c5af043143e47a0574d3b59621e535e1952 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 01:43:14 +0000 Subject: [PATCH 356/598] build(deps-dev): bump ruff from 0.8.1 to 0.8.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.8.1 to 0.8.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.8.1...0.8.2) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 16ef1b4a9c..973f01720b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1432,29 +1432,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.8.1" +version = "0.8.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"}, - {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"}, - {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"}, - {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"}, - {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"}, - {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"}, - {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"}, - {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"}, - {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"}, - {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"}, - {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"}, + {file = "ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d"}, + {file = "ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5"}, + {file = "ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d"}, + {file = "ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0"}, + {file = "ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa"}, + {file = "ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f"}, + {file = "ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22"}, + {file = "ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1"}, + {file = "ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea"}, + {file = "ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8"}, + {file = "ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5"}, ] [[package]] From 636a0696ea1f76acff94eca16d945845907ee581 Mon Sep 17 00:00:00 2001 From: Adrian DC Date: Sun, 25 Aug 2024 03:12:42 +0200 Subject: [PATCH 357/598] feat(commit): allow '-- --allow-empty' to create empty commits Signed-off-by: Adrian DC --- commitizen/commands/commit.py | 8 +++-- tests/commands/test_commit_command.py | 49 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 9b13a020b6..abecb3b3ca 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -93,6 +93,10 @@ def manual_edit(self, message: str) -> str: return message def __call__(self): + extra_args: str = self.arguments.get("extra_cli_args", "") + + allow_empty: bool = "--allow-empty" in extra_args + dry_run: bool = self.arguments.get("dry_run") write_message_to_file: bool = self.arguments.get("write_message_to_file") manual_edit: bool = self.arguments.get("edit") @@ -101,7 +105,7 @@ def __call__(self): if is_all: c = git.add("-u") - if git.is_staging_clean() and not dry_run: + if git.is_staging_clean() and not (dry_run or allow_empty): raise NothingToCommitError("No files added to staging!") if write_message_to_file is not None and write_message_to_file.is_dir(): @@ -137,8 +141,6 @@ def __call__(self): always_signoff: bool = self.config.settings["always_signoff"] signoff: bool = self.arguments.get("signoff") - extra_args = self.arguments.get("extra_cli_args", "") - if signoff: out.warn( "signoff mechanic is deprecated, please use `cz commit -- -s` instead." diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 85959abe33..55751f6902 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -324,6 +324,55 @@ def test_commit_when_nothing_to_commit(config, mocker: MockFixture): assert "No files added to staging!" in str(excinfo.value) +@pytest.mark.usefixtures("staging_is_clean") +def test_commit_with_allow_empty(config, mocker: MockFixture): + prompt_mock = mocker.patch("questionary.prompt") + prompt_mock.return_value = { + "prefix": "feat", + "subject": "user created", + "scope": "", + "is_breaking_change": False, + "body": "closes #21", + "footer": "", + } + + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) + success_mock = mocker.patch("commitizen.out.success") + + commands.Commit(config, {"extra_cli_args": "--allow-empty"})() + + commit_mock.assert_called_with( + "feat: user created\n\ncloses #21", args="--allow-empty" + ) + success_mock.assert_called_once() + + +@pytest.mark.usefixtures("staging_is_clean") +def test_commit_with_signoff_and_allow_empty(config, mocker: MockFixture): + prompt_mock = mocker.patch("questionary.prompt") + prompt_mock.return_value = { + "prefix": "feat", + "subject": "user created", + "scope": "", + "is_breaking_change": False, + "body": "closes #21", + "footer": "", + } + + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command("success", "", b"", b"", 0) + success_mock = mocker.patch("commitizen.out.success") + + config.settings["always_signoff"] = True + commands.Commit(config, {"extra_cli_args": "--allow-empty"})() + + commit_mock.assert_called_with( + "feat: user created\n\ncloses #21", args="--allow-empty -s" + ) + success_mock.assert_called_once() + + @pytest.mark.usefixtures("staging_is_clean") def test_commit_when_customized_expected_raised(config, mocker: MockFixture, capsys): _err = ValueError() From 27499d727f5ceff802bda34bbda314644824ce06 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 6 Dec 2024 15:13:16 +0000 Subject: [PATCH 358/598] =?UTF-8?q?bump:=20version=204.0.0=20=E2=86=92=204?= =?UTF-8?q?.1.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 52049e967f..986b63f875 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.0.0 # automatically updated by Commitizen + rev: v4.1.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index c6556ab016..858f7d7181 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.1.0 (2024-12-06) + +### Feat + +- **commit**: allow '-- --allow-empty' to create empty commits + ## v4.0.0 (2024-11-26) ## v3.31.0 (2024-11-16) diff --git a/commitizen/__version__.py b/commitizen/__version__.py index ce1305bf4e..7039708762 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.0.0" +__version__ = "4.1.0" diff --git a/pyproject.toml b/pyproject.toml index 8737b86f28..e1b884f479 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "4.0.0" +version = "4.1.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "4.0.0" +version = "4.1.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 2eda7dd90b40498f61ca63009a5f907ee56513c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 01:34:36 +0000 Subject: [PATCH 359/598] build(deps-dev): bump types-python-dateutil Bumps [types-python-dateutil](https://github.com/python/typeshed) from 2.9.0.20241003 to 2.9.0.20241206. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-python-dateutil dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 973f01720b..78da53d281 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1551,13 +1551,13 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.9.0.20241003" +version = "2.9.0.20241206" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.9.0.20241003.tar.gz", hash = "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446"}, - {file = "types_python_dateutil-2.9.0.20241003-py3-none-any.whl", hash = "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d"}, + {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, + {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, ] [[package]] From ec9e911a690aa7b11ceae3d0b6c63ae9b6736825 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 01:34:55 +0000 Subject: [PATCH 360/598] build(deps): bump argcomplete from 3.5.1 to 3.5.2 Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 3.5.1 to 3.5.2. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/develop/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v3.5.1...v3.5.2) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 78da53d281..7cd09373f8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "argcomplete" -version = "3.5.1" +version = "3.5.2" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.5.1-py3-none-any.whl", hash = "sha256:1a1d148bdaa3e3b93454900163403df41448a248af01b6e849edc5ac08e6c363"}, - {file = "argcomplete-3.5.1.tar.gz", hash = "sha256:eb1ee355aa2557bd3d0145de7b06b2a45b0ce461e1e7813f5d066039ab4177b4"}, + {file = "argcomplete-3.5.2-py3-none-any.whl", hash = "sha256:036d020d79048a5d525bc63880d7a4b8d1668566b8a76daf1144c0bbe0f63472"}, + {file = "argcomplete-3.5.2.tar.gz", hash = "sha256:23146ed7ac4403b70bd6026402468942ceba34a6732255b9edf5b7354f68a6bb"}, ] [package.extras] From a60407addee791eef67cca7e6ca91b9bea565de0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Dec 2024 20:43:24 +0100 Subject: [PATCH 361/598] build(deps-dev): bump pytest-freezer from 0.4.8 to 0.4.9 (#1311) Bumps [pytest-freezer](https://github.com/pytest-dev/pytest-freezer) from 0.4.8 to 0.4.9. - [Release notes](https://github.com/pytest-dev/pytest-freezer/releases) - [Commits](https://github.com/pytest-dev/pytest-freezer/compare/0.4.8...0.4.9) --- updated-dependencies: - dependency-name: pytest-freezer dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7cd09373f8..9a384ddc37 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "argcomplete" @@ -1111,17 +1111,17 @@ pytest = ">=5.0" [[package]] name = "pytest-freezer" -version = "0.4.8" +version = "0.4.9" description = "Pytest plugin providing a fixture interface for spulec/freezegun" optional = false -python-versions = ">= 3.6" +python-versions = ">=3.6" files = [ - {file = "pytest_freezer-0.4.8-py3-none-any.whl", hash = "sha256:644ce7ddb8ba52b92a1df0a80a699bad2b93514c55cf92e9f2517b68ebe74814"}, - {file = "pytest_freezer-0.4.8.tar.gz", hash = "sha256:8ee2f724b3ff3540523fa355958a22e6f4c1c819928b78a7a183ae4248ce6ee6"}, + {file = "pytest_freezer-0.4.9-py3-none-any.whl", hash = "sha256:8b6c50523b7d4aec4590b52bfa5ff766d772ce506e2bf4846c88041ea9ccae59"}, + {file = "pytest_freezer-0.4.9.tar.gz", hash = "sha256:21bf16bc9cc46bf98f94382c4b5c3c389be7056ff0be33029111ae11b3f1c82a"}, ] [package.dependencies] -freezegun = ">=1.0" +freezegun = ">=1.1" pytest = ">=3.6" [[package]] From 166e634a4e29e6450d103249b54eff16c3d075ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Dec 2024 20:44:15 +0100 Subject: [PATCH 362/598] build(deps-dev): bump ruff from 0.8.2 to 0.8.3 (#1310) Bumps [ruff](https://github.com/astral-sh/ruff) from 0.8.2 to 0.8.3. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.8.2...0.8.3) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9a384ddc37..2f571b012d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1432,29 +1432,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.8.2" +version = "0.8.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d"}, - {file = "ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5"}, - {file = "ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d"}, - {file = "ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0"}, - {file = "ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa"}, - {file = "ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f"}, - {file = "ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22"}, - {file = "ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1"}, - {file = "ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea"}, - {file = "ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8"}, - {file = "ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5"}, + {file = "ruff-0.8.3-py3-none-linux_armv6l.whl", hash = "sha256:8d5d273ffffff0acd3db5bf626d4b131aa5a5ada1276126231c4174543ce20d6"}, + {file = "ruff-0.8.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e4d66a21de39f15c9757d00c50c8cdd20ac84f55684ca56def7891a025d7e939"}, + {file = "ruff-0.8.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c356e770811858bd20832af696ff6c7e884701115094f427b64b25093d6d932d"}, + {file = "ruff-0.8.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c0a60a825e3e177116c84009d5ebaa90cf40dfab56e1358d1df4e29a9a14b13"}, + {file = "ruff-0.8.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75fb782f4db39501210ac093c79c3de581d306624575eddd7e4e13747e61ba18"}, + {file = "ruff-0.8.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f26bc76a133ecb09a38b7868737eded6941b70a6d34ef53a4027e83913b6502"}, + {file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:01b14b2f72a37390c1b13477c1c02d53184f728be2f3ffc3ace5b44e9e87b90d"}, + {file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53babd6e63e31f4e96ec95ea0d962298f9f0d9cc5990a1bbb023a6baf2503a82"}, + {file = "ruff-0.8.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ae441ce4cf925b7f363d33cd6570c51435972d697e3e58928973994e56e1452"}, + {file = "ruff-0.8.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7c65bc0cadce32255e93c57d57ecc2cca23149edd52714c0c5d6fa11ec328cd"}, + {file = "ruff-0.8.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5be450bb18f23f0edc5a4e5585c17a56ba88920d598f04a06bd9fd76d324cb20"}, + {file = "ruff-0.8.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8faeae3827eaa77f5721f09b9472a18c749139c891dbc17f45e72d8f2ca1f8fc"}, + {file = "ruff-0.8.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:db503486e1cf074b9808403991663e4277f5c664d3fe237ee0d994d1305bb060"}, + {file = "ruff-0.8.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6567be9fb62fbd7a099209257fef4ad2c3153b60579818b31a23c886ed4147ea"}, + {file = "ruff-0.8.3-py3-none-win32.whl", hash = "sha256:19048f2f878f3ee4583fc6cb23fb636e48c2635e30fb2022b3a1cd293402f964"}, + {file = "ruff-0.8.3-py3-none-win_amd64.whl", hash = "sha256:f7df94f57d7418fa7c3ffb650757e0c2b96cf2501a0b192c18e4fb5571dfada9"}, + {file = "ruff-0.8.3-py3-none-win_arm64.whl", hash = "sha256:fe2756edf68ea79707c8d68b78ca9a58ed9af22e430430491ee03e718b5e4936"}, + {file = "ruff-0.8.3.tar.gz", hash = "sha256:5e7558304353b84279042fc584a4f4cb8a07ae79b2bf3da1a7551d960b5626d3"}, ] [[package]] From 069c503eb56cf1f07eb1eead6446511bc05fd8e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Dec 2024 20:44:58 +0100 Subject: [PATCH 363/598] build(deps-dev): bump mkdocs-material from 9.5.47 to 9.5.48 (#1309) Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.47 to 9.5.48. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.47...9.5.48) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2f571b012d..23a33ed85b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -756,13 +756,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.47" +version = "9.5.48" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.47-py3-none-any.whl", hash = "sha256:53fb9c9624e7865da6ec807d116cd7be24b3cb36ab31b1d1d1a9af58c56009a2"}, - {file = "mkdocs_material-9.5.47.tar.gz", hash = "sha256:fc3b7a8e00ad896660bd3a5cc12ca0cb28bdc2bcbe2a946b5714c23ac91b0ede"}, + {file = "mkdocs_material-9.5.48-py3-none-any.whl", hash = "sha256:b695c998f4b939ce748adbc0d3bff73fa886a670ece948cf27818fa115dc16f8"}, + {file = "mkdocs_material-9.5.48.tar.gz", hash = "sha256:a582531e8b34f4c7ed38c29d5c44763053832cf2a32f7409567e0c74749a47db"}, ] [package.dependencies] From c1ec4d9b6efa2661e5298aa1930323e096de4820 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Dec 2024 19:11:07 +0100 Subject: [PATCH 364/598] build(deps-dev): bump ruff from 0.8.3 to 0.8.4 (#1314) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 23a33ed85b..a302b921b5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1432,29 +1432,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.8.3" +version = "0.8.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.8.3-py3-none-linux_armv6l.whl", hash = "sha256:8d5d273ffffff0acd3db5bf626d4b131aa5a5ada1276126231c4174543ce20d6"}, - {file = "ruff-0.8.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e4d66a21de39f15c9757d00c50c8cdd20ac84f55684ca56def7891a025d7e939"}, - {file = "ruff-0.8.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c356e770811858bd20832af696ff6c7e884701115094f427b64b25093d6d932d"}, - {file = "ruff-0.8.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c0a60a825e3e177116c84009d5ebaa90cf40dfab56e1358d1df4e29a9a14b13"}, - {file = "ruff-0.8.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75fb782f4db39501210ac093c79c3de581d306624575eddd7e4e13747e61ba18"}, - {file = "ruff-0.8.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f26bc76a133ecb09a38b7868737eded6941b70a6d34ef53a4027e83913b6502"}, - {file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:01b14b2f72a37390c1b13477c1c02d53184f728be2f3ffc3ace5b44e9e87b90d"}, - {file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53babd6e63e31f4e96ec95ea0d962298f9f0d9cc5990a1bbb023a6baf2503a82"}, - {file = "ruff-0.8.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ae441ce4cf925b7f363d33cd6570c51435972d697e3e58928973994e56e1452"}, - {file = "ruff-0.8.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7c65bc0cadce32255e93c57d57ecc2cca23149edd52714c0c5d6fa11ec328cd"}, - {file = "ruff-0.8.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5be450bb18f23f0edc5a4e5585c17a56ba88920d598f04a06bd9fd76d324cb20"}, - {file = "ruff-0.8.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8faeae3827eaa77f5721f09b9472a18c749139c891dbc17f45e72d8f2ca1f8fc"}, - {file = "ruff-0.8.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:db503486e1cf074b9808403991663e4277f5c664d3fe237ee0d994d1305bb060"}, - {file = "ruff-0.8.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6567be9fb62fbd7a099209257fef4ad2c3153b60579818b31a23c886ed4147ea"}, - {file = "ruff-0.8.3-py3-none-win32.whl", hash = "sha256:19048f2f878f3ee4583fc6cb23fb636e48c2635e30fb2022b3a1cd293402f964"}, - {file = "ruff-0.8.3-py3-none-win_amd64.whl", hash = "sha256:f7df94f57d7418fa7c3ffb650757e0c2b96cf2501a0b192c18e4fb5571dfada9"}, - {file = "ruff-0.8.3-py3-none-win_arm64.whl", hash = "sha256:fe2756edf68ea79707c8d68b78ca9a58ed9af22e430430491ee03e718b5e4936"}, - {file = "ruff-0.8.3.tar.gz", hash = "sha256:5e7558304353b84279042fc584a4f4cb8a07ae79b2bf3da1a7551d960b5626d3"}, + {file = "ruff-0.8.4-py3-none-linux_armv6l.whl", hash = "sha256:58072f0c06080276804c6a4e21a9045a706584a958e644353603d36ca1eb8a60"}, + {file = "ruff-0.8.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ffb60904651c00a1e0b8df594591770018a0f04587f7deeb3838344fe3adabac"}, + {file = "ruff-0.8.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ddf5d654ac0d44389f6bf05cee4caeefc3132a64b58ea46738111d687352296"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e248b1f0fa2749edd3350a2a342b67b43a2627434c059a063418e3d375cfe643"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf197b98ed86e417412ee3b6c893f44c8864f816451441483253d5ff22c0e81e"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c41319b85faa3aadd4d30cb1cffdd9ac6b89704ff79f7664b853785b48eccdf3"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9f8402b7c4f96463f135e936d9ab77b65711fcd5d72e5d67597b543bbb43cf3f"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4e56b3baa9c23d324ead112a4fdf20db9a3f8f29eeabff1355114dd96014604"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:736272574e97157f7edbbb43b1d046125fce9e7d8d583d5d65d0c9bf2c15addf"}, + {file = "ruff-0.8.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fe710ab6061592521f902fca7ebcb9fabd27bc7c57c764298b1c1f15fff720"}, + {file = "ruff-0.8.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:13e9ec6d6b55f6da412d59953d65d66e760d583dd3c1c72bf1f26435b5bfdbae"}, + {file = "ruff-0.8.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:97d9aefef725348ad77d6db98b726cfdb075a40b936c7984088804dfd38268a7"}, + {file = "ruff-0.8.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ab78e33325a6f5374e04c2ab924a3367d69a0da36f8c9cb6b894a62017506111"}, + {file = "ruff-0.8.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8ef06f66f4a05c3ddbc9121a8b0cecccd92c5bf3dd43b5472ffe40b8ca10f0f8"}, + {file = "ruff-0.8.4-py3-none-win32.whl", hash = "sha256:552fb6d861320958ca5e15f28b20a3d071aa83b93caee33a87b471f99a6c0835"}, + {file = "ruff-0.8.4-py3-none-win_amd64.whl", hash = "sha256:f21a1143776f8656d7f364bd264a9d60f01b7f52243fbe90e7670c0dfe0cf65d"}, + {file = "ruff-0.8.4-py3-none-win_arm64.whl", hash = "sha256:9183dd615d8df50defa8b1d9a074053891ba39025cf5ae88e8bcb52edcc4bf08"}, + {file = "ruff-0.8.4.tar.gz", hash = "sha256:0d5f89f254836799af1615798caa5f80b7f935d7a670fad66c5007928e57ace8"}, ] [[package]] From 32271c143d711b77d26a1e7208701aafc5bfaabe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Dec 2024 19:11:59 +0100 Subject: [PATCH 365/598] build(deps-dev): bump pytest-regressions from 2.5.0 to 2.6.0 (#1313) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index a302b921b5..fcc4896ff1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1143,13 +1143,13 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-regressions" -version = "2.5.0" +version = "2.6.0" description = "Easy to use fixtures to write regression tests." optional = false python-versions = ">=3.8" files = [ - {file = "pytest-regressions-2.5.0.tar.gz", hash = "sha256:818c7884c1cff3babf89eebb02cbc27b307856b1985427c24d52cb812a106fd9"}, - {file = "pytest_regressions-2.5.0-py3-none-any.whl", hash = "sha256:8c4e5c4037325fdb0825bc1fdcb75e17e03adf3407049f0cb704bb996d496255"}, + {file = "pytest_regressions-2.6.0-py3-none-any.whl", hash = "sha256:5c4a4763415f765770449190097a99b3a8a6ebf20b24e6d90a32da6644e5d041"}, + {file = "pytest_regressions-2.6.0.tar.gz", hash = "sha256:e3dce521fac11199a2a91a1b8837974d708c7e8665b8c9668b3a721b556c8183"}, ] [package.dependencies] @@ -1159,7 +1159,7 @@ pyyaml = "*" [package.extras] dataframe = ["numpy", "pandas"] -dev = ["matplotlib", "mypy", "numpy", "pandas", "pillow", "pre-commit", "restructuredtext-lint", "tox"] +dev = ["matplotlib", "mypy", "numpy", "pandas", "pillow", "pre-commit", "pyarrow", "restructuredtext-lint", "tox"] image = ["numpy", "pillow"] num = ["numpy", "pandas"] From d335cdf753512c17f281866332868de513c87ddc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Dec 2024 19:12:39 +0100 Subject: [PATCH 366/598] build(deps-dev): bump mkdocs-material from 9.5.48 to 9.5.49 (#1312) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index fcc4896ff1..5d45dcf0f8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -756,13 +756,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.48" +version = "9.5.49" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.48-py3-none-any.whl", hash = "sha256:b695c998f4b939ce748adbc0d3bff73fa886a670ece948cf27818fa115dc16f8"}, - {file = "mkdocs_material-9.5.48.tar.gz", hash = "sha256:a582531e8b34f4c7ed38c29d5c44763053832cf2a32f7409567e0c74749a47db"}, + {file = "mkdocs_material-9.5.49-py3-none-any.whl", hash = "sha256:c3c2d8176b18198435d3a3e119011922f3e11424074645c24019c2dcf08a360e"}, + {file = "mkdocs_material-9.5.49.tar.gz", hash = "sha256:3671bb282b4f53a1c72e08adbe04d2481a98f85fed392530051f80ff94a9621d"}, ] [package.dependencies] From 218a32e7981104086b1c99e0da655c3477bd73e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:51:12 +0000 Subject: [PATCH 367/598] build(deps): bump jinja2 from 3.1.4 to 3.1.5 Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.4 to 3.1.5. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.4...3.1.5) --- updated-dependencies: - dependency-name: jinja2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5d45dcf0f8..1a2acc0446 100644 --- a/poetry.lock +++ b/poetry.lock @@ -543,13 +543,13 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] From a699f647426c6c7f5a5b9e859a50bcf7cf330ca8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:51:32 +0000 Subject: [PATCH 368/598] build(deps-dev): bump mypy from 1.13.0 to 1.14.0 Bumps [mypy](https://github.com/python/mypy) from 1.13.0 to 1.14.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 70 ++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1a2acc0446..d926888c18 100644 --- a/poetry.lock +++ b/poetry.lock @@ -796,49 +796,49 @@ files = [ [[package]] name = "mypy" -version = "1.13.0" +version = "1.14.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, - {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, - {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, - {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, - {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, - {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, - {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, - {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, - {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, - {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, - {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, - {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, - {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, - {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, - {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, - {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, - {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, - {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, - {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, - {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, - {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, - {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, + {file = "mypy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e971c1c667007f9f2b397ffa80fa8e1e0adccff336e5e77e74cb5f22868bee87"}, + {file = "mypy-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e86aaeaa3221a278c66d3d673b297232947d873773d61ca3ee0e28b2ff027179"}, + {file = "mypy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1628c5c3ce823d296e41e2984ff88c5861499041cb416a8809615d0c1f41740e"}, + {file = "mypy-1.14.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fadb29b77fc14a0dd81304ed73c828c3e5cde0016c7e668a86a3e0dfc9f3af3"}, + {file = "mypy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:3fa76988dc760da377c1e5069200a50d9eaaccf34f4ea18428a3337034ab5a44"}, + {file = "mypy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e73c8a154eed31db3445fe28f63ad2d97b674b911c00191416cf7f6459fd49a"}, + {file = "mypy-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:273e70fcb2e38c5405a188425aa60b984ffdcef65d6c746ea5813024b68c73dc"}, + {file = "mypy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1daca283d732943731a6a9f20fdbcaa927f160bc51602b1d4ef880a6fb252015"}, + {file = "mypy-1.14.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7e68047bedb04c1c25bba9901ea46ff60d5eaac2d71b1f2161f33107e2b368eb"}, + {file = "mypy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:7a52f26b9c9b1664a60d87675f3bae00b5c7f2806e0c2800545a32c325920bcc"}, + {file = "mypy-1.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d5326ab70a6db8e856d59ad4cb72741124950cbbf32e7b70e30166ba7bbf61dd"}, + {file = "mypy-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf4ec4980bec1e0e24e5075f449d014011527ae0055884c7e3abc6a99cd2c7f1"}, + {file = "mypy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:390dfb898239c25289495500f12fa73aa7f24a4c6d90ccdc165762462b998d63"}, + {file = "mypy-1.14.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7e026d55ddcd76e29e87865c08cbe2d0104e2b3153a523c529de584759379d3d"}, + {file = "mypy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:585ed36031d0b3ee362e5107ef449a8b5dfd4e9c90ccbe36414ee405ee6b32ba"}, + {file = "mypy-1.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9f6f4c0b27401d14c483c622bc5105eff3911634d576bbdf6695b9a7c1ba741"}, + {file = "mypy-1.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b2280cedcb312c7a79f5001ae5325582d0d339bce684e4a529069d0e7ca1e7"}, + {file = "mypy-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:342de51c48bab326bfc77ce056ba08c076d82ce4f5a86621f972ed39970f94d8"}, + {file = "mypy-1.14.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:00df23b42e533e02a6f0055e54de9a6ed491cd8b7ea738647364fd3a39ea7efc"}, + {file = "mypy-1.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:e8c8387e5d9dff80e7daf961df357c80e694e942d9755f3ad77d69b0957b8e3f"}, + {file = "mypy-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b16738b1d80ec4334654e89e798eb705ac0c36c8a5c4798496cd3623aa02286"}, + {file = "mypy-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:10065fcebb7c66df04b05fc799a854b1ae24d9963c8bb27e9064a9bdb43aa8ad"}, + {file = "mypy-1.14.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fbb7d683fa6bdecaa106e8368aa973ecc0ddb79a9eaeb4b821591ecd07e9e03c"}, + {file = "mypy-1.14.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3498cb55448dc5533e438cd13d6ddd28654559c8c4d1fd4b5ca57a31b81bac01"}, + {file = "mypy-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:c7b243408ea43755f3a21a0a08e5c5ae30eddb4c58a80f415ca6b118816e60aa"}, + {file = "mypy-1.14.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:14117b9da3305b39860d0aa34b8f1ff74d209a368829a584eb77524389a9c13e"}, + {file = "mypy-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af98c5a958f9c37404bd4eef2f920b94874507e146ed6ee559f185b8809c44cc"}, + {file = "mypy-1.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0b343a1d3989547024377c2ba0dca9c74a2428ad6ed24283c213af8dbb0710b"}, + {file = "mypy-1.14.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cdb5563c1726c85fb201be383168f8c866032db95e1095600806625b3a648cb7"}, + {file = "mypy-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:74e925649c1ee0a79aa7448baf2668d81cc287dc5782cff6a04ee93f40fb8d3f"}, + {file = "mypy-1.14.0-py3-none-any.whl", hash = "sha256:2238d7f93fc4027ed1efc944507683df3ba406445a2b6c96e79666a045aadfab"}, + {file = "mypy-1.14.0.tar.gz", hash = "sha256:822dbd184d4a9804df5a7d5335a68cf7662930e70b8c1bc976645d1509f9a9d6"}, ] [package.dependencies] -mypy-extensions = ">=1.0.0" +mypy_extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" +typing_extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] From c2aaff4569fd16da9ac6e4ba262171b1072c6927 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:51:46 +0000 Subject: [PATCH 369/598] build(deps-dev): bump types-pyyaml Bumps [types-pyyaml](https://github.com/python/typeshed) from 6.0.12.20240917 to 6.0.12.20241221. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-pyyaml dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d926888c18..57e8390ca0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1562,13 +1562,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.20240917" +version = "6.0.12.20241221" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"}, - {file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"}, + {file = "types_PyYAML-6.0.12.20241221-py3-none-any.whl", hash = "sha256:0657a4ff8411a030a2116a196e8e008ea679696b5b1a8e1a6aa8ebb737b34688"}, + {file = "types_pyyaml-6.0.12.20241221.tar.gz", hash = "sha256:4f149aa893ff6a46889a30af4c794b23833014c469cc57cbc3ad77498a58996f"}, ] [[package]] From 7a8907151df7fa8611b066fc51735e289eff8d57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Dec 2024 02:00:39 +0000 Subject: [PATCH 370/598] build(deps): bump charset-normalizer from 3.4.0 to 3.4.1 Bumps [charset-normalizer](https://github.com/jawah/charset_normalizer) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/jawah/charset_normalizer/releases) - [Changelog](https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md) - [Commits](https://github.com/jawah/charset_normalizer/compare/3.4.0...3.4.1) --- updated-dependencies: - dependency-name: charset-normalizer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 203 ++++++++++++++++++++++++---------------------------- 1 file changed, 95 insertions(+), 108 deletions(-) diff --git a/poetry.lock b/poetry.lock index 57e8390ca0..b9d5210294 100644 --- a/poetry.lock +++ b/poetry.lock @@ -70,116 +70,103 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] From 526e76154503beb5c8e28a1d235b536a32b54f77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 02:04:20 +0000 Subject: [PATCH 371/598] build(deps): bump questionary from 2.0.1 to 2.1.0 Bumps [questionary](https://github.com/tmbo/questionary) from 2.0.1 to 2.1.0. - [Commits](https://github.com/tmbo/questionary/compare/2.0.1...2.1.0) --- updated-dependencies: - dependency-name: questionary dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index b9d5210294..bc24fb5b11 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1262,17 +1262,17 @@ pyyaml = "*" [[package]] name = "questionary" -version = "2.0.1" +version = "2.1.0" description = "Python library to build pretty command line user prompts ⭐️" optional = false python-versions = ">=3.8" files = [ - {file = "questionary-2.0.1-py3-none-any.whl", hash = "sha256:8ab9a01d0b91b68444dff7f6652c1e754105533f083cbe27597c8110ecc230a2"}, - {file = "questionary-2.0.1.tar.gz", hash = "sha256:bcce898bf3dbb446ff62830c86c5c6fb9a22a54146f0f5597d3da43b10d8fc8b"}, + {file = "questionary-2.1.0-py3-none-any.whl", hash = "sha256:44174d237b68bc828e4878c763a9ad6790ee61990e0ae72927694ead57bab8ec"}, + {file = "questionary-2.1.0.tar.gz", hash = "sha256:6302cdd645b19667d8f6e6634774e9538bfcd1aad9be287e743d96cacaf95587"}, ] [package.dependencies] -prompt_toolkit = ">=2.0,<=3.0.36" +prompt_toolkit = ">=2.0,<4.0" [[package]] name = "regex" From 09faa018a3067e325920f14d2f073548057c3bb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 02:01:50 +0000 Subject: [PATCH 372/598] build(deps-dev): bump types-pyyaml Bumps [types-pyyaml](https://github.com/python/typeshed) from 6.0.12.20241221 to 6.0.12.20241230. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-pyyaml dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index bc24fb5b11..0e98fb0efd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1549,13 +1549,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.20241221" +version = "6.0.12.20241230" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" files = [ - {file = "types_PyYAML-6.0.12.20241221-py3-none-any.whl", hash = "sha256:0657a4ff8411a030a2116a196e8e008ea679696b5b1a8e1a6aa8ebb737b34688"}, - {file = "types_pyyaml-6.0.12.20241221.tar.gz", hash = "sha256:4f149aa893ff6a46889a30af4c794b23833014c469cc57cbc3ad77498a58996f"}, + {file = "types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6"}, + {file = "types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c"}, ] [[package]] From 8e36610ab3440d54dbf52d6e34a0c44ef4f392a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 02:01:38 +0000 Subject: [PATCH 373/598] build(deps-dev): bump mypy from 1.14.0 to 1.14.1 Bumps [mypy](https://github.com/python/mypy) from 1.14.0 to 1.14.1. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.14.0...v1.14.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 72 +++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0e98fb0efd..ff1f4d34e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -783,43 +783,49 @@ files = [ [[package]] name = "mypy" -version = "1.14.0" +version = "1.14.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e971c1c667007f9f2b397ffa80fa8e1e0adccff336e5e77e74cb5f22868bee87"}, - {file = "mypy-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e86aaeaa3221a278c66d3d673b297232947d873773d61ca3ee0e28b2ff027179"}, - {file = "mypy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1628c5c3ce823d296e41e2984ff88c5861499041cb416a8809615d0c1f41740e"}, - {file = "mypy-1.14.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fadb29b77fc14a0dd81304ed73c828c3e5cde0016c7e668a86a3e0dfc9f3af3"}, - {file = "mypy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:3fa76988dc760da377c1e5069200a50d9eaaccf34f4ea18428a3337034ab5a44"}, - {file = "mypy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e73c8a154eed31db3445fe28f63ad2d97b674b911c00191416cf7f6459fd49a"}, - {file = "mypy-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:273e70fcb2e38c5405a188425aa60b984ffdcef65d6c746ea5813024b68c73dc"}, - {file = "mypy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1daca283d732943731a6a9f20fdbcaa927f160bc51602b1d4ef880a6fb252015"}, - {file = "mypy-1.14.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7e68047bedb04c1c25bba9901ea46ff60d5eaac2d71b1f2161f33107e2b368eb"}, - {file = "mypy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:7a52f26b9c9b1664a60d87675f3bae00b5c7f2806e0c2800545a32c325920bcc"}, - {file = "mypy-1.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d5326ab70a6db8e856d59ad4cb72741124950cbbf32e7b70e30166ba7bbf61dd"}, - {file = "mypy-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf4ec4980bec1e0e24e5075f449d014011527ae0055884c7e3abc6a99cd2c7f1"}, - {file = "mypy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:390dfb898239c25289495500f12fa73aa7f24a4c6d90ccdc165762462b998d63"}, - {file = "mypy-1.14.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7e026d55ddcd76e29e87865c08cbe2d0104e2b3153a523c529de584759379d3d"}, - {file = "mypy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:585ed36031d0b3ee362e5107ef449a8b5dfd4e9c90ccbe36414ee405ee6b32ba"}, - {file = "mypy-1.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9f6f4c0b27401d14c483c622bc5105eff3911634d576bbdf6695b9a7c1ba741"}, - {file = "mypy-1.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b2280cedcb312c7a79f5001ae5325582d0d339bce684e4a529069d0e7ca1e7"}, - {file = "mypy-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:342de51c48bab326bfc77ce056ba08c076d82ce4f5a86621f972ed39970f94d8"}, - {file = "mypy-1.14.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:00df23b42e533e02a6f0055e54de9a6ed491cd8b7ea738647364fd3a39ea7efc"}, - {file = "mypy-1.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:e8c8387e5d9dff80e7daf961df357c80e694e942d9755f3ad77d69b0957b8e3f"}, - {file = "mypy-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b16738b1d80ec4334654e89e798eb705ac0c36c8a5c4798496cd3623aa02286"}, - {file = "mypy-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:10065fcebb7c66df04b05fc799a854b1ae24d9963c8bb27e9064a9bdb43aa8ad"}, - {file = "mypy-1.14.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fbb7d683fa6bdecaa106e8368aa973ecc0ddb79a9eaeb4b821591ecd07e9e03c"}, - {file = "mypy-1.14.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3498cb55448dc5533e438cd13d6ddd28654559c8c4d1fd4b5ca57a31b81bac01"}, - {file = "mypy-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:c7b243408ea43755f3a21a0a08e5c5ae30eddb4c58a80f415ca6b118816e60aa"}, - {file = "mypy-1.14.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:14117b9da3305b39860d0aa34b8f1ff74d209a368829a584eb77524389a9c13e"}, - {file = "mypy-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af98c5a958f9c37404bd4eef2f920b94874507e146ed6ee559f185b8809c44cc"}, - {file = "mypy-1.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0b343a1d3989547024377c2ba0dca9c74a2428ad6ed24283c213af8dbb0710b"}, - {file = "mypy-1.14.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cdb5563c1726c85fb201be383168f8c866032db95e1095600806625b3a648cb7"}, - {file = "mypy-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:74e925649c1ee0a79aa7448baf2668d81cc287dc5782cff6a04ee93f40fb8d3f"}, - {file = "mypy-1.14.0-py3-none-any.whl", hash = "sha256:2238d7f93fc4027ed1efc944507683df3ba406445a2b6c96e79666a045aadfab"}, - {file = "mypy-1.14.0.tar.gz", hash = "sha256:822dbd184d4a9804df5a7d5335a68cf7662930e70b8c1bc976645d1509f9a9d6"}, + {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, + {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, + {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"}, + {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"}, + {file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"}, + {file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"}, + {file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"}, + {file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"}, + {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"}, + {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"}, + {file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"}, + {file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"}, + {file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"}, + {file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"}, + {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"}, + {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"}, + {file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"}, + {file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"}, + {file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"}, + {file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"}, + {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"}, + {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"}, + {file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"}, + {file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"}, + {file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"}, + {file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"}, + {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"}, + {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"}, + {file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"}, + {file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"}, + {file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"}, + {file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"}, + {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"}, + {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"}, + {file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"}, + {file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"}, + {file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"}, + {file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"}, ] [package.dependencies] From 2b0bcdd1f17b70815b6d75166dd2163c7d6580d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 02:02:11 +0000 Subject: [PATCH 374/598] build(deps-dev): bump ipython from 8.18.0 to 8.18.1 Bumps [ipython](https://github.com/ipython/ipython) from 8.18.0 to 8.18.1. - [Release notes](https://github.com/ipython/ipython/releases) - [Commits](https://github.com/ipython/ipython/compare/8.18.0...8.18.1) --- updated-dependencies: - dependency-name: ipython dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index ff1f4d34e6..a4618fecc6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -474,13 +474,13 @@ files = [ [[package]] name = "ipython" -version = "8.18.0" +version = "8.18.1" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.9" files = [ - {file = "ipython-8.18.0-py3-none-any.whl", hash = "sha256:d538a7a98ad9b7e018926447a5f35856113a85d08fd68a165d7871ab5175f6e0"}, - {file = "ipython-8.18.0.tar.gz", hash = "sha256:4feb61210160f75e229ce932dbf8b719bff37af123c0b985fd038b14233daa16"}, + {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, + {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, ] [package.dependencies] @@ -490,7 +490,7 @@ exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +prompt-toolkit = ">=3.0.41,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" @@ -979,13 +979,13 @@ virtualenv = ">=20.10.0" [[package]] name = "prompt-toolkit" -version = "3.0.36" +version = "3.0.48" description = "Library for building powerful interactive command lines in Python" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"}, - {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"}, + {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, + {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, ] [package.dependencies] From 1d8b5312753887e62fd91f0531bd1d51fb4fdc25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 01:13:32 +0000 Subject: [PATCH 375/598] build(deps-dev): bump ruff from 0.8.4 to 0.8.5 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.8.4 to 0.8.5. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.8.4...0.8.5) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index a4618fecc6..41ca91754f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.8.4" +version = "0.8.5" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.8.4-py3-none-linux_armv6l.whl", hash = "sha256:58072f0c06080276804c6a4e21a9045a706584a958e644353603d36ca1eb8a60"}, - {file = "ruff-0.8.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ffb60904651c00a1e0b8df594591770018a0f04587f7deeb3838344fe3adabac"}, - {file = "ruff-0.8.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ddf5d654ac0d44389f6bf05cee4caeefc3132a64b58ea46738111d687352296"}, - {file = "ruff-0.8.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e248b1f0fa2749edd3350a2a342b67b43a2627434c059a063418e3d375cfe643"}, - {file = "ruff-0.8.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf197b98ed86e417412ee3b6c893f44c8864f816451441483253d5ff22c0e81e"}, - {file = "ruff-0.8.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c41319b85faa3aadd4d30cb1cffdd9ac6b89704ff79f7664b853785b48eccdf3"}, - {file = "ruff-0.8.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9f8402b7c4f96463f135e936d9ab77b65711fcd5d72e5d67597b543bbb43cf3f"}, - {file = "ruff-0.8.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4e56b3baa9c23d324ead112a4fdf20db9a3f8f29eeabff1355114dd96014604"}, - {file = "ruff-0.8.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:736272574e97157f7edbbb43b1d046125fce9e7d8d583d5d65d0c9bf2c15addf"}, - {file = "ruff-0.8.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fe710ab6061592521f902fca7ebcb9fabd27bc7c57c764298b1c1f15fff720"}, - {file = "ruff-0.8.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:13e9ec6d6b55f6da412d59953d65d66e760d583dd3c1c72bf1f26435b5bfdbae"}, - {file = "ruff-0.8.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:97d9aefef725348ad77d6db98b726cfdb075a40b936c7984088804dfd38268a7"}, - {file = "ruff-0.8.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ab78e33325a6f5374e04c2ab924a3367d69a0da36f8c9cb6b894a62017506111"}, - {file = "ruff-0.8.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8ef06f66f4a05c3ddbc9121a8b0cecccd92c5bf3dd43b5472ffe40b8ca10f0f8"}, - {file = "ruff-0.8.4-py3-none-win32.whl", hash = "sha256:552fb6d861320958ca5e15f28b20a3d071aa83b93caee33a87b471f99a6c0835"}, - {file = "ruff-0.8.4-py3-none-win_amd64.whl", hash = "sha256:f21a1143776f8656d7f364bd264a9d60f01b7f52243fbe90e7670c0dfe0cf65d"}, - {file = "ruff-0.8.4-py3-none-win_arm64.whl", hash = "sha256:9183dd615d8df50defa8b1d9a074053891ba39025cf5ae88e8bcb52edcc4bf08"}, - {file = "ruff-0.8.4.tar.gz", hash = "sha256:0d5f89f254836799af1615798caa5f80b7f935d7a670fad66c5007928e57ace8"}, + {file = "ruff-0.8.5-py3-none-linux_armv6l.whl", hash = "sha256:5ad11a5e3868a73ca1fa4727fe7e33735ea78b416313f4368c504dbeb69c0f88"}, + {file = "ruff-0.8.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f69ab37771ea7e0715fead8624ec42996d101269a96e31f4d31be6fc33aa19b7"}, + {file = "ruff-0.8.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b5462d7804558ccff9c08fe8cbf6c14b7efe67404316696a2dde48297b1925bb"}, + {file = "ruff-0.8.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d56de7220a35607f9fe59f8a6d018e14504f7b71d784d980835e20fc0611cd50"}, + {file = "ruff-0.8.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9d99cf80b0429cbebf31cbbf6f24f05a29706f0437c40413d950e67e2d4faca4"}, + {file = "ruff-0.8.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b75ac29715ac60d554a049dbb0ef3b55259076181c3369d79466cb130eb5afd"}, + {file = "ruff-0.8.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c9d526a62c9eda211b38463528768fd0ada25dad524cb33c0e99fcff1c67b5dc"}, + {file = "ruff-0.8.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:587c5e95007612c26509f30acc506c874dab4c4abbacd0357400bd1aa799931b"}, + {file = "ruff-0.8.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:622b82bf3429ff0e346835ec213aec0a04d9730480cbffbb6ad9372014e31bbd"}, + {file = "ruff-0.8.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f99be814d77a5dac8a8957104bdd8c359e85c86b0ee0e38dca447cb1095f70fb"}, + {file = "ruff-0.8.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c01c048f9c3385e0fd7822ad0fd519afb282af9cf1778f3580e540629df89725"}, + {file = "ruff-0.8.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7512e8cb038db7f5db6aae0e24735ff9ea03bb0ed6ae2ce534e9baa23c1dc9ea"}, + {file = "ruff-0.8.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:762f113232acd5b768d6b875d16aad6b00082add40ec91c927f0673a8ec4ede8"}, + {file = "ruff-0.8.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:03a90200c5dfff49e4c967b405f27fdfa81594cbb7c5ff5609e42d7fe9680da5"}, + {file = "ruff-0.8.5-py3-none-win32.whl", hash = "sha256:8710ffd57bdaa6690cbf6ecff19884b8629ec2a2a2a2f783aa94b1cc795139ed"}, + {file = "ruff-0.8.5-py3-none-win_amd64.whl", hash = "sha256:4020d8bf8d3a32325c77af452a9976a9ad6455773bcb94991cf15bd66b347e47"}, + {file = "ruff-0.8.5-py3-none-win_arm64.whl", hash = "sha256:134ae019ef13e1b060ab7136e7828a6d83ea727ba123381307eb37c6bd5e01cb"}, + {file = "ruff-0.8.5.tar.gz", hash = "sha256:1098d36f69831f7ff2a1da3e6407d5fbd6dfa2559e4f74ff2d260c5588900317"}, ] [[package]] From fc96f9c9fb8582634d1b291731109649294a91a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 01:33:13 +0000 Subject: [PATCH 376/598] build(deps-dev): bump mkdocs-material from 9.5.49 to 9.5.50 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.49 to 9.5.50. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.49...9.5.50) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 41ca91754f..9d747b8735 100644 --- a/poetry.lock +++ b/poetry.lock @@ -743,13 +743,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.49" +version = "9.5.50" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.49-py3-none-any.whl", hash = "sha256:c3c2d8176b18198435d3a3e119011922f3e11424074645c24019c2dcf08a360e"}, - {file = "mkdocs_material-9.5.49.tar.gz", hash = "sha256:3671bb282b4f53a1c72e08adbe04d2481a98f85fed392530051f80ff94a9621d"}, + {file = "mkdocs_material-9.5.50-py3-none-any.whl", hash = "sha256:f24100f234741f4d423a9d672a909d859668a4f404796be3cf035f10d6050385"}, + {file = "mkdocs_material-9.5.50.tar.gz", hash = "sha256:ae5fe16f3d7c9ccd05bb6916a7da7420cf99a9ce5e33debd9d40403a090d5825"}, ] [package.dependencies] @@ -766,7 +766,7 @@ regex = ">=2022.4" requests = ">=2.26,<3.0" [package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<3)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] From f810b2c9a4b6671eabfec21ae3d24b1bc71aa821 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 01:08:34 +0000 Subject: [PATCH 377/598] build(deps): bump importlib-metadata from 8.5.0 to 8.6.1 Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 8.5.0 to 8.6.1. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v8.5.0...v8.6.1) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9d747b8735..7c85f4c137 100644 --- a/poetry.lock +++ b/poetry.lock @@ -440,13 +440,13 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 [[package]] name = "importlib-metadata" -version = "8.5.0" +version = "8.6.1" description = "Read metadata from Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, - {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, + {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, + {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, ] [package.dependencies] @@ -458,7 +458,7 @@ cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +test = ["flufl.flake8", "importlib_resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] type = ["pytest-mypy"] [[package]] From 2902d5a0b18084c5a297676752ddc66512883c7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 01:08:21 +0000 Subject: [PATCH 378/598] build(deps-dev): bump pre-commit from 4.0.1 to 4.1.0 Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 4.0.1 to 4.1.0. - [Release notes](https://github.com/pre-commit/pre-commit/releases) - [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pre-commit/pre-commit/compare/v4.0.1...v4.1.0) --- updated-dependencies: - dependency-name: pre-commit dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7c85f4c137..23deba7a24 100644 --- a/poetry.lock +++ b/poetry.lock @@ -961,13 +961,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "4.0.1" +version = "4.1.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" files = [ - {file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"}, - {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, + {file = "pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b"}, + {file = "pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4"}, ] [package.dependencies] From 15c29df50e161ebce154b573f3c882fee32521d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 02:02:14 +0000 Subject: [PATCH 379/598] build(deps-dev): bump pytest-regressions from 2.6.0 to 2.7.0 Bumps [pytest-regressions](https://github.com/ESSS/pytest-regressions) from 2.6.0 to 2.7.0. - [Release notes](https://github.com/ESSS/pytest-regressions/releases) - [Changelog](https://github.com/ESSS/pytest-regressions/blob/master/CHANGELOG.rst) - [Commits](https://github.com/ESSS/pytest-regressions/compare/v2.6.0...v2.7.0) --- updated-dependencies: - dependency-name: pytest-regressions dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 23deba7a24..956eb75ffb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1136,13 +1136,13 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-regressions" -version = "2.6.0" +version = "2.7.0" description = "Easy to use fixtures to write regression tests." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pytest_regressions-2.6.0-py3-none-any.whl", hash = "sha256:5c4a4763415f765770449190097a99b3a8a6ebf20b24e6d90a32da6644e5d041"}, - {file = "pytest_regressions-2.6.0.tar.gz", hash = "sha256:e3dce521fac11199a2a91a1b8837974d708c7e8665b8c9668b3a721b556c8183"}, + {file = "pytest_regressions-2.7.0-py3-none-any.whl", hash = "sha256:69f5e3f03493cf0ef84d96d23e50a546617c198b1d7746f2e2b9e441cbab4847"}, + {file = "pytest_regressions-2.7.0.tar.gz", hash = "sha256:4c30064e0923929012c94f5d6f35205be06fd8709c7f0dba0228e05c460af05e"}, ] [package.dependencies] From ed8f0831ef822bf5be22ccd437504f0aa0280a59 Mon Sep 17 00:00:00 2001 From: Lyonel Martinez Date: Fri, 29 Nov 2024 16:09:07 +0100 Subject: [PATCH 380/598] fix(get-next-bump): fix to permit usage of --get-next options even when update_changelog_on_bump is set to true --- commitizen/commands/bump.py | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index a3682df8f3..1f98c19954 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -66,9 +66,8 @@ def __init__(self, config: BaseConfig, arguments: dict): }, } self.cz = factory.commiter_factory(self.config) - self.changelog = arguments["changelog"] or self.config.settings.get( - "update_changelog_on_bump" - ) + self.changelog_flag = arguments["changelog"] + self.changelog_config = self.config.settings.get("update_changelog_on_bump") self.changelog_to_stdout = arguments["changelog_to_stdout"] self.git_output_to_stderr = arguments["git_output_to_stderr"] self.no_verify = arguments["no_verify"] @@ -207,17 +206,24 @@ def __call__(self) -> None: # noqa: C901 "--local-version cannot be combined with --build-metadata" ) - # If user specified changelog_to_stdout, they probably want the - # changelog to be generated as well, this is the most intuitive solution - self.changelog = self.changelog or bool(self.changelog_to_stdout) - if get_next: - if self.changelog: + # if trying to use --get-next, we should not allow --changelog or --changelog-to-stdout + if self.changelog_flag or bool(self.changelog_to_stdout): raise NotAllowed( "--changelog or --changelog-to-stdout is not allowed with --get-next" ) + # --get-next is a special case, taking precedence over config for 'update_changelog_on_bump' + self.changelog_config = False # Setting dry_run to prevent any unwanted changes to the repo or files self.dry_run = True + else: + # If user specified changelog_to_stdout, they probably want the + # changelog to be generated as well, this is the most intuitive solution + self.changelog_flag = ( + self.changelog_flag + or bool(self.changelog_to_stdout) + or self.changelog_config + ) current_tag_version: str = bump.normalize_tag( current_version, @@ -309,7 +315,7 @@ def __call__(self) -> None: # noqa: C901 ) files: list[str] = [] - if self.changelog: + if self.changelog_flag: args = { "unreleased_version": new_tag_version, "template": self.template, @@ -356,7 +362,9 @@ def __call__(self) -> None: # noqa: C901 new_tag_version=new_tag_version, message=message, increment=increment, - changelog_file_name=changelog_cmd.file_name if self.changelog else None, + changelog_file_name=changelog_cmd.file_name + if self.changelog_flag + else None, ) if is_files_only: @@ -365,7 +373,7 @@ def __call__(self) -> None: # noqa: C901 # FIXME: check if any changes have been staged git.add(*files) c = git.commit(message, args=self._get_commit_args()) - if self.retry and c.return_code != 0 and self.changelog: + if self.retry and c.return_code != 0 and self.changelog_flag: # Maybe pre-commit reformatted some files? Retry once logger.debug("1st git.commit error: %s", c.err) logger.info("1st commit attempt failed; retrying once") @@ -410,7 +418,9 @@ def __call__(self) -> None: # noqa: C901 current_tag_version=new_tag_version, message=message, increment=increment, - changelog_file_name=changelog_cmd.file_name if self.changelog else None, + changelog_file_name=changelog_cmd.file_name + if self.changelog_flag + else None, ) # TODO: For v3 output this only as diagnostic and remove this if From d20580dda697c83bd7427704490c958cd73cd565 Mon Sep 17 00:00:00 2001 From: Lyonel Martinez Date: Fri, 29 Nov 2024 16:27:21 +0100 Subject: [PATCH 381/598] fix(get-next-bump): add a test case --- tests/commands/test_bump_command.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 81273764dd..8acb5143c7 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1481,6 +1481,26 @@ def test_bump_get_next(mocker: MockFixture, capsys): assert tag_exists is False +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_get_next_update_changelog_on_bump( + mocker: MockFixture, capsys, config_path +): + create_file_and_commit("feat: new file") + with open(config_path, "a", encoding="utf-8") as fp: + fp.write("update_changelog_on_bump = true\n") + + testargs = ["cz", "bump", "--yes", "--get-next"] + mocker.patch.object(sys, "argv", testargs) + with pytest.raises(GetNextExit): + cli.main() + + out, _ = capsys.readouterr() + assert "0.2.0" in out + + tag_exists = git.tag_exist("0.2.0") + assert tag_exists is False + + @pytest.mark.usefixtures("tmp_commitizen_project") def test_bump_get_next__changelog_is_not_allowed(mocker: MockFixture): create_file_and_commit("feat: new file") From c6119812f7c21e6b2b01583025e2664945c550a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jan 2025 10:49:23 +0000 Subject: [PATCH 382/598] =?UTF-8?q?bump:=20version=204.1.0=20=E2=86=92=204?= =?UTF-8?q?.1.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 7 +++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 986b63f875..5ee5c84c96 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.1.0 # automatically updated by Commitizen + rev: v4.1.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 858f7d7181..3687908b19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v4.1.1 (2025-01-26) + +### Fix + +- **get-next-bump**: add a test case +- **get-next-bump**: fix to permit usage of --get-next options even when update_changelog_on_bump is set to true + ## v4.1.0 (2024-12-06) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 7039708762..72aa75832f 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.1.0" +__version__ = "4.1.1" diff --git a/pyproject.toml b/pyproject.toml index e1b884f479..094d6fca0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "4.1.0" +version = "4.1.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "4.1.0" +version = "4.1.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" From 0d093b83596fb320a5ee0533d53e5cee0bdc6daf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 01:24:58 +0000 Subject: [PATCH 383/598] build(deps-dev): bump deprecated from 1.2.15 to 1.2.17 Bumps [deprecated](https://github.com/laurent-laporte-pro/deprecated) from 1.2.15 to 1.2.17. - [Release notes](https://github.com/laurent-laporte-pro/deprecated/releases) - [Changelog](https://github.com/laurent-laporte-pro/deprecated/blob/master/CHANGELOG.rst) - [Commits](https://github.com/laurent-laporte-pro/deprecated/compare/v1.2.15...v1.2.17) --- updated-dependencies: - dependency-name: deprecated dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 956eb75ffb..4779c42af8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -295,20 +295,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.15" +version = "1.2.17" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, - {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, + {file = "Deprecated-1.2.17-py2.py3-none-any.whl", hash = "sha256:69cdc0a751671183f569495e2efb14baee4344b0236342eec29f1fde25d61818"}, + {file = "deprecated-1.2.17.tar.gz", hash = "sha256:0114a10f0bbb750b90b2c2296c90cf7e9eaeb0abb5cf06c80de2c60138de0a82"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools", "tox"] [[package]] name = "distlib" From fda99f82aa822380bbcd9eb7fcce240b2c4fe00c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 01:32:53 +0000 Subject: [PATCH 384/598] build(deps-dev): bump deprecated from 1.2.17 to 1.2.18 Bumps [deprecated](https://github.com/laurent-laporte-pro/deprecated) from 1.2.17 to 1.2.18. - [Release notes](https://github.com/laurent-laporte-pro/deprecated/releases) - [Changelog](https://github.com/laurent-laporte-pro/deprecated/blob/master/CHANGELOG.rst) - [Commits](https://github.com/laurent-laporte-pro/deprecated/compare/v1.2.17...v1.2.18) --- updated-dependencies: - dependency-name: deprecated dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4779c42af8..2da5e39cf8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -295,13 +295,13 @@ files = [ [[package]] name = "deprecated" -version = "1.2.17" +version = "1.2.18" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.17-py2.py3-none-any.whl", hash = "sha256:69cdc0a751671183f569495e2efb14baee4344b0236342eec29f1fde25d61818"}, - {file = "deprecated-1.2.17.tar.gz", hash = "sha256:0114a10f0bbb750b90b2c2296c90cf7e9eaeb0abb5cf06c80de2c60138de0a82"}, + {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, + {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, ] [package.dependencies] From 62f482e6187534d20030cd7cbb698c0cb4f55759 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 01:46:15 +0000 Subject: [PATCH 385/598] build(deps): bump argcomplete from 3.5.2 to 3.5.3 Bumps [argcomplete](https://github.com/kislyuk/argcomplete) from 3.5.2 to 3.5.3. - [Release notes](https://github.com/kislyuk/argcomplete/releases) - [Changelog](https://github.com/kislyuk/argcomplete/blob/main/Changes.rst) - [Commits](https://github.com/kislyuk/argcomplete/compare/v3.5.2...v3.5.3) --- updated-dependencies: - dependency-name: argcomplete dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2da5e39cf8..5698043093 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "argcomplete" -version = "3.5.2" +version = "3.5.3" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" files = [ - {file = "argcomplete-3.5.2-py3-none-any.whl", hash = "sha256:036d020d79048a5d525bc63880d7a4b8d1668566b8a76daf1144c0bbe0f63472"}, - {file = "argcomplete-3.5.2.tar.gz", hash = "sha256:23146ed7ac4403b70bd6026402468942ceba34a6732255b9edf5b7354f68a6bb"}, + {file = "argcomplete-3.5.3-py3-none-any.whl", hash = "sha256:2ab2c4a215c59fd6caaff41a869480a23e8f6a5f910b266c1808037f4e375b61"}, + {file = "argcomplete-3.5.3.tar.gz", hash = "sha256:c12bf50eded8aebb298c7b7da7a5ff3ee24dffd9f5281867dfe1424b58c55392"}, ] [package.extras] From f6db6a934597a08547201eb8952fd2c85f166d65 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 30 Jan 2025 10:02:18 +0000 Subject: [PATCH 386/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz___help.svg | 162 ++++----- docs/images/cli_help/cz_bump___help.svg | 350 +++++++++---------- docs/images/cli_help/cz_changelog___help.svg | 190 +++++----- docs/images/cli_help/cz_check___help.svg | 134 ++++--- docs/images/cli_help/cz_commit___help.svg | 110 +++--- 5 files changed, 467 insertions(+), 479 deletions(-) diff --git a/docs/images/cli_help/cz___help.svg b/docs/images/cli_help/cz___help.svg index 22a9e4d0e7..098e7df70d 100644 --- a/docs/images/cli_help/cz___help.svg +++ b/docs/images/cli_help/cz___help.svg @@ -19,133 +19,133 @@ font-weight: 700; } - .terminal-4198725382-matrix { + .terminal-2205183093-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4198725382-title { + .terminal-2205183093-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4198725382-r1 { fill: #c5c8c6 } -.terminal-4198725382-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-4198725382-r3 { fill: #d0b344 } -.terminal-4198725382-r4 { fill: #1984e9;text-decoration: underline; } -.terminal-4198725382-r5 { fill: #68a0b3;font-weight: bold } + .terminal-2205183093-r1 { fill: #c5c8c6 } +.terminal-2205183093-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-2205183093-r3 { fill: #d0b344 } +.terminal-2205183093-r4 { fill: #1984e9;text-decoration: underline; } +.terminal-2205183093-r5 { fill: #68a0b3;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -157,45 +157,45 @@ - + - - $ cz --help -usage: cz [-h][--config CONFIG][--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 -  --config 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 -                        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) - + + $ cz --help +usage: cz [-h][--config CONFIG][--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 +  --config CONFIG       the path of configuration file +  --debug               use debug mode +  -n, --name NAME       use the given commitizen (default: +                        cz_conventional_commits) +  -nr, --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 index 7af2aa8c27..4030b1ba90 100644 --- a/docs/images/cli_help/cz_bump___help.svg +++ b/docs/images/cli_help/cz_bump___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + - - $ 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 {pep440,semver,semver2}] -[--version-type {pep440,semver,semver2}] -[--build-metadata BUILD_METADATA][--get-next] -[MANUAL_VERSION] - -bump semantic version based on the git log - -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 {pep440,semver,semver2} -                        choose version scheme -  --version-type {pep440,semver,semver2} -                        Deprecated, use --version-scheme -  --build-metadata BUILD_METADATA -                        Add additional build-metadata to the version-number -  --get-next            Determine the next version and write to stdout - + + $ 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 {pep440,semver,semver2}] +[--version-type {pep440,semver,semver2}] +[--build-metadata BUILD_METADATA][--get-next] +[MANUAL_VERSION] + +bump semantic version based on the git log + +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, -pr {alpha,beta,rc} +                        choose type of prerelease +  --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, -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, -t TEMPLATE +                        changelog template file name (relative to the current +                        working directory) +  --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 {pep440,semver,semver2} +                        choose version scheme +  --version-type {pep440,semver,semver2} +                        Deprecated, use --version-scheme +  --build-metadata BUILD_METADATA +                        Add additional build-metadata to the version-number +  --get-next            Determine the next version and write to stdout + diff --git a/docs/images/cli_help/cz_changelog___help.svg b/docs/images/cli_help/cz_changelog___help.svg index 8cb3fcf2fe..1160ccf6cf 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + - - $ 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,semver2}] -[--export-template EXPORT_TEMPLATE][--template TEMPLATE] -[--extra EXTRA] - - -generate changelog (note that it will overwrite existing file) - -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,semver2} -                        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') - + + $ 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,semver2}] +[--export-template EXPORT_TEMPLATE][--template TEMPLATE] +[--extra EXTRA] + + +generate changelog (note that it will overwrite existing file) + +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,semver2} +                        choose version scheme +  --export-template EXPORT_TEMPLATE +                        Export the changelog template into this file instead +                        of rendering it +  --template, -t TEMPLATE +                        changelog template file name (relative to the current +                        working directory) +  --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 index 922a6458a6..690bfec684 100644 --- a/docs/images/cli_help/cz_check___help.svg +++ b/docs/images/cli_help/cz_check___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + - - $ 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 ...]] -[-l MESSAGE_LENGTH_LIMIT] - -validates that a commit message matches the commitizen schema - -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 -  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit - + + $ 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 ...]] +[-l MESSAGE_LENGTH_LIMIT] + +validates that a commit message matches the commitizen schema + +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 +                        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 +  -l, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit + diff --git a/docs/images/cli_help/cz_commit___help.svg b/docs/images/cli_help/cz_commit___help.svg index 0346c40588..5aea02232f 100644 --- a/docs/images/cli_help/cz_commit___help.svg +++ b/docs/images/cli_help/cz_commit___help.svg @@ -19,95 +19,95 @@ font-weight: 700; } - .terminal-1670560432-matrix { + .terminal-463778956-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1670560432-title { + .terminal-463778956-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1670560432-r1 { fill: #c5c8c6 } -.terminal-1670560432-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-1670560432-r3 { fill: #68a0b3;font-weight: bold } + .terminal-463778956-r1 { fill: #c5c8c6 } +.terminal-463778956-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-463778956-r3 { fill: #68a0b3;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -119,33 +119,33 @@ - + - - $ cz commit --help -usage: cz commit [-h][--retry][--no-retry][--dry-run] -[--write-message-to-file FILE_PATH][-s][-a][-e] -[-l MESSAGE_LENGTH_LIMIT][--] - -create new commit - -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. -  -e, --edit            edit the commit message before committing -  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit -  --                    Positional arguments separator (recommended) - + + $ cz commit --help +usage: cz commit [-h][--retry][--no-retry][--dry-run] +[--write-message-to-file FILE_PATH][-s][-a][-e] +[-l MESSAGE_LENGTH_LIMIT][--] + +create new commit + +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. +  -e, --edit            edit the commit message before committing +  -l, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit +  --                    Positional arguments separator (recommended) + From 646a9df524c887e4c043bbda03a4561df327c6ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 01:25:00 +0000 Subject: [PATCH 387/598] build(deps-dev): bump ruff from 0.8.5 to 0.9.3 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.8.5 to 0.9.3. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.8.5...0.9.3) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 40 ++++++++++++++++++++-------------------- pyproject.toml | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5698043093..aaf4e460a8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.8.5" +version = "0.9.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.8.5-py3-none-linux_armv6l.whl", hash = "sha256:5ad11a5e3868a73ca1fa4727fe7e33735ea78b416313f4368c504dbeb69c0f88"}, - {file = "ruff-0.8.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f69ab37771ea7e0715fead8624ec42996d101269a96e31f4d31be6fc33aa19b7"}, - {file = "ruff-0.8.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b5462d7804558ccff9c08fe8cbf6c14b7efe67404316696a2dde48297b1925bb"}, - {file = "ruff-0.8.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d56de7220a35607f9fe59f8a6d018e14504f7b71d784d980835e20fc0611cd50"}, - {file = "ruff-0.8.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9d99cf80b0429cbebf31cbbf6f24f05a29706f0437c40413d950e67e2d4faca4"}, - {file = "ruff-0.8.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b75ac29715ac60d554a049dbb0ef3b55259076181c3369d79466cb130eb5afd"}, - {file = "ruff-0.8.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c9d526a62c9eda211b38463528768fd0ada25dad524cb33c0e99fcff1c67b5dc"}, - {file = "ruff-0.8.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:587c5e95007612c26509f30acc506c874dab4c4abbacd0357400bd1aa799931b"}, - {file = "ruff-0.8.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:622b82bf3429ff0e346835ec213aec0a04d9730480cbffbb6ad9372014e31bbd"}, - {file = "ruff-0.8.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f99be814d77a5dac8a8957104bdd8c359e85c86b0ee0e38dca447cb1095f70fb"}, - {file = "ruff-0.8.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c01c048f9c3385e0fd7822ad0fd519afb282af9cf1778f3580e540629df89725"}, - {file = "ruff-0.8.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7512e8cb038db7f5db6aae0e24735ff9ea03bb0ed6ae2ce534e9baa23c1dc9ea"}, - {file = "ruff-0.8.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:762f113232acd5b768d6b875d16aad6b00082add40ec91c927f0673a8ec4ede8"}, - {file = "ruff-0.8.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:03a90200c5dfff49e4c967b405f27fdfa81594cbb7c5ff5609e42d7fe9680da5"}, - {file = "ruff-0.8.5-py3-none-win32.whl", hash = "sha256:8710ffd57bdaa6690cbf6ecff19884b8629ec2a2a2a2f783aa94b1cc795139ed"}, - {file = "ruff-0.8.5-py3-none-win_amd64.whl", hash = "sha256:4020d8bf8d3a32325c77af452a9976a9ad6455773bcb94991cf15bd66b347e47"}, - {file = "ruff-0.8.5-py3-none-win_arm64.whl", hash = "sha256:134ae019ef13e1b060ab7136e7828a6d83ea727ba123381307eb37c6bd5e01cb"}, - {file = "ruff-0.8.5.tar.gz", hash = "sha256:1098d36f69831f7ff2a1da3e6407d5fbd6dfa2559e4f74ff2d260c5588900317"}, + {file = "ruff-0.9.3-py3-none-linux_armv6l.whl", hash = "sha256:7f39b879064c7d9670197d91124a75d118d00b0990586549949aae80cdc16624"}, + {file = "ruff-0.9.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a187171e7c09efa4b4cc30ee5d0d55a8d6c5311b3e1b74ac5cb96cc89bafc43c"}, + {file = "ruff-0.9.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c59ab92f8e92d6725b7ded9d4a31be3ef42688a115c6d3da9457a5bda140e2b4"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc153c25e715be41bb228bc651c1e9b1a88d5c6e5ed0194fa0dfea02b026439"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:646909a1e25e0dc28fbc529eab8eb7bb583079628e8cbe738192853dbbe43af5"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a5a46e09355695fbdbb30ed9889d6cf1c61b77b700a9fafc21b41f097bfbba4"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c4bb09d2bbb394e3730d0918c00276e79b2de70ec2a5231cd4ebb51a57df9ba1"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96a87ec31dc1044d8c2da2ebbed1c456d9b561e7d087734336518181b26b3aa5"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb7554aca6f842645022fe2d301c264e6925baa708b392867b7a62645304df4"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabc332b7075a914ecea912cd1f3d4370489c8018f2c945a30bcc934e3bc06a6"}, + {file = "ruff-0.9.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:33866c3cc2a575cbd546f2cd02bdd466fed65118e4365ee538a3deffd6fcb730"}, + {file = "ruff-0.9.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:006e5de2621304c8810bcd2ee101587712fa93b4f955ed0985907a36c427e0c2"}, + {file = "ruff-0.9.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba6eea4459dbd6b1be4e6bfc766079fb9b8dd2e5a35aff6baee4d9b1514ea519"}, + {file = "ruff-0.9.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:90230a6b8055ad47d3325e9ee8f8a9ae7e273078a66401ac66df68943ced029b"}, + {file = "ruff-0.9.3-py3-none-win32.whl", hash = "sha256:eabe5eb2c19a42f4808c03b82bd313fc84d4e395133fb3fc1b1516170a31213c"}, + {file = "ruff-0.9.3-py3-none-win_amd64.whl", hash = "sha256:040ceb7f20791dfa0e78b4230ee9dce23da3b64dd5848e40e3bf3ab76468dcf4"}, + {file = "ruff-0.9.3-py3-none-win_arm64.whl", hash = "sha256:800d773f6d4d33b0a3c60e2c6ae8f4c202ea2de056365acfa519aa48acf28e0b"}, + {file = "ruff-0.9.3.tar.gz", hash = "sha256:8293f89985a090ebc3ed1064df31f3b4b56320cdfcec8b60d3295bddb955c22a"}, ] [[package]] @@ -1772,4 +1772,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9" -content-hash = "36ac305c62f5139da82126a1b3bc71f86320af1abab5c473b3c0d21c81e214bd" +content-hash = "ac79ae58b65962eac836910d2b1359591d1fd53c68afb354b4c549cdcdd4349c" diff --git a/pyproject.toml b/pyproject.toml index 094d6fca0b..8ee2cf8d58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,7 @@ pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" # linter -ruff = ">=0.5.0,<0.9.0" +ruff = ">=0.5.0,<0.10.0" pre-commit = ">=2.18,<5.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" From e6dcdbc13bfa22db73bf97ca0ac5860f4a252490 Mon Sep 17 00:00:00 2001 From: "Axel H." Date: Wed, 29 Jan 2025 20:04:12 +0100 Subject: [PATCH 388/598] style: fix formatting for `ruff>=0.9` --- commitizen/cli.py | 3 +-- commitizen/commands/bump.py | 7 +++---- .../conventional_commits.py | 4 +--- tests/commands/test_bump_command.py | 20 +++++++++---------- tests/commands/test_changelog_command.py | 2 +- tests/commands/test_check_command.py | 2 +- tests/commands/test_version_command.py | 2 +- tests/conftest.py | 8 +++----- tests/test_changelog.py | 6 +++--- tests/test_conf.py | 2 +- tests/test_cz_conventional_commits.py | 2 +- tests/test_git.py | 2 +- 12 files changed, 27 insertions(+), 33 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 2ee7d41eba..0b411cba60 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -71,8 +71,7 @@ def __call__( { "name": ["--template", "-t"], "help": ( - "changelog template file name " - "(relative to the current working directory)" + "changelog template file name (relative to the current working directory)" ), }, { diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 1f98c19954..1b274061cb 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -252,7 +252,7 @@ def __call__(self) -> None: # noqa: C901 # Unless we previously had a prerelease. if not commits and not current_version.is_prerelease: raise NoCommitsFoundError( - "[NO_COMMITS_FOUND]\n" "No new commits found." + "[NO_COMMITS_FOUND]\nNo new commits found." ) increment = self.find_increment(commits) @@ -296,7 +296,7 @@ def __call__(self) -> None: # noqa: C901 raise GetNextExit() # Report found information - information = f"{message}\n" f"tag to create: {new_tag_version}\n" + information = f"{message}\ntag to create: {new_tag_version}\n" if increment: information += f"increment detected: {increment}\n" @@ -310,8 +310,7 @@ def __call__(self) -> None: # noqa: C901 if increment is None and new_tag_version == current_tag_version: raise NoneIncrementExit( - "[NO_COMMITS_TO_BUMP]\n" - "The commits found are not eligible to be bumped" + "[NO_COMMITS_TO_BUMP]\nThe commits found are not eligible to be bumped" ) files: list[str] = [] diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index dcfd7bab89..c7b88258cb 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -86,9 +86,7 @@ def questions(self) -> Questions: }, { "value": "test", - "name": ( - "test: Adding missing or correcting " "existing tests" - ), + "name": ("test: Adding missing or correcting existing tests"), "key": "t", }, { diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 8acb5143c7..728a424107 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -102,7 +102,7 @@ def test_bump_minor_increment_annotated_config_file( ): tmp_commitizen_cfg_file = tmp_commitizen_project.join("pyproject.toml") tmp_commitizen_cfg_file.write( - f"{tmp_commitizen_cfg_file.read()}\n" f"annotated_tag = 1" + f"{tmp_commitizen_cfg_file.read()}\nannotated_tag = 1" ) create_file_and_commit(commit_msg) testargs = ["cz", "bump", "--yes"] @@ -121,7 +121,7 @@ def test_bump_minor_increment_signed_config_file( commit_msg, mocker: MockFixture, tmp_commitizen_project_with_gpg ): tmp_commitizen_cfg_file = tmp_commitizen_project_with_gpg.join("pyproject.toml") - tmp_commitizen_cfg_file.write(f"{tmp_commitizen_cfg_file.read()}\n" f"gpg_sign = 1") + tmp_commitizen_cfg_file.write(f"{tmp_commitizen_cfg_file.read()}\ngpg_sign = 1") create_file_and_commit(commit_msg) testargs = ["cz", "bump", "--yes"] mocker.patch.object(sys, "argv", testargs) @@ -383,7 +383,7 @@ 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", encoding="utf-8") as f: - f.write("#!/usr/bin/env bash\n" 'echo "0.1.0"') + f.write('#!/usr/bin/env bash\necho "0.1.0"') cmd.run("chmod +x .git/hooks/pre-commit") # MINOR @@ -402,7 +402,7 @@ def test_bump_on_git_with_hooks_no_verify_disabled(mocker: MockFixture): def test_bump_tag_exists_raises_exception(mocker: MockFixture): cmd.run("mkdir .git/hooks") with open(".git/hooks/post-commit", "w", encoding="utf-8") as f: - f.write("#!/usr/bin/env bash\n" "exit 9") + f.write("#!/usr/bin/env bash\nexit 9") cmd.run("chmod +x .git/hooks/post-commit") # MINOR @@ -421,7 +421,7 @@ def test_bump_tag_exists_raises_exception(mocker: MockFixture): def test_bump_on_git_with_hooks_no_verify_enabled(mocker: MockFixture): cmd.run("mkdir .git/hooks") with open(".git/hooks/pre-commit", "w", encoding="utf-8") as f: - f.write("#!/usr/bin/env bash\n" 'echo "0.1.0"') + f.write('#!/usr/bin/env bash\necho "0.1.0"') cmd.run("chmod +x .git/hooks/pre-commit") # MINOR @@ -478,7 +478,7 @@ def test_bump_when_no_new_commit(mocker: MockFixture): with pytest.raises(NoCommitsFoundError) as excinfo: cli.main() - expected_error_message = "[NO_COMMITS_FOUND]\n" "No new commits found." + expected_error_message = "[NO_COMMITS_FOUND]\nNo new commits found." assert expected_error_message in str(excinfo.value) @@ -710,7 +710,7 @@ def test_prevent_prerelease_when_no_increment_detected(mocker: MockFixture, caps cli.main() expected_error_message = ( - "[NO_COMMITS_FOUND]\n" "No commits found to generate a pre-release." + "[NO_COMMITS_FOUND]\nNo commits found to generate a pre-release." ) assert expected_error_message in str(excinfo.value) @@ -862,7 +862,7 @@ def test_bump_changelog_command_commits_untracked_changelog_and_version_files( mode="a", encoding="utf-8", ) as commitizen_config: - commitizen_config.write(f"version_files = [\n" f"'{version_regex}'\n]") + commitizen_config.write(f"version_files = [\n'{version_regex}'\n]") with tmp_commitizen_project.join(version_filepath).open( mode="a+", encoding="utf-8" @@ -917,7 +917,7 @@ def test_bump_invalid_manual_version_raises_exception(mocker, manual_version): cli.main() expected_error_message = ( - "[INVALID_MANUAL_VERSION]\n" f"Invalid manual version: '{manual_version}'" + f"[INVALID_MANUAL_VERSION]\nInvalid manual version: '{manual_version}'" ) assert expected_error_message in str(excinfo.value) @@ -1425,7 +1425,7 @@ def test_bump_changelog_contains_increment_only(mocker, tmp_commitizen_project, project_root = Path(tmp_commitizen_project) tmp_commitizen_cfg_file = project_root / "pyproject.toml" tmp_commitizen_cfg_file.write_text( - "[tool.commitizen]\n" 'version="1.0.0"\n' "update_changelog_on_bump = true\n" + '[tool.commitizen]\nversion="1.0.0"\nupdate_changelog_on_bump = true\n' ) tmp_changelog_file = project_root / "CHANGELOG.md" tmp_changelog_file.write_text("## v1.0.0") diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index bc0d6c6a28..a6ff7db2d8 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -1295,7 +1295,7 @@ def test_changelog_prerelease_rev_with_use_scheme_semver( mocker.patch("commitizen.git.GitTag.date", "2022-02-13") with open(config_path, "a") as f: - f.write('tag_format = "$version"\n' 'version_scheme = "semver"') + f.write('tag_format = "$version"\nversion_scheme = "semver"') # create commit and tag create_file_and_commit("feat: new file") diff --git a/tests/commands/test_check_command.py b/tests/commands/test_check_command.py index 57bfe3f10a..f1db446190 100644 --- a/tests/commands/test_check_command.py +++ b/tests/commands/test_check_command.py @@ -238,7 +238,7 @@ def test_check_a_range_of_failed_git_commits(config, mocker: MockFixture): ill_formated_commits_msgs = [ "First commit does not follow rule", "Second commit does not follow rule", - ("Third commit does not follow rule\n" "Ill-formatted commit with body"), + ("Third commit does not follow rule\nIll-formatted commit with body"), ] mocker.patch( "commitizen.git.get_commits", diff --git a/tests/commands/test_version_command.py b/tests/commands/test_version_command.py index f7d38c202d..927cf55f25 100644 --- a/tests/commands/test_version_command.py +++ b/tests/commands/test_version_command.py @@ -61,7 +61,7 @@ def test_version_for_showing_both_versions(config, capsys): )() captured = capsys.readouterr() expected_out = ( - f"Installed Commitizen Version: {__version__}\n" f"Project Version: v0.0.1" + f"Installed Commitizen Version: {__version__}\nProject Version: v0.0.1" ) assert expected_out in captured.out diff --git a/tests/conftest.py b/tests/conftest.py index 1e6bc15f0c..3d88f19b12 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -69,7 +69,7 @@ def tmp_git_project(tmpdir): @pytest.fixture(scope="function") def tmp_commitizen_project(tmp_git_project): tmp_commitizen_cfg_file = tmp_git_project.join("pyproject.toml") - tmp_commitizen_cfg_file.write("[tool.commitizen]\n" 'version="0.1.0"\n') + tmp_commitizen_cfg_file.write('[tool.commitizen]\nversion="0.1.0"\n') yield tmp_git_project @@ -83,9 +83,7 @@ def _initial( ): with tmp_git_project.as_cwd(): tmp_commitizen_cfg_file = tmp_git_project.join("pyproject.toml") - tmp_commitizen_cfg_file.write( - f"[tool.commitizen]\n" f'version="{version}"\n' - ) + tmp_commitizen_cfg_file.write(f'[tool.commitizen]\nversion="{version}"\n') tmp_version_file = tmp_git_project.join("__version__.py") tmp_version_file.write(version) tmp_commitizen_cfg_file = tmp_git_project.join("pyproject.toml") @@ -251,7 +249,7 @@ def changelog_format( if "tmp_commitizen_project" in request.fixturenames: tmp_commitizen_project = request.getfixturevalue("tmp_commitizen_project") pyproject = tmp_commitizen_project / "pyproject.toml" - pyproject.write(f"{pyproject.read()}\n" f'changelog_format = "{format}"\n') + pyproject.write(f'{pyproject.read()}\nchangelog_format = "{format}"\n') return get_changelog_format(config) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 20d59488d3..76ee80600b 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1413,9 +1413,9 @@ def changelog_message_builder_hook(message: dict, commit: git.GitCommit): for no, line in enumerate(result.splitlines()): if (line := line.strip()) and (match := RE_HEADER.match(line)): change_type = match.group("type") - assert ( - change_type == "overridden" - ), f"Line {no}: type {change_type} should have been overridden" + assert change_type == "overridden", ( + f"Line {no}: type {change_type} should have been overridden" + ) def test_render_changelog_with_changelog_release_hook( diff --git a/tests/test_conf.py b/tests/test_conf.py index 1cbbc57aca..3e0a44c7dd 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -235,7 +235,7 @@ def test_init_empty_config_content(self, tmpdir, config_file, exception_string): def test_init_empty_config_content_with_existing_content( self, tmpdir, config_file, exception_string ): - existing_content = "[tool.black]\n" "line-length = 88\n" + existing_content = "[tool.black]\nline-length = 88\n" path = tmpdir.mkdir("commitizen").join(config_file) path.write(existing_content) diff --git a/tests/test_cz_conventional_commits.py b/tests/test_cz_conventional_commits.py index 04d0522174..6d4e0f7435 100644 --- a/tests/test_cz_conventional_commits.py +++ b/tests/test_cz_conventional_commits.py @@ -7,7 +7,7 @@ ) from commitizen.cz.exceptions import AnswerRequiredError -valid_scopes = ["", "simple", "dash-separated", "camelCase" "UPPERCASE"] +valid_scopes = ["", "simple", "dash-separated", "camelCaseUPPERCASE"] scopes_transformations = [["with spaces", "with-spaces"], [None, ""]] diff --git a/tests/test_git.py b/tests/test_git.py index 8bf995e8a8..f929ba6a44 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -84,7 +84,7 @@ def test_get_reachable_tags_with_commits( def test_get_tag_names(mocker: MockFixture): - tag_str = "v1.0.0\n" "v0.5.0\n" "v0.0.1\n" + tag_str = "v1.0.0\nv0.5.0\nv0.0.1\n" mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=tag_str)) assert git.get_tag_names() == ["v1.0.0", "v0.5.0", "v0.0.1"] From b9febf5d223e01171e43d110b0e93b3e4c5543b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2025 01:53:27 +0000 Subject: [PATCH 389/598] build(deps-dev): bump ruff from 0.9.3 to 0.9.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.9.3 to 0.9.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.9.3...0.9.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index aaf4e460a8..73c2b9f618 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,29 +1425,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.9.3" +version = "0.9.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.9.3-py3-none-linux_armv6l.whl", hash = "sha256:7f39b879064c7d9670197d91124a75d118d00b0990586549949aae80cdc16624"}, - {file = "ruff-0.9.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a187171e7c09efa4b4cc30ee5d0d55a8d6c5311b3e1b74ac5cb96cc89bafc43c"}, - {file = "ruff-0.9.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c59ab92f8e92d6725b7ded9d4a31be3ef42688a115c6d3da9457a5bda140e2b4"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc153c25e715be41bb228bc651c1e9b1a88d5c6e5ed0194fa0dfea02b026439"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:646909a1e25e0dc28fbc529eab8eb7bb583079628e8cbe738192853dbbe43af5"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a5a46e09355695fbdbb30ed9889d6cf1c61b77b700a9fafc21b41f097bfbba4"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c4bb09d2bbb394e3730d0918c00276e79b2de70ec2a5231cd4ebb51a57df9ba1"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96a87ec31dc1044d8c2da2ebbed1c456d9b561e7d087734336518181b26b3aa5"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb7554aca6f842645022fe2d301c264e6925baa708b392867b7a62645304df4"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabc332b7075a914ecea912cd1f3d4370489c8018f2c945a30bcc934e3bc06a6"}, - {file = "ruff-0.9.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:33866c3cc2a575cbd546f2cd02bdd466fed65118e4365ee538a3deffd6fcb730"}, - {file = "ruff-0.9.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:006e5de2621304c8810bcd2ee101587712fa93b4f955ed0985907a36c427e0c2"}, - {file = "ruff-0.9.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba6eea4459dbd6b1be4e6bfc766079fb9b8dd2e5a35aff6baee4d9b1514ea519"}, - {file = "ruff-0.9.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:90230a6b8055ad47d3325e9ee8f8a9ae7e273078a66401ac66df68943ced029b"}, - {file = "ruff-0.9.3-py3-none-win32.whl", hash = "sha256:eabe5eb2c19a42f4808c03b82bd313fc84d4e395133fb3fc1b1516170a31213c"}, - {file = "ruff-0.9.3-py3-none-win_amd64.whl", hash = "sha256:040ceb7f20791dfa0e78b4230ee9dce23da3b64dd5848e40e3bf3ab76468dcf4"}, - {file = "ruff-0.9.3-py3-none-win_arm64.whl", hash = "sha256:800d773f6d4d33b0a3c60e2c6ae8f4c202ea2de056365acfa519aa48acf28e0b"}, - {file = "ruff-0.9.3.tar.gz", hash = "sha256:8293f89985a090ebc3ed1064df31f3b4b56320cdfcec8b60d3295bddb955c22a"}, + {file = "ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706"}, + {file = "ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf"}, + {file = "ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0"}, + {file = "ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402"}, + {file = "ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e"}, + {file = "ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41"}, + {file = "ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7"}, ] [[package]] From 54b4fdac5dda187875e5fee97f0100e26f8fe4df Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 30 Jan 2025 22:25:16 +0800 Subject: [PATCH 390/598] build(poetry): migrate to poetry 2.0 and follow pep 621 --- poetry.lock | 99 +++++++++++++++++++++++++++++++++-- pyproject.toml | 136 +++++++++++++++++++++++++++---------------------- 2 files changed, 169 insertions(+), 66 deletions(-) diff --git a/poetry.lock b/poetry.lock index 73c2b9f618..ebdf60ddda 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. [[package]] name = "argcomplete" @@ -6,6 +6,7 @@ version = "3.5.3" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "argcomplete-3.5.3-py3-none-any.whl", hash = "sha256:2ab2c4a215c59fd6caaff41a869480a23e8f6a5f910b266c1808037f4e375b61"}, {file = "argcomplete-3.5.3.tar.gz", hash = "sha256:c12bf50eded8aebb298c7b7da7a5ff3ee24dffd9f5281867dfe1424b58c55392"}, @@ -20,6 +21,7 @@ version = "2.4.1" description = "Annotate AST trees with source code positions" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, @@ -38,6 +40,7 @@ version = "2.16.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, @@ -52,6 +55,7 @@ version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, @@ -63,6 +67,7 @@ version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, @@ -74,6 +79,7 @@ version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, @@ -175,6 +181,7 @@ version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, @@ -189,6 +196,7 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main", "dev"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -200,6 +208,7 @@ version = "7.6.8" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, @@ -277,6 +286,7 @@ version = "0.6.2" description = "Minimal, easy-to-use, declarative cli tool" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed"}, {file = "decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f"}, @@ -288,6 +298,7 @@ version = "5.1.1" description = "Decorators for Humans" optional = false python-versions = ">=3.5" +groups = ["dev"] files = [ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, @@ -299,6 +310,7 @@ version = "1.2.18" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +groups = ["dev"] files = [ {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, @@ -316,6 +328,7 @@ version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, @@ -327,6 +340,8 @@ version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" +groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, @@ -341,6 +356,7 @@ version = "2.1.1" description = "execnet: rapid multi-Python deployment" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, @@ -355,6 +371,7 @@ version = "2.1.0" description = "Get the currently executing AST node of a frame, and other information" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"}, {file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"}, @@ -369,6 +386,7 @@ version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, @@ -385,6 +403,7 @@ version = "1.5.1" description = "Let your Python tests travel through time" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"}, {file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"}, @@ -399,6 +418,7 @@ version = "2.1.0" description = "Copy your docs directly to the gh-pages branch." optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, @@ -416,6 +436,7 @@ version = "2.6.3" description = "File identification library for Python" optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "identify-2.6.3-py2.py3-none-any.whl", hash = "sha256:9edba65473324c2ea9684b1f944fe3191db3345e50b6d04571d10ed164f8d7bd"}, {file = "identify-2.6.3.tar.gz", hash = "sha256:62f5dae9b5fef52c84cc188514e9ea4f3f636b1d8799ab5ebc475471f9e47a02"}, @@ -430,6 +451,7 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -444,6 +466,8 @@ version = "8.6.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" +groups = ["main", "dev"] +markers = "python_version < \"3.10\"" files = [ {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, @@ -467,6 +491,7 @@ version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -478,6 +503,7 @@ version = "8.18.1" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, @@ -515,6 +541,7 @@ version = "0.19.2" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, @@ -534,6 +561,7 @@ version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" +groups = ["main", "dev"] files = [ {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, @@ -551,6 +579,7 @@ version = "3.7" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, @@ -569,6 +598,7 @@ version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" +groups = ["dev"] 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"}, @@ -593,6 +623,7 @@ version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" +groups = ["main", "dev"] files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, @@ -663,6 +694,7 @@ version = "0.1.7" description = "Inline Matplotlib backend for Jupyter" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, @@ -677,6 +709,7 @@ version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -688,6 +721,7 @@ version = "1.3.4" description = "A deep merge function for 🐍." optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, @@ -699,6 +733,7 @@ version = "1.6.1" description = "Project documentation with Markdown." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"}, {file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"}, @@ -730,6 +765,7 @@ version = "0.2.0" description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, @@ -747,6 +783,7 @@ version = "9.5.50" description = "Documentation that simply works" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "mkdocs_material-9.5.50-py3-none-any.whl", hash = "sha256:f24100f234741f4d423a9d672a909d859668a4f404796be3cf035f10d6050385"}, {file = "mkdocs_material-9.5.50.tar.gz", hash = "sha256:ae5fe16f3d7c9ccd05bb6916a7da7420cf99a9ce5e33debd9d40403a090d5825"}, @@ -776,6 +813,7 @@ version = "1.3.1" description = "Extension pack for Python Markdown and MkDocs Material." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, @@ -787,6 +825,7 @@ version = "1.14.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, @@ -846,6 +885,7 @@ version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" +groups = ["dev"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -857,6 +897,7 @@ version = "1.9.1" description = "Node.js virtual environment builder" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] files = [ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, @@ -868,6 +909,7 @@ version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -879,6 +921,7 @@ version = "0.5.7" description = "Divides large result sets into pages for easier browsing" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"}, {file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"}, @@ -894,6 +937,7 @@ version = "0.8.4" description = "A Python Parser" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, @@ -909,6 +953,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -920,6 +965,8 @@ version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" +groups = ["dev"] +markers = "sys_platform != \"win32\"" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, @@ -934,6 +981,7 @@ version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -950,6 +998,7 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -965,6 +1014,7 @@ version = "4.1.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b"}, {file = "pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4"}, @@ -983,6 +1033,7 @@ version = "3.0.48" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" +groups = ["main", "dev"] files = [ {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, @@ -997,6 +1048,8 @@ version = "0.7.0" description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" +groups = ["dev"] +markers = "sys_platform != \"win32\"" files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, @@ -1008,6 +1061,7 @@ version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, @@ -1022,6 +1076,7 @@ version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, @@ -1036,6 +1091,7 @@ version = "10.12" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77"}, {file = "pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7"}, @@ -1054,6 +1110,7 @@ version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, @@ -1076,6 +1133,7 @@ version = "6.0.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, @@ -1094,6 +1152,7 @@ version = "1.5.0" description = "pytest plugin for test data directories and files" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest-datadir-1.5.0.tar.gz", hash = "sha256:1617ed92f9afda0c877e4eac91904b5f779d24ba8f5e438752e3ae39d8d2ee3f"}, {file = "pytest_datadir-1.5.0-py3-none-any.whl", hash = "sha256:34adf361bcc7b37961bbc1dfa8d25a4829e778bab461703c38a5c50ca9c36dc8"}, @@ -1108,6 +1167,7 @@ version = "0.4.9" description = "Pytest plugin providing a fixture interface for spulec/freezegun" optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "pytest_freezer-0.4.9-py3-none-any.whl", hash = "sha256:8b6c50523b7d4aec4590b52bfa5ff766d772ce506e2bf4846c88041ea9ccae59"}, {file = "pytest_freezer-0.4.9.tar.gz", hash = "sha256:21bf16bc9cc46bf98f94382c4b5c3c389be7056ff0be33029111ae11b3f1c82a"}, @@ -1123,6 +1183,7 @@ version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, @@ -1140,6 +1201,7 @@ version = "2.7.0" description = "Easy to use fixtures to write regression tests." optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "pytest_regressions-2.7.0-py3-none-any.whl", hash = "sha256:69f5e3f03493cf0ef84d96d23e50a546617c198b1d7746f2e2b9e441cbab4847"}, {file = "pytest_regressions-2.7.0.tar.gz", hash = "sha256:4c30064e0923929012c94f5d6f35205be06fd8709c7f0dba0228e05c460af05e"}, @@ -1162,6 +1224,7 @@ version = "3.6.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, @@ -1182,6 +1245,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["dev"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -1196,6 +1260,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -1258,6 +1323,7 @@ version = "0.1" description = "A custom YAML tag for referencing environment variables in YAML files. " optional = false python-versions = ">=3.6" +groups = ["dev"] files = [ {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, @@ -1272,6 +1338,7 @@ version = "2.1.0" description = "Python library to build pretty command line user prompts ⭐️" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "questionary-2.1.0-py3-none-any.whl", hash = "sha256:44174d237b68bc828e4878c763a9ad6790ee61990e0ae72927694ead57bab8ec"}, {file = "questionary-2.1.0.tar.gz", hash = "sha256:6302cdd645b19667d8f6e6634774e9538bfcd1aad9be287e743d96cacaf95587"}, @@ -1286,6 +1353,7 @@ version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, @@ -1389,6 +1457,7 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -1410,6 +1479,7 @@ version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, @@ -1429,6 +1499,7 @@ version = "0.9.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706"}, {file = "ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf"}, @@ -1456,6 +1527,7 @@ version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +groups = ["dev"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -1467,6 +1539,7 @@ version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, @@ -1486,6 +1559,7 @@ version = "2.5.0" description = "ANSI color formatting for output in terminal" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8"}, {file = "termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f"}, @@ -1500,6 +1574,8 @@ version = "2.1.0" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" +groups = ["dev"] +markers = "python_full_version <= \"3.11.0a6\"" files = [ {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, @@ -1511,6 +1587,7 @@ version = "0.13.2" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, @@ -1522,6 +1599,7 @@ version = "5.14.3" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, @@ -1537,6 +1615,7 @@ version = "1.2.15.20241117" description = "Typing stubs for Deprecated" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types-Deprecated-1.2.15.20241117.tar.gz", hash = "sha256:924002c8b7fddec51ba4949788a702411a2e3636cd9b2a33abd8ee119701d77e"}, {file = "types_Deprecated-1.2.15.20241117-py3-none-any.whl", hash = "sha256:a0cc5e39f769fc54089fd8e005416b55d74aa03f6964d2ed1a0b0b2e28751884"}, @@ -1548,6 +1627,7 @@ version = "2.9.0.20241206" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, @@ -1559,6 +1639,7 @@ version = "6.0.12.20241230" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6"}, {file = "types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c"}, @@ -1570,6 +1651,7 @@ version = "0.1.1" description = "Typing stubs for termcolor" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "types-termcolor-0.1.1.tar.gz", hash = "sha256:4d9e09ce7f3267985f5280b22e25790c98cb64628b6466e1fb915dbb52ad7136"}, {file = "types_termcolor-0.1.1-py2.py3-none-any.whl", hash = "sha256:3694c312e32f71fdc0f469c334ea21645f3130d90c93cd53bcb06b1233e174d5"}, @@ -1581,10 +1663,12 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main", "dev"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +markers = {main = "python_version < \"3.11\""} [[package]] name = "urllib3" @@ -1592,6 +1676,7 @@ version = "2.2.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, @@ -1609,6 +1694,7 @@ version = "20.27.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, @@ -1629,6 +1715,7 @@ version = "6.0.0" description = "Filesystem events monitoring" optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"}, {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"}, @@ -1671,6 +1758,7 @@ version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" +groups = ["main", "dev"] files = [ {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, @@ -1682,6 +1770,7 @@ version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, @@ -1756,6 +1845,8 @@ version = "3.21.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" +groups = ["main", "dev"] +markers = "python_version < \"3.10\"" files = [ {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, @@ -1770,6 +1861,6 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", type = ["pytest-mypy"] [metadata] -lock-version = "2.0" -python-versions = ">=3.9" -content-hash = "ac79ae58b65962eac836910d2b1359591d1fd53c68afb354b4c549cdcdd4349c" +lock-version = "2.1" +python-versions = ">=3.9,<4.0" +content-hash = "0ba0fceb54fee21c1f4b61a80f1e2b5f0d0eff4ac688f22a97f274d7da9a598e" diff --git a/pyproject.toml b/pyproject.toml index 8ee2cf8d58..3609f7ba52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,21 +1,28 @@ -[tool.commitizen] -version = "4.1.1" -tag_format = "v$version" -version_files = [ - "pyproject.toml:version", - "commitizen/__version__.py", - ".pre-commit-config.yaml:rev:.+Commitizen", -] - -[tool.poetry] +[project] name = "commitizen" version = "4.1.1" description = "Python commitizen client tool" -authors = ["Santiago Fraire "] -license = "MIT" -keywords = ["commitizen", "conventional", "commits", "git"] +authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] +license = { text = "LICENSE" } readme = "docs/README.md" -homepage = "https://github.com/commitizen-tools/commitizen" +requires-python = ">=3.9,<4.0" +dependencies = [ + "questionary (>=2.0,<3.0)", + "decli (>=0.6.0,<1.0)", + "colorama (>=0.4.1,<1.0)", + "termcolor (>=1.1,<3)", + "packaging>=19", + "tomlkit (>=0.5.3,<1.0.0)", + "jinja2>=2.10.3", + "pyyaml>=3.08", + "argcomplete >=1.12.1,<3.6", + "typing-extensions (>=4.0.1,<5.0.0) ; python_version < '3.11'", + "charset-normalizer (>=2.1.0,<4)", + # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility + "importlib_metadata (>=8.0.0,<9) ; python_version < '3.10'", + +] +keywords = ["commitizen", "conventional", "commits", "git"] # See also: https://pypi.org/classifiers/ classifiers = [ "Development Status :: 5 - Production/Stable", @@ -32,23 +39,60 @@ classifiers = [ "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", ] -packages = [{ include = "commitizen" }, { include = "commitizen/py.typed" }] -[tool.poetry.dependencies] -python = ">=3.9" -questionary = "^2.0" -decli = "^0.6.0" -colorama = "^0.4.1" -termcolor = ">= 1.1, < 3" -packaging = ">=19" -tomlkit = ">=0.5.3,<1.0.0" -jinja2 = ">=2.10.3" -pyyaml = ">=3.08" -argcomplete = ">=1.12.1,<3.6" -typing-extensions = { version = "^4.0.1", python = "<3.11" } -charset-normalizer = ">=2.1.0,<4" -# Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility -importlib_metadata = { version = ">=8.0.0,<9", python = "<3.10" } +[project.urls] +Homepage = "https://github.com/commitizen-tools/commitizen" +Documentation = "https://commitizen-tools.github.io/commitizen/" +Repository = "https://github.com/commitizen-tools/commitizen" +Issues = "https://github.com/commitizen-tools/commitizen/issues" +Changelog = "https://github.com/commitizen-tools/commitizen/blob/master/CHANGELOG.md" + +[project.scripts] +cz = "commitizen.cli:main" +git-cz = "commitizen.cli:main" + +[project.entry-points."commitizen.plugin"] +cz_conventional_commits = "commitizen.cz.conventional_commits:ConventionalCommitsCz" +cz_jira = "commitizen.cz.jira:JiraSmartCz" +cz_customize = "commitizen.cz.customize:CustomizeCommitsCz" + +[project.entry-points."commitizen.changelog_format"] +markdown = "commitizen.changelog_formats.markdown:Markdown" +asciidoc = "commitizen.changelog_formats.asciidoc:AsciiDoc" +textile = "commitizen.changelog_formats.textile:Textile" +restructuredtext = "commitizen.changelog_formats.restructuredtext:RestructuredText" + +[project.entry-points."commitizen.provider"] +cargo = "commitizen.providers:CargoProvider" +commitizen = "commitizen.providers:CommitizenProvider" +composer = "commitizen.providers:ComposerProvider" +npm = "commitizen.providers:NpmProvider" +pep621 = "commitizen.providers:Pep621Provider" +poetry = "commitizen.providers:PoetryProvider" +scm = "commitizen.providers:ScmProvider" + +[project.entry-points."commitizen.scheme"] +pep440 = "commitizen.version_schemes:Pep440" +semver = "commitizen.version_schemes:SemVer" +semver2 = "commitizen.version_schemes:SemVer2" + +[build-system] +requires = ["poetry-core>=2.0"] +build-backend = "poetry.core.masonry.api" + + +[tool.commitizen] +version = "4.1.1" +tag_format = "v$version" +version_files = [ + "pyproject.toml:version", + "commitizen/__version__.py", + ".pre-commit-config.yaml:rev:.+Commitizen", +] + + +[tool.poetry] +packages = [{ include = "commitizen" }, { include = "commitizen/py.typed" }] [tool.poetry.group.dev.dependencies] # dev tool @@ -75,35 +119,6 @@ types-python-dateutil = "^2.8.19.13" rich = "^13.7.1" -[tool.poetry.scripts] -cz = "commitizen.cli:main" -git-cz = "commitizen.cli:main" - -[tool.poetry.plugins."commitizen.plugin"] -cz_conventional_commits = "commitizen.cz.conventional_commits:ConventionalCommitsCz" -cz_jira = "commitizen.cz.jira:JiraSmartCz" -cz_customize = "commitizen.cz.customize:CustomizeCommitsCz" - -[tool.poetry.plugins."commitizen.changelog_format"] -markdown = "commitizen.changelog_formats.markdown:Markdown" -asciidoc = "commitizen.changelog_formats.asciidoc:AsciiDoc" -textile = "commitizen.changelog_formats.textile:Textile" -restructuredtext = "commitizen.changelog_formats.restructuredtext:RestructuredText" - -[tool.poetry.plugins."commitizen.provider"] -cargo = "commitizen.providers:CargoProvider" -commitizen = "commitizen.providers:CommitizenProvider" -composer = "commitizen.providers:ComposerProvider" -npm = "commitizen.providers:NpmProvider" -pep621 = "commitizen.providers:Pep621Provider" -poetry = "commitizen.providers:PoetryProvider" -scm = "commitizen.providers:ScmProvider" - -[tool.poetry.plugins."commitizen.scheme"] -pep440 = "commitizen.version_schemes:Pep440" -semver = "commitizen.version_schemes:SemVer" -semver2 = "commitizen.version_schemes:SemVer2" - [tool.coverage] [tool.coverage.report] show_missing = true @@ -133,9 +148,6 @@ omit = [ '*/tests/*', ] -[build-system] -requires = ["poetry_core>=1.0.0"] -build-backend = "poetry.core.masonry.api" [tool.pytest.ini_options] addopts = "--strict-markers" From 949a9e5b364d227a58843a7a9b73336b545dc4e9 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 30 Jan 2025 22:31:32 +0800 Subject: [PATCH 391/598] build(poetry): group dependencies --- poetry.lock | 136 ++++++++++++++++++++++++------------------------- pyproject.toml | 19 ++++--- 2 files changed, 80 insertions(+), 75 deletions(-) diff --git a/poetry.lock b/poetry.lock index ebdf60ddda..723dceddd9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -40,7 +40,7 @@ version = "2.16.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, @@ -55,7 +55,7 @@ version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, @@ -67,7 +67,7 @@ version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["linters"] files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, @@ -79,7 +79,7 @@ version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" -groups = ["main", "dev"] +groups = ["main", "documentation"] files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, @@ -181,7 +181,7 @@ version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, @@ -196,7 +196,7 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main", "dev"] +groups = ["main", "dev", "documentation", "test"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -208,7 +208,7 @@ version = "7.6.8" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" -groups = ["dev"] +groups = ["test"] files = [ {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, @@ -310,7 +310,7 @@ version = "1.2.18" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -groups = ["dev"] +groups = ["test"] files = [ {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, @@ -328,7 +328,7 @@ version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" -groups = ["dev"] +groups = ["linters"] files = [ {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, @@ -340,7 +340,7 @@ version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["dev", "test"] markers = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, @@ -356,7 +356,7 @@ version = "2.1.1" description = "execnet: rapid multi-Python deployment" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["test"] files = [ {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, @@ -386,7 +386,7 @@ version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["linters"] files = [ {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, @@ -403,7 +403,7 @@ version = "1.5.1" description = "Let your Python tests travel through time" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["test"] files = [ {file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"}, {file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"}, @@ -418,7 +418,7 @@ version = "2.1.0" description = "Copy your docs directly to the gh-pages branch." optional = false python-versions = "*" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, @@ -436,7 +436,7 @@ version = "2.6.3" description = "File identification library for Python" optional = false python-versions = ">=3.9" -groups = ["dev"] +groups = ["linters"] files = [ {file = "identify-2.6.3-py2.py3-none-any.whl", hash = "sha256:9edba65473324c2ea9684b1f944fe3191db3345e50b6d04571d10ed164f8d7bd"}, {file = "identify-2.6.3.tar.gz", hash = "sha256:62f5dae9b5fef52c84cc188514e9ea4f3f636b1d8799ab5ebc475471f9e47a02"}, @@ -451,7 +451,7 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -466,7 +466,7 @@ version = "8.6.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" -groups = ["main", "dev"] +groups = ["main", "documentation"] markers = "python_version < \"3.10\"" files = [ {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, @@ -491,7 +491,7 @@ version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["test"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -561,7 +561,7 @@ version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" -groups = ["main", "dev"] +groups = ["main", "documentation"] files = [ {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, @@ -579,7 +579,7 @@ version = "3.7" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, @@ -598,7 +598,7 @@ version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["script"] 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"}, @@ -623,7 +623,7 @@ version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" -groups = ["main", "dev"] +groups = ["main", "documentation"] files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, @@ -709,7 +709,7 @@ version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["script"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -721,7 +721,7 @@ version = "1.3.4" description = "A deep merge function for 🐍." optional = false python-versions = ">=3.6" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, @@ -733,7 +733,7 @@ version = "1.6.1" description = "Project documentation with Markdown." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"}, {file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"}, @@ -765,7 +765,7 @@ version = "0.2.0" description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, @@ -783,7 +783,7 @@ version = "9.5.50" description = "Documentation that simply works" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "mkdocs_material-9.5.50-py3-none-any.whl", hash = "sha256:f24100f234741f4d423a9d672a909d859668a4f404796be3cf035f10d6050385"}, {file = "mkdocs_material-9.5.50.tar.gz", hash = "sha256:ae5fe16f3d7c9ccd05bb6916a7da7420cf99a9ce5e33debd9d40403a090d5825"}, @@ -813,7 +813,7 @@ version = "1.3.1" description = "Extension pack for Python Markdown and MkDocs Material." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, @@ -825,7 +825,7 @@ version = "1.14.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["linters"] files = [ {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, @@ -885,7 +885,7 @@ version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false python-versions = ">=3.5" -groups = ["dev"] +groups = ["linters"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, @@ -897,7 +897,7 @@ version = "1.9.1" description = "Node.js virtual environment builder" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["dev"] +groups = ["linters"] files = [ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, @@ -909,7 +909,7 @@ version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] +groups = ["main", "documentation", "test"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -921,7 +921,7 @@ version = "0.5.7" description = "Divides large result sets into pages for easier browsing" optional = false python-versions = "*" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"}, {file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"}, @@ -953,7 +953,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -981,7 +981,7 @@ version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation", "linters"] files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -998,7 +998,7 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["test"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -1014,7 +1014,7 @@ version = "4.1.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" -groups = ["dev"] +groups = ["linters"] files = [ {file = "pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b"}, {file = "pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4"}, @@ -1076,7 +1076,7 @@ version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["dev", "documentation", "script"] files = [ {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, @@ -1091,7 +1091,7 @@ version = "10.12" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77"}, {file = "pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7"}, @@ -1110,7 +1110,7 @@ version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["test"] files = [ {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, @@ -1133,7 +1133,7 @@ version = "6.0.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" -groups = ["dev"] +groups = ["test"] files = [ {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, @@ -1152,7 +1152,7 @@ version = "1.5.0" description = "pytest plugin for test data directories and files" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["test"] files = [ {file = "pytest-datadir-1.5.0.tar.gz", hash = "sha256:1617ed92f9afda0c877e4eac91904b5f779d24ba8f5e438752e3ae39d8d2ee3f"}, {file = "pytest_datadir-1.5.0-py3-none-any.whl", hash = "sha256:34adf361bcc7b37961bbc1dfa8d25a4829e778bab461703c38a5c50ca9c36dc8"}, @@ -1167,7 +1167,7 @@ version = "0.4.9" description = "Pytest plugin providing a fixture interface for spulec/freezegun" optional = false python-versions = ">=3.6" -groups = ["dev"] +groups = ["test"] files = [ {file = "pytest_freezer-0.4.9-py3-none-any.whl", hash = "sha256:8b6c50523b7d4aec4590b52bfa5ff766d772ce506e2bf4846c88041ea9ccae59"}, {file = "pytest_freezer-0.4.9.tar.gz", hash = "sha256:21bf16bc9cc46bf98f94382c4b5c3c389be7056ff0be33029111ae11b3f1c82a"}, @@ -1183,7 +1183,7 @@ version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["test"] files = [ {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, @@ -1201,7 +1201,7 @@ version = "2.7.0" description = "Easy to use fixtures to write regression tests." optional = false python-versions = ">=3.9" -groups = ["dev"] +groups = ["test"] files = [ {file = "pytest_regressions-2.7.0-py3-none-any.whl", hash = "sha256:69f5e3f03493cf0ef84d96d23e50a546617c198b1d7746f2e2b9e441cbab4847"}, {file = "pytest_regressions-2.7.0.tar.gz", hash = "sha256:4c30064e0923929012c94f5d6f35205be06fd8709c7f0dba0228e05c460af05e"}, @@ -1224,7 +1224,7 @@ version = "3.6.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["test"] files = [ {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, @@ -1245,7 +1245,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["dev"] +groups = ["documentation", "test"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -1260,7 +1260,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] +groups = ["main", "documentation", "linters", "test"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -1323,7 +1323,7 @@ version = "0.1" description = "A custom YAML tag for referencing environment variables in YAML files. " optional = false python-versions = ">=3.6" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, @@ -1353,7 +1353,7 @@ version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, @@ -1457,7 +1457,7 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -1479,7 +1479,7 @@ version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" -groups = ["dev"] +groups = ["script"] files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, @@ -1499,7 +1499,7 @@ version = "0.9.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" -groups = ["dev"] +groups = ["linters"] files = [ {file = "ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706"}, {file = "ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf"}, @@ -1527,7 +1527,7 @@ version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -groups = ["dev"] +groups = ["dev", "documentation", "test"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -1574,12 +1574,12 @@ version = "2.1.0" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" -groups = ["dev"] -markers = "python_full_version <= \"3.11.0a6\"" +groups = ["linters", "test"] files = [ {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, ] +markers = {linters = "python_version < \"3.11\"", test = "python_full_version <= \"3.11.0a6\""} [[package]] name = "tomlkit" @@ -1615,7 +1615,7 @@ version = "1.2.15.20241117" description = "Typing stubs for Deprecated" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["linters"] files = [ {file = "types-Deprecated-1.2.15.20241117.tar.gz", hash = "sha256:924002c8b7fddec51ba4949788a702411a2e3636cd9b2a33abd8ee119701d77e"}, {file = "types_Deprecated-1.2.15.20241117-py3-none-any.whl", hash = "sha256:a0cc5e39f769fc54089fd8e005416b55d74aa03f6964d2ed1a0b0b2e28751884"}, @@ -1627,7 +1627,7 @@ version = "2.9.0.20241206" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["linters"] files = [ {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, @@ -1639,7 +1639,7 @@ version = "6.0.12.20241230" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["linters"] files = [ {file = "types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6"}, {file = "types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c"}, @@ -1651,7 +1651,7 @@ version = "0.1.1" description = "Typing stubs for termcolor" optional = false python-versions = "*" -groups = ["dev"] +groups = ["linters"] files = [ {file = "types-termcolor-0.1.1.tar.gz", hash = "sha256:4d9e09ce7f3267985f5280b22e25790c98cb64628b6466e1fb915dbb52ad7136"}, {file = "types_termcolor-0.1.1-py2.py3-none-any.whl", hash = "sha256:3694c312e32f71fdc0f469c334ea21645f3130d90c93cd53bcb06b1233e174d5"}, @@ -1663,12 +1663,12 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] +groups = ["main", "dev", "linters", "script"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] -markers = {main = "python_version < \"3.11\""} +markers = {main = "python_version < \"3.11\"", dev = "python_version < \"3.11\"", script = "python_version < \"3.11\""} [[package]] name = "urllib3" @@ -1676,7 +1676,7 @@ version = "2.2.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, @@ -1694,7 +1694,7 @@ version = "20.27.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["linters"] files = [ {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, @@ -1715,7 +1715,7 @@ version = "6.0.0" description = "Filesystem events monitoring" optional = false python-versions = ">=3.9" -groups = ["dev"] +groups = ["documentation"] files = [ {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"}, {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"}, @@ -1770,7 +1770,7 @@ version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.8" -groups = ["dev"] +groups = ["test"] files = [ {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, @@ -1845,7 +1845,7 @@ version = "3.21.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" -groups = ["main", "dev"] +groups = ["main", "documentation"] markers = "python_version < \"3.10\"" files = [ {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, @@ -1863,4 +1863,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "0ba0fceb54fee21c1f4b61a80f1e2b5f0d0eff4ac688f22a97f274d7da9a598e" +content-hash = "83c82b26a9bff591edf995c9c251e52dc23d9a4024562e1218a783ddf151fc20" diff --git a/pyproject.toml b/pyproject.toml index 3609f7ba52..a76ef78183 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,27 +95,32 @@ version_files = [ packages = [{ include = "commitizen" }, { include = "commitizen/py.typed" }] [tool.poetry.group.dev.dependencies] -# dev tool ipython = "^8.0" -# test + +[tool.poetry.group.test.dependencies] pytest = ">=7.2,<9.0" pytest-cov = ">=4,<7" pytest-mock = "^3.10" pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" -# linter +deprecated = "^1.2.13" + +[tool.poetry.group.linters.dependencies] ruff = ">=0.5.0,<0.10.0" pre-commit = ">=2.18,<5.0" mypy = "^1.4" +types-deprecated = "^1.2.9.2" +types-python-dateutil = "^2.8.19.13" types-PyYAML = ">=5.4.3,<7.0.0" types-termcolor = "^0.1.1" -# documentation + +[tool.poetry.group.documentation.dependencies] mkdocs = "^1.4.2" mkdocs-material = "^9.1.6" -deprecated = "^1.2.13" -types-deprecated = "^1.2.9.2" -types-python-dateutil = "^2.8.19.13" + +[tool.poetry.group.script.dependencies] +# for scripts/gen_cli_help_screenshots.py rich = "^13.7.1" From 665895c19c0a46876afe4dfba02582628ce7e980 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 30 Jan 2025 22:33:47 +0800 Subject: [PATCH 392/598] docs(contributing): update minimum poetry requirment to 2.0.0 --- docs/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.md b/docs/contributing.md index a49196277e..439e3a19f7 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -8,7 +8,7 @@ If you're a first-time contributor, you can check the issues with [good first is ## Install before contributing -1. Install [poetry](https://python-poetry.org/) `1.2.0+`, installation [pages](https://python-poetry.org/docs/#installing-with-the-official-installer) +1. Install [poetry](https://python-poetry.org/) `>=2.0.0`, installation [pages](https://python-poetry.org/docs/#installing-with-the-official-installer) 2. Install [gpg](https://gnupg.org), installation [pages](https://gnupg.org/documentation/manuals/gnupg/Installation.html#Installation). For Mac users, you could try [homebrew](https://brew.sh/). ## Before making a pull request From a88ecd9500b9dceb88cf5f57273f99d49f049a82 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 31 Jan 2025 08:48:18 +0800 Subject: [PATCH 393/598] ci(github-actions): replace deprecated file key with files in codecov-action --- .github/workflows/pythonpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 4f99a595c7..8df5e54c03 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -33,6 +33,6 @@ jobs: uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - file: ./coverage.xml + files: ./coverage.xml flags: unittests name: codecov-umbrella From b311b39985a4e3bfe3d917a9d0cbdee1753989f7 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 31 Jan 2025 21:40:25 +0800 Subject: [PATCH 394/598] build(pyproject.toml): add maintainers --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index a76ef78183..39169a3743 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,10 @@ name = "commitizen" version = "4.1.1" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] +maintainers = [ + { name = "Wei Lee", email = "weilee.rx@gmail.com" }, + { name = " Axel H.", email = "noirbizarre@gmail.com" }, +] license = { text = "LICENSE" } readme = "docs/README.md" requires-python = ">=3.9,<4.0" From e31a31589e577a3bf7019206ecd26edab4902ebf Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 31 Jan 2025 21:40:43 +0800 Subject: [PATCH 395/598] fixup! build(pyproject.toml): add maintainers --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 39169a3743..5ea78a0ba1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ { name = "Wei Lee", email = "weilee.rx@gmail.com" }, - { name = " Axel H.", email = "noirbizarre@gmail.com" }, + { name = "Axel H.", email = "noirbizarre@gmail.com" }, ] license = { text = "LICENSE" } readme = "docs/README.md" From 95e7d5a65bfd340e0b47f7f44900dcfd127d77b0 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 31 Jan 2025 21:42:33 +0800 Subject: [PATCH 396/598] build(pyproject.toml): set version_scheme = "pep440" --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 5ea78a0ba1..76c51c474a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,6 +93,7 @@ version_files = [ "commitizen/__version__.py", ".pre-commit-config.yaml:rev:.+Commitizen", ] +version_scheme = "pep440" [tool.poetry] From 5d6369ee1c6e06f610f5a77117df909cee389b64 Mon Sep 17 00:00:00 2001 From: Michael Hirschler Date: Fri, 31 Jan 2025 13:45:29 +0100 Subject: [PATCH 397/598] docs(customization): fix yaml example --- docs/customization.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/customization.md b/docs/customization.md index 16ba588f10..132f4f0490 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -104,7 +104,7 @@ The equivalent example for a json config file: } ``` -And the correspondent example for a yaml json file: +And the correspondent example for a yaml file: ```yaml commitizen: @@ -115,8 +115,8 @@ commitizen: schema: ": " schema_pattern: "(feature|bug fix):(\\s.*)" bump_pattern: "^(break|new|fix|hotfix)" - commit_parser: "^(?Pfeature|bug fix):\\s(?P.*)?", - changelog_pattern: "^(feature|bug fix)?(!)?", + commit_parser: "^(?Pfeature|bug fix):\\s(?P.*)?" + changelog_pattern: "^(feature|bug fix)?(!)?" change_type_map: feature: Feat bug fix: Fix @@ -139,10 +139,10 @@ commitizen: message: Select the type of change you are committing - type: input name: message - message: Body. + message: 'Body.' - type: confirm name: show_message - message: Do you want to add body message in commit? + message: 'Do you want to add body message in commit?' ``` ### Customize configuration From 6327544cbe61cac3c03051544d3c38d537c67217 Mon Sep 17 00:00:00 2001 From: Pierrick Rambaud Date: Mon, 24 Apr 2023 07:02:32 +0200 Subject: [PATCH 398/598] feat: draft of the --empty parameter --- commitizen/cli.py | 6 ++++++ commitizen/commands/bump.py | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 0b411cba60..88c186d833 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -371,6 +371,12 @@ def __call__( "help": "Determine the next version and write to stdout", "default": False, }, + { + "name": ["--empty"], + "default": False, + "help": "bump tags without new commits", + "action": "store_true", + }, ], }, { diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 1b274061cb..7b8f5fc849 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -160,6 +160,7 @@ def __call__(self) -> None: # noqa: C901 build_metadata = self.arguments["build_metadata"] increment_mode: str = self.arguments["increment_mode"] get_next: bool = self.arguments["get_next"] + is_empty: bool | None = self.arguments["empty"] if manual_version: if increment: @@ -250,7 +251,7 @@ def __call__(self) -> None: # noqa: C901 # No commits, there is no need to create an empty tag. # Unless we previously had a prerelease. - if not commits and not current_version.is_prerelease: + if not commits and not current_version.is_prerelease and not is_empty: raise NoCommitsFoundError( "[NO_COMMITS_FOUND]\nNo new commits found." ) @@ -266,6 +267,10 @@ def __call__(self) -> None: # noqa: C901 "To avoid this error, manually specify the type of increment with `--increment`" ) + # we create an empty PATCH increment for empty tag + if increment is None and is_empty: + increment = "PATCH" + new_version = current_version.bump( increment, prerelease=prerelease, From 685e4ee1e20c5fa63011a962c18911ca16b08fee Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sun, 21 Apr 2024 17:01:27 +0800 Subject: [PATCH 399/598] refactor(bump): rename --empty as --allow-no-commit --- commitizen/cli.py | 4 ++-- commitizen/commands/bump.py | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 88c186d833..72d824380d 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -372,9 +372,9 @@ def __call__( "default": False, }, { - "name": ["--empty"], + "name": ["--allow-no-commit"], "default": False, - "help": "bump tags without new commits", + "help": "bump version without eligible commits", "action": "store_true", }, ], diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 7b8f5fc849..b82cac940f 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -160,7 +160,7 @@ def __call__(self) -> None: # noqa: C901 build_metadata = self.arguments["build_metadata"] increment_mode: str = self.arguments["increment_mode"] get_next: bool = self.arguments["get_next"] - is_empty: bool | None = self.arguments["empty"] + allow_no_commit: bool | None = self.arguments["allow_no_commit"] if manual_version: if increment: @@ -251,7 +251,11 @@ def __call__(self) -> None: # noqa: C901 # No commits, there is no need to create an empty tag. # Unless we previously had a prerelease. - if not commits and not current_version.is_prerelease and not is_empty: + if ( + not commits + and not current_version.is_prerelease + and not allow_no_commit + ): raise NoCommitsFoundError( "[NO_COMMITS_FOUND]\nNo new commits found." ) @@ -268,7 +272,7 @@ def __call__(self) -> None: # noqa: C901 ) # we create an empty PATCH increment for empty tag - if increment is None and is_empty: + if increment is None and allow_no_commit: increment = "PATCH" new_version = current_version.bump( From 3b5a2aef5be88be740d93f2c919f6522b9784d85 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sun, 21 Apr 2024 17:02:48 +0800 Subject: [PATCH 400/598] test(bump): add test cases for "--allow-no-commit" argument for bump command --- tests/commands/test_bump_command.py | 101 ++++++++++++++++++ ...shows_description_when_use_help_option.txt | 2 + 2 files changed, 103 insertions(+) diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 728a424107..934c0b8179 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1543,3 +1543,104 @@ def test_bump_get_next__no_eligible_commits_raises(mocker: MockFixture): with pytest.raises(NoneIncrementExit): cli.main() + + +def test_bump_allow_no_commit_with_no_commit(mocker, tmp_commitizen_project, capsys): + with tmp_commitizen_project.as_cwd(): + # Create the first commit and bump to 1.0.0 + create_file_and_commit("feat(user)!: new file") + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + # Verify NoCommitsFoundError should be raised + # when there's no new commit and "--allow-no-commit" is not set + with pytest.raises(NoCommitsFoundError): + testargs = ["cz", "bump"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + # bump to 1.0.1 with new commit when "--allow-no-commit" is set + testargs = ["cz", "bump", "--allow-no-commit"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + out, _ = capsys.readouterr() + assert "bump: version 1.0.0 → 1.0.1" in out + + +def test_bump_allow_no_commit_with_no_eligible_commit( + mocker, tmp_commitizen_project, capsys +): + with tmp_commitizen_project.as_cwd(): + # Create the first commit and bump to 1.0.0 + create_file_and_commit("feat(user)!: new file") + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + # Create a commit that is ineligible to bump + create_file_and_commit("docs(bump): add description for allow no commit") + + # Verify NoneIncrementExit should be raised + # when there's no eligible bumping commit and "--allow-no-commit" is not set + with pytest.raises(NoneIncrementExit): + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + # bump to 1.0.1 with ineligible commit when "--allow-no-commit" is set + testargs = ["cz", "bump", "--allow-no-commit"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + out, _ = capsys.readouterr() + assert "bump: version 1.0.0 → 1.0.1" in out + + +def test_bump_allow_no_commit_with_increment(mocker, tmp_commitizen_project, capsys): + with tmp_commitizen_project.as_cwd(): + # # Create the first commit and bump to 1.0.0 + create_file_and_commit("feat(user)!: new file") + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + # Verify NoCommitsFoundError should be raised + # when there's no new commit and "--allow-no-commit" is not set + with pytest.raises(NoCommitsFoundError): + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + # bump to 1.1.0 with no new commit when "--allow-no-commit" is set + # and increment is specified + testargs = ["cz", "bump", "--yes", "--allow-no-commit", "--increment", "MINOR"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + out, _ = capsys.readouterr() + assert "bump: version 1.0.0 → 1.1.0" in out + + +def test_bump_allow_no_commit_with_manual_version( + mocker, tmp_commitizen_project, capsys +): + with tmp_commitizen_project.as_cwd(): + # # Create the first commit and bump to 1.0.0 + create_file_and_commit("feat(user)!: new file") + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + # Verify NoCommitsFoundError should be raised + # when there's no new commit and "--allow-no-commit" is not set + with pytest.raises(NoCommitsFoundError): + testargs = ["cz", "bump", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + # bump to 1.1.0 with no new commit when "--allow-no-commit" is set + # and increment is specified + testargs = ["cz", "bump", "--yes", "--allow-no-commit", "2.0.0"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + out, _ = capsys.readouterr() + assert "bump: version 1.0.0 → 2.0.0" in out diff --git a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt index ab73bd4491..5d4438875d 100644 --- a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt @@ -11,6 +11,7 @@ usage: cz bump [-h] [--dry-run] [--files-only] [--local-version] [--changelog] [--version-scheme {pep440,semver,semver2}] [--version-type {pep440,semver,semver2}] [--build-metadata BUILD_METADATA] [--get-next] + [--allow-no-commit] [MANUAL_VERSION] bump semantic version based on the git log @@ -77,3 +78,4 @@ options: --build-metadata BUILD_METADATA Add additional build-metadata to the version-number --get-next Determine the next version and write to stdout + --allow-no-commit bump version without eligible commits From 2c97d0294df6c491012c7b1ab77740ba7cc4f3d1 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Sun, 21 Apr 2024 17:14:17 +0800 Subject: [PATCH 401/598] docs(bump): add description for bump "--allow-no-commit" argument --- docs/commands/bump.md | 36 +- docs/images/cli_help/cz___help.svg | 162 ++++----- docs/images/cli_help/cz_bump___help.svg | 358 ++++++++++--------- docs/images/cli_help/cz_changelog___help.svg | 190 +++++----- docs/images/cli_help/cz_check___help.svg | 134 +++---- docs/images/cli_help/cz_commit___help.svg | 110 +++--- 6 files changed, 511 insertions(+), 479 deletions(-) diff --git a/docs/commands/bump.md b/docs/commands/bump.md index afb43230e4..49c6f03434 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -52,7 +52,6 @@ Some examples of pep440: ![cz bump --help](../images/cli_help/cz_bump___help.svg) - ### `--files-only` Bumps the version in the files defined in `version_files` without creating a commit and tag on the git repository, @@ -178,6 +177,7 @@ If `--local-version` is used, it will bump only the local version `0.1.0` and ke If `--annotated-tag` is used, commitizen will create annotated tags. Also available via configuration, in `pyproject.toml` or `.cz.toml`. ### `--annotated-tag-message` + If `--annotated-tag-message` is used, commitizen will create annotated tags with the given message. ### `--changelog-to-stdout` @@ -276,14 +276,14 @@ cz bump --build-metadata yourmetadata Will create a version like `1.1.2+yourmetadata`. This can be useful for multiple things -* Git hash in version -* Labeling the version with additional metadata. +- Git hash in version +- Labeling the version with additional metadata. Note that Commitizen ignores everything after `+` when it bumps the version. It is therefore safe to write different build-metadata between versions. You should normally not use this functionality, but if you decide to do, keep in mind that -* Version `1.2.3+a`, and `1.2.3+b` are the same version! Tools should not use the string after `+` for version calculation. This is probably not a guarantee (example in helm) even tho it is in the spec. -* It might be problematic having the metadata in place when doing upgrades depending on what tool you use. +- Version `1.2.3+a`, and `1.2.3+b` are the same version! Tools should not use the string after `+` for version calculation. This is probably not a guarantee (example in helm) even tho it is in the spec. +- It might be problematic having the metadata in place when doing upgrades depending on what tool you use. ### `--get-next` @@ -318,6 +318,18 @@ The `--get-next` flag will raise a `NoneIncrementExit` if the found commits are For information on how to suppress this exit, see [avoid raising errors](#avoid-raising-errors). +### `--allow-no-commit` + +Allow the project version to be bumped even when there's no eligible version. This is most useful when used with `--increment {MAJOR,MINOR,PATCH}` or `[MANUL_VERSION]` + +```sh +# bump a minor version even when there's only bug fixes, documentation changes or even no commits +cz bump --incremental MINOR --allow-no-commit + +# bump version to 2.0.0 even when there's no breaking changes changes or even no commits +cz bump --allow-no-commit 2.0.0 +``` + ## Avoid raising errors Some situations from commitizen raise an exit code different than 0. @@ -389,13 +401,13 @@ cz -nr 21 bump These are used in: -* `cz bump`: Find previous release tag (exact match) and generate new tag. -* Find previous release tags in `cz changelog`. - * If `--incremental`: Using latest version found in the changelog, scan existing Git tags with 89\% similarity match. - * `--rev-range` is converted to Git tag names with `tag_format` before searching Git history. -* If the `scm` `version_provider` is used, it uses different regexes to find the previous version tags: - * If `tag_format` is set to `$version` (default): `VersionProtocol.parser` (allows `v` prefix) - * If `tag_format` is set: Custom regex similar to SemVer (not as lenient as PEP440 e.g. on dev-releases) +- `cz bump`: Find previous release tag (exact match) and generate new tag. +- Find previous release tags in `cz changelog`. + - If `--incremental`: Using latest version found in the changelog, scan existing Git tags with 89\% similarity match. + - `--rev-range` is converted to Git tag names with `tag_format` before searching Git history. +- If the `scm` `version_provider` is used, it uses different regexes to find the previous version tags: + - If `tag_format` is set to `$version` (default): `VersionProtocol.parser` (allows `v` prefix) + - If `tag_format` is set: Custom regex similar to SemVer (not as lenient as PEP440 e.g. on dev-releases) Commitizen supports 2 types of formats, a simple and a more complex. diff --git a/docs/images/cli_help/cz___help.svg b/docs/images/cli_help/cz___help.svg index 098e7df70d..22a9e4d0e7 100644 --- a/docs/images/cli_help/cz___help.svg +++ b/docs/images/cli_help/cz___help.svg @@ -19,133 +19,133 @@ font-weight: 700; } - .terminal-2205183093-matrix { + .terminal-4198725382-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2205183093-title { + .terminal-4198725382-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2205183093-r1 { fill: #c5c8c6 } -.terminal-2205183093-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-2205183093-r3 { fill: #d0b344 } -.terminal-2205183093-r4 { fill: #1984e9;text-decoration: underline; } -.terminal-2205183093-r5 { fill: #68a0b3;font-weight: bold } + .terminal-4198725382-r1 { fill: #c5c8c6 } +.terminal-4198725382-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-4198725382-r3 { fill: #d0b344 } +.terminal-4198725382-r4 { fill: #1984e9;text-decoration: underline; } +.terminal-4198725382-r5 { fill: #68a0b3;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -157,45 +157,45 @@ - + - - $ cz --help -usage: cz [-h][--config CONFIG][--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 -  --config CONFIG       the path of configuration file -  --debug               use debug mode -  -n, --name NAME       use the given commitizen (default: -                        cz_conventional_commits) -  -nr, --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) - + + $ cz --help +usage: cz [-h][--config CONFIG][--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 +  --config 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 +                        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 index 4030b1ba90..659b68b955 100644 --- a/docs/images/cli_help/cz_bump___help.svg +++ b/docs/images/cli_help/cz_bump___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + - + - + - - $ 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 {pep440,semver,semver2}] -[--version-type {pep440,semver,semver2}] -[--build-metadata BUILD_METADATA][--get-next] -[MANUAL_VERSION] - -bump semantic version based on the git log - -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, -pr {alpha,beta,rc} -                        choose type of prerelease -  --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, -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, -t TEMPLATE -                        changelog template file name (relative to the current -                        working directory) -  --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 {pep440,semver,semver2} -                        choose version scheme -  --version-type {pep440,semver,semver2} -                        Deprecated, use --version-scheme -  --build-metadata BUILD_METADATA -                        Add additional build-metadata to the version-number -  --get-next            Determine the next version and write to stdout - + + $ 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 {pep440,semver,semver2}] +[--version-type {pep440,semver,semver2}] +[--build-metadata BUILD_METADATA][--get-next] +[--allow-no-commit] +[MANUAL_VERSION] + +bump semantic version based on the git log + +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 {pep440,semver,semver2} +                        choose version scheme +  --version-type {pep440,semver,semver2} +                        Deprecated, use --version-scheme +  --build-metadata BUILD_METADATA +                        Add additional build-metadata to the version-number +  --get-next            Determine the next version and write to stdout +  --allow-no-commit     bump version without eligible commits + diff --git a/docs/images/cli_help/cz_changelog___help.svg b/docs/images/cli_help/cz_changelog___help.svg index 1160ccf6cf..8cb3fcf2fe 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - - $ 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,semver2}] -[--export-template EXPORT_TEMPLATE][--template TEMPLATE] -[--extra EXTRA] - - -generate changelog (note that it will overwrite existing file) - -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,semver2} -                        choose version scheme -  --export-template EXPORT_TEMPLATE -                        Export the changelog template into this file instead -                        of rendering it -  --template, -t TEMPLATE -                        changelog template file name (relative to the current -                        working directory) -  --extra, -e EXTRA     a changelog extra variable (in the form 'key=value') - + + $ 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,semver2}] +[--export-template EXPORT_TEMPLATE][--template TEMPLATE] +[--extra EXTRA] + + +generate changelog (note that it will overwrite existing file) + +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,semver2} +                        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 index 690bfec684..922a6458a6 100644 --- a/docs/images/cli_help/cz_check___help.svg +++ b/docs/images/cli_help/cz_check___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - - $ 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 ...]] -[-l MESSAGE_LENGTH_LIMIT] - -validates that a commit message matches the commitizen schema - -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 -                        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 -  -l, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit - + + $ 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 ...]] +[-l MESSAGE_LENGTH_LIMIT] + +validates that a commit message matches the commitizen schema + +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 +  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit + diff --git a/docs/images/cli_help/cz_commit___help.svg b/docs/images/cli_help/cz_commit___help.svg index 5aea02232f..0346c40588 100644 --- a/docs/images/cli_help/cz_commit___help.svg +++ b/docs/images/cli_help/cz_commit___help.svg @@ -19,95 +19,95 @@ font-weight: 700; } - .terminal-463778956-matrix { + .terminal-1670560432-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-463778956-title { + .terminal-1670560432-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-463778956-r1 { fill: #c5c8c6 } -.terminal-463778956-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-463778956-r3 { fill: #68a0b3;font-weight: bold } + .terminal-1670560432-r1 { fill: #c5c8c6 } +.terminal-1670560432-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-1670560432-r3 { fill: #68a0b3;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -119,33 +119,33 @@ - + - - $ cz commit --help -usage: cz commit [-h][--retry][--no-retry][--dry-run] -[--write-message-to-file FILE_PATH][-s][-a][-e] -[-l MESSAGE_LENGTH_LIMIT][--] - -create new commit - -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. -  -e, --edit            edit the commit message before committing -  -l, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit -  --                    Positional arguments separator (recommended) - + + $ cz commit --help +usage: cz commit [-h][--retry][--no-retry][--dry-run] +[--write-message-to-file FILE_PATH][-s][-a][-e] +[-l MESSAGE_LENGTH_LIMIT][--] + +create new commit + +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. +  -e, --edit            edit the commit message before committing +  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit +  --                    Positional arguments separator (recommended) + From 98ae920d1fb97617e6dd42ae16a928bb1842f646 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 7 Feb 2025 01:13:48 +0000 Subject: [PATCH 402/598] =?UTF-8?q?bump:=20version=204.1.1=20=E2=86=92=204?= =?UTF-8?q?.2.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 10 ++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5ee5c84c96..470d1f1621 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,7 +49,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.1.1 # automatically updated by Commitizen + rev: v4.2.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 3687908b19..e8a573f8ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v4.2.0 (2025-02-07) + +### Feat + +- draft of the --empty parameter + +### Refactor + +- **bump**: rename --empty as --allow-no-commit + ## v4.1.1 (2025-01-26) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 72aa75832f..0fd7811c0d 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.1.1" +__version__ = "4.2.0" diff --git a/pyproject.toml b/pyproject.toml index 76c51c474a..47d83785cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.1.1" +version = "4.2.0" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -86,7 +86,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.1.1" +version = "4.2.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", From d4dfd3340d311203b74a42ae0a730504c462bc30 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 7 Feb 2025 01:14:18 +0000 Subject: [PATCH 403/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz___help.svg | 162 ++++----- docs/images/cli_help/cz_bump___help.svg | 358 +++++++++---------- docs/images/cli_help/cz_changelog___help.svg | 190 +++++----- docs/images/cli_help/cz_check___help.svg | 134 ++++--- docs/images/cli_help/cz_commit___help.svg | 110 +++--- 5 files changed, 471 insertions(+), 483 deletions(-) diff --git a/docs/images/cli_help/cz___help.svg b/docs/images/cli_help/cz___help.svg index 22a9e4d0e7..098e7df70d 100644 --- a/docs/images/cli_help/cz___help.svg +++ b/docs/images/cli_help/cz___help.svg @@ -19,133 +19,133 @@ font-weight: 700; } - .terminal-4198725382-matrix { + .terminal-2205183093-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4198725382-title { + .terminal-2205183093-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4198725382-r1 { fill: #c5c8c6 } -.terminal-4198725382-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-4198725382-r3 { fill: #d0b344 } -.terminal-4198725382-r4 { fill: #1984e9;text-decoration: underline; } -.terminal-4198725382-r5 { fill: #68a0b3;font-weight: bold } + .terminal-2205183093-r1 { fill: #c5c8c6 } +.terminal-2205183093-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-2205183093-r3 { fill: #d0b344 } +.terminal-2205183093-r4 { fill: #1984e9;text-decoration: underline; } +.terminal-2205183093-r5 { fill: #68a0b3;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -157,45 +157,45 @@ - + - - $ cz --help -usage: cz [-h][--config CONFIG][--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 -  --config 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 -                        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) - + + $ cz --help +usage: cz [-h][--config CONFIG][--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 +  --config CONFIG       the path of configuration file +  --debug               use debug mode +  -n, --name NAME       use the given commitizen (default: +                        cz_conventional_commits) +  -nr, --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 index 659b68b955..7f27636ddf 100644 --- a/docs/images/cli_help/cz_bump___help.svg +++ b/docs/images/cli_help/cz_bump___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + - - $ 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 {pep440,semver,semver2}] -[--version-type {pep440,semver,semver2}] -[--build-metadata BUILD_METADATA][--get-next] -[--allow-no-commit] -[MANUAL_VERSION] - -bump semantic version based on the git log - -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 {pep440,semver,semver2} -                        choose version scheme -  --version-type {pep440,semver,semver2} -                        Deprecated, use --version-scheme -  --build-metadata BUILD_METADATA -                        Add additional build-metadata to the version-number -  --get-next            Determine the next version and write to stdout -  --allow-no-commit     bump version without eligible commits - + + $ 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 {pep440,semver,semver2}] +[--version-type {pep440,semver,semver2}] +[--build-metadata BUILD_METADATA][--get-next] +[--allow-no-commit] +[MANUAL_VERSION] + +bump semantic version based on the git log + +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, -pr {alpha,beta,rc} +                        choose type of prerelease +  --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, -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, -t TEMPLATE +                        changelog template file name (relative to the current +                        working directory) +  --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 {pep440,semver,semver2} +                        choose version scheme +  --version-type {pep440,semver,semver2} +                        Deprecated, use --version-scheme +  --build-metadata BUILD_METADATA +                        Add additional build-metadata to the version-number +  --get-next            Determine the next version and write to stdout +  --allow-no-commit     bump version without eligible commits + diff --git a/docs/images/cli_help/cz_changelog___help.svg b/docs/images/cli_help/cz_changelog___help.svg index 8cb3fcf2fe..1160ccf6cf 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + - - $ 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,semver2}] -[--export-template EXPORT_TEMPLATE][--template TEMPLATE] -[--extra EXTRA] - - -generate changelog (note that it will overwrite existing file) - -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,semver2} -                        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') - + + $ 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,semver2}] +[--export-template EXPORT_TEMPLATE][--template TEMPLATE] +[--extra EXTRA] + + +generate changelog (note that it will overwrite existing file) + +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,semver2} +                        choose version scheme +  --export-template EXPORT_TEMPLATE +                        Export the changelog template into this file instead +                        of rendering it +  --template, -t TEMPLATE +                        changelog template file name (relative to the current +                        working directory) +  --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 index 922a6458a6..690bfec684 100644 --- a/docs/images/cli_help/cz_check___help.svg +++ b/docs/images/cli_help/cz_check___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + - - $ 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 ...]] -[-l MESSAGE_LENGTH_LIMIT] - -validates that a commit message matches the commitizen schema - -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 -  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit - + + $ 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 ...]] +[-l MESSAGE_LENGTH_LIMIT] + +validates that a commit message matches the commitizen schema + +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 +                        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 +  -l, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit + diff --git a/docs/images/cli_help/cz_commit___help.svg b/docs/images/cli_help/cz_commit___help.svg index 0346c40588..5aea02232f 100644 --- a/docs/images/cli_help/cz_commit___help.svg +++ b/docs/images/cli_help/cz_commit___help.svg @@ -19,95 +19,95 @@ font-weight: 700; } - .terminal-1670560432-matrix { + .terminal-463778956-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1670560432-title { + .terminal-463778956-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1670560432-r1 { fill: #c5c8c6 } -.terminal-1670560432-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-1670560432-r3 { fill: #68a0b3;font-weight: bold } + .terminal-463778956-r1 { fill: #c5c8c6 } +.terminal-463778956-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-463778956-r3 { fill: #68a0b3;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -119,33 +119,33 @@ - + - - $ cz commit --help -usage: cz commit [-h][--retry][--no-retry][--dry-run] -[--write-message-to-file FILE_PATH][-s][-a][-e] -[-l MESSAGE_LENGTH_LIMIT][--] - -create new commit - -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. -  -e, --edit            edit the commit message before committing -  -l MESSAGE_LENGTH_LIMIT, --message-length-limit MESSAGE_LENGTH_LIMIT -                        length limit of the commit message; 0 for no limit -  --                    Positional arguments separator (recommended) - + + $ cz commit --help +usage: cz commit [-h][--retry][--no-retry][--dry-run] +[--write-message-to-file FILE_PATH][-s][-a][-e] +[-l MESSAGE_LENGTH_LIMIT][--] + +create new commit + +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. +  -e, --edit            edit the commit message before committing +  -l, --message-length-limit MESSAGE_LENGTH_LIMIT +                        length limit of the commit message; 0 for no limit +  --                    Positional arguments separator (recommended) + From fe13eba654dbb569dde56848f7ae883b8b63fce7 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 30 Jan 2025 21:54:40 +0800 Subject: [PATCH 404/598] style(hooks): improve type annotation --- hooks/post-commit.py | 5 +++-- hooks/prepare-commit-msg.py | 26 ++++++++++++-------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/hooks/post-commit.py b/hooks/post-commit.py index 6444e5ca84..c7dea825bd 100755 --- a/hooks/post-commit.py +++ b/hooks/post-commit.py @@ -8,7 +8,7 @@ exit(1) -def post_commit(): +def post_commit() -> None: backup_file = Path(get_backup_file_path()) # remove backup file if it exists @@ -17,4 +17,5 @@ def post_commit(): if __name__ == "__main__": - exit(post_commit()) + post_commit() + exit(0) diff --git a/hooks/prepare-commit-msg.py b/hooks/prepare-commit-msg.py index d1ccf169cf..e666fa673b 100755 --- a/hooks/prepare-commit-msg.py +++ b/hooks/prepare-commit-msg.py @@ -13,22 +13,19 @@ exit(1) -def prepare_commit_msg(commit_msg_file: Path) -> int: +def prepare_commit_msg(commit_msg_file: str) -> int: # check if the commit message needs to be generated using commitizen - if ( - subprocess.run( - [ - "cz", - "check", - "--commit-msg-file", - commit_msg_file, - ], - capture_output=True, - ).returncode - != 0 - ): + exit_code = subprocess.run( + [ + "cz", + "check", + "--commit-msg-file", + commit_msg_file, + ], + capture_output=True, + ).returncode + if exit_code != 0: backup_file = Path(get_backup_file_path()) - if backup_file.is_file(): # confirm if commit message from backup file should be reused answer = input("retry with previous message? [y/N]: ") @@ -54,6 +51,7 @@ def prepare_commit_msg(commit_msg_file: Path) -> int: # write message to backup file shutil.copyfile(commit_msg_file, backup_file) + return 0 if __name__ == "__main__": From b4dc83284dc8c9729032a774a037df1d1f2397d5 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Thu, 30 Jan 2025 21:55:41 +0800 Subject: [PATCH 405/598] docs(hooks): fix missing link --- docs/tutorials/auto_prepare_commit_message.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/auto_prepare_commit_message.md b/docs/tutorials/auto_prepare_commit_message.md index 3011142679..7e8295b7c8 100644 --- a/docs/tutorials/auto_prepare_commit_message.md +++ b/docs/tutorials/auto_prepare_commit_message.md @@ -25,7 +25,7 @@ commitizen and use the generated commit message for the commit. ## Installation -Copy the hooks from [here](https://github.com/commitizen-tools/hooks) into the `.git/hooks` folder and make them +Copy the hooks from [here](https://github.com/commitizen-tools/commitizen/tree/master/hooks) into the `.git/hooks` folder and make them executable by running the following commands from the root of your Git repository: ```bash From 7663adcf36b4bc12ab5a80f85a2c5478db2264d5 Mon Sep 17 00:00:00 2001 From: "Axel H." Date: Sat, 8 Feb 2025 00:54:22 +0100 Subject: [PATCH 406/598] ci(poe): use `poethepoet` as script runner for dev and ci and use poetry dependencies groups in ci Fix #724 --- .github/pull_request_template.md | 2 +- .github/workflows/docspublish.yml | 12 ++++--- .github/workflows/pythonpackage.yml | 6 ++-- .github/workflows/pythonpublish.yml | 10 +++--- .pre-commit-config.yaml | 11 +++--- docs/contributing.md | 8 ++--- pyproject.toml | 54 +++++++++++++++++++++++++++++ scripts/format | 10 ------ scripts/publish | 2 -- scripts/test | 10 ------ 10 files changed, 77 insertions(+), 48 deletions(-) delete mode 100755 scripts/format delete mode 100755 scripts/publish delete mode 100755 scripts/test diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 14bee6b434..0064604fba 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -10,7 +10,7 @@ Please fill in the following content to let us know better about this change. ## Checklist - [ ] Add test cases to all the changes you introduce -- [ ] Run `./scripts/format` and `./scripts/test` locally to ensure this change passes linter check and test +- [ ] Run `poetry all` locally to ensure this change passes linter check and test - [ ] Test the changes on the local machine manually - [ ] Update the documentation for the changes diff --git a/.github/workflows/docspublish.yml b/.github/workflows/docspublish.yml index f318b86858..a871d3c379 100644 --- a/.github/workflows/docspublish.yml +++ b/.github/workflows/docspublish.yml @@ -19,12 +19,12 @@ jobs: python-version: "3.x" - name: Install dependencies run: | - python -m pip install -U pip poetry + python -m pip install -U pip poetry poethepoet poetry --version - poetry install + poetry install --only main,script - name: Update CLI screenshots run: | - poetry run python scripts/gen_cli_help_screenshots.py + poetry doc:screenshots - name: Commit and push updated CLI screenshots run: | git config --global user.name "github-actions[bot]" @@ -55,12 +55,14 @@ jobs: python-version: "3.x" - name: Install dependencies run: | - python -m pip install -U mkdocs mkdocs-material + python -m pip install -U pip poetry poethepoet + poetry --version + poetry install --no-root --only documentation - name: Build docs env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - python -m mkdocs build + poetry doc:build - name: Generate Sponsors 💖 uses: JamesIves/github-sponsors-readme-action@v1 with: diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 8df5e54c03..f2363745cb 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -19,14 +19,14 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - python -m pip install -U pip poetry + python -m pip install -U pip poetry poethepoet poetry --version - poetry install + poetry install --only main,linters,test - name: Run tests and linters run: | git config --global user.email "action@github.com" git config --global user.name "GitHub Action" - SKIP=no-commit-to-branch,commitizen-branch poetry run pre-commit run --all-files --hook-stage pre-push + poetry ci shell: bash - name: Upload coverage to Codecov if: runner.os == 'Linux' diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml index e3b3aa6f30..dc522bc0fd 100644 --- a/.github/workflows/pythonpublish.yml +++ b/.github/workflows/pythonpublish.yml @@ -19,12 +19,10 @@ jobs: python-version: "3.x" - name: Install dependencies run: | - python -m pip install -U pip poetry mkdocs mkdocs-material + python -m pip install -U pip poetry poetry --version - poetry install - name: Publish env: - PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }} - PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - ./scripts/publish + POETRY_HTTP_BASIC_PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }} + POETRY_HTTP_BASIC_PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: poetry publish --build diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 470d1f1621..5db6862aeb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,6 @@ default_install_hook_types: default_stages: - pre-commit - - pre-push repos: - repo: meta @@ -55,21 +54,19 @@ repos: - id: commitizen-branch stages: - post-commit - - pre-push - repo: local hooks: - id: format - name: format + name: Format language: system pass_filenames: false - entry: ./scripts/format + entry: poetry format types: [ python ] - id: linter and test - name: linter and test + name: Linters language: system pass_filenames: false - stages: [ pre-push ] - entry: ./scripts/test + entry: poetry lint types: [ python ] diff --git a/docs/contributing.md b/docs/contributing.md index 439e3a19f7..0da1707da6 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -16,16 +16,16 @@ If you're a first-time contributor, you can check the issues with [good first is 1. Fork [the repository](https://github.com/commitizen-tools/commitizen). 2. Clone the repository from your GitHub. 3. Setup development environment through [poetry](https://python-poetry.org/) (`poetry install`). -4. Setup [pre-commit](https://pre-commit.com/) hook (`poetry run pre-commit install`) +4. Setup [pre-commit](https://pre-commit.com/) hook (`poetry setup-pre-commit`) 5. Check out a new branch and add your modification. 6. Add test cases for all your changes. (We use [CodeCov](https://codecov.io/) to ensure our test coverage does not drop.) 7. Use [commitizen](https://github.com/commitizen-tools/commitizen) to do git commit. We follow [conventional commits](https://www.conventionalcommits.org/). -8. Run `./scripts/format` and `./scripts/test` to ensure you follow the coding style and the tests pass. -9. Optionally, update the `./docs/README.md` or `docs/images/cli_help` (through running `scripts/gen_cli_help_screenshots.py`). +8. Run `poetry all` to ensure you follow the coding style and the tests pass. +9. Optionally, update the `./docs/README.md` or `docs/images/cli_help` (through running `poetry doc:screenshots`). 9. **Do not** update the `CHANGELOG.md`, it will be automatically created after merging to `master`. 10. **Do not** update the versions in the project, they will be automatically updated. -10. If your changes are about documentation. Run `poetry run mkdocs serve` to serve documentation locally and check whether there is any warning or error. +10. If your changes are about documentation. Run `poetry doc` to serve documentation locally and check whether there is any warning or error. 11. Send a [pull request](https://github.com/commitizen-tools/commitizen/pulls) 🙏 ## Use of GitHub Labels diff --git a/pyproject.toml b/pyproject.toml index 47d83785cd..56131bef5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -99,6 +99,9 @@ version_scheme = "pep440" [tool.poetry] packages = [{ include = "commitizen" }, { include = "commitizen/py.typed" }] +[tool.poetry.requires-plugins] +"poethepoet" = ">=0.32.2" + [tool.poetry.group.dev.dependencies] ipython = "^8.0" @@ -161,6 +164,9 @@ omit = [ [tool.pytest.ini_options] addopts = "--strict-markers" +testpaths = [ + "tests/", +] [tool.ruff] line-length = 88 @@ -202,3 +208,51 @@ ignore_missing_imports = true skip = '.git*,*.svg,*.lock' check-hidden = true ignore-words-list = 'asend' + +[tool.poe] +poetry_command = "" + +[tool.poe.tasks] +format.help = "Format the code" +format.sequence = [ + {cmd = "ruff check --fix commitizen tests"}, + {cmd = "ruff format commitizen tests"}, +] + +lint.help = "Lint the code" +lint.sequence = [ + {cmd = "ruff check commitizen/ tests/ --fix"}, + {cmd = "mypy commitizen/ tests/"}, +] + +test.help = "Run the test suite" +test.cmd = "pytest -n 3 --dist=loadfile" + +cover.help = "Run the test suite with coverage" +cover.ref = "test --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen" + +all.help = "Run all tasks" +all.sequence = [ + "format", + "lint", + "cover", +] + +"doc:screenshots".help = "Render documentation screeenshots" +"doc:screenshots".script = "scripts.gen_cli_help_screenshots:gen_cli_help_screenshots" + +"doc:build".help = "Build the documentation" +"doc:build".cmd = "mkdocs build" + +doc.help = "Live documentation server" +doc.cmd = "mkdocs serve" + +ci.help = "Run all tasks in CI" +ci.sequence = [ + {cmd="pre-commit run --all-files"}, + "cover", +] +ci.env = {SKIP = "no-commit-to-branch"} + +setup-pre-commit.help = "Install pre-commit hooks" +setup-pre-commit.cmd = "pre-commit install" diff --git a/scripts/format b/scripts/format deleted file mode 100755 index 0ffe29ba4f..0000000000 --- a/scripts/format +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env sh -set -e - -export PREFIX="poetry run python -m " - -set -x - -# This is needed for running import sorting -${PREFIX}ruff check --fix commitizen tests -${PREFIX}ruff format commitizen tests diff --git a/scripts/publish b/scripts/publish deleted file mode 100755 index 4d31f1188e..0000000000 --- a/scripts/publish +++ /dev/null @@ -1,2 +0,0 @@ -# Publish to pypi -poetry publish --build -u $PYPI_USERNAME -p $PYPI_PASSWORD diff --git a/scripts/test b/scripts/test deleted file mode 100755 index 894228b41f..0000000000 --- a/scripts/test +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env sh -set -e - -export PREFIX='poetry run python -m ' -export REGEX='^(?![.]|venv).*' - -${PREFIX}pytest -n 3 --dist=loadfile --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen tests/ -${PREFIX}ruff check commitizen/ tests/ --fix -${PREFIX}mypy commitizen/ tests/ -${PREFIX}commitizen -nr 3 check --rev-range origin/master.. From 69203030925ccac0202575484b3ef8309b5332ae Mon Sep 17 00:00:00 2001 From: "Axel H." Date: Sat, 8 Feb 2025 02:09:32 +0100 Subject: [PATCH 407/598] ci(tox): add `test:all` command to run the test suite on all support Python versions using `tox` --- poetry.lock | 130 +++++++++++++++++++++++++++++++++++++++++++------ pyproject.toml | 15 ++++++ 2 files changed, 131 insertions(+), 14 deletions(-) diff --git a/poetry.lock b/poetry.lock index 723dceddd9..073e1bc247 100644 --- a/poetry.lock +++ b/poetry.lock @@ -49,6 +49,18 @@ files = [ [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] +[[package]] +name = "cachetools" +version = "5.5.1" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "cachetools-5.5.1-py3-none-any.whl", hash = "sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb"}, + {file = "cachetools-5.5.1.tar.gz", hash = "sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95"}, +] + [[package]] name = "certifi" version = "2024.8.30" @@ -73,6 +85,18 @@ files = [ {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + [[package]] name = "charset-normalizer" version = "3.4.1" @@ -328,7 +352,7 @@ version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" -groups = ["linters"] +groups = ["dev", "linters"] files = [ {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, @@ -386,7 +410,7 @@ version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" -groups = ["linters"] +groups = ["dev", "linters"] files = [ {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, @@ -909,7 +933,7 @@ version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["main", "documentation", "test"] +groups = ["main", "dev", "documentation", "test"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -981,7 +1005,7 @@ version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" -groups = ["documentation", "linters"] +groups = ["dev", "documentation", "linters"] files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -998,7 +1022,7 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" -groups = ["test"] +groups = ["dev", "test"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -1104,6 +1128,26 @@ pyyaml = "*" [package.extras] extra = ["pygments (>=2.12)"] +[[package]] +name = "pyproject-api" +version = "1.9.0" +description = "API to interact with the python pyproject.toml based projects" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pyproject_api-1.9.0-py3-none-any.whl", hash = "sha256:326df9d68dea22d9d98b5243c46e3ca3161b07a1b9b18e213d1e24fd0e605766"}, + {file = "pyproject_api-1.9.0.tar.gz", hash = "sha256:7e8a9854b2dfb49454fae421cb86af43efbb2b2454e5646ffb7623540321ae6e"}, +] + +[package.dependencies] +packaging = ">=24.2" +tomli = {version = ">=2.2.1", markers = "python_version < \"3.11\""} + +[package.extras] +docs = ["furo (>=2024.8.6)", "sphinx-autodoc-typehints (>=3)"] +testing = ["covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "setuptools (>=75.8)"] + [[package]] name = "pytest" version = "8.3.4" @@ -1570,16 +1614,46 @@ tests = ["pytest", "pytest-cov"] [[package]] name = "tomli" -version = "2.1.0" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" -groups = ["linters", "test"] -files = [ - {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, - {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, -] -markers = {linters = "python_version < \"3.11\"", test = "python_full_version <= \"3.11.0a6\""} +groups = ["dev", "linters", "test"] +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] +markers = {dev = "python_version < \"3.11\"", linters = "python_version < \"3.11\"", test = "python_full_version <= \"3.11.0a6\""} [[package]] name = "tomlkit" @@ -1593,6 +1667,34 @@ files = [ {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, ] +[[package]] +name = "tox" +version = "4.24.1" +description = "tox is a generic virtualenv management and test command line tool" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "tox-4.24.1-py3-none-any.whl", hash = "sha256:57ba7df7d199002c6df8c2db9e6484f3de6ca8f42013c083ea2d4d1e5c6bdc75"}, + {file = "tox-4.24.1.tar.gz", hash = "sha256:083a720adbc6166fff0b7d1df9d154f9d00bfccb9403b8abf6bc0ee435d6a62e"}, +] + +[package.dependencies] +cachetools = ">=5.5" +chardet = ">=5.2" +colorama = ">=0.4.6" +filelock = ">=3.16.1" +packaging = ">=24.2" +platformdirs = ">=4.3.6" +pluggy = ">=1.5" +pyproject-api = ">=1.8" +tomli = {version = ">=2.1", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.12.2", markers = "python_version < \"3.11\""} +virtualenv = ">=20.27.1" + +[package.extras] +test = ["devpi-process (>=1.0.2)", "pytest (>=8.3.3)", "pytest-mock (>=3.14)"] + [[package]] name = "traitlets" version = "5.14.3" @@ -1694,7 +1796,7 @@ version = "20.27.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" -groups = ["linters"] +groups = ["dev", "linters"] files = [ {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, @@ -1863,4 +1965,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "83c82b26a9bff591edf995c9c251e52dc23d9a4024562e1218a783ddf151fc20" +content-hash = "b0f8544806163bc0dddc039eb313f9d82119b845b3a19dedc381e9c88e8f4466" diff --git a/pyproject.toml b/pyproject.toml index 56131bef5e..11a3837dac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,6 +104,7 @@ packages = [{ include = "commitizen" }, { include = "commitizen/py.typed" }] [tool.poetry.group.dev.dependencies] ipython = "^8.0" +tox = ">4" [tool.poetry.group.test.dependencies] pytest = ">=7.2,<9.0" @@ -168,6 +169,17 @@ testpaths = [ "tests/", ] +[tool.tox] +requires = ["tox>=4.22"] +env_list = ["3.9", "3.10", "3.11", "3.12", "3.13"] + +[tool.tox.env_run_base] +description = "Run tests suite against Python {base_python}" +skip_install = true +deps = ["poetry>=2.0"] +commands_pre = [["poetry", "install", "--only", "main,test"]] +commands = [["pytest", { replace = "posargs", extend = true}]] + [tool.ruff] line-length = 88 @@ -228,6 +240,9 @@ lint.sequence = [ test.help = "Run the test suite" test.cmd = "pytest -n 3 --dist=loadfile" +"test:all".help = "Run the test suite on all supported Python versions" +"test:all".cmd = "tox --parallel" + cover.help = "Run the test suite with coverage" cover.ref = "test --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen" From fe3b726268679892b3ce9e1ad08b8ed48b9f2761 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Fri, 7 Feb 2025 13:28:01 +0100 Subject: [PATCH 408/598] fix(bump): add debugging to bump command --- commitizen/bump.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/commitizen/bump.py b/commitizen/bump.py index 2351dbd7ec..908899eb0e 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -4,6 +4,7 @@ import re from collections import OrderedDict from glob import iglob +from logging import getLogger from string import Template from typing import cast @@ -14,6 +15,8 @@ VERSION_TYPES = [None, PATCH, MINOR, MAJOR] +logger = getLogger("commitizen") + def find_increment( commits: list[GitCommit], regex: str, increments_map: dict | OrderedDict @@ -38,7 +41,15 @@ def find_increment( new_increment = increments_map[match_pattern] break + if new_increment is None: + logger.debug( + f"no increment needed for '{found_keyword}' in '{message}'" + ) + if VERSION_TYPES.index(increment) < VERSION_TYPES.index(new_increment): + logger.debug( + f"increment detected is '{new_increment}' due to '{found_keyword}' in '{message}'" + ) increment = new_increment if increment == MAJOR: From 8519ca470e88f8c7eb30dfe31cad2b0dd8acfea2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 8 Feb 2025 15:24:57 +0000 Subject: [PATCH 409/598] =?UTF-8?q?bump:=20version=204.2.0=20=E2=86=92=204?= =?UTF-8?q?.2.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5db6862aeb..3149a3658f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.2.0 # automatically updated by Commitizen + rev: v4.2.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index e8a573f8ef..ddcf5ff204 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.2.1 (2025-02-08) + +### Fix + +- **bump**: add debugging to bump + ## v4.2.0 (2025-02-07) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 0fd7811c0d..aef46acb47 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.2.0" +__version__ = "4.2.1" diff --git a/pyproject.toml b/pyproject.toml index 11a3837dac..a2f9d7923b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.2.0" +version = "4.2.1" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -86,7 +86,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.2.0" +version = "4.2.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 43ee8a06b2ff003f45e8975cf9487a802cdf6d89 Mon Sep 17 00:00:00 2001 From: Matheus Cardoso Date: Sun, 9 Feb 2025 14:35:27 -0300 Subject: [PATCH 410/598] docs(tutorials): Add "stages" explicitly to the hook example As mentioned here: https://github.com/commitizen-tools/commitizen/issues/177#issuecomment-621939385, without the stages explicitly set, the hook always fails. --- docs/tutorials/auto_check.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tutorials/auto_check.md b/docs/tutorials/auto_check.md index ede8759e68..2fce57f9bd 100644 --- a/docs/tutorials/auto_check.md +++ b/docs/tutorials/auto_check.md @@ -25,6 +25,7 @@ repos: rev: v1.17.0 hooks: - id: commitizen + stages: [commit-msg] ``` - Step 3: Install the configuration into git hook through `pre-commit` From 295f9757f42e7f2287fa9608e2a65e59fb821f2b Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Tue, 11 Feb 2025 23:24:09 +0800 Subject: [PATCH 411/598] ci(github-actions): add check-commit task --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index a2f9d7923b..24c3153b45 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -237,6 +237,9 @@ lint.sequence = [ {cmd = "mypy commitizen/ tests/"}, ] +check-commit.help = "Check the commit message" +check-commit.cmd = "cz -nr 3 check --rev-range origin/master.." + test.help = "Run the test suite" test.cmd = "pytest -n 3 --dist=loadfile" @@ -251,6 +254,7 @@ all.sequence = [ "format", "lint", "cover", + "check-commit" ] "doc:screenshots".help = "Render documentation screeenshots" From d831c9995c17e14a8835599fe0405a6fa17d46b2 Mon Sep 17 00:00:00 2001 From: Christian Kagerer Date: Mon, 17 Feb 2025 15:32:20 +0100 Subject: [PATCH 412/598] fix(bump): manual version bump if prerelease offset is configured If you use the prerelase offset in the .cz.toml, as in the following example, no bump with a manual version number is possible. The error occurs when bumping with manual version number: cz bump 9.8.7 --prerelease-offset cannot be combined with MANUAL_VERSION ```toml [tool.commitizen] changelog_incremental = true tag_format = "v$version" update_changelog_on_bump = true version = "1.2.0b13" prerelease_offset = 1 ``` --- commitizen/commands/bump.py | 5 ----- docs/commands/bump.md | 2 +- tests/commands/test_bump_command.py | 17 ----------------- 3 files changed, 1 insertion(+), 23 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index b82cac940f..8e9f0f181b 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -187,11 +187,6 @@ def __call__(self) -> None: # noqa: C901 "--major-version-zero cannot be combined with MANUAL_VERSION" ) - if prerelease_offset: - raise NotAllowed( - "--prerelease-offset cannot be combined with MANUAL_VERSION" - ) - if get_next: raise NotAllowed("--get-next cannot be combined with MANUAL_VERSION") diff --git a/docs/commands/bump.md b/docs/commands/bump.md index 49c6f03434..efdba76257 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -599,7 +599,7 @@ post_bump_hooks = [ ### `prerelease_offset` -Offset with which to start counting prereleses. +Offset with which to start counting prereleases. Defaults to: `0` diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 934c0b8179..52e2defde0 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1041,23 +1041,6 @@ def test_bump_with_hooks_and_increment(mocker: MockFixture, tmp_commitizen_proje assert tag_exists is True -@pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_manual_version_disallows_prerelease_offset(mocker): - create_file_and_commit("feat: new file") - - manual_version = "0.2.0" - testargs = ["cz", "bump", "--yes", "--prerelease-offset", "42", manual_version] - mocker.patch.object(sys, "argv", testargs) - - with pytest.raises(NotAllowed) as excinfo: - cli.main() - - expected_error_message = ( - "--prerelease-offset cannot be combined with MANUAL_VERSION" - ) - assert expected_error_message in str(excinfo.value) - - @pytest.mark.usefixtures("tmp_git_project") def test_bump_use_version_provider(mocker: MockFixture): mock = mocker.MagicMock(name="provider") From a330ac72b48927d99ea01ade8982236d4aa54f40 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Feb 2025 13:36:26 +0000 Subject: [PATCH 413/598] =?UTF-8?q?bump:=20version=204.2.1=20=E2=86=92=204?= =?UTF-8?q?.2.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3149a3658f..ba6ec51bae 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.2.1 # automatically updated by Commitizen + rev: v4.2.2 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index ddcf5ff204..5ee93c0430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.2.2 (2025-02-18) + +### Fix + +- **bump**: manual version bump if prerelease offset is configured + ## v4.2.1 (2025-02-08) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index aef46acb47..2e905e44da 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.2.1" +__version__ = "4.2.2" diff --git a/pyproject.toml b/pyproject.toml index 24c3153b45..c63fe4d238 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.2.1" +version = "4.2.2" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -86,7 +86,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.2.1" +version = "4.2.2" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 7805412e33b191504ebfd59c26bc3f2efea082f1 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 31 Jan 2025 22:39:34 +0800 Subject: [PATCH 414/598] feat(providers): add uv_provider closes: #1349 --- commitizen/providers/uv_provider.py | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 commitizen/providers/uv_provider.py diff --git a/commitizen/providers/uv_provider.py b/commitizen/providers/uv_provider.py new file mode 100644 index 0000000000..36c8a49ad3 --- /dev/null +++ b/commitizen/providers/uv_provider.py @@ -0,0 +1,41 @@ +from __future__ import annotations + +from pathlib import Path +from typing import TYPE_CHECKING + +import tomlkit + +from commitizen.providers.base_provider import TomlProvider + +if TYPE_CHECKING: + import tomlkit.items + + +class UvProvider(TomlProvider): + """ + uv.lock and pyproject.tom version management + """ + + filename = "pyproject.toml" + lock_filename = "uv.lock" + + @property + def lock_file(self) -> Path: + return Path() / self.lock_filename + + def set_version(self, version: str) -> None: + super().set_version(version) + self.set_lock_version(version) + + def set_lock_version(self, version: str) -> None: + pyproject_toml_content = tomlkit.parse(self.file.read_text()) + project_name = pyproject_toml_content["project"]["name"] # type: ignore[index] + + document = tomlkit.parse(self.lock_file.read_text()) + + packages: tomlkit.items.AoT = document["package"] # type: ignore[assignment] + for i, package in enumerate(packages): + if package["name"] == project_name: + document["package"][i]["version"] = version # type: ignore[index] + break + self.lock_file.write_text(tomlkit.dumps(document)) From c2def94bee5d9b9b20b57951a1d042abdcbd4699 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Tue, 18 Feb 2025 21:29:30 +0800 Subject: [PATCH 415/598] test(providers/uv_provider): add test case test_uv_provider --- commitizen/providers/__init__.py | 2 + pyproject.toml | 21 ++-- tests/providers/test_uv_provider.py | 97 +++++++++++++++++++ .../test_uv_provider/test_uv_provider.lock | 42 ++++++++ .../test_uv_provider/test_uv_provider.toml | 8 ++ 5 files changed, 159 insertions(+), 11 deletions(-) create mode 100644 tests/providers/test_uv_provider.py create mode 100644 tests/providers/test_uv_provider/test_uv_provider.lock create mode 100644 tests/providers/test_uv_provider/test_uv_provider.toml diff --git a/commitizen/providers/__init__.py b/commitizen/providers/__init__.py index 3fd4ab1bfd..9cf4ce5927 100644 --- a/commitizen/providers/__init__.py +++ b/commitizen/providers/__init__.py @@ -18,6 +18,7 @@ from commitizen.providers.pep621_provider import Pep621Provider from commitizen.providers.poetry_provider import PoetryProvider from commitizen.providers.scm_provider import ScmProvider +from commitizen.providers.uv_provider import UvProvider __all__ = [ "get_provider", @@ -28,6 +29,7 @@ "Pep621Provider", "PoetryProvider", "ScmProvider", + "UvProvider", ] PROVIDER_ENTRYPOINT = "commitizen.provider" diff --git a/pyproject.toml b/pyproject.toml index c63fe4d238..416032db11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,6 +74,7 @@ npm = "commitizen.providers:NpmProvider" pep621 = "commitizen.providers:Pep621Provider" poetry = "commitizen.providers:PoetryProvider" scm = "commitizen.providers:ScmProvider" +uv = "commitizen.providers:UvProvider" [project.entry-points."commitizen.scheme"] pep440 = "commitizen.version_schemes:Pep440" @@ -165,9 +166,7 @@ omit = [ [tool.pytest.ini_options] addopts = "--strict-markers" -testpaths = [ - "tests/", -] +testpaths = ["tests/"] [tool.tox] requires = ["tox>=4.22"] @@ -178,7 +177,7 @@ description = "Run tests suite against Python {base_python}" skip_install = true deps = ["poetry>=2.0"] commands_pre = [["poetry", "install", "--only", "main,test"]] -commands = [["pytest", { replace = "posargs", extend = true}]] +commands = [["pytest", { replace = "posargs", extend = true }]] [tool.ruff] line-length = 88 @@ -227,14 +226,14 @@ poetry_command = "" [tool.poe.tasks] format.help = "Format the code" format.sequence = [ - {cmd = "ruff check --fix commitizen tests"}, - {cmd = "ruff format commitizen tests"}, + { cmd = "ruff check --fix commitizen tests" }, + { cmd = "ruff format commitizen tests" }, ] lint.help = "Lint the code" lint.sequence = [ - {cmd = "ruff check commitizen/ tests/ --fix"}, - {cmd = "mypy commitizen/ tests/"}, + { cmd = "ruff check commitizen/ tests/ --fix" }, + { cmd = "mypy commitizen/ tests/" }, ] check-commit.help = "Check the commit message" @@ -254,7 +253,7 @@ all.sequence = [ "format", "lint", "cover", - "check-commit" + "check-commit", ] "doc:screenshots".help = "Render documentation screeenshots" @@ -268,10 +267,10 @@ doc.cmd = "mkdocs serve" ci.help = "Run all tasks in CI" ci.sequence = [ - {cmd="pre-commit run --all-files"}, + { cmd = "pre-commit run --all-files" }, "cover", ] -ci.env = {SKIP = "no-commit-to-branch"} +ci.env = { SKIP = "no-commit-to-branch" } setup-pre-commit.help = "Install pre-commit hooks" setup-pre-commit.cmd = "pre-commit install" diff --git a/tests/providers/test_uv_provider.py b/tests/providers/test_uv_provider.py new file mode 100644 index 0000000000..4093709376 --- /dev/null +++ b/tests/providers/test_uv_provider.py @@ -0,0 +1,97 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from commitizen.config.base_config import BaseConfig +from commitizen.providers import get_provider +from commitizen.providers.uv_provider import UvProvider + +if TYPE_CHECKING: + from pytest_regressions.file_regression import FileRegressionFixture + + +PYPROJECT_TOML = """ +[project] +name = "test-uv" +version = "4.2.1" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = ["commitizen==4.2.1"] +""" + +UV_LOCK_SIMPLIFIED = """ +version = 1 +revision = 1 +requires-python = ">=3.13" + +[[package]] +name = "commitizen" +version = "4.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argcomplete" }, + { name = "charset-normalizer" }, + { name = "colorama" }, + { name = "decli" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "questionary" }, + { name = "termcolor" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/a3/77ffc9aee014cbf46c84c9f156a1ddef2d4c7cfb87d567decf2541464245/commitizen-4.2.1.tar.gz", hash = "sha256:5255416f6d6071068159f0b97605777f3e25d00927ff157b7a8d01efeda7b952", size = 50645 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/ce/2f5d8ebe8376991b5f805e9f33d20c7f4c9ca6155bdbda761117dc41dff1/commitizen-4.2.1-py3-none-any.whl", hash = "sha256:a347889e0fe408c3b920a34130d8f35616be3ea8ac6b7b20c5b9aac19762661b", size = 72646 }, +] + +[[package]] +name = "decli" +version = "0.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/a0/a4658f93ecb589f479037b164dc13c68d108b50bf6594e54c820749f97ac/decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f", size = 7424 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/70/3ea48dc9e958d7d66c44c9944809181f1ca79aaef25703c023b5092d34ff/decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed", size = 7854 }, +] + +[[package]] +name = "test-uv" +version = "4.2.1" +source = { virtual = "." } +dependencies = [ + { name = "commitizen" }, +] +""" + + +def test_uv_provider( + config: BaseConfig, tmpdir, file_regression: FileRegressionFixture +): + with tmpdir.as_cwd(): + pyproject_toml_file = tmpdir / UvProvider.filename + pyproject_toml_file.write_text(PYPROJECT_TOML, encoding="utf-8") + + uv_lock_file = tmpdir / UvProvider.lock_filename + uv_lock_file.write_text(UV_LOCK_SIMPLIFIED, encoding="utf-8") + + config.settings["version_provider"] = "uv" + + provider = get_provider(config) + assert isinstance(provider, UvProvider) + assert provider.get_version() == "4.2.1" + + provider.set_version("100.100.100") + assert provider.get_version() == "100.100.100" + + updated_pyproject_toml_content = pyproject_toml_file.read_text(encoding="utf-8") + updated_uv_lock_content = uv_lock_file.read_text(encoding="utf-8") + + for content in (updated_pyproject_toml_content, updated_uv_lock_content): + # updated project version + assert "100.100.100" in content + # commitizen version which was the same as project version and should not be affected + assert "4.2.1" in content + + file_regression.check(updated_pyproject_toml_content, extension=".toml") + file_regression.check(updated_uv_lock_content, extension=".lock") diff --git a/tests/providers/test_uv_provider/test_uv_provider.lock b/tests/providers/test_uv_provider/test_uv_provider.lock new file mode 100644 index 0000000000..d353763ce3 --- /dev/null +++ b/tests/providers/test_uv_provider/test_uv_provider.lock @@ -0,0 +1,42 @@ + +version = 1 +revision = 1 +requires-python = ">=3.13" + +[[package]] +name = "commitizen" +version = "4.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argcomplete" }, + { name = "charset-normalizer" }, + { name = "colorama" }, + { name = "decli" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "questionary" }, + { name = "termcolor" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/a3/77ffc9aee014cbf46c84c9f156a1ddef2d4c7cfb87d567decf2541464245/commitizen-4.2.1.tar.gz", hash = "sha256:5255416f6d6071068159f0b97605777f3e25d00927ff157b7a8d01efeda7b952", size = 50645 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/ce/2f5d8ebe8376991b5f805e9f33d20c7f4c9ca6155bdbda761117dc41dff1/commitizen-4.2.1-py3-none-any.whl", hash = "sha256:a347889e0fe408c3b920a34130d8f35616be3ea8ac6b7b20c5b9aac19762661b", size = 72646 }, +] + +[[package]] +name = "decli" +version = "0.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/a0/a4658f93ecb589f479037b164dc13c68d108b50bf6594e54c820749f97ac/decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f", size = 7424 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/70/3ea48dc9e958d7d66c44c9944809181f1ca79aaef25703c023b5092d34ff/decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed", size = 7854 }, +] + +[[package]] +name = "test-uv" +version = "100.100.100" +source = { virtual = "." } +dependencies = [ + { name = "commitizen" }, +] diff --git a/tests/providers/test_uv_provider/test_uv_provider.toml b/tests/providers/test_uv_provider/test_uv_provider.toml new file mode 100644 index 0000000000..9fdb6eb5aa --- /dev/null +++ b/tests/providers/test_uv_provider/test_uv_provider.toml @@ -0,0 +1,8 @@ + +[project] +name = "test-uv" +version = "100.100.100" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = ["commitizen==4.2.1"] From 9639da1539720377a39777fcde309e8426cdbf6f Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Tue, 18 Feb 2025 21:44:15 +0800 Subject: [PATCH 416/598] ci(pre-commit): ignore test file eof --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ba6ec51bae..392d1c040c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: hooks: - id: check-vcs-permalinks - id: end-of-file-fixer - exclude: "tests/((commands|data)/|test_).+" + exclude: "tests/((commands|data|providers/test_uv_provider)/|test_).+" - id: trailing-whitespace args: [ --markdown-linebreak-ext=md ] exclude: '\.svg$' From 63191a3ef4cf6aa4953f5b3be2a6c30fa9687430 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 28 Feb 2025 05:00:36 +0000 Subject: [PATCH 417/598] =?UTF-8?q?bump:=20version=204.2.2=20=E2=86=92=204?= =?UTF-8?q?.3.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 392d1c040c..dd16cc9cc4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.2.2 # automatically updated by Commitizen + rev: v4.3.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ee93c0430..fa7409d227 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.3.0 (2025-02-28) + +### Feat + +- **providers**: add uv_provider + ## v4.2.2 (2025-02-18) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 2e905e44da..111dc9172a 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.2.2" +__version__ = "4.3.0" diff --git a/pyproject.toml b/pyproject.toml index 416032db11..0c03a6d508 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.2.2" +version = "4.3.0" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -87,7 +87,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.2.2" +version = "4.3.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 5306cbf2436284e61b4e092c4e4e9e82c1317fcc Mon Sep 17 00:00:00 2001 From: "Axel H." Date: Sun, 17 Nov 2024 19:49:55 +0100 Subject: [PATCH 418/598] refactor(get_tag_regexes): dedup tag regexes definition --- commitizen/defaults.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index d776e38d7a..45b6500e0b 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -138,17 +138,15 @@ class Settings(TypedDict, total=False): def get_tag_regexes( version_regex: str, ) -> dict[str, str]: + regexs = { + "version": version_regex, + "major": r"(?P\d+)", + "minor": r"(?P\d+)", + "patch": r"(?P\d+)", + "prerelease": r"(?P\w+\d+)?", + "devrelease": r"(?P\.dev\d+)?", + } return { - "$version": version_regex, - "$major": r"(?P\d+)", - "$minor": r"(?P\d+)", - "$patch": r"(?P\d+)", - "$prerelease": r"(?P\w+\d+)?", - "$devrelease": r"(?P\.dev\d+)?", - "${version}": version_regex, - "${major}": r"(?P\d+)", - "${minor}": r"(?P\d+)", - "${patch}": r"(?P\d+)", - "${prerelease}": r"(?P\w+\d+)?", - "${devrelease}": r"(?P\.dev\d+)?", + **{f"${k}": v for k, v in regexs.items()}, + **{f"${{{k}}}": v for k, v in regexs.items()}, } From 74554c2b4244341cda0f0db177fb78fa99d86646 Mon Sep 17 00:00:00 2001 From: "Axel H." Date: Mon, 18 Nov 2024 03:54:21 +0100 Subject: [PATCH 419/598] feat(tags): adds `legacy_tag_formats` and `ignored_tag_formats` settings --- commitizen/bump.py | 30 +- commitizen/changelog.py | 84 ++---- commitizen/changelog_formats/asciidoc.py | 23 +- commitizen/changelog_formats/base.py | 28 +- commitizen/changelog_formats/markdown.py | 25 +- .../changelog_formats/restructuredtext.py | 31 +-- commitizen/changelog_formats/textile.py | 28 +- commitizen/commands/bump.py | 38 +-- commitizen/commands/changelog.py | 39 ++- commitizen/commands/init.py | 2 +- commitizen/defaults.py | 6 +- commitizen/providers/scm_provider.py | 66 +---- commitizen/tags.py | 257 ++++++++++++++++++ commitizen/version_schemes.py | 12 +- docs/config.md | 20 ++ docs/faq.md | 33 +++ docs/tutorials/monorepo_guidance.md | 2 + docs/tutorials/tag_format.md | 101 +++++++ mkdocs.yml | 1 + tests/commands/test_bump_command.py | 29 ++ tests/commands/test_changelog_command.py | 242 ++++++++++++++--- ...from_rev_version_range_with_legacy_tags.md | 17 ++ ...changelog_incremental_change_tag_format.md | 17 ++ tests/providers/test_scm_provider.py | 23 ++ tests/test_bump_normalize_tag.py | 5 +- tests/test_changelog.py | 115 +++++++- tests/test_changelog_format_asciidoc.py | 19 +- tests/test_changelog_format_markdown.py | 19 +- .../test_changelog_format_restructuredtext.py | 5 + tests/test_changelog_format_textile.py | 19 +- tests/test_conf.py | 4 + tests/test_version_schemes.py | 14 +- 32 files changed, 982 insertions(+), 372 deletions(-) create mode 100644 commitizen/tags.py create mode 100644 docs/tutorials/tag_format.md create mode 100644 tests/commands/test_changelog_command/test_changelog_from_rev_version_range_with_legacy_tags.md create mode 100644 tests/commands/test_changelog_command/test_changelog_incremental_change_tag_format.md diff --git a/commitizen/bump.py b/commitizen/bump.py index 908899eb0e..adfab64cb0 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -11,7 +11,7 @@ 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, Increment, Version, VersionScheme +from commitizen.version_schemes import Increment, Version VERSION_TYPES = [None, PATCH, MINOR, MAJOR] @@ -142,34 +142,6 @@ def _version_to_regex(version: str) -> str: return version.replace(".", r"\.").replace("+", r"\+") -def normalize_tag( - version: Version | str, - tag_format: str, - scheme: VersionScheme | None = None, -) -> str: - """The tag and the software version might be different. - - That's why this function exists. - - Example: - | tag | version (PEP 0440) | - | --- | ------- | - | v0.9.0 | 0.9.0 | - | ver1.0.0 | 1.0.0 | - | ver1.0.0.a0 | 1.0.0a0 | - """ - scheme = scheme or DEFAULT_SCHEME - version = scheme(version) if isinstance(version, str) else version - - major, minor, patch = version.release - prerelease = version.prerelease or "" - - t = Template(tag_format) - return t.safe_substitute( - version=version, major=major, minor=minor, patch=patch, prerelease=prerelease - ) - - def create_commit_message( current_version: Version | str, new_version: Version | str, diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 7f300354b6..95bf21d6f9 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -42,21 +42,13 @@ Template, ) -from commitizen import out -from commitizen.bump import normalize_tag from commitizen.cz.base import ChangelogReleaseHook -from commitizen.defaults import get_tag_regexes from commitizen.exceptions import InvalidConfigurationError, NoCommitsFoundError from commitizen.git import GitCommit, GitTag -from commitizen.version_schemes import ( - DEFAULT_SCHEME, - BaseVersion, - InvalidVersion, -) +from commitizen.tags import TagRules if TYPE_CHECKING: from commitizen.cz.base import MessageBuilderHook - from commitizen.version_schemes import VersionScheme @dataclass @@ -69,50 +61,19 @@ class Metadata: unreleased_end: int | None = None latest_version: str | None = None latest_version_position: int | None = None + latest_version_tag: str | None = None + + def __post_init__(self): + if self.latest_version and not self.latest_version_tag: + # Test syntactic sugar + # latest version tag is optional if same as latest version + self.latest_version_tag = self.latest_version def get_commit_tag(commit: GitCommit, tags: list[GitTag]) -> GitTag | None: return next((tag for tag in tags if tag.rev == commit.rev), None) -def tag_included_in_changelog( - tag: GitTag, - used_tags: list, - merge_prerelease: bool, - scheme: VersionScheme = DEFAULT_SCHEME, -) -> bool: - if tag in used_tags: - return False - - try: - version = scheme(tag.name) - except InvalidVersion: - return False - - if merge_prerelease and version.is_prerelease: - return False - - return True - - -def get_version_tags( - scheme: type[BaseVersion], tags: list[GitTag], tag_format: str -) -> list[GitTag]: - valid_tags: list[GitTag] = [] - TAG_FORMAT_REGEXS = get_tag_regexes(scheme.parser.pattern) - tag_format_regex = tag_format - for pattern, regex in TAG_FORMAT_REGEXS.items(): - tag_format_regex = tag_format_regex.replace(pattern, regex) - for tag in tags: - if re.match(tag_format_regex, tag.name): - valid_tags.append(tag) - else: - out.warn( - f"InvalidVersion {tag.name} doesn't match configured tag format {tag_format}" - ) - return valid_tags - - def generate_tree_from_commits( commits: list[GitCommit], tags: list[GitTag], @@ -122,13 +83,13 @@ def generate_tree_from_commits( change_type_map: dict[str, str] | None = None, changelog_message_builder_hook: MessageBuilderHook | None = None, changelog_release_hook: ChangelogReleaseHook | None = None, - merge_prerelease: bool = False, - scheme: VersionScheme = DEFAULT_SCHEME, + rules: TagRules | None = None, ) -> Iterable[dict]: pat = re.compile(changelog_pattern) map_pat = re.compile(commit_parser, re.MULTILINE) body_map_pat = re.compile(commit_parser, re.MULTILINE | re.DOTALL) current_tag: GitTag | None = None + rules = rules or TagRules() # Check if the latest commit is not tagged if commits: @@ -148,8 +109,10 @@ def generate_tree_from_commits( for commit in commits: commit_tag = get_commit_tag(commit, tags) - if commit_tag is not None and tag_included_in_changelog( - commit_tag, used_tags, merge_prerelease, scheme=scheme + if ( + commit_tag + and commit_tag not in used_tags + and rules.include_in_changelog(commit_tag) ): used_tags.append(commit_tag) release = { @@ -343,8 +306,7 @@ def get_smart_tag_range( def get_oldest_and_newest_rev( tags: list[GitTag], version: str, - tag_format: str, - scheme: VersionScheme | None = None, + rules: TagRules, ) -> tuple[str | None, str | None]: """Find the tags for the given version. @@ -358,22 +320,28 @@ def get_oldest_and_newest_rev( oldest, newest = version.split("..") except ValueError: newest = version - newest_tag = normalize_tag(newest, tag_format=tag_format, scheme=scheme) + if not (newest_tag := rules.find_tag_for(tags, newest)): + raise NoCommitsFoundError("Could not find a valid revision range.") oldest_tag = None + oldest_tag_name = None if oldest: - oldest_tag = normalize_tag(oldest, tag_format=tag_format, scheme=scheme) + if not (oldest_tag := rules.find_tag_for(tags, oldest)): + raise NoCommitsFoundError("Could not find a valid revision range.") + oldest_tag_name = oldest_tag.name - tags_range = get_smart_tag_range(tags, newest=newest_tag, oldest=oldest_tag) + tags_range = get_smart_tag_range( + tags, newest=newest_tag.name, oldest=oldest_tag_name + ) if not tags_range: raise NoCommitsFoundError("Could not find a valid revision range.") oldest_rev: str | None = tags_range[-1].name - newest_rev = newest_tag + newest_rev = newest_tag.name # check if it's the first tag created # and it's also being requested as part of the range - if oldest_rev == tags[-1].name and oldest_rev == oldest_tag: + if oldest_rev == tags[-1].name and oldest_rev == oldest_tag_name: return None, newest_rev # when they are the same, and it's also the diff --git a/commitizen/changelog_formats/asciidoc.py b/commitizen/changelog_formats/asciidoc.py index 6007a56d16..ed3e8607bd 100644 --- a/commitizen/changelog_formats/asciidoc.py +++ b/commitizen/changelog_formats/asciidoc.py @@ -1,36 +1,25 @@ from __future__ import annotations import re +from typing import TYPE_CHECKING from .base import BaseFormat +if TYPE_CHECKING: + from commitizen.tags import VersionTag + class AsciiDoc(BaseFormat): extension = "adoc" RE_TITLE = re.compile(r"^(?P=+) (?P.*)$") - def parse_version_from_title(self, line: str) -> str | None: + def parse_version_from_title(self, line: str) -> VersionTag | None: m = self.RE_TITLE.match(line) if not m: return None # Capture last match as AsciiDoc use postfixed URL labels - matches = list(re.finditer(self.version_parser, m.group("title"))) - if not matches: - return None - if "version" in matches[-1].groupdict(): - return matches[-1].group("version") - partial_matches = matches[-1].groupdict() - try: - partial_version = f"{partial_matches['major']}.{partial_matches['minor']}.{partial_matches['patch']}" - except KeyError: - return None - - if partial_matches.get("prerelease"): - partial_version = f"{partial_version}-{partial_matches['prerelease']}" - if partial_matches.get("devrelease"): - partial_version = f"{partial_version}{partial_matches['devrelease']}" - return partial_version + return self.tag_rules.search_version(m.group("title"), last=True) def parse_title_level(self, line: str) -> int | None: m = self.RE_TITLE.match(line) diff --git a/commitizen/changelog_formats/base.py b/commitizen/changelog_formats/base.py index 53527a060c..f69cf8f00f 100644 --- a/commitizen/changelog_formats/base.py +++ b/commitizen/changelog_formats/base.py @@ -1,14 +1,12 @@ from __future__ import annotations import os -import re from abc import ABCMeta -from re import Pattern from typing import IO, Any, ClassVar from commitizen.changelog import Metadata from commitizen.config.base_config import BaseConfig -from commitizen.defaults import get_tag_regexes +from commitizen.tags import TagRules, VersionTag from commitizen.version_schemes import get_version_scheme from . import ChangelogFormat @@ -28,15 +26,12 @@ def __init__(self, config: BaseConfig): self.config = config self.encoding = self.config.settings["encoding"] self.tag_format = self.config.settings["tag_format"] - - @property - def version_parser(self) -> Pattern: - tag_regex: str = self.tag_format - version_regex = get_version_scheme(self.config).parser.pattern - TAG_FORMAT_REGEXS = get_tag_regexes(version_regex) - for pattern, regex in TAG_FORMAT_REGEXS.items(): - tag_regex = tag_regex.replace(pattern, regex) - return re.compile(tag_regex) + self.tag_rules = TagRules( + scheme=get_version_scheme(self.config.settings), + tag_format=self.tag_format, + legacy_tag_formats=self.config.settings["legacy_tag_formats"], + ignored_tag_formats=self.config.settings["ignored_tag_formats"], + ) def get_metadata(self, filepath: str) -> Metadata: if not os.path.isfile(filepath): @@ -63,9 +58,10 @@ def get_metadata_from_file(self, file: IO[Any]) -> Metadata: meta.unreleased_end = index # Try to find the latest release done - version = self.parse_version_from_title(line) - if version: - meta.latest_version = version + parsed = self.parse_version_from_title(line) + if parsed: + meta.latest_version = parsed.version + meta.latest_version_tag = parsed.tag meta.latest_version_position = index break # there's no need for more info if meta.unreleased_start is not None and meta.unreleased_end is None: @@ -73,7 +69,7 @@ def get_metadata_from_file(self, file: IO[Any]) -> Metadata: return meta - def parse_version_from_title(self, line: str) -> str | None: + def parse_version_from_title(self, line: str) -> VersionTag | None: """ Extract the version from a title line if any """ diff --git a/commitizen/changelog_formats/markdown.py b/commitizen/changelog_formats/markdown.py index 29c1cce54a..e3d30fe174 100644 --- a/commitizen/changelog_formats/markdown.py +++ b/commitizen/changelog_formats/markdown.py @@ -1,9 +1,13 @@ from __future__ import annotations import re +from typing import TYPE_CHECKING from .base import BaseFormat +if TYPE_CHECKING: + from commitizen.tags import VersionTag + class Markdown(BaseFormat): extension = "md" @@ -12,28 +16,11 @@ class Markdown(BaseFormat): RE_TITLE = re.compile(r"^(?P#+) (?P.*)$") - def parse_version_from_title(self, line: str) -> str | None: + def parse_version_from_title(self, line: str) -> VersionTag | None: m = self.RE_TITLE.match(line) if not m: return None - m = re.search(self.version_parser, m.group("title")) - if not m: - return None - if "version" in m.groupdict(): - return m.group("version") - matches = m.groupdict() - try: - partial_version = ( - f"{matches['major']}.{matches['minor']}.{matches['patch']}" - ) - except KeyError: - return None - - if matches.get("prerelease"): - partial_version = f"{partial_version}-{matches['prerelease']}" - if matches.get("devrelease"): - partial_version = f"{partial_version}{matches['devrelease']}" - return partial_version + return self.tag_rules.search_version(m.group("title")) def parse_title_level(self, line: str) -> int | None: m = self.RE_TITLE.match(line) diff --git a/commitizen/changelog_formats/restructuredtext.py b/commitizen/changelog_formats/restructuredtext.py index 8bcf9a4a4f..b7e4e105a1 100644 --- a/commitizen/changelog_formats/restructuredtext.py +++ b/commitizen/changelog_formats/restructuredtext.py @@ -1,6 +1,5 @@ from __future__ import annotations -import re import sys from itertools import zip_longest from typing import IO, TYPE_CHECKING, Any, Union @@ -64,31 +63,11 @@ def get_metadata_from_file(self, file: IO[Any]) -> Metadata: elif unreleased_title_kind and unreleased_title_kind == kind: meta.unreleased_end = index # Try to find the latest release done - m = re.search(self.version_parser, title) - if m: - matches = m.groupdict() - if "version" in matches: - version = m.group("version") - meta.latest_version = version - meta.latest_version_position = index - break # there's no need for more info - try: - partial_version = ( - f"{matches['major']}.{matches['minor']}.{matches['patch']}" - ) - if matches.get("prerelease"): - partial_version = ( - f"{partial_version}-{matches['prerelease']}" - ) - if matches.get("devrelease"): - partial_version = ( - f"{partial_version}{matches['devrelease']}" - ) - meta.latest_version = partial_version - meta.latest_version_position = index - break - except KeyError: - pass + if version := self.tag_rules.search_version(title): + meta.latest_version = version[0] + meta.latest_version_tag = version[1] + meta.latest_version_position = index + break if meta.unreleased_start is not None and meta.unreleased_end is None: meta.unreleased_end = ( meta.latest_version_position if meta.latest_version else index + 1 diff --git a/commitizen/changelog_formats/textile.py b/commitizen/changelog_formats/textile.py index 8750f0056c..6693e5e002 100644 --- a/commitizen/changelog_formats/textile.py +++ b/commitizen/changelog_formats/textile.py @@ -1,39 +1,23 @@ from __future__ import annotations import re +from typing import TYPE_CHECKING from .base import BaseFormat +if TYPE_CHECKING: + from commitizen.tags import VersionTag + class Textile(BaseFormat): extension = "textile" RE_TITLE = re.compile(r"^h(?P<level>\d)\. (?P<title>.*)$") - def parse_version_from_title(self, line: str) -> str | None: + def parse_version_from_title(self, line: str) -> VersionTag | None: if not self.RE_TITLE.match(line): return None - m = re.search(self.version_parser, line) - if not m: - return None - if "version" in m.groupdict(): - return m.group("version") - matches = m.groupdict() - if not all( - [ - version_segment in matches - for version_segment in ("major", "minor", "patch") - ] - ): - return None - - partial_version = f"{matches['major']}.{matches['minor']}.{matches['patch']}" - - if matches.get("prerelease"): - partial_version = f"{partial_version}-{matches['prerelease']}" - if matches.get("devrelease"): - partial_version = f"{partial_version}{matches['devrelease']}" - return partial_version + return self.tag_rules.search_version(line) def parse_title_level(self, line: str) -> int | None: m = self.RE_TITLE.match(line) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 8e9f0f181b..60853094f9 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -2,6 +2,7 @@ import warnings from logging import getLogger +from typing import cast import questionary @@ -9,6 +10,7 @@ from commitizen.changelog_formats import get_changelog_format from commitizen.commands.changelog import Changelog from commitizen.config import BaseConfig +from commitizen.defaults import Settings from commitizen.exceptions import ( BumpCommitFailedError, BumpTagFailedError, @@ -24,6 +26,7 @@ NoVersionSpecifiedError, ) from commitizen.providers import get_provider +from commitizen.tags import TagRules from commitizen.version_schemes import ( Increment, InvalidVersion, @@ -84,7 +87,7 @@ def __init__(self, config: BaseConfig, arguments: dict): ) ) self.scheme = get_version_scheme( - self.config, arguments["version_scheme"] or deprecated_version_type + self.config.settings, arguments["version_scheme"] or deprecated_version_type ) self.file_name = arguments["file_name"] or self.config.settings.get( "changelog_file" @@ -98,18 +101,20 @@ def __init__(self, config: BaseConfig, arguments: dict): ) self.extras = arguments["extras"] - def is_initial_tag(self, current_tag_version: str, is_yes: bool = False) -> bool: + def is_initial_tag( + self, current_tag: git.GitTag | None, is_yes: bool = False + ) -> bool: """Check if reading the whole git tree up to HEAD is needed.""" is_initial = False - if not git.tag_exist(current_tag_version): + if not current_tag: if is_yes: is_initial = True else: - out.info(f"Tag {current_tag_version} could not be found. ") + out.info("No tag matching configuration could not be found.") out.info( "Possible causes:\n" "- version in configuration is not the current version\n" - "- tag_format is missing, check them using 'git tag --list'\n" + "- tag_format or legacy_tag_formats is missing, check them using 'git tag --list'\n" ) is_initial = questionary.confirm("Is this the first tag created?").ask() return is_initial @@ -143,7 +148,6 @@ def __call__(self) -> None: # noqa: C901 except TypeError: raise NoVersionSpecifiedError() - tag_format: str = self.bump_settings["tag_format"] bump_commit_message: str = self.bump_settings["bump_message"] version_files: list[str] = self.bump_settings["version_files"] major_version_zero: bool = self.bump_settings["major_version_zero"] @@ -221,13 +225,13 @@ def __call__(self) -> None: # noqa: C901 or self.changelog_config ) - current_tag_version: str = bump.normalize_tag( - current_version, - tag_format=tag_format, - scheme=self.scheme, + rules = TagRules.from_settings(cast(Settings, self.bump_settings)) + current_tag = rules.find_tag_for(git.get_tags(), current_version) + current_tag_version = getattr( + current_tag, "name", rules.normalize_tag(current_version) ) - is_initial = self.is_initial_tag(current_tag_version, is_yes) + is_initial = self.is_initial_tag(current_tag, is_yes) if manual_version: try: @@ -239,10 +243,10 @@ def __call__(self) -> None: # noqa: C901 ) from exc else: if increment is None: - if is_initial: - commits = git.get_commits() + if current_tag: + commits = git.get_commits(current_tag.name) else: - commits = git.get_commits(current_tag_version) + commits = git.get_commits() # No commits, there is no need to create an empty tag. # Unless we previously had a prerelease. @@ -280,11 +284,7 @@ def __call__(self) -> None: # noqa: C901 exact_increment=increment_mode == "exact", ) - new_tag_version = bump.normalize_tag( - new_version, - tag_format=tag_format, - scheme=self.scheme, - ) + new_tag_version = rules.normalize_tag(new_version) message = bump.create_commit_message( current_version, new_version, bump_commit_message ) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 25e644aaef..80a72651e4 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -6,7 +6,7 @@ from pathlib import Path from typing import Callable, cast -from commitizen import bump, changelog, defaults, factory, git, out +from commitizen import changelog, defaults, factory, git, out from commitizen.changelog_formats import get_changelog_format from commitizen.config import BaseConfig from commitizen.cz.base import ChangelogReleaseHook, MessageBuilderHook @@ -20,6 +20,7 @@ NotAllowed, ) from commitizen.git import GitTag, smart_open +from commitizen.tags import TagRules from commitizen.version_schemes import get_version_scheme @@ -53,7 +54,9 @@ def __init__(self, config: BaseConfig, args): ) self.dry_run = args["dry_run"] - self.scheme = get_version_scheme(self.config, args.get("version_scheme")) + self.scheme = get_version_scheme( + self.config.settings, args.get("version_scheme") + ) current_version = ( args.get("current_version", config.settings.get("version")) or "" @@ -73,9 +76,14 @@ def __init__(self, config: BaseConfig, args): self.tag_format: str = ( args.get("tag_format") or self.config.settings["tag_format"] ) - self.merge_prerelease = args.get( - "merge_prerelease" - ) or self.config.settings.get("changelog_merge_prerelease") + self.tag_rules = TagRules( + scheme=self.scheme, + tag_format=self.tag_format, + legacy_tag_formats=self.config.settings["legacy_tag_formats"], + ignored_tag_formats=self.config.settings["ignored_tag_formats"], + merge_prereleases=args.get("merge_prerelease") + or self.config.settings["changelog_merge_prerelease"], + ) self.template = ( args.get("template") @@ -152,7 +160,6 @@ def __call__(self): changelog_release_hook: ChangelogReleaseHook | None = ( self.cz.changelog_release_hook ) - merge_prerelease = self.merge_prerelease if self.export_template_to: return self.export_template() @@ -168,28 +175,19 @@ def __call__(self): # Don't continue if no `file_name` specified. assert self.file_name - tags = ( - changelog.get_version_tags(self.scheme, git.get_tags(), self.tag_format) - or [] - ) + tags = self.tag_rules.get_version_tags(git.get_tags(), warn=True) end_rev = "" if self.incremental: changelog_meta = self.changelog_format.get_metadata(self.file_name) if changelog_meta.latest_version: - latest_tag_version: str = bump.normalize_tag( - changelog_meta.latest_version, - tag_format=self.tag_format, - scheme=self.scheme, - ) start_rev = self._find_incremental_rev( - strip_local_version(latest_tag_version), tags + strip_local_version(changelog_meta.latest_version_tag), tags ) if self.rev_range: start_rev, end_rev = changelog.get_oldest_and_newest_rev( tags, - version=self.rev_range, - tag_format=self.tag_format, - scheme=self.scheme, + self.rev_range, + self.tag_rules, ) commits = git.get_commits(start=start_rev, end=end_rev, args="--topo-order") if not commits and ( @@ -205,8 +203,7 @@ def __call__(self): change_type_map=change_type_map, changelog_message_builder_hook=changelog_message_builder_hook, changelog_release_hook=changelog_release_hook, - merge_prerelease=merge_prerelease, - scheme=self.scheme, + rules=self.tag_rules, ) if self.change_type_order: tree = changelog.order_changelog_tree(tree, self.change_type_order) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index ffc5e3eb3b..e39dfbe291 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -98,7 +98,7 @@ def __call__(self): version_provider = self._ask_version_provider() # select tag = self._ask_tag() # confirm & select version_scheme = self._ask_version_scheme() # select - version = get_version_scheme(self.config, version_scheme)(tag) + version = get_version_scheme(self.config.settings, version_scheme)(tag) tag_format = self._ask_tag_format(tag) # confirm & text update_changelog_on_bump = self._ask_update_changelog_on_bump() # confirm major_version_zero = self._ask_major_version_zero(version) # confirm diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 45b6500e0b..0b78e1b0bb 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -2,7 +2,7 @@ import pathlib from collections import OrderedDict -from collections.abc import Iterable, MutableMapping +from collections.abc import Iterable, MutableMapping, Sequence from typing import Any, TypedDict # Type @@ -35,6 +35,8 @@ class Settings(TypedDict, total=False): version_scheme: str | None version_type: str | None tag_format: str + legacy_tag_formats: Sequence[str] + ignored_tag_formats: Sequence[str] bump_message: str | None retry_after_failure: bool allow_abort: bool @@ -77,6 +79,8 @@ class Settings(TypedDict, total=False): "version_provider": "commitizen", "version_scheme": None, "tag_format": "$version", # example v$version + "legacy_tag_formats": [], + "ignored_tag_formats": [], "bump_message": None, # bumped v$current_version to $new_version "retry_after_failure": False, "allow_abort": False, diff --git a/commitizen/providers/scm_provider.py b/commitizen/providers/scm_provider.py index 33e470cfc6..cb575148cb 100644 --- a/commitizen/providers/scm_provider.py +++ b/commitizen/providers/scm_provider.py @@ -1,17 +1,8 @@ from __future__ import annotations -import re -from typing import Callable - -from commitizen.defaults import get_tag_regexes from commitizen.git import get_tags from commitizen.providers.base_provider import VersionProvider -from commitizen.version_schemes import ( - InvalidVersion, - Version, - VersionProtocol, - get_version_scheme, -) +from commitizen.tags import TagRules class ScmProvider(VersionProvider): @@ -23,57 +14,14 @@ class ScmProvider(VersionProvider): It is meant for `setuptools-scm` or any package manager `*-scm` provider. """ - TAG_FORMAT_REGEXS = get_tag_regexes(r"(?P<version>.+)") - - def _tag_format_matcher(self) -> Callable[[str], VersionProtocol | None]: - version_scheme = get_version_scheme(self.config) - pattern = self.config.settings["tag_format"] - if pattern == "$version": - pattern = version_scheme.parser.pattern - for var, tag_pattern in self.TAG_FORMAT_REGEXS.items(): - pattern = pattern.replace(var, tag_pattern) - - regex = re.compile(f"^{pattern}$", re.VERBOSE) - - def matcher(tag: str) -> Version | None: - match = regex.match(tag) - if not match: - return None - groups = match.groupdict() - if "version" in groups: - ver = groups["version"] - elif "major" in groups: - ver = "".join( - ( - groups["major"], - f".{groups['minor']}" if groups.get("minor") else "", - f".{groups['patch']}" if groups.get("patch") else "", - groups["prerelease"] if groups.get("prerelease") else "", - groups["devrelease"] if groups.get("devrelease") else "", - ) - ) - elif pattern == version_scheme.parser.pattern: - ver = tag - else: - return None - - try: - return version_scheme(ver) - except InvalidVersion: - return None - - return matcher - def get_version(self) -> str: - matcher = self._tag_format_matcher() - matches = sorted( - version - for t in get_tags(reachable_only=True) - if (version := matcher(t.name)) - ) - if not matches: + rules = TagRules.from_settings(self.config.settings) + tags = get_tags(reachable_only=True) + version_tags = rules.get_version_tags(tags) + versions = sorted(rules.extract_version(t) for t in version_tags) + if not versions: return "0.0.0" - return str(matches[-1]) + return str(versions[-1]) def set_version(self, version: str): # Not necessary diff --git a/commitizen/tags.py b/commitizen/tags.py new file mode 100644 index 0000000000..962e428ef2 --- /dev/null +++ b/commitizen/tags.py @@ -0,0 +1,257 @@ +from __future__ import annotations + +import re +import warnings +from collections.abc import Sequence +from dataclasses import dataclass, field +from functools import cached_property +from string import Template +from typing import TYPE_CHECKING, NamedTuple + +from typing_extensions import Self + +from commitizen import out +from commitizen.defaults import DEFAULT_SETTINGS, Settings, get_tag_regexes +from commitizen.git import GitTag +from commitizen.version_schemes import ( + DEFAULT_SCHEME, + InvalidVersion, + Version, + VersionScheme, + get_version_scheme, +) + +if TYPE_CHECKING: + from commitizen.version_schemes import VersionScheme + + +class VersionTag(NamedTuple): + """Represent a version and its matching tag form.""" + + version: str + tag: str + + +@dataclass +class TagRules: + """ + Encapsulate tag-related rules. + + It allows to filter or match tags according to rules provided in settings: + - `tag_format`: the current format of the tags generated on `bump` + - `legacy_tag_formats`: previous known formats of the tag + - `ignored_tag_formats`: known formats that should be ignored + - `merge_prereleases`: if `True`, prereleases will be merged with their release counterpart + - `version_scheme`: the version scheme to use, which will be used to parse and format versions + + This class is meant to abstract and centralize all the logic related to tags. + To ensure consistency, it is recommended to use this class to handle tags. + + Example: + + ```py + settings = DEFAULT_SETTINGS.clone() + settings.update({ + "tag_format": "v{version}" + "legacy_tag_formats": ["version{version}", "ver{version}"], + "ignored_tag_formats": ["ignored{version}"], + }) + + rules = TagRules.from_settings(settings) + + assert rules.is_version_tag("v1.0.0") + assert rules.is_version_tag("version1.0.0") + assert rules.is_version_tag("ver1.0.0") + assert not rules.is_version_tag("ignored1.0.0", warn=True) # Does not warn + assert not rules.is_version_tag("warn1.0.0", warn=True) # Does warn + + assert rules.search_version("# My v1.0.0 version").version == "1.0.0" + assert rules.extract_version("v1.0.0") == Version("1.0.0") + try: + assert rules.extract_version("not-a-v1.0.0") + except InvalidVersion: + print "Does not match a tag format" + ``` + """ + + scheme: VersionScheme = DEFAULT_SCHEME + tag_format: str = DEFAULT_SETTINGS["tag_format"] + legacy_tag_formats: Sequence[str] = field(default_factory=list) + ignored_tag_formats: Sequence[str] = field(default_factory=list) + merge_prereleases: bool = False + + @cached_property + def version_regexes(self) -> Sequence[re.Pattern]: + """Regexes for all legit tag formats, current and legacy""" + tag_formats = [self.tag_format, *self.legacy_tag_formats] + regexes = (self._format_regex(p) for p in tag_formats) + return [re.compile(r) for r in regexes] + + @cached_property + def ignored_regexes(self) -> Sequence[re.Pattern]: + """Regexes for known but ignored tag formats""" + regexes = (self._format_regex(p, star=True) for p in self.ignored_tag_formats) + return [re.compile(r) for r in regexes] + + def _format_regex(self, tag_pattern: str, star: bool = False) -> str: + """ + Format a tag pattern into a regex pattern. + + If star is `True`, the `*` character will be considered as a wildcard. + """ + tag_regexes = get_tag_regexes(self.scheme.parser.pattern) + format_regex = tag_pattern.replace("*", "(?:.*?)") if star else tag_pattern + for pattern, regex in tag_regexes.items(): + format_regex = format_regex.replace(pattern, regex) + return format_regex + + def is_version_tag(self, tag: str | GitTag, warn: bool = False) -> bool: + """ + True if a given tag is a legit version tag. + + if `warn` is `True`, it will print a warning message if the tag is not a version tag. + """ + tag = tag.name if isinstance(tag, GitTag) else tag + is_legit = any(regex.match(tag) for regex in self.version_regexes) + if warn and not is_legit and not self.is_ignored_tag(tag): + out.warn(f"InvalidVersion {tag} doesn't match any configured tag format") + return is_legit + + def is_ignored_tag(self, tag: str | GitTag) -> bool: + """True if a given tag can be ignored""" + tag = tag.name if isinstance(tag, GitTag) else tag + return any(regex.match(tag) for regex in self.ignored_regexes) + + def get_version_tags( + self, tags: Sequence[GitTag], warn: bool = False + ) -> Sequence[GitTag]: + """Filter in version tags and warn on unexpected tags""" + return [tag for tag in tags if self.is_version_tag(tag, warn)] + + def extract_version(self, tag: GitTag) -> Version: + """ + Extract a version from the tag as defined in tag formats. + + Raises `InvalidVersion` if the tag does not match any format. + """ + candidates = ( + m for regex in self.version_regexes if (m := regex.fullmatch(tag.name)) + ) + if not (m := next(candidates, None)): + raise InvalidVersion() + if "version" in m.groupdict(): + return self.scheme(m.group("version")) + + parts = m.groupdict() + version = parts["major"] + + if minor := parts.get("minor"): + version = f"{version}.{minor}" + if patch := parts.get("patch"): + version = f"{version}.{patch}" + + if parts.get("prerelease"): + version = f"{version}-{parts['prerelease']}" + if parts.get("devrelease"): + version = f"{version}{parts['devrelease']}" + return self.scheme(version) + + def include_in_changelog(self, tag: GitTag) -> bool: + """Check if a tag should be included in the changelog""" + try: + version = self.extract_version(tag) + except InvalidVersion: + return False + + if self.merge_prereleases and version.is_prerelease: + return False + + return True + + def search_version(self, text: str, last: bool = False) -> VersionTag | None: + """ + Search the first or last version tag occurrence in text. + + It searches for complete versions only (aka `major`, `minor` and `patch`) + """ + candidates = ( + m for regex in self.version_regexes if len(m := list(regex.finditer(text))) + ) + if not (matches := next(candidates, [])): + return None + + match = matches[-1 if last else 0] + + if "version" in match.groupdict(): + return VersionTag(match.group("version"), match.group(0)) + + parts = match.groupdict() + try: + version = f"{parts['major']}.{parts['minor']}.{parts['patch']}" + except KeyError: + return None + + if parts.get("prerelease"): + version = f"{version}-{parts['prerelease']}" + if parts.get("devrelease"): + version = f"{version}{parts['devrelease']}" + return VersionTag(version, match.group(0)) + + def normalize_tag( + self, version: Version | str, tag_format: str | None = None + ) -> str: + """ + The tag and the software version might be different. + + That's why this function exists. + + Example: + | tag | version (PEP 0440) | + | --- | ------- | + | v0.9.0 | 0.9.0 | + | ver1.0.0 | 1.0.0 | + | ver1.0.0.a0 | 1.0.0a0 | + """ + version = self.scheme(version) if isinstance(version, str) else version + tag_format = tag_format or self.tag_format + + major, minor, patch = version.release + prerelease = version.prerelease or "" + + t = Template(tag_format) + return t.safe_substitute( + version=version, + major=major, + minor=minor, + patch=patch, + prerelease=prerelease, + ) + + def find_tag_for( + self, tags: Sequence[GitTag], version: Version | str + ) -> GitTag | None: + """Find the first matching tag for a given version.""" + version = self.scheme(version) if isinstance(version, str) else version + possible_tags = [ + self.normalize_tag(version, f) + for f in (self.tag_format, *self.legacy_tag_formats) + ] + candidates = [t for t in tags if any(t.name == p for p in possible_tags)] + if len(candidates) > 1: + warnings.warn( + UserWarning( + f"Multiple tags found for version {version}: {', '.join(t.name for t in candidates)}" + ) + ) + return next(iter(candidates), None) + + @classmethod + def from_settings(cls, settings: Settings) -> Self: + """Extract tag rules from settings""" + return cls( + scheme=get_version_scheme(settings), + tag_format=settings["tag_format"], + legacy_tag_formats=settings["legacy_tag_formats"], + ignored_tag_formats=settings["ignored_tag_formats"], + merge_prereleases=settings["changelog_merge_prerelease"], + ) diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 554864e3bf..2486be58c8 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -22,8 +22,7 @@ from packaging.version import InvalidVersion # noqa: F401: Rexpose the common exception from packaging.version import Version as _BaseVersion -from commitizen.config.base_config import BaseConfig -from commitizen.defaults import MAJOR, MINOR, PATCH +from commitizen.defaults import MAJOR, MINOR, PATCH, Settings from commitizen.exceptions import VersionSchemeUnknown if TYPE_CHECKING: @@ -42,7 +41,7 @@ Increment: TypeAlias = Literal["MAJOR", "MINOR", "PATCH"] Prerelease: TypeAlias = Literal["alpha", "beta", "rc"] -DEFAULT_VERSION_PARSER = r"v?(?P<version>([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?(\w+)?)" +DEFAULT_VERSION_PARSER = r"v?(?P<version>([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.]+)?(\w+)?)" @runtime_checkable @@ -408,14 +407,15 @@ def __str__(self) -> str: """All known registered version schemes""" -def get_version_scheme(config: BaseConfig, name: str | None = None) -> VersionScheme: +def get_version_scheme(settings: Settings, name: str | None = None) -> VersionScheme: """ Get the version scheme as defined in the configuration or from an overridden `name` :raises VersionSchemeUnknown: if the version scheme is not found. """ - deprecated_setting: str | None = config.settings.get("version_type") + # TODO: Remove the deprecated `version_type` handling + deprecated_setting: str | None = settings.get("version_type") if deprecated_setting: warnings.warn( DeprecationWarning( @@ -423,7 +423,7 @@ def get_version_scheme(config: BaseConfig, name: str | None = None) -> VersionSc "Please use `version_scheme` instead" ) ) - name = name or config.settings.get("version_scheme") or deprecated_setting + name = name or settings.get("version_scheme") or deprecated_setting if not name: return DEFAULT_SCHEME diff --git a/docs/config.md b/docs/config.md index 210b5d7ff8..5ec1894872 100644 --- a/docs/config.md +++ b/docs/config.md @@ -51,6 +51,26 @@ Default: `$version` Format for the git tag, useful for old projects, that use a convention like `"v1.2.1"`. [Read more][tag_format] +### `legacy_tag_formats` + +Type: `list` + +Default: `[ ]` + +Legacy git tag formats, useful for old projects that changed tag format. +Tags matching those formats will be recognized as version tags and be included in the changelog. +Each entry use the the syntax as [`tag_format`](#tag_format). [Read more][tag_format] + +### `ignored_tag_formats` + +Type: `list` + +Default: `[ ]` + +Tags matching those formats will be totally ignored and won't raise a warning. +Each entry use the the syntax as [`tag_format`](#tag_format) with the addition of `*` +that will match everything (non-greedy). [Read more][tag_format] + ### `update_changelog_on_bump` Type: `bool` diff --git a/docs/faq.md b/docs/faq.md index 4bcb2bc7cf..29d9f40512 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -107,3 +107,36 @@ If you would like to learn more about both schemes, there are plenty of good res [#173]: https://github.com/commitizen-tools/commitizen/issues/173 [#385]: https://github.com/commitizen-tools/commitizen/pull/385 + +## How to change the tag format ? + +You can use the [`legacy_tag_formats`](config.md#legacy_tag_formats) to list old tag formats. +New bumped tags will be in the new format but old ones will still work for: +- changelog generation (full, incremental and version range) +- bump new version computation (automatically guessed or increment given) + + +So given if you change from `myproject-$version` to `${version}` and then `v${version}`, +your commitizen configuration will look like this: + +```toml +tag_format = "v${version}" +legacy_tag_formats = [ + "${version}", + "myproject-$version", +] +``` + +## How to avoid warnings for expected non-version tags + +You can explicitly ignore them with [`ignored_tag_formats`](config.md#ignored_tag_formats). + +```toml +tag_format = "v${version}" +ignored_tag_formats = [ + "stable", + "component-*", + "env/*", + "v${major}.${minor}", +] +``` diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index ba6d70fd82..817f92321d 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -27,6 +27,7 @@ Sample `.cz.toml` for each component: name = "cz_customize" version = "0.0.0" tag_format = "${version}-library-b" # the component name can be a prefix or suffix with or without a separator +ignored_tag_formats = ["${version}-library-*"] # Avoid noise from other tags update_changelog_on_bump = true ``` @@ -36,6 +37,7 @@ update_changelog_on_bump = true name = "cz_customize" version = "0.0.0" tag_format = "${version}-library-z" +ignored_tag_formats = ["${version}-library-*"] # Avoid noise from other tags update_changelog_on_bump = true ``` diff --git a/docs/tutorials/tag_format.md b/docs/tutorials/tag_format.md new file mode 100644 index 0000000000..59c42bea13 --- /dev/null +++ b/docs/tutorials/tag_format.md @@ -0,0 +1,101 @@ +# Managing tag formats + +## Tag format and version scheme + +For most projects, the tag format is simply the version number which is set like this: + +```yaml +[tool.commitizen] +tag_format: $version +version_scheme: pep440 +``` + +As this is the default value so you don't have to specify it. + +This setting means that: + +- The tag generated on bump will have this format: `1.0.0` : + - the version is generated following PEP440 scheme + - the tag is exactly the generated version +- All tags having this format will be recognized as version tag when: + - searching the last while bumping a release + - searching previous versions while: + - generating incremental changelog + - generating a changelog for a version range +- The changelog versions (section titles) will have this format +- The `scm` version provider will identify the current version using this tag format + +The version format will change depending on your configured version scheme. +For most, it will only impact pre-releases and [developmental releases](dev_releases.md) formats (i.e. `1.0.0-rc.1` vs. `1.0.0.rc1`) + +But you may need a different tagging convention, let's say using `semver` and prefixed with a `v`. +In this case you will define your settings like this: + +```yaml +[tool.commitizen] +tag_format: v${version} +version_scheme: semver +``` + +As a result, the tag generated on bump will have this format: `v1.0.0` and the version will be generated following `semver` scheme. + +!!! note + Both `$version` and `${version}` syntaxes are strictly equivalent. You can use the one you prefer. + +See [the `version_scheme` section in `bump` command documentation](../commands/bump.md#version_scheme) for more details on version schemes and how to define your own. +See [`tag_format`](../config.md#tag_format) and [`version_scheme`](../config.md#version_scheme) settings in [Configuration reference](../config.md) for more details on these settings. + +## Changing convention + +Now, let's say you need to change the tag format for some reason (company convention, [migration to a monorepo](monorepo_guidance.md)...). +You will obviously want to keep all those features working as expected. + +Commitizen can deal with it as long as you provide the legacy tag format in the configuration. + +Using the previous example, let say you want to move from `v${version}` to `component-${version}`. +Then `component-${version}` will be the new tag format and `v${version}` the legacy one. + +```yaml +[tool.commitizen] +tag_format: component-${version} +legacy_tag_formats: + - v${version} +``` + +This way, you won't loose your version history, you'll still be able to generate you changelog properly +and on the next version bump, your last version in the form `v${version}` will be properly recognizef if you use the `scm` version provider. +Your new tag will be in the form `component-${version}`. + +## Known tags to ignore + +Now let's say you have some known tags you want to ignore, either because they are not versions, either because they are not versions of the component you are dealing with. +As a consequence, you don't want them to trigger a warning because Commitizen detected an unknown tag format: + +Then you can tell Commitizen about it using the [`ignored_tag_formats`](../config.md#ignored_tag_formats) setting: + +```yaml +[tool.commitizen] +ignored_tag_formats: + - prod + - other-component-${version} + - prefix-* +``` + +This will ignore: + +- The `prod` tag +- Any version tag prefixed with `other-component-` +- Any tag prefixed with `prefix-` + + +!!! tip + Note the `*` in the `prefix-*` pattern. This is a wildcard and only exists for `ignored_tag_formats`. + It will match any string from any length. This allows to exclude by prefix, whether it is followed by a version or not. + +!!! tip + If you don't want to be warned when Commitizen detect an unknown tag, you can by setting: + ``` + [tool.commitizen] + ignored_tag_formats = ["*"] + ``` + But be aware that you will not be warned if you have a typo in your tag formats. diff --git a/mkdocs.yml b/mkdocs.yml index f6a7eaa421..6a642161d2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,6 +47,7 @@ nav: - Customization: "customization.md" - Tutorials: - Writing commits: "tutorials/writing_commits.md" + - Managing tags formats: "tutorials/tag_format.md" - Auto check commits: "tutorials/auto_check.md" - Auto prepare commit message: "tutorials/auto_prepare_commit_message.md" - GitLab CI: "tutorials/gitlab_ci.md" diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 52e2defde0..b5ff7e6edb 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -7,6 +7,7 @@ from textwrap import dedent from unittest.mock import MagicMock, call +import py import pytest from pytest_mock import MockFixture @@ -1627,3 +1628,31 @@ def test_bump_allow_no_commit_with_manual_version( cli.main() out, _ = capsys.readouterr() assert "bump: version 1.0.0 → 2.0.0" in out + + +def test_bump_detect_legacy_tags_from_scm( + tmp_commitizen_project: py.path.local, mocker: MockFixture +): + project_root = Path(tmp_commitizen_project) + tmp_commitizen_cfg_file = project_root / "pyproject.toml" + tmp_commitizen_cfg_file.write_text( + "\n".join( + [ + "[tool.commitizen]", + 'version_provider = "scm"', + 'tag_format = "v$version"', + "legacy_tag_formats = [", + ' "legacy-${version}"', + "]", + ] + ), + ) + create_file_and_commit("feat: new file") + create_tag("legacy-0.4.2") + create_file_and_commit("feat: new file") + + testargs = ["cz", "bump", "--increment", "patch", "--changelog"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + assert git.tag_exist("v0.4.3") diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index a6ff7db2d8..f794b8d9f3 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -8,6 +8,7 @@ from dateutil import relativedelta from jinja2 import FileSystemLoader from pytest_mock import MockFixture +from pytest_regressions.file_regression import FileRegressionFixture from commitizen import __file__ as commitizen_init from commitizen import cli, git @@ -954,8 +955,17 @@ def test_changelog_from_rev_latest_version_from_arg( @pytest.mark.usefixtures("tmp_commitizen_project") @pytest.mark.freeze_time("2022-02-13") -def test_changelog_from_rev_single_version_not_found( - mocker: MockFixture, config_path, changelog_path +@pytest.mark.parametrize( + "rev_range,tag", + ( + pytest.param("0.8.0", "0.2.0", id="single-not-found"), + pytest.param("0.1.0..0.3.0", "0.3.0", id="lower-bound-not-found"), + pytest.param("0.1.0..0.3.0", "0.1.0", id="upper-bound-not-found"), + pytest.param("0.3.0..0.4.0", "0.2.0", id="none-found"), + ), +) +def test_changelog_from_rev_range_not_found( + mocker: MockFixture, config_path, rev_range: str, tag: str ): """Provides an invalid revision ID to changelog command""" with open(config_path, "a", encoding="utf-8") as f: @@ -963,26 +973,46 @@ def test_changelog_from_rev_single_version_not_found( # create commit and tag create_file_and_commit("feat: new file") - testargs = ["cz", "bump", "--yes"] + create_tag(tag) + create_file_and_commit("feat: new file") + create_tag("1.0.0") + + testargs = ["cz", "changelog", rev_range] # it shouldn't exist mocker.patch.object(sys, "argv", testargs) - cli.main() + with pytest.raises(NoCommitsFoundError) as excinfo: + cli.main() - wait_for_tag() + assert "Could not find a valid revision" in str(excinfo) - create_file_and_commit("feat: after 0.2.0") - create_file_and_commit("feat: another feature") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() - wait_for_tag() +@pytest.mark.usefixtures("tmp_commitizen_project") +@pytest.mark.freeze_time("2022-02-13") +def test_changelog_multiple_matching_tags( + mocker: MockFixture, config_path, changelog_path +): + with open(config_path, "a", encoding="utf-8") as f: + f.write('tag_format = "new-$version"\nlegacy_tag_formats = ["legacy-$version"]') + + create_file_and_commit("feat: new file") + create_tag("legacy-1.0.0") + create_file_and_commit("feat: new file") + create_tag("legacy-2.0.0") + create_tag("new-2.0.0") - testargs = ["cz", "changelog", "0.8.0"] # it shouldn't exist + testargs = ["cz", "changelog", "1.0.0..2.0.0"] # it shouldn't exist mocker.patch.object(sys, "argv", testargs) - with pytest.raises(NoCommitsFoundError) as excinfo: + with pytest.warns() as warnings: cli.main() - assert "Could not find a valid revision" in str(excinfo) + assert len(warnings) == 1 + warning = warnings[0] + assert "Multiple tags found for version 2.0.0" in str(warning.message) + + with open(changelog_path) as f: + out = f.read() + + # Ensure only one tag is rendered + assert out.count("2.0.0") == 1 @pytest.mark.usefixtures("tmp_commitizen_project") @@ -1016,34 +1046,6 @@ def test_changelog_from_rev_range_default_tag_format( assert "new file" not in out -@pytest.mark.usefixtures("tmp_commitizen_project") -@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", encoding="utf-8") as f: - f.write('tag_format = "$version"\n') - - # create commit and tag - create_file_and_commit("feat: new file") - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() - - create_file_and_commit("feat: after 0.2.0") - create_file_and_commit("feat: another feature") - - testargs = ["cz", "bump", "--yes"] - mocker.patch.object(sys, "argv", testargs) - cli.main() - - testargs = ["cz", "changelog", "0.5.0..0.8.0"] # it shouldn't exist - mocker.patch.object(sys, "argv", testargs) - with pytest.raises(NoCommitsFoundError) as excinfo: - cli.main() - - assert "Could not find a valid revision" in str(excinfo) - - @pytest.mark.usefixtures("tmp_commitizen_project") @pytest.mark.freeze_time("2022-02-13") def test_changelog_from_rev_version_range_including_first_tag( @@ -1116,6 +1118,41 @@ def test_changelog_from_rev_version_range_from_arg( file_regression.check(out, extension=".md") +@pytest.mark.usefixtures("tmp_commitizen_project") +@pytest.mark.freeze_time("2022-02-13") +def test_changelog_from_rev_version_range_with_legacy_tags( + mocker: MockFixture, config_path, changelog_path, file_regression +): + mocker.patch("commitizen.git.GitTag.date", "2022-02-13") + + changelog = Path(changelog_path) + Path(config_path).write_text( + "\n".join( + [ + "[tool.commitizen]", + 'version_provider = "scm"', + 'tag_format = "v$version"', + "legacy_tag_formats = [", + ' "legacy-${version}",', + ' "old-${version}",', + "]", + ] + ), + ) + + create_file_and_commit("feat: new file") + create_tag("old-0.2.0") + create_file_and_commit("feat: new file") + create_tag("legacy-0.3.0") + create_file_and_commit("feat: new file") + create_tag("legacy-0.4.0") + + testargs = ["cz", "changelog", "0.2.0..0.4.0"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + file_regression.check(changelog.read_text(), extension=".md") + + @pytest.mark.usefixtures("tmp_commitizen_project") @pytest.mark.freeze_time("2022-02-13") def test_changelog_from_rev_version_with_big_range_from_arg( @@ -1639,6 +1676,127 @@ def test_changelog_only_tag_matching_tag_format_included_suffix_sep( assert "## 0.2.0 (2021-06-11)" not in out +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_changelog_legacy_tags( + mocker: MockFixture, + changelog_path: Path, + config_path: Path, +): + with open(config_path, "a", encoding="utf-8") as f: + f.writelines( + [ + 'tag_format = "v${version}"\n', + "legacy_tag_formats = [\n", + ' "older-${version}",\n', + ' "oldest-${version}",\n', + "]\n", + ] + ) + create_file_and_commit("feat: new file") + git.tag("oldest-0.1.0") + create_file_and_commit("feat: new file") + git.tag("older-0.2.0") + create_file_and_commit("feat: another new file") + git.tag("v0.3.0") + create_file_and_commit("feat: another new file") + git.tag("not-0.3.1") + testargs = ["cz", "bump", "--changelog", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + out = open(changelog_path).read() + assert "## v0.3.0" in out + assert "## older-0.2.0" in out + assert "## oldest-0.1.0" in out + assert "## v0.3.0" in out + assert "## not-0.3.1" not in out + + +@pytest.mark.usefixtures("tmp_commitizen_project") +@pytest.mark.freeze_time("2024-11-18") +def test_changelog_incremental_change_tag_format( + mocker: MockFixture, + changelog_path: Path, + config_path: Path, + file_regression: FileRegressionFixture, +): + mocker.patch("commitizen.git.GitTag.date", "2024-11-18") + config = Path(config_path) + base_config = config.read_text() + config.write_text( + "\n".join( + ( + base_config, + 'tag_format = "older-${version}"', + ) + ) + ) + create_file_and_commit("feat: new file") + git.tag("older-0.1.0") + create_file_and_commit("feat: new file") + git.tag("older-0.2.0") + mocker.patch.object(sys, "argv", ["cz", "changelog"]) + cli.main() + + config.write_text( + "\n".join( + ( + base_config, + 'tag_format = "v${version}"', + 'legacy_tag_formats = ["older-${version}"]', + ) + ) + ) + create_file_and_commit("feat: another new file") + git.tag("v0.3.0") + mocker.patch.object(sys, "argv", ["cz", "changelog", "--incremental"]) + cli.main() + out = open(changelog_path).read() + assert "## v0.3.0" in out + assert "## older-0.2.0" in out + assert "## older-0.1.0" in out + file_regression.check(out, extension=".md") + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_changelog_ignored_tags( + mocker: MockFixture, + changelog_path: Path, + config_path: Path, + capsys: pytest.CaptureFixture, +): + with open(config_path, "a", encoding="utf-8") as f: + f.writelines( + [ + 'tag_format = "v${version}"\n', + "ignored_tag_formats = [\n", + ' "ignored",\n', + ' "ignore-${version}",\n', + "]\n", + ] + ) + create_file_and_commit("feat: new file") + git.tag("ignore-0.1.0") + create_file_and_commit("feat: new file") + git.tag("ignored") + create_file_and_commit("feat: another new file") + git.tag("v0.3.0") + create_file_and_commit("feat: another new file") + git.tag("not-ignored") + testargs = ["cz", "bump", "--changelog", "--yes"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + out = open(changelog_path).read() + _, err = capsys.readouterr() + assert "## ignore-0.1.0" not in out + assert "InvalidVersion ignore-0.1.0" not in err + assert "## ignored" not in out + assert "InvalidVersion ignored" not in err + assert "## not-ignored" not in out + assert "InvalidVersion not-ignored" in err + assert "## v0.3.0" in out + assert "InvalidVersion v0.3.0" not in err + + def test_changelog_template_extra_quotes( mocker: MockFixture, tmp_commitizen_project: Path, diff --git a/tests/commands/test_changelog_command/test_changelog_from_rev_version_range_with_legacy_tags.md b/tests/commands/test_changelog_command/test_changelog_from_rev_version_range_with_legacy_tags.md new file mode 100644 index 0000000000..5d37333aa5 --- /dev/null +++ b/tests/commands/test_changelog_command/test_changelog_from_rev_version_range_with_legacy_tags.md @@ -0,0 +1,17 @@ +## legacy-0.4.0 (2022-02-13) + +### Feat + +- new file + +## legacy-0.3.0 (2022-02-13) + +### Feat + +- new file + +## old-0.2.0 (2022-02-13) + +### Feat + +- new file diff --git a/tests/commands/test_changelog_command/test_changelog_incremental_change_tag_format.md b/tests/commands/test_changelog_command/test_changelog_incremental_change_tag_format.md new file mode 100644 index 0000000000..2f0cc2909e --- /dev/null +++ b/tests/commands/test_changelog_command/test_changelog_incremental_change_tag_format.md @@ -0,0 +1,17 @@ +## v0.3.0 (2024-11-18) + +### Feat + +- another new file + +## older-0.2.0 (2024-11-18) + +### Feat + +- new file + +## older-0.1.0 (2024-11-18) + +### Feat + +- new file diff --git a/tests/providers/test_scm_provider.py b/tests/providers/test_scm_provider.py index 01e7ab9943..9d955b2323 100644 --- a/tests/providers/test_scm_provider.py +++ b/tests/providers/test_scm_provider.py @@ -113,3 +113,26 @@ def test_scm_provider_default_with_commits_and_tags(config: BaseConfig): merge_branch("master") assert provider.get_version() == "1.1.0rc0" + + +@pytest.mark.usefixtures("tmp_git_project") +def test_scm_provider_detect_legacy_tags(config: BaseConfig): + config.settings["version_provider"] = "scm" + config.settings["tag_format"] = "v${version}" + config.settings["legacy_tag_formats"] = [ + "legacy-${version}", + "old-${version}", + ] + provider = get_provider(config) + + create_file_and_commit("test: fake commit") + create_tag("old-0.4.1") + assert provider.get_version() == "0.4.1" + + create_file_and_commit("test: fake commit") + create_tag("legacy-0.4.2") + assert provider.get_version() == "0.4.2" + + create_file_and_commit("test: fake commit") + create_tag("v0.5.0") + assert provider.get_version() == "0.5.0" diff --git a/tests/test_bump_normalize_tag.py b/tests/test_bump_normalize_tag.py index c1eb696afd..895acbd71a 100644 --- a/tests/test_bump_normalize_tag.py +++ b/tests/test_bump_normalize_tag.py @@ -1,6 +1,6 @@ import pytest -from commitizen import bump +from commitizen.tags import TagRules conversion = [ (("1.2.3", "v$version"), "v1.2.3"), @@ -18,5 +18,6 @@ @pytest.mark.parametrize("test_input,expected", conversion) def test_create_tag(test_input, expected): version, format = test_input - new_tag = bump.normalize_tag(version, format) + rules = TagRules() + new_tag = rules.normalize_tag(version, format) assert new_tag == expected diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 76ee80600b..accbf5d33c 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,4 +1,5 @@ import re +from dataclasses import dataclass from pathlib import Path from typing import Optional @@ -11,6 +12,7 @@ ConventionalCommitsCz, ) from commitizen.exceptions import InvalidConfigurationError +from commitizen.version_schemes import Pep440 COMMITS_DATA = [ { @@ -522,12 +524,14 @@ def test_get_commit_tag_is_None(gitcommits, tags): @pytest.mark.parametrize("test_input", TAGS) def test_valid_tag_included_in_changelog(test_input): tag = git.GitTag(*test_input) - assert changelog.tag_included_in_changelog(tag, [], False) + rules = changelog.TagRules() + assert rules.include_in_changelog(tag) def test_invalid_tag_included_in_changelog(): tag = git.GitTag("not_a_version", "rev", "date") - assert not changelog.tag_included_in_changelog(tag, [], False) + rules = changelog.TagRules() + assert not rules.include_in_changelog(tag) COMMITS_TREE = ( @@ -1080,8 +1084,11 @@ def test_invalid_tag_included_in_changelog(): def test_generate_tree_from_commits(gitcommits, tags, merge_prereleases): parser = ConventionalCommitsCz.commit_parser changelog_pattern = ConventionalCommitsCz.bump_pattern + rules = changelog.TagRules( + merge_prereleases=merge_prereleases, + ) tree = changelog.generate_tree_from_commits( - gitcommits, tags, parser, changelog_pattern, merge_prerelease=merge_prereleases + gitcommits, tags, parser, changelog_pattern, rules=rules ) expected = ( COMMITS_TREE_AFTER_MERGED_PRERELEASES if merge_prereleases else COMMITS_TREE @@ -1451,3 +1458,105 @@ def test_get_smart_tag_range_returns_an_extra_for_a_single_tag(tags): start = tags[0] # len here is 1, but we expect one more tag as designed res = changelog.get_smart_tag_range(tags, start.name) assert 2 == len(res) + + +@dataclass +class TagDef: + name: str + is_version: bool + is_legacy: bool + is_ignored: bool + + +TAGS_PARAMS = ( + pytest.param(TagDef("1.2.3", True, False, False), id="version"), + # We test with `v-` prefix as `v` prefix is a special case kept for backward compatibility + pytest.param(TagDef("v-1.2.3", False, True, False), id="v-prefix"), + pytest.param(TagDef("project-1.2.3", False, True, False), id="project-prefix"), + pytest.param(TagDef("ignored", False, False, True), id="ignored"), + pytest.param(TagDef("unknown", False, False, False), id="unknown"), +) + + +@pytest.mark.parametrize("tag", TAGS_PARAMS) +def test_tag_rules_tag_format_only(tag: TagDef): + rules = changelog.TagRules(Pep440, "$version") + assert rules.is_version_tag(tag.name) is tag.is_version + + +@pytest.mark.parametrize("tag", TAGS_PARAMS) +def test_tag_rules_with_legacy_tags(tag: TagDef): + rules = changelog.TagRules( + scheme=Pep440, + tag_format="$version", + legacy_tag_formats=["v-$version", "project-${version}"], + ) + assert rules.is_version_tag(tag.name) is tag.is_version or tag.is_legacy + + +@pytest.mark.parametrize("tag", TAGS_PARAMS) +def test_tag_rules_with_ignored_tags(tag: TagDef): + rules = changelog.TagRules( + scheme=Pep440, tag_format="$version", ignored_tag_formats=["ignored"] + ) + assert rules.is_ignored_tag(tag.name) is tag.is_ignored + + +def test_tags_rules_get_version_tags(capsys: pytest.CaptureFixture): + tags = [ + git.GitTag("v1.1.0", "17efb44d2cd16f6621413691a543e467c7d2dda6", "2019-04-14"), + git.GitTag("v1.0.0", "aa44a92d68014d0da98965c0c2cb8c07957d4362", "2019-03-01"), + git.GitTag("1.0.0b2", "aab33d13110f26604fb786878856ec0b9e5fc32b", "2019-01-18"), + git.GitTag( + "project-not-a-version", + "7c7e96b723c2aaa1aec3a52561f680adf0b60e97", + "2019-01-17", + ), + git.GitTag( + "not-a-version", "c52eca6f74f844ab3ffbde61d98ef96071e132b7", "2018-12-17" + ), + git.GitTag( + "star-something", "c52eca6f74f844ab3ffbde61d98fe96071e132b2", "2018-11-12" + ), + git.GitTag("known", "b3f89892222340150e32631ae6b7aab65230036f", "2018-09-22"), + git.GitTag( + "ignored-0.9.3", "684e0259cc95c7c5e94854608cd3dcebbd53219e", "2018-09-22" + ), + git.GitTag( + "project-0.9.3", "dacc86159b260ee98eb5f57941c99ba731a01399", "2018-07-28" + ), + git.GitTag( + "anything-0.9", "5141f54503d2e1cf39bd666c0ca5ab5eb78772ab", "2018-01-10" + ), + git.GitTag( + "project-0.9.2", "1541f54503d2e1cf39bd777c0ca5ab5eb78772ba", "2017-11-11" + ), + git.GitTag( + "ignored-0.9.1", "46e9032e18a819e466618c7a014bcb0e9981af9e", "2017-11-11" + ), + ] + + rules = changelog.TagRules( + scheme=Pep440, + tag_format="v$version", + legacy_tag_formats=["$version", "project-${version}"], + ignored_tag_formats=[ + "known", + "ignored-${version}", + "star-*", + "*-${major}.${minor}", + ], + ) + + version_tags = rules.get_version_tags(tags, warn=True) + assert {t.name for t in version_tags} == { + "v1.1.0", + "v1.0.0", + "1.0.0b2", + "project-0.9.3", + "project-0.9.2", + } + + captured = capsys.readouterr() + assert captured.err.count("InvalidVersion") == 2 + assert captured.err.count("not-a-version") == 2 diff --git a/tests/test_changelog_format_asciidoc.py b/tests/test_changelog_format_asciidoc.py index 0c5930df46..59ca56191e 100644 --- a/tests/test_changelog_format_asciidoc.py +++ b/tests/test_changelog_format_asciidoc.py @@ -55,6 +55,7 @@ """ EXPECTED_C = Metadata( latest_version="1.0.0", + latest_version_tag="v1.0.0", latest_version_position=3, unreleased_end=3, unreleased_start=1, @@ -105,20 +106,21 @@ def format(config: BaseConfig) -> AsciiDoc: @pytest.fixture def format_with_tags(config: BaseConfig, request) -> AsciiDoc: config.settings["tag_format"] = request.param + config.settings["legacy_tag_formats"] = ["legacy-${version}"] return AsciiDoc(config) VERSIONS_EXAMPLES = [ - ("== [1.0.0] - 2017-06-20", "1.0.0"), + ("== [1.0.0] - 2017-06-20", ("1.0.0", "1.0.0")), ( "= https://github.com/angular/angular/compare/10.0.0-next.2...10.0.0-next.3[10.0.0-next.3] (2020-04-22)", - "10.0.0-next.3", + ("10.0.0-next.3", "10.0.0-next.3"), ), - ("=== 0.19.1 (Jan 7, 2020)", "0.19.1"), - ("== 1.0.0", "1.0.0"), - ("== v1.0.0", "1.0.0"), - ("== v1.0.0 - (2012-24-32)", "1.0.0"), - ("= version 2020.03.24", "2020.03.24"), + ("=== 0.19.1 (Jan 7, 2020)", ("0.19.1", "0.19.1")), + ("== 1.0.0", ("1.0.0", "1.0.0")), + ("== v1.0.0", ("1.0.0", "v1.0.0")), + ("== v1.0.0 - (2012-24-32)", ("1.0.0", "v1.0.0")), + ("= version 2020.03.24", ("2020.03.24", "2020.03.24")), ("== [Unreleased]", None), ("All notable changes to this project will be documented in this file.", None), ("= Changelog", None), @@ -128,7 +130,7 @@ def format_with_tags(config: BaseConfig, request) -> AsciiDoc: @pytest.mark.parametrize("line_from_changelog,output_version", VERSIONS_EXAMPLES) def test_changelog_detect_version( - line_from_changelog: str, output_version: str, format: AsciiDoc + line_from_changelog: str, output_version: tuple[str, str] | None, format: AsciiDoc ): version = format.parse_version_from_title(line_from_changelog) assert version == output_version @@ -186,6 +188,7 @@ def test_get_matadata( "1-0-0-a1.dev1-example", "1.0.0-a1.dev1", ), + pytest.param("new-${version}", "legacy-1.0.0", "1.0.0"), ), indirect=["format_with_tags"], ) diff --git a/tests/test_changelog_format_markdown.py b/tests/test_changelog_format_markdown.py index 52612b8e2b..e1f0d67311 100644 --- a/tests/test_changelog_format_markdown.py +++ b/tests/test_changelog_format_markdown.py @@ -55,6 +55,7 @@ """ EXPECTED_C = Metadata( latest_version="1.0.0", + latest_version_tag="v1.0.0", latest_version_position=3, unreleased_end=3, unreleased_start=1, @@ -105,20 +106,21 @@ def format(config: BaseConfig) -> Markdown: @pytest.fixture def format_with_tags(config: BaseConfig, request) -> Markdown: config.settings["tag_format"] = request.param + config.settings["legacy_tag_formats"] = ["legacy-${version}"] return Markdown(config) VERSIONS_EXAMPLES = [ - ("## [1.0.0] - 2017-06-20", "1.0.0"), + ("## [1.0.0] - 2017-06-20", ("1.0.0", "1.0.0")), ( "# [10.0.0-next.3](https://github.com/angular/angular/compare/10.0.0-next.2...10.0.0-next.3) (2020-04-22)", - "10.0.0-next.3", + ("10.0.0-next.3", "10.0.0-next.3"), ), - ("### 0.19.1 (Jan 7, 2020)", "0.19.1"), - ("## 1.0.0", "1.0.0"), - ("## v1.0.0", "1.0.0"), - ("## v1.0.0 - (2012-24-32)", "1.0.0"), - ("# version 2020.03.24", "2020.03.24"), + ("### 0.19.1 (Jan 7, 2020)", ("0.19.1", "0.19.1")), + ("## 1.0.0", ("1.0.0", "1.0.0")), + ("## v1.0.0", ("1.0.0", "v1.0.0")), + ("## v1.0.0 - (2012-24-32)", ("1.0.0", "v1.0.0")), + ("# version 2020.03.24", ("2020.03.24", "2020.03.24")), ("## [Unreleased]", None), ("All notable changes to this project will be documented in this file.", None), ("# Changelog", None), @@ -128,7 +130,7 @@ def format_with_tags(config: BaseConfig, request) -> Markdown: @pytest.mark.parametrize("line_from_changelog,output_version", VERSIONS_EXAMPLES) def test_changelog_detect_version( - line_from_changelog: str, output_version: str, format: Markdown + line_from_changelog: str, output_version: tuple[str, str] | None, format: Markdown ): version = format.parse_version_from_title(line_from_changelog) assert version == output_version @@ -191,6 +193,7 @@ def test_get_matadata( "1-0-0-a1.dev1-example", "1.0.0-a1.dev1", ), + pytest.param("new-${version}", "legacy-1.0.0", "1.0.0"), ), indirect=["format_with_tags"], ) diff --git a/tests/test_changelog_format_restructuredtext.py b/tests/test_changelog_format_restructuredtext.py index 11356ae28f..74b6b736f9 100644 --- a/tests/test_changelog_format_restructuredtext.py +++ b/tests/test_changelog_format_restructuredtext.py @@ -22,6 +22,7 @@ def case( content: str, latest_version: str | None = None, latest_version_position: int | None = None, + latest_version_tag: str | None = None, unreleased_start: int | None = None, unreleased_end: int | None = None, ): @@ -30,6 +31,7 @@ def case( dedent(content).strip(), Metadata( latest_version=latest_version, + latest_version_tag=latest_version_tag, latest_version_position=latest_version_position, unreleased_start=unreleased_start, unreleased_end=unreleased_end, @@ -93,6 +95,7 @@ def case( ====== """, latest_version="1.0.0", + latest_version_tag="v1.0.0", latest_version_position=3, unreleased_start=0, unreleased_end=3, @@ -303,6 +306,7 @@ def format(config: BaseConfig) -> RestructuredText: @pytest.fixture def format_with_tags(config: BaseConfig, request) -> RestructuredText: config.settings["tag_format"] = request.param + config.settings["legacy_tag_formats"] = ["legacy-${version}"] return RestructuredText(config) @@ -357,6 +361,7 @@ def test_is_overlined_title(format: RestructuredText, text: str, expected: bool) "1-0-0-a1.dev1-example", "1.0.0-a1.dev1", ), + pytest.param("new-${version}", "legacy-1.0.0", "1.0.0"), ), indirect=["format_with_tags"], ) diff --git a/tests/test_changelog_format_textile.py b/tests/test_changelog_format_textile.py index 3fac5c1756..eb03484ad5 100644 --- a/tests/test_changelog_format_textile.py +++ b/tests/test_changelog_format_textile.py @@ -55,6 +55,7 @@ """ EXPECTED_C = Metadata( latest_version="1.0.0", + latest_version_tag="v1.0.0", latest_version_position=3, unreleased_end=3, unreleased_start=1, @@ -98,20 +99,21 @@ def format(config: BaseConfig) -> Textile: @pytest.fixture def format_with_tags(config: BaseConfig, request) -> Textile: config.settings["tag_format"] = request.param + config.settings["legacy_tag_formats"] = ["legacy-${version}"] return Textile(config) VERSIONS_EXAMPLES = [ - ("h2. [1.0.0] - 2017-06-20", "1.0.0"), + ("h2. [1.0.0] - 2017-06-20", ("1.0.0", "1.0.0")), ( 'h1. "10.0.0-next.3":https://github.com/angular/angular/compare/10.0.0-next.2...10.0.0-next.3 (2020-04-22)', - "10.0.0-next.3", + ("10.0.0-next.3", "10.0.0-next.3"), ), - ("h3. 0.19.1 (Jan 7, 2020)", "0.19.1"), - ("h2. 1.0.0", "1.0.0"), - ("h2. v1.0.0", "1.0.0"), - ("h2. v1.0.0 - (2012-24-32)", "1.0.0"), - ("h1. version 2020.03.24", "2020.03.24"), + ("h3. 0.19.1 (Jan 7, 2020)", ("0.19.1", "0.19.1")), + ("h2. 1.0.0", ("1.0.0", "1.0.0")), + ("h2. v1.0.0", ("1.0.0", "v1.0.0")), + ("h2. v1.0.0 - (2012-24-32)", ("1.0.0", "v1.0.0")), + ("h1. version 2020.03.24", ("2020.03.24", "2020.03.24")), ("h2. [Unreleased]", None), ("All notable changes to this project will be documented in this file.", None), ("h1. Changelog", None), @@ -121,7 +123,7 @@ def format_with_tags(config: BaseConfig, request) -> Textile: @pytest.mark.parametrize("line_from_changelog,output_version", VERSIONS_EXAMPLES) def test_changelog_detect_version( - line_from_changelog: str, output_version: str, format: Textile + line_from_changelog: str, output_version: tuple[str, str] | None, format: Textile ): version = format.parse_version_from_title(line_from_changelog) assert version == output_version @@ -179,6 +181,7 @@ def test_get_matadata( "1-0-0-a1.dev1-example", "1.0.0-a1.dev1", ), + pytest.param("new-${version}", "legacy-1.0.0", "1.0.0"), ), indirect=["format_with_tags"], ) diff --git a/tests/test_conf.py b/tests/test_conf.py index 3e0a44c7dd..80d58983e7 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -72,6 +72,8 @@ "version_provider": "commitizen", "version_scheme": None, "tag_format": "$version", + "legacy_tag_formats": [], + "ignored_tag_formats": [], "bump_message": None, "retry_after_failure": False, "allow_abort": False, @@ -101,6 +103,8 @@ "version_provider": "commitizen", "version_scheme": None, "tag_format": "$version", + "legacy_tag_formats": [], + "ignored_tag_formats": [], "bump_message": None, "retry_after_failure": False, "allow_abort": False, diff --git a/tests/test_version_schemes.py b/tests/test_version_schemes.py index 686c0bfde1..8e2dae9027 100644 --- a/tests/test_version_schemes.py +++ b/tests/test_version_schemes.py @@ -16,31 +16,31 @@ def test_default_version_scheme_is_pep440(config: BaseConfig): - scheme = get_version_scheme(config) + scheme = get_version_scheme(config.settings) assert scheme is Pep440 def test_version_scheme_from_config(config: BaseConfig): config.settings["version_scheme"] = "semver" - scheme = get_version_scheme(config) + scheme = get_version_scheme(config.settings) assert scheme is SemVer def test_version_scheme_from_name(config: BaseConfig): config.settings["version_scheme"] = "pep440" - scheme = get_version_scheme(config, "semver") + scheme = get_version_scheme(config.settings, "semver") assert scheme is SemVer def test_raise_for_unknown_version_scheme(config: BaseConfig): with pytest.raises(VersionSchemeUnknown): - get_version_scheme(config, "unknown") + get_version_scheme(config.settings, "unknown") def test_version_scheme_from_deprecated_config(config: BaseConfig): config.settings["version_type"] = "semver" with pytest.warns(DeprecationWarning): - scheme = get_version_scheme(config) + scheme = get_version_scheme(config.settings) assert scheme is SemVer @@ -48,7 +48,7 @@ def test_version_scheme_from_config_priority(config: BaseConfig): config.settings["version_scheme"] = "pep440" config.settings["version_type"] = "semver" with pytest.warns(DeprecationWarning): - scheme = get_version_scheme(config) + scheme = get_version_scheme(config.settings) assert scheme is Pep440 @@ -63,4 +63,4 @@ class NotVersionProtocol: mocker.patch.object(metadata, "entry_points", return_value=(ep,)) with pytest.warns(match="VersionProtocol"): - get_version_scheme(config, "any") + get_version_scheme(config.settings, "any") From 9aae58e56cf24b6f5e43250d818edd564de072dc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Sun, 2 Mar 2025 15:26:50 +0000 Subject: [PATCH 420/598] =?UTF-8?q?bump:=20version=204.3.0=20=E2=86=92=204?= =?UTF-8?q?.4.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 10 ++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dd16cc9cc4..c8861315d4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.3.0 # automatically updated by Commitizen + rev: v4.4.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index fa7409d227..30d2b76595 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v4.4.0 (2025-03-02) + +### Feat + +- **tags**: adds `legacy_tag_formats` and `ignored_tag_formats` settings + +### Refactor + +- **get_tag_regexes**: dedup tag regexes definition + ## v4.3.0 (2025-02-28) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 111dc9172a..ecdb1cef9e 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.3.0" +__version__ = "4.4.0" diff --git a/pyproject.toml b/pyproject.toml index 0c03a6d508..570eabd3a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.3.0" +version = "4.4.0" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -87,7 +87,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.3.0" +version = "4.4.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", From bc8479e7aa1a5b9d2f491b79e3a4d4015519903c Mon Sep 17 00:00:00 2001 From: Wei Lee <weilee.rx@gmail.com> Date: Sun, 2 Mar 2025 23:27:56 +0800 Subject: [PATCH 421/598] docs(config): add uv provider description (#1362) --- docs/config.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/config.md b/docs/config.md index 5ec1894872..3d53249585 100644 --- a/docs/config.md +++ b/docs/config.md @@ -352,6 +352,7 @@ Commitizen provides some version providers for some well known formats: | `scm` | Fetch the version from git and does not need to set it back | | `pep621` | Get and set version from `pyproject.toml` `project.version` field | | `poetry` | Get and set version from `pyproject.toml` `tool.poetry.version` field | +| `uv` | Get and set version from `pyproject.toml` `project.version` field and `uv.lock` `pacakge.version` field whose `package.name` field is the same as `pyproject.toml` `project.name` field | | `cargo` | Get and set version from `Cargo.toml` `project.version` field | | `npm` | Get and set version from `package.json` `version` field, `package-lock.json` `version,packages.''.version` fields if the file exists, and `npm-shrinkwrap.json` `version,packages.''.version` fields if the file exists | | `composer` | Get and set version from `composer.json` `project.version` field | From 79dd19dc132de2fae6d3f07e4f17383bac6b99e8 Mon Sep 17 00:00:00 2001 From: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> Date: Sun, 2 Mar 2025 17:28:31 +0100 Subject: [PATCH 422/598] fix(tags): fixes ImportError on Python >=3.11 (#1363) (#1364) --- commitizen/tags.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/commitizen/tags.py b/commitizen/tags.py index 962e428ef2..915dd3120c 100644 --- a/commitizen/tags.py +++ b/commitizen/tags.py @@ -8,8 +8,6 @@ from string import Template from typing import TYPE_CHECKING, NamedTuple -from typing_extensions import Self - from commitizen import out from commitizen.defaults import DEFAULT_SETTINGS, Settings, get_tag_regexes from commitizen.git import GitTag @@ -22,8 +20,16 @@ ) if TYPE_CHECKING: + import sys + from commitizen.version_schemes import VersionScheme + # Self is Python 3.11+ but backported in typing-extensions + if sys.version_info < (3, 11): + from typing_extensions import Self + else: + from typing import Self + class VersionTag(NamedTuple): """Represent a version and its matching tag form.""" From b494c556437473519f8ab69020c7256ba84714c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Sun, 2 Mar 2025 16:28:55 +0000 Subject: [PATCH 423/598] =?UTF-8?q?bump:=20version=204.4.0=20=E2=86=92=204?= =?UTF-8?q?.4.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8861315d4..86997bc3ad 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.4.0 # automatically updated by Commitizen + rev: v4.4.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 30d2b76595..8fc88ad695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.4.1 (2025-03-02) + +### Fix + +- **tags**: fixes ImportError on Python >=3.11 (#1363) (#1364) + ## v4.4.0 (2025-03-02) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index ecdb1cef9e..9905939ff6 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.4.0" +__version__ = "4.4.1" diff --git a/pyproject.toml b/pyproject.toml index 570eabd3a6..314ddd925c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.4.0" +version = "4.4.1" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -87,7 +87,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.4.0" +version = "4.4.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", From a202e661bacf9643373255965f34bbdb382cb299 Mon Sep 17 00:00:00 2001 From: "Axel H." <noirbizarre@gmail.com> Date: Sun, 2 Mar 2025 17:35:30 +0100 Subject: [PATCH 424/598] ci(pre-commit): update `pre-commit` hooks to latest version and fix detected errors --- .pre-commit-config.yaml | 6 +++--- commitizen/tags.py | 20 +++++++++++--------- docs/config.md | 19 +++++++++---------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 86997bc3ad..bb1beaefcb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: check-useless-excludes - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v5.0.0 hooks: - id: check-vcs-permalinks - id: end-of-file-fixer @@ -30,13 +30,13 @@ repos: - id: detect-private-key - repo: https://github.com/asottile/blacken-docs - rev: 1.13.0 + rev: 1.19.1 hooks: - id: blacken-docs additional_dependencies: [ black~=23.11 ] - repo: https://github.com/codespell-project/codespell - rev: v2.2.4 + rev: v2.4.1 hooks: - id: codespell name: Run codespell to check for common misspellings in files diff --git a/commitizen/tags.py b/commitizen/tags.py index 915dd3120c..aa11cb7a9c 100644 --- a/commitizen/tags.py +++ b/commitizen/tags.py @@ -55,28 +55,30 @@ class TagRules: Example: - ```py + ```python settings = DEFAULT_SETTINGS.clone() - settings.update({ - "tag_format": "v{version}" - "legacy_tag_formats": ["version{version}", "ver{version}"], - "ignored_tag_formats": ["ignored{version}"], - }) + settings.update( + { + "tag_format": "v{version}", + "legacy_tag_formats": ["version{version}", "ver{version}"], + "ignored_tag_formats": ["ignored{version}"], + } + ) rules = TagRules.from_settings(settings) assert rules.is_version_tag("v1.0.0") assert rules.is_version_tag("version1.0.0") assert rules.is_version_tag("ver1.0.0") - assert not rules.is_version_tag("ignored1.0.0", warn=True) # Does not warn - assert not rules.is_version_tag("warn1.0.0", warn=True) # Does warn + assert not rules.is_version_tag("ignored1.0.0", warn=True) # Does not warn + assert not rules.is_version_tag("warn1.0.0", warn=True) # Does warn assert rules.search_version("# My v1.0.0 version").version == "1.0.0" assert rules.extract_version("v1.0.0") == Version("1.0.0") try: assert rules.extract_version("not-a-v1.0.0") except InvalidVersion: - print "Does not match a tag format" + print("Does not match a tag format") ``` """ diff --git a/docs/config.md b/docs/config.md index 3d53249585..d1ae90b29a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -352,7 +352,7 @@ Commitizen provides some version providers for some well known formats: | `scm` | Fetch the version from git and does not need to set it back | | `pep621` | Get and set version from `pyproject.toml` `project.version` field | | `poetry` | Get and set version from `pyproject.toml` `tool.poetry.version` field | -| `uv` | Get and set version from `pyproject.toml` `project.version` field and `uv.lock` `pacakge.version` field whose `package.name` field is the same as `pyproject.toml` `project.name` field | +| `uv` | Get and set version from `pyproject.toml` `project.version` field and `uv.lock` `package.version` field whose `package.name` field is the same as `pyproject.toml` `project.name` field | | `cargo` | Get and set version from `Cargo.toml` `project.version` field | | `npm` | Get and set version from `package.json` `version` field, `package-lock.json` `version,packages.''.version` fields if the file exists, and `npm-shrinkwrap.json` `version,packages.''.version` fields if the file exists | | `composer` | Get and set version from `composer.json` `project.version` field | @@ -386,22 +386,21 @@ class MyProvider(VersionProvider): def set_version(self, version: str): self.file.write_text(version) - ``` ```python title="setup.py" from setuptools import setup setup( - name='my-commitizen-provider', - version='0.1.0', - py_modules=['my_provider'], - install_requires=['commitizen'], - entry_points = { - 'commitizen.provider': [ - 'my-provider = my_provider:MyProvider', + name="my-commitizen-provider", + version="0.1.0", + py_modules=["my_provider"], + install_requires=["commitizen"], + entry_points={ + "commitizen.provider": [ + "my-provider = my_provider:MyProvider", ] - } + }, ) ``` From 58eecdccbaf02879dc5672f431485b582c66ffad Mon Sep 17 00:00:00 2001 From: Capi Etheriel <barraponto@gmail.com> Date: Sun, 16 Mar 2025 19:18:22 -0300 Subject: [PATCH 425/598] update precommit example --- docs/getting_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 378b819192..3c6257c363 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -94,7 +94,7 @@ repos: hooks: - id: commitizen - id: commitizen-branch - stages: [push] + stages: [pre-push] ``` After the configuration is added, you'll need to run: From 13bc11a9c560bad69c24a08b153b7ad0ca769fff Mon Sep 17 00:00:00 2001 From: Wei Lee <weilee.rx@gmail.com> Date: Thu, 20 Mar 2025 22:11:40 +0800 Subject: [PATCH 426/598] build(pyproject.toml): fix license metadata --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 314ddd925c..cedccabb0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ maintainers = [ { name = "Wei Lee", email = "weilee.rx@gmail.com" }, { name = "Axel H.", email = "noirbizarre@gmail.com" }, ] -license = { text = "LICENSE" } +license = { file = "LICENSE" } readme = "docs/README.md" requires-python = ">=3.9,<4.0" dependencies = [ @@ -42,6 +42,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", + "License :: OSI Approved :: MIT License", ] [project.urls] From 17021fa05ef37e754fd37053c822071c3368b3ca Mon Sep 17 00:00:00 2001 From: Wei Lee <weilee.rx@gmail.com> Date: Sun, 30 Mar 2025 17:50:23 +0800 Subject: [PATCH 427/598] fix(commands/init): add missing uv provider to "cz init" --- commitizen/commands/init.py | 1 + 1 file changed, 1 insertion(+) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index e39dfbe291..14ec8067e9 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -228,6 +228,7 @@ def _ask_version_provider(self) -> str: "npm": "npm: Get and set version from package.json:project.version field", "pep621": "pep621: Get and set version from pyproject.toml:project.version field", "poetry": "poetry: Get and set version from pyproject.toml:tool.poetry.version field", + "uv": "uv: Get and Get and set version from pyproject.toml and uv.lock", "scm": "scm: Fetch the version from git and does not need to set it back", } From 904173e3193714d2db6a67615bd8ee1132065526 Mon Sep 17 00:00:00 2001 From: Wei Lee <weilee.rx@gmail.com> Date: Fri, 4 Apr 2025 23:48:55 +0800 Subject: [PATCH 428/598] feat(init): set uv to default value if both pyproject.toml and uv.lock present --- commitizen/commands/init.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 14ec8067e9..df872ec7ee 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -24,6 +24,10 @@ class ProjectInfo: def has_pyproject(self) -> bool: return os.path.isfile("pyproject.toml") + @property + def has_uv_lock(self) -> bool: + return os.path.isfile("uv.lock") + @property def has_setup(self) -> bool: return os.path.isfile("setup.py") @@ -32,6 +36,10 @@ def has_setup(self) -> bool: def has_pre_commit_config(self) -> bool: return os.path.isfile(".pre-commit-config.yaml") + @property + def is_python_uv(self) -> bool: + return self.has_pyproject and self.has_uv_lock + @property def is_python_poetry(self) -> bool: if not self.has_pyproject: @@ -236,6 +244,8 @@ def _ask_version_provider(self) -> str: if self.project_info.is_python: if self.project_info.is_python_poetry: default_val = "poetry" + elif self.project_info.is_python_uv: + default_val = "uv" else: default_val = "pep621" elif self.project_info.is_rust_cargo: From e0b1c7743d5ea0bcba82e4ff515ce2caf5e87865 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 22:07:31 +0000 Subject: [PATCH 429/598] =?UTF-8?q?bump:=20version=204.4.1=20=E2=86=92=204?= =?UTF-8?q?.5.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 10 ++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bb1beaefcb..6c1cbd7670 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.4.1 # automatically updated by Commitizen + rev: v4.5.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fc88ad695..6250af20d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v4.5.0 (2025-04-04) + +### Feat + +- **init**: set uv to default value if both pyproject.toml and uv.lock present + +### Fix + +- **commands/init**: add missing uv provider to "cz init" + ## v4.4.1 (2025-03-02) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 9905939ff6..9faa2c2dd5 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.4.1" +__version__ = "4.5.0" diff --git a/pyproject.toml b/pyproject.toml index cedccabb0e..009bd13ca4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.4.1" +version = "4.5.0" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.4.1" +version = "4.5.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", From d666aa0bae8aec53b23b0495f8b007eeac4fdba8 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez <carlos@apache.org> Date: Fri, 21 Mar 2025 17:32:39 +0100 Subject: [PATCH 430/598] fix: print which tag is invalid and the regex used for validation --- commitizen/tags.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/commitizen/tags.py b/commitizen/tags.py index aa11cb7a9c..5724bb2574 100644 --- a/commitizen/tags.py +++ b/commitizen/tags.py @@ -146,7 +146,9 @@ def extract_version(self, tag: GitTag) -> Version: m for regex in self.version_regexes if (m := regex.fullmatch(tag.name)) ) if not (m := next(candidates, None)): - raise InvalidVersion() + raise InvalidVersion( + f"Invalid version tag: '{tag.name}' does not match any configured tag format" + ) if "version" in m.groupdict(): return self.scheme(m.group("version")) From 1451bc53f274b3794776e345212b518736272eca Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 01:24:52 +0000 Subject: [PATCH 431/598] =?UTF-8?q?bump:=20version=204.5.0=20=E2=86=92=204?= =?UTF-8?q?.5.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6c1cbd7670..19b4394cf6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.5.0 # automatically updated by Commitizen + rev: v4.5.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 6250af20d7..39eee25df0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.5.1 (2025-04-09) + +### Fix + +- print which tag is invalid + ## v4.5.0 (2025-04-04) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 9faa2c2dd5..f9f7166e62 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.5.0" +__version__ = "4.5.1" diff --git a/pyproject.toml b/pyproject.toml index 009bd13ca4..c9ea806cfc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.5.0" +version = "4.5.1" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.5.0" +version = "4.5.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", From d7b1a89061f44bda94ded6f0d54f193373d5b6d6 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz <alex@flawedcode.org> Date: Thu, 20 Mar 2025 14:25:47 +0100 Subject: [PATCH 432/598] feat(git): add parents' digests in commit information --- commitizen/git.py | 16 +++++++++++--- tests/test_git.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/commitizen/git.py b/commitizen/git.py index 7de8e1f1c8..19ca46b6c3 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -44,13 +44,20 @@ def __eq__(self, other) -> bool: class GitCommit(GitObject): def __init__( - self, rev, title, body: str = "", author: str = "", author_email: str = "" + self, + rev, + title, + body: str = "", + author: str = "", + author_email: str = "", + parents: list[str] | None = None, ): self.rev = rev.strip() self.title = title.strip() self.body = body.strip() self.author = author.strip() self.author_email = author_email.strip() + self.parents = parents or [] @property def message(self): @@ -137,7 +144,9 @@ def get_commits( for rev_and_commit in git_log_entries: if not rev_and_commit: continue - rev, title, author, author_email, *body_list = rev_and_commit.split("\n") + rev, parents, title, author, author_email, *body_list = rev_and_commit.split( + "\n" + ) if rev_and_commit: git_commit = GitCommit( rev=rev.strip(), @@ -145,6 +154,7 @@ def get_commits( body="\n".join(body_list).strip(), author=author, author_email=author_email, + parents=[p for p in parents.strip().split(" ") if p], ) git_commits.append(git_commit) return git_commits @@ -286,7 +296,7 @@ def smart_open(*args, **kargs): def _get_log_as_str_list(start: str | None, end: str, args: str) -> list[str]: """Get string representation of each log entry""" delimiter = "----------commit-delimiter----------" - log_format: str = "%H%n%s%n%an%n%ae%n%b" + log_format: str = "%H%n%P%n%s%n%an%n%ae%n%b" git_log_cmd = ( f"git -c log.showSignature=False log --pretty={log_format}{delimiter} {args}" ) diff --git a/tests/test_git.py b/tests/test_git.py index f929ba6a44..8b2fc2b86e 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -132,11 +132,13 @@ def test_get_commits_author_and_email(): def test_get_commits_without_email(mocker: MockFixture): raw_commit = ( "a515bb8f71c403f6f7d1c17b9d8ebf2ce3959395\n" + "95bbfc703eb99cb49ba0d6ffd8469911303dbe63 12d3b4bdaa996ea7067a07660bb5df4772297bdd\n" "\n" "user name\n" "\n" "----------commit-delimiter----------\n" "12d3b4bdaa996ea7067a07660bb5df4772297bdd\n" + "de33bc5070de19600f2f00262b3c15efea762408\n" "feat(users): add username\n" "user name\n" "\n" @@ -159,16 +161,19 @@ def test_get_commits_without_email(mocker: MockFixture): def test_get_commits_without_breakline_in_each_commit(mocker: MockFixture): raw_commit = ( "ae9ba6fc5526cf478f52ef901418d85505109744\n" + "ff2f56ca844de72a9d59590831087bf5a97bac84\n" "bump: version 2.13.0 → 2.14.0\n" "GitHub Action\n" "action@github.com\n" "----------commit-delimiter----------\n" "ff2f56ca844de72a9d59590831087bf5a97bac84\n" + "b4dc83284dc8c9729032a774a037df1d1f2397d5 20a54bf1b82cd7b573351db4d1e8814dd0be205d\n" "Merge pull request #332 from cliles/feature/271-redux\n" "User\n" "user@email.com\n" "Feature/271 redux----------commit-delimiter----------\n" "20a54bf1b82cd7b573351db4d1e8814dd0be205d\n" + "658f38c3fe832cdab63ed4fb1f7b3a0969a583be\n" "feat(#271): enable creation of annotated tags when bumping\n" "User 2\n" "user@email.edu\n" @@ -193,6 +198,55 @@ def test_get_commits_without_breakline_in_each_commit(mocker: MockFixture): ) +def test_get_commits_with_and_without_parents(mocker: MockFixture): + raw_commit = ( + "4206e661bacf9643373255965f34bbdb382cb2b9\n" + "ae9ba6fc5526cf478f52ef901418d85505109744 bf8479e7aa1a5b9d2f491b79e3a4d4015519903e\n" + "Merge pull request from someone\n" + "Maintainer\n" + "maintainer@email.com\n" + "This is a much needed feature----------commit-delimiter----------\n" + "ae9ba6fc5526cf478f52ef901418d85505109744\n" + "ff2f56ca844de72a9d59590831087bf5a97bac84\n" + "Release 0.1.0\n" + "GitHub Action\n" + "action@github.com\n" + "----------commit-delimiter----------\n" + "ff2f56ca844de72a9d59590831087bf5a97bac84\n" + "\n" + "Initial commit\n" + "User\n" + "user@email.com\n" + "----------commit-delimiter----------\n" + ) + mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=raw_commit)) + + commits = git.get_commits() + + assert commits[0].author == "Maintainer" + assert commits[1].author == "GitHub Action" + assert commits[2].author == "User" + + assert commits[0].author_email == "maintainer@email.com" + assert commits[1].author_email == "action@github.com" + assert commits[2].author_email == "user@email.com" + + assert commits[0].title == "Merge pull request from someone" + assert commits[1].title == "Release 0.1.0" + assert commits[2].title == "Initial commit" + + assert commits[0].body == "This is a much needed feature" + assert commits[1].body == "" + assert commits[2].body == "" + + assert commits[0].parents == [ + "ae9ba6fc5526cf478f52ef901418d85505109744", + "bf8479e7aa1a5b9d2f491b79e3a4d4015519903e", + ] + assert commits[1].parents == ["ff2f56ca844de72a9d59590831087bf5a97bac84"] + assert commits[2].parents == [] + + def test_get_commits_with_signature(): config_file = ".git/config" config_backup = ".git/config.bak" From 57ea95f652439e78804e16dca822f36f9f5debcc Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz <alex@flawedcode.org> Date: Thu, 20 Mar 2025 14:25:54 +0100 Subject: [PATCH 433/598] feat(changelog): expose commit parents' digests when processing commits COMMIT_DATA in test_changelog.py had to be type annotated to avoid an issue with mypy linting when creating a GitCommit where the tool would expect the wrong type for the arguments. --- commitizen/changelog.py | 1 + tests/test_changelog.py | 75 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 95bf21d6f9..704efe6071 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -172,6 +172,7 @@ def process_commit_message( ): message: dict = { "sha1": commit.rev, + "parents": commit.parents, "author": commit.author, "author_email": commit.author_email, **parsed.groupdict(), diff --git a/tests/test_changelog.py b/tests/test_changelog.py index accbf5d33c..df42b82264 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,7 +1,7 @@ import re from dataclasses import dataclass from pathlib import Path -from typing import Optional +from typing import Any, Optional import pytest from jinja2 import FileSystemLoader @@ -14,9 +14,10 @@ from commitizen.exceptions import InvalidConfigurationError from commitizen.version_schemes import Pep440 -COMMITS_DATA = [ +COMMITS_DATA: list[dict[str, Any]] = [ { "rev": "141ee441c9c9da0809c554103a558eb17c30ed17", + "parents": ["6c4948501031b7d6405b54b21d3d635827f9421b"], "title": "bump: version 1.1.1 → 1.2.0", "body": "", "author": "Commitizen", @@ -24,6 +25,7 @@ }, { "rev": "6c4948501031b7d6405b54b21d3d635827f9421b", + "parents": ["ddd220ad515502200fe2dde443614c1075d26238"], "title": "docs: how to create custom bumps", "body": "", "author": "Commitizen", @@ -31,6 +33,7 @@ }, { "rev": "ddd220ad515502200fe2dde443614c1075d26238", + "parents": ["ad17acff2e3a2e141cbc3c6efd7705e4e6de9bfc"], "title": "feat: custom cz plugins now support bumping version", "body": "", "author": "Commitizen", @@ -38,6 +41,7 @@ }, { "rev": "ad17acff2e3a2e141cbc3c6efd7705e4e6de9bfc", + "parents": ["56c8a8da84e42b526bcbe130bd194306f7c7e813"], "title": "docs: added bump gif", "body": "", "author": "Commitizen", @@ -45,6 +49,7 @@ }, { "rev": "56c8a8da84e42b526bcbe130bd194306f7c7e813", + "parents": ["74c6134b1b2e6bb8b07ed53410faabe99b204f36"], "title": "bump: version 1.1.0 → 1.1.1", "body": "", "author": "Commitizen", @@ -52,6 +57,7 @@ }, { "rev": "74c6134b1b2e6bb8b07ed53410faabe99b204f36", + "parents": ["cbc7b5f22c4e74deff4bc92d14e19bd93524711e"], "title": "refactor: changed stdout statements", "body": "", "author": "Commitizen", @@ -59,6 +65,7 @@ }, { "rev": "cbc7b5f22c4e74deff4bc92d14e19bd93524711e", + "parents": ["1ba46f2a63cb9d6e7472eaece21528c8cd28b118"], "title": "fix(bump): commit message now fits better with semver", "body": "", "author": "Commitizen", @@ -66,6 +73,7 @@ }, { "rev": "1ba46f2a63cb9d6e7472eaece21528c8cd28b118", + "parents": ["c35dbffd1bb98bb0b3d1593797e79d1c3366af8f"], "title": "fix: conventional commit 'breaking change' in body instead of title", "body": "closes #16", "author": "Commitizen", @@ -73,6 +81,7 @@ }, { "rev": "c35dbffd1bb98bb0b3d1593797e79d1c3366af8f", + "parents": ["25313397a4ac3dc5b5c986017bee2a614399509d"], "title": "refactor(schema): command logic removed from commitizen base", "body": "", "author": "Commitizen", @@ -80,6 +89,7 @@ }, { "rev": "25313397a4ac3dc5b5c986017bee2a614399509d", + "parents": ["d2f13ac41b4e48995b3b619d931c82451886e6ff"], "title": "refactor(info): command logic removed from commitizen base", "body": "", "author": "Commitizen", @@ -87,6 +97,7 @@ }, { "rev": "d2f13ac41b4e48995b3b619d931c82451886e6ff", + "parents": ["d839e317e5b26671b010584ad8cc6bf362400fa1"], "title": "refactor(example): command logic removed from commitizen base", "body": "", "author": "Commitizen", @@ -94,6 +105,7 @@ }, { "rev": "d839e317e5b26671b010584ad8cc6bf362400fa1", + "parents": ["12d0e65beda969f7983c444ceedc2a01584f4e08"], "title": "refactor(commit): moved most of the commit logic to the commit command", "body": "", "author": "Commitizen", @@ -101,6 +113,7 @@ }, { "rev": "12d0e65beda969f7983c444ceedc2a01584f4e08", + "parents": ["fb4c85abe51c228e50773e424cbd885a8b6c610d"], "title": "docs(README): updated documentation url)", "body": "", "author": "Commitizen", @@ -108,6 +121,7 @@ }, { "rev": "fb4c85abe51c228e50773e424cbd885a8b6c610d", + "parents": ["17efb44d2cd16f6621413691a543e467c7d2dda6"], "title": "docs: mkdocs documentation", "body": "", "author": "Commitizen", @@ -115,6 +129,7 @@ }, { "rev": "17efb44d2cd16f6621413691a543e467c7d2dda6", + "parents": ["6012d9eecfce8163d75c8fff179788e9ad5347da"], "title": "Bump version 1.0.0 → 1.1.0", "body": "", "author": "Commitizen", @@ -122,6 +137,7 @@ }, { "rev": "6012d9eecfce8163d75c8fff179788e9ad5347da", + "parents": ["0c7fb0ca0168864dfc55d83c210da57771a18319"], "title": "test: fixed issues with conf", "body": "", "author": "Commitizen", @@ -129,6 +145,7 @@ }, { "rev": "0c7fb0ca0168864dfc55d83c210da57771a18319", + "parents": ["cb1dd2019d522644da5bdc2594dd6dee17122d7f"], "title": "docs(README): some new information about bump", "body": "", "author": "Commitizen", @@ -136,6 +153,7 @@ }, { "rev": "cb1dd2019d522644da5bdc2594dd6dee17122d7f", + "parents": ["9c7450f85df6bf6be508e79abf00855a30c3c73c"], "title": "feat: new working bump command", "body": "", "author": "Commitizen", @@ -143,6 +161,7 @@ }, { "rev": "9c7450f85df6bf6be508e79abf00855a30c3c73c", + "parents": ["9f3af3772baab167e3fd8775d37f041440184251"], "title": "feat: create version tag", "body": "", "author": "Commitizen", @@ -150,6 +169,7 @@ }, { "rev": "9f3af3772baab167e3fd8775d37f041440184251", + "parents": ["b0d6a3defbfde14e676e7eb34946409297d0221b"], "title": "docs: added new changelog", "body": "", "author": "Commitizen", @@ -157,6 +177,7 @@ }, { "rev": "b0d6a3defbfde14e676e7eb34946409297d0221b", + "parents": ["d630d07d912e420f0880551f3ac94e933f9d3beb"], "title": "feat: update given files with new version", "body": "", "author": "Commitizen", @@ -164,6 +185,7 @@ }, { "rev": "d630d07d912e420f0880551f3ac94e933f9d3beb", + "parents": ["1792b8980c58787906dbe6836f93f31971b1ec2d"], "title": "fix: removed all from commit", "body": "", "author": "Commitizen", @@ -171,6 +193,7 @@ }, { "rev": "1792b8980c58787906dbe6836f93f31971b1ec2d", + "parents": ["52def1ea3555185ba4b936b463311949907e31ec"], "title": "feat(config): new set key, used to set version to cfg", "body": "", "author": "Commitizen", @@ -178,6 +201,7 @@ }, { "rev": "52def1ea3555185ba4b936b463311949907e31ec", + "parents": ["3127e05077288a5e2b62893345590bf1096141b7"], "title": "feat: support for pyproject.toml", "body": "", "author": "Commitizen", @@ -185,6 +209,7 @@ }, { "rev": "3127e05077288a5e2b62893345590bf1096141b7", + "parents": ["fd480ed90a80a6ffa540549408403d5b60d0e90c"], "title": "feat: first semantic version bump implementation", "body": "", "author": "Commitizen", @@ -192,6 +217,7 @@ }, { "rev": "fd480ed90a80a6ffa540549408403d5b60d0e90c", + "parents": ["e4840a059731c0bf488381ffc77e989e85dd81ad"], "title": "fix: fix config file not working", "body": "", "author": "Commitizen", @@ -199,6 +225,7 @@ }, { "rev": "e4840a059731c0bf488381ffc77e989e85dd81ad", + "parents": ["aa44a92d68014d0da98965c0c2cb8c07957d4362"], "title": "refactor: added commands folder, better integration with decli", "body": "", "author": "Commitizen", @@ -206,6 +233,7 @@ }, { "rev": "aa44a92d68014d0da98965c0c2cb8c07957d4362", + "parents": ["58bb709765380dbd46b74ce6e8978515764eb955"], "title": "Bump version: 1.0.0b2 → 1.0.0", "body": "", "author": "Commitizen", @@ -213,6 +241,7 @@ }, { "rev": "58bb709765380dbd46b74ce6e8978515764eb955", + "parents": ["97afb0bb48e72b6feca793091a8a23c706693257"], "title": "docs(README): new badges", "body": "", "author": "Commitizen", @@ -220,6 +249,10 @@ }, { "rev": "97afb0bb48e72b6feca793091a8a23c706693257", + "parents": [ + "9cecb9224aa7fa68d4afeac37eba2a25770ef251", + "e004a90b81ea5b374f118759bce5951202d03d69", + ], "title": "Merge pull request #10 from Woile/feat/decli", "body": "Feat/decli", "author": "Commitizen", @@ -227,6 +260,7 @@ }, { "rev": "9cecb9224aa7fa68d4afeac37eba2a25770ef251", + "parents": ["f5781d1a2954d71c14ade2a6a1a95b91310b2577"], "title": "style: black to files", "body": "", "author": "Commitizen", @@ -234,6 +268,7 @@ }, { "rev": "f5781d1a2954d71c14ade2a6a1a95b91310b2577", + "parents": ["80105fb3c6d45369bc0cbf787bd329fba603864c"], "title": "ci: added travis", "body": "", "author": "Commitizen", @@ -241,6 +276,7 @@ }, { "rev": "80105fb3c6d45369bc0cbf787bd329fba603864c", + "parents": ["a96008496ffefb6b1dd9b251cb479eac6a0487f7"], "title": "refactor: removed delegator, added decli and many tests", "body": "BREAKING CHANGE: API is stable", "author": "Commitizen", @@ -248,6 +284,7 @@ }, { "rev": "a96008496ffefb6b1dd9b251cb479eac6a0487f7", + "parents": ["aab33d13110f26604fb786878856ec0b9e5fc32b"], "title": "docs: updated test command", "body": "", "author": "Commitizen", @@ -255,6 +292,7 @@ }, { "rev": "aab33d13110f26604fb786878856ec0b9e5fc32b", + "parents": ["b73791563d2f218806786090fb49ef70faa51a3a"], "title": "Bump version: 1.0.0b1 → 1.0.0b2", "body": "", "author": "Commitizen", @@ -262,6 +300,7 @@ }, { "rev": "b73791563d2f218806786090fb49ef70faa51a3a", + "parents": ["7aa06a454fb717408b3657faa590731fb4ab3719"], "title": "docs(README): updated to reflect current state", "body": "", "author": "Commitizen", @@ -269,6 +308,10 @@ }, { "rev": "7aa06a454fb717408b3657faa590731fb4ab3719", + "parents": [ + "7c7e96b723c2aaa1aec3a52561f680adf0b60e97", + "9589a65880016996cff156b920472b9d28d771ca", + ], "title": "Merge pull request #9 from Woile/dev", "body": "feat: py3 only, tests and conventional commits 1.0", "author": "Commitizen", @@ -276,6 +319,7 @@ }, { "rev": "7c7e96b723c2aaa1aec3a52561f680adf0b60e97", + "parents": ["ed830019581c83ba633bfd734720e6758eca6061"], "title": "Bump version: 0.9.11 → 1.0.0b1", "body": "", "author": "Commitizen", @@ -283,6 +327,7 @@ }, { "rev": "ed830019581c83ba633bfd734720e6758eca6061", + "parents": ["c52eca6f74f844ab3ffbde61d98ef96071e132b7"], "title": "feat: py3 only, tests and conventional commits 1.0", "body": "more tests\npyproject instead of Pipfile\nquestionary instead of whaaaaat (promptkit 2.0.0 support)", "author": "Commitizen", @@ -290,6 +335,7 @@ }, { "rev": "c52eca6f74f844ab3ffbde61d98ef96071e132b7", + "parents": ["0326652b2657083929507ee66d4d1a0899e861ba"], "title": "Bump version: 0.9.10 → 0.9.11", "body": "", "author": "Commitizen", @@ -297,6 +343,7 @@ }, { "rev": "0326652b2657083929507ee66d4d1a0899e861ba", + "parents": ["b3f89892222340150e32631ae6b7aab65230036f"], "title": "fix(config): load config reads in order without failing if there is no commitizen section", "body": "Closes #8", "author": "Commitizen", @@ -304,6 +351,7 @@ }, { "rev": "b3f89892222340150e32631ae6b7aab65230036f", + "parents": ["5e837bf8ef0735193597372cd2d85e31a8f715b9"], "title": "Bump version: 0.9.9 → 0.9.10", "body": "", "author": "Commitizen", @@ -311,6 +359,7 @@ }, { "rev": "5e837bf8ef0735193597372cd2d85e31a8f715b9", + "parents": ["684e0259cc95c7c5e94854608cd3dcebbd53219e"], "title": "fix: parse scope (this is my punishment for not having tests)", "body": "", "author": "Commitizen", @@ -318,6 +367,7 @@ }, { "rev": "684e0259cc95c7c5e94854608cd3dcebbd53219e", + "parents": ["ca38eac6ff09870851b5c76a6ff0a2a8e5ecda15"], "title": "Bump version: 0.9.8 → 0.9.9", "body": "", "author": "Commitizen", @@ -325,6 +375,7 @@ }, { "rev": "ca38eac6ff09870851b5c76a6ff0a2a8e5ecda15", + "parents": ["64168f18d4628718c49689ee16430549e96c5d4b"], "title": "fix: parse scope empty", "body": "", "author": "Commitizen", @@ -332,6 +383,7 @@ }, { "rev": "64168f18d4628718c49689ee16430549e96c5d4b", + "parents": ["9d4def716ef235a1fa5ae61614366423fbc8256f"], "title": "Bump version: 0.9.7 → 0.9.8", "body": "", "author": "Commitizen", @@ -339,6 +391,7 @@ }, { "rev": "9d4def716ef235a1fa5ae61614366423fbc8256f", + "parents": ["33b0bf1a0a4dc60aac45ed47476d2e5473add09e"], "title": "fix(scope): parse correctly again", "body": "", "author": "Commitizen", @@ -346,6 +399,7 @@ }, { "rev": "33b0bf1a0a4dc60aac45ed47476d2e5473add09e", + "parents": ["696885e891ec35775daeb5fec3ba2ab92c2629e1"], "title": "Bump version: 0.9.6 → 0.9.7", "body": "", "author": "Commitizen", @@ -353,6 +407,7 @@ }, { "rev": "696885e891ec35775daeb5fec3ba2ab92c2629e1", + "parents": ["bef4a86761a3bda309c962bae5d22ce9b57119e4"], "title": "fix(scope): parse correctly", "body": "", "author": "Commitizen", @@ -360,6 +415,7 @@ }, { "rev": "bef4a86761a3bda309c962bae5d22ce9b57119e4", + "parents": ["72472efb80f08ee3fd844660afa012c8cb256e4b"], "title": "Bump version: 0.9.5 → 0.9.6", "body": "", "author": "Commitizen", @@ -367,6 +423,7 @@ }, { "rev": "72472efb80f08ee3fd844660afa012c8cb256e4b", + "parents": ["b5561ce0ab3b56bb87712c8f90bcf37cf2474f1b"], "title": "refactor(conventionalCommit): moved filters to questions instead of message", "body": "", "author": "Commitizen", @@ -374,6 +431,7 @@ }, { "rev": "b5561ce0ab3b56bb87712c8f90bcf37cf2474f1b", + "parents": ["3e31714dc737029d96898f412e4ecd2be1bcd0ce"], "title": "fix(manifest): included missing files", "body": "", "author": "Commitizen", @@ -381,6 +439,7 @@ }, { "rev": "3e31714dc737029d96898f412e4ecd2be1bcd0ce", + "parents": ["9df721e06595fdd216884c36a28770438b4f4a39"], "title": "Bump version: 0.9.4 → 0.9.5", "body": "", "author": "Commitizen", @@ -388,6 +447,7 @@ }, { "rev": "9df721e06595fdd216884c36a28770438b4f4a39", + "parents": ["0cf6ada372470c8d09e6c9e68ebf94bbd5a1656f"], "title": "fix(config): home path for python versions between 3.0 and 3.5", "body": "", "author": "Commitizen", @@ -395,6 +455,7 @@ }, { "rev": "0cf6ada372470c8d09e6c9e68ebf94bbd5a1656f", + "parents": ["973c6b3e100f6f69a3fe48bd8ee55c135b96c318"], "title": "Bump version: 0.9.3 → 0.9.4", "body": "", "author": "Commitizen", @@ -402,6 +463,7 @@ }, { "rev": "973c6b3e100f6f69a3fe48bd8ee55c135b96c318", + "parents": ["dacc86159b260ee98eb5f57941c99ba731a01399"], "title": "feat(cli): added version", "body": "", "author": "Commitizen", @@ -409,6 +471,7 @@ }, { "rev": "dacc86159b260ee98eb5f57941c99ba731a01399", + "parents": ["4368f3c3cbfd4a1ced339212230d854bc5bab496"], "title": "Bump version: 0.9.2 → 0.9.3", "body": "", "author": "Commitizen", @@ -416,6 +479,7 @@ }, { "rev": "4368f3c3cbfd4a1ced339212230d854bc5bab496", + "parents": ["da94133288727d35dae9b91866a25045038f2d38"], "title": "feat(committer): conventional commit is a bit more intelligent now", "body": "", "author": "Commitizen", @@ -423,6 +487,7 @@ }, { "rev": "da94133288727d35dae9b91866a25045038f2d38", + "parents": ["1541f54503d2e1cf39bd777c0ca5ab5eb78772ba"], "title": "docs(README): motivation", "body": "", "author": "Commitizen", @@ -430,6 +495,7 @@ }, { "rev": "1541f54503d2e1cf39bd777c0ca5ab5eb78772ba", + "parents": ["ddc855a637b7879108308b8dbd85a0fd27c7e0e7"], "title": "Bump version: 0.9.1 → 0.9.2", "body": "", "author": "Commitizen", @@ -437,6 +503,7 @@ }, { "rev": "ddc855a637b7879108308b8dbd85a0fd27c7e0e7", + "parents": ["46e9032e18a819e466618c7a014bcb0e9981af9e"], "title": "refactor: renamed conventional_changelog to conventional_commits, not backward compatible", "body": "", "author": "Commitizen", @@ -444,6 +511,7 @@ }, { "rev": "46e9032e18a819e466618c7a014bcb0e9981af9e", + "parents": ["0fef73cd7dc77a25b82e197e7c1d3144a58c1350"], "title": "Bump version: 0.9.0 → 0.9.1", "body": "", "author": "Commitizen", @@ -451,6 +519,7 @@ }, { "rev": "0fef73cd7dc77a25b82e197e7c1d3144a58c1350", + "parents": [], "title": "fix(setup.py): future is now required for every python version", "body": "", "author": "Commitizen", @@ -489,6 +558,7 @@ def gitcommits() -> list: commit["body"], commit["author"], commit["author_email"], + commit["parents"], ) for commit in COMMITS_DATA ] @@ -1108,6 +1178,7 @@ def test_generate_tree_from_commits(gitcommits, tags, merge_prereleases): assert change["author"] == "Commitizen" assert change["author_email"] in "author@cz.dev" assert "sha1" in change + assert "parents" in change def test_generate_tree_from_commits_with_no_commits(tags): From 3f767e154f1459207523b688b8794f0343191f69 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz <alex@flawedcode.org> Date: Fri, 21 Mar 2025 12:53:45 +0100 Subject: [PATCH 434/598] docs(customization): add "parents" to the list of fields in Changes --- docs/customization.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/customization.md b/docs/customization.md index 132f4f0490..50113301db 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -507,12 +507,16 @@ Each `Change` has the following fields: | scope | `str | None` | An optional scope | | message | `str` | The commit message body | | sha1 | `str` | The commit `sha1` | +| parents | `list[str]` | The parent commit(s) `sha1`(s) | | author | `str` | The commit author name | | author_email | `str` | The commit author email | !!! Note The field values depend on the customization class and/or the settings you provide +The `parents` field can be used to identify merge commits and generate a changelog based on those. Another use case +is listing commits that belong to the same pull request. + When using another template (either provided by a plugin or by yourself), you can also pass extra template variables by: From 35f5c23b6dad6bd6be24f783857751bca71ae36d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Sun, 13 Apr 2025 07:26:06 +0000 Subject: [PATCH 435/598] =?UTF-8?q?bump:=20version=204.5.1=20=E2=86=92=204?= =?UTF-8?q?.6.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 7 +++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19b4394cf6..1373277b2d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.5.1 # automatically updated by Commitizen + rev: v4.6.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 39eee25df0..1d2ab1e48f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v4.6.0 (2025-04-13) + +### Feat + +- **changelog**: expose commit parents' digests when processing commits +- **git**: add parents' digests in commit information + ## v4.5.1 (2025-04-09) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index f9f7166e62..db01fb213a 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.5.1" +__version__ = "4.6.0" diff --git a/pyproject.toml b/pyproject.toml index c9ea806cfc..6475ec01a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.5.1" +version = "4.6.0" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.5.1" +version = "4.6.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 58ca48db42fe994bda1617ea998b9089a2222b03 Mon Sep 17 00:00:00 2001 From: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> Date: Tue, 22 Apr 2025 13:43:12 +0200 Subject: [PATCH 436/598] ci(github-actions): bump deprecated ubuntu-20.04 to ubuntu-22.04 Signed-off-by: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> --- .github/workflows/pythonpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index f2363745cb..b50b02a681 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -7,7 +7,7 @@ jobs: strategy: matrix: python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] - platform: [ubuntu-20.04, macos-latest, windows-latest] + platform: [ubuntu-22.04, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 From af285656734fd74c13a8d373a2a0ff303e0971f1 Mon Sep 17 00:00:00 2001 From: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> Date: Tue, 22 Apr 2025 13:30:57 +0200 Subject: [PATCH 437/598] build(deps): bump argcomplete from 3.5.3 to 3.6.2 Signed-off-by: Jakob Keller <57402305+jakob-keller@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 073e1bc247..cccd7a532a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,14 +2,14 @@ [[package]] name = "argcomplete" -version = "3.5.3" +version = "3.6.2" description = "Bash tab completion for argparse" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "argcomplete-3.5.3-py3-none-any.whl", hash = "sha256:2ab2c4a215c59fd6caaff41a869480a23e8f6a5f910b266c1808037f4e375b61"}, - {file = "argcomplete-3.5.3.tar.gz", hash = "sha256:c12bf50eded8aebb298c7b7da7a5ff3ee24dffd9f5281867dfe1424b58c55392"}, + {file = "argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591"}, + {file = "argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf"}, ] [package.extras] @@ -1965,4 +1965,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "b0f8544806163bc0dddc039eb313f9d82119b845b3a19dedc381e9c88e8f4466" +content-hash = "e15b424a0569f939e297c8abfcf09753f1fbcc5b4ad891163cc0982accd3b372" diff --git a/pyproject.toml b/pyproject.toml index 6475ec01a2..5be231aaa7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ dependencies = [ "tomlkit (>=0.5.3,<1.0.0)", "jinja2>=2.10.3", "pyyaml>=3.08", - "argcomplete >=1.12.1,<3.6", + "argcomplete >=1.12.1,<3.7", "typing-extensions (>=4.0.1,<5.0.0) ; python_version < '3.11'", "charset-normalizer (>=2.1.0,<4)", # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility From 2a8a8ea93d519e5964ef92a9a673b5b014898064 Mon Sep 17 00:00:00 2001 From: Alexander Gubin <alexander.gubin@oediv.de> Date: Tue, 29 Apr 2025 14:32:43 +0200 Subject: [PATCH 438/598] fix(commit): use os.unlink to remove temp file NamedTemporaryFile doesn't have a unlink function when delete=False is used Fix https://github.com/commitizen-tools/commitizen/issues/1352 --- commitizen/commands/commit.py | 2 +- tests/commands/test_commit_command.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index abecb3b3ca..93f048082b 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -89,7 +89,7 @@ def manual_edit(self, message: str) -> str: subprocess.call(argv) with open(file_path) as temp_file: message = temp_file.read().strip() - file.unlink() + os.unlink(file.name) return message def __call__(self): diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 55751f6902..3a92f5af48 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -511,8 +511,6 @@ def test_manual_edit(editor, config, mocker: MockFixture, tmp_path): assert edited_message == test_message.strip() - temp_file.unlink() - @skip_below_py_3_13 def test_commit_command_shows_description_when_use_help_option( From 53d43ad0920b23e8867952274783f14848cb887e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 01:09:40 +0000 Subject: [PATCH 439/598] =?UTF-8?q?bump:=20version=204.6.0=20=E2=86=92=204?= =?UTF-8?q?.6.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1373277b2d..ee153c3500 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.6.0 # automatically updated by Commitizen + rev: v4.6.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d2ab1e48f..ecd6b68143 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.6.1 (2025-05-05) + +### Fix + +- **commit**: use os.unlink to remove temp file + ## v4.6.0 (2025-04-13) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index db01fb213a..b56d675263 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.6.0" +__version__ = "4.6.1" diff --git a/pyproject.toml b/pyproject.toml index 5be231aaa7..6744c14858 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.6.0" +version = "4.6.1" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.6.0" +version = "4.6.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 943b51fb7890b2a14e220ce6d30c7f0d40ba185c Mon Sep 17 00:00:00 2001 From: Raffaello Baluyot <baluyotraf@outlook.com> Date: Mon, 5 May 2025 22:19:55 +0200 Subject: [PATCH 440/598] fix(docs): fix url link and table formatting in the customization docs (#1399) --- docs/customization.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/customization.md b/docs/customization.md index 50113301db..da41071b98 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -164,7 +164,7 @@ commitizen: | `change_type_map` | `dict` | `None` | (OPTIONAL) Dictionary mapping the type of the commit to a changelog entry | [jinja2]: https://jinja.palletsprojects.com/en/2.10.x/ -[changelog-spec]: https://commitizen-tools.github.io/commitizen/changelog/ +[changelog-spec]: https://commitizen-tools.github.io/commitizen/commands/changelog/ #### Detailed `questions` content @@ -177,6 +177,7 @@ commitizen: | `default` | `Any` | `None` | (OPTIONAL) The default value for this question. | | `filter` | `str` | `None` | (OPTIONAL) Validator for user's answer. **(Work in Progress)** | | `multiline` | `bool` | `False` | (OPTIONAL) Enable multiline support when `type = input`. | + [different-question-types]: https://github.com/tmbo/questionary#different-question-types #### Shortcut keys From c44e2fe8ccd7760147d90426c3782d525558d589 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 20:20:18 +0000 Subject: [PATCH 441/598] =?UTF-8?q?bump:=20version=204.6.1=20=E2=86=92=204?= =?UTF-8?q?.6.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee153c3500..ac8b996267 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.6.1 # automatically updated by Commitizen + rev: v4.6.2 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd6b68143..def8dab180 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.6.2 (2025-05-05) + +### Fix + +- **docs**: fix url link and table formatting in the customization docs (#1399) + ## v4.6.1 (2025-05-05) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index b56d675263..456bc7c315 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.6.1" +__version__ = "4.6.2" diff --git a/pyproject.toml b/pyproject.toml index 6744c14858..43bed32b5c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.6.1" +version = "4.6.2" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.6.1" +version = "4.6.2" tag_format = "v$version" version_files = [ "pyproject.toml:version", From a3682d5afc156272f7b3135232c3619c4d25b142 Mon Sep 17 00:00:00 2001 From: baluyotraf <baluyotraf@outlook.com> Date: Mon, 5 May 2025 18:06:48 +0200 Subject: [PATCH 442/598] docs: Fix the changelog_pattern regex in the monorepo tutorial --- docs/tutorials/monorepo_guidance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index 817f92321d..e530c596c7 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -71,11 +71,11 @@ Example config and commit for `library-b`: ```toml [tool.commitizen.customize] -changelog_pattern = "^(feat|fix)\\(library-b\\)(!)?:" #the pattern on types can be a wild card or any types you wish to include +changelog_pattern = "^(feat|fix)\(library-b\)(!)?:" #the pattern on types can be a wild card or any types you wish to include ``` A commit message looking like this, would be included: ``` -fix:(library-b) Some awesome message +fix(library-b): Some awesome message ``` From 5f607f3d090bbc9291cce4ca3fec6bd1618ac2d5 Mon Sep 17 00:00:00 2001 From: baluyotraf <baluyotraf@outlook.com> Date: Tue, 6 May 2025 15:42:35 +0200 Subject: [PATCH 443/598] Revert removal of escape in toml --- docs/tutorials/monorepo_guidance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index e530c596c7..792c8c224f 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -71,7 +71,7 @@ Example config and commit for `library-b`: ```toml [tool.commitizen.customize] -changelog_pattern = "^(feat|fix)\(library-b\)(!)?:" #the pattern on types can be a wild card or any types you wish to include +changelog_pattern = "^(feat|fix)\\(library-b\\)(!)?:" #the pattern on types can be a wild card or any types you wish to include ``` A commit message looking like this, would be included: From c991feaf07370e635e38cd713d59da06eb19aba1 Mon Sep 17 00:00:00 2001 From: name <you@example.com> Date: Tue, 8 Apr 2025 02:19:34 +0800 Subject: [PATCH 444/598] docs(customization.md): add select type and search filter documentation --- docs/customization.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/customization.md b/docs/customization.md index da41071b98..31749d1c83 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -170,13 +170,15 @@ commitizen: | Parameter | Type | Default | Description | | ----------- | ------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `type` | `str` | `None` | The type of questions. Valid type: `list`, `input` and etc. [See More][different-question-types] | +| `type` | `str` | `None` | The type of questions. Valid types: `list`, `select`, `input` and etc. The `select` type provides an interactive searchable list interface. [See More][different-question-types] | | `name` | `str` | `None` | The key for the value answered by user. It's used in `message_template` | | `message` | `str` | `None` | Detail description for the question. | -| `choices` | `list` | `None` | (OPTIONAL) The choices when `type = list`. Either use a list of values or a list of dictionaries with `name` and `value` keys. Keyboard shortcuts can be defined via `key`. See examples above. | +| `choices` | `list` | `None` | (OPTIONAL) The choices when `type = list` or `type = select`. Either use a list of values or a list of dictionaries with `name` and `value` keys. Keyboard shortcuts can be defined via `key`. See examples above. | | `default` | `Any` | `None` | (OPTIONAL) The default value for this question. | | `filter` | `str` | `None` | (OPTIONAL) Validator for user's answer. **(Work in Progress)** | -| `multiline` | `bool` | `False` | (OPTIONAL) Enable multiline support when `type = input`. | +| `multiline` | `bool` | `False` | (OPTIONAL) Enable multiline support when `type = input`. | +| `use_search_filter` | `bool` | `False` | (OPTIONAL) Enable search/filter functionality for list/select type questions. This allows users to type and filter through the choices. | +| `use_jk_keys` | `bool` | `True` | (OPTIONAL) Enable/disable j/k keys for navigation in list/select type questions. Set to false if you prefer arrow keys only. | [different-question-types]: https://github.com/tmbo/questionary#different-question-types @@ -445,8 +447,8 @@ Commitizen gives you the possibility to provide your own changelog template, by: - providing one with your customization class - providing one from the current working directory and setting it: - - as [configuration][template-config] - - as `--template` parameter to both `bump` and `changelog` commands + - as [configuration][template-config] + - as `--template` parameter to both `bump` and `changelog` commands - either by providing a template with the same name as the default template By default, the template used is the `CHANGELOG.md.j2` file from the commitizen repository. From 5be28470ecf803c5092794201810ef89f54b9f87 Mon Sep 17 00:00:00 2001 From: yusin huang <os-yusin.huang@twtp1pc1753.deltaos.corp> Date: Mon, 14 Apr 2025 10:11:42 +0800 Subject: [PATCH 445/598] test(test_cz_search_filter.py): add test cases for search filter configuration --- tests/test_cz_search_filter.py | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 tests/test_cz_search_filter.py diff --git a/tests/test_cz_search_filter.py b/tests/test_cz_search_filter.py new file mode 100644 index 0000000000..0e70e3104a --- /dev/null +++ b/tests/test_cz_search_filter.py @@ -0,0 +1,76 @@ +import pytest + +from commitizen.config import TomlConfig +from commitizen.cz.customize import CustomizeCommitsCz + +TOML_WITH_SEARCH_FILTER = r""" +[tool.commitizen] +name = "cz_customize" + +[tool.commitizen.customize] +message_template = "{{change_type}}:{% if scope %} ({{scope}}){% endif %}{% if breaking %}!{% endif %} {{message}}" + +[[tool.commitizen.customize.questions]] +type = "select" +name = "change_type" +message = "Select the type of change you are committing" +use_search_filter = true +use_jk_keys = false +choices = [ + {value = "fix", name = "fix: A bug fix. Correlates with PATCH in SemVer"}, + {value = "feat", name = "feat: A new feature. Correlates with MINOR in SemVer"}, + {value = "docs", name = "docs: Documentation only changes"}, + {value = "style", name = "style: Changes that do not affect the meaning of the code"}, + {value = "refactor", name = "refactor: A code change that neither fixes a bug nor adds a feature"}, + {value = "perf", name = "perf: A code change that improves performance"}, + {value = "test", name = "test: Adding missing or correcting existing tests"}, + {value = "build", name = "build: Changes that affect the build system or external dependencies"}, + {value = "ci", name = "ci: Changes to CI configuration files and scripts"} +] + +[[tool.commitizen.customize.questions]] +type = "input" +name = "scope" +message = "What is the scope of this change? (class or file name): (press [enter] to skip)" + +[[tool.commitizen.customize.questions]] +type = "input" +name = "message" +message = "Write a short and imperative summary of the code changes: (lower case and no period)" +""" + + +@pytest.fixture +def config(): + return TomlConfig(data=TOML_WITH_SEARCH_FILTER, path="not_exist.toml") + + +def test_questions_with_search_filter(config): + """Test that questions are properly configured with search filter""" + cz = CustomizeCommitsCz(config) + questions = cz.questions() + + # Test that the first question (change_type) has search filter enabled + assert questions[0]["type"] == "select" + assert questions[0]["name"] == "change_type" + assert questions[0]["use_search_filter"] is True + assert questions[0]["use_jk_keys"] is False + + # Test that the choices are properly configured + choices = questions[0]["choices"] + assert len(choices) == 9 # We have 9 commit types + assert choices[0]["value"] == "fix" + assert choices[1]["value"] == "feat" + + +def test_message_template(config): + """Test that the message template is properly configured""" + cz = CustomizeCommitsCz(config) + template = cz.message( + { + "change_type": "feat", + "scope": "search", + "message": "add search filter support", + } + ) + assert template == "feat: (search) add search filter support" From 776d70f700752789a42b31864807c389337e314f Mon Sep 17 00:00:00 2001 From: Yusin Huang <abcd51018@gmail.com> Date: Tue, 15 Apr 2025 23:00:50 +0800 Subject: [PATCH 446/598] fix(changelog.py): modify the CHANGELOG.md generated by cz bump --changelog to the right place --- commitizen/commands/changelog.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 80a72651e4..71bc93265b 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -32,21 +32,28 @@ 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( - "changelog_start_rev" - ) - self.file_name = args.get("file_name") or cast( + changelog_file_name = args.get("file_name") or cast( str, self.config.settings.get("changelog_file") ) - if not isinstance(self.file_name, str): + if not isinstance(changelog_file_name, str): raise NotAllowed( "Changelog file name is broken.\n" "Check the flag `--file-name` in the terminal " f"or the setting `changelog_file` in {self.config.path}" ) + self.file_name = ( + str(Path(self.config.path.parent) / changelog_file_name) + if self.config.path is not None + else changelog_file_name + ) + + 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( + "changelog_start_rev" + ) + self.changelog_format = get_changelog_format(self.config, self.file_name) self.incremental = args["incremental"] or self.config.settings.get( From 15c185709ea2dba6a850f1b19c9a3790d4e92f50 Mon Sep 17 00:00:00 2001 From: Yusin Huang <abcd51018@gmail.com> Date: Tue, 15 Apr 2025 23:01:40 +0800 Subject: [PATCH 447/598] test(test_changelog_command.py): add test for changelog file_name construction from args and config --- tests/test_changelog.py | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index df42b82264..6ffb6bc294 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,13 +1,18 @@ +from __future__ import annotations + import re from dataclasses import dataclass from pathlib import Path -from typing import Any, Optional +from typing import Any +from unittest.mock import Mock import pytest from jinja2 import FileSystemLoader from commitizen import changelog, git from commitizen.changelog_formats import ChangelogFormat +from commitizen.commands.changelog import Changelog +from commitizen.config import BaseConfig from commitizen.cz.conventional_commits.conventional_commits import ( ConventionalCommitsCz, ) @@ -1499,7 +1504,7 @@ def changelog_message_builder_hook(message: dict, commit: git.GitCommit): def test_render_changelog_with_changelog_release_hook( gitcommits, tags, any_changelog_format: ChangelogFormat ): - def changelog_release_hook(release: dict, tag: Optional[git.GitTag]) -> dict: + def changelog_release_hook(release: dict, tag: git.GitTag | None) -> dict: release["extra"] = "whatever" return release @@ -1631,3 +1636,32 @@ def test_tags_rules_get_version_tags(capsys: pytest.CaptureFixture): captured = capsys.readouterr() assert captured.err.count("InvalidVersion") == 2 assert captured.err.count("not-a-version") == 2 + + +def test_changelog_file_name_from_args_and_config(): + mock_config = Mock(spec=BaseConfig) + mock_config.path.parent = "/my/project/" + mock_config.settings = { + "name": "cz_conventional_commits", + "changelog_file": "CHANGELOG.md", + "encoding": "utf-8", + "changelog_start_rev": "v1.0.0", + "tag_format": "$version", + "legacy_tag_formats": [], + "ignored_tag_formats": [], + "incremental": True, + "changelog_merge_prerelease": True, + } + + args = { + "file_name": "CUSTOM.md", + "incremental": None, + "dry_run": False, + "unreleased_version": "1.0.1", + } + changelog = Changelog(mock_config, args) + assert changelog.file_name == "/my/project/CUSTOM.md" + + args = {"incremental": None, "dry_run": False, "unreleased_version": "1.0.1"} + changelog = Changelog(mock_config, args) + assert changelog.file_name == "/my/project/CHANGELOG.md" From 7bea5a5082fe0fafc1e62515a9868095bb96fa4c Mon Sep 17 00:00:00 2001 From: Yusin Huang <abcd51018@gmail.com> Date: Thu, 17 Apr 2025 01:02:27 +0800 Subject: [PATCH 448/598] fix(changelog.py): cross-platform path handling using os.path.join and modify the path linter and test parameter --- commitizen/commands/changelog.py | 3 ++- tests/test_changelog.py | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 71bc93265b..3b8f43e372 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -1,5 +1,6 @@ from __future__ import annotations +import os import os.path from difflib import SequenceMatcher from operator import itemgetter @@ -42,7 +43,7 @@ def __init__(self, config: BaseConfig, args): f"or the setting `changelog_file` in {self.config.path}" ) self.file_name = ( - str(Path(self.config.path.parent) / changelog_file_name) + os.path.join(str(self.config.path.parent), changelog_file_name) if self.config.path is not None else changelog_file_name ) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 6ffb6bc294..67ba273b5c 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1,5 +1,6 @@ from __future__ import annotations +import os import re from dataclasses import dataclass from pathlib import Path @@ -1640,7 +1641,7 @@ def test_tags_rules_get_version_tags(capsys: pytest.CaptureFixture): def test_changelog_file_name_from_args_and_config(): mock_config = Mock(spec=BaseConfig) - mock_config.path.parent = "/my/project/" + mock_config.path.parent = "/my/project" mock_config.settings = { "name": "cz_conventional_commits", "changelog_file": "CHANGELOG.md", @@ -1660,8 +1661,12 @@ def test_changelog_file_name_from_args_and_config(): "unreleased_version": "1.0.1", } changelog = Changelog(mock_config, args) - assert changelog.file_name == "/my/project/CUSTOM.md" + assert os.path.normpath(changelog.file_name) == os.path.normpath( + os.path.join("/my/project", "CUSTOM.md") + ) args = {"incremental": None, "dry_run": False, "unreleased_version": "1.0.1"} changelog = Changelog(mock_config, args) - assert changelog.file_name == "/my/project/CHANGELOG.md" + assert os.path.normpath(changelog.file_name) == os.path.normpath( + os.path.join("/my/project", "CHANGELOG.md") + ) From e177141ec11f6bf72a6661c6a9fabebe3b670251 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 00:43:53 +0000 Subject: [PATCH 449/598] =?UTF-8?q?bump:=20version=204.6.2=20=E2=86=92=204?= =?UTF-8?q?.6.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 7 +++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ac8b996267..08c31ba0a0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.6.2 # automatically updated by Commitizen + rev: v4.6.3 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index def8dab180..dbad463955 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v4.6.3 (2025-05-07) + +### Fix + +- **changelog.py**: cross-platform path handling using os.path.join and modify the path linter and test parameter +- **changelog.py**: modify the CHANGELOG.md generated by cz bump --changelog to the right place + ## v4.6.2 (2025-05-05) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 456bc7c315..de3842dc77 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.6.2" +__version__ = "4.6.3" diff --git a/pyproject.toml b/pyproject.toml index 43bed32b5c..92b28fd091 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.6.2" +version = "4.6.3" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.6.2" +version = "4.6.3" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 72c274309fbbb87f8bccd0ba7aee12ea71fa1fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuna=20Alika=C5=9Fifo=C4=9Flu?= <tunakasif@gmail.com> Date: Thu, 8 May 2025 22:55:24 +0300 Subject: [PATCH 450/598] feat(providers): add support for `Cargo.lock` If `Cargo.lock` file is present in the same path as the `Cargo.toml`, the version of the package will also be updated in the `Cargo.lock` file. The implementation is similar to the one used for `UvProvider`, which extends the `CargoProvider` to handle lock files. The change does not break any existing functionality, if the `Cargo.lock` file is not present, since it checks for the existence of the file before attempting a lock file update. --- commitizen/providers/cargo_provider.py | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/commitizen/providers/cargo_provider.py b/commitizen/providers/cargo_provider.py index cee687c15b..2e73ff35a1 100644 --- a/commitizen/providers/cargo_provider.py +++ b/commitizen/providers/cargo_provider.py @@ -1,5 +1,7 @@ from __future__ import annotations +from pathlib import Path + import tomlkit from commitizen.providers.base_provider import TomlProvider @@ -13,6 +15,11 @@ class CargoProvider(TomlProvider): """ filename = "Cargo.toml" + lock_filename = "Cargo.lock" + + @property + def lock_file(self) -> Path: + return Path() / self.lock_filename def get(self, document: tomlkit.TOMLDocument) -> str: try: @@ -28,3 +35,23 @@ def set(self, document: tomlkit.TOMLDocument, version: str): except tomlkit.exceptions.NonExistentKey: ... document["package"]["version"] = version # type: ignore + + def set_version(self, version: str) -> None: + super().set_version(version) + if self.lock_file.exists(): + self.set_lock_version(version) + + def set_lock_version(self, version: str) -> None: + cargo_toml_content = tomlkit.parse(self.file.read_text()) + try: + package_name = cargo_toml_content["package"]["name"] # type: ignore + except tomlkit.exceptions.NonExistentKey: + package_name = cargo_toml_content["workspace"]["package"]["name"] # type: ignore + + cargo_lock_content = tomlkit.parse(self.lock_file.read_text()) + packages: tomlkit.items.AoT = cargo_lock_content["package"] # type: ignore[assignment] + for i, package in enumerate(packages): + if package["name"] == package_name: + cargo_lock_content["package"][i]["version"] = version # type: ignore[index] + break + self.lock_file.write_text(tomlkit.dumps(cargo_lock_content)) From aabeae3f64c91b2735259a849c6832bfc0b997f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuna=20Alika=C5=9Fifo=C4=9Flu?= <tunakasif@gmail.com> Date: Thu, 8 May 2025 23:07:24 +0300 Subject: [PATCH 451/598] refactor(tests): increase verbosity of variables To add more test variables, increase the verbosity of current ones and make them more clear. --- tests/providers/test_cargo_provider.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/providers/test_cargo_provider.py b/tests/providers/test_cargo_provider.py index 646ef3a53d..2144a145a7 100644 --- a/tests/providers/test_cargo_provider.py +++ b/tests/providers/test_cargo_provider.py @@ -15,7 +15,7 @@ version = "0.1.0" """ -CARGO_EXPECTED = """\ +CARGO_TOML_EXPECTED = """\ [package] name = "whatever" version = "42.1" @@ -27,7 +27,7 @@ version = "0.1.0" """ -CARGO_WORKSPACE_EXPECTED = """\ +CARGO_WORKSPACE_TOML_EXPECTED = """\ [workspace.package] name = "whatever" version = "42.1" @@ -37,8 +37,8 @@ @pytest.mark.parametrize( "content, expected", ( - (CARGO_TOML, CARGO_EXPECTED), - (CARGO_WORKSPACE_TOML, CARGO_WORKSPACE_EXPECTED), + (CARGO_TOML, CARGO_TOML_EXPECTED), + (CARGO_WORKSPACE_TOML, CARGO_WORKSPACE_TOML_EXPECTED), ), ) def test_cargo_provider( From d14218b3ddf0e95855f6147ae472559c3a9d5055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuna=20Alika=C5=9Fifo=C4=9Flu?= <tunakasif@gmail.com> Date: Thu, 8 May 2025 23:08:12 +0300 Subject: [PATCH 452/598] test: add test for cargo provider with lock files Add a test to check the behavior of the cargo provider when a `Cargo.lock` file is present. This test ensures that the `CargoProvider` behaves correctly when the lock file is present, and updates both the `Cargo.lock` and `Cargo.toml` files accordingly. --- tests/providers/test_cargo_provider.py | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/providers/test_cargo_provider.py b/tests/providers/test_cargo_provider.py index 2144a145a7..4b20c6ea53 100644 --- a/tests/providers/test_cargo_provider.py +++ b/tests/providers/test_cargo_provider.py @@ -33,6 +33,32 @@ version = "42.1" """ +CARGO_LOCK = """\ +[[package]] +name = "whatever" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123abc" +dependencies = [ + "packageA", + "packageB", + "packageC", +] +""" + +CARGO_LOCK_EXPECTED = """\ +[[package]] +name = "whatever" +version = "42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123abc" +dependencies = [ + "packageA", + "packageB", + "packageC", +] +""" + @pytest.mark.parametrize( "content, expected", @@ -58,3 +84,46 @@ def test_cargo_provider( provider.set_version("42.1") assert file.read_text() == dedent(expected) + + +@pytest.mark.parametrize( + "toml_content, lock_content, toml_expected, lock_expected", + ( + ( + CARGO_TOML, + CARGO_LOCK, + CARGO_TOML_EXPECTED, + CARGO_LOCK_EXPECTED, + ), + ( + CARGO_WORKSPACE_TOML, + CARGO_LOCK, + CARGO_WORKSPACE_TOML_EXPECTED, + CARGO_LOCK_EXPECTED, + ), + ), +) +def test_cargo_provider_with_lock( + config: BaseConfig, + chdir: Path, + toml_content: str, + lock_content: str, + toml_expected: str, + lock_expected: str, +): + filename = CargoProvider.filename + file = chdir / filename + file.write_text(dedent(toml_content)) + + lock_filename = CargoProvider.lock_filename + lock_file = chdir / lock_filename + lock_file.write_text(dedent(lock_content)) + config.settings["version_provider"] = "cargo" + + provider = get_provider(config) + assert isinstance(provider, CargoProvider) + assert provider.get_version() == "0.1.0" + + provider.set_version("42.1") + assert file.read_text() == dedent(toml_expected) + assert lock_file.read_text() == dedent(lock_expected) From 7173c47d8561ec86d060ec3c8783604b7744cea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuna=20Alika=C5=9Fifo=C4=9Flu?= <tunakasif@gmail.com> Date: Thu, 8 May 2025 23:22:17 +0300 Subject: [PATCH 453/598] docs(providers): update `cargo` explanation Add `Cargo.lock` update information to the documentation. --- docs/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index d1ae90b29a..a522312743 100644 --- a/docs/config.md +++ b/docs/config.md @@ -353,7 +353,7 @@ Commitizen provides some version providers for some well known formats: | `pep621` | Get and set version from `pyproject.toml` `project.version` field | | `poetry` | Get and set version from `pyproject.toml` `tool.poetry.version` field | | `uv` | Get and set version from `pyproject.toml` `project.version` field and `uv.lock` `package.version` field whose `package.name` field is the same as `pyproject.toml` `project.name` field | -| `cargo` | Get and set version from `Cargo.toml` `project.version` field | +| `cargo` | Get and set version from `Cargo.toml` `package.version` field and `Cargo.lock` `package.version` field whose `package.name` field is the same as `Cargo.toml` `package.name` field | | `npm` | Get and set version from `package.json` `version` field, `package-lock.json` `version,packages.''.version` fields if the file exists, and `npm-shrinkwrap.json` `version,packages.''.version` fields if the file exists | | `composer` | Get and set version from `composer.json` `project.version` field | From be02801f92cb948ba86d8c1a9a306be4172e4efe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Sat, 10 May 2025 13:47:12 +0000 Subject: [PATCH 454/598] =?UTF-8?q?bump:=20version=204.6.3=20=E2=86=92=204?= =?UTF-8?q?.7.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 10 ++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 08c31ba0a0..ad78003cf3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.6.3 # automatically updated by Commitizen + rev: v4.7.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index dbad463955..7ca4f2aa70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## v4.7.0 (2025-05-10) + +### Feat + +- **providers**: add support for `Cargo.lock` + +### Refactor + +- **tests**: increase verbosity of variables + ## v4.6.3 (2025-05-07) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index de3842dc77..8355eb42a9 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.6.3" +__version__ = "4.7.0" diff --git a/pyproject.toml b/pyproject.toml index 92b28fd091..02c6d12762 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.6.3" +version = "4.7.0" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.6.3" +version = "4.7.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 454494788f0b9efc90b90c496d144b0edfc76348 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 11 May 2025 16:09:40 +0800 Subject: [PATCH 455/598] docs(bug_report.yml): update bug_report.yml Closes #1134 --- .github/ISSUE_TEMPLATE/bug_report.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 10d782d30b..3b15906cfa 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -48,14 +48,14 @@ body: attributes: label: Environment description: | - For older commitizen versions, please include the output of the following commands manually - placeholder: | - - commitizen version: `cz version` - - python version: `python --version` - - operating system: `python3 -c "import platform; print(platform.system())"` + For older commitizen versions, please include the output of the following command manually: ```bash cz version --report ``` + placeholder: | + Commitizen Version: 4.0.0 + Python Version: 3.13.3 (main, Apr 8 2025, 13:54:08) [Clang 16.0.0 (clang-1600.0.26.6)] + Operating System: Darwin validations: required: true From 617b610e2f6e1ea9c373a09e7355d134ff0e7ac8 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 11 May 2025 21:04:16 +0800 Subject: [PATCH 456/598] docs(bug_report.yml): resolve comments --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3b15906cfa..9ed5badae4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -48,7 +48,7 @@ body: attributes: label: Environment description: | - For older commitizen versions, please include the output of the following command manually: + Please use the following command to retrieve environment information ```bash cz version --report From d86ec4c32b619020f86724fdf7804cee48b77adc Mon Sep 17 00:00:00 2001 From: Tim Hsiung <bear890707@gmail.com> Date: Thu, 15 May 2025 19:11:52 +0800 Subject: [PATCH 457/598] style: fix some typos (#1407) --- commitizen/commands/bump.py | 2 +- commitizen/commands/changelog.py | 2 +- commitizen/commands/check.py | 6 +++--- commitizen/commands/commit.py | 2 +- commitizen/commands/example.py | 2 +- commitizen/commands/info.py | 2 +- commitizen/commands/init.py | 2 +- commitizen/commands/schema.py | 2 +- commitizen/factory.py | 2 +- commitizen/version_schemes.py | 10 +++++----- tests/commands/test_bump_command.py | 18 +++++++++--------- tests/commands/test_changelog_command.py | 4 ++-- tests/commands/test_check_command.py | 2 +- tests/commands/test_init_command.py | 2 +- tests/conftest.py | 2 +- tests/test_bump_update_version_in_files.py | 4 ++-- tests/test_changelog_format_asciidoc.py | 2 +- tests/test_changelog_format_markdown.py | 2 +- .../test_changelog_format_restructuredtext.py | 2 +- tests/test_changelog_format_textile.py | 2 +- tests/test_cz_customize.py | 6 +++--- tests/test_factory.py | 4 ++-- tests/test_version_scheme_pep440.py | 4 ++-- tests/test_version_scheme_semver.py | 4 ++-- 24 files changed, 45 insertions(+), 45 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 60853094f9..0a2bbe37fc 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -68,7 +68,7 @@ def __init__(self, config: BaseConfig, arguments: dict): if arguments[key] is not None }, } - self.cz = factory.commiter_factory(self.config) + self.cz = factory.committer_factory(self.config) self.changelog_flag = arguments["changelog"] self.changelog_config = self.config.settings.get("update_changelog_on_bump") self.changelog_to_stdout = arguments["changelog_to_stdout"] diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 3b8f43e372..fb6f76a6b7 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -49,7 +49,7 @@ def __init__(self, config: BaseConfig, args): ) self.encoding = self.config.settings["encoding"] - self.cz = factory.commiter_factory(self.config) + self.cz = factory.committer_factory(self.config) self.start_rev = args.get("start_rev") or self.config.settings.get( "changelog_start_rev" diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index e22155cf78..087db03ea5 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -46,7 +46,7 @@ def __init__(self, config: BaseConfig, arguments: dict[str, Any], cwd=os.getcwd( self.config: BaseConfig = config self.encoding = config.settings["encoding"] - self.cz = factory.commiter_factory(self.config) + self.cz = factory.committer_factory(self.config) def _valid_command_argument(self): num_exclusive_args_provided = sum( @@ -72,7 +72,7 @@ def __call__(self): raise NoCommitsFoundError(f"No commit found with range: '{self.rev_range}'") pattern = self.cz.schema_pattern() - ill_formated_commits = [ + ill_formatted_commits = [ commit for commit in commits if not self.validate_commit_message(commit.message, pattern) @@ -80,7 +80,7 @@ def __call__(self): displayed_msgs_content = "\n".join( [ f'commit "{commit.rev}": "{commit.message}"' - for commit in ill_formated_commits + for commit in ill_formatted_commits ] ) if displayed_msgs_content: diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 93f048082b..cb34c41a50 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -35,7 +35,7 @@ def __init__(self, config: BaseConfig, arguments: dict): self.config: BaseConfig = config self.encoding = config.settings["encoding"] - self.cz = factory.commiter_factory(self.config) + self.cz = factory.committer_factory(self.config) self.arguments = arguments self.temp_file: str = get_backup_file_path() diff --git a/commitizen/commands/example.py b/commitizen/commands/example.py index e7abe7b318..a28ad85f16 100644 --- a/commitizen/commands/example.py +++ b/commitizen/commands/example.py @@ -7,7 +7,7 @@ class Example: def __init__(self, config: BaseConfig, *args): self.config: BaseConfig = config - self.cz = factory.commiter_factory(self.config) + self.cz = factory.committer_factory(self.config) def __call__(self): out.write(self.cz.example()) diff --git a/commitizen/commands/info.py b/commitizen/commands/info.py index afac9797e4..abd4197e7f 100644 --- a/commitizen/commands/info.py +++ b/commitizen/commands/info.py @@ -7,7 +7,7 @@ class Info: def __init__(self, config: BaseConfig, *args): self.config: BaseConfig = config - self.cz = factory.commiter_factory(self.config) + self.cz = factory.committer_factory(self.config) def __call__(self): out.write(self.cz.info()) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index df872ec7ee..20277399d8 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -82,7 +82,7 @@ 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.cz = factory.committer_factory(self.config) self.project_info = ProjectInfo() def __call__(self): diff --git a/commitizen/commands/schema.py b/commitizen/commands/schema.py index 0940648cde..4af5679cf5 100644 --- a/commitizen/commands/schema.py +++ b/commitizen/commands/schema.py @@ -7,7 +7,7 @@ class Schema: def __init__(self, config: BaseConfig, *args): self.config: BaseConfig = config - self.cz = factory.commiter_factory(self.config) + self.cz = factory.committer_factory(self.config) def __call__(self): out.write(self.cz.schema()) diff --git a/commitizen/factory.py b/commitizen/factory.py index 09af5fd0f7..b5d665b65e 100644 --- a/commitizen/factory.py +++ b/commitizen/factory.py @@ -4,7 +4,7 @@ from commitizen.exceptions import NoCommitizenFoundException -def commiter_factory(config: BaseConfig) -> BaseCommitizen: +def committer_factory(config: BaseConfig) -> BaseCommitizen: """Return the correct commitizen existing in the registry.""" name: str = config.settings["name"] try: diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 2486be58c8..84ded9316e 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -19,7 +19,7 @@ else: import importlib_metadata as metadata -from packaging.version import InvalidVersion # noqa: F401: Rexpose the common exception +from packaging.version import InvalidVersion # noqa: F401: expose the common exception from packaging.version import Version as _BaseVersion from commitizen.defaults import MAJOR, MINOR, PATCH, Settings @@ -78,7 +78,7 @@ def is_prerelease(self) -> bool: @property def prerelease(self) -> str | None: - """The prelease potion of the version is this is a prerelease.""" + """The prerelease potion of the version is this is a prerelease.""" raise NotImplementedError("must be implemented") @property @@ -142,7 +142,7 @@ def bump( prerelease: The type of prerelease, if Any is_local_version: Whether to increment the local version instead exact_increment: Treat the increment and prerelease arguments explicitly. Disables logic - that attempts to deduce the correct increment when a prelease suffix is present. + that attempts to deduce the correct increment when a prerelease suffix is present. """ @@ -351,7 +351,7 @@ class SemVer2(SemVer): See: https://semver.org/spec/v2.0.0.html """ - _STD_PRELEASES = { + _STD_PRERELEASES = { "a": "alpha", "b": "beta", } @@ -359,7 +359,7 @@ class SemVer2(SemVer): @property def prerelease(self) -> str | None: if self.is_prerelease and self.pre: - prerelease_type = self._STD_PRELEASES.get(self.pre[0], self.pre[0]) + prerelease_type = self._STD_PRERELEASES.get(self.pre[0], self.pre[0]) return f"{prerelease_type}.{self.pre[1]}" return None diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index b5ff7e6edb..f3c1ba923b 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -209,7 +209,7 @@ def test_bump_command_increment_option( @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_command_prelease(mocker: MockFixture): +def test_bump_command_prerelease(mocker: MockFixture): create_file_and_commit("feat: location") # Create an alpha pre-release. @@ -281,7 +281,7 @@ def test_bump_command_prelease(mocker: MockFixture): @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_command_prelease_increment(mocker: MockFixture): +def test_bump_command_prerelease_increment(mocker: MockFixture): # FINAL RELEASE create_file_and_commit("fix: location") @@ -317,7 +317,7 @@ def test_bump_command_prelease_increment(mocker: MockFixture): @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_command_prelease_exact_mode(mocker: MockFixture): +def test_bump_command_prerelease_exact_mode(mocker: MockFixture): # PRERELEASE create_file_and_commit("feat: location") @@ -437,7 +437,7 @@ def test_bump_on_git_with_hooks_no_verify_enabled(mocker: MockFixture): @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_when_bumpping_is_not_support(mocker: MockFixture): +def test_bump_when_bumping_is_not_support(mocker: MockFixture): create_file_and_commit( "feat: new user interface\n\nBREAKING CHANGE: age is no longer supported" ) @@ -1062,7 +1062,7 @@ def test_bump_use_version_provider(mocker: MockFixture): mock.set_version.assert_called_once_with("0.0.1") -def test_bump_command_prelease_scheme_via_cli( +def test_bump_command_prerelease_scheme_via_cli( tmp_commitizen_project_initial, mocker: MockFixture ): tmp_commitizen_project = tmp_commitizen_project_initial() @@ -1101,7 +1101,7 @@ def test_bump_command_prelease_scheme_via_cli( assert "0.2.0" in f.read() -def test_bump_command_prelease_scheme_via_config( +def test_bump_command_prerelease_scheme_via_config( tmp_commitizen_project_initial, mocker: MockFixture ): tmp_commitizen_project = tmp_commitizen_project_initial( @@ -1145,7 +1145,7 @@ def test_bump_command_prelease_scheme_via_config( assert "0.2.0" in f.read() -def test_bump_command_prelease_scheme_check_old_tags( +def test_bump_command_prerelease_scheme_check_old_tags( tmp_commitizen_project_initial, mocker: MockFixture ): tmp_commitizen_project = tmp_commitizen_project_initial( @@ -1285,7 +1285,7 @@ def test_bump_command_version_scheme_priority_over_version_type(mocker: MockFixt ), ), ) -def test_bump_template_option_precedance( +def test_bump_template_option_precedence( mocker: MockFixture, tmp_commitizen_project: Path, any_changelog_format: ChangelogFormat, @@ -1327,7 +1327,7 @@ def test_bump_template_option_precedance( assert out == expected -def test_bump_template_extras_precedance( +def test_bump_template_extras_precedence( mocker: MockFixture, tmp_commitizen_project: Path, any_changelog_format: ChangelogFormat, diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index f794b8d9f3..12a2e04b42 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -1481,7 +1481,7 @@ def test_changelog_from_current_version_tag_with_nonversion_tag( ), ), ) -def test_changelog_template_option_precedance( +def test_changelog_template_option_precedence( mocker: MockFixture, tmp_commitizen_project: Path, any_changelog_format: ChangelogFormat, @@ -1523,7 +1523,7 @@ def test_changelog_template_option_precedance( assert out == expected -def test_changelog_template_extras_precedance( +def test_changelog_template_extras_precedence( mocker: MockFixture, tmp_commitizen_project: Path, mock_plugin: BaseCommitizen, diff --git a/tests/commands/test_check_command.py b/tests/commands/test_check_command.py index f1db446190..d95a173d8a 100644 --- a/tests/commands/test_check_command.py +++ b/tests/commands/test_check_command.py @@ -365,7 +365,7 @@ def test_check_command_with_pipe_message_and_failed(mocker: MockFixture): assert "commit validation: failed!" in str(excinfo.value) -def test_check_command_with_comment_in_messege_file(mocker: MockFixture, capsys): +def test_check_command_with_comment_in_message_file(mocker: MockFixture, capsys): testargs = ["cz", "check", "--commit-msg-file", "some_file"] mocker.patch.object(sys, "argv", testargs) mocker.patch( diff --git a/tests/commands/test_init_command.py b/tests/commands/test_init_command.py index ea18e89a2b..f617c51d8f 100644 --- a/tests/commands/test_init_command.py +++ b/tests/commands/test_init_command.py @@ -183,7 +183,7 @@ def check_pre_commit_config(expected: list[dict[str, Any]]): @pytest.mark.usefixtures("pre_commit_installed") class TestPreCommitCases: - def test_no_existing_pre_commit_conifg(_, default_choice, tmpdir, config): + def test_no_existing_pre_commit_config(_, default_choice, tmpdir, config): with tmpdir.as_cwd(): commands.Init(config)() check_cz_config(default_choice) diff --git a/tests/conftest.py b/tests/conftest.py index 3d88f19b12..60c586f2e6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -232,7 +232,7 @@ def message(self, answers: dict) -> str: @pytest.fixture def mock_plugin(mocker: MockerFixture, config: BaseConfig) -> BaseCommitizen: mock = MockPlugin(config) - mocker.patch("commitizen.factory.commiter_factory", return_value=mock) + mocker.patch("commitizen.factory.committer_factory", return_value=mock) return mock diff --git a/tests/test_bump_update_version_in_files.py b/tests/test_bump_update_version_in_files.py index 850b59c166..c14e4ad1cb 100644 --- a/tests/test_bump_update_version_in_files.py +++ b/tests/test_bump_update_version_in_files.py @@ -197,7 +197,7 @@ def test_file_version_inconsistent_error( assert expected_msg in str(excinfo.value) -def test_multiplt_versions_to_bump( +def test_multiple_versions_to_bump( multiple_versions_to_update_poetry_lock, file_regression ): old_version = "1.2.9" @@ -216,7 +216,7 @@ def test_update_version_in_globbed_files(commitizen_config_file, file_regression print(commitizen_config_file, other) copyfile(commitizen_config_file, other) - # Prepend full ppath as test assume absolute paths or cwd-relative + # Prepend full path as test assume absolute paths or cwd-relative version_files = [commitizen_config_file.dirpath("*.toml")] bump.update_version_in_files( diff --git a/tests/test_changelog_format_asciidoc.py b/tests/test_changelog_format_asciidoc.py index 59ca56191e..cc81a24f2a 100644 --- a/tests/test_changelog_format_asciidoc.py +++ b/tests/test_changelog_format_asciidoc.py @@ -160,7 +160,7 @@ def test_parse_title_type_of_line( pytest.param(CHANGELOG_D, EXPECTED_D, id="D"), ), ) -def test_get_matadata( +def test_get_metadata( tmp_path: Path, format: AsciiDoc, content: str, expected: Metadata ): changelog = tmp_path / format.default_changelog_file diff --git a/tests/test_changelog_format_markdown.py b/tests/test_changelog_format_markdown.py index e1f0d67311..1abc63f29f 100644 --- a/tests/test_changelog_format_markdown.py +++ b/tests/test_changelog_format_markdown.py @@ -160,7 +160,7 @@ def test_parse_title_type_of_line( pytest.param(CHANGELOG_D, EXPECTED_D, id="D"), ), ) -def test_get_matadata( +def test_get_metadata( tmp_path: Path, format: Markdown, content: str, expected: Metadata ): changelog = tmp_path / format.default_changelog_file diff --git a/tests/test_changelog_format_restructuredtext.py b/tests/test_changelog_format_restructuredtext.py index 74b6b736f9..14bc15ec09 100644 --- a/tests/test_changelog_format_restructuredtext.py +++ b/tests/test_changelog_format_restructuredtext.py @@ -311,7 +311,7 @@ def format_with_tags(config: BaseConfig, request) -> RestructuredText: @pytest.mark.parametrize("content, expected", CASES) -def test_get_matadata( +def test_get_metadata( tmp_path: Path, format: RestructuredText, content: str, expected: Metadata ): changelog = tmp_path / format.default_changelog_file diff --git a/tests/test_changelog_format_textile.py b/tests/test_changelog_format_textile.py index eb03484ad5..812fa6bf60 100644 --- a/tests/test_changelog_format_textile.py +++ b/tests/test_changelog_format_textile.py @@ -153,7 +153,7 @@ def test_parse_title_type_of_line( pytest.param(CHANGELOG_D, EXPECTED_D, id="D"), ), ) -def test_get_matadata( +def test_get_metadata( tmp_path: Path, format: Textile, content: str, expected: Metadata ): changelog = tmp_path / format.default_changelog_file diff --git a/tests/test_cz_customize.py b/tests/test_cz_customize.py index 210c8b6774..933b1aa065 100644 --- a/tests/test_cz_customize.py +++ b/tests/test_cz_customize.py @@ -473,16 +473,16 @@ def test_answer(config): cz = CustomizeCommitsCz(config) answers = { "change_type": "feature", - "message": "this feature enaable customize through config file", + "message": "this feature enable customize through config file", "show_message": True, } message = cz.message(answers) - assert message == "feature: this feature enaable customize through config file" + assert message == "feature: this feature enable customize through config file" cz = CustomizeCommitsCz(config) answers = { "change_type": "feature", - "message": "this feature enaable customize through config file", + "message": "this feature enable customize through config file", "show_message": False, } message = cz.message(answers) diff --git a/tests/test_factory.py b/tests/test_factory.py index 390742f467..d81a84b3d5 100644 --- a/tests/test_factory.py +++ b/tests/test_factory.py @@ -28,7 +28,7 @@ class OtherPlugin: def test_factory(): config = BaseConfig() config.settings.update({"name": defaults.DEFAULT_SETTINGS["name"]}) - r = factory.commiter_factory(config) + r = factory.committer_factory(config) assert isinstance(r, BaseCommitizen) @@ -36,7 +36,7 @@ def test_factory_fails(): config = BaseConfig() config.settings.update({"name": "Nothing"}) with pytest.raises(NoCommitizenFoundException) as excinfo: - factory.commiter_factory(config) + factory.committer_factory(config) assert "The committer has not been found in the system." in str(excinfo) diff --git a/tests/test_version_scheme_pep440.py b/tests/test_version_scheme_pep440.py index 6b1f621cb8..a983dad14a 100644 --- a/tests/test_version_scheme_pep440.py +++ b/tests/test_version_scheme_pep440.py @@ -144,7 +144,7 @@ (("3.1.4a0", "MAJOR", "alpha", 0, None), "4.0.0a0"), ] -excact_cases = [ +exact_cases = [ (("1.0.0", "PATCH", None, 0, None), "1.0.1"), (("1.0.0", "MINOR", None, 0, None), "1.1.0"), # with exact_increment=False: "1.0.0b0" @@ -213,7 +213,7 @@ def test_bump_pep440_version(test_input, expected): ) -@pytest.mark.parametrize("test_input, expected", excact_cases) +@pytest.mark.parametrize("test_input, expected", exact_cases) def test_bump_pep440_version_force(test_input, expected): current_version = test_input[0] increment = test_input[1] diff --git a/tests/test_version_scheme_semver.py b/tests/test_version_scheme_semver.py index 71d5e5876c..8785717a34 100644 --- a/tests/test_version_scheme_semver.py +++ b/tests/test_version_scheme_semver.py @@ -83,7 +83,7 @@ (("1.0.0-alpha1", None, "alpha", 0, None), "1.0.0-a2"), ] -excact_cases = [ +exact_cases = [ (("1.0.0", "PATCH", None, 0, None), "1.0.1"), (("1.0.0", "MINOR", None, 0, None), "1.1.0"), # with exact_increment=False: "1.0.0-b0" @@ -144,7 +144,7 @@ def test_bump_semver_version(test_input, expected): ) -@pytest.mark.parametrize("test_input, expected", excact_cases) +@pytest.mark.parametrize("test_input, expected", exact_cases) def test_bump_semver_version_force(test_input, expected): current_version = test_input[0] increment = test_input[1] From 2cb2daf39b78d0796ff39cc2912047ea6ea32e5d Mon Sep 17 00:00:00 2001 From: Tim Hsiung <bear890707@gmail.com> Date: Thu, 15 May 2025 19:13:20 +0800 Subject: [PATCH 458/598] docs(pull_request_template): make the checklist holistic (#1408) --- .github/pull_request_template.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 0064604fba..e28480e5b9 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,12 +9,24 @@ Please fill in the following content to let us know better about this change. ## Checklist +- [ ] I have read the [contributing guidelines](https://commitizen-tools.github.io/commitizen/contributing/) + +### Code Changes + - [ ] Add test cases to all the changes you introduce -- [ ] Run `poetry all` locally to ensure this change passes linter check and test -- [ ] Test the changes on the local machine manually +- [ ] Run `poetry all` locally to ensure this change passes linter check and tests +- [ ] Manually test the changes: + - [ ] Verify the feature/bug fix works as expected in real-world scenarios + - [ ] Test edge cases and error conditions + - [ ] Ensure backward compatibility is maintained + - [ ] Document any manual testing steps performed - [ ] Update the documentation for the changes -## Expected behavior +### Documentation Changes + +- [ ] Run `poetry doc` locally to ensure the documentation pages renders correctly + +## Expected Behavior <!-- A clear and concise description of what you expected to happen --> @@ -25,5 +37,5 @@ Please fill in the following content to let us know better about this change. 3. ... --> -## Additional context +## Additional Context <!-- Add any other RELATED ISSUE, context or screenshots about the pull request here. --> From 46c5ecc79ec7b3e1006a33cd69e1f576a5ba6379 Mon Sep 17 00:00:00 2001 From: "Axel H." <noirbizarre@users.noreply.github.com> Date: Fri, 16 May 2025 04:50:15 +0200 Subject: [PATCH 459/598] fix(bump): don't fail if an invalid version tag is present (fix #1410) (#1418) --- commitizen/tags.py | 12 +++++---- tests/commands/test_bump_command.py | 32 ++++++++++++++++++++++++ tests/commands/test_changelog_command.py | 8 +++--- tests/test_changelog.py | 2 +- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/commitizen/tags.py b/commitizen/tags.py index 5724bb2574..2b9a4b091a 100644 --- a/commitizen/tags.py +++ b/commitizen/tags.py @@ -113,6 +113,10 @@ def _format_regex(self, tag_pattern: str, star: bool = False) -> str: format_regex = format_regex.replace(pattern, regex) return format_regex + def _version_tag_error(self, tag: str) -> str: + """Format the error message for an invalid version tag""" + return f"Invalid version tag: '{tag}' does not match any configured tag format" + def is_version_tag(self, tag: str | GitTag, warn: bool = False) -> bool: """ True if a given tag is a legit version tag. @@ -120,9 +124,9 @@ def is_version_tag(self, tag: str | GitTag, warn: bool = False) -> bool: if `warn` is `True`, it will print a warning message if the tag is not a version tag. """ tag = tag.name if isinstance(tag, GitTag) else tag - is_legit = any(regex.match(tag) for regex in self.version_regexes) + is_legit = any(regex.fullmatch(tag) for regex in self.version_regexes) if warn and not is_legit and not self.is_ignored_tag(tag): - out.warn(f"InvalidVersion {tag} doesn't match any configured tag format") + out.warn(self._version_tag_error(tag)) return is_legit def is_ignored_tag(self, tag: str | GitTag) -> bool: @@ -146,9 +150,7 @@ def extract_version(self, tag: GitTag) -> Version: m for regex in self.version_regexes if (m := regex.fullmatch(tag.name)) ) if not (m := next(candidates, None)): - raise InvalidVersion( - f"Invalid version tag: '{tag.name}' does not match any configured tag format" - ) + raise InvalidVersion(self._version_tag_error(tag.name)) if "version" in m.groupdict(): return self.scheme(m.group("version")) diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index f3c1ba923b..e15539d8a7 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1656,3 +1656,35 @@ def test_bump_detect_legacy_tags_from_scm( cli.main() assert git.tag_exist("v0.4.3") + + +def test_bump_warn_but_dont_fail_on_invalid_tags( + tmp_commitizen_project: py.path.local, + mocker: MockFixture, + capsys: pytest.CaptureFixture, +): + project_root = Path(tmp_commitizen_project) + tmp_commitizen_cfg_file = project_root / "pyproject.toml" + tmp_commitizen_cfg_file.write_text( + "\n".join( + [ + "[tool.commitizen]", + 'version_provider = "scm"', + 'version_scheme = "pep440"', + ] + ), + ) + create_file_and_commit("feat: new file") + create_tag("0.4.2") + create_file_and_commit("feat: new file") + create_tag("0.4.3.deadbeaf") + create_file_and_commit("feat: new file") + + testargs = ["cz", "bump", "--increment", "patch", "--changelog"] + mocker.patch.object(sys, "argv", testargs) + cli.main() + + _, err = capsys.readouterr() + + assert err.count("Invalid version tag: '0.4.3.deadbeaf'") == 1 + assert git.tag_exist("0.4.3") diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 12a2e04b42..0eb29cdb04 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -1788,13 +1788,13 @@ def test_changelog_ignored_tags( out = open(changelog_path).read() _, err = capsys.readouterr() assert "## ignore-0.1.0" not in out - assert "InvalidVersion ignore-0.1.0" not in err + assert "Invalid version tag: 'ignore-0.1.0'" not in err assert "## ignored" not in out - assert "InvalidVersion ignored" not in err + assert "Invalid version tag: 'ignored'" not in err assert "## not-ignored" not in out - assert "InvalidVersion not-ignored" in err + assert "Invalid version tag: 'not-ignored'" in err assert "## v0.3.0" in out - assert "InvalidVersion v0.3.0" not in err + assert "Invalid version tag: 'v0.3.0'" not in err def test_changelog_template_extra_quotes( diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 67ba273b5c..067adb4a91 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1635,7 +1635,7 @@ def test_tags_rules_get_version_tags(capsys: pytest.CaptureFixture): } captured = capsys.readouterr() - assert captured.err.count("InvalidVersion") == 2 + assert captured.err.count("Invalid version tag:") == 2 assert captured.err.count("not-a-version") == 2 From a0cc4901b0faaced74c713a9e355555fc4de0880 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 02:50:37 +0000 Subject: [PATCH 460/598] =?UTF-8?q?bump:=20version=204.7.0=20=E2=86=92=204?= =?UTF-8?q?.7.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ad78003cf3..df32532598 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.7.0 # automatically updated by Commitizen + rev: v4.7.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ca4f2aa70..486ee8dcb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.7.1 (2025-05-16) + +### Fix + +- **bump**: don't fail if an invalid version tag is present (fix #1410) (#1418) + ## v4.7.0 (2025-05-10) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 8355eb42a9..cc72154c1b 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.7.0" +__version__ = "4.7.1" diff --git a/pyproject.toml b/pyproject.toml index 02c6d12762..734d5127be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.7.0" +version = "4.7.1" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.7.0" +version = "4.7.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 94c02b3faf89cacf7186ad8a84e9200ede851574 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 02:28:08 +0800 Subject: [PATCH 461/598] refactor(default): capitalize all constants and remove unnecessary variable --- commitizen/bump.py | 8 ++++---- commitizen/commands/changelog.py | 2 +- commitizen/commands/init.py | 4 ++-- commitizen/config/__init__.py | 2 +- .../conventional_commits.py | 8 ++++---- commitizen/cz/customize/customize.py | 8 ++++---- commitizen/defaults.py | 19 +++++++++---------- tests/test_conf.py | 4 ++-- 8 files changed, 27 insertions(+), 28 deletions(-) diff --git a/commitizen/bump.py b/commitizen/bump.py index adfab64cb0..76a8e15893 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -8,7 +8,7 @@ from string import Template from typing import cast -from commitizen.defaults import MAJOR, MINOR, PATCH, bump_message, encoding +from commitizen.defaults import BUMP_MESSAGE, ENCODING, MAJOR, MINOR, PATCH from commitizen.exceptions import CurrentVersionNotFoundError from commitizen.git import GitCommit, smart_open from commitizen.version_schemes import Increment, Version @@ -64,7 +64,7 @@ def update_version_in_files( files: list[str], *, check_consistency: bool = False, - encoding: str = encoding, + encoding: str = ENCODING, ) -> list[str]: """Change old version to the new one in every file given. @@ -121,7 +121,7 @@ def _bump_with_regex( current_version: str, new_version: str, regex: str, - encoding: str = encoding, + encoding: str = ENCODING, ) -> tuple[bool, str]: current_version_found = False lines = [] @@ -148,6 +148,6 @@ def create_commit_message( message_template: str | None = None, ) -> str: if message_template is None: - message_template = bump_message + message_template = BUMP_MESSAGE t = Template(message_template) return t.safe_substitute(current_version=current_version, new_version=new_version) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index fb6f76a6b7..0e4efabfa1 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -78,7 +78,7 @@ def __init__(self, config: BaseConfig, args): self.change_type_order = ( self.config.settings.get("change_type_order") or self.cz.change_type_order - or defaults.change_type_order + or defaults.CHANGE_TYPE_ORDER ) self.rev_range = args.get("rev_range") self.tag_format: str = ( diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 20277399d8..0eb3d99d17 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -11,7 +11,7 @@ from commitizen.__version__ import __version__ from commitizen.config import BaseConfig, JsonConfig, TomlConfig, YAMLConfig from commitizen.cz import registry -from commitizen.defaults import DEFAULT_SETTINGS, config_files +from commitizen.defaults import CONFIG_FILES, DEFAULT_SETTINGS from commitizen.exceptions import InitFailedError, NoAnswersError from commitizen.git import get_latest_tag_name, get_tag_names, smart_open from commitizen.version_schemes import KNOWN_SCHEMES, Version, get_version_scheme @@ -165,7 +165,7 @@ def _ask_config_path(self) -> str: name: str = questionary.select( "Please choose a supported config file: ", - choices=config_files, + choices=CONFIG_FILES, default=default_path, style=self.cz.style, ).unsafe_ask() diff --git a/commitizen/config/__init__.py b/commitizen/config/__init__.py index f3720bb1b3..9dfd591c40 100644 --- a/commitizen/config/__init__.py +++ b/commitizen/config/__init__.py @@ -28,7 +28,7 @@ def read_cfg(filepath: str | None = None) -> BaseConfig: cfg_paths = ( path / Path(filename) for path in cfg_search_paths - for filename in defaults.config_files + for filename in defaults.CONFIG_FILES ) for filename in cfg_paths: diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index c7b88258cb..af29a209fc 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -28,9 +28,9 @@ def parse_subject(text): class ConventionalCommitsCz(BaseCommitizen): - bump_pattern = defaults.bump_pattern - bump_map = defaults.bump_map - bump_map_major_version_zero = defaults.bump_map_major_version_zero + bump_pattern = defaults.BUMP_PATTERN + bump_map = defaults.BUMP_MAP + bump_map_major_version_zero = defaults.BUMP_MAP_MAJOR_VERSION_ZERO commit_parser = r"^((?P<change_type>feat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P<scope>[^()\r\n]*)\)|\()?(?P<breaking>!)?|\w+!):\s(?P<message>.*)?" # noqa change_type_map = { "feat": "Feat", @@ -38,7 +38,7 @@ class ConventionalCommitsCz(BaseCommitizen): "refactor": "Refactor", "perf": "Perf", } - changelog_pattern = defaults.bump_pattern + changelog_pattern = defaults.BUMP_PATTERN def questions(self) -> Questions: questions: Questions = [ diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index d53ae29f1b..afa35e92de 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -21,10 +21,10 @@ class CustomizeCommitsCz(BaseCommitizen): - bump_pattern = defaults.bump_pattern - bump_map = defaults.bump_map - bump_map_major_version_zero = defaults.bump_map_major_version_zero - change_type_order = defaults.change_type_order + bump_pattern = defaults.BUMP_PATTERN + bump_map = defaults.BUMP_MAP + bump_map_major_version_zero = defaults.BUMP_MAP_MAJOR_VERSION_ZERO + change_type_order = defaults.CHANGE_TYPE_ORDER def __init__(self, config: BaseConfig): super().__init__(config) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 0b78e1b0bb..0b6c28e6a9 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -60,8 +60,7 @@ class Settings(TypedDict, total=False): extras: dict[str, Any] -name: str = "cz_conventional_commits" -config_files: list[str] = [ +CONFIG_FILES: list[str] = [ "pyproject.toml", ".cz.toml", ".cz.json", @@ -70,10 +69,10 @@ class Settings(TypedDict, total=False): "cz.yaml", "cz.toml", ] -encoding: str = "utf-8" +ENCODING = "utf-8" DEFAULT_SETTINGS: Settings = { - "name": name, + "name": "cz_conventional_commits", "version": None, "version_files": [], "version_provider": "commitizen", @@ -102,7 +101,7 @@ class Settings(TypedDict, total=False): "pre_bump_hooks": [], "post_bump_hooks": [], "prerelease_offset": 0, - "encoding": encoding, + "encoding": ENCODING, "always_signoff": False, "template": None, # default provided by plugin "extras": {}, @@ -114,8 +113,8 @@ class Settings(TypedDict, total=False): CHANGELOG_FORMAT = "markdown" -bump_pattern = r"^((BREAKING[\-\ ]CHANGE|\w+)(\(.+\))?!?):" -bump_map = OrderedDict( +BUMP_PATTERN = r"^((BREAKING[\-\ ]CHANGE|\w+)(\(.+\))?!?):" +BUMP_MAP = OrderedDict( ( (r"^.+!$", MAJOR), (r"^BREAKING[\-\ ]CHANGE", MAJOR), @@ -125,7 +124,7 @@ class Settings(TypedDict, total=False): (r"^perf", PATCH), ) ) -bump_map_major_version_zero = OrderedDict( +BUMP_MAP_MAJOR_VERSION_ZERO = OrderedDict( ( (r"^.+!$", MINOR), (r"^BREAKING[\-\ ]CHANGE", MINOR), @@ -135,8 +134,8 @@ class Settings(TypedDict, total=False): (r"^perf", PATCH), ) ) -change_type_order = ["BREAKING CHANGE", "Feat", "Fix", "Refactor", "Perf"] -bump_message = "bump: version $current_version → $new_version" +CHANGE_TYPE_ORDER = ["BREAKING CHANGE", "Feat", "Fix", "Refactor", "Perf"] +BUMP_MESSAGE = "bump: version $current_version → $new_version" def get_tag_regexes( diff --git a/tests/test_conf.py b/tests/test_conf.py index 80d58983e7..f89a0049f4 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -151,7 +151,7 @@ def test_find_git_project_root(tmpdir): @pytest.mark.parametrize( - "config_files_manager", defaults.config_files.copy(), indirect=True + "config_files_manager", defaults.CONFIG_FILES.copy(), indirect=True ) def test_set_key(config_files_manager): _conf = config.read_cfg() @@ -162,7 +162,7 @@ def test_set_key(config_files_manager): class TestReadCfg: @pytest.mark.parametrize( - "config_files_manager", defaults.config_files.copy(), indirect=True + "config_files_manager", defaults.CONFIG_FILES.copy(), indirect=True ) def test_load_conf(_, config_files_manager): cfg = config.read_cfg() From 8d573069ff591f909c9b9725da769fbab05d5bb0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Sun, 18 May 2025 15:17:25 +0000 Subject: [PATCH 462/598] =?UTF-8?q?bump:=20version=204.7.1=20=E2=86=92=204?= =?UTF-8?q?.7.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index df32532598..7497946571 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.7.1 # automatically updated by Commitizen + rev: v4.7.2 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 486ee8dcb2..de772c6a75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.7.2 (2025-05-18) + +### Refactor + +- **default**: capitalize all constants and remove unnecessary variable + ## v4.7.1 (2025-05-16) ### Fix diff --git a/commitizen/__version__.py b/commitizen/__version__.py index cc72154c1b..98c926d162 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.7.1" +__version__ = "4.7.2" diff --git a/pyproject.toml b/pyproject.toml index 734d5127be..8d9214615a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.7.1" +version = "4.7.2" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.7.1" +version = "4.7.2" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 767c5fede43c8f8858778b3e7f372c532495c48e Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 19 May 2025 20:17:08 +0800 Subject: [PATCH 463/598] docs(ISSUE_TEMPLATE): correct labels --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/documentation.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 9ed5badae4..9d597c7b36 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,7 @@ name: 🛠 Bug report description: Create a report to help us improve title: Good bug title tells us about precise symptom, not about the root cause. -labels: [bug] +labels: ['type: bug'] body: - type: textarea id: description diff --git a/.github/ISSUE_TEMPLATE/documentation.yml b/.github/ISSUE_TEMPLATE/documentation.yml index 51d378b747..8fe40136c3 100644 --- a/.github/ISSUE_TEMPLATE/documentation.yml +++ b/.github/ISSUE_TEMPLATE/documentation.yml @@ -1,7 +1,7 @@ name: 📖 Documentation description: Suggest an improvement for the documentation of this project title: Content to be added or fixed -labels: [documentation] +labels: ['type: documentation'] body: - type: checkboxes id: type diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 7d67eb18af..4bd19b9b3a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,7 +1,7 @@ name: 🚀 Feature request description: Suggest an idea for this project title: "<One feature request per issue>" -labels: [feature] +labels: ['type: feature'] body: - type: textarea id: description From 2982c6e5e31c9fd171e364c2a2866dc109303c20 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 19 May 2025 20:32:54 +0800 Subject: [PATCH 464/598] docs(label_issues): add logics for adding os related labels --- .github/workflows/label_issues.yml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/label_issues.yml b/.github/workflows/label_issues.yml index 45ca450f89..ec18d98be2 100644 --- a/.github/workflows/label_issues.yml +++ b/.github/workflows/label_issues.yml @@ -15,9 +15,31 @@ jobs: - uses: actions/github-script@v7 with: script: | - github.rest.issues.addLabels({ + const issue = await github.rest.issues.get({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - labels: ['issue-status: needs-triage'] - }) + }); + + const body = issue.data.body || ''; + + const osLabels = new Set(); // Use a Set to avoid duplicates + + if (body.includes('Operating System: Darwin')) { + osLabels.add('os: macOS'); + } + + if (body.includes('Operating System: Linux')) { + osLabels.add('os: Linux'); + } + + if (body.includes('Operating System: Windows')) { + osLabels.add('os: Windows'); + } + + await github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['issue-status: needs-triage', ...osLabels], + }); From 49f4d2b1a68de7e9b78cd39497483787de892db2 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 19 May 2025 21:13:19 +0800 Subject: [PATCH 465/598] docs(label_issues): add comment --- .github/workflows/label_issues.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/label_issues.yml b/.github/workflows/label_issues.yml index ec18d98be2..e74a36c4bd 100644 --- a/.github/workflows/label_issues.yml +++ b/.github/workflows/label_issues.yml @@ -25,6 +25,7 @@ jobs: const osLabels = new Set(); // Use a Set to avoid duplicates + // Parse the "Environment" section, output of `cz version --report` if (body.includes('Operating System: Darwin')) { osLabels.add('os: macOS'); } From e3b4465261cfe9c541cdd1174adae53bc7e309cb Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 19 May 2025 22:05:33 +0800 Subject: [PATCH 466/598] docs(bug_report): add fallback command if cz version --report is not available --- .github/ISSUE_TEMPLATE/bug_report.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 9d597c7b36..5eac443f29 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -53,6 +53,14 @@ body: ```bash cz version --report ``` + + If `cz version --report` is not available, please run the following commands to retrieve your environment information: + + ```bash + echo "Commitizen Version: $(cz version)" + echo "Python Version: $(python3 -c 'import sys; print(sys.version)')" + echo "Operating System: $(python3 -c 'import platform; print(platform.system())')" + ``` placeholder: | Commitizen Version: 4.0.0 Python Version: 3.13.3 (main, Apr 8 2025, 13:54:08) [Clang 16.0.0 (clang-1600.0.26.6)] From 87873f99d89b3da65388d1a93827a1536e29348e Mon Sep 17 00:00:00 2001 From: Jani Jappinen <2580412+jappja@users.noreply.github.com> Date: Thu, 15 May 2025 09:19:20 +0000 Subject: [PATCH 467/598] feat(cli): add --tag-format argument to changelog command Changelog command already checks "tag_format" argument but cli support was missing. --- commitizen/cli.py | 4 ++++ ...angelog_command_shows_description_when_use_help_option.txt | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 72d824380d..d08afc6706 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -450,6 +450,10 @@ def __call__( "help": "Export the changelog template into this file instead of rendering it", }, *deepcopy(tpl_arguments), + { + "name": "--tag-format", + "help": "The format of the tag, wrap around simple quotes", + }, ], }, { diff --git a/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt b/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt index 461eb2edd6..91b7f389b5 100644 --- a/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_changelog_command/test_changelog_command_shows_description_when_use_help_option.txt @@ -3,7 +3,7 @@ usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] [--start-rev START_REV] [--merge-prerelease] [--version-scheme {pep440,semver,semver2}] [--export-template EXPORT_TEMPLATE] [--template TEMPLATE] - [--extra EXTRA] + [--extra EXTRA] [--tag-format TAG_FORMAT] [rev_range] generate changelog (note that it will overwrite existing file) @@ -37,3 +37,5 @@ options: changelog template file name (relative to the current working directory) --extra, -e EXTRA a changelog extra variable (in the form 'key=value') + --tag-format TAG_FORMAT + The format of the tag, wrap around simple quotes From dbdfa60e1f95eccd9eb5d22e20f854043b2a8d37 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 15:03:32 +0000 Subject: [PATCH 468/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz_changelog___help.svg | 194 ++++++++++--------- 1 file changed, 101 insertions(+), 93 deletions(-) diff --git a/docs/images/cli_help/cz_changelog___help.svg b/docs/images/cli_help/cz_changelog___help.svg index 1160ccf6cf..69304f40cf 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -1,4 +1,4 @@ -<svg class="rich-terminal" viewBox="0 0 994 1050.4" xmlns="http://www.w3.org/2000/svg"> +<svg class="rich-terminal" viewBox="0 0 994 1099.2" xmlns="http://www.w3.org/2000/svg"> <!-- Generated with Rich https://www.textualize.io --> <style> @@ -19,202 +19,210 @@ font-weight: 700; } - .terminal-1106739011-matrix { + .terminal-2926696453-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1106739011-title { + .terminal-2926696453-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1106739011-r1 { fill: #c5c8c6 } -.terminal-1106739011-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-1106739011-r3 { fill: #68a0b3;font-weight: bold } -.terminal-1106739011-r4 { fill: #98a84b } + .terminal-2926696453-r1 { fill: #c5c8c6 } +.terminal-2926696453-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-2926696453-r3 { fill: #68a0b3;font-weight: bold } +.terminal-2926696453-r4 { fill: #98a84b } </style> <defs> - <clipPath id="terminal-1106739011-clip-terminal"> - <rect x="0" y="0" width="975.0" height="999.4" /> + <clipPath id="terminal-2926696453-clip-terminal"> + <rect x="0" y="0" width="975.0" height="1048.2" /> </clipPath> - <clipPath id="terminal-1106739011-line-0"> + <clipPath id="terminal-2926696453-line-0"> <rect x="0" y="1.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-1"> +<clipPath id="terminal-2926696453-line-1"> <rect x="0" y="25.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-2"> +<clipPath id="terminal-2926696453-line-2"> <rect x="0" y="50.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-3"> +<clipPath id="terminal-2926696453-line-3"> <rect x="0" y="74.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-4"> +<clipPath id="terminal-2926696453-line-4"> <rect x="0" y="99.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-5"> +<clipPath id="terminal-2926696453-line-5"> <rect x="0" y="123.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-6"> +<clipPath id="terminal-2926696453-line-6"> <rect x="0" y="147.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-7"> +<clipPath id="terminal-2926696453-line-7"> <rect x="0" y="172.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-8"> +<clipPath id="terminal-2926696453-line-8"> <rect x="0" y="196.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-9"> +<clipPath id="terminal-2926696453-line-9"> <rect x="0" y="221.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-10"> +<clipPath id="terminal-2926696453-line-10"> <rect x="0" y="245.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-11"> +<clipPath id="terminal-2926696453-line-11"> <rect x="0" y="269.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-12"> +<clipPath id="terminal-2926696453-line-12"> <rect x="0" y="294.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-13"> +<clipPath id="terminal-2926696453-line-13"> <rect x="0" y="318.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-14"> +<clipPath id="terminal-2926696453-line-14"> <rect x="0" y="343.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-15"> +<clipPath id="terminal-2926696453-line-15"> <rect x="0" y="367.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-16"> +<clipPath id="terminal-2926696453-line-16"> <rect x="0" y="391.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-17"> +<clipPath id="terminal-2926696453-line-17"> <rect x="0" y="416.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-18"> +<clipPath id="terminal-2926696453-line-18"> <rect x="0" y="440.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-19"> +<clipPath id="terminal-2926696453-line-19"> <rect x="0" y="465.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-20"> +<clipPath id="terminal-2926696453-line-20"> <rect x="0" y="489.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-21"> +<clipPath id="terminal-2926696453-line-21"> <rect x="0" y="513.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-22"> +<clipPath id="terminal-2926696453-line-22"> <rect x="0" y="538.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-23"> +<clipPath id="terminal-2926696453-line-23"> <rect x="0" y="562.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-24"> +<clipPath id="terminal-2926696453-line-24"> <rect x="0" y="587.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-25"> +<clipPath id="terminal-2926696453-line-25"> <rect x="0" y="611.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-26"> +<clipPath id="terminal-2926696453-line-26"> <rect x="0" y="635.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-27"> +<clipPath id="terminal-2926696453-line-27"> <rect x="0" y="660.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-28"> +<clipPath id="terminal-2926696453-line-28"> <rect x="0" y="684.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-29"> +<clipPath id="terminal-2926696453-line-29"> <rect x="0" y="709.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-30"> +<clipPath id="terminal-2926696453-line-30"> <rect x="0" y="733.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-31"> +<clipPath id="terminal-2926696453-line-31"> <rect x="0" y="757.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-32"> +<clipPath id="terminal-2926696453-line-32"> <rect x="0" y="782.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-33"> +<clipPath id="terminal-2926696453-line-33"> <rect x="0" y="806.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-34"> +<clipPath id="terminal-2926696453-line-34"> <rect x="0" y="831.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-35"> +<clipPath id="terminal-2926696453-line-35"> <rect x="0" y="855.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-36"> +<clipPath id="terminal-2926696453-line-36"> <rect x="0" y="879.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-37"> +<clipPath id="terminal-2926696453-line-37"> <rect x="0" y="904.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-38"> +<clipPath id="terminal-2926696453-line-38"> <rect x="0" y="928.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-1106739011-line-39"> +<clipPath id="terminal-2926696453-line-39"> <rect x="0" y="953.1" width="976" height="24.65"/> </clipPath> +<clipPath id="terminal-2926696453-line-40"> + <rect x="0" y="977.5" width="976" height="24.65"/> + </clipPath> +<clipPath id="terminal-2926696453-line-41"> + <rect x="0" y="1001.9" width="976" height="24.65"/> + </clipPath> </defs> - <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="992" height="1048.4" rx="8"/> + <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="992" height="1097.2" rx="8"/> <g transform="translate(26,22)"> <circle cx="0" cy="0" r="7" fill="#ff5f57"/> <circle cx="22" cy="0" r="7" fill="#febc2e"/> <circle cx="44" cy="0" r="7" fill="#28c840"/> </g> - <g transform="translate(9, 41)" clip-path="url(#terminal-1106739011-clip-terminal)"> + <g transform="translate(9, 41)" clip-path="url(#terminal-2926696453-clip-terminal)"> - <g class="terminal-1106739011-matrix"> - <text class="terminal-1106739011-r1" x="0" y="20" textLength="256.2" clip-path="url(#terminal-1106739011-line-0)">$ cz changelog --help</text><text class="terminal-1106739011-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-1106739011-line-0)"> -</text><text class="terminal-1106739011-r1" x="0" y="44.4" textLength="244" clip-path="url(#terminal-1106739011-line-1)">usage: cz changelog </text><text class="terminal-1106739011-r2" x="244" y="44.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-1)">[</text><text class="terminal-1106739011-r1" x="256.2" y="44.4" textLength="24.4" clip-path="url(#terminal-1106739011-line-1)">-h</text><text class="terminal-1106739011-r2" x="280.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-1)">]</text><text class="terminal-1106739011-r2" x="305" y="44.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-1)">[</text><text class="terminal-1106739011-r1" x="317.2" y="44.4" textLength="109.8" clip-path="url(#terminal-1106739011-line-1)">--dry-run</text><text class="terminal-1106739011-r2" x="427" y="44.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-1)">]</text><text class="terminal-1106739011-r2" x="451.4" y="44.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-1)">[</text><text class="terminal-1106739011-r1" x="463.6" y="44.4" textLength="256.2" clip-path="url(#terminal-1106739011-line-1)">--file-name FILE_NAME</text><text class="terminal-1106739011-r2" x="719.8" y="44.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-1)">]</text><text class="terminal-1106739011-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-1)"> -</text><text class="terminal-1106739011-r2" x="244" y="68.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-2)">[</text><text class="terminal-1106739011-r1" x="256.2" y="68.8" textLength="475.8" clip-path="url(#terminal-1106739011-line-2)">--unreleased-version UNRELEASED_VERSION</text><text class="terminal-1106739011-r2" x="732" y="68.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-2)">]</text><text class="terminal-1106739011-r2" x="756.4" y="68.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-2)">[</text><text class="terminal-1106739011-r1" x="768.6" y="68.8" textLength="158.6" clip-path="url(#terminal-1106739011-line-2)">--incremental</text><text class="terminal-1106739011-r2" x="927.2" y="68.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-2)">]</text><text class="terminal-1106739011-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-2)"> -</text><text class="terminal-1106739011-r2" x="244" y="93.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-3)">[</text><text class="terminal-1106739011-r1" x="256.2" y="93.2" textLength="256.2" clip-path="url(#terminal-1106739011-line-3)">--start-rev START_REV</text><text class="terminal-1106739011-r2" x="512.4" y="93.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-3)">]</text><text class="terminal-1106739011-r2" x="536.8" y="93.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-3)">[</text><text class="terminal-1106739011-r1" x="549" y="93.2" textLength="219.6" clip-path="url(#terminal-1106739011-line-3)">--merge-prerelease</text><text class="terminal-1106739011-r2" x="768.6" y="93.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-3)">]</text><text class="terminal-1106739011-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-3)"> -</text><text class="terminal-1106739011-r2" x="244" y="117.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-4)">[</text><text class="terminal-1106739011-r1" x="256.2" y="117.6" textLength="207.4" clip-path="url(#terminal-1106739011-line-4)">--version-scheme </text><text class="terminal-1106739011-r2" x="463.6" y="117.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-4)">{</text><text class="terminal-1106739011-r1" x="475.8" y="117.6" textLength="256.2" clip-path="url(#terminal-1106739011-line-4)">pep440,semver,semver2</text><text class="terminal-1106739011-r2" x="732" y="117.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-4)">}</text><text class="terminal-1106739011-r2" x="744.2" y="117.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-4)">]</text><text class="terminal-1106739011-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-4)"> -</text><text class="terminal-1106739011-r2" x="244" y="142" textLength="12.2" clip-path="url(#terminal-1106739011-line-5)">[</text><text class="terminal-1106739011-r1" x="256.2" y="142" textLength="402.6" clip-path="url(#terminal-1106739011-line-5)">--export-template EXPORT_TEMPLATE</text><text class="terminal-1106739011-r2" x="658.8" y="142" textLength="12.2" clip-path="url(#terminal-1106739011-line-5)">]</text><text class="terminal-1106739011-r2" x="683.2" y="142" textLength="12.2" clip-path="url(#terminal-1106739011-line-5)">[</text><text class="terminal-1106739011-r1" x="695.4" y="142" textLength="231.8" clip-path="url(#terminal-1106739011-line-5)">--template TEMPLATE</text><text class="terminal-1106739011-r2" x="927.2" y="142" textLength="12.2" clip-path="url(#terminal-1106739011-line-5)">]</text><text class="terminal-1106739011-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-1106739011-line-5)"> -</text><text class="terminal-1106739011-r2" x="244" y="166.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-6)">[</text><text class="terminal-1106739011-r1" x="256.2" y="166.4" textLength="158.6" clip-path="url(#terminal-1106739011-line-6)">--extra EXTRA</text><text class="terminal-1106739011-r2" x="414.8" y="166.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-6)">]</text><text class="terminal-1106739011-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-6)"> -</text><text class="terminal-1106739011-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-7)"> -</text><text class="terminal-1106739011-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-8)"> -</text><text class="terminal-1106739011-r1" x="0" y="239.6" textLength="231.8" clip-path="url(#terminal-1106739011-line-9)">generate changelog </text><text class="terminal-1106739011-r2" x="231.8" y="239.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-9)">(</text><text class="terminal-1106739011-r1" x="244" y="239.6" textLength="500.2" clip-path="url(#terminal-1106739011-line-9)">note that it will overwrite existing file</text><text class="terminal-1106739011-r2" x="744.2" y="239.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-9)">)</text><text class="terminal-1106739011-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-9)"> -</text><text class="terminal-1106739011-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-1106739011-line-10)"> -</text><text class="terminal-1106739011-r1" x="0" y="288.4" textLength="256.2" clip-path="url(#terminal-1106739011-line-11)">positional arguments:</text><text class="terminal-1106739011-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-11)"> -</text><text class="terminal-1106739011-r1" x="0" y="312.8" textLength="805.2" clip-path="url(#terminal-1106739011-line-12)">  rev_range             generates changelog for the given version </text><text class="terminal-1106739011-r2" x="805.2" y="312.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-12)">(</text><text class="terminal-1106739011-r1" x="817.4" y="312.8" textLength="61" clip-path="url(#terminal-1106739011-line-12)">e.g: </text><text class="terminal-1106739011-r3" x="878.4" y="312.8" textLength="36.6" clip-path="url(#terminal-1106739011-line-12)">1.5</text><text class="terminal-1106739011-r1" x="915" y="312.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-12)">.</text><text class="terminal-1106739011-r3" x="927.2" y="312.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-12)">3</text><text class="terminal-1106739011-r2" x="939.4" y="312.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-12)">)</text><text class="terminal-1106739011-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-12)"> -</text><text class="terminal-1106739011-r1" x="0" y="337.2" textLength="500.2" clip-path="url(#terminal-1106739011-line-13)">                        or version range </text><text class="terminal-1106739011-r2" x="500.2" y="337.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-13)">(</text><text class="terminal-1106739011-r1" x="512.4" y="337.2" textLength="61" clip-path="url(#terminal-1106739011-line-13)">e.g: </text><text class="terminal-1106739011-r3" x="573.4" y="337.2" textLength="36.6" clip-path="url(#terminal-1106739011-line-13)">1.5</text><text class="terminal-1106739011-r1" x="610" y="337.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-13)">.</text><text class="terminal-1106739011-r3" x="622.2" y="337.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-13)">3</text><text class="terminal-1106739011-r1" x="634.4" y="337.2" textLength="24.4" clip-path="url(#terminal-1106739011-line-13)">..</text><text class="terminal-1106739011-r3" x="658.8" y="337.2" textLength="36.6" clip-path="url(#terminal-1106739011-line-13)">1.7</text><text class="terminal-1106739011-r1" x="695.4" y="337.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-13)">.</text><text class="terminal-1106739011-r3" x="707.6" y="337.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-13)">9</text><text class="terminal-1106739011-r2" x="719.8" y="337.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-13)">)</text><text class="terminal-1106739011-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-13)"> -</text><text class="terminal-1106739011-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-14)"> -</text><text class="terminal-1106739011-r1" x="0" y="386" textLength="97.6" clip-path="url(#terminal-1106739011-line-15)">options:</text><text class="terminal-1106739011-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-1106739011-line-15)"> -</text><text class="terminal-1106739011-r1" x="0" y="410.4" textLength="671" clip-path="url(#terminal-1106739011-line-16)">  -h, --help            show this help message and exit</text><text class="terminal-1106739011-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-16)"> -</text><text class="terminal-1106739011-r1" x="0" y="434.8" textLength="585.6" clip-path="url(#terminal-1106739011-line-17)">  --dry-run             show changelog to stdout</text><text class="terminal-1106739011-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-17)"> -</text><text class="terminal-1106739011-r1" x="0" y="459.2" textLength="280.6" clip-path="url(#terminal-1106739011-line-18)">  --file-name FILE_NAME</text><text class="terminal-1106739011-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-18)"> -</text><text class="terminal-1106739011-r1" x="0" y="483.6" textLength="573.4" clip-path="url(#terminal-1106739011-line-19)">                        file name of changelog </text><text class="terminal-1106739011-r2" x="573.4" y="483.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-19)">(</text><text class="terminal-1106739011-r1" x="585.6" y="483.6" textLength="109.8" clip-path="url(#terminal-1106739011-line-19)">default: </text><text class="terminal-1106739011-r4" x="695.4" y="483.6" textLength="170.8" clip-path="url(#terminal-1106739011-line-19)">'CHANGELOG.md'</text><text class="terminal-1106739011-r2" x="866.2" y="483.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-19)">)</text><text class="terminal-1106739011-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-19)"> -</text><text class="terminal-1106739011-r1" x="0" y="508" textLength="500.2" clip-path="url(#terminal-1106739011-line-20)">  --unreleased-version UNRELEASED_VERSION</text><text class="terminal-1106739011-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-1106739011-line-20)"> -</text><text class="terminal-1106739011-r1" x="0" y="532.4" textLength="707.6" clip-path="url(#terminal-1106739011-line-21)">                        set the value for the new version </text><text class="terminal-1106739011-r2" x="707.6" y="532.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-21)">(</text><text class="terminal-1106739011-r1" x="719.8" y="532.4" textLength="207.4" clip-path="url(#terminal-1106739011-line-21)">use the tag value</text><text class="terminal-1106739011-r2" x="927.2" y="532.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-21)">)</text><text class="terminal-1106739011-r1" x="939.4" y="532.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-21)">,</text><text class="terminal-1106739011-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-21)"> -</text><text class="terminal-1106739011-r1" x="0" y="556.8" textLength="622.2" clip-path="url(#terminal-1106739011-line-22)">                        instead of using unreleased</text><text class="terminal-1106739011-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-22)"> -</text><text class="terminal-1106739011-r1" x="0" y="581.2" textLength="939.4" clip-path="url(#terminal-1106739011-line-23)">  --incremental         generates changelog from last created version, useful</text><text class="terminal-1106739011-r1" x="976" y="581.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-23)"> -</text><text class="terminal-1106739011-r1" x="0" y="605.6" textLength="817.4" clip-path="url(#terminal-1106739011-line-24)">                        if the changelog has been manually modified</text><text class="terminal-1106739011-r1" x="976" y="605.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-24)"> -</text><text class="terminal-1106739011-r1" x="0" y="630" textLength="280.6" clip-path="url(#terminal-1106739011-line-25)">  --start-rev START_REV</text><text class="terminal-1106739011-r1" x="976" y="630" textLength="12.2" clip-path="url(#terminal-1106739011-line-25)"> -</text><text class="terminal-1106739011-r1" x="0" y="654.4" textLength="866.2" clip-path="url(#terminal-1106739011-line-26)">                        start rev of the changelog. If not set, it will</text><text class="terminal-1106739011-r1" x="976" y="654.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-26)"> -</text><text class="terminal-1106739011-r1" x="0" y="678.8" textLength="695.4" clip-path="url(#terminal-1106739011-line-27)">                        generate changelog from the start</text><text class="terminal-1106739011-r1" x="976" y="678.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-27)"> -</text><text class="terminal-1106739011-r1" x="0" y="703.2" textLength="915" clip-path="url(#terminal-1106739011-line-28)">  --merge-prerelease    collect all changes from prereleases into next non-</text><text class="terminal-1106739011-r1" x="976" y="703.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-28)"> -</text><text class="terminal-1106739011-r1" x="0" y="727.6" textLength="951.6" clip-path="url(#terminal-1106739011-line-29)">                        prerelease. If not set, it will include prereleases in</text><text class="terminal-1106739011-r1" x="976" y="727.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-29)"> -</text><text class="terminal-1106739011-r1" x="0" y="752" textLength="451.4" clip-path="url(#terminal-1106739011-line-30)">                        the changelog</text><text class="terminal-1106739011-r1" x="976" y="752" textLength="12.2" clip-path="url(#terminal-1106739011-line-30)"> -</text><text class="terminal-1106739011-r1" x="0" y="776.4" textLength="231.8" clip-path="url(#terminal-1106739011-line-31)">  --version-scheme </text><text class="terminal-1106739011-r2" x="231.8" y="776.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-31)">{</text><text class="terminal-1106739011-r1" x="244" y="776.4" textLength="256.2" clip-path="url(#terminal-1106739011-line-31)">pep440,semver,semver2</text><text class="terminal-1106739011-r2" x="500.2" y="776.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-31)">}</text><text class="terminal-1106739011-r1" x="976" y="776.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-31)"> -</text><text class="terminal-1106739011-r1" x="0" y="800.8" textLength="549" clip-path="url(#terminal-1106739011-line-32)">                        choose version scheme</text><text class="terminal-1106739011-r1" x="976" y="800.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-32)"> -</text><text class="terminal-1106739011-r1" x="0" y="825.2" textLength="427" clip-path="url(#terminal-1106739011-line-33)">  --export-template EXPORT_TEMPLATE</text><text class="terminal-1106739011-r1" x="976" y="825.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-33)"> -</text><text class="terminal-1106739011-r1" x="0" y="849.6" textLength="927.2" clip-path="url(#terminal-1106739011-line-34)">                        Export the changelog template into this file instead</text><text class="terminal-1106739011-r1" x="976" y="849.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-34)"> -</text><text class="terminal-1106739011-r1" x="0" y="874" textLength="475.8" clip-path="url(#terminal-1106739011-line-35)">                        of rendering it</text><text class="terminal-1106739011-r1" x="976" y="874" textLength="12.2" clip-path="url(#terminal-1106739011-line-35)"> -</text><text class="terminal-1106739011-r1" x="0" y="898.4" textLength="305" clip-path="url(#terminal-1106739011-line-36)">  --template, -t TEMPLATE</text><text class="terminal-1106739011-r1" x="976" y="898.4" textLength="12.2" clip-path="url(#terminal-1106739011-line-36)"> -</text><text class="terminal-1106739011-r1" x="0" y="922.8" textLength="646.6" clip-path="url(#terminal-1106739011-line-37)">                        changelog template file name </text><text class="terminal-1106739011-r2" x="646.6" y="922.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-37)">(</text><text class="terminal-1106739011-r1" x="658.8" y="922.8" textLength="280.6" clip-path="url(#terminal-1106739011-line-37)">relative to the current</text><text class="terminal-1106739011-r1" x="976" y="922.8" textLength="12.2" clip-path="url(#terminal-1106739011-line-37)"> -</text><text class="terminal-1106739011-r1" x="0" y="947.2" textLength="500.2" clip-path="url(#terminal-1106739011-line-38)">                        working directory</text><text class="terminal-1106739011-r2" x="500.2" y="947.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-38)">)</text><text class="terminal-1106739011-r1" x="976" y="947.2" textLength="12.2" clip-path="url(#terminal-1106739011-line-38)"> -</text><text class="terminal-1106739011-r1" x="0" y="971.6" textLength="622.2" clip-path="url(#terminal-1106739011-line-39)">  --extra, -e EXTRA     a changelog extra variable </text><text class="terminal-1106739011-r2" x="622.2" y="971.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-39)">(</text><text class="terminal-1106739011-r1" x="634.4" y="971.6" textLength="146.4" clip-path="url(#terminal-1106739011-line-39)">in the form </text><text class="terminal-1106739011-r4" x="780.8" y="971.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-39)">'</text><text class="terminal-1106739011-r4" x="793" y="971.6" textLength="36.6" clip-path="url(#terminal-1106739011-line-39)">key</text><text class="terminal-1106739011-r4" x="829.6" y="971.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-39)">=</text><text class="terminal-1106739011-r4" x="841.8" y="971.6" textLength="61" clip-path="url(#terminal-1106739011-line-39)">value</text><text class="terminal-1106739011-r4" x="902.8" y="971.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-39)">'</text><text class="terminal-1106739011-r2" x="915" y="971.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-39)">)</text><text class="terminal-1106739011-r1" x="976" y="971.6" textLength="12.2" clip-path="url(#terminal-1106739011-line-39)"> -</text><text class="terminal-1106739011-r1" x="976" y="996" textLength="12.2" clip-path="url(#terminal-1106739011-line-40)"> + <g class="terminal-2926696453-matrix"> + <text class="terminal-2926696453-r1" x="0" y="20" textLength="256.2" clip-path="url(#terminal-2926696453-line-0)">$ cz changelog --help</text><text class="terminal-2926696453-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-2926696453-line-0)"> +</text><text class="terminal-2926696453-r1" x="0" y="44.4" textLength="244" clip-path="url(#terminal-2926696453-line-1)">usage: cz changelog </text><text class="terminal-2926696453-r2" x="244" y="44.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-1)">[</text><text class="terminal-2926696453-r1" x="256.2" y="44.4" textLength="24.4" clip-path="url(#terminal-2926696453-line-1)">-h</text><text class="terminal-2926696453-r2" x="280.6" y="44.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-1)">]</text><text class="terminal-2926696453-r2" x="305" y="44.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-1)">[</text><text class="terminal-2926696453-r1" x="317.2" y="44.4" textLength="109.8" clip-path="url(#terminal-2926696453-line-1)">--dry-run</text><text class="terminal-2926696453-r2" x="427" y="44.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-1)">]</text><text class="terminal-2926696453-r2" x="451.4" y="44.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-1)">[</text><text class="terminal-2926696453-r1" x="463.6" y="44.4" textLength="256.2" clip-path="url(#terminal-2926696453-line-1)">--file-name FILE_NAME</text><text class="terminal-2926696453-r2" x="719.8" y="44.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-1)">]</text><text class="terminal-2926696453-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-1)"> +</text><text class="terminal-2926696453-r2" x="244" y="68.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-2)">[</text><text class="terminal-2926696453-r1" x="256.2" y="68.8" textLength="475.8" clip-path="url(#terminal-2926696453-line-2)">--unreleased-version UNRELEASED_VERSION</text><text class="terminal-2926696453-r2" x="732" y="68.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-2)">]</text><text class="terminal-2926696453-r2" x="756.4" y="68.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-2)">[</text><text class="terminal-2926696453-r1" x="768.6" y="68.8" textLength="158.6" clip-path="url(#terminal-2926696453-line-2)">--incremental</text><text class="terminal-2926696453-r2" x="927.2" y="68.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-2)">]</text><text class="terminal-2926696453-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-2)"> +</text><text class="terminal-2926696453-r2" x="244" y="93.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-3)">[</text><text class="terminal-2926696453-r1" x="256.2" y="93.2" textLength="256.2" clip-path="url(#terminal-2926696453-line-3)">--start-rev START_REV</text><text class="terminal-2926696453-r2" x="512.4" y="93.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-3)">]</text><text class="terminal-2926696453-r2" x="536.8" y="93.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-3)">[</text><text class="terminal-2926696453-r1" x="549" y="93.2" textLength="219.6" clip-path="url(#terminal-2926696453-line-3)">--merge-prerelease</text><text class="terminal-2926696453-r2" x="768.6" y="93.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-3)">]</text><text class="terminal-2926696453-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-3)"> +</text><text class="terminal-2926696453-r2" x="244" y="117.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-4)">[</text><text class="terminal-2926696453-r1" x="256.2" y="117.6" textLength="207.4" clip-path="url(#terminal-2926696453-line-4)">--version-scheme </text><text class="terminal-2926696453-r2" x="463.6" y="117.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-4)">{</text><text class="terminal-2926696453-r1" x="475.8" y="117.6" textLength="256.2" clip-path="url(#terminal-2926696453-line-4)">pep440,semver,semver2</text><text class="terminal-2926696453-r2" x="732" y="117.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-4)">}</text><text class="terminal-2926696453-r2" x="744.2" y="117.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-4)">]</text><text class="terminal-2926696453-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-4)"> +</text><text class="terminal-2926696453-r2" x="244" y="142" textLength="12.2" clip-path="url(#terminal-2926696453-line-5)">[</text><text class="terminal-2926696453-r1" x="256.2" y="142" textLength="402.6" clip-path="url(#terminal-2926696453-line-5)">--export-template EXPORT_TEMPLATE</text><text class="terminal-2926696453-r2" x="658.8" y="142" textLength="12.2" clip-path="url(#terminal-2926696453-line-5)">]</text><text class="terminal-2926696453-r2" x="683.2" y="142" textLength="12.2" clip-path="url(#terminal-2926696453-line-5)">[</text><text class="terminal-2926696453-r1" x="695.4" y="142" textLength="231.8" clip-path="url(#terminal-2926696453-line-5)">--template TEMPLATE</text><text class="terminal-2926696453-r2" x="927.2" y="142" textLength="12.2" clip-path="url(#terminal-2926696453-line-5)">]</text><text class="terminal-2926696453-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-2926696453-line-5)"> +</text><text class="terminal-2926696453-r2" x="244" y="166.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-6)">[</text><text class="terminal-2926696453-r1" x="256.2" y="166.4" textLength="158.6" clip-path="url(#terminal-2926696453-line-6)">--extra EXTRA</text><text class="terminal-2926696453-r2" x="414.8" y="166.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-6)">]</text><text class="terminal-2926696453-r2" x="439.2" y="166.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-6)">[</text><text class="terminal-2926696453-r1" x="451.4" y="166.4" textLength="280.6" clip-path="url(#terminal-2926696453-line-6)">--tag-format TAG_FORMAT</text><text class="terminal-2926696453-r2" x="732" y="166.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-6)">]</text><text class="terminal-2926696453-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-6)"> +</text><text class="terminal-2926696453-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-7)"> +</text><text class="terminal-2926696453-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-8)"> +</text><text class="terminal-2926696453-r1" x="0" y="239.6" textLength="231.8" clip-path="url(#terminal-2926696453-line-9)">generate changelog </text><text class="terminal-2926696453-r2" x="231.8" y="239.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-9)">(</text><text class="terminal-2926696453-r1" x="244" y="239.6" textLength="500.2" clip-path="url(#terminal-2926696453-line-9)">note that it will overwrite existing file</text><text class="terminal-2926696453-r2" x="744.2" y="239.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-9)">)</text><text class="terminal-2926696453-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-9)"> +</text><text class="terminal-2926696453-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-2926696453-line-10)"> +</text><text class="terminal-2926696453-r1" x="0" y="288.4" textLength="256.2" clip-path="url(#terminal-2926696453-line-11)">positional arguments:</text><text class="terminal-2926696453-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-11)"> +</text><text class="terminal-2926696453-r1" x="0" y="312.8" textLength="805.2" clip-path="url(#terminal-2926696453-line-12)">  rev_range             generates changelog for the given version </text><text class="terminal-2926696453-r2" x="805.2" y="312.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-12)">(</text><text class="terminal-2926696453-r1" x="817.4" y="312.8" textLength="61" clip-path="url(#terminal-2926696453-line-12)">e.g: </text><text class="terminal-2926696453-r3" x="878.4" y="312.8" textLength="36.6" clip-path="url(#terminal-2926696453-line-12)">1.5</text><text class="terminal-2926696453-r1" x="915" y="312.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-12)">.</text><text class="terminal-2926696453-r3" x="927.2" y="312.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-12)">3</text><text class="terminal-2926696453-r2" x="939.4" y="312.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-12)">)</text><text class="terminal-2926696453-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-12)"> +</text><text class="terminal-2926696453-r1" x="0" y="337.2" textLength="500.2" clip-path="url(#terminal-2926696453-line-13)">                        or version range </text><text class="terminal-2926696453-r2" x="500.2" y="337.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-13)">(</text><text class="terminal-2926696453-r1" x="512.4" y="337.2" textLength="61" clip-path="url(#terminal-2926696453-line-13)">e.g: </text><text class="terminal-2926696453-r3" x="573.4" y="337.2" textLength="36.6" clip-path="url(#terminal-2926696453-line-13)">1.5</text><text class="terminal-2926696453-r1" x="610" y="337.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-13)">.</text><text class="terminal-2926696453-r3" x="622.2" y="337.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-13)">3</text><text class="terminal-2926696453-r1" x="634.4" y="337.2" textLength="24.4" clip-path="url(#terminal-2926696453-line-13)">..</text><text class="terminal-2926696453-r3" x="658.8" y="337.2" textLength="36.6" clip-path="url(#terminal-2926696453-line-13)">1.7</text><text class="terminal-2926696453-r1" x="695.4" y="337.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-13)">.</text><text class="terminal-2926696453-r3" x="707.6" y="337.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-13)">9</text><text class="terminal-2926696453-r2" x="719.8" y="337.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-13)">)</text><text class="terminal-2926696453-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-13)"> +</text><text class="terminal-2926696453-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-14)"> +</text><text class="terminal-2926696453-r1" x="0" y="386" textLength="97.6" clip-path="url(#terminal-2926696453-line-15)">options:</text><text class="terminal-2926696453-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-2926696453-line-15)"> +</text><text class="terminal-2926696453-r1" x="0" y="410.4" textLength="671" clip-path="url(#terminal-2926696453-line-16)">  -h, --help            show this help message and exit</text><text class="terminal-2926696453-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-16)"> +</text><text class="terminal-2926696453-r1" x="0" y="434.8" textLength="585.6" clip-path="url(#terminal-2926696453-line-17)">  --dry-run             show changelog to stdout</text><text class="terminal-2926696453-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-17)"> +</text><text class="terminal-2926696453-r1" x="0" y="459.2" textLength="280.6" clip-path="url(#terminal-2926696453-line-18)">  --file-name FILE_NAME</text><text class="terminal-2926696453-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-18)"> +</text><text class="terminal-2926696453-r1" x="0" y="483.6" textLength="573.4" clip-path="url(#terminal-2926696453-line-19)">                        file name of changelog </text><text class="terminal-2926696453-r2" x="573.4" y="483.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-19)">(</text><text class="terminal-2926696453-r1" x="585.6" y="483.6" textLength="109.8" clip-path="url(#terminal-2926696453-line-19)">default: </text><text class="terminal-2926696453-r4" x="695.4" y="483.6" textLength="170.8" clip-path="url(#terminal-2926696453-line-19)">'CHANGELOG.md'</text><text class="terminal-2926696453-r2" x="866.2" y="483.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-19)">)</text><text class="terminal-2926696453-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-19)"> +</text><text class="terminal-2926696453-r1" x="0" y="508" textLength="500.2" clip-path="url(#terminal-2926696453-line-20)">  --unreleased-version UNRELEASED_VERSION</text><text class="terminal-2926696453-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-2926696453-line-20)"> +</text><text class="terminal-2926696453-r1" x="0" y="532.4" textLength="707.6" clip-path="url(#terminal-2926696453-line-21)">                        set the value for the new version </text><text class="terminal-2926696453-r2" x="707.6" y="532.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-21)">(</text><text class="terminal-2926696453-r1" x="719.8" y="532.4" textLength="207.4" clip-path="url(#terminal-2926696453-line-21)">use the tag value</text><text class="terminal-2926696453-r2" x="927.2" y="532.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-21)">)</text><text class="terminal-2926696453-r1" x="939.4" y="532.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-21)">,</text><text class="terminal-2926696453-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-21)"> +</text><text class="terminal-2926696453-r1" x="0" y="556.8" textLength="622.2" clip-path="url(#terminal-2926696453-line-22)">                        instead of using unreleased</text><text class="terminal-2926696453-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-22)"> +</text><text class="terminal-2926696453-r1" x="0" y="581.2" textLength="939.4" clip-path="url(#terminal-2926696453-line-23)">  --incremental         generates changelog from last created version, useful</text><text class="terminal-2926696453-r1" x="976" y="581.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-23)"> +</text><text class="terminal-2926696453-r1" x="0" y="605.6" textLength="817.4" clip-path="url(#terminal-2926696453-line-24)">                        if the changelog has been manually modified</text><text class="terminal-2926696453-r1" x="976" y="605.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-24)"> +</text><text class="terminal-2926696453-r1" x="0" y="630" textLength="280.6" clip-path="url(#terminal-2926696453-line-25)">  --start-rev START_REV</text><text class="terminal-2926696453-r1" x="976" y="630" textLength="12.2" clip-path="url(#terminal-2926696453-line-25)"> +</text><text class="terminal-2926696453-r1" x="0" y="654.4" textLength="866.2" clip-path="url(#terminal-2926696453-line-26)">                        start rev of the changelog. If not set, it will</text><text class="terminal-2926696453-r1" x="976" y="654.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-26)"> +</text><text class="terminal-2926696453-r1" x="0" y="678.8" textLength="695.4" clip-path="url(#terminal-2926696453-line-27)">                        generate changelog from the start</text><text class="terminal-2926696453-r1" x="976" y="678.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-27)"> +</text><text class="terminal-2926696453-r1" x="0" y="703.2" textLength="915" clip-path="url(#terminal-2926696453-line-28)">  --merge-prerelease    collect all changes from prereleases into next non-</text><text class="terminal-2926696453-r1" x="976" y="703.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-28)"> +</text><text class="terminal-2926696453-r1" x="0" y="727.6" textLength="951.6" clip-path="url(#terminal-2926696453-line-29)">                        prerelease. If not set, it will include prereleases in</text><text class="terminal-2926696453-r1" x="976" y="727.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-29)"> +</text><text class="terminal-2926696453-r1" x="0" y="752" textLength="451.4" clip-path="url(#terminal-2926696453-line-30)">                        the changelog</text><text class="terminal-2926696453-r1" x="976" y="752" textLength="12.2" clip-path="url(#terminal-2926696453-line-30)"> +</text><text class="terminal-2926696453-r1" x="0" y="776.4" textLength="231.8" clip-path="url(#terminal-2926696453-line-31)">  --version-scheme </text><text class="terminal-2926696453-r2" x="231.8" y="776.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-31)">{</text><text class="terminal-2926696453-r1" x="244" y="776.4" textLength="256.2" clip-path="url(#terminal-2926696453-line-31)">pep440,semver,semver2</text><text class="terminal-2926696453-r2" x="500.2" y="776.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-31)">}</text><text class="terminal-2926696453-r1" x="976" y="776.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-31)"> +</text><text class="terminal-2926696453-r1" x="0" y="800.8" textLength="549" clip-path="url(#terminal-2926696453-line-32)">                        choose version scheme</text><text class="terminal-2926696453-r1" x="976" y="800.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-32)"> +</text><text class="terminal-2926696453-r1" x="0" y="825.2" textLength="427" clip-path="url(#terminal-2926696453-line-33)">  --export-template EXPORT_TEMPLATE</text><text class="terminal-2926696453-r1" x="976" y="825.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-33)"> +</text><text class="terminal-2926696453-r1" x="0" y="849.6" textLength="927.2" clip-path="url(#terminal-2926696453-line-34)">                        Export the changelog template into this file instead</text><text class="terminal-2926696453-r1" x="976" y="849.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-34)"> +</text><text class="terminal-2926696453-r1" x="0" y="874" textLength="475.8" clip-path="url(#terminal-2926696453-line-35)">                        of rendering it</text><text class="terminal-2926696453-r1" x="976" y="874" textLength="12.2" clip-path="url(#terminal-2926696453-line-35)"> +</text><text class="terminal-2926696453-r1" x="0" y="898.4" textLength="305" clip-path="url(#terminal-2926696453-line-36)">  --template, -t TEMPLATE</text><text class="terminal-2926696453-r1" x="976" y="898.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-36)"> +</text><text class="terminal-2926696453-r1" x="0" y="922.8" textLength="646.6" clip-path="url(#terminal-2926696453-line-37)">                        changelog template file name </text><text class="terminal-2926696453-r2" x="646.6" y="922.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-37)">(</text><text class="terminal-2926696453-r1" x="658.8" y="922.8" textLength="280.6" clip-path="url(#terminal-2926696453-line-37)">relative to the current</text><text class="terminal-2926696453-r1" x="976" y="922.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-37)"> +</text><text class="terminal-2926696453-r1" x="0" y="947.2" textLength="500.2" clip-path="url(#terminal-2926696453-line-38)">                        working directory</text><text class="terminal-2926696453-r2" x="500.2" y="947.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-38)">)</text><text class="terminal-2926696453-r1" x="976" y="947.2" textLength="12.2" clip-path="url(#terminal-2926696453-line-38)"> +</text><text class="terminal-2926696453-r1" x="0" y="971.6" textLength="622.2" clip-path="url(#terminal-2926696453-line-39)">  --extra, -e EXTRA     a changelog extra variable </text><text class="terminal-2926696453-r2" x="622.2" y="971.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-39)">(</text><text class="terminal-2926696453-r1" x="634.4" y="971.6" textLength="146.4" clip-path="url(#terminal-2926696453-line-39)">in the form </text><text class="terminal-2926696453-r4" x="780.8" y="971.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-39)">'</text><text class="terminal-2926696453-r4" x="793" y="971.6" textLength="36.6" clip-path="url(#terminal-2926696453-line-39)">key</text><text class="terminal-2926696453-r4" x="829.6" y="971.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-39)">=</text><text class="terminal-2926696453-r4" x="841.8" y="971.6" textLength="61" clip-path="url(#terminal-2926696453-line-39)">value</text><text class="terminal-2926696453-r4" x="902.8" y="971.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-39)">'</text><text class="terminal-2926696453-r2" x="915" y="971.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-39)">)</text><text class="terminal-2926696453-r1" x="976" y="971.6" textLength="12.2" clip-path="url(#terminal-2926696453-line-39)"> +</text><text class="terminal-2926696453-r1" x="0" y="996" textLength="305" clip-path="url(#terminal-2926696453-line-40)">  --tag-format TAG_FORMAT</text><text class="terminal-2926696453-r1" x="976" y="996" textLength="12.2" clip-path="url(#terminal-2926696453-line-40)"> +</text><text class="terminal-2926696453-r1" x="0" y="1020.4" textLength="878.4" clip-path="url(#terminal-2926696453-line-41)">                        The format of the tag, wrap around simple quotes</text><text class="terminal-2926696453-r1" x="976" y="1020.4" textLength="12.2" clip-path="url(#terminal-2926696453-line-41)"> +</text><text class="terminal-2926696453-r1" x="976" y="1044.8" textLength="12.2" clip-path="url(#terminal-2926696453-line-42)"> </text> </g> </g> From 225fd76ecbd80fd81471886047d3b60b9710bbf9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 15:03:39 +0000 Subject: [PATCH 469/598] =?UTF-8?q?bump:=20version=204.7.2=20=E2=86=92=204?= =?UTF-8?q?.8.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7497946571..ff222cac1a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.7.2 # automatically updated by Commitizen + rev: v4.8.0 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index de772c6a75..d11930cce2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.8.0 (2025-05-20) + +### Feat + +- **cli**: add --tag-format argument to changelog command + ## v4.7.2 (2025-05-18) ### Refactor diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 98c926d162..ea674c5c54 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.7.2" +__version__ = "4.8.0" diff --git a/pyproject.toml b/pyproject.toml index 8d9214615a..4e41a885fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.7.2" +version = "4.8.0" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.7.2" +version = "4.8.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 10581b3b4399abb2972d932d22d9b4b55b433a3b Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 16 May 2025 02:18:37 +0800 Subject: [PATCH 470/598] test(changelog): code cleanup and better type --- tests/test_changelog.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 067adb4a91..b1c7c802e1 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -556,8 +556,8 @@ @pytest.fixture -def gitcommits() -> list: - commits = [ +def gitcommits() -> list[git.GitCommit]: + return [ git.GitCommit( commit["rev"], commit["title"], @@ -568,13 +568,11 @@ def gitcommits() -> list: ) for commit in COMMITS_DATA ] - return commits @pytest.fixture -def tags() -> list: - tags = [git.GitTag(*tag) for tag in TAGS] - return tags +def tags() -> list[git.GitTag]: + return [git.GitTag(*tag) for tag in TAGS] @pytest.fixture From d0c26742ef05f3976bf3e42486857612b17e83d4 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 14 May 2025 18:05:55 +0800 Subject: [PATCH 471/598] refactor(customize): improve code readability --- commitizen/cz/customize/customize.py | 54 ++++++++-------------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index afa35e92de..53ada4b2c0 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -33,35 +33,17 @@ def __init__(self, config: BaseConfig): raise MissingCzCustomizeConfigError() self.custom_settings = self.config.settings["customize"] - custom_bump_pattern = self.custom_settings.get("bump_pattern") - if custom_bump_pattern: - self.bump_pattern = custom_bump_pattern - - custom_bump_map = self.custom_settings.get("bump_map") - if custom_bump_map: - self.bump_map = custom_bump_map - - custom_bump_map_major_version_zero = self.custom_settings.get( - "bump_map_major_version_zero" - ) - if custom_bump_map_major_version_zero: - self.bump_map_major_version_zero = custom_bump_map_major_version_zero - - custom_change_type_order = self.custom_settings.get("change_type_order") - if custom_change_type_order: - self.change_type_order = custom_change_type_order - - commit_parser = self.custom_settings.get("commit_parser") - if commit_parser: - self.commit_parser = commit_parser - - changelog_pattern = self.custom_settings.get("changelog_pattern") - if changelog_pattern: - self.changelog_pattern = changelog_pattern - - change_type_map = self.custom_settings.get("change_type_map") - if change_type_map: - self.change_type_map = change_type_map + for attr_name in [ + "bump_pattern", + "bump_map", + "bump_map_major_version_zero", + "change_type_order", + "commit_parser", + "changelog_pattern", + "change_type_map", + ]: + if value := self.custom_settings.get(attr_name): + setattr(self, attr_name, value) def questions(self) -> Questions: return self.custom_settings.get("questions", [{}]) @@ -70,8 +52,7 @@ def message(self, answers: dict) -> str: message_template = Template(self.custom_settings.get("message_template", "")) if getattr(Template, "substitute", None): return message_template.substitute(**answers) # type: ignore - else: - return message_template.render(**answers) + return message_template.render(**answers) def example(self) -> str: return self.custom_settings.get("example") or "" @@ -83,12 +64,7 @@ def schema(self) -> str: return self.custom_settings.get("schema") or "" def info(self) -> str: - info_path = self.custom_settings.get("info_path") - info = self.custom_settings.get("info") - if info_path: + if info_path := self.custom_settings.get("info_path"): with open(info_path, encoding=self.config.settings["encoding"]) as f: - content = f.read() - return content - elif info: - return info - return "" + return f.read() + return self.custom_settings.get("info") or "" From ba571827e4bba1b5ac5fbdaf38302e53cd8efe75 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 03:12:05 +0000 Subject: [PATCH 472/598] =?UTF-8?q?bump:=20version=204.8.0=20=E2=86=92=204?= =?UTF-8?q?.8.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ff222cac1a..f1aef91193 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.8.0 # automatically updated by Commitizen + rev: v4.8.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index d11930cce2..9904ae3bbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v4.8.1 (2025-05-22) + +### Refactor + +- **customize**: improve code readability + ## v4.8.0 (2025-05-20) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index ea674c5c54..1969a66ecd 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.8.0" +__version__ = "4.8.1" diff --git a/pyproject.toml b/pyproject.toml index 4e41a885fa..853d9ccaf8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.8.0" +version = "4.8.1" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.8.0" +version = "4.8.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", From fe72043eeec8ffdd34d721ada65c45c622acdac2 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 19:59:18 +0800 Subject: [PATCH 473/598] refactor(check): remove unnecessary variable --- commitizen/commands/check.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index 087db03ea5..a0d06cbc47 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -72,15 +72,11 @@ def __call__(self): raise NoCommitsFoundError(f"No commit found with range: '{self.rev_range}'") pattern = self.cz.schema_pattern() - ill_formatted_commits = [ - commit - for commit in commits - if not self.validate_commit_message(commit.message, pattern) - ] displayed_msgs_content = "\n".join( [ f'commit "{commit.rev}": "{commit.message}"' - for commit in ill_formatted_commits + for commit in commits + if not self.validate_commit_message(commit.message, pattern) ] ) if displayed_msgs_content: From 7fd6ce33d59f90f0a85826b54224aa063ddfdc70 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 20:05:39 +0800 Subject: [PATCH 474/598] refactor(check): simplify code --- commitizen/commands/check.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index a0d06cbc47..1e3b8464e1 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -88,24 +88,21 @@ def __call__(self): ) out.success("Commit validation: successful!") + def _get_commit_message(self) -> str | None: + if self.commit_msg_file is None: + # Get commit message from command line (--message) + return self.commit_msg + + with open(self.commit_msg_file, encoding=self.encoding) as commit_file: + # Get commit message from file (--commit-msg-file) + return commit_file.read() + def _get_commits(self): - msg = None - # 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, encoding=self.encoding) as commit_file: - msg = commit_file.read() - # Get commit message from command line (--message) - elif self.commit_msg is not None: - msg = self.commit_msg - if msg is not None: - msg = self._filter_comments(msg) - return [git.GitCommit(rev="", title="", body=msg)] + if (msg := self._get_commit_message()) is not None: + return [git.GitCommit(rev="", title="", body=self._filter_comments(msg))] # Get commit messages from git log (--rev-range) - if self.rev_range: - return git.get_commits(end=self.rev_range) - return git.get_commits() + return git.get_commits(end=self.rev_range or "HEAD") @staticmethod def _filter_comments(msg: str) -> str: From a8094aebad266040ef07f118a96c88a93f4aecf8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 03:16:18 +0000 Subject: [PATCH 475/598] =?UTF-8?q?bump:=20version=204.8.1=20=E2=86=92=204?= =?UTF-8?q?.8.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 7 +++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f1aef91193..4e108eb9b9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.8.1 # automatically updated by Commitizen + rev: v4.8.2 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 9904ae3bbf..5b737a851a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v4.8.2 (2025-05-22) + +### Refactor + +- **check**: simplify code +- **check**: remove unnecessary variable + ## v4.8.1 (2025-05-22) ### Refactor diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 1969a66ecd..8e288a597c 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.8.1" +__version__ = "4.8.2" diff --git a/pyproject.toml b/pyproject.toml index 853d9ccaf8..b306e5e78c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.8.1" +version = "4.8.2" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.8.1" +version = "4.8.2" tag_format = "v$version" version_files = [ "pyproject.toml:version", From 9420b44c86a9271d0d9f107360501a058533f9e2 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 23 May 2025 16:55:07 +0800 Subject: [PATCH 476/598] docs(label_pr.yml): add labels based on new PR title --- .github/workflows/label_pr.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/label_pr.yml b/.github/workflows/label_pr.yml index b409c8b757..176d7cc794 100644 --- a/.github/workflows/label_pr.yml +++ b/.github/workflows/label_pr.yml @@ -17,3 +17,31 @@ jobs: - uses: actions/labeler@v5 with: configuration-path: .github/labeler.yml + - name: Label based on PR title + uses: actions/github-script@v7 + with: + script: | + const title = context.payload.pull_request.title.toLowerCase(); + const labels = []; + + if (title.includes("fix") || title.includes("bug")) { + labels.push("type: bug"); + } + if (title.includes("feat")) { + labels.push("type: feature"); + } + if (title.includes("doc")) { + labels.push("type: documentation"); + } + if (title.includes("refactor")) { + labels.push("type: refactor"); + } + + if (labels.length > 0) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + labels + }); + } From 5aa58c6638f7e2237f596ec373e9001e21ba1a8c Mon Sep 17 00:00:00 2001 From: Adrian Carolli <adrian.caarolli@gmail.com> Date: Mon, 26 May 2025 19:45:10 -0400 Subject: [PATCH 477/598] docs: add installation and usage guide for cz-ai plugin leveraging GPT-4o --- docs/third-party-commitizen.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/third-party-commitizen.md b/docs/third-party-commitizen.md index 1c8ef8a183..b6d598985f 100644 --- a/docs/third-party-commitizen.md +++ b/docs/third-party-commitizen.md @@ -3,6 +3,22 @@ In addition to the native templates, some alternative commit format templates are available as PyPI packages (installable with `pip`). +### [cz-ai](https://github.com/watadarkstar/cz_ai) + +A Commitizen plugin that leverages OpenAI's GPT-4o to automatically generate clear, concise, and conventional commit messages based on your staged git changes. + +#### Installation + +```sh +pip install cz-ai +``` + +#### Usage + +```sh +cz --name cz_ai commit +``` + ### [Conventional JIRA](https://pypi.org/project/conventional-JIRA/) Just like _conventional commit_ format, but the scope has been restricted to a From e69e0a1babe6b9dd64f7c3cabb2246bd299379ab Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 11 May 2025 17:04:41 +0800 Subject: [PATCH 478/598] docs: fix typos and grammar mistakes --- docs/commands/changelog.md | 10 +++++----- docs/commands/check.md | 22 ++++++++++----------- docs/commands/commit.md | 2 +- docs/config.md | 6 +++--- docs/contributing.md | 32 +++++++++++++++---------------- docs/customization.md | 26 ++++++++++++------------- docs/faq.md | 8 ++++---- docs/third-party-commitizen.md | 2 +- docs/tutorials/auto_check.md | 18 ++++++++--------- docs/tutorials/dev_releases.md | 11 +++-------- docs/tutorials/github_actions.md | 4 ++-- docs/tutorials/gitlab_ci.md | 8 ++++---- docs/tutorials/tag_format.md | 14 +++++++------- docs/tutorials/writing_commits.md | 16 ++++++++-------- 14 files changed, 87 insertions(+), 92 deletions(-) diff --git a/docs/commands/changelog.md b/docs/commands/changelog.md index cbf22b15a7..aee1a0e075 100644 --- a/docs/commands/changelog.md +++ b/docs/commands/changelog.md @@ -56,7 +56,7 @@ These are the variables used by the changelog generator. It will create a full block like above per version found in the tags. And it will create a list of the commits found. The `change_type` and the `scope` are optional, they don't need to be provided, -but if your regex does they will be rendered. +but if your regex does, they will be rendered. The format followed by the changelog is the one from [keep a changelog][keepachangelog] and the following variables are expected: @@ -108,7 +108,7 @@ cz bump --changelog This value can be updated in the `toml` file with the key `changelog_file` under `tools.commitizen` -Specify the name of the output file, remember that changelog only works with markdown. +Specify the name of the output file, remember that changelog only works with Markdown. ```bash cz changelog --file-name="CHANGES.md" @@ -120,7 +120,7 @@ This flag can be set in the `toml` file with the key `changelog_incremental` und Benefits: -- Build from latest version found in changelog, this is useful if you have a different changelog and want to use commitizen +- Build from the latest version found in changelog, this is useful if you have a different changelog and want to use commitizen - Update unreleased area - Allows users to manually touch the changelog without being rewritten. @@ -185,8 +185,8 @@ See [the template customization section](../customization.md#customizing-the-cha Supported hook methods: -- per parsed message: useful to add links -- end of changelog generation: useful to send slack or chat message, or notify another department +- Per parsed message: Useful to add links +- End of changelog generation: Useful to send Slack or chat messages, or notify another department Read more about hooks in the [customization page][customization] diff --git a/docs/commands/check.md b/docs/commands/check.md index e45ecd86c8..33e41e04f8 100644 --- a/docs/commands/check.md +++ b/docs/commands/check.md @@ -2,9 +2,9 @@ ## About -This feature checks whether the commit message follows the given committing rules. And comment in git message will be ignored. +This feature checks whether the commit message follows the given committing rules. Comments in git messages will be ignored. -If you want to setup an automatic check before every git commit, please refer to +If you want to set up an automatic check before every git commit, please refer to [Automatically check message before commit](../tutorials/auto_check.md). ## Usage @@ -27,7 +27,7 @@ $ cz check --rev-range REV_RANGE For example, if you'd like to check all commits on a branch, you can use `--rev-range master..HEAD`. Or, if you'd like to check all commits starting from when you first implemented commit message linting, you can use `--rev-range <first_commit_sha>..HEAD`. -For more info on how git commit ranges work, you can check the [git documentation](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#_commit_ranges). +For more information on how git commit ranges work, you can check the [git documentation](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#_commit_ranges). ### Commit Message @@ -47,7 +47,7 @@ In this option, MESSAGE is the commit message to be checked. $ echo MESSAGE | cz check ``` -In this option, MESSAGE is piped to cz check and would be checked. +In this option, MESSAGE is piped to cz check and will be checked. ### Commit Message File @@ -55,8 +55,8 @@ In this option, MESSAGE is piped to cz check and would be checked. $ cz check --commit-msg-file COMMIT_MSG_FILE ``` -In this option, COMMIT_MSG_FILE is the path of the temporal file that contains the commit message. -This argument can be useful when cooperating with git hook, please check [Automatically check message before commit](../tutorials/auto_check.md) for more information about how to use this argument with git hook. +In this option, COMMIT_MSG_FILE is the path of the temporary file that contains the commit message. +This argument can be useful when cooperating with git hooks. Please check [Automatically check message before commit](../tutorials/auto_check.md) for more information about how to use this argument with git hooks. ### Allow Abort @@ -69,8 +69,8 @@ permit them. Since `git commit` accepts an `--allow-empty-message` flag (primari ### Allowed Prefixes -If the commit message starts by some specific prefixes, `cz check` returns `True` without checkign the regex. -By default, the the following prefixes are allowed: `Merge`, `Revert`, `Pull request`, `fixup!` and `squash!`. +If the commit message starts with some specific prefixes, `cz check` returns `True` without checking the regex. +By default, the following prefixes are allowed: `Merge`, `Revert`, `Pull request`, `fixup!` and `squash!`. ```bash cz check --message MESSAGE --allowed-prefixes 'Merge' 'Revert' 'Custom Prefix' @@ -78,10 +78,10 @@ cz check --message MESSAGE --allowed-prefixes 'Merge' 'Revert' 'Custom Prefix' ### Commit message length limit -The argument `-l` (or `--message-length-limmit`) followed by a positive number, can limit the length of commit messages. +The argument `-l` (or `--message-length-limit`) followed by a positive number can limit the length of commit messages. For example, `cz check --message MESSAGE -l 3` would fail the check, since `MESSAGE` is more than 3 characters long. By default, the limit is set to 0, which means no limit on the length. -**Note that the limit applies only to the first line of the message.*** +**Note that the limit applies only to the first line of the message.** Specifically, for `ConventionalCommitsCz` the length only counts from the type of change to the subject, -while the body, and the footer are not counted. +while the body and the footer are not counted. diff --git a/docs/commands/commit.md b/docs/commands/commit.md index 7760a2b88e..ea033cc411 100644 --- a/docs/commands/commit.md +++ b/docs/commands/commit.md @@ -45,7 +45,7 @@ a new commit message to be prompted. The argument `-l` (or `--message-length-limit`) followed by a positive number can limit the length of commit messages. An exception would be raised when the message length exceeds the limit. For example, `cz commit -l 72` will limit the length of commit messages to 72 characters. -By default the limit is set to 0, which means no limit on the length. +By default, the limit is set to 0, which means no limit on the length. **Note that the limit applies only to the first line of the message.** Specifically, for `ConventionalCommitsCz` the length only counts from the type of change to the subject, diff --git a/docs/config.md b/docs/config.md index a522312743..b6dd794fb3 100644 --- a/docs/config.md +++ b/docs/config.md @@ -341,7 +341,7 @@ commitizen: ## Version providers Commitizen can read and write version from different sources. -By default, it use the `commitizen` one which is using the `version` field from the commitizen settings. +By default, it uses the `commitizen` one which is using the `version` field from the commitizen settings. But you can use any `commitizen.provider` entrypoint as value for `version_provider`. Commitizen provides some version providers for some well known formats: @@ -369,9 +369,9 @@ version_provider = "pep621" ### Custom version provider -You can add you own version provider by extending `VersionProvider` and exposing it on the `commitizen.provider` entrypoint. +You can add your own version provider by extending `VersionProvider` and exposing it on the `commitizen.provider` entrypoint. -Here a quick example of a `my-provider` provider reading and writing version in a `VERSION` file. +Here is a quick example of a `my-provider` provider reading and writing version in a `VERSION` file. ```python title="my_provider.py" from pathlib import Path diff --git a/docs/contributing.md b/docs/contributing.md index 0da1707da6..1192e57c0a 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -8,25 +8,25 @@ If you're a first-time contributor, you can check the issues with [good first is ## Install before contributing -1. Install [poetry](https://python-poetry.org/) `>=2.0.0`, installation [pages](https://python-poetry.org/docs/#installing-with-the-official-installer) -2. Install [gpg](https://gnupg.org), installation [pages](https://gnupg.org/documentation/manuals/gnupg/Installation.html#Installation). For Mac users, you could try [homebrew](https://brew.sh/). +1. Install [poetry](https://python-poetry.org/) `>=2.0.0`. See installation [pages](https://python-poetry.org/docs/#installing-with-the-official-installer). +2. Install [gpg](https://gnupg.org). See installation [pages](https://gnupg.org/documentation/manuals/gnupg/Installation.html#Installation). For Mac users, you can use [homebrew](https://brew.sh/). ## Before making a pull request 1. Fork [the repository](https://github.com/commitizen-tools/commitizen). -2. Clone the repository from your GitHub. -3. Setup development environment through [poetry](https://python-poetry.org/) (`poetry install`). -4. Setup [pre-commit](https://pre-commit.com/) hook (`poetry setup-pre-commit`) -5. Check out a new branch and add your modification. -6. Add test cases for all your changes. +1. Clone the repository from your GitHub. +1. Set up development environment through [poetry](https://python-poetry.org/) (`poetry install`). +1. Set up [pre-commit](https://pre-commit.com/) hook (`poetry setup-pre-commit`). +1. Checkout a new branch and add your modifications. +1. Add test cases for all your changes. (We use [CodeCov](https://codecov.io/) to ensure our test coverage does not drop.) -7. Use [commitizen](https://github.com/commitizen-tools/commitizen) to do git commit. We follow [conventional commits](https://www.conventionalcommits.org/). -8. Run `poetry all` to ensure you follow the coding style and the tests pass. -9. Optionally, update the `./docs/README.md` or `docs/images/cli_help` (through running `poetry doc:screenshots`). -9. **Do not** update the `CHANGELOG.md`, it will be automatically created after merging to `master`. -10. **Do not** update the versions in the project, they will be automatically updated. -10. If your changes are about documentation. Run `poetry doc` to serve documentation locally and check whether there is any warning or error. -11. Send a [pull request](https://github.com/commitizen-tools/commitizen/pulls) 🙏 +1. Use [commitizen](https://github.com/commitizen-tools/commitizen) to do git commit. We follow [conventional commits](https://www.conventionalcommits.org/). +1. Run `poetry all` to ensure you follow the coding style and the tests pass. +1. Optionally, update the `./docs/README.md` or `docs/images/cli_help` (through running `poetry doc:screenshots`). +1. **Do not** update the `CHANGELOG.md`; it will be automatically created after merging to `master`. +1. **Do not** update the versions in the project; they will be automatically updated. +1. If your changes are about documentation, run `poetry doc` to serve documentation locally and check whether there are any warnings or errors. +1. Send a [pull request](https://github.com/commitizen-tools/commitizen/pulls) 🙏 ## Use of GitHub Labels @@ -45,8 +45,8 @@ If you're a first-time contributor, you can check the issues with [good first is * pr-status: wait-for-modification * pr-status: wait-for-response * pr-status: ready-to-merge -* needs: test-case *(pr only)* -* needs: documentation *(pr only)* +* needs: test-case *(PR only)* +* needs: documentation *(PR only)* * type: feature * type: bug * type: documentation diff --git a/docs/customization.md b/docs/customization.md index 31749d1c83..cef03469e0 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -170,7 +170,7 @@ commitizen: | Parameter | Type | Default | Description | | ----------- | ------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `type` | `str` | `None` | The type of questions. Valid types: `list`, `select`, `input` and etc. The `select` type provides an interactive searchable list interface. [See More][different-question-types] | +| `type` | `str` | `None` | The type of questions. Valid types: `list`, `select`, `input`, etc. The `select` type provides an interactive searchable list interface. [See More][different-question-types] | | `name` | `str` | `None` | The key for the value answered by user. It's used in `message_template` | | `message` | `str` | `None` | Detail description for the question. | | `choices` | `list` | `None` | (OPTIONAL) The choices when `type = list` or `type = select`. Either use a list of values or a list of dictionaries with `name` and `value` keys. Keyboard shortcuts can be defined via `key`. See examples above. | @@ -192,10 +192,10 @@ To specify keyboard shortcuts for your custom choices, provide the shortcut usin The basic steps are: -1. Inheriting from `BaseCommitizen` +1. Inheriting from `BaseCommitizen`. 2. Give a name to your rules. -3. Create a python package using `setup.py`, `poetry`, etc -4. Expose the class as a `commitizen.plugin` entrypoint +3. Create a python package using `setup.py`, `poetry`, etc. +4. Expose the class as a `commitizen.plugin` entrypoint. Check an [example][convcomms] on how to configure `BaseCommitizen`. @@ -322,9 +322,9 @@ You can customize it of course, and this are the variables you need to add to yo | `commit_parser` | `str` | NO | Regex which should provide the variables explained in the [changelog description][changelog-des] | | `changelog_pattern` | `str` | NO | Regex to validate the commits, this is useful to skip commits that don't meet your ruling standards like a Merge. Usually the same as bump_pattern | | `change_type_map` | `dict` | NO | Convert the title of the change type that will appear in the changelog, if a value is not found, the original will be provided | -| `changelog_message_builder_hook` | `method: (dict, git.GitCommit) -> dict | list | None` | NO | Customize with extra information your message output, like adding links, this function is executed per parsed commit. Each GitCommit contains the following attrs: `rev`, `title`, `body`, `author`, `author_email`. Returning a falsy value ignore the commit. | +| `changelog_message_builder_hook` | `method: (dict, git.GitCommit) -> dict | list | None` | NO | Customize with extra information your message output, like adding links, this function is executed per parsed commit. Each GitCommit contains the following attrs: `rev`, `title`, `body`, `author`, `author_email`. Returning a falsy value ignore the commit. | | `changelog_hook` | `method: (full_changelog: str, partial_changelog: Optional[str]) -> str` | NO | Receives the whole and partial (if used incremental) changelog. Useful to send slack messages or notify a compliance department. Must return the full_changelog | -| `changelog_release_hook` | `method: (release: dict, tag: git.GitTag) -> dict` | NO | Receives each generated changelog release and its associated tag. Useful to enrich a releases before they are rendered. Must return the update release +| `changelog_release_hook` | `method: (release: dict, tag: git.GitTag) -> dict` | NO | Receives each generated changelog release and its associated tag. Useful to enrich releases before they are rendered. Must return the update release ```python from commitizen.cz.base import BaseCommitizen @@ -395,7 +395,7 @@ class NoSubjectProvidedException(CzException): Commitizen migrated to a new plugin format relying on `importlib.metadata.EntryPoint`. Migration should be straight-forward for legacy plugins: -- Remove the `discover_this` line from you plugin module +- Remove the `discover_this` line from your plugin module - Expose the plugin class under as a `commitizen.plugin` entrypoint. The name of the plugin is now determined by the name of the entrypoint. @@ -455,12 +455,12 @@ By default, the template used is the `CHANGELOG.md.j2` file from the commitizen ### Providing a template with your customization class -There is 3 parameters available to change the template rendering from your custom `BaseCommitizen`. +There are 3 parameters available to change the template rendering from your custom `BaseCommitizen`. | Parameter | Type | Default | Description | | ----------------- | ------ | ------- | ----------------------------------------------------------------------------------------------------- | -| `template` | `str` | `None` | Provide your own template name (default to `CHANGELOG.md.j2`) | -| `template_loader` | `str` | `None` | Override the default template loader (so you can provide template from you customization class) | +| `template` | `str` | `None` | Provide your own template name (default to `CHANGELOG.md.j2`) | +| `template_loader` | `str` | `None` | Override the default template loader (so you can provide template from your customization class) | | `template_extras` | `dict` | `None` | Provide some extra template parameters | Let's see an example. @@ -484,14 +484,14 @@ This snippet will: ### Providing a template from the current working directory -Users can provides their own template from their current working directory (your project root) by: +Users can provide their own template from their current working directory (your project root) by: - providing a template with the same name (`CHANGELOG.md.j2` unless overridden by your custom class) - setting your template path as `template` configuration - giving your template path as `--template` parameter to `bump` and `changelog` commands !!! Note - The path is relative to the current working directory, aka. your project root most of the time. + The path is relative to the current working directory, aka your project root most of the time. ### Template variables @@ -524,7 +524,7 @@ When using another template (either provided by a plugin or by yourself), you ca by: - defining them in your configuration with the [`extras` settings][extras-config] -- providing them on the commandline with the `--extra/-e` parameter to `bump` and `changelog` commands +- providing them on the command line with the `--extra/-e` parameter to `bump` and `changelog` commands [template-config]: config.md#template [extras-config]: config.md#extras diff --git a/docs/faq.md b/docs/faq.md index 29d9f40512..0302efd267 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -52,7 +52,7 @@ It is not affiliated. Both are used for similar purposes, parsing commits, generating changelog and version we presume. This one is written in python to make integration easier for python projects and the other serves the JS packages. -They differ a bit in design, not sure if cz-js does any of this, but these are some of the stuff you can do with this repo (python's commitizen): +They differ a bit in design, not sure if cz-js does any of this, but these are some things you can do with this repo (python's commitizen): - create custom rules, version bumps and changelog generation, by default we use the popular conventional commits (I think cz-js allows this). - single package, install one thing and it will work (cz-js is a monorepo, but you have to install different dependencies AFAIK) @@ -83,14 +83,14 @@ More discussion can be found in issue [#318](https://github.com/commitizen-tools ## Why does commitizen not support CalVer? `commitizen` could support CalVer alongside SemVer, but in practice implementing CalVer -creates numerous edge cases that are difficult to maintain ([#385]) and more generally +creates numerous edge cases that are difficult to maintain ([#385]) and more generally, mixing the two version schemes may not be a good idea. If CalVer or other custom versioning scheme is needed, `commitizen` could still be used to standardize commits and create changelogs, but a separate package should be used for version increments. Mixing CalVer and SemVer is generally not recommended because each versioning scheme -serves a different purposes. Diverging from either specification can be confusing to -users and cause errors with third party tools that don't expect the non-standard format. +serves a different purpose. Diverging from either specification can be confusing to +users and cause errors with third-party tools that don't expect the non-standard format. In the future, `commitizen` may support some implementation of CalVer, but at the time of writing, there are no plans to implement the feature ([#173]). diff --git a/docs/third-party-commitizen.md b/docs/third-party-commitizen.md index b6d598985f..e9eb822ed3 100644 --- a/docs/third-party-commitizen.md +++ b/docs/third-party-commitizen.md @@ -117,7 +117,7 @@ See the [README][1] for instructions on configuration ## Third-Party Commitizen Providers -Commitizen can read and write version from different sources. In addition to the native providers, some alternative version sources are available as PyPI packages (installable with `pip`). +Commitizen can read and write version from different sources. In addition to the native providers, some alternative version sources are available as PyPI packages (installable with `pip`). ### [commitizen-deno-provider](https://pypi.org/project/commitizen-deno-provider/) diff --git a/docs/tutorials/auto_check.md b/docs/tutorials/auto_check.md index 2fce57f9bd..d143528767 100644 --- a/docs/tutorials/auto_check.md +++ b/docs/tutorials/auto_check.md @@ -6,9 +6,9 @@ To automatically check a commit message prior to committing, you can use a [git ## How to -There are two common methods for installing the hook: +There are two common methods for installing the hooks: -### Method 1: Add git hook through [pre-commit](https://pre-commit.com/) +### Method 1: Add a git hook through [pre-commit](https://pre-commit.com/) - Step 1: Install [pre-commit](https://pre-commit.com/) @@ -16,7 +16,7 @@ There are two common methods for installing the hook: python -m pip install pre-commit ``` -- Step 2: Create `.pre-commit-config.yaml` at your root directory with the following content +- Step 2: Create `.pre-commit-config.yaml` in your root directory with the following content ```yaml --- @@ -28,19 +28,19 @@ repos: stages: [commit-msg] ``` -- Step 3: Install the configuration into git hook through `pre-commit` +- Step 3: Install the configuration into the git hook through `pre-commit` ```bash pre-commit install --hook-type commit-msg ``` -### Method 2: Manually add git hook +### Method 2: Manually add a git hook -The command might be included inside of a Git hook (inside of `.git/hooks/` at the root of the project). +The command might be included inside a Git hook (inside `.git/hooks/` at the root of the project). The selected hook might be the file called commit-msg. -This example shows how to use the check command inside of commit-msg. +This example shows how to use the check command inside commit-msg. At the root of the project: @@ -62,7 +62,7 @@ Where `$1` is the name of the temporary file that contains the current commit me The `--commit-msg-file` flag is required, not optional. -Each time you create a commit, automatically, this hook will analyze it. -If the commit message is invalid, it'll be rejected. +Each time you create a commit, this hook will automatically analyze it. +If the commit message is invalid, it will be rejected. The commit should follow the given committing rules; otherwise, it won't be accepted. diff --git a/docs/tutorials/dev_releases.md b/docs/tutorials/dev_releases.md index 8142334754..e2b29fb191 100644 --- a/docs/tutorials/dev_releases.md +++ b/docs/tutorials/dev_releases.md @@ -5,9 +5,7 @@ To make use of a `.dev` suffix, as per [PEP440](https://peps.python.org/pep-0440/#developmental-releases). -If more than one active branch attempts to create a tag, relative to the main -branch, there is the possibility that each will attempt to create the _same_ -tag, resulting in a collision. +If multiple active branches attempt to create a tag relative to the main branch, there is a possibility that they will attempt to create the _same_ tag, resulting in a collision. Developmental releases aim to avoid this by including a `.dev` segment which includes a non-negative integer unique to that workflow: @@ -19,9 +17,7 @@ X.Y.devN !!! note As noted in [PEP440](https://peps.python.org/pep-0440/#developmental-releases), - although developmental releases are useful in avoiding the situation - described above, depending on the value passed as the developmental - release, they can be _"difficult to parse for human readers"_. + while developmental releases help avoid the situation described above, they can be _"difficult to parse for human readers"_ depending on the value passed as the developmental release. ## How to @@ -64,8 +60,7 @@ Equally, as the developmental release needs only a non-negative integer, it is possible to use the Unix time (i.e. the number of seconds since 1st January 1970 UTC). -This would create the possibility of a collision if two builds occur at -precisely the same second but this may be sufficient for many cases: +This approach could potentially create a collision if two builds occur at precisely the same second, but it may be sufficient for many use cases: ```sh --devrelease $(date +%s) diff --git a/docs/tutorials/github_actions.md b/docs/tutorials/github_actions.md index 7a98abe2be..bcb3fda22c 100644 --- a/docs/tutorials/github_actions.md +++ b/docs/tutorials/github_actions.md @@ -51,7 +51,7 @@ where to output the content of the changelog for the newly created version. And then add a step using a github action to create the release: `softprops/action-gh-release` The commitizen action creates an env variable called `REVISION`, containing the -newely created version. +newly created version. ```yaml - name: Create bump and changelog @@ -119,7 +119,7 @@ jobs: ./scripts/publish ``` -Notice that we are using poetry, and we are calling a bash script in `./scripts/publish`. You should configure the action, and the publish with your tools (twine, poetry, etc.). Check [commitizen example](https://github.com/commitizen-tools/commitizen/blob/master/scripts/publish) +Notice that we are using poetry, and we are calling a bash script in `./scripts/publish`. You should configure the action, and publish with your tools (twine, poetry, etc.). Check [commitizen example](https://github.com/commitizen-tools/commitizen/blob/master/scripts/publish) You can also use [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) to publish your package. Push the changes and that's it. diff --git a/docs/tutorials/gitlab_ci.md b/docs/tutorials/gitlab_ci.md index 85abb3fe6d..85b6a615c3 100644 --- a/docs/tutorials/gitlab_ci.md +++ b/docs/tutorials/gitlab_ci.md @@ -38,7 +38,7 @@ The latest step is to create a `deploy key.` To do this, we should create it und If you have more projects under the same organization, you can reuse the deploy key created before, but you will have to repeat the step where we have created the environment variables (ssh key, email, and username). -tip: If the CI raise some errors, try to unprotected the private key. +Tip: If the CI raise some errors, try to unprotect the private key. ### Defining GitLab CI Pipeline @@ -105,9 +105,9 @@ auto-bump: - variables ``` -So, every time that a developer push to any branch, the `test` job is executed. If the branch is `master` and the test jobs success, the `auto-bump` takes place. -To be able to push using the Gitlab runner, we have to set the ssh key, configure git, and finally execute the auto bump. +So, every time that a developer pushes to any branch, the `test` job is executed. If the branch is `master` and the test jobs succeed, the `auto-bump` takes place. +To be able to push using the GitLab runner, we have to set the SSH key, configure git, and finally execute the auto bump. -After merging the new changed into master, we have the final result: +After merging the new changes into master, we have the final result: ![gitlab final ci result](../images/gitlab_ci/gitlab_final_ci_result.png) diff --git a/docs/tutorials/tag_format.md b/docs/tutorials/tag_format.md index 59c42bea13..8408b4c801 100644 --- a/docs/tutorials/tag_format.md +++ b/docs/tutorials/tag_format.md @@ -10,7 +10,7 @@ tag_format: $version version_scheme: pep440 ``` -As this is the default value so you don't have to specify it. +As this is the default value, you don't have to specify it. This setting means that: @@ -52,7 +52,7 @@ You will obviously want to keep all those features working as expected. Commitizen can deal with it as long as you provide the legacy tag format in the configuration. -Using the previous example, let say you want to move from `v${version}` to `component-${version}`. +Using the previous example, let's say you want to move from `v${version}` to `component-${version}`. Then `component-${version}` will be the new tag format and `v${version}` the legacy one. ```yaml @@ -62,14 +62,14 @@ legacy_tag_formats: - v${version} ``` -This way, you won't loose your version history, you'll still be able to generate you changelog properly -and on the next version bump, your last version in the form `v${version}` will be properly recognizef if you use the `scm` version provider. +This way, you won't lose your version history, you'll still be able to generate your changelog properly, +and on the next version bump, your last version in the form `v${version}` will be properly recognized if you use the `scm` version provider. Your new tag will be in the form `component-${version}`. ## Known tags to ignore -Now let's say you have some known tags you want to ignore, either because they are not versions, either because they are not versions of the component you are dealing with. -As a consequence, you don't want them to trigger a warning because Commitizen detected an unknown tag format: +Now let's say you have some known tags you want to ignore, either because they are not versions, or because they are not versions of the component you are dealing with. +As a consequence, you don't want them to trigger a warning because Commitizen detected an unknown tag format. Then you can tell Commitizen about it using the [`ignored_tag_formats`](../config.md#ignored_tag_formats) setting: @@ -93,7 +93,7 @@ This will ignore: It will match any string from any length. This allows to exclude by prefix, whether it is followed by a version or not. !!! tip - If you don't want to be warned when Commitizen detect an unknown tag, you can by setting: + If you don't want to be warned when Commitizen detects an unknown tag, you can do so by setting: ``` [tool.commitizen] ignored_tag_formats = ["*"] diff --git a/docs/tutorials/writing_commits.md b/docs/tutorials/writing_commits.md index 9ba151cc37..d1b2c6645d 100644 --- a/docs/tutorials/writing_commits.md +++ b/docs/tutorials/writing_commits.md @@ -1,21 +1,21 @@ For this project to work well in your pipeline, a commit convention must be followed. -By default commitizen uses the known [conventional commits][conventional_commits], but -you can create your own following the docs information over at +By default, commitizen uses the known [conventional commits][conventional_commits], but +you can create your own following the documentation information over at [customization][customization]. ## Conventional commits If you are using [conventional commits][conventional_commits], the most important thing to know is that you must begin your commits with at least one of these tags: -`fix`, `feat`. And if you introduce a breaking change, then, you must +`fix`, `feat`. And if you introduce a breaking change, then you must add to your commit body the following `BREAKING CHANGE`. -Using these 3 keywords will allow the proper identification of the semantic version. +Using these three keywords will allow the proper identification of the semantic version. Of course, there are other keywords, but I'll leave it to the reader to explore them. ## Writing commits -Now to the important part, when writing commits, it's important to think about: +Now to the important part: when writing commits, it's important to think about: - Your future self - Your colleagues @@ -23,16 +23,16 @@ 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]. +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). - **Talk imperative**: Follow this rule: `If applied, this commit will <commit message>` -- **Think about the CHANGELOG**: Your commits will probably end up in the changelog +- **Think about the CHANGELOG**: Your commits will probably end up in the changelog, so try writing for it, but also keep in mind that you can skip sending commits to the CHANGELOG by using different keywords (like `build`). -- **Use a commit per new feature**: if you introduce multiple things related to the same +- **Use a commit per new feature**: If you introduce multiple things related to the same commit, squash them. This is useful for auto-generating CHANGELOG. | Do's | Don'ts | From c3d4152fb736969b83be7b555ea44b025ffc6c7e Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 11 May 2025 17:19:32 +0800 Subject: [PATCH 479/598] docs: fix typo issues in cli.py, README.md, and contributing.md --- commitizen/cli.py | 2 +- docs/README.md | 18 +++++++++--------- docs/contributing.md | 30 +++++++++++++++--------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index d08afc6706..f0df2f4242 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -105,7 +105,7 @@ def __call__( "name": ["-nr", "--no-raise"], "type": str, "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/", + "help": "comma separated error codes that won't raise error, e.g: cz -nr 1,2,3 bump. See codes at https://commitizen-tools.github.io/commitizen/exit_codes/", }, ], "subcommands": { diff --git a/docs/README.md b/docs/README.md index 128602dfb3..ee50ad4582 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,16 +18,16 @@ ## About -Commitizen is release management tool designed for teams. +Commitizen is a release management tool designed for teams. Commitizen assumes your team uses a standard way of committing rules and from that foundation, it can bump your project's version, create the changelog, and update files. By default, commitizen uses [conventional commits][conventional_commits], but you -can build your own set of rules, and publish them. +can build your own set of rules and publish them. -Using a standardized set of rules to write commits, makes commits easier to read, and enforces writing +Using a standardized set of rules to write commits makes commits easier to read and enforces writing descriptive commits. ### Features @@ -55,7 +55,7 @@ pipx install commitizen pipx upgrade commitizen ``` -Install commitizen using `pip` with `--user` flag: +Install commitizen using `pip` with the `--user` flag: ```bash pip install --user -U commitizen @@ -63,7 +63,7 @@ pip install --user -U commitizen ### Python project -You can add it to your local project using one of the following. +You can add it to your local project using one of the following methods. With `pip`: @@ -99,7 +99,7 @@ brew install commitizen ## Usage -Most of the time this is the only command you'll run: +Most of the time, this is the only command you'll run: ```sh cz bump @@ -120,7 +120,7 @@ $ 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/ +For more information about the topic, go to https://conventionalcommits.org/ optional arguments: -h, --help show this help message and exit @@ -128,7 +128,7 @@ optional arguments: --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- + comma separated error codes that won't raise error, e.g: cz -nr 1,2,3 bump. See codes at https://commitizen- tools.github.io/commitizen/exit_codes/ commands: @@ -147,7 +147,7 @@ commands: ## Setting up bash completion -When using bash as your shell (limited support for zsh, fish, and tcsh is available), Commitizen can use [argcomplete](https://kislyuk.github.io/argcomplete/) for auto-completion. For this argcomplete needs to be enabled. +When using bash as your shell (limited support for zsh, fish, and tcsh is available), Commitizen can use [argcomplete](https://kislyuk.github.io/argcomplete/) for auto-completion. For this, argcomplete needs to be enabled. argcomplete is installed when you install Commitizen since it's a dependency. diff --git a/docs/contributing.md b/docs/contributing.md index 1192e57c0a..0987771066 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -4,29 +4,29 @@ First of all, thank you for taking the time to contribute! 🎉 When contributing to [commitizen](https://github.com/commitizen-tools/commitizen), please first create an [issue](https://github.com/commitizen-tools/commitizen/issues) to discuss the change you wish to make before making a change. -If you're a first-time contributor, you can check the issues with [good first issue](https://github.com/commitizen-tools/commitizen/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag. +If you're a first-time contributor, you can check the issues with the [good first issue](https://github.com/commitizen-tools/commitizen/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag. ## Install before contributing -1. Install [poetry](https://python-poetry.org/) `>=2.0.0`. See installation [pages](https://python-poetry.org/docs/#installing-with-the-official-installer). -2. Install [gpg](https://gnupg.org). See installation [pages](https://gnupg.org/documentation/manuals/gnupg/Installation.html#Installation). For Mac users, you can use [homebrew](https://brew.sh/). +1. Install [poetry](https://python-poetry.org/) `>=2.0.0`. See the installation [pages](https://python-poetry.org/docs/#installing-with-the-official-installer). +2. Install [gpg](https://gnupg.org). See the installation [pages](https://gnupg.org/documentation/manuals/gnupg/Installation.html#Installation). For Mac users, you can use [homebrew](https://brew.sh/). ## Before making a pull request 1. Fork [the repository](https://github.com/commitizen-tools/commitizen). -1. Clone the repository from your GitHub. -1. Set up development environment through [poetry](https://python-poetry.org/) (`poetry install`). -1. Set up [pre-commit](https://pre-commit.com/) hook (`poetry setup-pre-commit`). -1. Checkout a new branch and add your modifications. -1. Add test cases for all your changes. +2. Clone the repository from your GitHub. +3. Set up the development environment through [poetry](https://python-poetry.org/) (`poetry install`). +4. Set up the [pre-commit](https://pre-commit.com/) hook (`poetry setup-pre-commit`). +5. Checkout a new branch and add your modifications. +6. Add test cases for all your changes. (We use [CodeCov](https://codecov.io/) to ensure our test coverage does not drop.) -1. Use [commitizen](https://github.com/commitizen-tools/commitizen) to do git commit. We follow [conventional commits](https://www.conventionalcommits.org/). -1. Run `poetry all` to ensure you follow the coding style and the tests pass. -1. Optionally, update the `./docs/README.md` or `docs/images/cli_help` (through running `poetry doc:screenshots`). -1. **Do not** update the `CHANGELOG.md`; it will be automatically created after merging to `master`. -1. **Do not** update the versions in the project; they will be automatically updated. -1. If your changes are about documentation, run `poetry doc` to serve documentation locally and check whether there are any warnings or errors. -1. Send a [pull request](https://github.com/commitizen-tools/commitizen/pulls) 🙏 +7. Use [commitizen](https://github.com/commitizen-tools/commitizen) to make git commits. We follow [conventional commits](https://www.conventionalcommits.org/). +8. Run `poetry all` to ensure you follow the coding style and the tests pass. +9. Optionally, update the `./docs/README.md` or `docs/images/cli_help` (by running `poetry doc:screenshots`). +10. **Do not** update the `CHANGELOG.md`; it will be automatically created after merging to `master`. +11. **Do not** update the versions in the project; they will be automatically updated. +12. If your changes are about documentation, run `poetry doc` to serve documentation locally and check whether there are any warnings or errors. +13. Send a [pull request](https://github.com/commitizen-tools/commitizen/pulls) 🙏 ## Use of GitHub Labels From 23bd8936a448c15e36f775496221731fb40df0ad Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 11 May 2025 22:53:40 +0800 Subject: [PATCH 480/598] docs(README.md): sync help section with the latest `cz --help` command output --- docs/README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/README.md b/docs/README.md index ee50ad4582..bcc206642d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -115,21 +115,22 @@ Read more in the section [Getting Started](./getting_started.md). ### Help +<!-- Please manually update the following section after changing `cz --help` command output. --> + ```sh $ cz --help -usage: cz [-h] [--debug] [-n NAME] [-nr NO_RAISE] {init,commit,c,ls,example,info,schema,bump,changelog,ch,check,version} ... +usage: cz [-h] [--config CONFIG] [--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/ +For more information about the topic go to https://conventionalcommits.org/ -optional arguments: +options: -h, --help show this help message and exit - --config the path of configuration file + --config 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 - comma separated error codes that won't raise error, e.g: cz -nr 1,2,3 bump. See codes at https://commitizen- - tools.github.io/commitizen/exit_codes/ + -n, --name NAME use the given commitizen (default: cz_conventional_commits) + -nr, --no-raise NO_RAISE + comma separated error codes that won't raise 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} From 3fcefbd591aa1c14c40730d9deae82f7918f8b2a Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 11 May 2025 23:08:34 +0800 Subject: [PATCH 481/598] docs(README.md): make it easier for readers to understand what Commitizen does --- docs/README.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/README.md b/docs/README.md index bcc206642d..616e7610cc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,17 +18,26 @@ ## About -Commitizen is a release management tool designed for teams. +Commitizen is a powerful release management tool that helps teams maintain consistent and meaningful commit messages while automating version management. -Commitizen assumes your team uses a standard way of committing rules -and from that foundation, it can bump your project's version, create -the changelog, and update files. +### What Commitizen Does -By default, commitizen uses [conventional commits][conventional_commits], but you -can build your own set of rules and publish them. +By enforcing standardized commit conventions (defaulting to [Conventional Commits][conventional_commits]), Commitizen helps teams: -Using a standardized set of rules to write commits makes commits easier to read and enforces writing -descriptive commits. +- Write clear, structured commit messages +- Automatically manage version numbers using semantic versioning +- Generate and maintain changelogs +- Streamline the release process + +### Key Benefits + +With just a simple `cz bump` command, Commitizen handles: + +1. **Version Management**: Automatically bumps version numbers and updates version files based on your commit history +2. **Changelog Generation**: Creates and updates changelogs following the [Keep a changelog][keepchangelog] format +3. **Commit Standardization**: Enforces consistent commit message formats across your team + +This standardization makes your commit history more readable and meaningful, while the automation reduces manual work and potential errors in the release process. ### Features From 889198d5688e78793e4099e7493b030a652bb670 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 11 May 2025 23:38:41 +0800 Subject: [PATCH 482/598] docs(README.md): move Getting Started to README and improve clarity of the section Closes #1405 --- docs/README.md | 137 ++++++++++++++++++++++++++++++++-------- docs/getting_started.md | 119 ---------------------------------- mkdocs.yml | 1 - 3 files changed, 112 insertions(+), 145 deletions(-) delete mode 100644 docs/getting_started.md diff --git a/docs/README.md b/docs/README.md index 616e7610cc..2a9e79bbfb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -48,81 +48,168 @@ This standardization makes your commit history more readable and meaningful, whi - Display information about your commit rules (commands: schema, example, info) - Create your own set of rules and publish them to pip. Read more on [Customization](./customization.md) -## Requirements +## Getting Started -[Python](https://www.python.org/downloads/) `3.9+` +### Requirements -[Git][gitscm] `1.8.5.2+` +Before installing Commitizen, ensure you have: -## Installation +- [Python](https://www.python.org/downloads/) `3.9+` +- [Git][gitscm] `1.8.5.2+` -Install commitizen in your system using `pipx` (Recommended, <https://pypa.github.io/pipx/installation/>): +### Installation + +#### Global Installation (Recommended) + +The recommended way to install Commitizen is using `pipx`, which ensures a clean, isolated installation: ```bash +# Install pipx if you haven't already pipx ensurepath + +# Install Commitizen pipx install commitizen + +# Keep it updated pipx upgrade commitizen ``` -Install commitizen using `pip` with the `--user` flag: +If you're on macOS, you can also install Commitizen using Homebrew: ```bash -pip install --user -U commitizen +brew install commitizen ``` -### Python project +#### Project-Specific Installation -You can add it to your local project using one of the following methods. +You can add Commitizen to your Python project using any of these package managers: -With `pip`: +**Using pip:** ```bash pip install -U commitizen ``` -With `conda`: +**Using conda:** ```bash conda install -c conda-forge commitizen ``` -With Poetry >= 1.2.0: +**Using Poetry:** ```bash +# For Poetry >= 1.2.0 poetry add commitizen --group dev + +# For Poetry < 1.2.0 +poetry add commitizen --dev ``` -With Poetry < 1.2.0: +### Basic Commands -```bash -poetry add commitizen --dev +#### Initialize Commitizen + +To get started, you'll need to set up your configuration. You have two options: + +1. Use the interactive setup: +```sh +cz init ``` -### macOS +2. Manually create a configuration file (`.cz.toml` or `cz.toml`): +```toml +[tool.commitizen] +version = "0.1.0" +update_changelog_on_bump = true +``` -via [homebrew](https://formulae.brew.sh/formula/commitizen): +#### Create Commits -```bash -brew install commitizen +Create standardized commits using: +```sh +cz commit +# or use the shortcut +cz c ``` -## Usage +To sign off your commits: +```sh +cz commit -- --signoff +# or use the shortcut +cz commit -- -s +``` -Most of the time, this is the only command you'll run: +For more commit options, run `cz commit --help`. +#### Version Management + +The most common command you'll use is: ```sh cz bump ``` -On top of that, you can use commitizen to assist you with the creation of commits: +This command: +- Bumps your project's version +- Creates a git tag +- Updates the changelog (if `update_changelog_on_bump` is enabled) +- Updates version files + +You can customize: +- [Version files](./commands/bump.md#version_files) +- [Version scheme](./commands/bump.md#version_scheme) +- [Version provider](./config.md#version-providers) + +For all available options, see the [bump command documentation](./commands/bump.md). + +### Advanced Usage + +#### Get Project Version +To get your project's version (instead of Commitizen's version): ```sh -cz commit +cz version -p +``` + +This is particularly useful for automation. For example, to preview changelog changes for Slack: +```sh +cz changelog --dry-run "$(cz version -p)" +``` + +#### Pre-commit Integration + +Commitizen can automatically validate your commit messages using pre-commit hooks. + +1. Add to your `.pre-commit-config.yaml`: +```yaml +--- +repos: + - repo: https://github.com/commitizen-tools/commitizen + rev: master # Replace with latest tag + hooks: + - id: commitizen + - id: commitizen-branch + stages: [pre-push] +``` + +2. Install the hooks: +```sh +pre-commit install --hook-type commit-msg --hook-type pre-push ``` -Read more in the section [Getting Started](./getting_started.md). +| Hook | Recommended Stage | +| ----------------- | ----------------- | +| commitizen | commit-msg | +| commitizen-branch | pre-push | + +> **Note**: Replace `master` with the [latest tag](https://github.com/commitizen-tools/commitizen/tags) to avoid warnings. You can automatically update this with: +> ```sh +> pre-commit autoupdate +> ``` -### Help +For more details about commit validation, see the [check command documentation](commands/check.md). + +## Usage <!-- Please manually update the following section after changing `cz --help` command output. --> diff --git a/docs/getting_started.md b/docs/getting_started.md deleted file mode 100644 index 3c6257c363..0000000000 --- a/docs/getting_started.md +++ /dev/null @@ -1,119 +0,0 @@ -## Initialize commitizen - -If it's your first time, you'll need to create a commitizen configuration file. - -The assistant utility will help you set up everything - -```sh -cz init -``` - -Alternatively, create a file `.cz.toml` or `cz.toml` in your project's directory. - -```toml -[tool.commitizen] -version = "0.1.0" -update_changelog_on_bump = true -``` - -## Usage - -### Bump version - -```sh -cz bump -``` - -This command will bump your project's version, and it will create a tag. - -Because of the setting `update_changelog_on_bump`, bump will also create the **changelog**. -You can also [update files](./commands/bump.md#version_files). -You can configure the [version scheme](./commands/bump.md#version_scheme) and [version provider](./config.md#version-providers). - -There are many more options available, please read the docs for the [bump command](./commands/bump.md). - -### Committing - -Run in your terminal - -```bash -cz commit -``` - -or the shortcut - -```bash -cz c -``` - -#### Sign off the commit - -Run in the terminal - -```bash -cz commit -- --signoff -``` - -or the shortcut - -```bash -cz commit -- -s -``` - -### Get project version - -Running `cz version` will return the version of commitizen, but if you want -your project's version you can run: - -```sh -cz version -p -``` - -This can be useful in many situations, where otherwise, you would require a way -to parse the version of your project. Maybe it's simple if you use a `VERSION` file, -but once you start working with many different projects, it becomes tricky. - -A common example is, when you need to send to slack, the changes for the version that you -just created: - -```sh -cz changelog --dry-run "$(cz version -p)" -``` - -### Integration with Pre-commit - -Commitizen can lint your commit message for you with `cz check`. - -You can integrate this in your [pre-commit](https://pre-commit.com/) config with: - -```yaml ---- -repos: - - repo: https://github.com/commitizen-tools/commitizen - rev: master - hooks: - - id: commitizen - - id: commitizen-branch - stages: [pre-push] -``` - -After the configuration is added, you'll need to run: - -```sh -pre-commit install --hook-type commit-msg --hook-type pre-push -``` - -If you aren't using both hooks, you needn't install both stages. - -| Hook | Recommended Stage | -| ----------------- | ----------------- | -| commitizen | commit-msg | -| commitizen-branch | pre-push | - -Note that pre-commit discourages using `master` as a revision, and the above command will print a warning. You should replace the `master` revision with the [latest tag](https://github.com/commitizen-tools/commitizen/tags). This can be done automatically with: - -```sh -pre-commit autoupdate -``` - -Read more about the `check` command [here](commands/check.md). diff --git a/mkdocs.yml b/mkdocs.yml index 6a642161d2..a8a2fe2d44 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -31,7 +31,6 @@ edit_uri: "" nav: - Introduction: "README.md" - - Getting Started: "getting_started.md" - Commands: - init: "commands/init.md" - commit: "commands/commit.md" From 36c7ae576fa4ffae3abcd16f95d5caf066fd7911 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 11 May 2025 23:55:40 +0800 Subject: [PATCH 483/598] docs(README.md): improve clarity of README reference section --- docs/README.md | 72 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 7 deletions(-) diff --git a/docs/README.md b/docs/README.md index 2a9e79bbfb..22d22f42c9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -209,7 +209,11 @@ pre-commit install --hook-type commit-msg --hook-type pre-push For more details about commit validation, see the [check command documentation](commands/check.md). -## Usage +## Help & Reference + +### Command Line Interface + +Commitizen provides a comprehensive CLI with various commands. Here's the complete reference: <!-- Please manually update the following section after changing `cz --help` command output. --> @@ -242,31 +246,85 @@ commands: version get the version of the installed commitizen or the current project (default: installed commitizen) ``` +### Quick Reference + +| Command | Description | Alias | +|---------|-------------|-------| +| `cz init` | Initialize Commitizen configuration | - | +| `cz commit` | Create a new commit | `cz c` | +| `cz bump` | Bump version and update changelog | - | +| `cz changelog` | Generate changelog | `cz ch` | +| `cz check` | Validate commit messages | - | +| `cz version` | Show version information | - | + +### Additional Resources + +- [Conventional Commits Specification][conventional_commits] +- [Exit Codes Reference](./exit_codes.md) +- [Configuration Guide](./config.md) +- [Command Documentation](./commands/init.md) + +### Getting Help + +For each command, you can get detailed help by adding `--help`: + +```sh +cz commit --help +cz bump --help +cz changelog --help +``` + +For more detailed documentation, visit our [documentation site](https://commitizen-tools.github.io/commitizen/). + ## Setting up bash completion -When using bash as your shell (limited support for zsh, fish, and tcsh is available), Commitizen can use [argcomplete](https://kislyuk.github.io/argcomplete/) for auto-completion. For this, argcomplete needs to be enabled. +Commitizen supports command-line completion through [argcomplete](https://kislyuk.github.io/argcomplete/), which is automatically installed as a dependency. This feature provides intelligent auto-completion for all Commitizen commands and options. + +### Supported Shells + +- **Bash**: Full support +- **Zsh**: Limited support +- **Fish**: Limited support +- **Tcsh**: Limited support -argcomplete is installed when you install Commitizen since it's a dependency. +### Installation Methods + +#### Global Installation (Recommended) -If Commitizen is installed globally, global activation can be executed: +If you installed Commitizen globally (e.g., using `pipx` or `brew`), you can enable global completion: ```bash +# Enable global completion for all Python applications sudo activate-global-python-argcomplete ``` -For permanent (but not global) Commitizen activation, use: +#### User-Specific Installation + +For a user-specific installation that persists across sessions: ```bash +# Add to your shell's startup file (e.g., ~/.bashrc, ~/.zshrc) register-python-argcomplete cz >> ~/.bashrc ``` -For one-time activation of argcomplete for Commitizen only, use: +#### Temporary Installation + +For one-time activation in your current shell session: ```bash +# Activate completion for current session only eval "$(register-python-argcomplete cz)" ``` -For further information on activation, please visit the [argcomplete website](https://kislyuk.github.io/argcomplete/). +### Verification + +After installation, you can verify the completion is working by: + +1. Opening a new terminal session +2. Typing `cz` followed by a space and pressing `TAB` twice +3. You should see a list of available commands + +For more detailed information about argcomplete configuration and troubleshooting, visit the [argcomplete documentation](https://kislyuk.github.io/argcomplete/). ## Sponsors From 37a4a3ae4b0f9347f3cb4445931f027fee0ea9c2 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 12 May 2025 00:58:47 +0800 Subject: [PATCH 484/598] docs(cli): align cli output with docs --- commitizen/cli.py | 5 ++--- docs/README.md | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index f0df2f4242..cb834c5d6f 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -86,9 +86,8 @@ def __call__( data = { "prog": "cz", "description": ( - "Commitizen is a cli tool to generate conventional commits.\n" - "For more information about the topic go to " - "https://conventionalcommits.org/" + "Commitizen is a powerful release management tool that helps teams maintain consistent and meaningful commit messages while automating version management.\n" + "For more information, please visit https://commitizen-tools.github.io/commitizen" ), "formatter_class": argparse.RawDescriptionHelpFormatter, "arguments": [ diff --git a/docs/README.md b/docs/README.md index 22d22f42c9..144c253a81 100644 --- a/docs/README.md +++ b/docs/README.md @@ -221,8 +221,8 @@ Commitizen provides a comprehensive CLI with various commands. Here's the comple $ cz --help usage: cz [-h] [--config CONFIG] [--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/ +Commitizen is a powerful release management tool that helps teams maintain consistent and meaningful commit messages while automating version management. +For more information, please visit https://commitizen-tools.github.io/commitizen options: -h, --help show this help message and exit From 4cd6d78a6bfc603497f9cb2c1b14c38616218b9f Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 12 May 2025 01:56:29 +0800 Subject: [PATCH 485/598] docs(contributing.md): improve readability of contributing docs --- docs/contributing.md | 97 ++++++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/docs/contributing.md b/docs/contributing.md index 0987771066..4ca12765aa 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,32 +1,78 @@ ## Contributing to commitizen -First of all, thank you for taking the time to contribute! 🎉 +First, thank you for taking the time to contribute! 🎉 When contributing to [commitizen](https://github.com/commitizen-tools/commitizen), please first create an [issue](https://github.com/commitizen-tools/commitizen/issues) to discuss the change you wish to make before making a change. If you're a first-time contributor, you can check the issues with the [good first issue](https://github.com/commitizen-tools/commitizen/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag. -## Install before contributing - -1. Install [poetry](https://python-poetry.org/) `>=2.0.0`. See the installation [pages](https://python-poetry.org/docs/#installing-with-the-official-installer). -2. Install [gpg](https://gnupg.org). See the installation [pages](https://gnupg.org/documentation/manuals/gnupg/Installation.html#Installation). For Mac users, you can use [homebrew](https://brew.sh/). - -## Before making a pull request - -1. Fork [the repository](https://github.com/commitizen-tools/commitizen). -2. Clone the repository from your GitHub. -3. Set up the development environment through [poetry](https://python-poetry.org/) (`poetry install`). -4. Set up the [pre-commit](https://pre-commit.com/) hook (`poetry setup-pre-commit`). -5. Checkout a new branch and add your modifications. -6. Add test cases for all your changes. - (We use [CodeCov](https://codecov.io/) to ensure our test coverage does not drop.) -7. Use [commitizen](https://github.com/commitizen-tools/commitizen) to make git commits. We follow [conventional commits](https://www.conventionalcommits.org/). -8. Run `poetry all` to ensure you follow the coding style and the tests pass. -9. Optionally, update the `./docs/README.md` or `docs/images/cli_help` (by running `poetry doc:screenshots`). -10. **Do not** update the `CHANGELOG.md`; it will be automatically created after merging to `master`. -11. **Do not** update the versions in the project; they will be automatically updated. -12. If your changes are about documentation, run `poetry doc` to serve documentation locally and check whether there are any warnings or errors. -13. Send a [pull request](https://github.com/commitizen-tools/commitizen/pulls) 🙏 +## Prerequisites & Setup + +### Required Tools + +1. **Python Environment** + - Python `>=3.9` + - [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer) `>=2.0.0` +2. **Version Control & Security** + - Git + - Commitizen + - [GPG](https://gnupg.org) for commit signing + - [Installation page](https://gnupg.org/documentation/manuals/gnupg/Installation.html#Installation) + - For Mac users: `brew install gnupg` + - For Windows users: Download from [Gpg4win](https://www.gpg4win.org/) + - For Linux users: Use your distribution's package manager (e.g., `apt install gnupg` for Ubuntu) + +### Getting Started + +1. Fork [Commitizen](https://github.com/commitizen-tools/commitizen) +2. Clone your fork: + ```bash + git clone https://github.com/YOUR_USERNAME/commitizen.git + cd commitizen + ``` +3. Add the upstream repository: + ```bash + git remote add upstream https://github.com/commitizen-tools/commitizen.git + ``` +4. Set up the development environment: + ```bash + poetry install + ``` +5. Set up pre-commit hooks: + ```bash + poetry setup-pre-commit + ``` + +## Development Workflow + +1. **Create a New Branch** + ```bash + git switch -c feature/your-feature-name + # or + git switch -c fix/your-bug-fix + ``` +2. **Make Your Changes** + - Write your code + - Add tests for new functionalities or fixes + - Update documentation if needed + - Follow the existing code style +3. **Testing** + - Run the full test suite: `poetry all` + - Ensure test coverage doesn't drop (we use [CodeCov](https://codecov.io/)) + - For documentation changes, run `poetry doc` to check for warnings/errors +4. **Committing Changes** + - Use commitizen to make commits (we follow [conventional commits](https://www.conventionalcommits.org/)) + - Example: `cz commit` +5. **Documentation** + - Update `docs/README.md` if needed + - For CLI help screenshots: `poetry doc:screenshots` + - **DO NOT** update `CHANGELOG.md` (automatically generated) + - **DO NOT** update version numbers (automatically handled) +6. **Pull Request** + - Push your changes: `git push origin your-branch-name` + - Create a pull request on GitHub + - Ensure CI checks pass + - Wait for review and address any feedback ## Use of GitHub Labels @@ -57,7 +103,7 @@ If you're a first-time contributor, you can check the issues with the [good firs * os: macOS -### Issue life cycle +## Issue life cycle ```mermaid graph TD @@ -75,7 +121,7 @@ graph TD close --> output[/close/] ``` -### Pull request life cycle +## Pull request life cycle ```mermaid flowchart TD @@ -103,6 +149,3 @@ flowchart TD --modification-received--> review ``` - - -[conventional-commits]: https://www.conventionalcommits.org/ From 5e14843ef8ac0c85724588e0f49317132c3cab0f Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 12 May 2025 03:05:22 +0800 Subject: [PATCH 486/598] docs(pyproject.toml): fix typo --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b306e5e78c..a653ecdb5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -257,7 +257,7 @@ all.sequence = [ "check-commit", ] -"doc:screenshots".help = "Render documentation screeenshots" +"doc:screenshots".help = "Render documentation screenshots" "doc:screenshots".script = "scripts.gen_cli_help_screenshots:gen_cli_help_screenshots" "doc:build".help = "Build the documentation" From 614eaa3995cf45f55e8d1e7efdcf52e94946f2f8 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Tue, 13 May 2025 00:29:29 +0800 Subject: [PATCH 487/598] docs(README): update get project version section --- docs/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 144c253a81..721ab99791 100644 --- a/docs/README.md +++ b/docs/README.md @@ -166,16 +166,16 @@ For all available options, see the [bump command documentation](./commands/bump. #### Get Project Version -To get your project's version (instead of Commitizen's version): ```sh +# Get your project's version (instead of Commitizen's version) cz version -p -``` - -This is particularly useful for automation. For example, to preview changelog changes for Slack: -```sh +# Preview changelog changes cz changelog --dry-run "$(cz version -p)" ``` +This command is particularly useful for automation scripts and CI/CD pipelines. +For example, you can use the output of the command `cz changelog --dry-run "$(cz version -p)"` to notify your team about a new release in Slack. + #### Pre-commit Integration Commitizen can automatically validate your commit messages using pre-commit hooks. From f893d082030527dc965348ec6dfb163130b75359 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 14 May 2025 23:00:31 +0800 Subject: [PATCH 488/598] docs(README): update installation methods --- docs/README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index 721ab99791..e35cf5e358 100644 --- a/docs/README.md +++ b/docs/README.md @@ -61,12 +61,9 @@ Before installing Commitizen, ensure you have: #### Global Installation (Recommended) -The recommended way to install Commitizen is using `pipx`, which ensures a clean, isolated installation: - +The recommended way to install Commitizen is using [`pipx`](https://pipx.pypa.io/) or [`uv`](https://docs.astral.sh/uv/), which ensures a clean, isolated installation: +**Using pipx:** ```bash -# Install pipx if you haven't already -pipx ensurepath - # Install Commitizen pipx install commitizen @@ -74,8 +71,16 @@ pipx install commitizen pipx upgrade commitizen ``` -If you're on macOS, you can also install Commitizen using Homebrew: +**Using uv:** +```bash +# Install commitizen +uv tool install commitizen +# Keep it updated +uv tool upgrade commitizen +``` + +**(For macOS users) Using Homebrew:** ```bash brew install commitizen ``` @@ -85,19 +90,16 @@ brew install commitizen You can add Commitizen to your Python project using any of these package managers: **Using pip:** - ```bash pip install -U commitizen ``` **Using conda:** - ```bash conda install -c conda-forge commitizen ``` **Using Poetry:** - ```bash # For Poetry >= 1.2.0 poetry add commitizen --group dev From 6930aaaea170fba7fa1aca13cbff40b11d79564e Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 15 May 2025 20:54:23 +0800 Subject: [PATCH 489/598] docs(README): use cli screenshots Closes #1413 --- docs/README.md | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/docs/README.md b/docs/README.md index e35cf5e358..ed1aaef2a1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -217,36 +217,7 @@ For more details about commit validation, see the [check command documentation]( Commitizen provides a comprehensive CLI with various commands. Here's the complete reference: -<!-- Please manually update the following section after changing `cz --help` command output. --> - -```sh -$ cz --help -usage: cz [-h] [--config CONFIG] [--debug] [-n NAME] [-nr NO_RAISE] {init,commit,c,ls,example,info,schema,bump,changelog,ch,check,version} ... - -Commitizen is a powerful release management tool that helps teams maintain consistent and meaningful commit messages while automating version management. -For more information, please visit https://commitizen-tools.github.io/commitizen - -options: - -h, --help show this help message and exit - --config CONFIG the path of configuration file - --debug use debug mode - -n, --name NAME use the given commitizen (default: cz_conventional_commits) - -nr, --no-raise NO_RAISE - comma separated error codes that won't raise 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) -``` +![cz --help](images/cli_help/cz___help.svg) ### Quick Reference From ec57f7de0da977f43157b7235e7f817399bc10ed Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 15 May 2025 21:13:54 +0800 Subject: [PATCH 490/598] docs: fix link warnings and minor grammar issues --- docs/commands/bump.md | 10 +++++----- docs/config.md | 24 ++++++++++++------------ docs/customization.md | 4 ++-- docs/tutorials/github_actions.md | 4 ++-- docs/tutorials/gitlab_ci.md | 4 ++-- docs/tutorials/jenkins_pipeline.md | 2 +- docs/tutorials/monorepo_guidance.md | 4 ++-- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/commands/bump.md b/docs/commands/bump.md index efdba76257..6eb5b55c54 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -72,7 +72,7 @@ cz bump --changelog The bump is a pre-release bump, meaning that in addition to a possible version bump the new version receives a pre-release segment compatible with the bump’s version scheme, where the segment consist of a _phase_ and a -non-negative number. Supported options for `--prerelease` are the following phase names `alpha`, `beta`, or +non-negative number. Supported options for `--prerelease` are the following phase names `alpha`, `beta`, or `rc` (release candidate). For more details, refer to the [Python Packaging User Guide](https://packaging.python.org/en/latest/specifications/version-specifiers/#pre-releases). @@ -387,7 +387,7 @@ to skip and why. Remember to document somewhere this, because you'll forget. For example if the system raises a `NoneIncrementExit` error, you look it up -on the list and then you can use the exit code: +on the list, and then you can use the exit code: ```sh cz -nr 21 bump @@ -403,7 +403,7 @@ These are used in: - `cz bump`: Find previous release tag (exact match) and generate new tag. - Find previous release tags in `cz changelog`. - - If `--incremental`: Using latest version found in the changelog, scan existing Git tags with 89\% similarity match. + - If `--incremental`: Using the latest version found in the changelog, scan existing Git tags with 89\% similarity match. - `--rev-range` is converted to Git tag names with `tag_format` before searching Git history. - If the `scm` `version_provider` is used, it uses different regexes to find the previous version tags: - If `tag_format` is set to `$version` (default): `VersionProtocol.parser` (allows `v` prefix) @@ -477,7 +477,7 @@ in a line containing the `version` substring. Template used to specify the commit message generated when bumping. -defaults to: `bump: version $current_version → $new_version` +Defaults to: `bump: version $current_version → $new_version` | Variable | Description | | ------------------ | ----------------------------------- | @@ -499,7 +499,7 @@ bump_message = "release $current_version → $new_version [skip-ci]" When set to `true` the changelog is always updated incrementally when running `cz bump`, so the user does not have to provide the `--changelog` flag every time. -defaults to: `false` +Defaults to: `false` ```toml [tool.commitizen] diff --git a/docs/config.md b/docs/config.md index b6dd794fb3..1ea02d5f67 100644 --- a/docs/config.md +++ b/docs/config.md @@ -59,7 +59,7 @@ Default: `[ ]` Legacy git tag formats, useful for old projects that changed tag format. Tags matching those formats will be recognized as version tags and be included in the changelog. -Each entry use the the syntax as [`tag_format`](#tag_format). [Read more][tag_format] +Each entry uses the syntax as [`tag_format`](#tag_format). [Read more][tag_format] ### `ignored_tag_formats` @@ -68,7 +68,7 @@ Type: `list` Default: `[ ]` Tags matching those formats will be totally ignored and won't raise a warning. -Each entry use the the syntax as [`tag_format`](#tag_format) with the addition of `*` +Each entry uses the syntax as [`tag_format`](#tag_format) with the addition of `*` that will match everything (non-greedy). [Read more][tag_format] ### `update_changelog_on_bump` @@ -101,7 +101,7 @@ Type: `str` Default: `None` -Create custom commit message, useful to skip ci. [Read more][bump_message] +Create custom commit message, useful to skip CI. [Read more][bump_message] ### `retry_after_failure` @@ -117,7 +117,7 @@ Type: `bool` Default: `false` -Disallow empty commit messages, useful in ci. [Read more][allow_abort] +Disallow empty commit messages, useful in CI. [Read more][allow_abort] ### `allowed_prefixes` @@ -195,7 +195,7 @@ Type: `bool` Default: `false` -When true, breaking changes on a `0.x` will remain as a `0.x` version. On `false`, a breaking change will bump a `0.x` version to `1.0`. [major-version-zero] +When true, breaking changes on a `0.x` will remain as a `0.x` version. On `false`, a breaking change will bump a `0.x` version to `1.0`. [Read more][major-version-zero] ### `prerelease_offset` @@ -203,7 +203,7 @@ Type: `int` Default: `0` -In some circumstances, a prerelease cannot start with a 0, e.g. in an embedded project individual characters are encoded as bytes. This can be done by specifying an offset from which to start counting. [prerelease-offset] +In some circumstances, a prerelease cannot start with a 0, e.g. in an embedded project individual characters are encoded as bytes. This can be done by specifying an offset from which to start counting. [Read more][prerelease-offset] ### `pre_bump_hooks` @@ -247,7 +247,7 @@ Provide extra variables to the changelog template. [Read more][template-customiz ## Configuration file -### pyproject.toml, .cz.toml or cz.toml +### `pyproject.toml`, `.cz.toml` or `cz.toml` Default and recommended configuration format for a project. For a **python** project, we recommend adding an entry to your `pyproject.toml`. @@ -278,7 +278,7 @@ style = [ ] ``` -### .cz.json or cz.json +### `.cz.json` or `cz.json` Commitizen has support for JSON configuration. Recommended for `NodeJS` projects. @@ -304,7 +304,7 @@ Commitizen has support for JSON configuration. Recommended for `NodeJS` projects } ``` -### .cz.yaml or cz.yaml +### `.cz.yaml` or `cz.yaml` YAML configuration is supported by Commitizen. Recommended for `Go`, `ansible`, or even `helm` charts projects. @@ -358,7 +358,7 @@ Commitizen provides some version providers for some well known formats: | `composer` | Get and set version from `composer.json` `project.version` field | !!! note -The `scm` provider is meant to be used with `setuptools-scm` or any packager `*-scm` plugin. + The `scm` provider is meant to be used with `setuptools-scm` or any packager `*-scm` plugin. An example in your `.cz.toml` or `cz.toml` would look like this: @@ -408,10 +408,10 @@ setup( [tag_format]: commands/bump.md#tag_format [bump_message]: commands/bump.md#bump_message [major-version-zero]: commands/bump.md#-major-version-zero -[prerelease-offset]: commands/bump.md#-prerelease_offset +[prerelease-offset]: commands/bump.md#prerelease_offset [retry_after_failure]: commands/commit.md#retry [allow_abort]: commands/check.md#allow-abort -[version-scheme]: commands/bump.md#version-scheme +[version-scheme]: commands/bump.md#-version-scheme [pre_bump_hooks]: commands/bump.md#pre_bump_hooks [post_bump_hooks]: commands/bump.md#post_bump_hooks [allowed_prefixes]: commands/check.md#allowed-prefixes diff --git a/docs/customization.md b/docs/customization.md index cef03469e0..805173e900 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -490,7 +490,7 @@ Users can provide their own template from their current working directory (your - setting your template path as `template` configuration - giving your template path as `--template` parameter to `bump` and `changelog` commands -!!! Note +!!! note The path is relative to the current working directory, aka your project root most of the time. ### Template variables @@ -514,7 +514,7 @@ Each `Change` has the following fields: | author | `str` | The commit author name | | author_email | `str` | The commit author email | -!!! Note +!!! note The field values depend on the customization class and/or the settings you provide The `parents` field can be used to identify merge commits and generate a changelog based on those. Another use case diff --git a/docs/tutorials/github_actions.md b/docs/tutorials/github_actions.md index bcb3fda22c..4f50aaf4e7 100644 --- a/docs/tutorials/github_actions.md +++ b/docs/tutorials/github_actions.md @@ -41,14 +41,14 @@ jobs: Push to master and that's it. -### Creating a github release +### Creating a GitHub release You can modify the previous action. Add the variable `changelog_increment_filename` in the `commitizen-action`, specifying where to output the content of the changelog for the newly created version. -And then add a step using a github action to create the release: `softprops/action-gh-release` +And then add a step using a GitHub action to create the release: `softprops/action-gh-release` The commitizen action creates an env variable called `REVISION`, containing the newly created version. diff --git a/docs/tutorials/gitlab_ci.md b/docs/tutorials/gitlab_ci.md index 85b6a615c3..6f6d53a57e 100644 --- a/docs/tutorials/gitlab_ci.md +++ b/docs/tutorials/gitlab_ci.md @@ -12,9 +12,9 @@ _Goal_: Bump a new version every time that a change occurs on the `master` branc 4. For simplification, we store the software version in a file called `VERSION`. You can use any file that you want as `commitizen` supports it. 5. The commit message executed automatically by the `CI` must include `[skip-ci]` in the message; otherwise, the process will generate a loop. You can define the message structure in [commitizen](../commands/bump.md) as well. -### Gitlab Configuration +### GitLab Configuration -To be able to change files and push new changes with `Gitlab CI` runners, we need to have a `ssh` key and configure a git user. +To be able to change files and push new changes with `GitLab CI` runners, we need to have a `ssh` key and configure a git user. First, let's create a `ssh key`. The only requirement is to create it without a passphrase: diff --git a/docs/tutorials/jenkins_pipeline.md b/docs/tutorials/jenkins_pipeline.md index fb87820c4c..2b9ad173d3 100644 --- a/docs/tutorials/jenkins_pipeline.md +++ b/docs/tutorials/jenkins_pipeline.md @@ -47,7 +47,7 @@ def useCz(String authorName = 'Jenkins CI Server', String authorEmail = 'your-je ``` !!! warning - Using jenkins pipeline with any git plugin may require many different configurations, + Using jenkins pipeline with any git plugin may require many configurations, you'll have to tinker with it until your pipelines properly detects git events. Check your webhook in your git repository and check the "behaviors" and "build strategies" in your pipeline settings. diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index 792c8c224f..434899f86f 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -56,9 +56,9 @@ In order to filter the correct commits for each component, you'll have to come u For example: - Trigger the pipeline based on the changed path, which can have some downsides, as you'll rely on the developer not including files from other files - - [github actions](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore) uses `path` + - [GitHub actions](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore) uses `path` - [Jenkins](https://www.jenkins.io/doc/book/pipeline/syntax/#built-in-conditions) uses `changeset` - - [Gitlab](https://docs.gitlab.com/ee/ci/yaml/#ruleschanges) uses `rules:changes` + - [GitLab](https://docs.gitlab.com/ee/ci/yaml/#ruleschanges) uses `rules:changes` - Filter certain pattern of the commit message (recommended) From 71c2e914d477ac7e45a05eddb9ad511f4fe0c4ca Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 15 May 2025 21:22:04 +0800 Subject: [PATCH 491/598] docs(pull_request_template): add broken link check to the checklist --- .github/pull_request_template.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e28480e5b9..5686474709 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -25,6 +25,13 @@ Please fill in the following content to let us know better about this change. ### Documentation Changes - [ ] Run `poetry doc` locally to ensure the documentation pages renders correctly + - [ ] Check if there are any broken links in the documentation + +> When running `poetry doc`, any broken internal documentation links will be reported in the console output like this: +> +> ```text +> INFO - Doc file 'config.md' contains a link 'commands/bump.md#-post_bump_hooks', but the doc 'commands/bump.md' does not contain an anchor '#-post_bump_hooks'. +> ``` ## Expected Behavior <!-- A clear and concise description of what you expected to happen --> From 2a68e89aed582ef4d89c3d0799406f5cb6584c5a Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 15 May 2025 21:27:41 +0800 Subject: [PATCH 492/598] docs(contributing): update codecov link --- docs/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.md b/docs/contributing.md index 4ca12765aa..336f83352a 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -58,7 +58,7 @@ If you're a first-time contributor, you can check the issues with the [good firs - Follow the existing code style 3. **Testing** - Run the full test suite: `poetry all` - - Ensure test coverage doesn't drop (we use [CodeCov](https://codecov.io/)) + - Ensure test coverage doesn't drop (we use [CodeCov](https://app.codecov.io/gh/commitizen-tools/commitizen)) - For documentation changes, run `poetry doc` to check for warnings/errors 4. **Committing Changes** - Use commitizen to make commits (we follow [conventional commits](https://www.conventionalcommits.org/)) From 1c58b1c272c4ab9ee2ce93907280d5ac3bde10a6 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 15 May 2025 21:44:23 +0800 Subject: [PATCH 493/598] docs(README): update project specific installation methods --- docs/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/README.md b/docs/README.md index ed1aaef2a1..e0c3fed747 100644 --- a/docs/README.md +++ b/docs/README.md @@ -108,6 +108,16 @@ poetry add commitizen --group dev poetry add commitizen --dev ``` +**Using uv:** +```bash +uv add commitizen +``` + +**Using pdm:** +```bash +pdm add -d commitizen +``` + ### Basic Commands #### Initialize Commitizen From 70af1a6dc947cb78d10de546d6441b89ccd5bcd8 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 15 May 2025 22:03:19 +0800 Subject: [PATCH 494/598] docs: capitalize commitizen for consistency --- docs/README.md | 2 +- docs/commands/bump.md | 26 +++++++++---------- docs/commands/commit.md | 10 +++---- docs/commands/init.md | 2 +- docs/commands/version.md | 2 +- docs/config.md | 6 ++--- docs/contributing.md | 2 +- docs/customization.md | 12 ++++----- docs/exit_codes.md | 2 +- docs/external_links.md | 2 +- docs/faq.md | 6 ++--- docs/third-party-commitizen.md | 4 +-- docs/tutorials/auto_prepare_commit_message.md | 8 +++--- docs/tutorials/github_actions.md | 4 +-- docs/tutorials/monorepo_guidance.md | 2 +- docs/tutorials/writing_commits.md | 2 +- 16 files changed, 46 insertions(+), 46 deletions(-) diff --git a/docs/README.md b/docs/README.md index e0c3fed747..9bb1555721 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,7 +8,7 @@ [![Codecov](https://img.shields.io/codecov/c/github/commitizen-tools/commitizen.svg?style=flat-square)](https://codecov.io/gh/commitizen-tools/commitizen) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?style=flat-square&logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) -![Using commitizen cli](images/demo.gif) +![Using Commitizen cli](images/demo.gif) --- diff --git a/docs/commands/bump.md b/docs/commands/bump.md index 6eb5b55c54..ee3d77430a 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -116,7 +116,7 @@ Below are some examples that illustrate the difference in behavior: ### `--check-consistency` -Check whether the versions defined in `version_files` and the version in commitizen +Check whether the versions defined in `version_files` and the version in Commitizen configuration are consistent before bumping version. ```bash @@ -148,7 +148,7 @@ from setuptools import setup setup(..., version="1.0.5", ...) ``` -If `--check-consistency` is used, commitizen will check whether the current version in `pyproject.toml` +If `--check-consistency` is used, Commitizen will check whether the current version in `pyproject.toml` exists in all version_files and find out it does not exist in `setup.py` and fails. However, it will still update `pyproject.toml` and `src/__version__.py`. @@ -174,11 +174,11 @@ If `--local-version` is used, it will bump only the local version `0.1.0` and ke ### `--annotated-tag` -If `--annotated-tag` is used, commitizen will create annotated tags. Also available via configuration, in `pyproject.toml` or `.cz.toml`. +If `--annotated-tag` is used, Commitizen will create annotated tags. It is also available via configuration, in `pyproject.toml` or `.cz.toml`. ### `--annotated-tag-message` -If `--annotated-tag-message` is used, commitizen will create annotated tags with the given message. +If `--annotated-tag-message` is used, Commitizen will create annotated tags with the given message. ### `--changelog-to-stdout` @@ -332,11 +332,11 @@ cz bump --allow-no-commit 2.0.0 ## Avoid raising errors -Some situations from commitizen raise an exit code different than 0. -If the error code is different than 0, any CI or script running commitizen might be interrupted. +Some situations from Commitizen raise an exit code different from 0. +If the error code is different from 0, any CI or script running Commitizen might be interrupted. If you have a special use case, where you don't want to raise one of this error codes, you can -tell commitizen to not raise them. +tell Commitizen to not raise them. ### Recommended use case @@ -355,7 +355,7 @@ cz -nr 21 bump ### Easy way -Check which error code was raised by commitizen by running in the terminal +Check which error code was raised by Commitizen by running in the terminal ```sh echo $? @@ -367,13 +367,13 @@ The output should be an integer like this 3 ``` -And then you can tell commitizen to ignore it: +And then you can tell Commitizen to ignore it: ```sh cz --no-raise 3 ``` -You can tell commitizen to skip more than one if needed: +You can tell Commitizen to skip more than one if needed: ```sh cz --no-raise 3,4,5 @@ -510,7 +510,7 @@ update_changelog_on_bump = true ### `annotated_tag` -When set to `true` commitizen will create annotated tags. +When set to `true`, Commitizen will create annotated tags. ```toml [tool.commitizen] @@ -521,7 +521,7 @@ annotated_tag = true ### `gpg_sign` -When set to `true` commitizen will create gpg signed tags. +When set to `true`, Commitizen will create gpg signed tags. ```toml [tool.commitizen] @@ -532,7 +532,7 @@ gpg_sign = true ### `major_version_zero` -When set to `true` commitizen will keep the major version at zero. +When set to `true`, Commitizen will keep the major version at zero. Useful during the initial development stage of your project. Defaults to: `false` diff --git a/docs/commands/commit.md b/docs/commands/commit.md index ea033cc411..febaee3cf2 100644 --- a/docs/commands/commit.md +++ b/docs/commands/commit.md @@ -1,4 +1,4 @@ -![Using commitizen cli](../images/demo.gif) +![Using Commitizen cli](../images/demo.gif) ## About @@ -20,14 +20,14 @@ case for this is to [automatically prepare a commit message](../tutorials/auto_p ### git options -`git` command options that are not implemented by commitizen can be use via the `--` syntax for the `commit` command. -The syntax separates commitizen arguments from `git commit` arguments by a double dash. This is the resulting syntax: +`git` command options that are not implemented by Commitizen can be use via the `--` syntax for the `commit` command. +The syntax separates Commitizen arguments from `git commit` arguments by a double dash. This is the resulting syntax: ```sh cz commit <commitizen-args> -- <git-cli-args> # e.g., cz commit --dry-run -- -a -S ``` -For example, using the `-S` option on `git commit` to sign a commit is now commitizen compatible: `cz c -- -S` +For example, using the `-S` option on `git commit` to sign a commit is now Commitizen compatible: `cz c -- -S` !!! note Deprecation warning: A commit can be signed off using `cz commit --signoff` or the shortcut `cz commit -s`. @@ -37,7 +37,7 @@ For example, using the `-S` option on `git commit` to sign a commit is now commi You can use `cz commit --retry` to reuse the last commit message when the previous commit attempt failed. To automatically retry when running `cz commit`, you can set the `retry_after_failure` -configuration option to `true`. Running `cz commit --no-retry` makes commitizen ignore `retry_after_failure`, forcing +configuration option to `true`. Running `cz commit --no-retry` makes Commitizen ignore `retry_after_failure`, forcing a new commit message to be prompted. ### Commit message length limit diff --git a/docs/commands/init.md b/docs/commands/init.md index 01e1db6be8..a799c44810 100644 --- a/docs/commands/init.md +++ b/docs/commands/init.md @@ -4,7 +4,7 @@ ## Example -To start using commitizen, the recommended approach is to run +To start using Commitizen, the recommended approach is to run ```sh cz init diff --git a/docs/commands/version.md b/docs/commands/version.md index 9a8176b45f..4d2e6a0323 100644 --- a/docs/commands/version.md +++ b/docs/commands/version.md @@ -1,4 +1,4 @@ -Get the version of the installed commitizen or the current project (default: installed commitizen) +Get the version of the installed Commitizen or the current project (default: installed commitizen) ## Usage diff --git a/docs/config.md b/docs/config.md index 1ea02d5f67..5ca2c5d788 100644 --- a/docs/config.md +++ b/docs/config.md @@ -187,7 +187,7 @@ Type: `bool` Default: `false` -If enabled, commitizen will show keyboard shortcuts when selecting from a list. Define a `key` for each of your choices to set the key. [Read more][shortcuts] +If enabled, Commitizen will show keyboard shortcuts when selecting from a list. Define a `key` for each of your choices to set the key. [Read more][shortcuts] ### `major_version_zero` @@ -341,14 +341,14 @@ commitizen: ## Version providers Commitizen can read and write version from different sources. -By default, it uses the `commitizen` one which is using the `version` field from the commitizen settings. +By default, it uses the `commitizen` one which is using the `version` field from the Commitizen settings. But you can use any `commitizen.provider` entrypoint as value for `version_provider`. Commitizen provides some version providers for some well known formats: | name | description | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `commitizen` | Default version provider: Fetch and set version in commitizen config. | +| `commitizen` | Default version provider: Fetch and set version in Commitizen config. | | `scm` | Fetch the version from git and does not need to set it back | | `pep621` | Get and set version from `pyproject.toml` `project.version` field | | `poetry` | Get and set version from `pyproject.toml` `tool.poetry.version` field | diff --git a/docs/contributing.md b/docs/contributing.md index 336f83352a..e9e162d2df 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -61,7 +61,7 @@ If you're a first-time contributor, you can check the issues with the [good firs - Ensure test coverage doesn't drop (we use [CodeCov](https://app.codecov.io/gh/commitizen-tools/commitizen)) - For documentation changes, run `poetry doc` to check for warnings/errors 4. **Committing Changes** - - Use commitizen to make commits (we follow [conventional commits](https://www.conventionalcommits.org/)) + - Use Commitizen to make commits (we follow [conventional commits](https://www.conventionalcommits.org/)) - Example: `cz commit` 5. **Documentation** - Update `docs/README.md` if needed diff --git a/docs/customization.md b/docs/customization.md index 805173e900..e97558a308 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -1,4 +1,4 @@ -Customizing commitizen is not hard at all. +Customizing Commitizen is not hard at all. We have two different ways to do so. ## 1. Customize in configuration file @@ -6,7 +6,7 @@ We have two different ways to do so. The basic steps are: 1. Define your custom committing or bumping rules in the configuration file. -2. Declare `name = "cz_customize"` in your configuration file, or add `-n cz_customize` when running commitizen. +2. Declare `name = "cz_customize"` in your configuration file, or add `-n cz_customize` when running Commitizen. Example: @@ -184,8 +184,8 @@ commitizen: #### Shortcut keys -When the [`use_shortcuts`](config.md#settings) config option is enabled, commitizen can show and use keyboard shortcuts to select items from lists directly. -For example, when using the `cz_conventional_commits` commitizen template, shortcut keys are shown when selecting the commit type. Unless otherwise defined, keyboard shortcuts will be numbered automatically. +When the [`use_shortcuts`](config.md#settings) config option is enabled, Commitizen can show and use keyboard shortcuts to select items from lists directly. +For example, when using the `cz_conventional_commits` Commitizen template, shortcut keys are shown when selecting the commit type. Unless otherwise defined, keyboard shortcuts will be numbered automatically. To specify keyboard shortcuts for your custom choices, provide the shortcut using the `key` parameter in dictionary form for each choice you would like to customize. ## 2. Customize through customizing a class @@ -304,7 +304,7 @@ class StrangeCommitizen(BaseCommitizen): bump_map = {"break": "MAJOR", "new": "MINOR", "fix": "PATCH", "hotfix": "PATCH"} ``` -That's it, your commitizen now supports custom rules, and you can run. +That's it, your Commitizen now supports custom rules, and you can run. ```bash cz -n cz_strange bump @@ -451,7 +451,7 @@ Commitizen gives you the possibility to provide your own changelog template, by: - as `--template` parameter to both `bump` and `changelog` commands - either by providing a template with the same name as the default template -By default, the template used is the `CHANGELOG.md.j2` file from the commitizen repository. +By default, the template used is the `CHANGELOG.md.j2` file from the Commitizen repository. ### Providing a template with your customization class diff --git a/docs/exit_codes.md b/docs/exit_codes.md index af9cb83627..fd92961d38 100644 --- a/docs/exit_codes.md +++ b/docs/exit_codes.md @@ -20,7 +20,7 @@ These exit codes can be found in `commitizen/exceptions.py::ExitCode`. | NoCommitBackupError | 10 | Commit back up file cannot be found | | NothingToCommitError | 11 | Nothing in staging to be committed | | CustomError | 12 | `CzException` raised | -| NoCommandFoundError | 13 | No command found when running commitizen cli (e.g., `cz --debug`) | +| NoCommandFoundError | 13 | No command found when running Commitizen cli (e.g., `cz --debug`) | | InvalidCommitMessageError | 14 | The commit message does not pass `cz check` | | MissingConfigError | 15 | Configuration missed for `cz_customize` | | NoRevisionError | 16 | No revision found | diff --git a/docs/external_links.md b/docs/external_links.md index 388bcc8dea..24e4127d86 100644 --- a/docs/external_links.md +++ b/docs/external_links.md @@ -1,4 +1,4 @@ -> If you have written over commitizen, make a PR and add the link here 💪 +> If you have written over Commitizen, make a PR and add the link here 💪 ## Talks diff --git a/docs/faq.md b/docs/faq.md index 0302efd267..ceabac2e10 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -63,7 +63,7 @@ Where do they cross paths? If you are using conventional commits in your git history, then you could swap one with the other in theory. -Regarding the name, [cz-js][cz-js] came first, they used the word commitizen first. When this project was created originally, the creator read "be a good commitizen", and thought it was just a cool word that made sense, and this would be a package that helps you be a good "commit citizen". +Regarding the name, [cz-js][cz-js] came first, they used the word Commitizen first. When this project was created originally, the creator read "be a good commitizen", and thought it was just a cool word that made sense, and this would be a package that helps you be a good "commit citizen". [cz-js]: https://github.com/commitizen/cz-cli @@ -80,7 +80,7 @@ This error was caused by a Python bug on Windows. It's been fixed by [this PR](h More discussion can be found in issue [#318](https://github.com/commitizen-tools/commitizen/issues/318). -## Why does commitizen not support CalVer? +## Why does Commitizen not support CalVer? `commitizen` could support CalVer alongside SemVer, but in practice implementing CalVer creates numerous edge cases that are difficult to maintain ([#385]) and more generally, @@ -117,7 +117,7 @@ New bumped tags will be in the new format but old ones will still work for: So given if you change from `myproject-$version` to `${version}` and then `v${version}`, -your commitizen configuration will look like this: +your Commitizen configuration will look like this: ```toml tag_format = "v${version}" diff --git a/docs/third-party-commitizen.md b/docs/third-party-commitizen.md index e9eb822ed3..dc9b539c85 100644 --- a/docs/third-party-commitizen.md +++ b/docs/third-party-commitizen.md @@ -33,9 +33,9 @@ pip install conventional-JIRA ### [GitHub JIRA Conventional](https://pypi.org/project/cz-github-jira-conventional/) -This plugin extends the commitizen tools by: +This plugin extends the Commitizen tools by: -- requiring a JIRA issue id in the commit message +- requiring a JIRA issue ID in the commit message - creating links to GitHub commits in the CHANGELOG.md - creating links to JIRA issues in the CHANGELOG.md diff --git a/docs/tutorials/auto_prepare_commit_message.md b/docs/tutorials/auto_prepare_commit_message.md index 7e8295b7c8..84ac62b689 100644 --- a/docs/tutorials/auto_prepare_commit_message.md +++ b/docs/tutorials/auto_prepare_commit_message.md @@ -2,7 +2,7 @@ ## About -It can be desirable to use commitizen for all types of commits (i.e. regular, merge, +It can be desirable to use Commitizen for all types of commits (i.e. regular, merge, squash) so that the complete git history adheres to the commit message convention without ever having to call `cz commit`. @@ -18,10 +18,10 @@ To automatically perform arbitrary cleanup steps after a successful commit you c > This hook is invoked by git-commit. It takes no parameters, and is invoked after a > commit is made. -A combination of these two hooks allows for enforcing the usage of commitizen so that -whenever a commit is about to be created, commitizen is used for creating the commit +A combination of these two hooks allows for enforcing the usage of Commitizen so that +whenever a commit is about to be created, Commitizen is used for creating the commit message. Running `git commit` or `git commit -m "..."` for example, would trigger -commitizen and use the generated commit message for the commit. +Commitizen and use the generated commit message for the commit. ## Installation diff --git a/docs/tutorials/github_actions.md b/docs/tutorials/github_actions.md index 4f50aaf4e7..bf08eb3bc5 100644 --- a/docs/tutorials/github_actions.md +++ b/docs/tutorials/github_actions.md @@ -50,7 +50,7 @@ where to output the content of the changelog for the newly created version. And then add a step using a GitHub action to create the release: `softprops/action-gh-release` -The commitizen action creates an env variable called `REVISION`, containing the +Commitizen action creates an env variable called `REVISION`, containing the newly created version. ```yaml @@ -119,7 +119,7 @@ jobs: ./scripts/publish ``` -Notice that we are using poetry, and we are calling a bash script in `./scripts/publish`. You should configure the action, and publish with your tools (twine, poetry, etc.). Check [commitizen example](https://github.com/commitizen-tools/commitizen/blob/master/scripts/publish) +Notice that we are using poetry, and we are calling a bash script in `./scripts/publish`. You should configure the action, and publish with your tools (twine, poetry, etc.). Check [Commitizen example](https://github.com/commitizen-tools/commitizen/blob/master/scripts/publish) You can also use [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) to publish your package. Push the changes and that's it. diff --git a/docs/tutorials/monorepo_guidance.md b/docs/tutorials/monorepo_guidance.md index 434899f86f..6f15a87247 100644 --- a/docs/tutorials/monorepo_guidance.md +++ b/docs/tutorials/monorepo_guidance.md @@ -1,4 +1,4 @@ -# Configuring commitizen in a monorepo +# Configuring Commitizen in a monorepo This tutorial assumes the monorepo layout is designed with multiple components that can be released independently of each other, it also assumes that conventional commits with scopes are in use. Some suggested layouts: diff --git a/docs/tutorials/writing_commits.md b/docs/tutorials/writing_commits.md index d1b2c6645d..7d9139929c 100644 --- a/docs/tutorials/writing_commits.md +++ b/docs/tutorials/writing_commits.md @@ -1,6 +1,6 @@ For this project to work well in your pipeline, a commit convention must be followed. -By default, commitizen uses the known [conventional commits][conventional_commits], but +By default, Commitizen uses the known [conventional commits][conventional_commits], but you can create your own following the documentation information over at [customization][customization]. From f6280c88a14aabf30324a4d9901f4fee577debfc Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 18 May 2025 21:41:24 +0800 Subject: [PATCH 495/598] docs(README): update documentation site link text --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 9bb1555721..516b2a4863 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,7 +12,7 @@ --- -**Documentation:** [https://commitizen-tools.github.io/commitizen/](https://commitizen-tools.github.io/commitizen/) +[**Commitizen Documentation Site**](https://commitizen-tools.github.io/commitizen/) --- From ba1c9c0ce4cba699e61a2ab26d08d3159d0f3bdb Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 18 May 2025 21:46:08 +0800 Subject: [PATCH 496/598] docs(README): replace internal links with documentation site link --- docs/README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index 516b2a4863..078d6da06e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -42,11 +42,11 @@ This standardization makes your commit history more readable and meaningful, whi ### Features - Command-line utility to create commits with your rules. Defaults: [Conventional commits][conventional_commits] -- Bump version automatically using [semantic versioning][semver] based on the commits. [Read More](./commands/bump.md) +- Bump version automatically using [semantic versioning][semver] based on the commits. [Read More](https://commitizen-tools.github.io/commitizen/commands/bump/) - Generate a changelog using [Keep a changelog][keepchangelog] - Update your project's version files automatically - Display information about your commit rules (commands: schema, example, info) -- Create your own set of rules and publish them to pip. Read more on [Customization](./customization.md) +- Create your own set of rules and publish them to pip. Read more on [Customization](https://commitizen-tools.github.io/commitizen/customization/) ## Getting Started @@ -168,11 +168,11 @@ This command: - Updates version files You can customize: -- [Version files](./commands/bump.md#version_files) -- [Version scheme](./commands/bump.md#version_scheme) -- [Version provider](./config.md#version-providers) +- [Version files](https://commitizen-tools.github.io/commitizen/commands/bump/#version_files) +- [Version scheme](https://commitizen-tools.github.io/commitizen/commands/bump/#version_scheme) +- [Version provider](https://commitizen-tools.github.io/commitizen/config/#version-providers) -For all available options, see the [bump command documentation](./commands/bump.md). +For all available options, see the [bump command documentation](https://commitizen-tools.github.io/commitizen/commands/bump/). ### Advanced Usage @@ -219,7 +219,7 @@ pre-commit install --hook-type commit-msg --hook-type pre-push > pre-commit autoupdate > ``` -For more details about commit validation, see the [check command documentation](commands/check.md). +For more details about commit validation, see the [check command documentation](https://commitizen-tools.github.io/commitizen/commands/check/). ## Help & Reference @@ -243,9 +243,9 @@ Commitizen provides a comprehensive CLI with various commands. Here's the comple ### Additional Resources - [Conventional Commits Specification][conventional_commits] -- [Exit Codes Reference](./exit_codes.md) -- [Configuration Guide](./config.md) -- [Command Documentation](./commands/init.md) +- [Exit Codes Reference](https://commitizen-tools.github.io/commitizen/exit_codes/) +- [Configuration Guide](https://commitizen-tools.github.io/commitizen/config/) +- [Command Documentation](https://commitizen-tools.github.io/commitizen/commands/init/) ### Getting Help @@ -257,7 +257,7 @@ cz bump --help cz changelog --help ``` -For more detailed documentation, visit our [documentation site](https://commitizen-tools.github.io/commitizen/). +For more details, visit our [documentation site](https://commitizen-tools.github.io/commitizen/). ## Setting up bash completion From bb1539deb206d58f7b94c3b8ece268f8f34f287d Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 18 May 2025 21:57:02 +0800 Subject: [PATCH 497/598] docs(README): paraphase features --- docs/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index 078d6da06e..f730c17837 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,12 +41,13 @@ This standardization makes your commit history more readable and meaningful, whi ### Features -- Command-line utility to create commits with your rules. Defaults: [Conventional commits][conventional_commits] -- Bump version automatically using [semantic versioning][semver] based on the commits. [Read More](https://commitizen-tools.github.io/commitizen/commands/bump/) -- Generate a changelog using [Keep a changelog][keepchangelog] -- Update your project's version files automatically -- Display information about your commit rules (commands: schema, example, info) -- Create your own set of rules and publish them to pip. Read more on [Customization](https://commitizen-tools.github.io/commitizen/customization/) +- Interactive CLI for standardized commits with default [Conventional Commits][conventional_commits] support +- Intelligent [version bumping](https://commitizen-tools.github.io/commitizen/commands/bump/) using [Semantic Versioning][semver] +- Automatic [keep a changelog][keepchangelog] generation +- Built-in commit validation with pre-commit hooks +- [Customizable](https://commitizen-tools.github.io/commitizen/customization/) commit rules and templates +- Multi-format version file support +- Custom rules and plugins via pip ## Getting Started From 8e65b88288328dd794e9f8046f5b1164c9afb569 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 01:27:30 +0000 Subject: [PATCH 498/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz___help.svg | 172 +++++++++++++++-------------- 1 file changed, 88 insertions(+), 84 deletions(-) diff --git a/docs/images/cli_help/cz___help.svg b/docs/images/cli_help/cz___help.svg index 098e7df70d..d580cfe619 100644 --- a/docs/images/cli_help/cz___help.svg +++ b/docs/images/cli_help/cz___help.svg @@ -1,4 +1,4 @@ -<svg class="rich-terminal" viewBox="0 0 994 928.4" xmlns="http://www.w3.org/2000/svg"> +<svg class="rich-terminal" viewBox="0 0 994 952.8" xmlns="http://www.w3.org/2000/svg"> <!-- Generated with Rich https://www.textualize.io --> <style> @@ -19,183 +19,187 @@ font-weight: 700; } - .terminal-2205183093-matrix { + .terminal-1389600277-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2205183093-title { + .terminal-1389600277-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2205183093-r1 { fill: #c5c8c6 } -.terminal-2205183093-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-2205183093-r3 { fill: #d0b344 } -.terminal-2205183093-r4 { fill: #1984e9;text-decoration: underline; } -.terminal-2205183093-r5 { fill: #68a0b3;font-weight: bold } + .terminal-1389600277-r1 { fill: #c5c8c6 } +.terminal-1389600277-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-1389600277-r3 { fill: #d0b344 } +.terminal-1389600277-r4 { fill: #1984e9;text-decoration: underline; } +.terminal-1389600277-r5 { fill: #68a0b3;font-weight: bold } </style> <defs> - <clipPath id="terminal-2205183093-clip-terminal"> - <rect x="0" y="0" width="975.0" height="877.4" /> + <clipPath id="terminal-1389600277-clip-terminal"> + <rect x="0" y="0" width="975.0" height="901.8" /> </clipPath> - <clipPath id="terminal-2205183093-line-0"> + <clipPath id="terminal-1389600277-line-0"> <rect x="0" y="1.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-1"> +<clipPath id="terminal-1389600277-line-1"> <rect x="0" y="25.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-2"> +<clipPath id="terminal-1389600277-line-2"> <rect x="0" y="50.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-3"> +<clipPath id="terminal-1389600277-line-3"> <rect x="0" y="74.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-4"> +<clipPath id="terminal-1389600277-line-4"> <rect x="0" y="99.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-5"> +<clipPath id="terminal-1389600277-line-5"> <rect x="0" y="123.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-6"> +<clipPath id="terminal-1389600277-line-6"> <rect x="0" y="147.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-7"> +<clipPath id="terminal-1389600277-line-7"> <rect x="0" y="172.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-8"> +<clipPath id="terminal-1389600277-line-8"> <rect x="0" y="196.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-9"> +<clipPath id="terminal-1389600277-line-9"> <rect x="0" y="221.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-10"> +<clipPath id="terminal-1389600277-line-10"> <rect x="0" y="245.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-11"> +<clipPath id="terminal-1389600277-line-11"> <rect x="0" y="269.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-12"> +<clipPath id="terminal-1389600277-line-12"> <rect x="0" y="294.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-13"> +<clipPath id="terminal-1389600277-line-13"> <rect x="0" y="318.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-14"> +<clipPath id="terminal-1389600277-line-14"> <rect x="0" y="343.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-15"> +<clipPath id="terminal-1389600277-line-15"> <rect x="0" y="367.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-16"> +<clipPath id="terminal-1389600277-line-16"> <rect x="0" y="391.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-17"> +<clipPath id="terminal-1389600277-line-17"> <rect x="0" y="416.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-18"> +<clipPath id="terminal-1389600277-line-18"> <rect x="0" y="440.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-19"> +<clipPath id="terminal-1389600277-line-19"> <rect x="0" y="465.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-20"> +<clipPath id="terminal-1389600277-line-20"> <rect x="0" y="489.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-21"> +<clipPath id="terminal-1389600277-line-21"> <rect x="0" y="513.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-22"> +<clipPath id="terminal-1389600277-line-22"> <rect x="0" y="538.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-23"> +<clipPath id="terminal-1389600277-line-23"> <rect x="0" y="562.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-24"> +<clipPath id="terminal-1389600277-line-24"> <rect x="0" y="587.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-25"> +<clipPath id="terminal-1389600277-line-25"> <rect x="0" y="611.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-26"> +<clipPath id="terminal-1389600277-line-26"> <rect x="0" y="635.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-27"> +<clipPath id="terminal-1389600277-line-27"> <rect x="0" y="660.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-28"> +<clipPath id="terminal-1389600277-line-28"> <rect x="0" y="684.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-29"> +<clipPath id="terminal-1389600277-line-29"> <rect x="0" y="709.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-30"> +<clipPath id="terminal-1389600277-line-30"> <rect x="0" y="733.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-31"> +<clipPath id="terminal-1389600277-line-31"> <rect x="0" y="757.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-32"> +<clipPath id="terminal-1389600277-line-32"> <rect x="0" y="782.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-33"> +<clipPath id="terminal-1389600277-line-33"> <rect x="0" y="806.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-2205183093-line-34"> +<clipPath id="terminal-1389600277-line-34"> <rect x="0" y="831.1" width="976" height="24.65"/> </clipPath> +<clipPath id="terminal-1389600277-line-35"> + <rect x="0" y="855.5" width="976" height="24.65"/> + </clipPath> </defs> - <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="992" height="926.4" rx="8"/> + <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="992" height="950.8" rx="8"/> <g transform="translate(26,22)"> <circle cx="0" cy="0" r="7" fill="#ff5f57"/> <circle cx="22" cy="0" r="7" fill="#febc2e"/> <circle cx="44" cy="0" r="7" fill="#28c840"/> </g> - <g transform="translate(9, 41)" clip-path="url(#terminal-2205183093-clip-terminal)"> + <g transform="translate(9, 41)" clip-path="url(#terminal-1389600277-clip-terminal)"> - <g class="terminal-2205183093-matrix"> - <text class="terminal-2205183093-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-2205183093-line-0)">$ cz --help</text><text class="terminal-2205183093-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-2205183093-line-0)"> -</text><text class="terminal-2205183093-r1" x="0" y="44.4" textLength="122" clip-path="url(#terminal-2205183093-line-1)">usage: cz </text><text class="terminal-2205183093-r2" x="122" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">[</text><text class="terminal-2205183093-r1" x="134.2" y="44.4" textLength="24.4" clip-path="url(#terminal-2205183093-line-1)">-h</text><text class="terminal-2205183093-r2" x="158.6" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">]</text><text class="terminal-2205183093-r2" x="183" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">[</text><text class="terminal-2205183093-r1" x="195.2" y="44.4" textLength="183" clip-path="url(#terminal-2205183093-line-1)">--config CONFIG</text><text class="terminal-2205183093-r2" x="378.2" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">]</text><text class="terminal-2205183093-r2" x="402.6" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">[</text><text class="terminal-2205183093-r1" x="414.8" y="44.4" textLength="85.4" clip-path="url(#terminal-2205183093-line-1)">--debug</text><text class="terminal-2205183093-r2" x="500.2" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">]</text><text class="terminal-2205183093-r2" x="524.6" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">[</text><text class="terminal-2205183093-r1" x="536.8" y="44.4" textLength="85.4" clip-path="url(#terminal-2205183093-line-1)">-n NAME</text><text class="terminal-2205183093-r2" x="622.2" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">]</text><text class="terminal-2205183093-r2" x="646.6" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">[</text><text class="terminal-2205183093-r1" x="658.8" y="44.4" textLength="146.4" clip-path="url(#terminal-2205183093-line-1)">-nr NO_RAISE</text><text class="terminal-2205183093-r2" x="805.2" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)">]</text><text class="terminal-2205183093-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-1)"> -</text><text class="terminal-2205183093-r2" x="122" y="68.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-2)">{</text><text class="terminal-2205183093-r1" x="134.2" y="68.8" textLength="829.6" clip-path="url(#terminal-2205183093-line-2)">init,commit,c,ls,example,info,schema,bump,changelog,ch,check,version</text><text class="terminal-2205183093-r2" x="963.8" y="68.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-2)">}</text><text class="terminal-2205183093-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-2)"> -</text><text class="terminal-2205183093-r3" x="0" y="93.2" textLength="36.6" clip-path="url(#terminal-2205183093-line-3)">...</text><text class="terminal-2205183093-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-3)"> -</text><text class="terminal-2205183093-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-4)"> -</text><text class="terminal-2205183093-r1" x="0" y="142" textLength="707.6" clip-path="url(#terminal-2205183093-line-5)">Commitizen is a cli tool to generate conventional commits.</text><text class="terminal-2205183093-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-2205183093-line-5)"> -</text><text class="terminal-2205183093-r1" x="0" y="166.4" textLength="524.6" clip-path="url(#terminal-2205183093-line-6)">For more information about the topic go to </text><text class="terminal-2205183093-r4" x="524.6" y="166.4" textLength="390.4" clip-path="url(#terminal-2205183093-line-6)">https://conventionalcommits.org/</text><text class="terminal-2205183093-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-6)"> -</text><text class="terminal-2205183093-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-7)"> -</text><text class="terminal-2205183093-r1" x="0" y="215.2" textLength="97.6" clip-path="url(#terminal-2205183093-line-8)">options:</text><text class="terminal-2205183093-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-8)"> -</text><text class="terminal-2205183093-r1" x="0" y="239.6" textLength="671" clip-path="url(#terminal-2205183093-line-9)">  -h, --help            show this help message and exit</text><text class="terminal-2205183093-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-9)"> -</text><text class="terminal-2205183093-r1" x="0" y="264" textLength="658.8" clip-path="url(#terminal-2205183093-line-10)">  --config CONFIG       the path of configuration file</text><text class="terminal-2205183093-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-2205183093-line-10)"> -</text><text class="terminal-2205183093-r1" x="0" y="288.4" textLength="463.6" clip-path="url(#terminal-2205183093-line-11)">  --debug               use debug mode</text><text class="terminal-2205183093-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-11)"> -</text><text class="terminal-2205183093-r1" x="0" y="312.8" textLength="597.8" clip-path="url(#terminal-2205183093-line-12)">  -n, --name NAME       use the given commitizen </text><text class="terminal-2205183093-r2" x="597.8" y="312.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-12)">(</text><text class="terminal-2205183093-r1" x="610" y="312.8" textLength="97.6" clip-path="url(#terminal-2205183093-line-12)">default:</text><text class="terminal-2205183093-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-12)"> -</text><text class="terminal-2205183093-r1" x="0" y="337.2" textLength="573.4" clip-path="url(#terminal-2205183093-line-13)">                        cz_conventional_commits</text><text class="terminal-2205183093-r2" x="573.4" y="337.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-13)">)</text><text class="terminal-2205183093-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-13)"> -</text><text class="terminal-2205183093-r1" x="0" y="361.6" textLength="317.2" clip-path="url(#terminal-2205183093-line-14)">  -nr, --no-raise NO_RAISE</text><text class="terminal-2205183093-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-14)"> -</text><text class="terminal-2205183093-r1" x="0" y="386" textLength="902.8" clip-path="url(#terminal-2205183093-line-15)">                        comma separated error codes that won't rise error,</text><text class="terminal-2205183093-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-2205183093-line-15)"> -</text><text class="terminal-2205183093-r1" x="0" y="410.4" textLength="439.2" clip-path="url(#terminal-2205183093-line-16)">                        e.g: cz -nr </text><text class="terminal-2205183093-r5" x="439.2" y="410.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-16)">1</text><text class="terminal-2205183093-r1" x="451.4" y="410.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-16)">,</text><text class="terminal-2205183093-r5" x="463.6" y="410.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-16)">2</text><text class="terminal-2205183093-r1" x="475.8" y="410.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-16)">,</text><text class="terminal-2205183093-r5" x="488" y="410.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-16)">3</text><text class="terminal-2205183093-r1" x="500.2" y="410.4" textLength="231.8" clip-path="url(#terminal-2205183093-line-16)"> bump. See codes at</text><text class="terminal-2205183093-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-16)"> -</text><text class="terminal-2205183093-r4" x="292.8" y="434.8" textLength="231.8" clip-path="url(#terminal-2205183093-line-17)">https://commitizen-</text><text class="terminal-2205183093-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-17)"> -</text><text class="terminal-2205183093-r1" x="0" y="459.2" textLength="756.4" clip-path="url(#terminal-2205183093-line-18)">                        tools.github.io/commitizen/exit_codes/</text><text class="terminal-2205183093-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-18)"> -</text><text class="terminal-2205183093-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-19)"> -</text><text class="terminal-2205183093-r1" x="0" y="508" textLength="109.8" clip-path="url(#terminal-2205183093-line-20)">commands:</text><text class="terminal-2205183093-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-2205183093-line-20)"> -</text><text class="terminal-2205183093-r2" x="24.4" y="532.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-21)">{</text><text class="terminal-2205183093-r1" x="36.6" y="532.4" textLength="829.6" clip-path="url(#terminal-2205183093-line-21)">init,commit,c,ls,example,info,schema,bump,changelog,ch,check,version</text><text class="terminal-2205183093-r2" x="866.2" y="532.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-21)">}</text><text class="terminal-2205183093-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-21)"> -</text><text class="terminal-2205183093-r1" x="0" y="556.8" textLength="646.6" clip-path="url(#terminal-2205183093-line-22)">    init                init commitizen configuration</text><text class="terminal-2205183093-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-22)"> -</text><text class="terminal-2205183093-r1" x="0" y="581.2" textLength="134.2" clip-path="url(#terminal-2205183093-line-23)">    commit </text><text class="terminal-2205183093-r2" x="134.2" y="581.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-23)">(</text><text class="terminal-2205183093-r1" x="146.4" y="581.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-23)">c</text><text class="terminal-2205183093-r2" x="158.6" y="581.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-23)">)</text><text class="terminal-2205183093-r1" x="170.8" y="581.2" textLength="329.4" clip-path="url(#terminal-2205183093-line-23)">          create new commit</text><text class="terminal-2205183093-r1" x="976" y="581.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-23)"> -</text><text class="terminal-2205183093-r1" x="0" y="605.6" textLength="610" clip-path="url(#terminal-2205183093-line-24)">    ls                  show available commitizens</text><text class="terminal-2205183093-r1" x="976" y="605.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-24)"> -</text><text class="terminal-2205183093-r1" x="0" y="630" textLength="524.6" clip-path="url(#terminal-2205183093-line-25)">    example             show commit example</text><text class="terminal-2205183093-r1" x="976" y="630" textLength="12.2" clip-path="url(#terminal-2205183093-line-25)"> -</text><text class="terminal-2205183093-r1" x="0" y="654.4" textLength="646.6" clip-path="url(#terminal-2205183093-line-26)">    info                show information about the cz</text><text class="terminal-2205183093-r1" x="976" y="654.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-26)"> -</text><text class="terminal-2205183093-r1" x="0" y="678.8" textLength="512.4" clip-path="url(#terminal-2205183093-line-27)">    schema              show commit schema</text><text class="terminal-2205183093-r1" x="976" y="678.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-27)"> -</text><text class="terminal-2205183093-r1" x="0" y="703.2" textLength="805.2" clip-path="url(#terminal-2205183093-line-28)">    bump                bump semantic version based on the git log</text><text class="terminal-2205183093-r1" x="976" y="703.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-28)"> -</text><text class="terminal-2205183093-r1" x="0" y="727.6" textLength="170.8" clip-path="url(#terminal-2205183093-line-29)">    changelog </text><text class="terminal-2205183093-r2" x="170.8" y="727.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-29)">(</text><text class="terminal-2205183093-r1" x="183" y="727.6" textLength="24.4" clip-path="url(#terminal-2205183093-line-29)">ch</text><text class="terminal-2205183093-r2" x="207.4" y="727.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-29)">)</text><text class="terminal-2205183093-r1" x="219.6" y="727.6" textLength="305" clip-path="url(#terminal-2205183093-line-29)">      generate changelog </text><text class="terminal-2205183093-r2" x="524.6" y="727.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-29)">(</text><text class="terminal-2205183093-r1" x="536.8" y="727.6" textLength="329.4" clip-path="url(#terminal-2205183093-line-29)">note that it will overwrite</text><text class="terminal-2205183093-r1" x="976" y="727.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-29)"> -</text><text class="terminal-2205183093-r1" x="0" y="752" textLength="451.4" clip-path="url(#terminal-2205183093-line-30)">                        existing file</text><text class="terminal-2205183093-r2" x="451.4" y="752" textLength="12.2" clip-path="url(#terminal-2205183093-line-30)">)</text><text class="terminal-2205183093-r1" x="976" y="752" textLength="12.2" clip-path="url(#terminal-2205183093-line-30)"> -</text><text class="terminal-2205183093-r1" x="0" y="776.4" textLength="951.6" clip-path="url(#terminal-2205183093-line-31)">    check               validates that a commit message matches the commitizen</text><text class="terminal-2205183093-r1" x="976" y="776.4" textLength="12.2" clip-path="url(#terminal-2205183093-line-31)"> -</text><text class="terminal-2205183093-r1" x="0" y="800.8" textLength="366" clip-path="url(#terminal-2205183093-line-32)">                        schema</text><text class="terminal-2205183093-r1" x="976" y="800.8" textLength="12.2" clip-path="url(#terminal-2205183093-line-32)"> -</text><text class="terminal-2205183093-r1" x="0" y="825.2" textLength="902.8" clip-path="url(#terminal-2205183093-line-33)">    version             get the version of the installed commitizen or the</text><text class="terminal-2205183093-r1" x="976" y="825.2" textLength="12.2" clip-path="url(#terminal-2205183093-line-33)"> -</text><text class="terminal-2205183093-r1" x="0" y="849.6" textLength="488" clip-path="url(#terminal-2205183093-line-34)">                        current project </text><text class="terminal-2205183093-r2" x="488" y="849.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-34)">(</text><text class="terminal-2205183093-r1" x="500.2" y="849.6" textLength="353.8" clip-path="url(#terminal-2205183093-line-34)">default: installed commitizen</text><text class="terminal-2205183093-r2" x="854" y="849.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-34)">)</text><text class="terminal-2205183093-r1" x="976" y="849.6" textLength="12.2" clip-path="url(#terminal-2205183093-line-34)"> -</text><text class="terminal-2205183093-r1" x="976" y="874" textLength="12.2" clip-path="url(#terminal-2205183093-line-35)"> + <g class="terminal-1389600277-matrix"> + <text class="terminal-1389600277-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-1389600277-line-0)">$ cz --help</text><text class="terminal-1389600277-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-1389600277-line-0)"> +</text><text class="terminal-1389600277-r1" x="0" y="44.4" textLength="122" clip-path="url(#terminal-1389600277-line-1)">usage: cz </text><text class="terminal-1389600277-r2" x="122" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">[</text><text class="terminal-1389600277-r1" x="134.2" y="44.4" textLength="24.4" clip-path="url(#terminal-1389600277-line-1)">-h</text><text class="terminal-1389600277-r2" x="158.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">]</text><text class="terminal-1389600277-r2" x="183" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">[</text><text class="terminal-1389600277-r1" x="195.2" y="44.4" textLength="183" clip-path="url(#terminal-1389600277-line-1)">--config CONFIG</text><text class="terminal-1389600277-r2" x="378.2" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">]</text><text class="terminal-1389600277-r2" x="402.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">[</text><text class="terminal-1389600277-r1" x="414.8" y="44.4" textLength="85.4" clip-path="url(#terminal-1389600277-line-1)">--debug</text><text class="terminal-1389600277-r2" x="500.2" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">]</text><text class="terminal-1389600277-r2" x="524.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">[</text><text class="terminal-1389600277-r1" x="536.8" y="44.4" textLength="85.4" clip-path="url(#terminal-1389600277-line-1)">-n NAME</text><text class="terminal-1389600277-r2" x="622.2" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">]</text><text class="terminal-1389600277-r2" x="646.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">[</text><text class="terminal-1389600277-r1" x="658.8" y="44.4" textLength="146.4" clip-path="url(#terminal-1389600277-line-1)">-nr NO_RAISE</text><text class="terminal-1389600277-r2" x="805.2" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)">]</text><text class="terminal-1389600277-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-1)"> +</text><text class="terminal-1389600277-r2" x="122" y="68.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-2)">{</text><text class="terminal-1389600277-r1" x="134.2" y="68.8" textLength="829.6" clip-path="url(#terminal-1389600277-line-2)">init,commit,c,ls,example,info,schema,bump,changelog,ch,check,version</text><text class="terminal-1389600277-r2" x="963.8" y="68.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-2)">}</text><text class="terminal-1389600277-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-2)"> +</text><text class="terminal-1389600277-r3" x="0" y="93.2" textLength="36.6" clip-path="url(#terminal-1389600277-line-3)">...</text><text class="terminal-1389600277-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-1389600277-line-3)"> +</text><text class="terminal-1389600277-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-4)"> +</text><text class="terminal-1389600277-r1" x="0" y="142" textLength="915" clip-path="url(#terminal-1389600277-line-5)">Commitizen is a powerful release management tool that helps teams maintain </text><text class="terminal-1389600277-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-1389600277-line-5)"> +</text><text class="terminal-1389600277-r1" x="0" y="166.4" textLength="951.6" clip-path="url(#terminal-1389600277-line-6)">consistent and meaningful commit messages while automating version management.</text><text class="terminal-1389600277-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-6)"> +</text><text class="terminal-1389600277-r1" x="0" y="190.8" textLength="427" clip-path="url(#terminal-1389600277-line-7)">For more information, please visit </text><text class="terminal-1389600277-r4" x="427" y="190.8" textLength="549" clip-path="url(#terminal-1389600277-line-7)">https://commitizen-tools.github.io/commitizen</text><text class="terminal-1389600277-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-7)"> +</text><text class="terminal-1389600277-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-1389600277-line-8)"> +</text><text class="terminal-1389600277-r1" x="0" y="239.6" textLength="97.6" clip-path="url(#terminal-1389600277-line-9)">options:</text><text class="terminal-1389600277-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-9)"> +</text><text class="terminal-1389600277-r1" x="0" y="264" textLength="671" clip-path="url(#terminal-1389600277-line-10)">  -h, --help            show this help message and exit</text><text class="terminal-1389600277-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-1389600277-line-10)"> +</text><text class="terminal-1389600277-r1" x="0" y="288.4" textLength="658.8" clip-path="url(#terminal-1389600277-line-11)">  --config CONFIG       the path of configuration file</text><text class="terminal-1389600277-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-11)"> +</text><text class="terminal-1389600277-r1" x="0" y="312.8" textLength="463.6" clip-path="url(#terminal-1389600277-line-12)">  --debug               use debug mode</text><text class="terminal-1389600277-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-12)"> +</text><text class="terminal-1389600277-r1" x="0" y="337.2" textLength="597.8" clip-path="url(#terminal-1389600277-line-13)">  -n, --name NAME       use the given commitizen </text><text class="terminal-1389600277-r2" x="597.8" y="337.2" textLength="12.2" clip-path="url(#terminal-1389600277-line-13)">(</text><text class="terminal-1389600277-r1" x="610" y="337.2" textLength="97.6" clip-path="url(#terminal-1389600277-line-13)">default:</text><text class="terminal-1389600277-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-1389600277-line-13)"> +</text><text class="terminal-1389600277-r1" x="0" y="361.6" textLength="573.4" clip-path="url(#terminal-1389600277-line-14)">                        cz_conventional_commits</text><text class="terminal-1389600277-r2" x="573.4" y="361.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-14)">)</text><text class="terminal-1389600277-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-14)"> +</text><text class="terminal-1389600277-r1" x="0" y="386" textLength="317.2" clip-path="url(#terminal-1389600277-line-15)">  -nr, --no-raise NO_RAISE</text><text class="terminal-1389600277-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-1389600277-line-15)"> +</text><text class="terminal-1389600277-r1" x="0" y="410.4" textLength="915" clip-path="url(#terminal-1389600277-line-16)">                        comma separated error codes that won't raise error,</text><text class="terminal-1389600277-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-16)"> +</text><text class="terminal-1389600277-r1" x="0" y="434.8" textLength="439.2" clip-path="url(#terminal-1389600277-line-17)">                        e.g: cz -nr </text><text class="terminal-1389600277-r5" x="439.2" y="434.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-17)">1</text><text class="terminal-1389600277-r1" x="451.4" y="434.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-17)">,</text><text class="terminal-1389600277-r5" x="463.6" y="434.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-17)">2</text><text class="terminal-1389600277-r1" x="475.8" y="434.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-17)">,</text><text class="terminal-1389600277-r5" x="488" y="434.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-17)">3</text><text class="terminal-1389600277-r1" x="500.2" y="434.8" textLength="231.8" clip-path="url(#terminal-1389600277-line-17)"> bump. See codes at</text><text class="terminal-1389600277-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-17)"> +</text><text class="terminal-1389600277-r4" x="292.8" y="459.2" textLength="231.8" clip-path="url(#terminal-1389600277-line-18)">https://commitizen-</text><text class="terminal-1389600277-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-1389600277-line-18)"> +</text><text class="terminal-1389600277-r1" x="0" y="483.6" textLength="756.4" clip-path="url(#terminal-1389600277-line-19)">                        tools.github.io/commitizen/exit_codes/</text><text class="terminal-1389600277-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-19)"> +</text><text class="terminal-1389600277-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-1389600277-line-20)"> +</text><text class="terminal-1389600277-r1" x="0" y="532.4" textLength="109.8" clip-path="url(#terminal-1389600277-line-21)">commands:</text><text class="terminal-1389600277-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-21)"> +</text><text class="terminal-1389600277-r2" x="24.4" y="556.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-22)">{</text><text class="terminal-1389600277-r1" x="36.6" y="556.8" textLength="829.6" clip-path="url(#terminal-1389600277-line-22)">init,commit,c,ls,example,info,schema,bump,changelog,ch,check,version</text><text class="terminal-1389600277-r2" x="866.2" y="556.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-22)">}</text><text class="terminal-1389600277-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-22)"> +</text><text class="terminal-1389600277-r1" x="0" y="581.2" textLength="646.6" clip-path="url(#terminal-1389600277-line-23)">    init                init commitizen configuration</text><text class="terminal-1389600277-r1" x="976" y="581.2" textLength="12.2" clip-path="url(#terminal-1389600277-line-23)"> +</text><text class="terminal-1389600277-r1" x="0" y="605.6" textLength="134.2" clip-path="url(#terminal-1389600277-line-24)">    commit </text><text class="terminal-1389600277-r2" x="134.2" y="605.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-24)">(</text><text class="terminal-1389600277-r1" x="146.4" y="605.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-24)">c</text><text class="terminal-1389600277-r2" x="158.6" y="605.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-24)">)</text><text class="terminal-1389600277-r1" x="170.8" y="605.6" textLength="329.4" clip-path="url(#terminal-1389600277-line-24)">          create new commit</text><text class="terminal-1389600277-r1" x="976" y="605.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-24)"> +</text><text class="terminal-1389600277-r1" x="0" y="630" textLength="610" clip-path="url(#terminal-1389600277-line-25)">    ls                  show available commitizens</text><text class="terminal-1389600277-r1" x="976" y="630" textLength="12.2" clip-path="url(#terminal-1389600277-line-25)"> +</text><text class="terminal-1389600277-r1" x="0" y="654.4" textLength="524.6" clip-path="url(#terminal-1389600277-line-26)">    example             show commit example</text><text class="terminal-1389600277-r1" x="976" y="654.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-26)"> +</text><text class="terminal-1389600277-r1" x="0" y="678.8" textLength="646.6" clip-path="url(#terminal-1389600277-line-27)">    info                show information about the cz</text><text class="terminal-1389600277-r1" x="976" y="678.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-27)"> +</text><text class="terminal-1389600277-r1" x="0" y="703.2" textLength="512.4" clip-path="url(#terminal-1389600277-line-28)">    schema              show commit schema</text><text class="terminal-1389600277-r1" x="976" y="703.2" textLength="12.2" clip-path="url(#terminal-1389600277-line-28)"> +</text><text class="terminal-1389600277-r1" x="0" y="727.6" textLength="805.2" clip-path="url(#terminal-1389600277-line-29)">    bump                bump semantic version based on the git log</text><text class="terminal-1389600277-r1" x="976" y="727.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-29)"> +</text><text class="terminal-1389600277-r1" x="0" y="752" textLength="170.8" clip-path="url(#terminal-1389600277-line-30)">    changelog </text><text class="terminal-1389600277-r2" x="170.8" y="752" textLength="12.2" clip-path="url(#terminal-1389600277-line-30)">(</text><text class="terminal-1389600277-r1" x="183" y="752" textLength="24.4" clip-path="url(#terminal-1389600277-line-30)">ch</text><text class="terminal-1389600277-r2" x="207.4" y="752" textLength="12.2" clip-path="url(#terminal-1389600277-line-30)">)</text><text class="terminal-1389600277-r1" x="219.6" y="752" textLength="305" clip-path="url(#terminal-1389600277-line-30)">      generate changelog </text><text class="terminal-1389600277-r2" x="524.6" y="752" textLength="12.2" clip-path="url(#terminal-1389600277-line-30)">(</text><text class="terminal-1389600277-r1" x="536.8" y="752" textLength="329.4" clip-path="url(#terminal-1389600277-line-30)">note that it will overwrite</text><text class="terminal-1389600277-r1" x="976" y="752" textLength="12.2" clip-path="url(#terminal-1389600277-line-30)"> +</text><text class="terminal-1389600277-r1" x="0" y="776.4" textLength="451.4" clip-path="url(#terminal-1389600277-line-31)">                        existing file</text><text class="terminal-1389600277-r2" x="451.4" y="776.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-31)">)</text><text class="terminal-1389600277-r1" x="976" y="776.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-31)"> +</text><text class="terminal-1389600277-r1" x="0" y="800.8" textLength="951.6" clip-path="url(#terminal-1389600277-line-32)">    check               validates that a commit message matches the commitizen</text><text class="terminal-1389600277-r1" x="976" y="800.8" textLength="12.2" clip-path="url(#terminal-1389600277-line-32)"> +</text><text class="terminal-1389600277-r1" x="0" y="825.2" textLength="366" clip-path="url(#terminal-1389600277-line-33)">                        schema</text><text class="terminal-1389600277-r1" x="976" y="825.2" textLength="12.2" clip-path="url(#terminal-1389600277-line-33)"> +</text><text class="terminal-1389600277-r1" x="0" y="849.6" textLength="902.8" clip-path="url(#terminal-1389600277-line-34)">    version             get the version of the installed commitizen or the</text><text class="terminal-1389600277-r1" x="976" y="849.6" textLength="12.2" clip-path="url(#terminal-1389600277-line-34)"> +</text><text class="terminal-1389600277-r1" x="0" y="874" textLength="488" clip-path="url(#terminal-1389600277-line-35)">                        current project </text><text class="terminal-1389600277-r2" x="488" y="874" textLength="12.2" clip-path="url(#terminal-1389600277-line-35)">(</text><text class="terminal-1389600277-r1" x="500.2" y="874" textLength="353.8" clip-path="url(#terminal-1389600277-line-35)">default: installed commitizen</text><text class="terminal-1389600277-r2" x="854" y="874" textLength="12.2" clip-path="url(#terminal-1389600277-line-35)">)</text><text class="terminal-1389600277-r1" x="976" y="874" textLength="12.2" clip-path="url(#terminal-1389600277-line-35)"> +</text><text class="terminal-1389600277-r1" x="976" y="898.4" textLength="12.2" clip-path="url(#terminal-1389600277-line-36)"> </text> </g> </g> From aaa64aca07db9acd52ee069fc4abb572524e0cf4 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 24 May 2025 00:56:51 +0800 Subject: [PATCH 499/598] docs(faq): add features we wont add Closes #1129 --- docs/faq.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/faq.md b/docs/faq.md index ceabac2e10..920f533d73 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,3 +1,11 @@ +## Features we won't add + +For a comprehensive list of features that have been considered but won't be implemented, please refer to our [issue tracker](https://github.com/commitizen-tools/commitizen/issues?q=is:issue%20state:closed%20label:%22issue-status:%20wont-fix%22%20OR%20label:%22issue-status:%20wont-implement%22). + +- Enable multiple locations of config file `.cz.*` [#955](https://github.com/commitizen-tools/commitizen/issues/955) +- Create a flag to build the changelog from commits in multiple git repositories [#790](https://github.com/commitizen-tools/commitizen/issues/790) +- Global Configuration [#597](https://github.com/commitizen-tools/commitizen/issues/597) + ## Support for PEP621 PEP621 establishes a `[project]` definition inside `pyproject.toml` From 3560156e518416846baec3cd7d3b772a7478ffb8 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 24 May 2025 01:17:32 +0800 Subject: [PATCH 500/598] docs(bump): rewrite bump about section, fix incorrect version increment rules Closes #781 --- docs/commands/bump.md | 92 ++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 32 deletions(-) diff --git a/docs/commands/bump.md b/docs/commands/bump.md index ee3d77430a..d399ec9eb8 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -2,51 +2,79 @@ ## About -`cz bump` **automatically** increases the version, based on the commits. +`cz bump` is a powerful command that **automatically** determines and increases your project's version number based on your commit history. It analyzes your commits to determine the appropriate version increment according to semantic versioning principles. -The commits should follow the rules established by the committer in order to be parsed correctly. +### Key Features -**prerelease** versions are supported (alpha, beta, release candidate). +- **Automatic Version Detection**: Analyzes commit history to determine the appropriate version bump +- **Manual Version Control**: Supports manual version specification when needed +- **Pre-release Support**: Handles alpha, beta, and release candidate versions +- **Multiple Version Schemes**: Supports both [PEP 0440][pep440] and [semantic versioning][semver] formats -The version can also be **manually** bumped. +### Version Increment Rules -The version format follows [PEP 0440][pep440] and [semantic versioning][semver]. - -This means `MAJOR.MINOR.PATCH` +The version follows the `MAJOR.MINOR.PATCH` format, with increments determined by your commit types: | Increment | Description | Conventional commit map | | --------- | --------------------------- | ----------------------- | -| `MAJOR` | Breaking changes introduced | `BREAKING CHANGE` | +| `MAJOR` | Breaking changes introduced | `BREAKING CHANGE`, bang (e.g. `feat!`)| | `MINOR` | New features | `feat` | -| `PATCH` | Fixes | `fix` + everything else | +| `PATCH` | Fixes and improvements | `fix`, `perf`, `refactor`| + +### Version Schemes -[PEP 0440][pep440] is the default, you can switch by using the setting `version_scheme` or the cli: +By default, Commitizen uses [PEP 0440][pep440] for version formatting. You can switch to semantic versioning using either: +1. Command line: ```sh cz bump --version-scheme semver ``` -Some examples of pep440: +2. Configuration file: +```toml +[tool.commitizen] +version_scheme = "semver" +``` -```bash -0.9.0 -0.9.1 -0.9.2 -0.9.10 -0.9.11 -1.0.0a0 # alpha -1.0.0a1 -1.0.0b0 # beta -1.0.0rc0 # release candidate -1.0.0rc1 -1.0.0 -1.0.1 -1.1.0 -2.0.0 -2.0.1a -``` - -`post` releases are not supported yet. +### PEP440 Version Examples + +Commitizen supports the [PEP 440][pep440] version format, which includes several version types. Here are examples of each: + +#### Standard Releases +```text +0.9.0 # Initial development release +0.9.1 # Patch release +0.9.2 # Another patch release +0.9.10 # Tenth patch release +0.9.11 # Eleventh patch release +1.0.0 # First stable release +1.0.1 # Patch release after stable +1.1.0 # Minor feature release +2.0.0 # Major version release +``` + +#### Pre-releases +```text +1.0.0a0 # Alpha release 0 +1.0.0a1 # Alpha release 1 +1.0.0b0 # Beta release 0 +1.0.0rc0 # Release candidate 0 +1.0.0rc1 # Release candidate 1 +``` + +#### Development Releases +```text +1.0.0.dev0 # Development release 0 +1.0.0.dev1 # Development release 1 +``` + +#### Combined Pre-release and Development +```text +1.0.0a1.dev0 # Development release 0 of alpha 1 +1.0.0b2.dev1 # Development release 1 of beta 2 +``` + +> **Note**: `post` releases (e.g., `1.0.0.post1`) are not currently supported. ## Usage @@ -97,7 +125,7 @@ by their precedence and showcase how a release might flow through a development By default, `--increment-mode` is set to `linear`, which ensures that bumping pre-releases _maintains linearity_: bumping of a pre-release with lower precedence than the current pre-release phase maintains the current phase of higher precedence. For example, if the current version is `1.0.0b1` then bumping with `--prerelease alpha` will -continue to bump the “beta” phase. +continue to bump the "beta" phase. Setting `--increment-mode` to `exact` instructs `cz bump` to instead apply the exact changes that have been specified with `--increment` or determined from the commit log. For example, @@ -223,7 +251,7 @@ If used together with a manual version the command also fails. We recommend setting `major_version_zero = true` in your configuration file while a project is in its initial development. Remove that configuration using a breaking-change commit to bump -your project’s major version to `v1.0.0` once your project has reached maturity. +your project's major version to `v1.0.0` once your project has reached maturity. ### `--version-scheme` From 08ced5dbfc6a3283be7cfac87afb86a652069622 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 28 May 2025 18:04:31 +0800 Subject: [PATCH 501/598] docs(README): fix broken bullet points --- docs/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/README.md b/docs/README.md index f730c17837..31f2a77d15 100644 --- a/docs/README.md +++ b/docs/README.md @@ -163,12 +163,14 @@ cz bump ``` This command: + - Bumps your project's version - Creates a git tag - Updates the changelog (if `update_changelog_on_bump` is enabled) - Updates version files You can customize: + - [Version files](https://commitizen-tools.github.io/commitizen/commands/bump/#version_files) - [Version scheme](https://commitizen-tools.github.io/commitizen/commands/bump/#version_scheme) - [Version provider](https://commitizen-tools.github.io/commitizen/config/#version-providers) @@ -187,6 +189,7 @@ cz changelog --dry-run "$(cz version -p)" ``` This command is particularly useful for automation scripts and CI/CD pipelines. + For example, you can use the output of the command `cz changelog --dry-run "$(cz version -p)"` to notify your team about a new release in Slack. #### Pre-commit Integration From 59e7532cccabf08a0a4b633a13ee174853f5c6f0 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 28 May 2025 18:31:53 +0800 Subject: [PATCH 502/598] docs(external_links): typo --- docs/external_links.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/external_links.md b/docs/external_links.md index 24e4127d86..a90bbd085b 100644 --- a/docs/external_links.md +++ b/docs/external_links.md @@ -4,7 +4,7 @@ | Name | Speaker | Occasion | Language | Extra | | ------------------------------------------------------------------------- | --------------- | ---------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- | -| commitizen-tools: What can we gain from crafting a git message convention | Wei Lee | Taipey.py 2020 June Meetup, Remote Python Pizza 2020 | English | [slides](https://speakerdeck.com/leew/commitizen-tools-what-can-we-gain-from-crafting-a-git-message-convention-at-taipey-dot-py) | +| commitizen-tools: What can we gain from crafting a git message convention | Wei Lee | Taipei.py 2020 June Meetup, Remote Python Pizza 2020 | English | [slides](https://speakerdeck.com/leew/commitizen-tools-what-can-we-gain-from-crafting-a-git-message-convention-at-taipey-dot-py) | | Automating release cycles | Santiago Fraire | PyAmsterdam June 24, 2020, Online | English | [slides](https://woile.github.io/commitizen-presentation/) | | [Automatizando Releases con Commitizen y Github Actions][automatizando] | Santiago Fraire | PyConAr 2020, Remote | Español | [slides](https://woile.github.io/automating-releases-github-actions-presentation/#/) | From 739abd50a12f996144fc73a5f5dc0fa668b252dc Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 28 May 2025 17:52:14 +0800 Subject: [PATCH 503/598] docs(init): rewrite commands init page --- docs/commands/init.md | 67 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/docs/commands/init.md b/docs/commands/init.md index a799c44810..4d92112d34 100644 --- a/docs/commands/init.md +++ b/docs/commands/init.md @@ -1,27 +1,66 @@ +The `cz init` command helps you set up Commitizen in your project by creating a configuration file with your preferred settings. + ## Usage ![cz init --help](../images/cli_help/cz_init___help.svg) -## Example - -To start using Commitizen, the recommended approach is to run +## Command ```sh cz init ``` +## Interactive Configuration + +When you run `cz init`, Commitizen will guide you through an interactive setup process: + ![init](../images/init.gif) -This command will ask you for information about the project and will -configure the selected file type (`pyproject.toml`, `.cz.toml`, etc.). +## Configuration File + +The initialization process will create a configuration file in your project root. + +Choose the configuration file format based on your project type: + +- Use `pyproject.toml` for Python projects +- Use `.cz.toml`, `.cz.yaml`, `.cz.json`, etc. for other projects. + +## Configuration Options + +During the initialization process, you'll be prompted to configure the following settings: + +1. **Convention Rules**: Select the commit message convention to follow (e.g., conventional commits) +2. **Version Provider**: Choose how to manage versioning in your project. Commitizen supports multiple version management systems: + - `commitizen`: Uses Commitizen's built-in version management system + - `npm`: Manages version in `package.json` for Node.js projects + - `cargo`: Manages version in `Cargo.toml` for Rust projects + - `composer`: Manages version in `composer.json` for PHP projects + - `pep621`: Uses `pyproject.toml` with PEP 621 standard + - `poetry`: Uses `pyproject.toml` with Poetry configuration + - `uv`: Uses `pyproject.toml` and `uv.lock` for Python projects + - `scm`: Reads version directly from git tags without modifying files +3. **Project Version**: The current version of your project will be detected automatically +4. **Tag Format**: The format used for version tags in your repository +5. **Version Type**: Choose between: + - `semver` or `semver2`: Semantic Versioning (MAJOR.MINOR.PATCH) + - `pep440`: Python Package Versioning +6. **Changelog Generation**: Configure whether to automatically generate changelog during version bumps +7. **Alpha Versioning**: Option to keep major version at 0 for alpha/beta software +8. **Pre-commit Hooks**: Set up Git pre-commit hooks for automated commit message validation + +## Example + +```sh +# Start the initialization process +cz init + +# Follow the interactive prompts to configure your project +``` + +## Next Steps -The `init` will help you with +After initialization, you can: -1. Choose a convention rules (`name`) -2. Choosing a version provider (`commitizen` or for example `Cargo.toml`) -3. Detecting your project's version -4. Detecting the tag format used -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. +1. Start using `cz commit` to create conventional commits +2. Use `cz bump` to manage versioning +3. Configure additional settings in your project's configuration file From ceb2b7afef13b48a1fe978de3e4cbba472fb6609 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 28 May 2025 18:25:30 +0800 Subject: [PATCH 504/598] docs: correct case GitHub --- docs/commands/bump.md | 2 +- docs/tutorials/github_actions.md | 2 +- mkdocs.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/commands/bump.md b/docs/commands/bump.md index d399ec9eb8..8219cc3461 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -219,7 +219,7 @@ understand that the user wants to create a changelog. It is recommended to be explicit and use `--changelog` (or the setting `update_changelog_on_bump`). This command is useful to "transport" the newly created changelog. -It can be sent to an auditing system, or to create a Github Release. +It can be sent to an auditing system, or to create a GitHub Release. Example: diff --git a/docs/tutorials/github_actions.md b/docs/tutorials/github_actions.md index bf08eb3bc5..2cb58cfee6 100644 --- a/docs/tutorials/github_actions.md +++ b/docs/tutorials/github_actions.md @@ -1,4 +1,4 @@ -## Create a new release with Github Actions +## Create a new release with GitHub Actions ### Automatic bumping of version diff --git a/mkdocs.yml b/mkdocs.yml index a8a2fe2d44..7b1e0feb30 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -50,7 +50,7 @@ nav: - Auto check commits: "tutorials/auto_check.md" - Auto prepare commit message: "tutorials/auto_prepare_commit_message.md" - GitLab CI: "tutorials/gitlab_ci.md" - - Github Actions: "tutorials/github_actions.md" + - GitHub Actions: "tutorials/github_actions.md" - Jenkins pipeline: "tutorials/jenkins_pipeline.md" - Developmental releases: "tutorials/dev_releases.md" - Monorepo support: "tutorials/monorepo_guidance.md" From 4b6b3fb4f9782ed0d55db5518b1e1523e0779eea Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 28 May 2025 18:16:16 +0800 Subject: [PATCH 505/598] docs(commit): rewrite command commit page --- docs/commands/commit.md | 75 ++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/docs/commands/commit.md b/docs/commands/commit.md index febaee3cf2..5a073a2644 100644 --- a/docs/commands/commit.md +++ b/docs/commands/commit.md @@ -1,52 +1,65 @@ +## Usage + +![cz commit --help](../images/cli_help/cz_commit___help.svg) + +## Overview + ![Using Commitizen cli](../images/demo.gif) -## About +The `commit` command provides an interactive way to create structured commits. Use either: -In your terminal run `cz commit` or the shortcut `cz c` to generate a guided git commit. +- `cz commit` +- `cz c` (shortcut) -You can run `cz commit --write-message-to-file COMMIT_MSG_FILE` to additionally save the -generated message to a file. This can be combined with the `--dry-run` flag to only -write the message to a file and not modify files and create a commit. A possible use -case for this is to [automatically prepare a commit message](../tutorials/auto_prepare_commit_message.md). +By default, Commitizen uses conventional commits, but you can customize the commit rules to match your project's needs. See the [customization guide](../customization.md) for details. +## Basic Usage -!!! note - To maintain platform compatibility, the `commit` command disable ANSI escaping in its output. - In particular pre-commit hooks coloring will be deactivated as discussed in [commitizen-tools/commitizen#417](https://github.com/commitizen-tools/commitizen/issues/417). +### Interactive Commit Creation -## Usage +Simply run `cz commit` in your terminal to start the interactive commit creation process. The command will guide you through creating a properly formatted commit message according to your configured rules. -![cz commit --help](../images/cli_help/cz_commit___help.svg) +### Writing Messages to File -### git options +You can save the generated commit message to a file using: +```sh +cz commit --write-message-to-file COMMIT_MSG_FILE +``` -`git` command options that are not implemented by Commitizen can be use via the `--` syntax for the `commit` command. -The syntax separates Commitizen arguments from `git commit` arguments by a double dash. This is the resulting syntax: +This can be combined with `--dry-run` to only write the message without creating a commit. This is particularly useful for [automatically preparing commit messages](../tutorials/auto_prepare_commit_message.md). + +## Advanced Features + +### Git Command Options + +You can pass any git commit options using the `--` syntax: ```sh cz commit <commitizen-args> -- <git-cli-args> -# e.g., cz commit --dry-run -- -a -S +# Examples: +cz c --dry-run -- -a -S # Stage all changes and sign the commit +cz c -a -- -n # Stage all changes and skip the pre-commit and commit-msg hooks ``` -For example, using the `-S` option on `git commit` to sign a commit is now Commitizen compatible: `cz c -- -S` -!!! note - Deprecation warning: A commit can be signed off using `cz commit --signoff` or the shortcut `cz commit -s`. - This syntax is now deprecated in favor of the new `cz commit -- -s` syntax. +!!! warning + The `--signoff` option (or `-s`) is now recommended being used with the new syntax: `cz commit -- -s`. The old syntax `cz commit --signoff` is deprecated. ### Retry -You can use `cz commit --retry` to reuse the last commit message when the previous commit attempt failed. -To automatically retry when running `cz commit`, you can set the `retry_after_failure` -configuration option to `true`. Running `cz commit --no-retry` makes Commitizen ignore `retry_after_failure`, forcing -a new commit message to be prompted. +- Use `cz commit --retry` to reuse the last commit message after a failed commit attempt +- Set `retry_after_failure: true` in your configuration to automatically retry +- Use `cz commit --no-retry` to force a new commit message prompt + +### Message Length Control -### Commit message length limit +Control the length of your commit messages using the `-l` or `--message-length-limit` option: +```sh +cz commit -l 72 # Limits message length to 72 characters +``` + +!!! note + The length limit only applies to the first line of the commit message. For conventional commits, this means the limit applies from the type of change through the subject. The body and footer are not counted. -The argument `-l` (or `--message-length-limit`) followed by a positive number can limit the length of commit messages. -An exception would be raised when the message length exceeds the limit. -For example, `cz commit -l 72` will limit the length of commit messages to 72 characters. -By default, the limit is set to 0, which means no limit on the length. +## Technical Notes -**Note that the limit applies only to the first line of the message.** -Specifically, for `ConventionalCommitsCz` the length only counts from the type of change to the subject, -while the body and the footer are not counted. +For platform compatibility, the `commit` command disables ANSI escaping in its output. This means pre-commit hooks coloring will be deactivated as discussed in [commitizen-tools/commitizen#417](https://github.com/commitizen-tools/commitizen/issues/417). From 13e4aaacbde5bcfc4bd2aea1a1c060508b86dcec Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 14:03:53 +0800 Subject: [PATCH 506/598] docs(contributing): improve documentation for first-time contributors --- docs/contributing.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/contributing.md b/docs/contributing.md index e9e162d2df..8389e9370d 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,10 +1,14 @@ -## Contributing to commitizen +## Contributing to Commitizen -First, thank you for taking the time to contribute! 🎉 +First, thank you for taking the time to contribute! 🎉 Your contributions help make Commitizen better for everyone. -When contributing to [commitizen](https://github.com/commitizen-tools/commitizen), please first create an [issue](https://github.com/commitizen-tools/commitizen/issues) to discuss the change you wish to make before making a change. +When contributing to Commitizen, we encourage you to: -If you're a first-time contributor, you can check the issues with the [good first issue](https://github.com/commitizen-tools/commitizen/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) tag. +1. First, check out the [issues](https://github.com/commitizen-tools/commitizen/issues) and [Features we won't add](faq.md#features-we-wont-add) to see if there's already a discussion about the change you wish to make. +2. If there's no discussion, [create an issue](https://github.com/commitizen-tools/commitizen/issues/new) to discuss your proposed changes. +3. Follow our [development workflow](#development-workflow) and guidelines below. + +If you're a first-time contributor, please check out issues labeled [good first issue](https://github.com/commitizen-tools/commitizen/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) - these are specifically chosen to be beginner-friendly. ## Prerequisites & Setup From 47beadc563d8272b64f88ddbf3e9a37351b8f535 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 14:15:29 +0800 Subject: [PATCH 507/598] docs(pull_request_template): add task to fix broken external links in the docs --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 5686474709..e37148c0a1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -25,7 +25,7 @@ Please fill in the following content to let us know better about this change. ### Documentation Changes - [ ] Run `poetry doc` locally to ensure the documentation pages renders correctly - - [ ] Check if there are any broken links in the documentation +- [ ] Check and fix any broken links (internal or external) in the documentation > When running `poetry doc`, any broken internal documentation links will be reported in the console output like this: > From 596038c68a51ad2485ca924d394ee1282eec9472 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 2 Jun 2025 14:59:09 +0800 Subject: [PATCH 508/598] docs(feature_request): eliminate duplicated label --- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 4bd19b9b3a..da3bd5af8a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -26,6 +26,6 @@ body: - type: textarea id: related-issue attributes: - label: Additional context + label: Related issues description: | If applicable, add link to existing issue also help us know better. From a4c87bc0ecb71028d327f82bdba64798518eacc3 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 31 May 2025 22:41:41 +0800 Subject: [PATCH 509/598] docs(contributing): add Contributing TL;DR page --- docs/contributing_tldr.md | 28 ++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 29 insertions(+) create mode 100644 docs/contributing_tldr.md diff --git a/docs/contributing_tldr.md b/docs/contributing_tldr.md new file mode 100644 index 0000000000..278fa520a3 --- /dev/null +++ b/docs/contributing_tldr.md @@ -0,0 +1,28 @@ +Feel free to send a PR to update this file if you find anything useful. 🙇 + +## Environment + +- Python `>=3.9` +- [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer) `>=2.0.0` + +## Useful commands + +Please check the [pyproject.toml](https://github.com/commitizen-tools/commitizen/blob/master/pyproject.toml) for a comprehensive list of commands. + +```bash +# Ensure you have the correct dependencies +poetry install + +# Make ruff happy +poetry format + +# Check if ruff and mypy are happy +poetry lint + +# Check if mypy is happy in python 3.9 +mypy --python-version 3.9 + +# Run tests in parallel. +pytest -n auto # This may take a while. +pytest -n auto <test_suite> +``` diff --git a/mkdocs.yml b/mkdocs.yml index 7b1e0feb30..dec8d3fd5d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -58,6 +58,7 @@ nav: - Exit Codes: "exit_codes.md" - Third-Party Commitizen Templates: "third-party-commitizen.md" - Contributing: "contributing.md" + - Contributing TL;DR: "contributing_tldr.md" - Resources: "external_links.md" markdown_extensions: From 195ed16275eb197fe7b2bd78f7120f59d0e84424 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 14:26:31 +0800 Subject: [PATCH 510/598] docs(contributing-tldr): add documentation changes section --- docs/contributing_tldr.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/contributing_tldr.md b/docs/contributing_tldr.md index 278fa520a3..f5483cddcd 100644 --- a/docs/contributing_tldr.md +++ b/docs/contributing_tldr.md @@ -9,6 +9,8 @@ Feel free to send a PR to update this file if you find anything useful. 🙇 Please check the [pyproject.toml](https://github.com/commitizen-tools/commitizen/blob/master/pyproject.toml) for a comprehensive list of commands. +### Code Changes + ```bash # Ensure you have the correct dependencies poetry install @@ -26,3 +28,10 @@ mypy --python-version 3.9 pytest -n auto # This may take a while. pytest -n auto <test_suite> ``` + +### Documentation Changes + +```bash +# Build the documentation locally and check for broken links +poetry doc +``` From c1884bddbeb6afa0af72c9526e18fac16c46e766 Mon Sep 17 00:00:00 2001 From: Anas Hasan <anas.hassan9417@gmail.com> Date: Sun, 1 Jun 2025 15:45:02 +0530 Subject: [PATCH 511/598] docs(faq): explain why Pydantic is not used --- docs/faq.md | 14 +++++++++++ poetry.lock | 68 +++++++++++++++++++++++++++++++++++++------------- pyproject.toml | 1 + 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 920f533d73..ee9d97068d 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -82,6 +82,20 @@ git revert --no-commit <SHA> git commit -m "revert: foo bar" ``` +## Why don't we use Pydantic? + +While Pydantic is a powerful and popular library for data validation, we intentionally avoid using it in this project to keep our dependency tree minimal and maintainable. + +Including Pydantic would increase the chances of version conflicts for users - especially with major changes introduced in Pydantic v3. Because we pin dependencies tightly, adding Pydantic could unintentionally restrict what other tools or libraries users can install alongside `commitizen`. + +Moreover we don't rely on the full feature set of Pydantic. Simpler alternatives like Python's built-in `TypedDict` offer sufficient type safety for our use cases, without the runtime overhead or dependency burden. + +In short, avoiding Pydantic helps us: +- Keep dependencies lightweight +- Reduce compatibility issues for users +- Maintain clarity about what contributors should and shouldn't use + + ## I got `Exception [WinError 995] The I/O operation ...` error This error was caused by a Python bug on Windows. It's been fixed by [this PR](https://github.com/python/cpython/pull/22017), and according to Python's changelog, [3.8.6rc1](https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-6-release-candidate-1) and [3.9.0rc2](https://docs.python.org/3.9/whatsnew/changelog.html#python-3-9-0-release-candidate-2) should be the accurate versions first contain this fix. In conclusion, upgrade your Python version might solve this issue. diff --git a/poetry.lock b/poetry.lock index cccd7a532a..64ec358bb3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. [[package]] name = "argcomplete" @@ -31,8 +31,8 @@ files = [ six = ">=1.12.0" [package.extras] -astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] -test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] +astroid = ["astroid (>=1,<2) ; python_version < \"3\"", "astroid (>=2,<4) ; python_version >= \"3\""] +test = ["astroid (>=1,<2) ; python_version < \"3\"", "astroid (>=2,<4) ; python_version >= \"3\"", "pytest"] [[package]] name = "babel" @@ -302,7 +302,7 @@ files = [ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] -toml = ["tomli"] +toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "decli" @@ -344,7 +344,7 @@ files = [ wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"] [[package]] name = "distlib" @@ -402,7 +402,7 @@ files = [ ] [package.extras] -tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""] [[package]] name = "filelock" @@ -419,7 +419,7 @@ files = [ [package.extras] docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] -typing = ["typing-extensions (>=4.12.2)"] +typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""] [[package]] name = "freezegun" @@ -491,7 +491,7 @@ description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" groups = ["main", "documentation"] -markers = "python_version < \"3.10\"" +markers = "python_version == \"3.9\"" files = [ {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, @@ -501,12 +501,12 @@ files = [ zipp = ">=3.20" [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] perf = ["ipython"] -test = ["flufl.flake8", "importlib_resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] type = ["pytest-mypy"] [[package]] @@ -781,7 +781,7 @@ watchdog = ">=2.0" [package.extras] i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4) ; platform_system == \"Windows\"", "ghp-import (==1.0)", "importlib-metadata (==4.4) ; python_version < \"3.10\"", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] [[package]] name = "mkdocs-get-deps" @@ -971,6 +971,18 @@ files = [ qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["docopt", "pytest"] +[[package]] +name = "pastel" +version = "0.2.1" +description = "Bring colors to your terminal." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["dev"] +files = [ + {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, + {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, +] + [[package]] name = "pathspec" version = "0.12.1" @@ -1032,6 +1044,26 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "poethepoet" +version = "0.34.0" +description = "A task runner that works well with poetry." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "poethepoet-0.34.0-py3-none-any.whl", hash = "sha256:c472d6f0fdb341b48d346f4ccd49779840c15b30dfd6bc6347a80d6274b5e34e"}, + {file = "poethepoet-0.34.0.tar.gz", hash = "sha256:86203acce555bbfe45cb6ccac61ba8b16a5784264484195874da457ddabf5850"}, +] + +[package.dependencies] +pastel = ">=0.2.1,<0.3.0" +pyyaml = ">=6.0.2,<7.0" +tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} + +[package.extras] +poetry-plugin = ["poetry (>=1.2.0,<3.0.0) ; python_version < \"4.0\""] + [[package]] name = "pre-commit" version = "4.1.0" @@ -1304,7 +1336,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" -groups = ["main", "documentation", "linters", "test"] +groups = ["main", "dev", "documentation", "linters", "test"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -1785,7 +1817,7 @@ files = [ ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -1809,7 +1841,7 @@ platformdirs = ">=3.9.1,<5" [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] [[package]] name = "watchdog" @@ -1948,21 +1980,21 @@ description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" groups = ["main", "documentation"] -markers = "python_version < \"3.10\"" +markers = "python_version == \"3.9\"" files = [ {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "e15b424a0569f939e297c8abfcf09753f1fbcc5b4ad891163cc0982accd3b372" +content-hash = "2951e44d1ec238ddef2139c76de3c838976a018b0993f7b84c6fd686e26fc5d0" diff --git a/pyproject.toml b/pyproject.toml index a653ecdb5d..cff51a2094 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -107,6 +107,7 @@ packages = [{ include = "commitizen" }, { include = "commitizen/py.typed" }] [tool.poetry.group.dev.dependencies] ipython = "^8.0" tox = ">4" +poethepoet = "^0.34.0" [tool.poetry.group.test.dependencies] pytest = ">=7.2,<9.0" From 612ef79eec468c9cbd1b88a36aa45d036989f754 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 16 May 2025 02:03:30 +0800 Subject: [PATCH 512/598] refactor: improve readability and fix typos --- commitizen/bump.py | 18 ++++++++++-------- commitizen/changelog.py | 2 +- commitizen/cli.py | 8 ++------ commitizen/cz/utils.py | 11 +++++------ commitizen/defaults.py | 6 +++--- commitizen/tags.py | 6 +----- tests/test_changelog.py | 2 +- 7 files changed, 23 insertions(+), 30 deletions(-) diff --git a/commitizen/bump.py b/commitizen/bump.py index 76a8e15893..b8ae18ba64 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -76,7 +76,7 @@ def update_version_in_files( """ # TODO: separate check step and write step updated = [] - for path, regex in files_and_regexs(files, current_version): + for path, regex in _files_and_regexes(files, current_version): current_version_found, version_file = _bump_with_regex( path, current_version, @@ -99,7 +99,7 @@ def update_version_in_files( return updated -def files_and_regexs(patterns: list[str], version: str) -> list[tuple[str, str]]: +def _files_and_regexes(patterns: list[str], version: str) -> list[tuple[str, str]]: """ Resolve all distinct files with their regexp from a list of glob patterns with optional regexp """ @@ -128,13 +128,15 @@ def _bump_with_regex( pattern = re.compile(regex) with open(version_filepath, encoding=encoding) as f: for line in f: - if pattern.search(line): - bumped_line = line.replace(current_version, new_version) - if bumped_line != line: - current_version_found = True - lines.append(bumped_line) - else: + if not pattern.search(line): lines.append(line) + continue + + bumped_line = line.replace(current_version, new_version) + if bumped_line != line: + current_version_found = True + lines.append(bumped_line) + return current_version_found, "".join(lines) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 704efe6071..d8ab56069b 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -190,7 +190,7 @@ def process_commit_message( def order_changelog_tree(tree: Iterable, change_type_order: list[str]) -> Iterable: if len(set(change_type_order)) != len(change_type_order): raise InvalidConfigurationError( - f"Change types contain duplicates types ({change_type_order})" + f"Change types contain duplicated types ({change_type_order})" ) sorted_tree = [] diff --git a/commitizen/cli.py b/commitizen/cli.py index cb834c5d6f..b566fc596d 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -636,14 +636,10 @@ 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() - + conf = config.read_cfg(args.config) if args.name: conf.update({"name": args.name}) - elif not args.name and not conf.path: + elif not conf.path: conf.update({"name": "cz_conventional_commits"}) if args.debug: diff --git a/commitizen/cz/utils.py b/commitizen/cz/utils.py index 7bc89673c6..cb79d65d1a 100644 --- a/commitizen/cz/utils.py +++ b/commitizen/cz/utils.py @@ -5,6 +5,8 @@ from commitizen import git from commitizen.cz import exceptions +_RE_LOCAL_VERSION = re.compile(r"\+.+") + def required_validator(answer, msg=None): if not answer: @@ -17,16 +19,13 @@ def multiple_line_breaker(answer, sep="|"): def strip_local_version(version: str) -> str: - return re.sub(r"\+.+", "", version) + return _RE_LOCAL_VERSION.sub("", version) def get_backup_file_path() -> str: project_root = git.find_git_project_root() - - if project_root is None: - project = "" - else: - project = project_root.as_posix().replace("/", "%") + project = project_root.as_posix().replace("/", "%") if project_root else "" user = os.environ.get("USER", "") + return os.path.join(tempfile.gettempdir(), f"cz.commit%{user}%{project}.backup") diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 0b6c28e6a9..1885848618 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -141,7 +141,7 @@ class Settings(TypedDict, total=False): def get_tag_regexes( version_regex: str, ) -> dict[str, str]: - regexs = { + regexes = { "version": version_regex, "major": r"(?P<major>\d+)", "minor": r"(?P<minor>\d+)", @@ -150,6 +150,6 @@ def get_tag_regexes( "devrelease": r"(?P<devrelease>\.dev\d+)?", } return { - **{f"${k}": v for k, v in regexs.items()}, - **{f"${{{k}}}": v for k, v in regexs.items()}, + **{f"${k}": v for k, v in regexes.items()}, + **{f"${{{k}}}": v for k, v in regexes.items()}, } diff --git a/commitizen/tags.py b/commitizen/tags.py index 2b9a4b091a..c5f06884fe 100644 --- a/commitizen/tags.py +++ b/commitizen/tags.py @@ -174,11 +174,7 @@ def include_in_changelog(self, tag: GitTag) -> bool: version = self.extract_version(tag) except InvalidVersion: return False - - if self.merge_prereleases and version.is_prerelease: - return False - - return True + return not (self.merge_prereleases and version.is_prerelease) def search_version(self, text: str, last: bool = False) -> VersionTag | None: """ diff --git a/tests/test_changelog.py b/tests/test_changelog.py index b1c7c802e1..511cd1a3df 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1236,7 +1236,7 @@ def test_order_changelog_tree_raises(): with pytest.raises(InvalidConfigurationError) as excinfo: changelog.order_changelog_tree(COMMITS_TREE, change_type_order) - assert "Change types contain duplicates types" in str(excinfo) + assert "Change types contain duplicated types" in str(excinfo) def test_render_changelog( From 33453b753676161db343c56dc4a9abda31c2d864 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 23:26:54 +0800 Subject: [PATCH 513/598] refactor(version_scheme): cleanup --- commitizen/version_schemes.py | 94 +++++++++++++++++------------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 84ded9316e..d5370b2c6c 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -41,7 +41,9 @@ Increment: TypeAlias = Literal["MAJOR", "MINOR", "PATCH"] Prerelease: TypeAlias = Literal["alpha", "beta", "rc"] -DEFAULT_VERSION_PARSER = r"v?(?P<version>([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.]+)?(\w+)?)" +_DEFAULT_VERSION_PARSER = re.compile( + r"v?(?P<version>([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.]+)?(\w+)?)" +) @runtime_checkable @@ -156,7 +158,7 @@ class BaseVersion(_BaseVersion): A base class implementing the `VersionProtocol` for PEP440-like versions. """ - parser: ClassVar[re.Pattern] = re.compile(DEFAULT_VERSION_PARSER) + parser: ClassVar[re.Pattern] = _DEFAULT_VERSION_PARSER """Regex capturing this version scheme into a `version` group""" @property @@ -265,39 +267,35 @@ def bump( if self.local and is_local_version: local_version = self.scheme(self.local).bump(increment) return self.scheme(f"{self.public}+{local_version}") # type: ignore - else: - if not self.is_prerelease: - base = self.increment_base(increment) - elif exact_increment: - base = self.increment_base(increment) - else: - base = f"{self.major}.{self.minor}.{self.micro}" - if increment == PATCH: - pass - elif increment == MINOR: - if self.micro != 0: - base = self.increment_base(increment) - elif increment == MAJOR: - if self.minor != 0 or self.micro != 0: - base = self.increment_base(increment) - dev_version = self.generate_devrelease(devrelease) - - release = list(self.release) - if len(release) < 3: - release += [0] * (3 - len(release)) - current_base = ".".join(str(part) for part in release) - if base == current_base: - pre_version = self.generate_prerelease( - prerelease, offset=prerelease_offset - ) - else: - base_version = cast(BaseVersion, self.scheme(base)) - pre_version = base_version.generate_prerelease( - prerelease, offset=prerelease_offset - ) - build_metadata = self.generate_build_metadata(build_metadata) - # TODO: post version - return self.scheme(f"{base}{pre_version}{dev_version}{build_metadata}") # type: ignore + + base = self._get_increment_base(increment, exact_increment) + dev_version = self.generate_devrelease(devrelease) + + release = list(self.release) + if len(release) < 3: + release += [0] * (3 - len(release)) + current_base = ".".join(str(part) for part in release) + + pre_version = ( + self if base == current_base else cast(BaseVersion, self.scheme(base)) + ).generate_prerelease(prerelease, offset=prerelease_offset) + + # TODO: post version + return self.scheme( + f"{base}{pre_version}{dev_version}{self.generate_build_metadata(build_metadata)}" + ) # type: ignore + + def _get_increment_base( + self, increment: Increment | None, exact_increment: bool + ) -> str: + if ( + not self.is_prerelease + or exact_increment + or (increment == MINOR and self.micro != 0) + or (increment == MAJOR and (self.minor != 0 or self.micro != 0)) + ): + return self.increment_base(increment) + return f"{self.major}.{self.minor}.{self.micro}" class Pep440(BaseVersion): @@ -316,7 +314,7 @@ class SemVer(BaseVersion): """ def __str__(self) -> str: - parts = [] + parts: list[str] = [] # Epoch if self.epoch != 0: @@ -364,7 +362,7 @@ def prerelease(self) -> str | None: return None def __str__(self) -> str: - parts = [] + parts: list[str] = [] # Epoch if self.epoch != 0: @@ -373,9 +371,19 @@ def __str__(self) -> str: # Release segment parts.append(".".join(str(x) for x in self.release)) + if prerelease := self._get_prerelease(): + parts.append(f"-{prerelease}") + + # Local version segment + if self.local: + parts.append(f"+{self.local}") + + return "".join(parts) + + def _get_prerelease(self) -> str: # Pre-release identifiers # See: https://semver.org/spec/v2.0.0.html#spec-item-9 - prerelease_parts = [] + prerelease_parts: list[str] = [] if self.prerelease: prerelease_parts.append(f"{self.prerelease}") @@ -387,15 +395,7 @@ def __str__(self) -> str: if self.dev is not None: prerelease_parts.append(f"dev.{self.dev}") - if prerelease_parts: - parts.append("-") - parts.append(".".join(prerelease_parts)) - - # Local version segment - if self.local: - parts.append(f"+{self.local}") - - return "".join(parts) + return ".".join(prerelease_parts) DEFAULT_SCHEME: VersionScheme = Pep440 From 8cfb859ffad0538cb17a1b1bb565df6c47e48ded Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 19:05:40 +0800 Subject: [PATCH 514/598] refactor(commit): simplify call --- commitizen/commands/commit.py | 64 +++++++++++++++-------------------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index cb34c41a50..eedf77e079 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -92,41 +92,36 @@ def manual_edit(self, message: str) -> str: os.unlink(file.name) return message - def __call__(self): - extra_args: str = self.arguments.get("extra_cli_args", "") + def _get_message(self) -> str: + if self.arguments.get("retry"): + m = self.read_backup_message() + if m is None: + raise NoCommitBackupError() + return m - allow_empty: bool = "--allow-empty" in extra_args + if self.config.settings.get("retry_after_failure") and not self.arguments.get( + "no_retry" + ): + return self.read_backup_message() or self.prompt_commit_questions() + return self.prompt_commit_questions() + def __call__(self): + extra_args: str = self.arguments.get("extra_cli_args", "") dry_run: bool = self.arguments.get("dry_run") write_message_to_file: bool = self.arguments.get("write_message_to_file") - manual_edit: bool = self.arguments.get("edit") + signoff: bool = self.arguments.get("signoff") - is_all: bool = self.arguments.get("all") - if is_all: - c = git.add("-u") + if self.arguments.get("all"): + git.add("-u") - if git.is_staging_clean() and not (dry_run or allow_empty): + if git.is_staging_clean() and not (dry_run or "--allow-empty" in extra_args): raise NothingToCommitError("No files added to staging!") if write_message_to_file is not None and write_message_to_file.is_dir(): raise NotAllowed(f"{write_message_to_file} is a directory") - retry: bool = self.arguments.get("retry") - no_retry: bool = self.arguments.get("no_retry") - retry_after_failure: bool = self.config.settings.get("retry_after_failure") - - if retry: - m = self.read_backup_message() - if m is None: - raise NoCommitBackupError() - elif retry_after_failure and not no_retry: - m = self.read_backup_message() - if m is None: - m = self.prompt_commit_questions() - else: - m = self.prompt_commit_questions() - - if manual_edit: + m = self._get_message() + if self.arguments.get("edit"): m = self.manual_edit(m) out.info(f"\n{m}\n") @@ -138,19 +133,15 @@ def __call__(self): if dry_run: raise DryRunExit() - always_signoff: bool = self.config.settings["always_signoff"] - signoff: bool = self.arguments.get("signoff") - if signoff: out.warn( "signoff mechanic is deprecated, please use `cz commit -- -s` instead." ) - if always_signoff or signoff: + if self.config.settings["always_signoff"] or signoff: extra_args = f"{extra_args} -s".strip() c = git.commit(m, args=extra_args) - if c.return_code != 0: out.error(c.err) @@ -160,11 +151,12 @@ def __call__(self): raise CommitError() - if "nothing added" in c.out or "no changes added to commit" in c.out: + if any(s in c.out for s in ("nothing added", "no changes added to commit")): out.error(c.out) - else: - with contextlib.suppress(FileNotFoundError): - os.remove(self.temp_file) - out.write(c.err) - out.write(c.out) - out.success("Commit successful!") + return + + with contextlib.suppress(FileNotFoundError): + os.remove(self.temp_file) + out.write(c.err) + out.write(c.out) + out.success("Commit successful!") From 471b778e18937cb0291bf266fa1cd2a58a53e081 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 19:43:14 +0800 Subject: [PATCH 515/598] test(commit): when nothing is added to commit --- tests/commands/test_commit_command.py | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/commands/test_commit_command.py b/tests/commands/test_commit_command.py index 3a92f5af48..930e1a7a9b 100644 --- a/tests/commands/test_commit_command.py +++ b/tests/commands/test_commit_command.py @@ -523,3 +523,34 @@ def test_commit_command_shows_description_when_use_help_option( out, _ = capsys.readouterr() file_regression.check(out, extension=".txt") + + +@pytest.mark.usefixtures("staging_is_clean") +@pytest.mark.parametrize( + "out", ["no changes added to commit", "nothing added to commit"] +) +def test_commit_when_nothing_added_to_commit(config, mocker: MockFixture, out): + prompt_mock = mocker.patch("questionary.prompt") + prompt_mock.return_value = { + "prefix": "feat", + "subject": "user created", + "scope": "", + "is_breaking_change": False, + "body": "", + "footer": "", + } + + commit_mock = mocker.patch("commitizen.git.commit") + commit_mock.return_value = cmd.Command( + out=out, + err="", + stdout=out.encode(), + stderr=b"", + return_code=0, + ) + error_mock = mocker.patch("commitizen.out.error") + + commands.Commit(config, {})() + + commit_mock.assert_called_once() + error_mock.assert_called_once_with(out) From 5b3b6efbbb30980616aa218af35e66587d79a6da Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 16 May 2025 02:18:37 +0800 Subject: [PATCH 516/598] refactor(git): code cleanup and better test coverage --- commitizen/git.py | 133 +++++++++++++++------------------------------- tests/test_git.py | 32 ++++++----- 2 files changed, 61 insertions(+), 104 deletions(-) diff --git a/commitizen/git.py b/commitizen/git.py index 19ca46b6c3..d0cc901a61 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -1,34 +1,14 @@ from __future__ import annotations import os -from enum import Enum -from os import linesep from pathlib import Path from tempfile import NamedTemporaryFile from commitizen import cmd, out from commitizen.exceptions import GitCommandError -UNIX_EOL = "\n" -WINDOWS_EOL = "\r\n" - - -class EOLTypes(Enum): - """The EOL type from `git config core.eol`.""" - - LF = "lf" - CRLF = "crlf" - NATIVE = "native" - - def get_eol_for_open(self) -> str: - """Get the EOL character for `open()`.""" - map = { - EOLTypes.CRLF: WINDOWS_EOL, - EOLTypes.LF: UNIX_EOL, - EOLTypes.NATIVE: linesep, - } - - return map[self] +_UNIX_EOL = "\n" +_WINDOWS_EOL = "\r\n" class GitObject: @@ -37,9 +17,7 @@ class GitObject: date: str def __eq__(self, other) -> bool: - if not hasattr(other, "rev"): - return False - return self.rev == other.rev # type: ignore + return hasattr(other, "rev") and self.rev == other.rev class GitCommit(GitObject): @@ -63,6 +41,20 @@ def __init__( def message(self): return f"{self.title}\n\n{self.body}".strip() + @classmethod + def from_rev_and_commit(cls, rev_and_commit: str) -> GitCommit: + rev, parents, title, author, author_email, *body_list = rev_and_commit.split( + "\n" + ) + return cls( + rev=rev.strip(), + title=title.strip(), + body="\n".join(body_list).strip(), + author=author, + author_email=author_email, + parents=[p for p in parents.strip().split(" ") if p], + ) + def __repr__(self): return f"{self.title} ({self.rev})" @@ -101,13 +93,11 @@ def tag( # according to https://git-scm.com/book/en/v2/Git-Basics-Tagging, # we're not able to create lightweight tag with message. # by adding message, we make it a annotated tags - c = cmd.run(f'git tag {_opt} "{tag if _opt == "" or msg is None else msg}"') - return c + return cmd.run(f'git tag {_opt} "{tag if _opt == "" or msg is None else msg}"') def add(*args: str) -> cmd.Command: - c = cmd.run(f"git add {' '.join(args)}") - return c + return cmd.run(f"git add {' '.join(args)}") def commit( @@ -140,24 +130,10 @@ def get_commits( ) -> list[GitCommit]: """Get the commits between start and end.""" git_log_entries = _get_log_as_str_list(start, end, args) - git_commits = [] - for rev_and_commit in git_log_entries: - if not rev_and_commit: - continue - rev, parents, title, author, author_email, *body_list = rev_and_commit.split( - "\n" - ) - if rev_and_commit: - git_commit = GitCommit( - rev=rev.strip(), - title=title.strip(), - body="\n".join(body_list).strip(), - author=author, - author_email=author_email, - parents=[p for p in parents.strip().split(" ") if p], - ) - git_commits.append(git_commit) - return git_commits + return [ + GitCommit.from_rev_and_commit(rev_and_commit) + for rev_and_commit in filter(None, git_log_entries) + ] def get_filenames_in_commit(git_reference: str = ""): @@ -170,8 +146,7 @@ def get_filenames_in_commit(git_reference: str = ""): c = cmd.run(f"git show --name-only --pretty=format: {git_reference}") if c.return_code == 0: return c.out.strip().split("\n") - else: - raise GitCommandError(c.err) + raise GitCommandError(c.err) def get_tags( @@ -197,16 +172,11 @@ def get_tags( if c.err: out.warn(f"Attempting to proceed after: {c.err}") - if not c.out: - return [] - - git_tags = [ + return [ GitTag.from_line(line=line, inner_delimiter=inner_delimiter) for line in c.out.split("\n")[:-1] ] - return git_tags - def tag_exist(tag: str) -> bool: c = cmd.run(f"git tag --list {tag}") @@ -231,18 +201,18 @@ def get_tag_message(tag: str) -> str | None: return c.out.strip() -def get_tag_names() -> list[str | None]: +def get_tag_names() -> list[str]: c = cmd.run("git tag --list") if c.err: return [] - return [tag.strip() for tag in c.out.split("\n") if tag.strip()] + return list(filter(None, (tag.strip() for tag in c.out.split("\n")))) def find_git_project_root() -> Path | None: c = cmd.run("git rev-parse --show-toplevel") - if not c.err: - return Path(c.out.strip()) - return None + if c.err: + return None + return Path(c.out.strip()) def is_staging_clean() -> bool: @@ -253,32 +223,19 @@ def is_staging_clean() -> bool: def is_git_project() -> bool: c = cmd.run("git rev-parse --is-inside-work-tree") - if c.out.strip() == "true": - return True - return False + return c.out.strip() == "true" -def get_eol_style() -> EOLTypes: +def get_eol_for_open() -> str: + # See: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreeol c = cmd.run("git config core.eol") eol = c.out.strip().lower() - # We enumerate the EOL types of the response of - # `git config core.eol`, and map it to our enumration EOLTypes. - # - # It is just like the variant of the "match" syntax. - map = { - "lf": EOLTypes.LF, - "crlf": EOLTypes.CRLF, - "native": EOLTypes.NATIVE, - } - - # If the response of `git config core.eol` is in the map: - if eol in map: - return map[eol] - else: - # The default value is "native". - # https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreeol - return map["native"] + if eol == "lf": + return _UNIX_EOL + if eol == "crlf": + return _WINDOWS_EOL + return os.linesep def get_core_editor() -> str | None: @@ -288,22 +245,18 @@ def get_core_editor() -> str | None: return None -def smart_open(*args, **kargs): +def smart_open(*args, **kwargs): """Open a file with the EOL style determined from Git.""" - return open(*args, newline=get_eol_style().get_eol_for_open(), **kargs) + return open(*args, newline=get_eol_for_open(), **kwargs) def _get_log_as_str_list(start: str | None, end: str, args: str) -> list[str]: """Get string representation of each log entry""" delimiter = "----------commit-delimiter----------" log_format: str = "%H%n%P%n%s%n%an%n%ae%n%b" - git_log_cmd = ( - f"git -c log.showSignature=False log --pretty={log_format}{delimiter} {args}" - ) - if start: - command = f"{git_log_cmd} {start}..{end}" - else: - command = f"{git_log_cmd} {end}" + command_range = f"{start}..{end}" if start else end + command = f"git -c log.showSignature=False log --pretty={log_format}{delimiter} {args} {command_range}" + c = cmd.run(command) if c.return_code != 0: raise GitCommandError(c.err) diff --git a/tests/test_git.py b/tests/test_git.py index 8b2fc2b86e..4e4b61ffe2 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -79,8 +79,7 @@ def test_get_reachable_tags_with_commits( monkeypatch.setenv("LANGUAGE", f"{locale}.UTF-8") monkeypatch.setenv("LC_ALL", f"{locale}.UTF-8") with tmp_commitizen_project.as_cwd(): - tags = git.get_tags(reachable_only=True) - assert tags == [] + assert git.get_tags(reachable_only=True) == [] def test_get_tag_names(mocker: MockFixture): @@ -271,7 +270,7 @@ def test_get_commits_with_signature(): def test_get_tag_names_has_correct_arrow_annotation(): arrow_annotation = inspect.getfullargspec(git.get_tag_names).annotations["return"] - assert arrow_annotation == "list[str | None]" + assert arrow_annotation == "list[str]" def test_get_latest_tag_name(tmp_commitizen_project): @@ -317,24 +316,18 @@ def test_is_staging_clean_when_updating_file(tmp_commitizen_project): assert git.is_staging_clean() is False -def test_git_eol_style(tmp_commitizen_project): +def test_get_eol_for_open(tmp_commitizen_project): with tmp_commitizen_project.as_cwd(): - assert git.get_eol_style() == git.EOLTypes.NATIVE + assert git.get_eol_for_open() == os.linesep cmd.run("git config core.eol lf") - assert git.get_eol_style() == git.EOLTypes.LF + assert git.get_eol_for_open() == "\n" cmd.run("git config core.eol crlf") - assert git.get_eol_style() == git.EOLTypes.CRLF + assert git.get_eol_for_open() == "\r\n" cmd.run("git config core.eol native") - assert git.get_eol_style() == git.EOLTypes.NATIVE - - -def test_eoltypes_get_eol_for_open(): - assert git.EOLTypes.get_eol_for_open(git.EOLTypes.NATIVE) == os.linesep - assert git.EOLTypes.get_eol_for_open(git.EOLTypes.LF) == "\n" - assert git.EOLTypes.get_eol_for_open(git.EOLTypes.CRLF) == "\r\n" + assert git.get_eol_for_open() == os.linesep def test_get_core_editor(mocker): @@ -401,3 +394,14 @@ def test_commit_with_spaces_in_path(mocker, file_path, expected_cmd): mock_run.assert_called_once_with(expected_cmd) mock_unlink.assert_called_once_with(file_path) + + +def test_get_filenames_in_commit_error(mocker: MockFixture): + """Test that GitCommandError is raised when git command fails.""" + mocker.patch( + "commitizen.cmd.run", + return_value=FakeCommand(out="", err="fatal: bad object HEAD", return_code=1), + ) + with pytest.raises(exceptions.GitCommandError) as excinfo: + git.get_filenames_in_commit() + assert str(excinfo.value) == "fatal: bad object HEAD" From 755a04113f1a32256de86ea73d3301ba5875bd8f Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 16:04:08 +0800 Subject: [PATCH 517/598] test(git): add test for from_rev_and_commit --- tests/test_git.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/test_git.py b/tests/test_git.py index 4e4b61ffe2..cb4ea93375 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -405,3 +405,47 @@ def test_get_filenames_in_commit_error(mocker: MockFixture): with pytest.raises(exceptions.GitCommandError) as excinfo: git.get_filenames_in_commit() assert str(excinfo.value) == "fatal: bad object HEAD" + + +def test_git_commit_from_rev_and_commit(): + # Test data with all fields populated + rev_and_commit = ( + "abc123\n" # rev + "def456 ghi789\n" # parents + "feat: add new feature\n" # title + "John Doe\n" # author + "john@example.com\n" # author_email + "This is a detailed description\n" # body + "of the new feature\n" + "with multiple lines" + ) + + commit = git.GitCommit.from_rev_and_commit(rev_and_commit) + + assert commit.rev == "abc123" + assert commit.title == "feat: add new feature" + assert ( + commit.body + == "This is a detailed description\nof the new feature\nwith multiple lines" + ) + assert commit.author == "John Doe" + assert commit.author_email == "john@example.com" + assert commit.parents == ["def456", "ghi789"] + + # Test with minimal data + minimal_commit = ( + "abc123\n" # rev + "\n" # no parents + "feat: minimal commit\n" # title + "John Doe\n" # author + "john@example.com\n" # author_email + ) + + commit = git.GitCommit.from_rev_and_commit(minimal_commit) + + assert commit.rev == "abc123" + assert commit.title == "feat: minimal commit" + assert commit.body == "" + assert commit.author == "John Doe" + assert commit.author_email == "john@example.com" + assert commit.parents == [] From 1deffcab679bcecc619652d6175d6ef97167ba25 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 16:04:38 +0800 Subject: [PATCH 518/598] docs(git): from_rev_and_commit docstring --- commitizen/git.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/commitizen/git.py b/commitizen/git.py index d0cc901a61..d80545bc44 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -43,6 +43,48 @@ def message(self): @classmethod def from_rev_and_commit(cls, rev_and_commit: str) -> GitCommit: + """Create a GitCommit instance from a formatted commit string. + + This method parses a multi-line string containing commit information in the following format: + ``` + <rev> + <parents> + <title> + <author> + <author_email> + <body_line_1> + <body_line_2> + ... + ``` + + Args: + rev_and_commit (str): A string containing commit information with fields separated by newlines. + - rev: The commit hash/revision + - parents: Space-separated list of parent commit hashes + - title: The commit title/message + - author: The commit author's name + - author_email: The commit author's email + - body: Optional multi-line commit body + + Returns: + GitCommit: A new GitCommit instance with the parsed information. + + Example: + >>> commit_str = '''abc123 + ... def456 ghi789 + ... feat: add new feature + ... John Doe + ... john@example.com + ... This is a detailed description + ... of the new feature''' + >>> commit = GitCommit.from_rev_and_commit(commit_str) + >>> commit.rev + 'abc123' + >>> commit.title + 'feat: add new feature' + >>> commit.parents + ['def456', 'ghi789'] + """ rev, parents, title, author, author_email, *body_list = rev_and_commit.split( "\n" ) From 1eb35c80ca731518d6f0194904ac390a5fcad021 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 18 May 2025 19:11:52 +0800 Subject: [PATCH 519/598] refactor(EOLType): add eol enum back and reorganize methods --- commitizen/git.py | 48 ++++++++++++++++++++++++++++++++--------------- tests/test_git.py | 8 ++++---- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/commitizen/git.py b/commitizen/git.py index d80545bc44..ef4e0452e3 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -1,14 +1,44 @@ from __future__ import annotations import os +from enum import Enum +from functools import lru_cache from pathlib import Path from tempfile import NamedTemporaryFile from commitizen import cmd, out from commitizen.exceptions import GitCommandError -_UNIX_EOL = "\n" -_WINDOWS_EOL = "\r\n" + +class EOLType(Enum): + """The EOL type from `git config core.eol`.""" + + LF = "lf" + CRLF = "crlf" + NATIVE = "native" + + @classmethod + def for_open(cls) -> str: + c = cmd.run("git config core.eol") + eol = c.out.strip().upper() + return cls._char_for_open()[cls._safe_cast(eol)] + + @classmethod + def _safe_cast(cls, eol: str) -> EOLType: + try: + return cls[eol] + except KeyError: + return cls.NATIVE + + @classmethod + @lru_cache + def _char_for_open(cls) -> dict[EOLType, str]: + """Get the EOL character for `open()`.""" + return { + cls.LF: "\n", + cls.CRLF: "\r\n", + cls.NATIVE: os.linesep, + } class GitObject: @@ -268,18 +298,6 @@ def is_git_project() -> bool: return c.out.strip() == "true" -def get_eol_for_open() -> str: - # See: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreeol - c = cmd.run("git config core.eol") - eol = c.out.strip().lower() - - if eol == "lf": - return _UNIX_EOL - if eol == "crlf": - return _WINDOWS_EOL - return os.linesep - - def get_core_editor() -> str | None: c = cmd.run("git var GIT_EDITOR") if c.out: @@ -289,7 +307,7 @@ def get_core_editor() -> str | None: def smart_open(*args, **kwargs): """Open a file with the EOL style determined from Git.""" - return open(*args, newline=get_eol_for_open(), **kwargs) + return open(*args, newline=EOLType.for_open(), **kwargs) def _get_log_as_str_list(start: str | None, end: str, args: str) -> list[str]: diff --git a/tests/test_git.py b/tests/test_git.py index cb4ea93375..de3130412b 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -318,16 +318,16 @@ def test_is_staging_clean_when_updating_file(tmp_commitizen_project): def test_get_eol_for_open(tmp_commitizen_project): with tmp_commitizen_project.as_cwd(): - assert git.get_eol_for_open() == os.linesep + assert git.EOLType.for_open() == os.linesep cmd.run("git config core.eol lf") - assert git.get_eol_for_open() == "\n" + assert git.EOLType.for_open() == "\n" cmd.run("git config core.eol crlf") - assert git.get_eol_for_open() == "\r\n" + assert git.EOLType.for_open() == "\r\n" cmd.run("git config core.eol native") - assert git.get_eol_for_open() == os.linesep + assert git.EOLType.for_open() == os.linesep def test_get_core_editor(mocker): From f67b29b0970bc72d36e27c6d9a50dc68d21759fd Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 18 May 2025 19:26:22 +0800 Subject: [PATCH 520/598] refactor(git): refactor get_tag_names --- commitizen/git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/git.py b/commitizen/git.py index ef4e0452e3..fa59e34d48 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -277,7 +277,7 @@ def get_tag_names() -> list[str]: c = cmd.run("git tag --list") if c.err: return [] - return list(filter(None, (tag.strip() for tag in c.out.split("\n")))) + return [tag for raw in c.out.split("\n") if (tag := raw.strip())] def find_git_project_root() -> Path | None: From febd0d6296430e7c49f13e4522092741a102cbed Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Tue, 20 May 2025 00:46:16 +0800 Subject: [PATCH 521/598] refactor(changelog): minor cleanup --- commitizen/commands/changelog.py | 45 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 0e4efabfa1..9ab8fdc37c 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -2,10 +2,10 @@ import os import os.path +from collections.abc import Generator from difflib import SequenceMatcher from operator import itemgetter from pathlib import Path -from typing import Callable, cast from commitizen import changelog, defaults, factory, git, out from commitizen.changelog_formats import get_changelog_format @@ -32,9 +32,10 @@ def __init__(self, config: BaseConfig, args): if not git.is_git_project(): raise NotAGitProjectError() - self.config: BaseConfig = config - changelog_file_name = args.get("file_name") or cast( - str, self.config.settings.get("changelog_file") + self.config = config + + changelog_file_name = args.get("file_name") or self.config.settings.get( + "changelog_file" ) if not isinstance(changelog_file_name, str): raise NotAllowed( @@ -114,28 +115,28 @@ def _find_incremental_rev(self, latest_version: str, tags: list[GitTag]) -> str: on our experience. """ SIMILARITY_THRESHOLD = 0.89 - tag_ratio = map( - lambda tag: ( - SequenceMatcher( + scores_and_tag_names: Generator[tuple[float, str]] = ( + ( + score, + tag.name, + ) + for tag in tags + if ( + score := SequenceMatcher( None, latest_version, strip_local_version(tag.name) - ).ratio(), - tag, - ), - tags, + ).ratio() + ) + >= SIMILARITY_THRESHOLD ) try: - score, tag = max(tag_ratio, key=itemgetter(0)) + _, start_rev = max(scores_and_tag_names, key=itemgetter(0)) except ValueError: raise NoRevisionError() - if score < SIMILARITY_THRESHOLD: - raise NoRevisionError() - start_rev = tag.name return start_rev def write_changelog( self, changelog_out: str, lines: list[str], changelog_meta: changelog.Metadata ): - changelog_hook: Callable | None = self.cz.changelog_hook with smart_open(self.file_name, "w", encoding=self.encoding) as changelog_file: partial_changelog: str | None = None if self.incremental: @@ -145,8 +146,8 @@ def write_changelog( changelog_out = "".join(new_lines) partial_changelog = changelog_out - if changelog_hook: - changelog_out = changelog_hook(changelog_out, partial_changelog) + if self.cz.changelog_hook: + changelog_out = self.cz.changelog_hook(changelog_out, partial_changelog) changelog_file.write(changelog_out) @@ -221,14 +222,12 @@ def __call__(self): extras.update(self.extras) changelog_out = changelog.render_changelog( tree, loader=self.cz.template_loader, template=self.template, **extras - ) - changelog_out = changelog_out.lstrip("\n") + ).lstrip("\n") # Dry_run is executed here to avoid checking and reading the files if self.dry_run: - changelog_hook: Callable | None = self.cz.changelog_hook - if changelog_hook: - changelog_out = changelog_hook(changelog_out, "") + if self.cz.changelog_hook: + changelog_out = self.cz.changelog_hook(changelog_out, "") out.write(changelog_out) raise DryRunExit() From f3fa22cefe0ac681e2c6e1f80ad119d1df135903 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Tue, 20 May 2025 21:23:30 +0800 Subject: [PATCH 522/598] refactor(BaseConfig): use setter --- commitizen/config/base_config.py | 12 +++++++++--- commitizen/config/json_config.py | 2 +- commitizen/config/toml_config.py | 2 +- commitizen/config/yaml_config.py | 2 +- tests/commands/test_init_command.py | 2 +- tests/test_changelog.py | 4 +++- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/commitizen/config/base_config.py b/commitizen/config/base_config.py index 478691aa14..fd034412fe 100644 --- a/commitizen/config/base_config.py +++ b/commitizen/config/base_config.py @@ -19,6 +19,15 @@ def settings(self) -> Settings: def path(self) -> Path | None: return self._path + @path.setter + def path(self, path: str | Path) -> None: + """ + mypy does not like this until 1.16 + See https://github.com/python/mypy/pull/18510 + TODO: remove "type: ignore" from the call sites when 1.16 is available + """ + self._path = Path(path) + def set_key(self, key, value): """Set or update a key in the conf. @@ -30,8 +39,5 @@ def set_key(self, key, value): def update(self, data: Settings) -> None: self._settings.update(data) - def add_path(self, path: str | Path) -> None: - self._path = Path(path) - def _parse_setting(self, data: bytes | str) -> None: raise NotImplementedError() diff --git a/commitizen/config/json_config.py b/commitizen/config/json_config.py index b6a07f4ced..d413d73383 100644 --- a/commitizen/config/json_config.py +++ b/commitizen/config/json_config.py @@ -13,7 +13,7 @@ class JsonConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super().__init__() self.is_empty_config = False - self.add_path(path) + self.path = path # type: ignore self._parse_setting(data) def init_empty_config_content(self): diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index 813389cbcf..e2cfcc9340 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -14,7 +14,7 @@ class TomlConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super().__init__() self.is_empty_config = False - self.add_path(path) + self.path = path # type: ignore self._parse_setting(data) def init_empty_config_content(self): diff --git a/commitizen/config/yaml_config.py b/commitizen/config/yaml_config.py index 2bb6fe3af8..c5721c8d4b 100644 --- a/commitizen/config/yaml_config.py +++ b/commitizen/config/yaml_config.py @@ -14,7 +14,7 @@ class YAMLConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super().__init__() self.is_empty_config = False - self.add_path(path) + self.path = path # type: ignore self._parse_setting(data) def init_empty_config_content(self): diff --git a/tests/commands/test_init_command.py b/tests/commands/test_init_command.py index f617c51d8f..3f12d0bd7f 100644 --- a/tests/commands/test_init_command.py +++ b/tests/commands/test_init_command.py @@ -86,7 +86,7 @@ def test_init_without_setup_pre_commit_hook(tmpdir, mocker: MockFixture, config) def test_init_when_config_already_exists(config, capsys): # Set config path path = os.sep.join(["tests", "pyproject.toml"]) - config.add_path(path) + config.path = path commands.Init(config)() captured = capsys.readouterr() diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 511cd1a3df..d42176f09a 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1639,7 +1639,9 @@ def test_tags_rules_get_version_tags(capsys: pytest.CaptureFixture): def test_changelog_file_name_from_args_and_config(): mock_config = Mock(spec=BaseConfig) - mock_config.path.parent = "/my/project" + mock_path = Mock(spec=Path) + mock_path.parent = Path("/my/project") + mock_config.path = mock_path mock_config.settings = { "name": "cz_conventional_commits", "changelog_file": "CHANGELOG.md", From c939df1f46e8aa9c28e1ddff60d523ff540cfab5 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Tue, 20 May 2025 23:34:37 +0800 Subject: [PATCH 523/598] build(poetry): upgrade mypy version to ^1.15.0 --- poetry.lock | 1086 +++++++++++++++++++++++------------------------- pyproject.toml | 14 +- 2 files changed, 513 insertions(+), 587 deletions(-) diff --git a/poetry.lock b/poetry.lock index 64ec358bb3..ceccd3da1c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -17,60 +17,76 @@ test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] [[package]] name = "asttokens" -version = "2.4.1" +version = "3.0.0" description = "Annotate AST trees with source code positions" optional = false -python-versions = "*" +python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, - {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, + {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, + {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, ] -[package.dependencies] -six = ">=1.12.0" - [package.extras] -astroid = ["astroid (>=1,<2) ; python_version < \"3\"", "astroid (>=2,<4) ; python_version >= \"3\""] -test = ["astroid (>=1,<2) ; python_version < \"3\"", "astroid (>=2,<4) ; python_version >= \"3\"", "pytest"] +astroid = ["astroid (>=2,<4)"] +test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "babel" -version = "2.16.0" +version = "2.17.0" description = "Internationalization utilities" optional = false python-versions = ">=3.8" groups = ["documentation"] files = [ - {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, - {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, + {file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"}, + {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, +] + +[package.extras] +dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""] + +[[package]] +name = "backrefs" +version = "5.8" +description = "A wrapper around re and regex that adds additional back references." +optional = false +python-versions = ">=3.9" +groups = ["documentation"] +files = [ + {file = "backrefs-5.8-py310-none-any.whl", hash = "sha256:c67f6638a34a5b8730812f5101376f9d41dc38c43f1fdc35cb54700f6ed4465d"}, + {file = "backrefs-5.8-py311-none-any.whl", hash = "sha256:2e1c15e4af0e12e45c8701bd5da0902d326b2e200cafcd25e49d9f06d44bb61b"}, + {file = "backrefs-5.8-py312-none-any.whl", hash = "sha256:bbef7169a33811080d67cdf1538c8289f76f0942ff971222a16034da88a73486"}, + {file = "backrefs-5.8-py313-none-any.whl", hash = "sha256:e3a63b073867dbefd0536425f43db618578528e3896fb77be7141328642a1585"}, + {file = "backrefs-5.8-py39-none-any.whl", hash = "sha256:a66851e4533fb5b371aa0628e1fee1af05135616b86140c9d787a2ffdf4b8fdc"}, + {file = "backrefs-5.8.tar.gz", hash = "sha256:2cab642a205ce966af3dd4b38ee36009b31fa9502a35fd61d59ccc116e40a6bd"}, ] [package.extras] -dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] +extras = ["regex"] [[package]] name = "cachetools" -version = "5.5.1" +version = "6.0.0" description = "Extensible memoizing collections and decorators" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "cachetools-5.5.1-py3-none-any.whl", hash = "sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb"}, - {file = "cachetools-5.5.1.tar.gz", hash = "sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95"}, + {file = "cachetools-6.0.0-py3-none-any.whl", hash = "sha256:82e73ba88f7b30228b5507dce1a1f878498fc669d972aef2dde4f3a3c24f103e"}, + {file = "cachetools-6.0.0.tar.gz", hash = "sha256:f225782b84438f828328fc2ad74346522f27e5b1440f4e9fd18b20ebfd1aa2cf"}, ] [[package]] name = "certifi" -version = "2024.8.30" +version = "2025.4.26" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" groups = ["documentation"] files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3"}, + {file = "certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6"}, ] [[package]] @@ -99,116 +115,116 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.1" +version = "3.4.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" groups = ["main", "documentation"] files = [ - {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, - {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, - {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win32.whl", hash = "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e"}, + {file = "charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0"}, + {file = "charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" groups = ["documentation"] files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -228,74 +244,79 @@ files = [ [[package]] name = "coverage" -version = "7.6.8" +version = "7.8.2" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" groups = ["test"] files = [ - {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, - {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, - {file = "coverage-7.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee"}, - {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6"}, - {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d"}, - {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331"}, - {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638"}, - {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed"}, - {file = "coverage-7.6.8-cp310-cp310-win32.whl", hash = "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e"}, - {file = "coverage-7.6.8-cp310-cp310-win_amd64.whl", hash = "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a"}, - {file = "coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4"}, - {file = "coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94"}, - {file = "coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4"}, - {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1"}, - {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb"}, - {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8"}, - {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a"}, - {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0"}, - {file = "coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801"}, - {file = "coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9"}, - {file = "coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee"}, - {file = "coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a"}, - {file = "coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d"}, - {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb"}, - {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649"}, - {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787"}, - {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c"}, - {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443"}, - {file = "coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad"}, - {file = "coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4"}, - {file = "coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb"}, - {file = "coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63"}, - {file = "coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365"}, - {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002"}, - {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3"}, - {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022"}, - {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e"}, - {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b"}, - {file = "coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146"}, - {file = "coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28"}, - {file = "coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d"}, - {file = "coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451"}, - {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764"}, - {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf"}, - {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5"}, - {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4"}, - {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83"}, - {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b"}, - {file = "coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71"}, - {file = "coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc"}, - {file = "coverage-7.6.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ac47fa29d8d41059ea3df65bd3ade92f97ee4910ed638e87075b8e8ce69599e"}, - {file = "coverage-7.6.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:24eda3a24a38157eee639ca9afe45eefa8d2420d49468819ac5f88b10de84f4c"}, - {file = "coverage-7.6.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c81ed2820b9023a9a90717020315e63b17b18c274a332e3b6437d7ff70abe0"}, - {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd55f8fc8fa494958772a2a7302b0354ab16e0b9272b3c3d83cdb5bec5bd1779"}, - {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f39e2f3530ed1626c66e7493be7a8423b023ca852aacdc91fb30162c350d2a92"}, - {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:716a78a342679cd1177bc8c2fe957e0ab91405bd43a17094324845200b2fddf4"}, - {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177f01eeaa3aee4a5ffb0d1439c5952b53d5010f86e9d2667963e632e30082cc"}, - {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:912e95017ff51dc3d7b6e2be158dedc889d9a5cc3382445589ce554f1a34c0ea"}, - {file = "coverage-7.6.8-cp39-cp39-win32.whl", hash = "sha256:4db3ed6a907b555e57cc2e6f14dc3a4c2458cdad8919e40b5357ab9b6db6c43e"}, - {file = "coverage-7.6.8-cp39-cp39-win_amd64.whl", hash = "sha256:428ac484592f780e8cd7b6b14eb568f7c85460c92e2a37cb0c0e5186e1a0d076"}, - {file = "coverage-7.6.8-pp39.pp310-none-any.whl", hash = "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce"}, - {file = "coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc"}, + {file = "coverage-7.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd8ec21e1443fd7a447881332f7ce9d35b8fbd2849e761bb290b584535636b0a"}, + {file = "coverage-7.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c26c2396674816deaeae7ded0e2b42c26537280f8fe313335858ffff35019be"}, + {file = "coverage-7.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1aec326ed237e5880bfe69ad41616d333712c7937bcefc1343145e972938f9b3"}, + {file = "coverage-7.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e818796f71702d7a13e50c70de2a1924f729228580bcba1607cccf32eea46e6"}, + {file = "coverage-7.8.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:546e537d9e24efc765c9c891328f30f826e3e4808e31f5d0f87c4ba12bbd1622"}, + {file = "coverage-7.8.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab9b09a2349f58e73f8ebc06fac546dd623e23b063e5398343c5270072e3201c"}, + {file = "coverage-7.8.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fd51355ab8a372d89fb0e6a31719e825cf8df8b6724bee942fb5b92c3f016ba3"}, + {file = "coverage-7.8.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0774df1e093acb6c9e4d58bce7f86656aeed6c132a16e2337692c12786b32404"}, + {file = "coverage-7.8.2-cp310-cp310-win32.whl", hash = "sha256:00f2e2f2e37f47e5f54423aeefd6c32a7dbcedc033fcd3928a4f4948e8b96af7"}, + {file = "coverage-7.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:145b07bea229821d51811bf15eeab346c236d523838eda395ea969d120d13347"}, + {file = "coverage-7.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b99058eef42e6a8dcd135afb068b3d53aff3921ce699e127602efff9956457a9"}, + {file = "coverage-7.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5feb7f2c3e6ea94d3b877def0270dff0947b8d8c04cfa34a17be0a4dc1836879"}, + {file = "coverage-7.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:670a13249b957bb9050fab12d86acef7bf8f6a879b9d1a883799276e0d4c674a"}, + {file = "coverage-7.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bdc8bf760459a4a4187b452213e04d039990211f98644c7292adf1e471162b5"}, + {file = "coverage-7.8.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07a989c867986c2a75f158f03fdb413128aad29aca9d4dbce5fc755672d96f11"}, + {file = "coverage-7.8.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2db10dedeb619a771ef0e2949ccba7b75e33905de959c2643a4607bef2f3fb3a"}, + {file = "coverage-7.8.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e6ea7dba4e92926b7b5f0990634b78ea02f208d04af520c73a7c876d5a8d36cb"}, + {file = "coverage-7.8.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ef2f22795a7aca99fc3c84393a55a53dd18ab8c93fb431004e4d8f0774150f54"}, + {file = "coverage-7.8.2-cp311-cp311-win32.whl", hash = "sha256:641988828bc18a6368fe72355df5f1703e44411adbe49bba5644b941ce6f2e3a"}, + {file = "coverage-7.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8ab4a51cb39dc1933ba627e0875046d150e88478dbe22ce145a68393e9652975"}, + {file = "coverage-7.8.2-cp311-cp311-win_arm64.whl", hash = "sha256:8966a821e2083c74d88cca5b7dcccc0a3a888a596a04c0b9668a891de3a0cc53"}, + {file = "coverage-7.8.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2f6fe3654468d061942591aef56686131335b7a8325684eda85dacdf311356c"}, + {file = "coverage-7.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76090fab50610798cc05241bf83b603477c40ee87acd358b66196ab0ca44ffa1"}, + {file = "coverage-7.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd0a0a5054be160777a7920b731a0570284db5142abaaf81bcbb282b8d99279"}, + {file = "coverage-7.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da23ce9a3d356d0affe9c7036030b5c8f14556bd970c9b224f9c8205505e3b99"}, + {file = "coverage-7.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9392773cffeb8d7e042a7b15b82a414011e9d2b5fdbbd3f7e6a6b17d5e21b20"}, + {file = "coverage-7.8.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:876cbfd0b09ce09d81585d266c07a32657beb3eaec896f39484b631555be0fe2"}, + {file = "coverage-7.8.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3da9b771c98977a13fbc3830f6caa85cae6c9c83911d24cb2d218e9394259c57"}, + {file = "coverage-7.8.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a990f6510b3292686713bfef26d0049cd63b9c7bb17e0864f133cbfd2e6167f"}, + {file = "coverage-7.8.2-cp312-cp312-win32.whl", hash = "sha256:bf8111cddd0f2b54d34e96613e7fbdd59a673f0cf5574b61134ae75b6f5a33b8"}, + {file = "coverage-7.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:86a323a275e9e44cdf228af9b71c5030861d4d2610886ab920d9945672a81223"}, + {file = "coverage-7.8.2-cp312-cp312-win_arm64.whl", hash = "sha256:820157de3a589e992689ffcda8639fbabb313b323d26388d02e154164c57b07f"}, + {file = "coverage-7.8.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ea561010914ec1c26ab4188aef8b1567272ef6de096312716f90e5baa79ef8ca"}, + {file = "coverage-7.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cb86337a4fcdd0e598ff2caeb513ac604d2f3da6d53df2c8e368e07ee38e277d"}, + {file = "coverage-7.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a4636ddb666971345541b59899e969f3b301143dd86b0ddbb570bd591f1e85"}, + {file = "coverage-7.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5040536cf9b13fb033f76bcb5e1e5cb3b57c4807fef37db9e0ed129c6a094257"}, + {file = "coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108"}, + {file = "coverage-7.8.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e6c86888fd076d9e0fe848af0a2142bf606044dc5ceee0aa9eddb56e26895a0"}, + {file = "coverage-7.8.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:684ca9f58119b8e26bef860db33524ae0365601492e86ba0b71d513f525e7050"}, + {file = "coverage-7.8.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8165584ddedb49204c4e18da083913bdf6a982bfb558632a79bdaadcdafd0d48"}, + {file = "coverage-7.8.2-cp313-cp313-win32.whl", hash = "sha256:34759ee2c65362163699cc917bdb2a54114dd06d19bab860725f94ef45a3d9b7"}, + {file = "coverage-7.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:2f9bc608fbafaee40eb60a9a53dbfb90f53cc66d3d32c2849dc27cf5638a21e3"}, + {file = "coverage-7.8.2-cp313-cp313-win_arm64.whl", hash = "sha256:9fe449ee461a3b0c7105690419d0b0aba1232f4ff6d120a9e241e58a556733f7"}, + {file = "coverage-7.8.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8369a7c8ef66bded2b6484053749ff220dbf83cba84f3398c84c51a6f748a008"}, + {file = "coverage-7.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:159b81df53a5fcbc7d45dae3adad554fdbde9829a994e15227b3f9d816d00b36"}, + {file = "coverage-7.8.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6fcbbd35a96192d042c691c9e0c49ef54bd7ed865846a3c9d624c30bb67ce46"}, + {file = "coverage-7.8.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05364b9cc82f138cc86128dc4e2e1251c2981a2218bfcd556fe6b0fbaa3501be"}, + {file = "coverage-7.8.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46d532db4e5ff3979ce47d18e2fe8ecad283eeb7367726da0e5ef88e4fe64740"}, + {file = "coverage-7.8.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4000a31c34932e7e4fa0381a3d6deb43dc0c8f458e3e7ea6502e6238e10be625"}, + {file = "coverage-7.8.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:43ff5033d657cd51f83015c3b7a443287250dc14e69910577c3e03bd2e06f27b"}, + {file = "coverage-7.8.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94316e13f0981cbbba132c1f9f365cac1d26716aaac130866ca812006f662199"}, + {file = "coverage-7.8.2-cp313-cp313t-win32.whl", hash = "sha256:3f5673888d3676d0a745c3d0e16da338c5eea300cb1f4ada9c872981265e76d8"}, + {file = "coverage-7.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:2c08b05ee8d7861e45dc5a2cc4195c8c66dca5ac613144eb6ebeaff2d502e73d"}, + {file = "coverage-7.8.2-cp313-cp313t-win_arm64.whl", hash = "sha256:1e1448bb72b387755e1ff3ef1268a06617afd94188164960dba8d0245a46004b"}, + {file = "coverage-7.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:496948261eaac5ac9cf43f5d0a9f6eb7a6d4cb3bedb2c5d294138142f5c18f2a"}, + {file = "coverage-7.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eacd2de0d30871eff893bab0b67840a96445edcb3c8fd915e6b11ac4b2f3fa6d"}, + {file = "coverage-7.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b039ffddc99ad65d5078ef300e0c7eed08c270dc26570440e3ef18beb816c1ca"}, + {file = "coverage-7.8.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e49824808d4375ede9dd84e9961a59c47f9113039f1a525e6be170aa4f5c34d"}, + {file = "coverage-7.8.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b069938961dfad881dc2f8d02b47645cd2f455d3809ba92a8a687bf513839787"}, + {file = "coverage-7.8.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:de77c3ba8bb686d1c411e78ee1b97e6e0b963fb98b1637658dd9ad2c875cf9d7"}, + {file = "coverage-7.8.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1676628065a498943bd3f64f099bb573e08cf1bc6088bbe33cf4424e0876f4b3"}, + {file = "coverage-7.8.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8e1a26e7e50076e35f7afafde570ca2b4d7900a491174ca357d29dece5aacee7"}, + {file = "coverage-7.8.2-cp39-cp39-win32.whl", hash = "sha256:6782a12bf76fa61ad9350d5a6ef5f3f020b57f5e6305cbc663803f2ebd0f270a"}, + {file = "coverage-7.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:1efa4166ba75ccefd647f2d78b64f53f14fb82622bc94c5a5cb0a622f50f1c9e"}, + {file = "coverage-7.8.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:ec455eedf3ba0bbdf8f5a570012617eb305c63cb9f03428d39bf544cb2b94837"}, + {file = "coverage-7.8.2-py3-none-any.whl", hash = "sha256:726f32ee3713f7359696331a18daf0c3b3a70bb0ae71141b9d3c52be7c595e32"}, + {file = "coverage-7.8.2.tar.gz", hash = "sha256:a886d531373a1f6ff9fad2a2ba4a045b68467b779ae729ee0b3b10ac20033b27"}, ] [package.dependencies] @@ -306,26 +327,26 @@ toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "decli" -version = "0.6.2" +version = "0.6.3" description = "Minimal, easy-to-use, declarative cli tool" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed"}, - {file = "decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f"}, + {file = "decli-0.6.3-py3-none-any.whl", hash = "sha256:5152347c7bb8e3114ad65db719e5709b28d7f7f45bdb709f70167925e55640f3"}, + {file = "decli-0.6.3.tar.gz", hash = "sha256:87f9d39361adf7f16b9ca6e3b614badf7519da13092f2db3c80ca223c53c7656"}, ] [[package]] name = "decorator" -version = "5.1.1" +version = "5.2.1" description = "Decorators for Humans" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, + {file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"}, + {file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"}, ] [[package]] @@ -360,17 +381,20 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.2" +version = "1.3.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" groups = ["dev", "test"] markers = "python_version < \"3.11\"" files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, + {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, + {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + [package.extras] test = ["pytest (>=6)"] @@ -391,14 +415,14 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "executing" -version = "2.1.0" +version = "2.2.0" description = "Get the currently executing AST node of a frame, and other information" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"}, - {file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"}, + {file = "executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa"}, + {file = "executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755"}, ] [package.extras] @@ -406,31 +430,31 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "filelock" -version = "3.16.1" +version = "3.18.0" description = "A platform independent file lock." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev", "linters"] files = [ - {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, - {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, + {file = "filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"}, + {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"}, ] [package.extras] -docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"] typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""] [[package]] name = "freezegun" -version = "1.5.1" +version = "1.5.2" description = "Let your Python tests travel through time" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["test"] files = [ - {file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"}, - {file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"}, + {file = "freezegun-1.5.2-py3-none-any.whl", hash = "sha256:5aaf3ba229cda57afab5bd311f0108d86b6fb119ae89d2cd9c43ec8c1733c85b"}, + {file = "freezegun-1.5.2.tar.gz", hash = "sha256:a54ae1d2f9c02dbf42e02c18a3ab95ab4295818b549a34dac55592d72a905181"}, ] [package.dependencies] @@ -456,14 +480,14 @@ dev = ["flake8", "markdown", "twine", "wheel"] [[package]] name = "identify" -version = "2.6.3" +version = "2.6.12" description = "File identification library for Python" optional = false python-versions = ">=3.9" groups = ["linters"] files = [ - {file = "identify-2.6.3-py2.py3-none-any.whl", hash = "sha256:9edba65473324c2ea9684b1f944fe3191db3345e50b6d04571d10ed164f8d7bd"}, - {file = "identify-2.6.3.tar.gz", hash = "sha256:62f5dae9b5fef52c84cc188514e9ea4f3f636b1d8799ab5ebc475471f9e47a02"}, + {file = "identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2"}, + {file = "identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6"}, ] [package.extras] @@ -486,15 +510,15 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 [[package]] name = "importlib-metadata" -version = "8.6.1" +version = "8.7.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" groups = ["main", "documentation"] markers = "python_version == \"3.9\"" files = [ - {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, - {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, + {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, + {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, ] [package.dependencies] @@ -511,14 +535,14 @@ type = ["pytest-mypy"] [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" description = "brain-dead simple config-ini parsing" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["test"] files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, ] [[package]] @@ -581,14 +605,14 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] [[package]] name = "jinja2" -version = "3.1.5" +version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" groups = ["main", "documentation"] files = [ - {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, - {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, ] [package.dependencies] @@ -599,21 +623,21 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "markdown" -version = "3.7" +version = "3.8" description = "Python implementation of John Gruber's Markdown." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["documentation"] files = [ - {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, - {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, + {file = "markdown-3.8-py3-none-any.whl", hash = "sha256:794a929b79c5af141ef5ab0f2f642d0f7b1872981250230e72682346f7cc90dc"}, + {file = "markdown-3.8.tar.gz", hash = "sha256:7df81e63f0df5c4b24b7d156eb81e4690595239b7d70937d0409f1b0de319c6f"}, ] [package.dependencies] importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} [package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +docs = ["mdx_gh_links (>=0.2)", "mkdocs (>=1.6)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] [[package]] @@ -803,27 +827,27 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-material" -version = "9.5.50" +version = "9.6.14" description = "Documentation that simply works" optional = false python-versions = ">=3.8" groups = ["documentation"] files = [ - {file = "mkdocs_material-9.5.50-py3-none-any.whl", hash = "sha256:f24100f234741f4d423a9d672a909d859668a4f404796be3cf035f10d6050385"}, - {file = "mkdocs_material-9.5.50.tar.gz", hash = "sha256:ae5fe16f3d7c9ccd05bb6916a7da7420cf99a9ce5e33debd9d40403a090d5825"}, + {file = "mkdocs_material-9.6.14-py3-none-any.whl", hash = "sha256:3b9cee6d3688551bf7a8e8f41afda97a3c39a12f0325436d76c86706114b721b"}, + {file = "mkdocs_material-9.6.14.tar.gz", hash = "sha256:39d795e90dce6b531387c255bd07e866e027828b7346d3eba5ac3de265053754"}, ] [package.dependencies] babel = ">=2.10,<3.0" +backrefs = ">=5.7.post1,<6.0" colorama = ">=0.4,<1.0" -jinja2 = ">=3.0,<4.0" +jinja2 = ">=3.1,<4.0" markdown = ">=3.2,<4.0" mkdocs = ">=1.6,<2.0" mkdocs-material-extensions = ">=1.3,<2.0" paginate = ">=0.5,<1.0" pygments = ">=2.16,<3.0" pymdown-extensions = ">=10.2,<11.0" -regex = ">=2022.4" requests = ">=2.26,<3.0" [package.extras] @@ -845,54 +869,49 @@ files = [ [[package]] name = "mypy" -version = "1.14.1" +version = "1.16.0" description = "Optional static typing for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["linters"] files = [ - {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, - {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, - {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"}, - {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"}, - {file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"}, - {file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"}, - {file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"}, - {file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"}, - {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"}, - {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"}, - {file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"}, - {file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"}, - {file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"}, - {file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"}, - {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"}, - {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"}, - {file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"}, - {file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"}, - {file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"}, - {file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"}, - {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"}, - {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"}, - {file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"}, - {file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"}, - {file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"}, - {file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"}, - {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"}, - {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"}, - {file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"}, - {file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"}, - {file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"}, - {file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"}, - {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"}, - {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"}, - {file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"}, - {file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"}, - {file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"}, - {file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"}, + {file = "mypy-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7909541fef256527e5ee9c0a7e2aeed78b6cda72ba44298d1334fe7881b05c5c"}, + {file = "mypy-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e71d6f0090c2256c713ed3d52711d01859c82608b5d68d4fa01a3fe30df95571"}, + {file = "mypy-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:936ccfdd749af4766be824268bfe22d1db9eb2f34a3ea1d00ffbe5b5265f5491"}, + {file = "mypy-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4086883a73166631307fdd330c4a9080ce24913d4f4c5ec596c601b3a4bdd777"}, + {file = "mypy-1.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:feec38097f71797da0231997e0de3a58108c51845399669ebc532c815f93866b"}, + {file = "mypy-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:09a8da6a0ee9a9770b8ff61b39c0bb07971cda90e7297f4213741b48a0cc8d93"}, + {file = "mypy-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9f826aaa7ff8443bac6a494cf743f591488ea940dd360e7dd330e30dd772a5ab"}, + {file = "mypy-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:82d056e6faa508501af333a6af192c700b33e15865bda49611e3d7d8358ebea2"}, + {file = "mypy-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:089bedc02307c2548eb51f426e085546db1fa7dd87fbb7c9fa561575cf6eb1ff"}, + {file = "mypy-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6a2322896003ba66bbd1318c10d3afdfe24e78ef12ea10e2acd985e9d684a666"}, + {file = "mypy-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:021a68568082c5b36e977d54e8f1de978baf401a33884ffcea09bd8e88a98f4c"}, + {file = "mypy-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:54066fed302d83bf5128632d05b4ec68412e1f03ef2c300434057d66866cea4b"}, + {file = "mypy-1.16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c5436d11e89a3ad16ce8afe752f0f373ae9620841c50883dc96f8b8805620b13"}, + {file = "mypy-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f2622af30bf01d8fc36466231bdd203d120d7a599a6d88fb22bdcb9dbff84090"}, + {file = "mypy-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d045d33c284e10a038f5e29faca055b90eee87da3fc63b8889085744ebabb5a1"}, + {file = "mypy-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4968f14f44c62e2ec4a038c8797a87315be8df7740dc3ee8d3bfe1c6bf5dba8"}, + {file = "mypy-1.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb14a4a871bb8efb1e4a50360d4e3c8d6c601e7a31028a2c79f9bb659b63d730"}, + {file = "mypy-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:bd4e1ebe126152a7bbaa4daedd781c90c8f9643c79b9748caa270ad542f12bec"}, + {file = "mypy-1.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a9e056237c89f1587a3be1a3a70a06a698d25e2479b9a2f57325ddaaffc3567b"}, + {file = "mypy-1.16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b07e107affb9ee6ce1f342c07f51552d126c32cd62955f59a7db94a51ad12c0"}, + {file = "mypy-1.16.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c6fb60cbd85dc65d4d63d37cb5c86f4e3a301ec605f606ae3a9173e5cf34997b"}, + {file = "mypy-1.16.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7e32297a437cc915599e0578fa6bc68ae6a8dc059c9e009c628e1c47f91495d"}, + {file = "mypy-1.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:afe420c9380ccec31e744e8baff0d406c846683681025db3531b32db56962d52"}, + {file = "mypy-1.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:55f9076c6ce55dd3f8cd0c6fff26a008ca8e5131b89d5ba6d86bd3f47e736eeb"}, + {file = "mypy-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f56236114c425620875c7cf71700e3d60004858da856c6fc78998ffe767b73d3"}, + {file = "mypy-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:15486beea80be24ff067d7d0ede673b001d0d684d0095803b3e6e17a886a2a92"}, + {file = "mypy-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f2ed0e0847a80655afa2c121835b848ed101cc7b8d8d6ecc5205aedc732b1436"}, + {file = "mypy-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eb5fbc8063cb4fde7787e4c0406aa63094a34a2daf4673f359a1fb64050e9cb2"}, + {file = "mypy-1.16.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a5fcfdb7318c6a8dd127b14b1052743b83e97a970f0edb6c913211507a255e20"}, + {file = "mypy-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:2e7e0ad35275e02797323a5aa1be0b14a4d03ffdb2e5f2b0489fa07b89c67b21"}, + {file = "mypy-1.16.0-py3-none-any.whl", hash = "sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031"}, + {file = "mypy-1.16.0.tar.gz", hash = "sha256:84b94283f817e2aa6350a14b4a8fb2a35a53c286f97c9d30f53b63620e7af8ab"}, ] [package.dependencies] mypy_extensions = ">=1.0.0" +pathspec = ">=0.9.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing_extensions = ">=4.6.0" @@ -905,14 +924,14 @@ reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "1.0.0" +version = "1.1.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" groups = ["linters"] files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, ] [[package]] @@ -929,14 +948,14 @@ files = [ [[package]] name = "packaging" -version = "24.2" +version = "25.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" groups = ["main", "dev", "documentation", "test"] files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] [[package]] @@ -989,7 +1008,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" -groups = ["documentation"] +groups = ["documentation", "linters"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -1013,36 +1032,36 @@ ptyprocess = ">=0.5" [[package]] name = "platformdirs" -version = "4.3.6" +version = "4.3.8" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev", "documentation", "linters"] files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, + {file = "platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"}, + {file = "platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc"}, ] [package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.14.1)"] [[package]] name = "pluggy" -version = "1.5.0" +version = "1.6.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev", "test"] files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, ] [package.extras] dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] +testing = ["coverage", "pytest", "pytest-benchmark"] [[package]] name = "poethepoet" @@ -1066,14 +1085,14 @@ poetry-plugin = ["poetry (>=1.2.0,<3.0.0) ; python_version < \"4.0\""] [[package]] name = "pre-commit" -version = "4.1.0" +version = "4.2.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" groups = ["linters"] files = [ - {file = "pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b"}, - {file = "pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4"}, + {file = "pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd"}, + {file = "pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146"}, ] [package.dependencies] @@ -1085,14 +1104,14 @@ virtualenv = ">=20.10.0" [[package]] name = "prompt-toolkit" -version = "3.0.48" +version = "3.0.51" description = "Library for building powerful interactive command lines in Python" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8" groups = ["main", "dev"] files = [ - {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"}, - {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"}, + {file = "prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07"}, + {file = "prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed"}, ] [package.dependencies] @@ -1128,14 +1147,14 @@ tests = ["pytest"] [[package]] name = "pygments" -version = "2.18.0" +version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" -groups = ["dev", "documentation", "script"] +groups = ["dev", "documentation", "script", "test"] files = [ - {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, - {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, + {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, + {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, ] [package.extras] @@ -1143,14 +1162,14 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pymdown-extensions" -version = "10.12" +version = "10.15" description = "Extension pack for Python Markdown." optional = false python-versions = ">=3.8" groups = ["documentation"] files = [ - {file = "pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77"}, - {file = "pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7"}, + {file = "pymdown_extensions-10.15-py3-none-any.whl", hash = "sha256:46e99bb272612b0de3b7e7caf6da8dd5f4ca5212c0b273feb9304e236c484e5f"}, + {file = "pymdown_extensions-10.15.tar.gz", hash = "sha256:0e5994e32155f4b03504f939e501b981d306daf7ec2aa1cd2eb6bd300784f8f7"}, ] [package.dependencies] @@ -1158,61 +1177,62 @@ markdown = ">=3.6" pyyaml = "*" [package.extras] -extra = ["pygments (>=2.12)"] +extra = ["pygments (>=2.19.1)"] [[package]] name = "pyproject-api" -version = "1.9.0" +version = "1.9.1" description = "API to interact with the python pyproject.toml based projects" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "pyproject_api-1.9.0-py3-none-any.whl", hash = "sha256:326df9d68dea22d9d98b5243c46e3ca3161b07a1b9b18e213d1e24fd0e605766"}, - {file = "pyproject_api-1.9.0.tar.gz", hash = "sha256:7e8a9854b2dfb49454fae421cb86af43efbb2b2454e5646ffb7623540321ae6e"}, + {file = "pyproject_api-1.9.1-py3-none-any.whl", hash = "sha256:7d6238d92f8962773dd75b5f0c4a6a27cce092a14b623b811dba656f3b628948"}, + {file = "pyproject_api-1.9.1.tar.gz", hash = "sha256:43c9918f49daab37e302038fc1aed54a8c7a91a9fa935d00b9a485f37e0f5335"}, ] [package.dependencies] -packaging = ">=24.2" +packaging = ">=25" tomli = {version = ">=2.2.1", markers = "python_version < \"3.11\""} [package.extras] -docs = ["furo (>=2024.8.6)", "sphinx-autodoc-typehints (>=3)"] -testing = ["covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "setuptools (>=75.8)"] +docs = ["furo (>=2024.8.6)", "sphinx-autodoc-typehints (>=3.2)"] +testing = ["covdefaults (>=2.3)", "pytest (>=8.3.5)", "pytest-cov (>=6.1.1)", "pytest-mock (>=3.14)", "setuptools (>=80.3.1)"] [[package]] name = "pytest" -version = "8.3.4" +version = "8.4.0" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["test"] files = [ - {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, - {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, + {file = "pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e"}, + {file = "pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6"}, ] [package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} +iniconfig = ">=1" +packaging = ">=20" pluggy = ">=1.5,<2" +pygments = ">=2.7.2" tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" -version = "6.0.0" +version = "6.1.1" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" groups = ["test"] files = [ - {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, - {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, + {file = "pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde"}, + {file = "pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a"}, ] [package.dependencies] @@ -1224,18 +1244,22 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-datadir" -version = "1.5.0" +version = "1.7.2" description = "pytest plugin for test data directories and files" optional = false python-versions = ">=3.8" groups = ["test"] files = [ - {file = "pytest-datadir-1.5.0.tar.gz", hash = "sha256:1617ed92f9afda0c877e4eac91904b5f779d24ba8f5e438752e3ae39d8d2ee3f"}, - {file = "pytest_datadir-1.5.0-py3-none-any.whl", hash = "sha256:34adf361bcc7b37961bbc1dfa8d25a4829e778bab461703c38a5c50ca9c36dc8"}, + {file = "pytest_datadir-1.7.2-py3-none-any.whl", hash = "sha256:8392ba0e9eaf37030e663dcd91cc5123dec99c44300f0c5eac44f35f13f0e086"}, + {file = "pytest_datadir-1.7.2.tar.gz", hash = "sha256:15f5228a35d0a3205e4968e75d3b9cca91762424e1eafc21eb637d380a48443e"}, ] [package.dependencies] -pytest = ">=5.0" +pytest = ">=7.0" + +[package.extras] +dev = ["pre-commit", "pytest-datadir[testing]"] +testing = ["pytest", "tox"] [[package]] name = "pytest-freezer" @@ -1255,14 +1279,14 @@ pytest = ">=3.6" [[package]] name = "pytest-mock" -version = "3.14.0" +version = "3.14.1" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" groups = ["test"] files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, + {file = "pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0"}, + {file = "pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e"}, ] [package.dependencies] @@ -1273,19 +1297,19 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-regressions" -version = "2.7.0" +version = "2.8.0" description = "Easy to use fixtures to write regression tests." optional = false python-versions = ">=3.9" groups = ["test"] files = [ - {file = "pytest_regressions-2.7.0-py3-none-any.whl", hash = "sha256:69f5e3f03493cf0ef84d96d23e50a546617c198b1d7746f2e2b9e441cbab4847"}, - {file = "pytest_regressions-2.7.0.tar.gz", hash = "sha256:4c30064e0923929012c94f5d6f35205be06fd8709c7f0dba0228e05c460af05e"}, + {file = "pytest_regressions-2.8.0-py3-none-any.whl", hash = "sha256:2926f37efa5fd6793806b10352e274c5284a5469a845aeab6243e86f9214766f"}, + {file = "pytest_regressions-2.8.0.tar.gz", hash = "sha256:775044e17117f5427df2caad3ab1c66889abe770a0ce2bc3f24fdeac99af76fe"}, ] [package.dependencies] pytest = ">=6.2.0" -pytest-datadir = ">=1.2.0" +pytest-datadir = ">=1.7.0" pyyaml = "*" [package.extras] @@ -1296,14 +1320,14 @@ num = ["numpy", "pandas"] [[package]] name = "pytest-xdist" -version = "3.6.1" +version = "3.7.0" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["test"] files = [ - {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, - {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, + {file = "pytest_xdist-3.7.0-py3-none-any.whl", hash = "sha256:7d3fbd255998265052435eb9daa4e99b62e6fb9cfb6efd1f858d4d8c0c7f0ca0"}, + {file = "pytest_xdist-3.7.0.tar.gz", hash = "sha256:f9248c99a7c15b7d2f90715df93610353a485827bc06eefb6566d23f6400f126"}, ] [package.dependencies] @@ -1395,14 +1419,14 @@ files = [ [[package]] name = "pyyaml-env-tag" -version = "0.1" -description = "A custom YAML tag for referencing environment variables in YAML files. " +version = "1.1" +description = "A custom YAML tag for referencing environment variables in YAML files." optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" groups = ["documentation"] files = [ - {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, - {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, + {file = "pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04"}, + {file = "pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff"}, ] [package.dependencies] @@ -1423,110 +1447,6 @@ files = [ [package.dependencies] prompt_toolkit = ">=2.0,<4.0" -[[package]] -name = "regex" -version = "2024.11.6" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.8" -groups = ["documentation"] -files = [ - {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, - {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, - {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, - {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, - {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, - {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, - {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, - {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, - {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, - {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, - {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, - {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, - {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, - {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, - {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, - {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, - {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, - {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, - {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, - {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, - {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, - {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, - {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, - {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, - {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, - {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, - {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, - {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, - {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, - {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, - {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, - {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, - {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, - {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, - {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, - {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, - {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, - {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, - {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, - {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, - {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, - {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, - {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, -] - [[package]] name = "requests" version = "2.32.3" @@ -1571,42 +1491,42 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.9.4" +version = "0.9.10" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" groups = ["linters"] files = [ - {file = "ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706"}, - {file = "ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf"}, - {file = "ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231"}, - {file = "ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b"}, - {file = "ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6"}, - {file = "ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c"}, - {file = "ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0"}, - {file = "ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402"}, - {file = "ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e"}, - {file = "ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41"}, - {file = "ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7"}, + {file = "ruff-0.9.10-py3-none-linux_armv6l.whl", hash = "sha256:eb4d25532cfd9fe461acc83498361ec2e2252795b4f40b17e80692814329e42d"}, + {file = "ruff-0.9.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:188a6638dab1aa9bb6228a7302387b2c9954e455fb25d6b4470cb0641d16759d"}, + {file = "ruff-0.9.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5284dcac6b9dbc2fcb71fdfc26a217b2ca4ede6ccd57476f52a587451ebe450d"}, + {file = "ruff-0.9.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47678f39fa2a3da62724851107f438c8229a3470f533894b5568a39b40029c0c"}, + {file = "ruff-0.9.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99713a6e2766b7a17147b309e8c915b32b07a25c9efd12ada79f217c9c778b3e"}, + {file = "ruff-0.9.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524ee184d92f7c7304aa568e2db20f50c32d1d0caa235d8ddf10497566ea1a12"}, + {file = "ruff-0.9.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:df92aeac30af821f9acf819fc01b4afc3dfb829d2782884f8739fb52a8119a16"}, + {file = "ruff-0.9.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de42e4edc296f520bb84954eb992a07a0ec5a02fecb834498415908469854a52"}, + {file = "ruff-0.9.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d257f95b65806104b6b1ffca0ea53f4ef98454036df65b1eda3693534813ecd1"}, + {file = "ruff-0.9.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60dec7201c0b10d6d11be00e8f2dbb6f40ef1828ee75ed739923799513db24c"}, + {file = "ruff-0.9.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d838b60007da7a39c046fcdd317293d10b845001f38bcb55ba766c3875b01e43"}, + {file = "ruff-0.9.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ccaf903108b899beb8e09a63ffae5869057ab649c1e9231c05ae354ebc62066c"}, + {file = "ruff-0.9.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f9567d135265d46e59d62dc60c0bfad10e9a6822e231f5b24032dba5a55be6b5"}, + {file = "ruff-0.9.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5f202f0d93738c28a89f8ed9eaba01b7be339e5d8d642c994347eaa81c6d75b8"}, + {file = "ruff-0.9.10-py3-none-win32.whl", hash = "sha256:bfb834e87c916521ce46b1788fbb8484966e5113c02df216680102e9eb960029"}, + {file = "ruff-0.9.10-py3-none-win_amd64.whl", hash = "sha256:f2160eeef3031bf4b17df74e307d4c5fb689a6f3a26a2de3f7ef4044e3c484f1"}, + {file = "ruff-0.9.10-py3-none-win_arm64.whl", hash = "sha256:5fd804c0327a5e5ea26615550e706942f348b197d5475ff34c19733aee4b2e69"}, + {file = "ruff-0.9.10.tar.gz", hash = "sha256:9bacb735d7bada9cfb0f2c227d3658fc443d90a727b47f206fb33f52f3c0eac7"}, ] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -groups = ["dev", "documentation", "test"] +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["documentation", "test"] files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1689,30 +1609,30 @@ markers = {dev = "python_version < \"3.11\"", linters = "python_version < \"3.11 [[package]] name = "tomlkit" -version = "0.13.2" +version = "0.13.3" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, - {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, + {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, + {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, ] [[package]] name = "tox" -version = "4.24.1" +version = "4.26.0" description = "tox is a generic virtualenv management and test command line tool" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tox-4.24.1-py3-none-any.whl", hash = "sha256:57ba7df7d199002c6df8c2db9e6484f3de6ca8f42013c083ea2d4d1e5c6bdc75"}, - {file = "tox-4.24.1.tar.gz", hash = "sha256:083a720adbc6166fff0b7d1df9d154f9d00bfccb9403b8abf6bc0ee435d6a62e"}, + {file = "tox-4.26.0-py3-none-any.whl", hash = "sha256:75f17aaf09face9b97bd41645028d9f722301e912be8b4c65a3f938024560224"}, + {file = "tox-4.26.0.tar.gz", hash = "sha256:a83b3b67b0159fa58e44e646505079e35a43317a62d2ae94725e0586266faeca"}, ] [package.dependencies] -cachetools = ">=5.5" +cachetools = ">=5.5.1" chardet = ">=5.2" colorama = ">=0.4.6" filelock = ">=3.16.1" @@ -1720,12 +1640,12 @@ packaging = ">=24.2" platformdirs = ">=4.3.6" pluggy = ">=1.5" pyproject-api = ">=1.8" -tomli = {version = ">=2.1", markers = "python_version < \"3.11\""} +tomli = {version = ">=2.2.1", markers = "python_version < \"3.11\""} typing-extensions = {version = ">=4.12.2", markers = "python_version < \"3.11\""} -virtualenv = ">=20.27.1" +virtualenv = ">=20.31" [package.extras] -test = ["devpi-process (>=1.0.2)", "pytest (>=8.3.3)", "pytest-mock (>=3.14)"] +test = ["devpi-process (>=1.0.2)", "pytest (>=8.3.4)", "pytest-mock (>=3.14)"] [[package]] name = "traitlets" @@ -1745,38 +1665,38 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "types-deprecated" -version = "1.2.15.20241117" +version = "1.2.15.20250304" description = "Typing stubs for Deprecated" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["linters"] files = [ - {file = "types-Deprecated-1.2.15.20241117.tar.gz", hash = "sha256:924002c8b7fddec51ba4949788a702411a2e3636cd9b2a33abd8ee119701d77e"}, - {file = "types_Deprecated-1.2.15.20241117-py3-none-any.whl", hash = "sha256:a0cc5e39f769fc54089fd8e005416b55d74aa03f6964d2ed1a0b0b2e28751884"}, + {file = "types_deprecated-1.2.15.20250304-py3-none-any.whl", hash = "sha256:86a65aa550ea8acf49f27e226b8953288cd851de887970fbbdf2239c116c3107"}, + {file = "types_deprecated-1.2.15.20250304.tar.gz", hash = "sha256:c329030553029de5cc6cb30f269c11f4e00e598c4241290179f63cda7d33f719"}, ] [[package]] name = "types-python-dateutil" -version = "2.9.0.20241206" +version = "2.9.0.20250516" description = "Typing stubs for python-dateutil" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["linters"] files = [ - {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, - {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, + {file = "types_python_dateutil-2.9.0.20250516-py3-none-any.whl", hash = "sha256:2b2b3f57f9c6a61fba26a9c0ffb9ea5681c9b83e69cd897c6b5f668d9c0cab93"}, + {file = "types_python_dateutil-2.9.0.20250516.tar.gz", hash = "sha256:13e80d6c9c47df23ad773d54b2826bd52dbbb41be87c3f339381c1700ad21ee5"}, ] [[package]] name = "types-pyyaml" -version = "6.0.12.20241230" +version = "6.0.12.20250516" description = "Typing stubs for PyYAML" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["linters"] files = [ - {file = "types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6"}, - {file = "types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c"}, + {file = "types_pyyaml-6.0.12.20250516-py3-none-any.whl", hash = "sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530"}, + {file = "types_pyyaml-6.0.12.20250516.tar.gz", hash = "sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba"}, ] [[package]] @@ -1793,27 +1713,27 @@ files = [ [[package]] name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" +version = "4.14.0" +description = "Backported and Experimental Type Hints for Python 3.9+" optional = false -python-versions = ">=3.8" -groups = ["main", "dev", "linters", "script"] +python-versions = ">=3.9" +groups = ["main", "dev", "linters", "script", "test"] files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, + {file = "typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af"}, + {file = "typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4"}, ] -markers = {main = "python_version < \"3.11\"", dev = "python_version < \"3.11\"", script = "python_version < \"3.11\""} +markers = {main = "python_version < \"3.11\"", dev = "python_version < \"3.11\"", script = "python_version < \"3.11\"", test = "python_version < \"3.11\""} [[package]] name = "urllib3" -version = "2.2.3" +version = "2.4.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["documentation"] files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"}, + {file = "urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"}, ] [package.extras] @@ -1824,14 +1744,14 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.27.1" +version = "20.31.2" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" groups = ["dev", "linters"] files = [ - {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, - {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, + {file = "virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11"}, + {file = "virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af"}, ] [package.dependencies] @@ -1841,7 +1761,7 @@ platformdirs = ">=3.9.1,<5" [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] [[package]] name = "watchdog" @@ -1900,90 +1820,104 @@ files = [ [[package]] name = "wrapt" -version = "1.17.0" +version = "1.17.2" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.8" groups = ["test"] files = [ - {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, - {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, - {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, - {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, - {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, - {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, - {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, - {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, - {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, - {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, - {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, - {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, - {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, - {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, - {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, - {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, - {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, - {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, - {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, - {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, - {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, - {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, - {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, - {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, - {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, - {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, - {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, - {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, - {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, - {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, - {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, - {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, - {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, - {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, - {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, - {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, - {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, - {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, - {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, - {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, - {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, - {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, - {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, - {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, - {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, - {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, - {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, - {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, - {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, - {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, - {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, - {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, - {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, - {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, - {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, - {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, - {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, - {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, - {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, - {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, - {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, - {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, - {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, - {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, - {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, + {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984"}, + {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22"}, + {file = "wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62"}, + {file = "wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563"}, + {file = "wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72"}, + {file = "wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317"}, + {file = "wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9"}, + {file = "wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9"}, + {file = "wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504"}, + {file = "wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a"}, + {file = "wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f"}, + {file = "wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555"}, + {file = "wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f"}, + {file = "wrapt-1.17.2-cp38-cp38-win32.whl", hash = "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7"}, + {file = "wrapt-1.17.2-cp38-cp38-win_amd64.whl", hash = "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9"}, + {file = "wrapt-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb"}, + {file = "wrapt-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb"}, + {file = "wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8"}, + {file = "wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3"}, ] [[package]] name = "zipp" -version = "3.21.0" +version = "3.22.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" groups = ["main", "documentation"] markers = "python_version == \"3.9\"" files = [ - {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, - {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, + {file = "zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343"}, + {file = "zipp-3.22.0.tar.gz", hash = "sha256:dd2f28c3ce4bc67507bfd3781d21b7bb2be31103b51a4553ad7d90b84e57ace5"}, ] [package.extras] @@ -1991,10 +1925,10 @@ check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \" cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +test = ["big-O", "importlib_resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "2951e44d1ec238ddef2139c76de3c838976a018b0993f7b84c6fd686e26fc5d0" +content-hash = "7375bf9072066831425c1b72fec016c42791695338c061324fb47420dafd2c8d" diff --git a/pyproject.toml b/pyproject.toml index cff51a2094..8215595737 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -121,7 +121,7 @@ deprecated = "^1.2.13" [tool.poetry.group.linters.dependencies] ruff = ">=0.5.0,<0.10.0" pre-commit = ">=2.18,<5.0" -mypy = "^1.4" +mypy = "^1.15.0" types-deprecated = "^1.2.9.2" types-python-dateutil = "^2.8.19.13" types-PyYAML = ">=5.4.3,<7.0.0" @@ -251,12 +251,7 @@ cover.help = "Run the test suite with coverage" cover.ref = "test --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen" all.help = "Run all tasks" -all.sequence = [ - "format", - "lint", - "cover", - "check-commit", -] +all.sequence = ["format", "lint", "cover", "check-commit"] "doc:screenshots".help = "Render documentation screenshots" "doc:screenshots".script = "scripts.gen_cli_help_screenshots:gen_cli_help_screenshots" @@ -268,10 +263,7 @@ doc.help = "Live documentation server" doc.cmd = "mkdocs serve" ci.help = "Run all tasks in CI" -ci.sequence = [ - { cmd = "pre-commit run --all-files" }, - "cover", -] +ci.sequence = [{ cmd = "pre-commit run --all-files" }, "cover"] ci.env = { SKIP = "no-commit-to-branch" } setup-pre-commit.help = "Install pre-commit hooks" From 18705031c303d3264e7402fb71c31170a7db23bb Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 22:08:12 +0800 Subject: [PATCH 524/598] refactor(bump): add type for out, replace function with re escape --- commitizen/bump.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/commitizen/bump.py b/commitizen/bump.py index b8ae18ba64..2fa814f7c8 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -103,13 +103,13 @@ def _files_and_regexes(patterns: list[str], version: str) -> list[tuple[str, str """ Resolve all distinct files with their regexp from a list of glob patterns with optional regexp """ - out = [] + out: list[tuple[str, str]] = [] for pattern in patterns: drive, tail = os.path.splitdrive(pattern) path, _, regex = tail.partition(":") filepath = drive + path if not regex: - regex = _version_to_regex(version) + regex = re.escape(version) for path in iglob(filepath): out.append((path, regex)) @@ -140,10 +140,6 @@ def _bump_with_regex( return current_version_found, "".join(lines) -def _version_to_regex(version: str) -> str: - return version.replace(".", r"\.").replace("+", r"\+") - - def create_commit_message( current_version: Version | str, new_version: Version | str, From 69a220c362c8a0dab364299a053dcb111c57157e Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 03:09:58 +0800 Subject: [PATCH 525/598] refactor(bump): clean up --- commitizen/commands/bump.py | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 0a2bbe37fc..d022599c76 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -105,19 +105,18 @@ def is_initial_tag( self, current_tag: git.GitTag | None, is_yes: bool = False ) -> bool: """Check if reading the whole git tree up to HEAD is needed.""" - is_initial = False - if not current_tag: - if is_yes: - is_initial = True - else: - out.info("No tag matching configuration could not be found.") - out.info( - "Possible causes:\n" - "- version in configuration is not the current version\n" - "- tag_format or legacy_tag_formats is missing, check them using 'git tag --list'\n" - ) - is_initial = questionary.confirm("Is this the first tag created?").ask() - return is_initial + if current_tag: + return False + if is_yes: + return True + + out.info("No tag matching configuration could not be found.") + out.info( + "Possible causes:\n" + "- version in configuration is not the current version\n" + "- tag_format or legacy_tag_formats is missing, check them using 'git tag --list'\n" + ) + return bool(questionary.confirm("Is this the first tag created?").ask()) def find_increment(self, commits: list[git.GitCommit]) -> Increment | None: # Update the bump map to ensure major version doesn't increment. @@ -134,10 +133,7 @@ def find_increment(self, commits: list[git.GitCommit]) -> Increment | None: raise NoPatternMapError( f"'{self.config.settings['name']}' rule does not support bump" ) - increment = bump.find_increment( - commits, regex=bump_pattern, increments_map=bump_map - ) - return increment + return bump.find_increment(commits, regex=bump_pattern, increments_map=bump_map) def __call__(self) -> None: # noqa: C901 """Steps executed to bump.""" @@ -148,7 +144,7 @@ def __call__(self) -> None: # noqa: C901 except TypeError: raise NoVersionSpecifiedError() - bump_commit_message: str = self.bump_settings["bump_message"] + bump_commit_message: str | None = self.bump_settings["bump_message"] version_files: list[str] = self.bump_settings["version_files"] major_version_zero: bool = self.bump_settings["major_version_zero"] prerelease_offset: int = self.bump_settings["prerelease_offset"] From b0f0d40ece88ca14c05b16d8fe760269096d7ca4 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 03:14:56 +0800 Subject: [PATCH 526/598] test(bump): improve test coverage --- commitizen/commands/bump.py | 4 +-- tests/commands/test_bump_command.py | 55 +++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index d022599c76..a2d98c2451 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -65,7 +65,7 @@ def __init__(self, config: BaseConfig, arguments: dict): "template", "file_name", ] - if arguments[key] is not None + if arguments.get(key) is not None }, } self.cz = factory.committer_factory(self.config) @@ -110,7 +110,7 @@ def is_initial_tag( if is_yes: return True - out.info("No tag matching configuration could not be found.") + out.info("No tag matching configuration could be found.") out.info( "Possible causes:\n" "- version in configuration is not the current version\n" diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index e15539d8a7..2af7bec121 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -12,8 +12,9 @@ from pytest_mock import MockFixture import commitizen.commands.bump as bump -from commitizen import cli, cmd, git, hooks +from commitizen import cli, cmd, defaults, git, hooks from commitizen.changelog_formats import ChangelogFormat +from commitizen.config.base_config import BaseConfig from commitizen.cz.base import BaseCommitizen from commitizen.exceptions import ( BumpTagFailedError, @@ -41,8 +42,8 @@ "fix(user): username exception", "refactor: remove ini configuration support", "refactor(config): remove ini configuration support", - "perf: update to use multiproess", - "perf(worker): update to use multiproess", + "perf: update to use multiprocess", + "perf(worker): update to use multiprocess", ), ) @pytest.mark.usefixtures("tmp_commitizen_project") @@ -1688,3 +1689,51 @@ def test_bump_warn_but_dont_fail_on_invalid_tags( assert err.count("Invalid version tag: '0.4.3.deadbeaf'") == 1 assert git.tag_exist("0.4.3") + + +def test_is_initial_tag(mocker: MockFixture, tmp_commitizen_project): + """Test the is_initial_tag method behavior.""" + # Create a commit but no tags + create_file_and_commit("feat: initial commit") + + # Initialize Bump with minimal config + config = BaseConfig() + config.settings.update( + { + "name": defaults.DEFAULT_SETTINGS["name"], + "encoding": "utf-8", + "pre_bump_hooks": [], + "post_bump_hooks": [], + } + ) + + # Initialize with required arguments + arguments = { + "changelog": False, + "changelog_to_stdout": False, + "git_output_to_stderr": False, + "no_verify": False, + "check_consistency": False, + "retry": False, + "version_scheme": None, + "file_name": None, + "template": None, + "extras": None, + } + + bump_cmd = bump.Bump(config, arguments) + + # Test case 1: No current tag, not yes mode + mocker.patch("questionary.confirm", return_value=mocker.Mock(ask=lambda: True)) + assert bump_cmd.is_initial_tag(None, is_yes=False) is True + + # Test case 2: No current tag, yes mode + assert bump_cmd.is_initial_tag(None, is_yes=True) is True + + # Test case 3: Has current tag + mock_tag = mocker.Mock() + assert bump_cmd.is_initial_tag(mock_tag, is_yes=False) is False + + # Test case 4: No current tag, user denies + mocker.patch("questionary.confirm", return_value=mocker.Mock(ask=lambda: False)) + assert bump_cmd.is_initial_tag(None, is_yes=False) is False From 74d3bc53d10cde3de9f56fec429416ff47fbbd18 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 22 May 2025 22:55:50 +0800 Subject: [PATCH 527/598] fix(defaults): add non-capitalized default constants back and deprecated warning relates #1446 --- commitizen/defaults.py | 29 +++++++++++++++++++++++++++++ tests/test_defaults.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 tests/test_defaults.py diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 1885848618..10d55b8621 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -1,6 +1,7 @@ from __future__ import annotations import pathlib +import warnings from collections import OrderedDict from collections.abc import Iterable, MutableMapping, Sequence from typing import Any, TypedDict @@ -153,3 +154,31 @@ def get_tag_regexes( **{f"${k}": v for k, v in regexes.items()}, **{f"${{{k}}}": v for k, v in regexes.items()}, } + + +def __getattr__(name: str) -> Any: + # PEP-562: deprecate module-level variable + + # {"deprecated key": (value, "new key")} + deprecated_vars = { + "bump_pattern": (BUMP_PATTERN, "BUMP_PATTERN"), + "bump_map": (BUMP_MAP, "BUMP_MAP"), + "bump_map_major_version_zero": ( + BUMP_MAP_MAJOR_VERSION_ZERO, + "BUMP_MAP_MAJOR_VERSION_ZERO", + ), + "bump_message": (BUMP_MESSAGE, "BUMP_MESSAGE"), + "change_type_order": (CHANGE_TYPE_ORDER, "CHANGE_TYPE_ORDER"), + "encoding": (ENCODING, "ENCODING"), + "name": (DEFAULT_SETTINGS["name"], "DEFAULT_SETTINGS['name']"), + } + if name in deprecated_vars: + value, replacement = deprecated_vars[name] + warnings.warn( + f"{name} is deprecated and will be removed in a future version. " + f"Use {replacement} instead.", + DeprecationWarning, + stacklevel=2, + ) + return value + raise AttributeError(f"{name} is not an attribute of {__name__}") diff --git a/tests/test_defaults.py b/tests/test_defaults.py new file mode 100644 index 0000000000..2298068662 --- /dev/null +++ b/tests/test_defaults.py @@ -0,0 +1,31 @@ +import pytest + +from commitizen import defaults + + +def test_getattr_deprecated_vars(): + # Test each deprecated variable + with pytest.warns(DeprecationWarning) as record: + assert defaults.bump_pattern == defaults.BUMP_PATTERN + assert defaults.bump_map == defaults.BUMP_MAP + assert ( + defaults.bump_map_major_version_zero == defaults.BUMP_MAP_MAJOR_VERSION_ZERO + ) + assert defaults.bump_message == defaults.BUMP_MESSAGE + assert defaults.change_type_order == defaults.CHANGE_TYPE_ORDER + assert defaults.encoding == defaults.ENCODING + assert defaults.name == defaults.DEFAULT_SETTINGS["name"] + + # Verify warning messages + assert len(record) == 7 + for warning in record: + assert "is deprecated and will be removed in a future version" in str( + warning.message + ) + + +def test_getattr_non_existent(): + # Test non-existent attribute + with pytest.raises(AttributeError) as exc_info: + _ = defaults.non_existent_attribute + assert "is not an attribute of" in str(exc_info.value) From 815f514b00300e628fad49e0400da760ab517bfb Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 17 May 2025 20:42:34 +0800 Subject: [PATCH 528/598] refactor: misc cleanup --- .../conventional_commits.py | 21 +++++++------------ commitizen/cz/jira/jira.py | 6 ++---- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index af29a209fc..9a2b9016b7 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -41,7 +41,7 @@ class ConventionalCommitsCz(BaseCommitizen): changelog_pattern = defaults.BUMP_PATTERN def questions(self) -> Questions: - questions: Questions = [ + return [ { "type": "list", "name": "prefix", @@ -146,7 +146,6 @@ def questions(self) -> Questions: ), }, ] - return questions def message(self, answers: dict) -> str: prefix = answers["prefix"] @@ -165,9 +164,7 @@ def message(self, answers: dict) -> str: if footer: footer = f"\n\n{footer}" - message = f"{prefix}{scope}: {subject}{body}{footer}" - - return message + return f"{prefix}{scope}: {subject}{body}{footer}" def example(self) -> str: return ( @@ -188,25 +185,21 @@ def schema(self) -> str: ) def schema_pattern(self) -> str: - PATTERN = ( + return ( r"(?s)" # To explicitly make . match new line r"(build|ci|docs|feat|fix|perf|refactor|style|test|chore|revert|bump)" # type r"(\(\S+\))?!?:" # scope r"( [^\n\r]+)" # subject r"((\n\n.*)|(\s*))?$" ) - return PATTERN 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, encoding=self.config.settings["encoding"]) as f: - content = f.read() - return content + return f.read() def process_commit(self, commit: str) -> str: - pat = re.compile(self.schema_pattern()) - m = re.match(pat, commit) - if m is None: - return "" - return m.group(3).strip() + if m := re.match(self.schema_pattern(), commit): + return m.group(3).strip() + return "" diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index b8fd056a71..f43de2177c 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -8,7 +8,7 @@ class JiraSmartCz(BaseCommitizen): def questions(self) -> Questions: - questions = [ + return [ { "type": "input", "name": "message", @@ -42,7 +42,6 @@ def questions(self) -> Questions: "filter": lambda x: "#comment " + x if x else "", }, ] - return questions def message(self, answers: dict) -> str: return " ".join( @@ -77,5 +76,4 @@ 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, encoding=self.config.settings["encoding"]) as f: - content = f.read() - return content + return f.read() From 03eff5cd86399c3d1ca16c0bfdba43cd29b2f996 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Tue, 20 May 2025 00:06:03 +0800 Subject: [PATCH 529/598] refactor(git): extract _create_commit_cmd_string --- commitizen/git.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/commitizen/git.py b/commitizen/git.py index fa59e34d48..ab2866ac48 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -181,19 +181,22 @@ def commit( f.write(message.encode("utf-8")) f.close() - command = f'git commit {args} -F "{f.name}"' - - if committer_date and os.name == "nt": # pragma: no cover - # Using `cmd /v /c "{command}"` sets environment variables only for that command - command = f'cmd /v /c "set GIT_COMMITTER_DATE={committer_date}&& {command}"' - elif committer_date: - command = f"GIT_COMMITTER_DATE={committer_date} {command}" - + command = _create_commit_cmd_string(args, committer_date, f.name) c = cmd.run(command) os.unlink(f.name) return c +def _create_commit_cmd_string(args: str, committer_date: str | None, name: str) -> str: + command = f'git commit {args} -F "{name}"' + if not committer_date: + return command + if os.name != "nt": + return f"GIT_COMMITTER_DATE={committer_date} {command}" + # Using `cmd /v /c "{command}"` sets environment variables only for that command + return f'cmd /v /c "set GIT_COMMITTER_DATE={committer_date}&& {command}"' + + def get_commits( start: str | None = None, end: str = "HEAD", From 3153e0795142f2b6d0f863d372cb547cfcdad57f Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 23 May 2025 16:24:05 +0800 Subject: [PATCH 530/598] test(test_git): mock os --- tests/test_git.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_git.py b/tests/test_git.py index de3130412b..3fecaabafd 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -449,3 +449,27 @@ def test_git_commit_from_rev_and_commit(): assert commit.author == "John Doe" assert commit.author_email == "john@example.com" assert commit.parents == [] + + +@pytest.mark.parametrize( + "os_name,committer_date,expected_cmd", + [ + ( + "nt", + "2024-03-20", + 'cmd /v /c "set GIT_COMMITTER_DATE=2024-03-20&& git commit -F "temp.txt""', + ), + ( + "posix", + "2024-03-20", + 'GIT_COMMITTER_DATE=2024-03-20 git commit -F "temp.txt"', + ), + ("nt", None, 'git commit -F "temp.txt"'), + ("posix", None, 'git commit -F "temp.txt"'), + ], +) +def test_create_commit_cmd_string(mocker, os_name, committer_date, expected_cmd): + """Test the OS-specific behavior of _create_commit_cmd_string""" + mocker.patch("os.name", os_name) + result = git._create_commit_cmd_string("", committer_date, "temp.txt") + assert result == expected_cmd From 876de4f8c1b1c4c3d0d4222c9affc1f2ab5f29c4 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 23 May 2025 22:20:58 +0800 Subject: [PATCH 531/598] refactor(cli): early return and improve test coverage --- commitizen/cli.py | 21 ++++++++--------- tests/test_cli.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index b566fc596d..deb5644d27 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -553,19 +553,20 @@ def commitizen_excepthook( type, value, traceback, debug=False, no_raise: list[int] | None = None ): traceback = traceback if isinstance(traceback, TracebackType) else None + if not isinstance(value, CommitizenException): + original_excepthook(type, value, traceback) + return + if not no_raise: no_raise = [] - if isinstance(value, CommitizenException): - if value.message: - value.output_method(value.message) - if debug: - original_excepthook(type, value, traceback) - exit_code = value.exit_code - if exit_code in no_raise: - exit_code = ExitCode.EXPECTED_EXIT - sys.exit(exit_code) - else: + if value.message: + value.output_method(value.message) + if debug: original_excepthook(type, value, traceback) + exit_code = value.exit_code + if exit_code in no_raise: + exit_code = ExitCode.EXPECTED_EXIT + sys.exit(exit_code) commitizen_debug_excepthook = partial(commitizen_excepthook, debug=True) diff --git a/tests/test_cli.py b/tests/test_cli.py index a91e633128..31371caea4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,6 +1,7 @@ import os import subprocess import sys +import types from functools import partial import pytest @@ -182,3 +183,59 @@ def test_unknown_args_before_double_dash_raises(mocker: MockFixture): assert "Invalid commitizen arguments were found before -- separator" in str( excinfo.value ) + + +def test_commitizen_excepthook_non_commitizen_exception(mocker: MockFixture): + """Test that commitizen_excepthook delegates to original_excepthook for non-CommitizenException.""" + # Mock the original excepthook + mock_original_excepthook = mocker.Mock() + mocker.patch("commitizen.cli.original_excepthook", mock_original_excepthook) + + # Create a regular exception + test_exception = ValueError("test error") + + # Call commitizen_excepthook with the regular exception + cli.commitizen_excepthook(ValueError, test_exception, None) + + # Verify original_excepthook was called with correct arguments + mock_original_excepthook.assert_called_once_with(ValueError, test_exception, None) + + +def test_commitizen_excepthook_non_commitizen_exception_with_traceback( + mocker: MockFixture, +): + """Test that commitizen_excepthook handles traceback correctly for non-CommitizenException.""" + # Mock the original excepthook + mock_original_excepthook = mocker.Mock() + mocker.patch("commitizen.cli.original_excepthook", mock_original_excepthook) + + # Create a regular exception with a traceback + test_exception = ValueError("test error") + test_traceback = mocker.Mock(spec=types.TracebackType) + + # Call commitizen_excepthook with the regular exception and traceback + cli.commitizen_excepthook(ValueError, test_exception, test_traceback) + + # Verify original_excepthook was called with correct arguments including traceback + mock_original_excepthook.assert_called_once_with( + ValueError, test_exception, test_traceback + ) + + +def test_commitizen_excepthook_non_commitizen_exception_with_invalid_traceback( + mocker: MockFixture, +): + """Test that commitizen_excepthook handles invalid traceback correctly for non-CommitizenException.""" + # Mock the original excepthook + mock_original_excepthook = mocker.Mock() + mocker.patch("commitizen.cli.original_excepthook", mock_original_excepthook) + + # Create a regular exception with an invalid traceback + test_exception = ValueError("test error") + test_traceback = mocker.Mock() # Not a TracebackType + + # Call commitizen_excepthook with the regular exception and invalid traceback + cli.commitizen_excepthook(ValueError, test_exception, test_traceback) + + # Verify original_excepthook was called with None as traceback + mock_original_excepthook.assert_called_once_with(ValueError, test_exception, None) From 52e44e5b4bcf62286d6545b5e3218bb54bafd6aa Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 24 May 2025 00:25:11 +0800 Subject: [PATCH 532/598] build(termcolor): remove termcolor <3 restriction --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index ceccd3da1c..b5dbcd9898 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1551,14 +1551,14 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] [[package]] name = "termcolor" -version = "2.5.0" +version = "3.1.0" description = "ANSI color formatting for output in terminal" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8"}, - {file = "termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f"}, + {file = "termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa"}, + {file = "termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970"}, ] [package.extras] @@ -1931,4 +1931,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "7375bf9072066831425c1b72fec016c42791695338c061324fb47420dafd2c8d" +content-hash = "5e42ee6a3a2b13c6f277b29f063fd8d71bf89841b1564636dffe56f7c65c33b4" diff --git a/pyproject.toml b/pyproject.toml index 8215595737..ac1eab66ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ dependencies = [ "questionary (>=2.0,<3.0)", "decli (>=0.6.0,<1.0)", "colorama (>=0.4.1,<1.0)", - "termcolor (>=1.1,<3)", + "termcolor (>=1.1.0,<4.0.0)", "packaging>=19", "tomlkit (>=0.5.3,<1.0.0)", "jinja2>=2.10.3", From edb21df5703332ae7320f7266021ec26c89891aa Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 25 May 2025 23:58:56 +0800 Subject: [PATCH 533/598] build: specify importlib-metadata version to fix unit tests --- poetry.lock | 95 ++++++++++++++++++++++++++++++++++++++++++++++---- pyproject.toml | 4 +-- 2 files changed, 91 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index b5dbcd9898..6a31d292fe 100644 --- a/poetry.lock +++ b/poetry.lock @@ -222,6 +222,7 @@ description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" groups = ["documentation"] +markers = "python_version == \"3.9\"" files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -230,6 +231,22 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "click" +version = "8.2.1" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.10" +groups = ["documentation"] +markers = "python_version != \"3.9\"" +files = [ + {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, + {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -510,12 +527,37 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 [[package]] name = "importlib-metadata" -version = "8.7.0" +version = "8.6.1" description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" groups = ["main", "documentation"] markers = "python_version == \"3.9\"" +files = [ + {file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"}, + {file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"}, +] + +[package.dependencies] +zipp = ">=3.20" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] + +[[package]] +name = "importlib-metadata" +version = "8.7.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version != \"3.9\"" files = [ {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, @@ -552,6 +594,7 @@ description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.9" groups = ["dev"] +markers = "python_version == \"3.9\"" files = [ {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, @@ -583,6 +626,46 @@ qtconsole = ["qtconsole"] test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] +[[package]] +name = "ipython" +version = "8.37.0" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +markers = "python_version != \"3.9\"" +files = [ + {file = "ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2"}, + {file = "ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} +prompt_toolkit = ">=3.0.41,<3.1.0" +pygments = ">=2.4.0" +stack_data = "*" +traitlets = ">=5.13.0" +typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} + +[package.extras] +all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] +black = ["black"] +doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli ; python_version < \"3.11\"", "typing_extensions"] +kernel = ["ipykernel"] +matplotlib = ["matplotlib"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["packaging", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "ipython[test]", "jupyter_ai", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"] + [[package]] name = "jedi" version = "0.19.2" @@ -1021,7 +1104,7 @@ description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" groups = ["dev"] -markers = "sys_platform != \"win32\"" +markers = "python_version == \"3.9\" and sys_platform != \"win32\" or sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, @@ -1124,7 +1207,7 @@ description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" groups = ["dev"] -markers = "sys_platform != \"win32\"" +markers = "python_version == \"3.9\" and sys_platform != \"win32\" or sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, @@ -1722,7 +1805,7 @@ files = [ {file = "typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af"}, {file = "typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4"}, ] -markers = {main = "python_version < \"3.11\"", dev = "python_version < \"3.11\"", script = "python_version < \"3.11\"", test = "python_version < \"3.11\""} +markers = {main = "python_version < \"3.11\"", dev = "python_version < \"3.12\"", script = "python_version < \"3.11\"", test = "python_version < \"3.11\""} [[package]] name = "urllib3" @@ -1914,11 +1997,11 @@ description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" groups = ["main", "documentation"] -markers = "python_version == \"3.9\"" files = [ {file = "zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343"}, {file = "zipp-3.22.0.tar.gz", hash = "sha256:dd2f28c3ce4bc67507bfd3781d21b7bb2be31103b51a4553ad7d90b84e57ace5"}, ] +markers = {documentation = "python_version == \"3.9\""} [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] @@ -1931,4 +2014,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "5e42ee6a3a2b13c6f277b29f063fd8d71bf89841b1564636dffe56f7c65c33b4" +content-hash = "146cae2abe0cdb8a831b9ece0aa1ee98366e3e4e17ef734f0e7001c4eb7508b3" diff --git a/pyproject.toml b/pyproject.toml index ac1eab66ca..144868e197 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,8 +23,8 @@ dependencies = [ "typing-extensions (>=4.0.1,<5.0.0) ; python_version < '3.11'", "charset-normalizer (>=2.1.0,<4)", # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility - "importlib_metadata (>=8.0.0,<9) ; python_version < '3.10'", - + "importlib-metadata >=8.0.0,!=8.7.0,<9.0.0 ; python_version == '3.9'", # importlib-metadata@8.7.0 + python3.9 breaks our unit test + "importlib-metadata >=8.0.0,<9.0.0 ; python_version != '3.9'", ] keywords = ["commitizen", "conventional", "commits", "git"] # See also: https://pypi.org/classifiers/ From 7750f420822ff4be81e103da34051c866c5a944f Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 24 May 2025 15:50:21 +0800 Subject: [PATCH 534/598] refactor(changelog): better typing, yield --- commitizen/changelog.py | 33 +++++++++++++++++--------------- commitizen/commands/changelog.py | 4 +++- tests/test_changelog.py | 16 ++++++++-------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index d8ab56069b..bac4d824f9 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -29,10 +29,10 @@ import re from collections import OrderedDict, defaultdict -from collections.abc import Iterable +from collections.abc import Generator, Iterable, Mapping from dataclasses import dataclass from datetime import date -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from jinja2 import ( BaseLoader, @@ -84,7 +84,7 @@ def generate_tree_from_commits( changelog_message_builder_hook: MessageBuilderHook | None = None, changelog_release_hook: ChangelogReleaseHook | None = None, rules: TagRules | None = None, -) -> Iterable[dict]: +) -> Generator[dict[str, Any], None, None]: pat = re.compile(changelog_pattern) map_pat = re.compile(commit_parser, re.MULTILINE) body_map_pat = re.compile(commit_parser, re.MULTILINE | re.DOTALL) @@ -187,24 +187,27 @@ def process_commit_message( changes[change_type].append(msg) -def order_changelog_tree(tree: Iterable, change_type_order: list[str]) -> Iterable: +def generate_ordered_changelog_tree( + tree: Iterable[Mapping[str, Any]], change_type_order: list[str] +) -> Generator[dict[str, Any], None, None]: if len(set(change_type_order)) != len(change_type_order): raise InvalidConfigurationError( f"Change types contain duplicated types ({change_type_order})" ) - sorted_tree = [] for entry in tree: - ordered_change_types = change_type_order + sorted( - set(entry["changes"].keys()) - set(change_type_order) - ) - changes = [ - (ct, entry["changes"][ct]) - for ct in ordered_change_types - if ct in entry["changes"] - ] - sorted_tree.append({**entry, **{"changes": OrderedDict(changes)}}) - return sorted_tree + yield { + **entry, + "changes": _calculate_sorted_changes(change_type_order, entry["changes"]), + } + + +def _calculate_sorted_changes( + change_type_order: list[str], changes: Mapping[str, Any] +) -> OrderedDict[str, Any]: + remaining_change_types = set(changes.keys()) - set(change_type_order) + sorted_change_types = change_type_order + sorted(remaining_change_types) + return OrderedDict((ct, changes[ct]) for ct in sorted_change_types if ct in changes) def get_changelog_template(loader: BaseLoader, template: str) -> Template: diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 9ab8fdc37c..7bf644a934 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -215,7 +215,9 @@ def __call__(self): rules=self.tag_rules, ) if self.change_type_order: - tree = changelog.order_changelog_tree(tree, self.change_type_order) + tree = changelog.generate_ordered_changelog_tree( + tree, self.change_type_order + ) extras = self.cz.template_extras.copy() extras.update(self.config.settings["extras"]) diff --git a/tests/test_changelog.py b/tests/test_changelog.py index d42176f09a..ed90ed08e4 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1215,26 +1215,26 @@ def test_generate_tree_from_commits_with_no_commits(tags): ), ), ) -def test_order_changelog_tree(change_type_order, expected_reordering): - tree = changelog.order_changelog_tree(COMMITS_TREE, change_type_order) +def test_generate_ordered_changelog_tree(change_type_order, expected_reordering): + tree = changelog.generate_ordered_changelog_tree(COMMITS_TREE, change_type_order) for index, entry in enumerate(tuple(tree)): - version = tree[index]["version"] + version = entry["version"] if version in expected_reordering: # Verify that all keys are present - assert [*tree[index].keys()] == [*COMMITS_TREE[index].keys()] + assert [*entry.keys()] == [*COMMITS_TREE[index].keys()] # Verify that the reorder only impacted the returned dict and not the original expected = expected_reordering[version] - assert [*tree[index]["changes"].keys()] == expected["sorted"] + assert [*entry["changes"].keys()] == expected["sorted"] assert [*COMMITS_TREE[index]["changes"].keys()] == expected["original"] else: - assert [*entry["changes"].keys()] == [*tree[index]["changes"].keys()] + assert [*entry["changes"].keys()] == [*entry["changes"].keys()] -def test_order_changelog_tree_raises(): +def test_generate_ordered_changelog_tree_raises(): change_type_order = ["BREAKING CHANGE", "feat", "refactor", "feat"] with pytest.raises(InvalidConfigurationError) as excinfo: - changelog.order_changelog_tree(COMMITS_TREE, change_type_order) + list(changelog.generate_ordered_changelog_tree(COMMITS_TREE, change_type_order)) assert "Change types contain duplicated types" in str(excinfo) From fcd609e72ba71ec14d83fb7a64e64503f268f314 Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 13:28:42 +0800 Subject: [PATCH 535/598] build(deps-dev): bump mypy to 1.16.0 --- poetry.lock | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6a31d292fe..cbe0fb0e3c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2014,4 +2014,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "146cae2abe0cdb8a831b9ece0aa1ee98366e3e4e17ef734f0e7001c4eb7508b3" +content-hash = "6eea6e061a2ece897c2fb37b0b5116085057e6d97e1f22c0fcd4294fb0ad1dbf" diff --git a/pyproject.toml b/pyproject.toml index 144868e197..1a29ca6bf9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -121,7 +121,7 @@ deprecated = "^1.2.13" [tool.poetry.group.linters.dependencies] ruff = ">=0.5.0,<0.10.0" pre-commit = ">=2.18,<5.0" -mypy = "^1.15.0" +mypy = "^1.16.0" types-deprecated = "^1.2.9.2" types-python-dateutil = "^2.8.19.13" types-PyYAML = ">=5.4.3,<7.0.0" From b4c8aa35e70e1ca6438497f658dedecfcbdc7656 Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 13:28:57 +0800 Subject: [PATCH 536/598] refactor(mypy): remove `unused-ignore` --- commitizen/config/json_config.py | 2 +- commitizen/config/toml_config.py | 2 +- commitizen/config/yaml_config.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/commitizen/config/json_config.py b/commitizen/config/json_config.py index d413d73383..28fac25662 100644 --- a/commitizen/config/json_config.py +++ b/commitizen/config/json_config.py @@ -13,7 +13,7 @@ class JsonConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super().__init__() self.is_empty_config = False - self.path = path # type: ignore + self.path = path self._parse_setting(data) def init_empty_config_content(self): diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index e2cfcc9340..a7050214ba 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -14,7 +14,7 @@ class TomlConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super().__init__() self.is_empty_config = False - self.path = path # type: ignore + self.path = path self._parse_setting(data) def init_empty_config_content(self): diff --git a/commitizen/config/yaml_config.py b/commitizen/config/yaml_config.py index c5721c8d4b..2c384cf17d 100644 --- a/commitizen/config/yaml_config.py +++ b/commitizen/config/yaml_config.py @@ -14,7 +14,7 @@ class YAMLConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): super().__init__() self.is_empty_config = False - self.path = path # type: ignore + self.path = path self._parse_setting(data) def init_empty_config_content(self): From 94b9796453e250c76f1bc4455c5542c2339cf7be Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 11:08:12 +0800 Subject: [PATCH 537/598] refactor(cli.py): add type hints --- commitizen/cli.py | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index deb5644d27..04a99e8c37 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -8,7 +8,7 @@ from functools import partial from pathlib import Path from types import TracebackType -from typing import Any +from typing import TYPE_CHECKING, Any, cast import argcomplete from decli import cli @@ -596,8 +596,33 @@ def parse_no_raise(comma_separated_no_raise: str) -> list[int]: return no_raise_codes +if TYPE_CHECKING: + + class Args(argparse.Namespace): + config: str | None = None + debug: bool = False + name: str | None = None + no_raise: str | None = None + report: bool = False + project: bool = False + commitizen: bool = False + verbose: bool = False + func: type[ + commands.Init # init + | commands.Commit # commit (c) + | commands.ListCz # ls + | commands.Example # example + | commands.Info # info + | commands.Schema # schema + | commands.Bump # bump + | commands.Changelog # changelog (ch) + | commands.Check # check + | commands.Version # version + ] + + def main(): - parser = cli(data) + parser: argparse.ArgumentParser = cli(data) argcomplete.autocomplete(parser) # Show help if no arg provided if len(sys.argv) == 1: @@ -611,7 +636,7 @@ def main(): # https://github.com/commitizen-tools/commitizen/issues/429 # argparse raises TypeError when non exist command is provided on Python < 3.9 # but raise SystemExit with exit code == 2 on Python 3.9 - if isinstance(e, TypeError) or (isinstance(e, SystemExit) and e.code == 2): + if isinstance(e, TypeError) or e.code == 2: raise NoCommandFoundError() raise e @@ -638,6 +663,7 @@ def main(): arguments["extra_cli_args"] = extra_args conf = config.read_cfg(args.config) + args = cast("Args", args) if args.name: conf.update({"name": args.name}) elif not conf.path: From a5033ab42c75bc859be94872ff80d474425a109d Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 13:55:34 +0800 Subject: [PATCH 538/598] refactor: add comment clarifying `no_raise` parsing to `list[int]` --- commitizen/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 04a99e8c37..861ba578a9 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -602,7 +602,7 @@ class Args(argparse.Namespace): config: str | None = None debug: bool = False name: str | None = None - no_raise: str | None = None + no_raise: str | None = None # comma-separated string, later parsed as list[int] report: bool = False project: bool = False commitizen: bool = False From 8055c9509283227def93235561b8675f504f4c18 Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 14:24:07 +0800 Subject: [PATCH 539/598] refactor: remove `TypeError` handling since `Python >=3.9` is required Since the project requires Python >=3.9, argparse only raises SystemExit when non-existent commands are provided, making TypeError handling unnecessary. --- commitizen/cli.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 861ba578a9..d245f731e3 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -632,11 +632,8 @@ def main(): # This is for the command required constraint in 2.0 try: args, unknown_args = parser.parse_known_args() - except (TypeError, SystemExit) as e: - # https://github.com/commitizen-tools/commitizen/issues/429 - # argparse raises TypeError when non exist command is provided on Python < 3.9 - # but raise SystemExit with exit code == 2 on Python 3.9 - if isinstance(e, TypeError) or e.code == 2: + except SystemExit as e: + if e.code == 2: raise NoCommandFoundError() raise e From 9f67a43286c28778458faa76e66f81e588523b39 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 2 Jun 2025 01:16:21 +0800 Subject: [PATCH 540/598] fix(deprecated): mark deprecate in v5 --- commitizen/commands/bump.py | 2 +- commitizen/defaults.py | 2 +- commitizen/version_schemes.py | 2 +- docs/commands/commit.md | 2 +- tests/test_defaults.py | 4 +--- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index a2d98c2451..3f909d97cb 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -82,7 +82,7 @@ def __init__(self, config: BaseConfig, arguments: dict): if deprecated_version_type: warnings.warn( DeprecationWarning( - "`--version-type` parameter is deprecated and will be removed in commitizen 4. " + "`--version-type` parameter is deprecated and will be removed in v5. " "Please use `--version-scheme` instead" ) ) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 10d55b8621..adbb9e6d1a 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -175,7 +175,7 @@ def __getattr__(name: str) -> Any: if name in deprecated_vars: value, replacement = deprecated_vars[name] warnings.warn( - f"{name} is deprecated and will be removed in a future version. " + f"{name} is deprecated and will be removed in v5. " f"Use {replacement} instead.", DeprecationWarning, stacklevel=2, diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index d5370b2c6c..2a5f7dc6e0 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -419,7 +419,7 @@ def get_version_scheme(settings: Settings, name: str | None = None) -> VersionSc if deprecated_setting: warnings.warn( DeprecationWarning( - "`version_type` setting is deprecated and will be removed in commitizen 4. " + "`version_type` setting is deprecated and will be removed in v5. " "Please use `version_scheme` instead" ) ) diff --git a/docs/commands/commit.md b/docs/commands/commit.md index 5a073a2644..be9d193b97 100644 --- a/docs/commands/commit.md +++ b/docs/commands/commit.md @@ -42,7 +42,7 @@ cz c -a -- -n # Stage all changes and skip the pre-commit and commit- ``` !!! warning - The `--signoff` option (or `-s`) is now recommended being used with the new syntax: `cz commit -- -s`. The old syntax `cz commit --signoff` is deprecated. + The `--signoff` option (or `-s`) is now recommended being used with the new syntax: `cz commit -- -s`. The old syntax `cz commit --signoff` is deprecated and will be removed in v5. ### Retry diff --git a/tests/test_defaults.py b/tests/test_defaults.py index 2298068662..73cd35b80c 100644 --- a/tests/test_defaults.py +++ b/tests/test_defaults.py @@ -19,9 +19,7 @@ def test_getattr_deprecated_vars(): # Verify warning messages assert len(record) == 7 for warning in record: - assert "is deprecated and will be removed in a future version" in str( - warning.message - ) + assert "is deprecated and will be removed" in str(warning.message) def test_getattr_non_existent(): From 1f9578fcbc9c23d0ff221e3e61f96b7e69b3bb96 Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 15:25:28 +0800 Subject: [PATCH 541/598] build(deps-dev): bump ruff --- poetry.lock | 40 ++++++++++++++++++++-------------------- pyproject.toml | 3 ++- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index cbe0fb0e3c..f9f74513a8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1574,30 +1574,30 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.9.10" +version = "0.11.13" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" groups = ["linters"] files = [ - {file = "ruff-0.9.10-py3-none-linux_armv6l.whl", hash = "sha256:eb4d25532cfd9fe461acc83498361ec2e2252795b4f40b17e80692814329e42d"}, - {file = "ruff-0.9.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:188a6638dab1aa9bb6228a7302387b2c9954e455fb25d6b4470cb0641d16759d"}, - {file = "ruff-0.9.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5284dcac6b9dbc2fcb71fdfc26a217b2ca4ede6ccd57476f52a587451ebe450d"}, - {file = "ruff-0.9.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47678f39fa2a3da62724851107f438c8229a3470f533894b5568a39b40029c0c"}, - {file = "ruff-0.9.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99713a6e2766b7a17147b309e8c915b32b07a25c9efd12ada79f217c9c778b3e"}, - {file = "ruff-0.9.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524ee184d92f7c7304aa568e2db20f50c32d1d0caa235d8ddf10497566ea1a12"}, - {file = "ruff-0.9.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:df92aeac30af821f9acf819fc01b4afc3dfb829d2782884f8739fb52a8119a16"}, - {file = "ruff-0.9.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de42e4edc296f520bb84954eb992a07a0ec5a02fecb834498415908469854a52"}, - {file = "ruff-0.9.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d257f95b65806104b6b1ffca0ea53f4ef98454036df65b1eda3693534813ecd1"}, - {file = "ruff-0.9.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60dec7201c0b10d6d11be00e8f2dbb6f40ef1828ee75ed739923799513db24c"}, - {file = "ruff-0.9.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d838b60007da7a39c046fcdd317293d10b845001f38bcb55ba766c3875b01e43"}, - {file = "ruff-0.9.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ccaf903108b899beb8e09a63ffae5869057ab649c1e9231c05ae354ebc62066c"}, - {file = "ruff-0.9.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f9567d135265d46e59d62dc60c0bfad10e9a6822e231f5b24032dba5a55be6b5"}, - {file = "ruff-0.9.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5f202f0d93738c28a89f8ed9eaba01b7be339e5d8d642c994347eaa81c6d75b8"}, - {file = "ruff-0.9.10-py3-none-win32.whl", hash = "sha256:bfb834e87c916521ce46b1788fbb8484966e5113c02df216680102e9eb960029"}, - {file = "ruff-0.9.10-py3-none-win_amd64.whl", hash = "sha256:f2160eeef3031bf4b17df74e307d4c5fb689a6f3a26a2de3f7ef4044e3c484f1"}, - {file = "ruff-0.9.10-py3-none-win_arm64.whl", hash = "sha256:5fd804c0327a5e5ea26615550e706942f348b197d5475ff34c19733aee4b2e69"}, - {file = "ruff-0.9.10.tar.gz", hash = "sha256:9bacb735d7bada9cfb0f2c227d3658fc443d90a727b47f206fb33f52f3c0eac7"}, + {file = "ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46"}, + {file = "ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48"}, + {file = "ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9"}, + {file = "ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc"}, + {file = "ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7"}, + {file = "ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432"}, + {file = "ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492"}, + {file = "ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250"}, + {file = "ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3"}, + {file = "ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b"}, + {file = "ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514"}, ] [[package]] @@ -2014,4 +2014,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "6eea6e061a2ece897c2fb37b0b5116085057e6d97e1f22c0fcd4294fb0ad1dbf" +content-hash = "10e298e9b4d2f2d81a82b43649a68d557ed3e9824b3b210b5b6a607935f9fe9d" diff --git a/pyproject.toml b/pyproject.toml index 1a29ca6bf9..d1e89cbed0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -119,7 +119,7 @@ pytest-xdist = "^3.1.0" deprecated = "^1.2.13" [tool.poetry.group.linters.dependencies] -ruff = ">=0.5.0,<0.10.0" +ruff = "^0.11.5" pre-commit = ">=2.18,<5.0" mypy = "^1.16.0" types-deprecated = "^1.2.9.2" @@ -182,6 +182,7 @@ commands_pre = [["poetry", "install", "--only", "main,test"]] commands = [["pytest", { replace = "posargs", extend = true }]] [tool.ruff] +required-version = ">=0.11.5" line-length = 88 [tool.ruff.lint] From 82cdfff22fa1bdf7ed3bf2fb673e6a07d5adf33d Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 15:30:28 +0800 Subject: [PATCH 542/598] style(ruff): resolve F401 --- commitizen/version_schemes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 2a5f7dc6e0..96a68b05fd 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -19,7 +19,7 @@ else: import importlib_metadata as metadata -from packaging.version import InvalidVersion # noqa: F401: expose the common exception +from packaging.version import InvalidVersion # noqa: F401 (expose the common exception) from packaging.version import Version as _BaseVersion from commitizen.defaults import MAJOR, MINOR, PATCH, Settings From ac3318dd19a7569dc8e887b956d6ef447aec25c8 Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 15:40:08 +0800 Subject: [PATCH 543/598] build(ruff): add RUF022 & RUF100 rules --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index d1e89cbed0..757c72bc0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -195,6 +195,10 @@ select = [ "UP", # isort "I", + # unsorted-dunder-all + "RUF022", + # unused-noqa + "RUF100", ] ignore = ["E501", "D1", "D415"] From 922bdc30cb9aa679f2be4fa19997d0d05b394fe9 Mon Sep 17 00:00:00 2001 From: gbaian10 <gbaian10@gmail.com> Date: Sat, 31 May 2025 15:41:42 +0800 Subject: [PATCH 544/598] style(ruff): run `ruff check --fix` Auto fix RUF022 and RUF100 --- commitizen/commands/__init__.py | 4 ++-- commitizen/commands/bump.py | 2 +- commitizen/cz/conventional_commits/conventional_commits.py | 2 +- commitizen/cz/jira/jira.py | 2 +- commitizen/providers/__init__.py | 2 +- tests/conftest.py | 2 +- tests/test_bump_find_increment.py | 4 ++-- tests/test_cz_conventional_commits.py | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/commitizen/commands/__init__.py b/commitizen/commands/__init__.py index 806e384522..58b18297dc 100644 --- a/commitizen/commands/__init__.py +++ b/commitizen/commands/__init__.py @@ -11,13 +11,13 @@ __all__ = ( "Bump", + "Changelog", "Check", "Commit", - "Changelog", "Example", "Info", + "Init", "ListCz", "Schema", "Version", - "Init", ) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 3f909d97cb..9556492499 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -135,7 +135,7 @@ def find_increment(self, commits: list[git.GitCommit]) -> Increment | None: ) return bump.find_increment(commits, regex=bump_pattern, increments_map=bump_map) - def __call__(self) -> None: # noqa: C901 + def __call__(self) -> None: """Steps executed to bump.""" provider = get_provider(self.config) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 9a2b9016b7..ff79119886 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -31,7 +31,7 @@ class ConventionalCommitsCz(BaseCommitizen): bump_pattern = defaults.BUMP_PATTERN bump_map = defaults.BUMP_MAP bump_map_major_version_zero = defaults.BUMP_MAP_MAJOR_VERSION_ZERO - commit_parser = r"^((?P<change_type>feat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P<scope>[^()\r\n]*)\)|\()?(?P<breaking>!)?|\w+!):\s(?P<message>.*)?" # noqa + commit_parser = r"^((?P<change_type>feat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P<scope>[^()\r\n]*)\)|\()?(?P<breaking>!)?|\w+!):\s(?P<message>.*)?" change_type_map = { "feat": "Feat", "fix": "Fix", diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index f43de2177c..05e23e1690 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -67,7 +67,7 @@ def example(self) -> str: ) def schema(self) -> str: - return "<ignored text> <ISSUE_KEY> <ignored text> #<COMMAND> <optional COMMAND_ARGUMENTS>" # noqa + return "<ignored text> <ISSUE_KEY> <ignored text> #<COMMAND> <optional COMMAND_ARGUMENTS>" def schema_pattern(self) -> str: return r".*[A-Z]{2,}\-[0-9]+( #| .* #).+( #.+)*" diff --git a/commitizen/providers/__init__.py b/commitizen/providers/__init__.py index 9cf4ce5927..3e01fe22f8 100644 --- a/commitizen/providers/__init__.py +++ b/commitizen/providers/__init__.py @@ -21,7 +21,6 @@ from commitizen.providers.uv_provider import UvProvider __all__ = [ - "get_provider", "CargoProvider", "CommitizenProvider", "ComposerProvider", @@ -30,6 +29,7 @@ "PoetryProvider", "ScmProvider", "UvProvider", + "get_provider", ] PROVIDER_ENTRYPOINT = "commitizen.provider" diff --git a/tests/conftest.py b/tests/conftest.py index 60c586f2e6..1b49dcbfaa 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -169,7 +169,7 @@ class SemverCommitizen(BaseCommitizen): "patch": "PATCH", } changelog_pattern = r"^(patch|minor|major)" - commit_parser = r"^(?P<change_type>patch|minor|major)(?:\((?P<scope>[^()\r\n]*)\)|\()?:?\s(?P<message>.+)" # noqa + commit_parser = r"^(?P<change_type>patch|minor|major)(?:\((?P<scope>[^()\r\n]*)\)|\()?:?\s(?P<message>.+)" change_type_map = { "major": "Breaking Changes", "minor": "Features", diff --git a/tests/test_bump_find_increment.py b/tests/test_bump_find_increment.py index ff24ff17a7..77e11c78c7 100644 --- a/tests/test_bump_find_increment.py +++ b/tests/test_bump_find_increment.py @@ -32,14 +32,14 @@ MAJOR_INCREMENTS_BREAKING_CHANGE_CC = [ "feat(cli): added version", "docs(README): motivation", - "BREAKING CHANGE: `extends` key in config file is now used for extending other config files", # noqa + "BREAKING CHANGE: `extends` key in config file is now used for extending other config files", "fix(setup.py): future is now required for every python version", ] MAJOR_INCREMENTS_BREAKING_CHANGE_ALT_CC = [ "feat(cli): added version", "docs(README): motivation", - "BREAKING-CHANGE: `extends` key in config file is now used for extending other config files", # noqa + "BREAKING-CHANGE: `extends` key in config file is now used for extending other config files", "fix(setup.py): future is now required for every python version", ] diff --git a/tests/test_cz_conventional_commits.py b/tests/test_cz_conventional_commits.py index 6d4e0f7435..7863e2f38c 100644 --- a/tests/test_cz_conventional_commits.py +++ b/tests/test_cz_conventional_commits.py @@ -89,7 +89,7 @@ def test_long_answer(config): message = conventional_commits.message(answers) assert ( message - == "fix(users): email pattern corrected\n\ncomplete content\n\ncloses #24" # noqa + == "fix(users): email pattern corrected\n\ncomplete content\n\ncloses #24" ) @@ -107,7 +107,7 @@ def test_breaking_change_in_footer(config): print(message) assert ( message - == "fix(users): email pattern corrected\n\ncomplete content\n\nBREAKING CHANGE: migrate by renaming user to users" # noqa + == "fix(users): email pattern corrected\n\ncomplete content\n\nBREAKING CHANGE: migrate by renaming user to users" ) From b6ad3d23cd3cd90f2f235f0fc7e501e551097087 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 12:10:17 +0800 Subject: [PATCH 545/598] refactor(BaseCommitizen): remove unused process_commit --- commitizen/cz/base.py | 7 ------ .../conventional_commits.py | 6 ----- tests/test_cz_base.py | 6 ----- tests/test_cz_conventional_commits.py | 23 ------------------- 4 files changed, 42 deletions(-) diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 43455a74ca..7463a67c24 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -99,10 +99,3 @@ def schema_pattern(self) -> str: def info(self) -> str: """Information about the standardized commit message.""" raise NotImplementedError("Not Implemented yet") - - def process_commit(self, commit: str) -> str: - """Process commit for changelog. - - If not overwritten, it returns the first line of commit. - """ - return commit.split("\n")[0] diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index ff79119886..320aa9b324 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -1,5 +1,4 @@ import os -import re from commitizen import defaults from commitizen.cz.base import BaseCommitizen @@ -198,8 +197,3 @@ def info(self) -> str: filepath = os.path.join(dir_path, "conventional_commits_info.txt") with open(filepath, encoding=self.config.settings["encoding"]) as f: return f.read() - - def process_commit(self, commit: str) -> str: - if m := re.match(self.schema_pattern(), commit): - return m.group(3).strip() - return "" diff --git a/tests/test_cz_base.py b/tests/test_cz_base.py index 4ee1cc6eda..be93b4ca0f 100644 --- a/tests/test_cz_base.py +++ b/tests/test_cz_base.py @@ -42,9 +42,3 @@ def test_info(config): cz = DummyCz(config) with pytest.raises(NotImplementedError): cz.info() - - -def test_process_commit(config): - cz = DummyCz(config) - message = cz.process_commit("test(test_scope): this is test msg") - assert message == "test(test_scope): this is test msg" diff --git a/tests/test_cz_conventional_commits.py b/tests/test_cz_conventional_commits.py index 7863e2f38c..89653f4c63 100644 --- a/tests/test_cz_conventional_commits.py +++ b/tests/test_cz_conventional_commits.py @@ -130,26 +130,3 @@ def test_info(config): conventional_commits = ConventionalCommitsCz(config) info = conventional_commits.info() assert isinstance(info, str) - - -@pytest.mark.parametrize( - ("commit_message", "expected_message"), - [ - ( - "test(test_scope): this is test msg", - "this is test msg", - ), - ( - "test(test_scope)!: this is test msg", - "this is test msg", - ), - ( - "test!(test_scope): this is test msg", - "", - ), - ], -) -def test_process_commit(commit_message, expected_message, config): - conventional_commits = ConventionalCommitsCz(config) - message = conventional_commits.process_commit(commit_message) - assert message == expected_message From 8c335705aef9acc83276d4be1c8798a1d2a0f1f6 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 29 May 2025 22:13:11 +0800 Subject: [PATCH 546/598] style(tags): improve types --- commitizen/tags.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/commitizen/tags.py b/commitizen/tags.py index c5f06884fe..4231e0053e 100644 --- a/commitizen/tags.py +++ b/commitizen/tags.py @@ -2,7 +2,7 @@ import re import warnings -from collections.abc import Sequence +from collections.abc import Iterable, Sequence from dataclasses import dataclass, field from functools import cached_property from string import Template @@ -89,14 +89,14 @@ class TagRules: merge_prereleases: bool = False @cached_property - def version_regexes(self) -> Sequence[re.Pattern]: + def version_regexes(self) -> list[re.Pattern]: """Regexes for all legit tag formats, current and legacy""" tag_formats = [self.tag_format, *self.legacy_tag_formats] regexes = (self._format_regex(p) for p in tag_formats) return [re.compile(r) for r in regexes] @cached_property - def ignored_regexes(self) -> Sequence[re.Pattern]: + def ignored_regexes(self) -> list[re.Pattern]: """Regexes for known but ignored tag formats""" regexes = (self._format_regex(p, star=True) for p in self.ignored_tag_formats) return [re.compile(r) for r in regexes] @@ -135,8 +135,8 @@ def is_ignored_tag(self, tag: str | GitTag) -> bool: return any(regex.match(tag) for regex in self.ignored_regexes) def get_version_tags( - self, tags: Sequence[GitTag], warn: bool = False - ) -> Sequence[GitTag]: + self, tags: Iterable[GitTag], warn: bool = False + ) -> list[GitTag]: """Filter in version tags and warn on unexpected tags""" return [tag for tag in tags if self.is_version_tag(tag, warn)] @@ -236,7 +236,7 @@ def normalize_tag( ) def find_tag_for( - self, tags: Sequence[GitTag], version: Version | str + self, tags: Iterable[GitTag], version: Version | str ) -> GitTag | None: """Find the first matching tag for a given version.""" version = self.scheme(version) if isinstance(version, str) else version From 28b3b9b8b553acb379a18f313ba8ec88e895ab6a Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 29 May 2025 22:18:06 +0800 Subject: [PATCH 547/598] perf(tags): use set --- commitizen/tags.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commitizen/tags.py b/commitizen/tags.py index 4231e0053e..b19bb89e09 100644 --- a/commitizen/tags.py +++ b/commitizen/tags.py @@ -240,11 +240,11 @@ def find_tag_for( ) -> GitTag | None: """Find the first matching tag for a given version.""" version = self.scheme(version) if isinstance(version, str) else version - possible_tags = [ + possible_tags = set( self.normalize_tag(version, f) for f in (self.tag_format, *self.legacy_tag_formats) - ] - candidates = [t for t in tags if any(t.name == p for p in possible_tags)] + ) + candidates = [t for t in tags if t.name in possible_tags] if len(candidates) > 1: warnings.warn( UserWarning( From 898d054a443d6fd591e5a7e8c4156f7e95038287 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Thu, 29 May 2025 23:20:33 +0800 Subject: [PATCH 548/598] refactor: fix mypy output and better type --- commitizen/changelog.py | 10 ++++---- commitizen/cli.py | 14 +++++++---- commitizen/cmd.py | 5 ++-- commitizen/commands/changelog.py | 24 ++++++++++--------- commitizen/commands/check.py | 10 ++++---- commitizen/commands/commit.py | 14 +++++++---- commitizen/commands/info.py | 4 ++-- commitizen/commands/init.py | 8 +++---- commitizen/commands/list_cz.py | 4 ++-- commitizen/commands/version.py | 6 +++-- commitizen/config/base_config.py | 2 +- .../conventional_commits.py | 4 ++-- commitizen/cz/utils.py | 5 ++-- commitizen/exceptions.py | 7 +++--- commitizen/git.py | 20 +++++++++------- commitizen/out.py | 7 +++--- tests/test_git.py | 7 ++++++ 17 files changed, 90 insertions(+), 61 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index bac4d824f9..6526b4c540 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -29,7 +29,7 @@ import re from collections import OrderedDict, defaultdict -from collections.abc import Generator, Iterable, Mapping +from collections.abc import Generator, Iterable, Mapping, Sequence from dataclasses import dataclass from datetime import date from typing import TYPE_CHECKING, Any @@ -225,7 +225,7 @@ def render_changelog( tree: Iterable, loader: BaseLoader, template: str, - **kwargs, + **kwargs: Any, ) -> str: jinja_template = get_changelog_template(loader, template) changelog: str = jinja_template.render(tree=tree, **kwargs) @@ -282,7 +282,7 @@ def incremental_build( def get_smart_tag_range( - tags: list[GitTag], newest: str, oldest: str | None = None + tags: Sequence[GitTag], newest: str, oldest: str | None = None ) -> list[GitTag]: """Smart because it finds the N+1 tag. @@ -308,10 +308,10 @@ def get_smart_tag_range( def get_oldest_and_newest_rev( - tags: list[GitTag], + tags: Sequence[GitTag], version: str, rules: TagRules, -) -> tuple[str | None, str | None]: +) -> tuple[str | None, str]: """Find the tags for the given version. `version` may come in different formats: diff --git a/commitizen/cli.py b/commitizen/cli.py index d245f731e3..9998691f41 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -50,7 +50,7 @@ def __call__( namespace: argparse.Namespace, kwarg: str | Sequence[Any] | None, option_string: str | None = None, - ): + ) -> None: if not isinstance(kwarg, str): return if "=" not in kwarg: @@ -550,8 +550,12 @@ def __call__( def commitizen_excepthook( - type, value, traceback, debug=False, no_raise: list[int] | None = None -): + type: type[BaseException], + value: BaseException, + traceback: TracebackType | None, + debug: bool = False, + no_raise: list[int] | None = None, +) -> None: traceback = traceback if isinstance(traceback, TracebackType) else None if not isinstance(value, CommitizenException): original_excepthook(type, value, traceback) @@ -581,7 +585,7 @@ def parse_no_raise(comma_separated_no_raise: str) -> list[int]: represents the exit code found in exceptions. """ no_raise_items: list[str] = comma_separated_no_raise.split(",") - no_raise_codes = [] + no_raise_codes: list[int] = [] for item in no_raise_items: if item.isdecimal(): no_raise_codes.append(int(item)) @@ -621,7 +625,7 @@ class Args(argparse.Namespace): ] -def main(): +def main() -> None: parser: argparse.ArgumentParser = cli(data) argcomplete.autocomplete(parser) # Show help if no arg provided diff --git a/commitizen/cmd.py b/commitizen/cmd.py index ba48ac7881..9d6b2f6d2a 100644 --- a/commitizen/cmd.py +++ b/commitizen/cmd.py @@ -1,6 +1,7 @@ import os import subprocess -from typing import NamedTuple +from collections.abc import Mapping +from typing import NamedTuple, Union from charset_normalizer import from_bytes @@ -28,7 +29,7 @@ def _try_decode(bytes_: bytes) -> str: raise CharacterSetDecodeError() from e -def run(cmd: str, env=None) -> Command: +def run(cmd: str, env: Union[Mapping[str, str], None] = None) -> Command: if env is not None: env = {**os.environ, **env} process = subprocess.Popen( diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 7bf644a934..181531dee2 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -2,10 +2,11 @@ import os import os.path -from collections.abc import Generator +from collections.abc import Generator, Iterable, Mapping from difflib import SequenceMatcher from operator import itemgetter from pathlib import Path +from typing import Any, cast from commitizen import changelog, defaults, factory, git, out from commitizen.changelog_formats import get_changelog_format @@ -28,7 +29,7 @@ class Changelog: """Generate a changelog based on the commit history.""" - def __init__(self, config: BaseConfig, args): + def __init__(self, config: BaseConfig, args: Mapping[str, Any]): if not git.is_git_project(): raise NotAGitProjectError() @@ -76,10 +77,11 @@ def __init__(self, config: BaseConfig, args): self.change_type_map = ( self.config.settings.get("change_type_map") or self.cz.change_type_map ) - self.change_type_order = ( + self.change_type_order = cast( + list[str], self.config.settings.get("change_type_order") or self.cz.change_type_order - or defaults.CHANGE_TYPE_ORDER + or defaults.CHANGE_TYPE_ORDER, ) self.rev_range = args.get("rev_range") self.tag_format: str = ( @@ -102,7 +104,7 @@ def __init__(self, config: BaseConfig, args): self.extras = args.get("extras") or {} self.export_template_to = args.get("export_template") - def _find_incremental_rev(self, latest_version: str, tags: list[GitTag]) -> str: + def _find_incremental_rev(self, latest_version: str, tags: Iterable[GitTag]) -> str: """Try to find the 'start_rev'. We use a similarity approach. We know how to parse the version from the markdown @@ -151,18 +153,18 @@ def write_changelog( changelog_file.write(changelog_out) - def export_template(self): + def export_template(self) -> None: tpl = changelog.get_changelog_template(self.cz.template_loader, self.template) - src = Path(tpl.filename) - Path(self.export_template_to).write_text(src.read_text()) + src = Path(tpl.filename) # type: ignore + Path(self.export_template_to).write_text(src.read_text()) # type: ignore - def __call__(self): + def __call__(self) -> None: commit_parser = self.cz.commit_parser changelog_pattern = self.cz.changelog_pattern start_rev = self.start_rev unreleased_version = self.unreleased_version changelog_meta = changelog.Metadata() - change_type_map: dict | None = self.change_type_map + change_type_map: dict[str, str] | None = self.change_type_map # type: ignore changelog_message_builder_hook: MessageBuilderHook | None = ( self.cz.changelog_message_builder_hook ) @@ -190,7 +192,7 @@ def __call__(self): changelog_meta = self.changelog_format.get_metadata(self.file_name) if changelog_meta.latest_version: start_rev = self._find_incremental_rev( - strip_local_version(changelog_meta.latest_version_tag), tags + strip_local_version(changelog_meta.latest_version_tag or ""), tags ) if self.rev_range: start_rev, end_rev = changelog.get_oldest_and_newest_rev( diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index 1e3b8464e1..6cf91bb926 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -17,7 +17,9 @@ class Check: """Check if the current commit msg matches the commitizen format.""" - def __init__(self, config: BaseConfig, arguments: dict[str, Any], cwd=os.getcwd()): + def __init__( + self, config: BaseConfig, arguments: dict[str, Any], cwd: str = os.getcwd() + ): """Initial check command. Args: @@ -48,7 +50,7 @@ def __init__(self, config: BaseConfig, arguments: dict[str, Any], cwd=os.getcwd( self.encoding = config.settings["encoding"] self.cz = factory.committer_factory(self.config) - def _valid_command_argument(self): + def _valid_command_argument(self) -> None: num_exclusive_args_provided = sum( arg is not None for arg in (self.commit_msg_file, self.commit_msg, self.rev_range) @@ -61,7 +63,7 @@ def _valid_command_argument(self): "See 'cz check -h' for more information" ) - def __call__(self): + def __call__(self) -> None: """Validate if commit messages follows the conventional pattern. Raises: @@ -97,7 +99,7 @@ def _get_commit_message(self) -> str | None: # Get commit message from file (--commit-msg-file) return commit_file.read() - def _get_commits(self): + def _get_commits(self) -> list[git.GitCommit]: if (msg := self._get_commit_message()) is not None: return [git.GitCommit(rev="", title="", body=self._filter_comments(msg))] diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index eedf77e079..3e7a850a05 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -5,6 +5,8 @@ import shutil import subprocess import tempfile +from pathlib import Path +from typing import Union, cast import questionary @@ -105,11 +107,13 @@ def _get_message(self) -> str: return self.read_backup_message() or self.prompt_commit_questions() return self.prompt_commit_questions() - def __call__(self): - extra_args: str = self.arguments.get("extra_cli_args", "") - dry_run: bool = self.arguments.get("dry_run") - write_message_to_file: bool = self.arguments.get("write_message_to_file") - signoff: bool = self.arguments.get("signoff") + def __call__(self) -> None: + extra_args = cast(str, self.arguments.get("extra_cli_args", "")) + dry_run = cast(bool, self.arguments.get("dry_run")) + write_message_to_file = cast( + Union[Path, None], self.arguments.get("write_message_to_file") + ) + signoff = cast(bool, self.arguments.get("signoff")) if self.arguments.get("all"): git.add("-u") diff --git a/commitizen/commands/info.py b/commitizen/commands/info.py index abd4197e7f..5b649ceb5d 100644 --- a/commitizen/commands/info.py +++ b/commitizen/commands/info.py @@ -5,9 +5,9 @@ class Info: """Show in depth explanation of your rules.""" - def __init__(self, config: BaseConfig, *args): + def __init__(self, config: BaseConfig, *args: object): self.config: BaseConfig = config self.cz = factory.committer_factory(self.config) - def __call__(self): + def __call__(self) -> None: out.write(self.cz.info()) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 0eb3d99d17..a7e1b56665 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -207,7 +207,7 @@ def _ask_tag(self) -> str: raise NoAnswersError("Tag is required!") return latest_tag - def _ask_tag_format(self, latest_tag) -> str: + def _ask_tag_format(self, latest_tag: str) -> str: is_correct_format = False if latest_tag.startswith("v"): tag_format = r"v$version" @@ -302,7 +302,7 @@ def _ask_update_changelog_on_bump(self) -> bool: ).unsafe_ask() return update_changelog_on_bump - def _exec_install_pre_commit_hook(self, hook_types: list[str]): + def _exec_install_pre_commit_hook(self, hook_types: list[str]) -> None: cmd_str = self._gen_pre_commit_cmd(hook_types) c = cmd.run(cmd_str) if c.return_code != 0: @@ -323,7 +323,7 @@ def _gen_pre_commit_cmd(self, hook_types: list[str]) -> str: ) return cmd_str - def _install_pre_commit_hook(self, hook_types: list[str] | None = None): + def _install_pre_commit_hook(self, hook_types: list[str] | None = None) -> None: pre_commit_config_filename = ".pre-commit-config.yaml" cz_hook_config = { "repo": "https://github.com/commitizen-tools/commitizen", @@ -369,6 +369,6 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None = None): self._exec_install_pre_commit_hook(hook_types) out.write("commitizen pre-commit hook is now installed in your '.git'\n") - def _update_config_file(self, values: dict[str, Any]): + def _update_config_file(self, values: dict[str, Any]) -> None: for key, value in values.items(): self.config.set_key(key, value) diff --git a/commitizen/commands/list_cz.py b/commitizen/commands/list_cz.py index 99701865af..ff4e12ad44 100644 --- a/commitizen/commands/list_cz.py +++ b/commitizen/commands/list_cz.py @@ -6,8 +6,8 @@ class ListCz: """List currently installed rules.""" - def __init__(self, config: BaseConfig, *args): + def __init__(self, config: BaseConfig, *args: object): self.config: BaseConfig = config - def __call__(self): + def __call__(self) -> None: out.write("\n".join(registry.keys())) diff --git a/commitizen/commands/version.py b/commitizen/commands/version.py index 45d553c710..55d0a950a3 100644 --- a/commitizen/commands/version.py +++ b/commitizen/commands/version.py @@ -1,5 +1,7 @@ import platform import sys +from collections.abc import Mapping +from typing import Any from commitizen import out from commitizen.__version__ import __version__ @@ -10,13 +12,13 @@ class Version: """Get the version of the installed commitizen or the current project.""" - def __init__(self, config: BaseConfig, *args): + def __init__(self, config: BaseConfig, *args: Mapping[str, Any]): self.config: BaseConfig = config self.parameter = args[0] self.operating_system = platform.system() self.python_version = sys.version - def __call__(self): + def __call__(self) -> None: if self.parameter.get("report"): out.write(f"Commitizen Version: {__version__}") out.write(f"Python Version: {self.python_version}") diff --git a/commitizen/config/base_config.py b/commitizen/config/base_config.py index fd034412fe..587b72aee6 100644 --- a/commitizen/config/base_config.py +++ b/commitizen/config/base_config.py @@ -6,7 +6,7 @@ class BaseConfig: - def __init__(self): + def __init__(self) -> None: self._settings: Settings = DEFAULT_SETTINGS.copy() self.encoding = self.settings["encoding"] self._path: Path | None = None diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 320aa9b324..5b4889114f 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -8,7 +8,7 @@ __all__ = ["ConventionalCommitsCz"] -def parse_scope(text): +def parse_scope(text: str) -> str: if not text: return "" @@ -19,7 +19,7 @@ def parse_scope(text): return "-".join(scope) -def parse_subject(text): +def parse_subject(text: str) -> str: if isinstance(text, str): text = text.strip(".").strip() diff --git a/commitizen/cz/utils.py b/commitizen/cz/utils.py index cb79d65d1a..430bda2d43 100644 --- a/commitizen/cz/utils.py +++ b/commitizen/cz/utils.py @@ -1,6 +1,7 @@ import os import re import tempfile +from typing import Union from commitizen import git from commitizen.cz import exceptions @@ -8,13 +9,13 @@ _RE_LOCAL_VERSION = re.compile(r"\+.+") -def required_validator(answer, msg=None): +def required_validator(answer: str, msg: Union[str, None] = None) -> str: if not answer: raise exceptions.AnswerRequiredError(msg) return answer -def multiple_line_breaker(answer, sep="|"): +def multiple_line_breaker(answer: str, sep: str = "|") -> str: return "\n".join(line.strip() for line in answer.split(sep) if line) diff --git a/commitizen/exceptions.py b/commitizen/exceptions.py index 29733b624b..87efabe2ab 100644 --- a/commitizen/exceptions.py +++ b/commitizen/exceptions.py @@ -1,4 +1,5 @@ import enum +from typing import Any from commitizen import out @@ -40,7 +41,7 @@ class ExitCode(enum.IntEnum): class CommitizenException(Exception): - def __init__(self, *args, **kwargs): + def __init__(self, *args: str, **kwargs: Any): self.output_method = kwargs.get("output_method") or out.error self.exit_code: ExitCode = self.__class__.exit_code if args: @@ -50,14 +51,14 @@ def __init__(self, *args, **kwargs): else: self.message = "" - def __str__(self): + def __str__(self) -> str: return self.message class ExpectedExit(CommitizenException): exit_code = ExitCode.EXPECTED_EXIT - def __init__(self, *args, **kwargs): + def __init__(self, *args: str, **kwargs: Any): output_method = kwargs.get("output_method") or out.write kwargs["output_method"] = output_method super().__init__(*args, **kwargs) diff --git a/commitizen/git.py b/commitizen/git.py index ab2866ac48..48fa13ec52 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -46,15 +46,15 @@ class GitObject: name: str date: str - def __eq__(self, other) -> bool: + def __eq__(self, other: object) -> bool: return hasattr(other, "rev") and self.rev == other.rev class GitCommit(GitObject): def __init__( self, - rev, - title, + rev: str, + title: str, body: str = "", author: str = "", author_email: str = "", @@ -68,7 +68,7 @@ def __init__( self.parents = parents or [] @property - def message(self): + def message(self) -> str: return f"{self.title}\n\n{self.body}".strip() @classmethod @@ -127,23 +127,27 @@ def from_rev_and_commit(cls, rev_and_commit: str) -> GitCommit: parents=[p for p in parents.strip().split(" ") if p], ) - def __repr__(self): + def __repr__(self) -> str: return f"{self.title} ({self.rev})" class GitTag(GitObject): - def __init__(self, name, rev, date): + def __init__(self, name: str, rev: str, date: str): self.rev = rev.strip() self.name = name.strip() self._date = date.strip() - def __repr__(self): + def __repr__(self) -> str: return f"GitTag('{self.name}', '{self.rev}', '{self.date}')" @property - def date(self): + def date(self) -> str: return self._date + @date.setter + def date(self, value: str) -> None: + self._date = value + @classmethod def from_line(cls, line: str, inner_delimiter: str) -> GitTag: name, objectname, date, obj = line.split(inner_delimiter) diff --git a/commitizen/out.py b/commitizen/out.py index 40342e9de5..1bbfe4329d 100644 --- a/commitizen/out.py +++ b/commitizen/out.py @@ -1,5 +1,6 @@ import io import sys +from typing import Any from termcolor import colored @@ -8,12 +9,12 @@ sys.stdout.reconfigure(encoding="utf-8") -def write(value: str, *args) -> None: +def write(value: str, *args: object) -> None: """Intended to be used when value is multiline.""" print(value, *args) -def line(value: str, *args, **kwargs) -> None: +def line(value: str, *args: object, **kwargs: Any) -> None: """Wrapper in case I want to do something different later.""" print(value, *args, **kwargs) @@ -33,7 +34,7 @@ def info(value: str) -> None: line(message) -def diagnostic(value: str): +def diagnostic(value: str) -> None: line(value, file=sys.stderr) diff --git a/tests/test_git.py b/tests/test_git.py index 3fecaabafd..e242b3a2ae 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -18,6 +18,13 @@ ) +@pytest.mark.parametrize("date", ["2020-01-21", "1970-01-01"]) +def test_git_tag_date(date: str): + git_tag = git.GitTag(rev="sha1-code", name="0.0.1", date="2025-05-30") + git_tag.date = date + assert git_tag.date == date + + def test_git_object_eq(): git_commit = git.GitCommit( rev="sha1-code", title="this is title", body="this is body" From 1647841d83c8047421f5bc75edadd55fd74ae795 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 01:25:06 +0800 Subject: [PATCH 549/598] refactor(conventional_commits): remove unnecessary checks --- .../conventional_commits.py | 22 +++----- tests/test_cz_conventional_commits.py | 54 +++++++++---------- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 5b4889114f..912770a726 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -8,22 +8,12 @@ __all__ = ["ConventionalCommitsCz"] -def parse_scope(text: str) -> str: - if not text: - return "" +def _parse_scope(text: str) -> str: + return "-".join(text.strip().split()) - scope = text.strip().split() - if len(scope) == 1: - return scope[0] - return "-".join(scope) - - -def parse_subject(text: str) -> str: - if isinstance(text, str): - text = text.strip(".").strip() - - return required_validator(text, msg="Subject is required.") +def _parse_subject(text: str) -> str: + return required_validator(text.strip(".").strip(), msg="Subject is required.") class ConventionalCommitsCz(BaseCommitizen): @@ -112,12 +102,12 @@ def questions(self) -> Questions: "message": ( "What is the scope of this change? (class or file name): (press [enter] to skip)\n" ), - "filter": parse_scope, + "filter": _parse_scope, }, { "type": "input", "name": "subject", - "filter": parse_subject, + "filter": _parse_subject, "message": ( "Write a short and imperative summary of the code changes: (lower case and no period)\n" ), diff --git a/tests/test_cz_conventional_commits.py b/tests/test_cz_conventional_commits.py index 89653f4c63..c96e036707 100644 --- a/tests/test_cz_conventional_commits.py +++ b/tests/test_cz_conventional_commits.py @@ -2,48 +2,42 @@ from commitizen.cz.conventional_commits.conventional_commits import ( ConventionalCommitsCz, - parse_scope, - parse_subject, + _parse_scope, + _parse_subject, ) from commitizen.cz.exceptions import AnswerRequiredError -valid_scopes = ["", "simple", "dash-separated", "camelCaseUPPERCASE"] -scopes_transformations = [["with spaces", "with-spaces"], [None, ""]] - -valid_subjects = ["this is a normal text", "aword"] - -subjects_transformations = [["with dot.", "with dot"]] - -invalid_subjects = ["", " ", ".", " .", "", None] - - -def test_parse_scope_valid_values(): - for valid_scope in valid_scopes: - assert valid_scope == parse_scope(valid_scope) +@pytest.mark.parametrize( + "valid_scope", ["", "simple", "dash-separated", "camelCaseUPPERCASE"] +) +def test_parse_scope_valid_values(valid_scope): + assert valid_scope == _parse_scope(valid_scope) -def test_scopes_transformations(): - for scopes_transformation in scopes_transformations: - invalid_scope, transformed_scope = scopes_transformation - assert transformed_scope == parse_scope(invalid_scope) +@pytest.mark.parametrize( + "scopes_transformation", [["with spaces", "with-spaces"], ["", ""]] +) +def test_scopes_transformations(scopes_transformation): + invalid_scope, transformed_scope = scopes_transformation + assert transformed_scope == _parse_scope(invalid_scope) -def test_parse_subject_valid_values(): - for valid_subject in valid_subjects: - assert valid_subject == parse_subject(valid_subject) +@pytest.mark.parametrize("valid_subject", ["this is a normal text", "aword"]) +def test_parse_subject_valid_values(valid_subject): + assert valid_subject == _parse_subject(valid_subject) -def test_parse_subject_invalid_values(): - for valid_subject in invalid_subjects: - with pytest.raises(AnswerRequiredError): - parse_subject(valid_subject) +@pytest.mark.parametrize("invalid_subject", ["", " ", ".", " .", "\t\t."]) +def test_parse_subject_invalid_values(invalid_subject): + with pytest.raises(AnswerRequiredError): + _parse_subject(invalid_subject) -def test_subject_transformations(): - for subject_transformation in subjects_transformations: - invalid_subject, transformed_subject = subject_transformation - assert transformed_subject == parse_subject(invalid_subject) +@pytest.mark.parametrize("subject_transformation", [["with dot.", "with dot"]]) +def test_subject_transformations(subject_transformation): + invalid_subject, transformed_subject = subject_transformation + assert transformed_subject == _parse_subject(invalid_subject) def test_questions(config): From 37eac1f292a6593935dfe32c0389f016947116ff Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 14:25:50 +0800 Subject: [PATCH 550/598] refactor: make methods protected, better type --- commitizen/commands/bump.py | 8 ++++---- commitizen/commands/changelog.py | 8 ++++---- commitizen/commands/commit.py | 10 +++++----- commitizen/commands/init.py | 4 ++-- commitizen/config/base_config.py | 3 +++ tests/commands/test_bump_command.py | 10 +++++----- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 9556492499..0607c7ef73 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -101,7 +101,7 @@ def __init__(self, config: BaseConfig, arguments: dict): ) self.extras = arguments["extras"] - def is_initial_tag( + def _is_initial_tag( self, current_tag: git.GitTag | None, is_yes: bool = False ) -> bool: """Check if reading the whole git tree up to HEAD is needed.""" @@ -118,7 +118,7 @@ def is_initial_tag( ) return bool(questionary.confirm("Is this the first tag created?").ask()) - def find_increment(self, commits: list[git.GitCommit]) -> Increment | None: + def _find_increment(self, commits: list[git.GitCommit]) -> Increment | None: # Update the bump map to ensure major version doesn't increment. is_major_version_zero: bool = self.bump_settings["major_version_zero"] # self.cz.bump_map = defaults.bump_map_major_version_zero @@ -227,7 +227,7 @@ def __call__(self) -> None: current_tag, "name", rules.normalize_tag(current_version) ) - is_initial = self.is_initial_tag(current_tag, is_yes) + is_initial = self._is_initial_tag(current_tag, is_yes) if manual_version: try: @@ -255,7 +255,7 @@ def __call__(self) -> None: "[NO_COMMITS_FOUND]\nNo new commits found." ) - increment = self.find_increment(commits) + increment = self._find_increment(commits) # It may happen that there are commits, but they are not eligible # for an increment, this generates a problem when using prerelease (#281) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 181531dee2..11f72cba18 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -136,7 +136,7 @@ def _find_incremental_rev(self, latest_version: str, tags: Iterable[GitTag]) -> raise NoRevisionError() return start_rev - def write_changelog( + def _write_changelog( self, changelog_out: str, lines: list[str], changelog_meta: changelog.Metadata ): with smart_open(self.file_name, "w", encoding=self.encoding) as changelog_file: @@ -153,7 +153,7 @@ def write_changelog( changelog_file.write(changelog_out) - def export_template(self) -> None: + def _export_template(self) -> None: tpl = changelog.get_changelog_template(self.cz.template_loader, self.template) src = Path(tpl.filename) # type: ignore Path(self.export_template_to).write_text(src.read_text()) # type: ignore @@ -173,7 +173,7 @@ def __call__(self) -> None: ) if self.export_template_to: - return self.export_template() + return self._export_template() if not changelog_pattern or not commit_parser: raise NoPatternMapError( @@ -240,4 +240,4 @@ def __call__(self) -> None: with open(self.file_name, encoding=self.encoding) as changelog_file: lines = changelog_file.readlines() - self.write_changelog(changelog_out, lines, changelog_meta) + self._write_changelog(changelog_out, lines, changelog_meta) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 3e7a850a05..22ad642c43 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -41,7 +41,7 @@ def __init__(self, config: BaseConfig, arguments: dict): self.arguments = arguments self.temp_file: str = get_backup_file_path() - def read_backup_message(self) -> str | None: + def _read_backup_message(self) -> str | None: # Check the commit backup file exists if not os.path.isfile(self.temp_file): return None @@ -50,7 +50,7 @@ def read_backup_message(self) -> str | None: with open(self.temp_file, encoding=self.encoding) as f: return f.read().strip() - def prompt_commit_questions(self) -> str: + def _prompt_commit_questions(self) -> str: # Prompt user for the commit message cz = self.cz questions = cz.questions() @@ -96,7 +96,7 @@ def manual_edit(self, message: str) -> str: def _get_message(self) -> str: if self.arguments.get("retry"): - m = self.read_backup_message() + m = self._read_backup_message() if m is None: raise NoCommitBackupError() return m @@ -104,8 +104,8 @@ def _get_message(self) -> str: if self.config.settings.get("retry_after_failure") and not self.arguments.get( "no_retry" ): - return self.read_backup_message() or self.prompt_commit_questions() - return self.prompt_commit_questions() + return self._read_backup_message() or self._prompt_commit_questions() + return self._prompt_commit_questions() def __call__(self) -> None: extra_args = cast(str, self.arguments.get("extra_cli_args", "")) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index a7e1b56665..e03103d4cb 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -85,7 +85,7 @@ def __init__(self, config: BaseConfig, *args): self.cz = factory.committer_factory(self.config) self.project_info = ProjectInfo() - def __call__(self): + def __call__(self) -> None: if self.config.path: out.line(f"Config file {self.config.path} already exists") return @@ -120,7 +120,7 @@ def __call__(self): self.config = JsonConfig(data="{}", path=config_path) elif "yaml" in config_path: self.config = YAMLConfig(data="", path=config_path) - values_to_add = {} + values_to_add: dict[str, Any] = {} values_to_add["name"] = cz_name values_to_add["tag_format"] = tag_format values_to_add["version_scheme"] = version_scheme diff --git a/commitizen/config/base_config.py b/commitizen/config/base_config.py index 587b72aee6..2c7bce206d 100644 --- a/commitizen/config/base_config.py +++ b/commitizen/config/base_config.py @@ -41,3 +41,6 @@ def update(self, data: Settings) -> None: def _parse_setting(self, data: bytes | str) -> None: raise NotImplementedError() + + def init_empty_config_content(self) -> None: + raise NotImplementedError() diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 2af7bec121..41da985704 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1692,7 +1692,7 @@ def test_bump_warn_but_dont_fail_on_invalid_tags( def test_is_initial_tag(mocker: MockFixture, tmp_commitizen_project): - """Test the is_initial_tag method behavior.""" + """Test the _is_initial_tag method behavior.""" # Create a commit but no tags create_file_and_commit("feat: initial commit") @@ -1725,15 +1725,15 @@ def test_is_initial_tag(mocker: MockFixture, tmp_commitizen_project): # Test case 1: No current tag, not yes mode mocker.patch("questionary.confirm", return_value=mocker.Mock(ask=lambda: True)) - assert bump_cmd.is_initial_tag(None, is_yes=False) is True + assert bump_cmd._is_initial_tag(None, is_yes=False) is True # Test case 2: No current tag, yes mode - assert bump_cmd.is_initial_tag(None, is_yes=True) is True + assert bump_cmd._is_initial_tag(None, is_yes=True) is True # Test case 3: Has current tag mock_tag = mocker.Mock() - assert bump_cmd.is_initial_tag(mock_tag, is_yes=False) is False + assert bump_cmd._is_initial_tag(mock_tag, is_yes=False) is False # Test case 4: No current tag, user denies mocker.patch("questionary.confirm", return_value=mocker.Mock(ask=lambda: False)) - assert bump_cmd.is_initial_tag(None, is_yes=False) is False + assert bump_cmd._is_initial_tag(None, is_yes=False) is False From c62aac03ee55c8d616ba078357dbbfe973cf5567 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 14:30:57 +0800 Subject: [PATCH 551/598] style: type untyped methods --- commitizen/changelog.py | 6 +++--- commitizen/commands/changelog.py | 2 +- commitizen/commands/example.py | 4 ++-- commitizen/commands/init.py | 2 +- commitizen/commands/schema.py | 4 ++-- commitizen/config/base_config.py | 12 +++++++++++- commitizen/config/json_config.py | 14 ++++++++++++-- commitizen/config/toml_config.py | 18 ++++++++++++++---- commitizen/config/yaml_config.py | 14 ++++++++++++-- commitizen/cz/base.py | 4 ++-- commitizen/git.py | 4 ++-- commitizen/hooks.py | 5 +++-- commitizen/providers/base_provider.py | 10 +++++----- commitizen/providers/cargo_provider.py | 2 +- commitizen/providers/commitizen_provider.py | 2 +- commitizen/providers/poetry_provider.py | 2 +- commitizen/providers/scm_provider.py | 2 +- 17 files changed, 74 insertions(+), 33 deletions(-) diff --git a/commitizen/changelog.py b/commitizen/changelog.py index 6526b4c540..ba6fbbc6b3 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -63,7 +63,7 @@ class Metadata: latest_version_position: int | None = None latest_version_tag: str | None = None - def __post_init__(self): + def __post_init__(self) -> None: if self.latest_version and not self.latest_version_tag: # Test syntactic sugar # latest version tag is optional if same as latest version @@ -169,8 +169,8 @@ def process_commit_message( commit: GitCommit, changes: dict[str | None, list], change_type_map: dict[str, str] | None = None, -): - message: dict = { +) -> None: + message: dict[str, Any] = { "sha1": commit.rev, "parents": commit.parents, "author": commit.author, diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 11f72cba18..5a1270dfd8 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -138,7 +138,7 @@ def _find_incremental_rev(self, latest_version: str, tags: Iterable[GitTag]) -> def _write_changelog( self, changelog_out: str, lines: list[str], changelog_meta: changelog.Metadata - ): + ) -> None: with smart_open(self.file_name, "w", encoding=self.encoding) as changelog_file: partial_changelog: str | None = None if self.incremental: diff --git a/commitizen/commands/example.py b/commitizen/commands/example.py index a28ad85f16..818e217530 100644 --- a/commitizen/commands/example.py +++ b/commitizen/commands/example.py @@ -5,9 +5,9 @@ class Example: """Show an example so people understands the rules.""" - def __init__(self, config: BaseConfig, *args): + def __init__(self, config: BaseConfig, *args: object): self.config: BaseConfig = config self.cz = factory.committer_factory(self.config) - def __call__(self): + def __call__(self) -> None: out.write(self.cz.example()) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index e03103d4cb..ca6426b0bd 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -79,7 +79,7 @@ def is_pre_commit_installed(self) -> bool: class Init: - def __init__(self, config: BaseConfig, *args): + def __init__(self, config: BaseConfig, *args: object): self.config: BaseConfig = config self.encoding = config.settings["encoding"] self.cz = factory.committer_factory(self.config) diff --git a/commitizen/commands/schema.py b/commitizen/commands/schema.py index 4af5679cf5..5c77898d8a 100644 --- a/commitizen/commands/schema.py +++ b/commitizen/commands/schema.py @@ -5,9 +5,9 @@ class Schema: """Show structure of the rule.""" - def __init__(self, config: BaseConfig, *args): + def __init__(self, config: BaseConfig, *args: object): self.config: BaseConfig = config self.cz = factory.committer_factory(self.config) - def __call__(self): + def __call__(self) -> None: out.write(self.cz.schema()) diff --git a/commitizen/config/base_config.py b/commitizen/config/base_config.py index 2c7bce206d..10a26e3f0c 100644 --- a/commitizen/config/base_config.py +++ b/commitizen/config/base_config.py @@ -1,9 +1,19 @@ from __future__ import annotations from pathlib import Path +from typing import TYPE_CHECKING, Any from commitizen.defaults import DEFAULT_SETTINGS, Settings +if TYPE_CHECKING: + import sys + + # Self is Python 3.11+ but backported in typing-extensions + if sys.version_info < (3, 11): + from typing_extensions import Self + else: + from typing import Self + class BaseConfig: def __init__(self) -> None: @@ -28,7 +38,7 @@ def path(self, path: str | Path) -> None: """ self._path = Path(path) - def set_key(self, key, value): + def set_key(self, key: str, value: Any) -> Self: """Set or update a key in the conf. For now only strings are supported. diff --git a/commitizen/config/json_config.py b/commitizen/config/json_config.py index 28fac25662..83e0a928a0 100644 --- a/commitizen/config/json_config.py +++ b/commitizen/config/json_config.py @@ -2,12 +2,22 @@ import json from pathlib import Path +from typing import TYPE_CHECKING, Any from commitizen.exceptions import InvalidConfigurationError from commitizen.git import smart_open from .base_config import BaseConfig +if TYPE_CHECKING: + import sys + + # Self is Python 3.11+ but backported in typing-extensions + if sys.version_info < (3, 11): + from typing_extensions import Self + else: + from typing import Self + class JsonConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): @@ -16,11 +26,11 @@ def __init__(self, *, data: bytes | str, path: Path | str): self.path = path self._parse_setting(data) - def init_empty_config_content(self): + def init_empty_config_content(self) -> None: with smart_open(self.path, "a", encoding=self.encoding) as json_file: json.dump({"commitizen": {}}, json_file) - def set_key(self, key, value): + def set_key(self, key: str, value: Any) -> Self: """Set or update a key in the conf. For now only strings are supported. diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index a7050214ba..9bab994fd5 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -2,6 +2,7 @@ import os from pathlib import Path +from typing import TYPE_CHECKING, Any from tomlkit import exceptions, parse, table @@ -9,6 +10,15 @@ from .base_config import BaseConfig +if TYPE_CHECKING: + import sys + + # Self is Python 3.11+ but backported in typing-extensions + if sys.version_info < (3, 11): + from typing_extensions import Self + else: + from typing import Self + class TomlConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): @@ -17,7 +27,7 @@ def __init__(self, *, data: bytes | str, path: Path | str): self.path = path self._parse_setting(data) - def init_empty_config_content(self): + def init_empty_config_content(self) -> None: if os.path.isfile(self.path): with open(self.path, "rb") as input_toml_file: parser = parse(input_toml_file.read()) @@ -27,10 +37,10 @@ def init_empty_config_content(self): with open(self.path, "wb") as output_toml_file: if parser.get("tool") is None: parser["tool"] = table() - parser["tool"]["commitizen"] = table() + parser["tool"]["commitizen"] = table() # type: ignore output_toml_file.write(parser.as_string().encode(self.encoding)) - def set_key(self, key, value): + def set_key(self, key: str, value: Any) -> Self: """Set or update a key in the conf. For now only strings are supported. @@ -39,7 +49,7 @@ def set_key(self, key, value): with open(self.path, "rb") as f: parser = parse(f.read()) - parser["tool"]["commitizen"][key] = value + parser["tool"]["commitizen"][key] = value # type: ignore with open(self.path, "wb") as f: f.write(parser.as_string().encode(self.encoding)) return self diff --git a/commitizen/config/yaml_config.py b/commitizen/config/yaml_config.py index 2c384cf17d..8eac9bb785 100644 --- a/commitizen/config/yaml_config.py +++ b/commitizen/config/yaml_config.py @@ -1,6 +1,7 @@ from __future__ import annotations from pathlib import Path +from typing import TYPE_CHECKING, Any import yaml @@ -9,6 +10,15 @@ from .base_config import BaseConfig +if TYPE_CHECKING: + import sys + + # Self is Python 3.11+ but backported in typing-extensions + if sys.version_info < (3, 11): + from typing_extensions import Self + else: + from typing import Self + class YAMLConfig(BaseConfig): def __init__(self, *, data: bytes | str, path: Path | str): @@ -17,7 +27,7 @@ def __init__(self, *, data: bytes | str, path: Path | str): self.path = path self._parse_setting(data) - def init_empty_config_content(self): + def init_empty_config_content(self) -> None: with smart_open(self.path, "a", encoding=self.encoding) as json_file: yaml.dump({"commitizen": {}}, json_file, explicit_start=True) @@ -41,7 +51,7 @@ def _parse_setting(self, data: bytes | str) -> None: except (KeyError, TypeError): self.is_empty_config = True - def set_key(self, key, value): + def set_key(self, key: str, value: Any) -> Self: """Set or update a key in the conf. For now only strings are supported. diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 7463a67c24..9e803c3d01 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -76,13 +76,13 @@ def message(self, answers: dict) -> str: """Format your git message.""" @property - def style(self): + def style(self) -> Style: return merge_styles( [ Style(BaseCommitizen.default_style_config), Style(self.config.settings["style"]), ] - ) + ) # type: ignore[return-value] def example(self) -> str: """Example of the commit message.""" diff --git a/commitizen/git.py b/commitizen/git.py index 48fa13ec52..54d57f69bb 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -215,7 +215,7 @@ def get_commits( ] -def get_filenames_in_commit(git_reference: str = ""): +def get_filenames_in_commit(git_reference: str = "") -> list[str]: """Get the list of files that were committed in the requested git reference. :param git_reference: a git reference as accepted by `git show`, default: the last commit @@ -312,7 +312,7 @@ def get_core_editor() -> str | None: return None -def smart_open(*args, **kwargs): +def smart_open(*args, **kwargs): # type: ignore[no-untyped-def,unused-ignore] """Open a file with the EOL style determined from Git.""" return open(*args, newline=EOLType.for_open(), **kwargs) diff --git a/commitizen/hooks.py b/commitizen/hooks.py index f5505d0e82..f60bd9b43e 100644 --- a/commitizen/hooks.py +++ b/commitizen/hooks.py @@ -1,12 +1,13 @@ from __future__ import annotations import os +from collections.abc import Mapping from commitizen import cmd, out from commitizen.exceptions import RunHookError -def run(hooks, _env_prefix="CZ_", **env): +def run(hooks: str | list[str], _env_prefix: str = "CZ_", **env: object) -> None: if isinstance(hooks, str): hooks = [hooks] @@ -24,7 +25,7 @@ def run(hooks, _env_prefix="CZ_", **env): raise RunHookError(f"Running hook '{hook}' failed") -def _format_env(prefix: str, env: dict[str, str]) -> dict[str, str]: +def _format_env(prefix: str, env: Mapping[str, object]) -> dict[str, str]: """_format_env() prefixes all given environment variables with the given prefix so it can be passed directly to cmd.run().""" penv = dict(os.environ) diff --git a/commitizen/providers/base_provider.py b/commitizen/providers/base_provider.py index 34048318e2..9c1e0f7a98 100644 --- a/commitizen/providers/base_provider.py +++ b/commitizen/providers/base_provider.py @@ -29,7 +29,7 @@ def get_version(self) -> str: """ @abstractmethod - def set_version(self, version: str): + def set_version(self, version: str) -> None: """ Set the new current version """ @@ -58,7 +58,7 @@ def get_version(self) -> str: document = json.loads(self.file.read_text()) return self.get(document) - def set_version(self, version: str): + def set_version(self, version: str) -> None: document = json.loads(self.file.read_text()) self.set(document, version) self.file.write_text(json.dumps(document, indent=self.indent) + "\n") @@ -66,7 +66,7 @@ def set_version(self, version: str): def get(self, document: dict[str, Any]) -> str: return document["version"] # type: ignore - def set(self, document: dict[str, Any], version: str): + def set(self, document: dict[str, Any], version: str) -> None: document["version"] = version @@ -79,7 +79,7 @@ def get_version(self) -> str: document = tomlkit.parse(self.file.read_text()) return self.get(document) - def set_version(self, version: str): + def set_version(self, version: str) -> None: document = tomlkit.parse(self.file.read_text()) self.set(document, version) self.file.write_text(tomlkit.dumps(document)) @@ -87,5 +87,5 @@ def set_version(self, version: str): def get(self, document: tomlkit.TOMLDocument) -> str: return document["project"]["version"] # type: ignore - def set(self, document: tomlkit.TOMLDocument, version: str): + def set(self, document: tomlkit.TOMLDocument, version: str) -> None: document["project"]["version"] = version # type: ignore diff --git a/commitizen/providers/cargo_provider.py b/commitizen/providers/cargo_provider.py index 2e73ff35a1..87e45cd71c 100644 --- a/commitizen/providers/cargo_provider.py +++ b/commitizen/providers/cargo_provider.py @@ -28,7 +28,7 @@ def get(self, document: tomlkit.TOMLDocument) -> str: ... return document["workspace"]["package"]["version"] # type: ignore - def set(self, document: tomlkit.TOMLDocument, version: str): + def set(self, document: tomlkit.TOMLDocument, version: str) -> None: try: document["workspace"]["package"]["version"] = version # type: ignore return diff --git a/commitizen/providers/commitizen_provider.py b/commitizen/providers/commitizen_provider.py index a1da25ff72..7ce177a604 100644 --- a/commitizen/providers/commitizen_provider.py +++ b/commitizen/providers/commitizen_provider.py @@ -11,5 +11,5 @@ class CommitizenProvider(VersionProvider): def get_version(self) -> str: return self.config.settings["version"] # type: ignore - def set_version(self, version: str): + def set_version(self, version: str) -> None: self.config.set_key("version", version) diff --git a/commitizen/providers/poetry_provider.py b/commitizen/providers/poetry_provider.py index 7aa28f56d9..1dd33f053e 100644 --- a/commitizen/providers/poetry_provider.py +++ b/commitizen/providers/poetry_provider.py @@ -15,5 +15,5 @@ class PoetryProvider(TomlProvider): def get(self, pyproject: tomlkit.TOMLDocument) -> str: return pyproject["tool"]["poetry"]["version"] # type: ignore - def set(self, pyproject: tomlkit.TOMLDocument, version: str): + def set(self, pyproject: tomlkit.TOMLDocument, version: str) -> None: pyproject["tool"]["poetry"]["version"] = version # type: ignore diff --git a/commitizen/providers/scm_provider.py b/commitizen/providers/scm_provider.py index cb575148cb..3085b16efa 100644 --- a/commitizen/providers/scm_provider.py +++ b/commitizen/providers/scm_provider.py @@ -23,6 +23,6 @@ def get_version(self) -> str: return "0.0.0" return str(versions[-1]) - def set_version(self, version: str): + def set_version(self, version: str) -> None: # Not necessary pass From 2e65d17cd086443f9f848755dd6d673052bb3189 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 18:48:20 +0800 Subject: [PATCH 552/598] style: remove Union --- commitizen/cmd.py | 6 ++++-- commitizen/cz/utils.py | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/commitizen/cmd.py b/commitizen/cmd.py index 9d6b2f6d2a..3f13087233 100644 --- a/commitizen/cmd.py +++ b/commitizen/cmd.py @@ -1,7 +1,9 @@ +from __future__ import annotations + import os import subprocess from collections.abc import Mapping -from typing import NamedTuple, Union +from typing import NamedTuple from charset_normalizer import from_bytes @@ -29,7 +31,7 @@ def _try_decode(bytes_: bytes) -> str: raise CharacterSetDecodeError() from e -def run(cmd: str, env: Union[Mapping[str, str], None] = None) -> Command: +def run(cmd: str, env: Mapping[str, str] | None = None) -> Command: if env is not None: env = {**os.environ, **env} process = subprocess.Popen( diff --git a/commitizen/cz/utils.py b/commitizen/cz/utils.py index 430bda2d43..a6f687226c 100644 --- a/commitizen/cz/utils.py +++ b/commitizen/cz/utils.py @@ -1,7 +1,6 @@ import os import re import tempfile -from typing import Union from commitizen import git from commitizen.cz import exceptions @@ -9,7 +8,7 @@ _RE_LOCAL_VERSION = re.compile(r"\+.+") -def required_validator(answer: str, msg: Union[str, None] = None) -> str: +def required_validator(answer: str, msg: object = None) -> str: if not answer: raise exceptions.AnswerRequiredError(msg) return answer From 59531a6482330d96ebe58fc7eb286a53b52eca74 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 19:00:05 +0800 Subject: [PATCH 553/598] style: better type --- commitizen/cli.py | 4 ++-- commitizen/providers/base_provider.py | 5 +++-- commitizen/providers/npm_provider.py | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 9998691f41..fa05fb2f73 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -8,7 +8,7 @@ from functools import partial from pathlib import Path from types import TracebackType -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, cast import argcomplete from decli import cli @@ -48,7 +48,7 @@ def __call__( self, parser: argparse.ArgumentParser, namespace: argparse.Namespace, - kwarg: str | Sequence[Any] | None, + kwarg: str | Sequence[object] | None, option_string: str | None = None, ) -> None: if not isinstance(kwarg, str): diff --git a/commitizen/providers/base_provider.py b/commitizen/providers/base_provider.py index 9c1e0f7a98..7a7e1205b4 100644 --- a/commitizen/providers/base_provider.py +++ b/commitizen/providers/base_provider.py @@ -2,6 +2,7 @@ import json from abc import ABC, abstractmethod +from collections.abc import Mapping from pathlib import Path from typing import Any, ClassVar @@ -63,8 +64,8 @@ def set_version(self, version: str) -> None: self.set(document, version) self.file.write_text(json.dumps(document, indent=self.indent) + "\n") - def get(self, document: dict[str, Any]) -> str: - return document["version"] # type: ignore + def get(self, document: Mapping[str, str]) -> str: + return document["version"] def set(self, document: dict[str, Any], version: str) -> None: document["version"] = version diff --git a/commitizen/providers/npm_provider.py b/commitizen/providers/npm_provider.py index 12900ff7de..3125447250 100644 --- a/commitizen/providers/npm_provider.py +++ b/commitizen/providers/npm_provider.py @@ -1,6 +1,7 @@ from __future__ import annotations import json +from collections.abc import Mapping from pathlib import Path from typing import Any, ClassVar @@ -58,8 +59,8 @@ def set_version(self, version: str) -> None: json.dumps(shrinkwrap_document, indent=self.indent) + "\n" ) - def get_package_version(self, document: dict[str, Any]) -> str: - return document["version"] # type: ignore + def get_package_version(self, document: Mapping[str, str]) -> str: + return document["version"] def set_package_version( self, document: dict[str, Any], version: str From e86d80ead8b1684c389f8ef76edb2723ee339e20 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 22:12:30 +0800 Subject: [PATCH 554/598] style: add `-> None` to __init__ --- commitizen/changelog_formats/__init__.py | 2 +- commitizen/changelog_formats/base.py | 2 +- commitizen/commands/bump.py | 2 +- commitizen/commands/changelog.py | 2 +- commitizen/commands/check.py | 2 +- commitizen/commands/commit.py | 2 +- commitizen/commands/example.py | 2 +- commitizen/commands/info.py | 2 +- commitizen/commands/init.py | 2 +- commitizen/commands/list_cz.py | 2 +- commitizen/commands/schema.py | 2 +- commitizen/commands/version.py | 2 +- commitizen/config/json_config.py | 2 +- commitizen/config/toml_config.py | 2 +- commitizen/config/yaml_config.py | 2 +- commitizen/cz/customize/customize.py | 2 +- commitizen/exceptions.py | 4 ++-- commitizen/git.py | 4 ++-- commitizen/providers/base_provider.py | 2 +- commitizen/version_schemes.py | 2 +- 20 files changed, 22 insertions(+), 22 deletions(-) diff --git a/commitizen/changelog_formats/__init__.py b/commitizen/changelog_formats/__init__.py index 782bfb24cb..b7b3cac01d 100644 --- a/commitizen/changelog_formats/__init__.py +++ b/commitizen/changelog_formats/__init__.py @@ -25,7 +25,7 @@ class ChangelogFormat(Protocol): config: BaseConfig - def __init__(self, config: BaseConfig): + def __init__(self, config: BaseConfig) -> None: self.config = config @property diff --git a/commitizen/changelog_formats/base.py b/commitizen/changelog_formats/base.py index f69cf8f00f..cb5d385bf8 100644 --- a/commitizen/changelog_formats/base.py +++ b/commitizen/changelog_formats/base.py @@ -20,7 +20,7 @@ class BaseFormat(ChangelogFormat, metaclass=ABCMeta): extension: ClassVar[str] = "" alternative_extensions: ClassVar[set[str]] = set() - def __init__(self, config: BaseConfig): + def __init__(self, config: BaseConfig) -> None: # Constructor needs to be redefined because `Protocol` prevent instantiation by default # See: https://bugs.python.org/issue44807 self.config = config diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 0607c7ef73..0aee74a817 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -40,7 +40,7 @@ class Bump: """Show prompt for the user to create a guided commit.""" - def __init__(self, config: BaseConfig, arguments: dict): + def __init__(self, config: BaseConfig, arguments: dict) -> None: if not git.is_git_project(): raise NotAGitProjectError() diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 5a1270dfd8..59d799b037 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -29,7 +29,7 @@ class Changelog: """Generate a changelog based on the commit history.""" - def __init__(self, config: BaseConfig, args: Mapping[str, Any]): + def __init__(self, config: BaseConfig, args: Mapping[str, Any]) -> None: if not git.is_git_project(): raise NotAGitProjectError() diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index 6cf91bb926..82a8039fa3 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -19,7 +19,7 @@ class Check: def __init__( self, config: BaseConfig, arguments: dict[str, Any], cwd: str = os.getcwd() - ): + ) -> None: """Initial check command. Args: diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 22ad642c43..68095d0e0c 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -31,7 +31,7 @@ class Commit: """Show prompt for the user to create a guided commit.""" - def __init__(self, config: BaseConfig, arguments: dict): + def __init__(self, config: BaseConfig, arguments: dict) -> None: if not git.is_git_project(): raise NotAGitProjectError() diff --git a/commitizen/commands/example.py b/commitizen/commands/example.py index 818e217530..ba9f34adc4 100644 --- a/commitizen/commands/example.py +++ b/commitizen/commands/example.py @@ -5,7 +5,7 @@ class Example: """Show an example so people understands the rules.""" - def __init__(self, config: BaseConfig, *args: object): + def __init__(self, config: BaseConfig, *args: object) -> None: self.config: BaseConfig = config self.cz = factory.committer_factory(self.config) diff --git a/commitizen/commands/info.py b/commitizen/commands/info.py index 5b649ceb5d..5ea8227313 100644 --- a/commitizen/commands/info.py +++ b/commitizen/commands/info.py @@ -5,7 +5,7 @@ class Info: """Show in depth explanation of your rules.""" - def __init__(self, config: BaseConfig, *args: object): + def __init__(self, config: BaseConfig, *args: object) -> None: self.config: BaseConfig = config self.cz = factory.committer_factory(self.config) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index ca6426b0bd..1207cd02ee 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -79,7 +79,7 @@ def is_pre_commit_installed(self) -> bool: class Init: - def __init__(self, config: BaseConfig, *args: object): + def __init__(self, config: BaseConfig, *args: object) -> None: self.config: BaseConfig = config self.encoding = config.settings["encoding"] self.cz = factory.committer_factory(self.config) diff --git a/commitizen/commands/list_cz.py b/commitizen/commands/list_cz.py index ff4e12ad44..412266f6c3 100644 --- a/commitizen/commands/list_cz.py +++ b/commitizen/commands/list_cz.py @@ -6,7 +6,7 @@ class ListCz: """List currently installed rules.""" - def __init__(self, config: BaseConfig, *args: object): + def __init__(self, config: BaseConfig, *args: object) -> None: self.config: BaseConfig = config def __call__(self) -> None: diff --git a/commitizen/commands/schema.py b/commitizen/commands/schema.py index 5c77898d8a..a7aeb53569 100644 --- a/commitizen/commands/schema.py +++ b/commitizen/commands/schema.py @@ -5,7 +5,7 @@ class Schema: """Show structure of the rule.""" - def __init__(self, config: BaseConfig, *args: object): + def __init__(self, config: BaseConfig, *args: object) -> None: self.config: BaseConfig = config self.cz = factory.committer_factory(self.config) diff --git a/commitizen/commands/version.py b/commitizen/commands/version.py index 55d0a950a3..ecf1f03129 100644 --- a/commitizen/commands/version.py +++ b/commitizen/commands/version.py @@ -12,7 +12,7 @@ class Version: """Get the version of the installed commitizen or the current project.""" - def __init__(self, config: BaseConfig, *args: Mapping[str, Any]): + def __init__(self, config: BaseConfig, *args: Mapping[str, Any]) -> None: self.config: BaseConfig = config self.parameter = args[0] self.operating_system = platform.system() diff --git a/commitizen/config/json_config.py b/commitizen/config/json_config.py index 83e0a928a0..be1f1c36b0 100644 --- a/commitizen/config/json_config.py +++ b/commitizen/config/json_config.py @@ -20,7 +20,7 @@ class JsonConfig(BaseConfig): - def __init__(self, *, data: bytes | str, path: Path | str): + def __init__(self, *, data: bytes | str, path: Path | str) -> None: super().__init__() self.is_empty_config = False self.path = path diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index 9bab994fd5..3571c9c882 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -21,7 +21,7 @@ class TomlConfig(BaseConfig): - def __init__(self, *, data: bytes | str, path: Path | str): + def __init__(self, *, data: bytes | str, path: Path | str) -> None: super().__init__() self.is_empty_config = False self.path = path diff --git a/commitizen/config/yaml_config.py b/commitizen/config/yaml_config.py index 8eac9bb785..f2a79e6937 100644 --- a/commitizen/config/yaml_config.py +++ b/commitizen/config/yaml_config.py @@ -21,7 +21,7 @@ class YAMLConfig(BaseConfig): - def __init__(self, *, data: bytes | str, path: Path | str): + def __init__(self, *, data: bytes | str, path: Path | str) -> None: super().__init__() self.is_empty_config = False self.path = path diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index 53ada4b2c0..8f844501ec 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -26,7 +26,7 @@ class CustomizeCommitsCz(BaseCommitizen): bump_map_major_version_zero = defaults.BUMP_MAP_MAJOR_VERSION_ZERO change_type_order = defaults.CHANGE_TYPE_ORDER - def __init__(self, config: BaseConfig): + def __init__(self, config: BaseConfig) -> None: super().__init__(config) if "customize" not in self.config.settings: diff --git a/commitizen/exceptions.py b/commitizen/exceptions.py index 87efabe2ab..8c0956be53 100644 --- a/commitizen/exceptions.py +++ b/commitizen/exceptions.py @@ -41,7 +41,7 @@ class ExitCode(enum.IntEnum): class CommitizenException(Exception): - def __init__(self, *args: str, **kwargs: Any): + def __init__(self, *args: str, **kwargs: Any) -> None: self.output_method = kwargs.get("output_method") or out.error self.exit_code: ExitCode = self.__class__.exit_code if args: @@ -58,7 +58,7 @@ def __str__(self) -> str: class ExpectedExit(CommitizenException): exit_code = ExitCode.EXPECTED_EXIT - def __init__(self, *args: str, **kwargs: Any): + def __init__(self, *args: str, **kwargs: Any) -> None: output_method = kwargs.get("output_method") or out.write kwargs["output_method"] = output_method super().__init__(*args, **kwargs) diff --git a/commitizen/git.py b/commitizen/git.py index 54d57f69bb..b8528e3f77 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -59,7 +59,7 @@ def __init__( author: str = "", author_email: str = "", parents: list[str] | None = None, - ): + ) -> None: self.rev = rev.strip() self.title = title.strip() self.body = body.strip() @@ -132,7 +132,7 @@ def __repr__(self) -> str: class GitTag(GitObject): - def __init__(self, name: str, rev: str, date: str): + def __init__(self, name: str, rev: str, date: str) -> None: self.rev = rev.strip() self.name = name.strip() self._date = date.strip() diff --git a/commitizen/providers/base_provider.py b/commitizen/providers/base_provider.py index 7a7e1205b4..27c3123416 100644 --- a/commitizen/providers/base_provider.py +++ b/commitizen/providers/base_provider.py @@ -20,7 +20,7 @@ class VersionProvider(ABC): config: BaseConfig - def __init__(self, config: BaseConfig): + def __init__(self, config: BaseConfig) -> None: self.config = config @abstractmethod diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index 96a68b05fd..a59d3c0aa0 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -51,7 +51,7 @@ class VersionProtocol(Protocol): parser: ClassVar[re.Pattern] """Regex capturing this version scheme into a `version` group""" - def __init__(self, version: str): + def __init__(self, version: str) -> None: """ Initialize a version object from its string representation. From 44123c41b8afb58b67d889fd25b90d935f14399a Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 22:35:44 +0800 Subject: [PATCH 555/598] build(ruff,mypy): more strict rules --- commitizen/git.py | 2 +- pyproject.toml | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/commitizen/git.py b/commitizen/git.py index b8528e3f77..fb59750eaf 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -312,7 +312,7 @@ def get_core_editor() -> str | None: return None -def smart_open(*args, **kwargs): # type: ignore[no-untyped-def,unused-ignore] +def smart_open(*args, **kwargs): # type: ignore[no-untyped-def,unused-ignore] # noqa: ANN201 """Open a file with the EOL style determined from Git.""" return open(*args, newline=EOLType.for_open(), **kwargs) diff --git a/pyproject.toml b/pyproject.toml index 757c72bc0a..9961a2f409 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -187,6 +187,9 @@ line-length = 88 [tool.ruff.lint] select = [ + # flake8-annotations + "ANN001", + "ANN2", # pycodestyle "E", # Pyflakes @@ -202,6 +205,9 @@ select = [ ] ignore = ["E501", "D1", "D415"] +[tool.ruff.lint.per-file-ignores] +"tests/*" = ["ANN"] + [tool.ruff.lint.isort] known-first-party = ["commitizen", "tests"] @@ -209,7 +215,8 @@ known-first-party = ["commitizen", "tests"] convention = "google" [tool.mypy] -files = "commitizen" +files = ["commitizen", "tests"] +disallow_untyped_defs = true disallow_untyped_decorators = true disallow_subclassing_any = true warn_return_any = true @@ -217,6 +224,10 @@ warn_redundant_casts = true warn_unused_ignores = true warn_unused_configs = true +[[tool.mypy.overrides]] +module = "tests/*" +disallow_untyped_defs = false + [[tool.mypy.overrides]] module = "py.*" # Legacy pytest dependencies ignore_missing_imports = true @@ -233,14 +244,14 @@ poetry_command = "" [tool.poe.tasks] format.help = "Format the code" format.sequence = [ - { cmd = "ruff check --fix commitizen tests" }, - { cmd = "ruff format commitizen tests" }, + { cmd = "ruff check --fix" }, + { cmd = "ruff format" }, ] lint.help = "Lint the code" lint.sequence = [ - { cmd = "ruff check commitizen/ tests/ --fix" }, - { cmd = "mypy commitizen/ tests/" }, + { cmd = "ruff check" }, + { cmd = "mypy" }, ] check-commit.help = "Check the commit message" From 20dda31eb1da62eab4839dcfc910d3130f7dfe7b Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 31 May 2025 18:20:41 +0800 Subject: [PATCH 556/598] fix(BaseConfig): mypy error --- commitizen/config/base_config.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/commitizen/config/base_config.py b/commitizen/config/base_config.py index 10a26e3f0c..59c0d16a06 100644 --- a/commitizen/config/base_config.py +++ b/commitizen/config/base_config.py @@ -26,16 +26,11 @@ def settings(self) -> Settings: return self._settings @property - def path(self) -> Path | None: - return self._path + def path(self) -> Path: + return self._path # type: ignore @path.setter def path(self, path: str | Path) -> None: - """ - mypy does not like this until 1.16 - See https://github.com/python/mypy/pull/18510 - TODO: remove "type: ignore" from the call sites when 1.16 is available - """ self._path = Path(path) def set_key(self, key: str, value: Any) -> Self: From 001fe8d2711f50fa093cb0f9e230856da660c316 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 31 May 2025 22:04:10 +0800 Subject: [PATCH 557/598] build(mypy): remove disallow_untyped_defs because it's already done by ruff rules --- pyproject.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9961a2f409..ee0ecc9ced 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -216,7 +216,6 @@ convention = "google" [tool.mypy] files = ["commitizen", "tests"] -disallow_untyped_defs = true disallow_untyped_decorators = true disallow_subclassing_any = true warn_return_any = true @@ -224,10 +223,6 @@ warn_redundant_casts = true warn_unused_ignores = true warn_unused_configs = true -[[tool.mypy.overrides]] -module = "tests/*" -disallow_untyped_defs = false - [[tool.mypy.overrides]] module = "py.*" # Legacy pytest dependencies ignore_missing_imports = true From f66e577442305255b7f2fdc9ce4e26c742921538 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 31 May 2025 00:45:15 +0800 Subject: [PATCH 558/598] refactor(bump): TypedDict for bump argument --- commitizen/cli.py | 2 +- commitizen/commands/bump.py | 129 ++++++++++++++++------------ commitizen/defaults.py | 38 ++++---- tests/commands/test_bump_command.py | 2 +- 4 files changed, 97 insertions(+), 74 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index fa05fb2f73..e1bd57b523 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -680,7 +680,7 @@ def main() -> None: ) sys.excepthook = no_raise_debug_excepthook - args.func(conf, arguments)() + args.func(conf, arguments)() # type: ignore if __name__ == "__main__": diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 0aee74a817..beed384b78 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -37,37 +37,65 @@ logger = getLogger("commitizen") +class BumpArguments(Settings, total=False): + allow_no_commit: bool | None + annotated_tag_message: str | None + annotated_tag: bool + build_metadata: str | None + changelog_to_stdout: bool + changelog: bool + check_consistency: bool + devrelease: int | None + dry_run: bool + file_name: str + files_only: bool | None + get_next: bool + git_output_to_stderr: bool + gpg_sign: bool + increment_mode: str + increment: Increment | None + local_version: bool + manual_version: str | None + no_verify: bool + prerelease: Prerelease | None + retry: bool + yes: bool + + class Bump: """Show prompt for the user to create a guided commit.""" - def __init__(self, config: BaseConfig, arguments: dict) -> None: + def __init__(self, config: BaseConfig, arguments: BumpArguments) -> None: if not git.is_git_project(): raise NotAGitProjectError() self.config: BaseConfig = config self.encoding = config.settings["encoding"] - self.arguments: dict = arguments - self.bump_settings: dict = { - **config.settings, - **{ - key: arguments[key] - for key in [ - "tag_format", - "prerelease", - "increment", - "increment_mode", - "bump_message", - "gpg_sign", - "annotated_tag", - "annotated_tag_message", - "major_version_zero", - "prerelease_offset", - "template", - "file_name", - ] - if arguments.get(key) is not None + self.arguments = arguments + self.bump_settings = cast( + BumpArguments, + { + **config.settings, + **{ + k: v + for k, v in { + "annotated_tag_message": arguments.get("annotated_tag_message"), + "annotated_tag": arguments.get("annotated_tag"), + "bump_message": arguments.get("bump_message"), + "file_name": arguments.get("file_name"), + "gpg_sign": arguments.get("gpg_sign"), + "increment_mode": arguments.get("increment_mode"), + "increment": arguments.get("increment"), + "major_version_zero": arguments.get("major_version_zero"), + "prerelease_offset": arguments.get("prerelease_offset"), + "prerelease": arguments.get("prerelease"), + "tag_format": arguments.get("tag_format"), + "template": arguments.get("template"), + }.items() + if v is not None + }, }, - } + ) self.cz = factory.committer_factory(self.config) self.changelog_flag = arguments["changelog"] self.changelog_config = self.config.settings.get("update_changelog_on_bump") @@ -120,11 +148,10 @@ def _is_initial_tag( def _find_increment(self, commits: list[git.GitCommit]) -> Increment | None: # Update the bump map to ensure major version doesn't increment. - is_major_version_zero: bool = self.bump_settings["major_version_zero"] # self.cz.bump_map = defaults.bump_map_major_version_zero bump_map = ( self.cz.bump_map_major_version_zero - if is_major_version_zero + if self.bump_settings["major_version_zero"] else self.cz.bump_map ) bump_pattern = self.cz.bump_pattern @@ -144,23 +171,14 @@ def __call__(self) -> None: except TypeError: raise NoVersionSpecifiedError() - bump_commit_message: str | None = self.bump_settings["bump_message"] - version_files: list[str] = self.bump_settings["version_files"] - major_version_zero: bool = self.bump_settings["major_version_zero"] - prerelease_offset: int = self.bump_settings["prerelease_offset"] - - dry_run: bool = self.arguments["dry_run"] - is_yes: bool = self.arguments["yes"] - increment: Increment | None = self.arguments["increment"] - prerelease: Prerelease | None = self.arguments["prerelease"] - devrelease: int | None = self.arguments["devrelease"] - is_files_only: bool | None = self.arguments["files_only"] - is_local_version: bool = self.arguments["local_version"] + increment = self.arguments["increment"] + prerelease = self.arguments["prerelease"] + devrelease = self.arguments["devrelease"] + is_local_version = self.arguments["local_version"] manual_version = self.arguments["manual_version"] build_metadata = self.arguments["build_metadata"] - increment_mode: str = self.arguments["increment_mode"] - get_next: bool = self.arguments["get_next"] - allow_no_commit: bool | None = self.arguments["allow_no_commit"] + get_next = self.arguments["get_next"] + allow_no_commit = self.arguments["allow_no_commit"] if manual_version: if increment: @@ -182,7 +200,7 @@ def __call__(self) -> None: "--build-metadata cannot be combined with MANUAL_VERSION" ) - if major_version_zero: + if self.bump_settings["major_version_zero"]: raise NotAllowed( "--major-version-zero cannot be combined with MANUAL_VERSION" ) @@ -190,7 +208,7 @@ def __call__(self) -> None: if get_next: raise NotAllowed("--get-next cannot be combined with MANUAL_VERSION") - if major_version_zero: + if self.bump_settings["major_version_zero"]: if not current_version.release[0] == 0: raise NotAllowed( f"--major-version-zero is meaningless for current version {current_version}" @@ -215,7 +233,7 @@ def __call__(self) -> None: else: # If user specified changelog_to_stdout, they probably want the # changelog to be generated as well, this is the most intuitive solution - self.changelog_flag = ( + self.changelog_flag = bool( self.changelog_flag or bool(self.changelog_to_stdout) or self.changelog_config @@ -227,7 +245,7 @@ def __call__(self) -> None: current_tag, "name", rules.normalize_tag(current_version) ) - is_initial = self._is_initial_tag(current_tag, is_yes) + is_initial = self._is_initial_tag(current_tag, self.arguments["yes"]) if manual_version: try: @@ -273,16 +291,16 @@ def __call__(self) -> None: new_version = current_version.bump( increment, prerelease=prerelease, - prerelease_offset=prerelease_offset, + prerelease_offset=self.bump_settings["prerelease_offset"], devrelease=devrelease, is_local_version=is_local_version, build_metadata=build_metadata, - exact_increment=increment_mode == "exact", + exact_increment=self.arguments["increment_mode"] == "exact", ) new_tag_version = rules.normalize_tag(new_version) message = bump.create_commit_message( - current_version, new_version, bump_commit_message + current_version, new_version, self.bump_settings["bump_message"] ) if get_next: @@ -314,6 +332,7 @@ def __call__(self) -> None: ) files: list[str] = [] + dry_run = self.arguments["dry_run"] if self.changelog_flag: args = { "unreleased_version": new_tag_version, @@ -342,7 +361,7 @@ def __call__(self) -> None: bump.update_version_in_files( str(current_version), str(new_version), - version_files, + self.bump_settings["version_files"], check_consistency=self.check_consistency, encoding=self.encoding, ) @@ -366,7 +385,7 @@ def __call__(self) -> None: else None, ) - if is_files_only: + if self.arguments["files_only"]: raise ExpectedExit() # FIXME: check if any changes have been staged @@ -395,11 +414,15 @@ def __call__(self) -> None: c = git.tag( new_tag_version, - signed=self.bump_settings.get("gpg_sign", False) - or bool(self.config.settings.get("gpg_sign", False)), - annotated=self.bump_settings.get("annotated_tag", False) - or bool(self.config.settings.get("annotated_tag", False)) - or bool(self.bump_settings.get("annotated_tag_message", False)), + signed=bool( + self.bump_settings.get("gpg_sign") + or self.config.settings.get("gpg_sign") + ), + annotated=bool( + self.bump_settings.get("annotated_tag") + or self.config.settings.get("annotated_tag") + or self.bump_settings.get("annotated_tag_message") + ), msg=self.bump_settings.get("annotated_tag_message", None), # TODO: also get from self.config.settings? ) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index adbb9e6d1a..4ad7ae4d8f 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -29,36 +29,36 @@ class CzSettings(TypedDict, total=False): class Settings(TypedDict, total=False): - name: str - version: str | None - version_files: list[str] - version_provider: str | None - version_scheme: str | None - version_type: str | None - tag_format: str - legacy_tag_formats: Sequence[str] - ignored_tag_formats: Sequence[str] - bump_message: str | None - retry_after_failure: bool allow_abort: bool allowed_prefixes: list[str] + always_signoff: bool + bump_message: str | None changelog_file: str changelog_format: str | None changelog_incremental: bool - changelog_start_rev: str | None changelog_merge_prerelease: bool - update_changelog_on_bump: bool - use_shortcuts: bool - style: list[tuple[str, str]] + changelog_start_rev: str | None customize: CzSettings + encoding: str + extras: dict[str, Any] + ignored_tag_formats: Sequence[str] + legacy_tag_formats: Sequence[str] major_version_zero: bool - pre_bump_hooks: list[str] | None + name: str post_bump_hooks: list[str] | None + pre_bump_hooks: list[str] | None prerelease_offset: int - encoding: str - always_signoff: bool + retry_after_failure: bool + style: list[tuple[str, str]] + tag_format: str template: str | None - extras: dict[str, Any] + update_changelog_on_bump: bool + use_shortcuts: bool + version_files: list[str] + version_provider: str | None + version_scheme: str | None + version_type: str | None + version: str | None CONFIG_FILES: list[str] = [ diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 41da985704..64b810e4de 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1721,7 +1721,7 @@ def test_is_initial_tag(mocker: MockFixture, tmp_commitizen_project): "extras": None, } - bump_cmd = bump.Bump(config, arguments) + bump_cmd = bump.Bump(config, arguments) # type: ignore # Test case 1: No current tag, not yes mode mocker.patch("questionary.confirm", return_value=mocker.Mock(ask=lambda: True)) From 8e88d8cf1766cc78c6975c7663480cc5752b64d5 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 00:57:10 +0800 Subject: [PATCH 559/598] refactor(changelog): type untyped arguments --- commitizen/commands/bump.py | 4 ++-- commitizen/commands/changelog.py | 38 +++++++++++++++++++++++--------- commitizen/defaults.py | 1 + 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index beed384b78..65827d406e 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -342,14 +342,14 @@ def __call__(self) -> None: "dry_run": dry_run, } if self.changelog_to_stdout: - changelog_cmd = Changelog(self.config, {**args, "dry_run": True}) + changelog_cmd = Changelog(self.config, {**args, "dry_run": True}) # type: ignore try: changelog_cmd() except DryRunExit: pass args["file_name"] = self.file_name - changelog_cmd = Changelog(self.config, args) + changelog_cmd = Changelog(self.config, args) # type: ignore changelog_cmd() files.append(changelog_cmd.file_name) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 59d799b037..6d150b03f9 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -2,11 +2,11 @@ import os import os.path -from collections.abc import Generator, Iterable, Mapping +from collections.abc import Generator, Iterable from difflib import SequenceMatcher from operator import itemgetter from pathlib import Path -from typing import Any, cast +from typing import Any, TypedDict, cast from commitizen import changelog, defaults, factory, git, out from commitizen.changelog_formats import get_changelog_format @@ -26,10 +26,28 @@ from commitizen.version_schemes import get_version_scheme +class ChangelogArgs(TypedDict, total=False): + change_type_map: dict[str, str] + change_type_order: list[str] + current_version: str + dry_run: bool + file_name: str + incremental: bool + merge_prerelease: bool + rev_range: str + start_rev: str + tag_format: str + unreleased_version: str | None + version_scheme: str + template: str + extras: dict[str, Any] + export_template: str + + class Changelog: """Generate a changelog based on the commit history.""" - def __init__(self, config: BaseConfig, args: Mapping[str, Any]) -> None: + def __init__(self, config: BaseConfig, args: ChangelogArgs) -> None: if not git.is_git_project(): raise NotAGitProjectError() @@ -59,17 +77,17 @@ def __init__(self, config: BaseConfig, args: Mapping[str, Any]) -> None: self.changelog_format = get_changelog_format(self.config, self.file_name) - self.incremental = args["incremental"] or self.config.settings.get( - "changelog_incremental" + self.incremental = bool( + args.get("incremental") or self.config.settings.get("changelog_incremental") ) - self.dry_run = args["dry_run"] + self.dry_run = bool(args.get("dry_run")) self.scheme = get_version_scheme( self.config.settings, args.get("version_scheme") ) current_version = ( - args.get("current_version", config.settings.get("version")) or "" + args.get("current_version") or self.config.settings.get("version") or "" ) self.current_version = self.scheme(current_version) if current_version else None @@ -84,9 +102,7 @@ def __init__(self, config: BaseConfig, args: Mapping[str, Any]) -> None: or defaults.CHANGE_TYPE_ORDER, ) self.rev_range = args.get("rev_range") - self.tag_format: str = ( - args.get("tag_format") or self.config.settings["tag_format"] - ) + self.tag_format = args.get("tag_format") or self.config.settings["tag_format"] self.tag_rules = TagRules( scheme=self.scheme, tag_format=self.tag_format, @@ -164,7 +180,7 @@ def __call__(self) -> None: start_rev = self.start_rev unreleased_version = self.unreleased_version changelog_meta = changelog.Metadata() - change_type_map: dict[str, str] | None = self.change_type_map # type: ignore + change_type_map: dict[str, str] | None = self.change_type_map changelog_message_builder_hook: MessageBuilderHook | None = ( self.cz.changelog_message_builder_hook ) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 4ad7ae4d8f..29c9f2a494 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -37,6 +37,7 @@ class Settings(TypedDict, total=False): changelog_format: str | None changelog_incremental: bool changelog_merge_prerelease: bool + change_type_map: dict[str, str] changelog_start_rev: str | None customize: CzSettings encoding: str From 49bb8547a3366a22ddd10973fad5623a5662c0a9 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 00:59:21 +0800 Subject: [PATCH 560/598] refactor(check): remove unused argument --- commitizen/commands/check.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index 82a8039fa3..a293b6f855 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -1,6 +1,5 @@ from __future__ import annotations -import os import re import sys from typing import Any @@ -17,9 +16,7 @@ class Check: """Check if the current commit msg matches the commitizen format.""" - def __init__( - self, config: BaseConfig, arguments: dict[str, Any], cwd: str = os.getcwd() - ) -> None: + def __init__(self, config: BaseConfig, arguments: dict[str, Any]) -> None: """Initial check command. Args: From 296b1b6281ce843d99d9f9c76c51675683c086c4 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:01:08 +0800 Subject: [PATCH 561/598] style(bump): rename class for consistency --- commitizen/commands/bump.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 65827d406e..4bad83f5d6 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -37,7 +37,7 @@ logger = getLogger("commitizen") -class BumpArguments(Settings, total=False): +class BumpArgs(Settings, total=False): allow_no_commit: bool | None annotated_tag_message: str | None annotated_tag: bool @@ -65,7 +65,7 @@ class BumpArguments(Settings, total=False): class Bump: """Show prompt for the user to create a guided commit.""" - def __init__(self, config: BaseConfig, arguments: BumpArguments) -> None: + def __init__(self, config: BaseConfig, arguments: BumpArgs) -> None: if not git.is_git_project(): raise NotAGitProjectError() @@ -73,7 +73,7 @@ def __init__(self, config: BaseConfig, arguments: BumpArguments) -> None: self.encoding = config.settings["encoding"] self.arguments = arguments self.bump_settings = cast( - BumpArguments, + BumpArgs, { **config.settings, **{ From 1ded688bf13fd13ab465b4236290ac0ed8aaea8b Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:08:03 +0800 Subject: [PATCH 562/598] refactor(check): type CheckArgs arguments --- commitizen/commands/check.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index a293b6f855..ba0beeeb4e 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -2,7 +2,7 @@ import re import sys -from typing import Any +from typing import TypedDict from commitizen import factory, git, out from commitizen.config import BaseConfig @@ -13,10 +13,20 @@ ) +class CheckArgs(TypedDict, total=False): + commit_msg_file: str + commit_msg: str + rev_range: str + allow_abort: bool + message_length_limit: int + allowed_prefixes: list[str] + message: str + + class Check: """Check if the current commit msg matches the commitizen format.""" - def __init__(self, config: BaseConfig, arguments: dict[str, Any]) -> None: + def __init__(self, config: BaseConfig, arguments: CheckArgs) -> None: """Initial check command. Args: @@ -24,16 +34,15 @@ def __init__(self, config: BaseConfig, arguments: dict[str, Any]) -> None: arguments: All the flags provided by the user cwd: Current work directory """ - self.commit_msg_file: str | None = arguments.get("commit_msg_file") - self.commit_msg: str | None = arguments.get("message") - self.rev_range: str | None = arguments.get("rev_range") - self.allow_abort: bool = bool( + self.commit_msg_file = arguments.get("commit_msg_file") + self.commit_msg = arguments.get("message") + self.rev_range = arguments.get("rev_range") + self.allow_abort = bool( arguments.get("allow_abort", config.settings["allow_abort"]) ) - self.max_msg_length: int = arguments.get("message_length_limit", 0) + self.max_msg_length = arguments.get("message_length_limit", 0) # we need to distinguish between None and [], which is a valid value - allowed_prefixes = arguments.get("allowed_prefixes") self.allowed_prefixes: list[str] = ( allowed_prefixes From e32778afb257706c7bea839ec784d5fc5b9020b3 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:16:52 +0800 Subject: [PATCH 563/598] refactor(commit): type commit args --- commitizen/commands/commit.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 68095d0e0c..43feb272ba 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -6,7 +6,7 @@ import subprocess import tempfile from pathlib import Path -from typing import Union, cast +from typing import TypedDict import questionary @@ -28,10 +28,22 @@ from commitizen.git import smart_open +class CommitArgs(TypedDict, total=False): + all: bool + dry_run: bool + edit: bool + extra_cli_args: str + message_length_limit: int + no_retry: bool + signoff: bool + write_message_to_file: Path | None + retry: bool + + class Commit: """Show prompt for the user to create a guided commit.""" - def __init__(self, config: BaseConfig, arguments: dict) -> None: + def __init__(self, config: BaseConfig, arguments: CommitArgs) -> None: if not git.is_git_project(): raise NotAGitProjectError() @@ -69,7 +81,7 @@ def _prompt_commit_questions(self) -> str: message = cz.message(answers) message_len = len(message.partition("\n")[0].strip()) - message_length_limit: int = self.arguments.get("message_length_limit", 0) + message_length_limit = self.arguments.get("message_length_limit", 0) if 0 < message_length_limit < message_len: raise CommitMessageLengthExceededError( f"Length of commit message exceeds limit ({message_len}/{message_length_limit})" @@ -108,12 +120,10 @@ def _get_message(self) -> str: return self._prompt_commit_questions() def __call__(self) -> None: - extra_args = cast(str, self.arguments.get("extra_cli_args", "")) - dry_run = cast(bool, self.arguments.get("dry_run")) - write_message_to_file = cast( - Union[Path, None], self.arguments.get("write_message_to_file") - ) - signoff = cast(bool, self.arguments.get("signoff")) + extra_args = self.arguments.get("extra_cli_args", "") + dry_run = bool(self.arguments.get("dry_run")) + write_message_to_file = self.arguments.get("write_message_to_file") + signoff = bool(self.arguments.get("signoff")) if self.arguments.get("all"): git.add("-u") From c60a3b877336c119cbece2e923a1cacfc4dcb974 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:30:59 +0800 Subject: [PATCH 564/598] refactor(commands): remove unused args, type version command args --- commitizen/commands/version.py | 13 +++++++++---- tests/commands/test_version_command.py | 1 - 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/commitizen/commands/version.py b/commitizen/commands/version.py index ecf1f03129..6b0aa331ad 100644 --- a/commitizen/commands/version.py +++ b/commitizen/commands/version.py @@ -1,7 +1,6 @@ import platform import sys -from collections.abc import Mapping -from typing import Any +from typing import TypedDict from commitizen import out from commitizen.__version__ import __version__ @@ -9,12 +8,18 @@ from commitizen.providers import get_provider +class VersionArgs(TypedDict, total=False): + report: bool + project: bool + verbose: bool + + class Version: """Get the version of the installed commitizen or the current project.""" - def __init__(self, config: BaseConfig, *args: Mapping[str, Any]) -> None: + def __init__(self, config: BaseConfig, arguments: VersionArgs) -> None: self.config: BaseConfig = config - self.parameter = args[0] + self.parameter = arguments self.operating_system = platform.system() self.python_version = sys.version diff --git a/tests/commands/test_version_command.py b/tests/commands/test_version_command.py index 927cf55f25..3dcbed168b 100644 --- a/tests/commands/test_version_command.py +++ b/tests/commands/test_version_command.py @@ -97,7 +97,6 @@ def test_version_use_version_provider( { "report": False, "project": project, - "commitizen": False, "verbose": not project, }, )() From 289198e938d28348d21dc4b52d0d93ab3e20ba40 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:38:22 +0800 Subject: [PATCH 565/598] style(cli): shorten arg type --- commitizen/cli.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index e1bd57b523..b5c03527d3 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -3,7 +3,6 @@ import argparse import logging import sys -from collections.abc import Sequence from copy import deepcopy from functools import partial from pathlib import Path @@ -48,7 +47,7 @@ def __call__( self, parser: argparse.ArgumentParser, namespace: argparse.Namespace, - kwarg: str | Sequence[object] | None, + kwarg: object, option_string: str | None = None, ) -> None: if not isinstance(kwarg, str): From e9758e1dad46f514901851d68d624c3d73e50523 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:41:39 +0800 Subject: [PATCH 566/598] docs(bump): comment on a stupid looking pattern --- commitizen/commands/bump.py | 1 + 1 file changed, 1 insertion(+) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 4bad83f5d6..fa49d37d5e 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -79,6 +79,7 @@ def __init__(self, config: BaseConfig, arguments: BumpArgs) -> None: **{ k: v for k, v in { + # All these are for making mypy happy "annotated_tag_message": arguments.get("annotated_tag_message"), "annotated_tag": arguments.get("annotated_tag"), "bump_message": arguments.get("bump_message"), From b04ebdf70b2c9e04f69a9b36f893db12532c231d Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:50:37 +0800 Subject: [PATCH 567/598] fix(Check): make parameters backward compatiable --- commitizen/commands/check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index ba0beeeb4e..8a7d0dd019 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -26,7 +26,7 @@ class CheckArgs(TypedDict, total=False): class Check: """Check if the current commit msg matches the commitizen format.""" - def __init__(self, config: BaseConfig, arguments: CheckArgs) -> None: + def __init__(self, config: BaseConfig, arguments: CheckArgs, *args: object) -> None: """Initial check command. Args: From b9a181cc70ab60c736a91cbf042a12cc9f12b30e Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:52:12 +0800 Subject: [PATCH 568/598] style(changelog): rename parameter for consistency --- commitizen/commands/changelog.py | 33 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 6d150b03f9..f0dd1c516c 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -47,13 +47,13 @@ class ChangelogArgs(TypedDict, total=False): class Changelog: """Generate a changelog based on the commit history.""" - def __init__(self, config: BaseConfig, args: ChangelogArgs) -> None: + def __init__(self, config: BaseConfig, arguments: ChangelogArgs) -> None: if not git.is_git_project(): raise NotAGitProjectError() self.config = config - changelog_file_name = args.get("file_name") or self.config.settings.get( + changelog_file_name = arguments.get("file_name") or self.config.settings.get( "changelog_file" ) if not isinstance(changelog_file_name, str): @@ -71,27 +71,30 @@ def __init__(self, config: BaseConfig, args: ChangelogArgs) -> None: self.encoding = self.config.settings["encoding"] self.cz = factory.committer_factory(self.config) - self.start_rev = args.get("start_rev") or self.config.settings.get( + self.start_rev = arguments.get("start_rev") or self.config.settings.get( "changelog_start_rev" ) self.changelog_format = get_changelog_format(self.config, self.file_name) self.incremental = bool( - args.get("incremental") or self.config.settings.get("changelog_incremental") + arguments.get("incremental") + or self.config.settings.get("changelog_incremental") ) - self.dry_run = bool(args.get("dry_run")) + self.dry_run = bool(arguments.get("dry_run")) self.scheme = get_version_scheme( - self.config.settings, args.get("version_scheme") + self.config.settings, arguments.get("version_scheme") ) current_version = ( - args.get("current_version") or self.config.settings.get("version") or "" + arguments.get("current_version") + or self.config.settings.get("version") + or "" ) self.current_version = self.scheme(current_version) if current_version else None - self.unreleased_version = args["unreleased_version"] + self.unreleased_version = arguments["unreleased_version"] self.change_type_map = ( self.config.settings.get("change_type_map") or self.cz.change_type_map ) @@ -101,24 +104,26 @@ def __init__(self, config: BaseConfig, args: ChangelogArgs) -> None: or self.cz.change_type_order or defaults.CHANGE_TYPE_ORDER, ) - self.rev_range = args.get("rev_range") - self.tag_format = args.get("tag_format") or self.config.settings["tag_format"] + self.rev_range = arguments.get("rev_range") + self.tag_format = ( + arguments.get("tag_format") or self.config.settings["tag_format"] + ) self.tag_rules = TagRules( scheme=self.scheme, tag_format=self.tag_format, legacy_tag_formats=self.config.settings["legacy_tag_formats"], ignored_tag_formats=self.config.settings["ignored_tag_formats"], - merge_prereleases=args.get("merge_prerelease") + merge_prereleases=arguments.get("merge_prerelease") or self.config.settings["changelog_merge_prerelease"], ) self.template = ( - args.get("template") + arguments.get("template") or self.config.settings.get("template") or self.changelog_format.template ) - self.extras = args.get("extras") or {} - self.export_template_to = args.get("export_template") + self.extras = arguments.get("extras") or {} + self.export_template_to = arguments.get("export_template") def _find_incremental_rev(self, latest_version: str, tags: Iterable[GitTag]) -> str: """Try to find the 'start_rev'. From 15a090069d0324f52a4ecf9b29719310ca942848 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 01:55:38 +0800 Subject: [PATCH 569/598] refactor(bump): improve readability and still bypass mypy check --- commitizen/commands/bump.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index fa49d37d5e..5edf59e9e8 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -78,22 +78,21 @@ def __init__(self, config: BaseConfig, arguments: BumpArgs) -> None: **config.settings, **{ k: v - for k, v in { - # All these are for making mypy happy - "annotated_tag_message": arguments.get("annotated_tag_message"), - "annotated_tag": arguments.get("annotated_tag"), - "bump_message": arguments.get("bump_message"), - "file_name": arguments.get("file_name"), - "gpg_sign": arguments.get("gpg_sign"), - "increment_mode": arguments.get("increment_mode"), - "increment": arguments.get("increment"), - "major_version_zero": arguments.get("major_version_zero"), - "prerelease_offset": arguments.get("prerelease_offset"), - "prerelease": arguments.get("prerelease"), - "tag_format": arguments.get("tag_format"), - "template": arguments.get("template"), - }.items() - if v is not None + for k in ( + "annotated_tag_message", + "annotated_tag", + "bump_message", + "file_name", + "gpg_sign", + "increment_mode", + "increment", + "major_version_zero", + "prerelease_offset", + "prerelease", + "tag_format", + "template", + ) + if (v := arguments.get(k)) is not None }, }, ) From 48f06e313724438794a3027262aa921deb1715f3 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 1 Jun 2025 02:05:23 +0800 Subject: [PATCH 570/598] refactor: remove unnecessary bool() and remove Any type from TypedDict get --- commitizen/commands/bump.py | 8 ++------ commitizen/defaults.py | 4 +++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 5edf59e9e8..9f8bc08244 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -40,7 +40,6 @@ class BumpArgs(Settings, total=False): allow_no_commit: bool | None annotated_tag_message: str | None - annotated_tag: bool build_metadata: str | None changelog_to_stdout: bool changelog: bool @@ -51,7 +50,6 @@ class BumpArgs(Settings, total=False): files_only: bool | None get_next: bool git_output_to_stderr: bool - gpg_sign: bool increment_mode: str increment: Increment | None local_version: bool @@ -222,7 +220,7 @@ def __call__(self) -> None: if get_next: # if trying to use --get-next, we should not allow --changelog or --changelog-to-stdout - if self.changelog_flag or bool(self.changelog_to_stdout): + if self.changelog_flag or self.changelog_to_stdout: raise NotAllowed( "--changelog or --changelog-to-stdout is not allowed with --get-next" ) @@ -234,9 +232,7 @@ def __call__(self) -> None: # If user specified changelog_to_stdout, they probably want the # changelog to be generated as well, this is the most intuitive solution self.changelog_flag = bool( - self.changelog_flag - or bool(self.changelog_to_stdout) - or self.changelog_config + self.changelog_flag or self.changelog_to_stdout or self.changelog_config ) rules = TagRules.from_settings(cast(Settings, self.bump_settings)) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 29c9f2a494..7a51389b7a 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -32,16 +32,18 @@ class Settings(TypedDict, total=False): allow_abort: bool allowed_prefixes: list[str] always_signoff: bool + annotated_tag: bool bump_message: str | None + change_type_map: dict[str, str] changelog_file: str changelog_format: str | None changelog_incremental: bool changelog_merge_prerelease: bool - change_type_map: dict[str, str] changelog_start_rev: str | None customize: CzSettings encoding: str extras: dict[str, Any] + gpg_sign: bool ignored_tag_formats: Sequence[str] legacy_tag_formats: Sequence[str] major_version_zero: bool From 8e9d40fbc8842651674257b7bb3c42969ae53418 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 4 Jun 2025 23:24:59 +0800 Subject: [PATCH 571/598] style(changelog): add TODO to fixable type ignores --- commitizen/commands/changelog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index f0dd1c516c..8ca36bdb9a 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -176,6 +176,7 @@ def _write_changelog( def _export_template(self) -> None: tpl = changelog.get_changelog_template(self.cz.template_loader, self.template) + # TODO: fix the following type ignores src = Path(tpl.filename) # type: ignore Path(self.export_template_to).write_text(src.read_text()) # type: ignore From c49a55c27bc09ba5f18ff2fe056d387233e52018 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 4 Jun 2025 23:26:37 +0800 Subject: [PATCH 572/598] style(cli): more specific type ignore --- commitizen/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index b5c03527d3..c13f713a27 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -679,7 +679,7 @@ def main() -> None: ) sys.excepthook = no_raise_debug_excepthook - args.func(conf, arguments)() # type: ignore + args.func(conf, arguments)() # type: ignore[arg-type] if __name__ == "__main__": From 150b35dc8e2aad836077887a0086a5c5f5f4fbe8 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 4 Jun 2025 23:35:19 +0800 Subject: [PATCH 573/598] style(cli): rename kwarg to values --- commitizen/cli.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index c13f713a27..12db01711c 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -47,17 +47,17 @@ def __call__( self, parser: argparse.ArgumentParser, namespace: argparse.Namespace, - kwarg: object, + values: object, option_string: str | None = None, ) -> None: - if not isinstance(kwarg, str): + if not isinstance(values, str): return - if "=" not in kwarg: + if "=" not in values: raise InvalidCommandArgumentError( f"Option {option_string} expect a key=value format" ) kwargs = getattr(namespace, self.dest, None) or {} - key, value = kwarg.split("=", 1) + key, value = values.split("=", 1) if not key: raise InvalidCommandArgumentError( f"Option {option_string} expect a key=value format" From 773575598eac2ab520e698935ded1896f14da137 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 6 Jun 2025 11:24:46 +0800 Subject: [PATCH 574/598] refactor(bump): use any to replace 'or' chain --- commitizen/commands/bump.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 9f8bc08244..a4024eee35 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -231,8 +231,8 @@ def __call__(self) -> None: else: # If user specified changelog_to_stdout, they probably want the # changelog to be generated as well, this is the most intuitive solution - self.changelog_flag = bool( - self.changelog_flag or self.changelog_to_stdout or self.changelog_config + self.changelog_flag = any( + (self.changelog_flag, self.changelog_to_stdout, self.changelog_config) ) rules = TagRules.from_settings(cast(Settings, self.bump_settings)) @@ -410,14 +410,18 @@ def __call__(self) -> None: c = git.tag( new_tag_version, - signed=bool( - self.bump_settings.get("gpg_sign") - or self.config.settings.get("gpg_sign") + signed=any( + ( + self.bump_settings.get("gpg_sign"), + self.config.settings.get("gpg_sign"), + ) ), - annotated=bool( - self.bump_settings.get("annotated_tag") - or self.config.settings.get("annotated_tag") - or self.bump_settings.get("annotated_tag_message") + annotated=any( + ( + self.bump_settings.get("annotated_tag"), + self.config.settings.get("annotated_tag"), + self.bump_settings.get("annotated_tag_message"), + ) ), msg=self.bump_settings.get("annotated_tag_message", None), # TODO: also get from self.config.settings? From 2966cf938b17a37537949e4ee2bbee99919f8999 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 6 Jun 2025 00:46:21 +0800 Subject: [PATCH 575/598] perf(bump): avoid unnecessary list construction and rename variable to avoid confusion --- commitizen/bump.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/commitizen/bump.py b/commitizen/bump.py index 2fa814f7c8..6d6b6dc069 100644 --- a/commitizen/bump.py +++ b/commitizen/bump.py @@ -3,6 +3,7 @@ import os import re from collections import OrderedDict +from collections.abc import Iterable from glob import iglob from logging import getLogger from string import Template @@ -61,7 +62,7 @@ def find_increment( def update_version_in_files( current_version: str, new_version: str, - files: list[str], + files: Iterable[str], *, check_consistency: bool = False, encoding: str = ENCODING, @@ -99,11 +100,11 @@ def update_version_in_files( return updated -def _files_and_regexes(patterns: list[str], version: str) -> list[tuple[str, str]]: +def _files_and_regexes(patterns: Iterable[str], version: str) -> list[tuple[str, str]]: """ Resolve all distinct files with their regexp from a list of glob patterns with optional regexp """ - out: list[tuple[str, str]] = [] + out: set[tuple[str, str]] = set() for pattern in patterns: drive, tail = os.path.splitdrive(pattern) path, _, regex = tail.partition(":") @@ -111,9 +112,10 @@ def _files_and_regexes(patterns: list[str], version: str) -> list[tuple[str, str if not regex: regex = re.escape(version) - for path in iglob(filepath): - out.append((path, regex)) - return sorted(list(set(out))) + for file in iglob(filepath): + out.add((file, regex)) + + return sorted(out) def _bump_with_regex( From 303d2ebc356f8753a1d7ebbffd68d51d924971a9 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 7 Jun 2025 23:29:10 +0800 Subject: [PATCH 576/598] refactor(bump): eliminate similar patterns in code --- commitizen/commands/bump.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index a4024eee35..7fe01393a2 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -397,16 +397,10 @@ def __call__(self) -> None: err = c.err.strip() or c.out raise BumpCommitFailedError(f'2nd git.commit error: "{err}"') - if c.out: - if self.git_output_to_stderr: - out.diagnostic(c.out) - else: - out.write(c.out) - if c.err: - if self.git_output_to_stderr: - out.diagnostic(c.err) - else: - out.write(c.err) + for msg in (c.out, c.err): + if msg: + out_func = out.diagnostic if self.git_output_to_stderr else out.write + out_func(msg) c = git.tag( new_tag_version, From af50d8572b611667690110bd540b10afafd4684a Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 6 Jun 2025 02:03:32 +0800 Subject: [PATCH 577/598] refactor(git): simplify tag logic --- commitizen/git.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/commitizen/git.py b/commitizen/git.py index fb59750eaf..0f5f820eb2 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -160,16 +160,14 @@ def from_line(cls, line: str, inner_delimiter: str) -> GitTag: def tag( tag: str, annotated: bool = False, signed: bool = False, msg: str | None = None ) -> cmd.Command: - _opt = "" - if annotated: - _opt = f"-a {tag} -m" - if signed: - _opt = f"-s {tag} -m" + if not annotated and not signed: + return cmd.run(f"git tag {tag}") # according to https://git-scm.com/book/en/v2/Git-Basics-Tagging, # we're not able to create lightweight tag with message. # by adding message, we make it a annotated tags - return cmd.run(f'git tag {_opt} "{tag if _opt == "" or msg is None else msg}"') + option = "-s" if signed else "-a" # The else case is for annotated tags + return cmd.run(f'git tag {option} {tag} -m "{msg or tag}"') def add(*args: str) -> cmd.Command: From 654f4a03b34c094b5b718f3b2a66f0905689c15c Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 6 Jun 2025 01:50:14 +0800 Subject: [PATCH 578/598] refactor(git): retype get_commits parameter to make it more friendly to call sites --- commitizen/commands/bump.py | 5 +---- commitizen/commands/check.py | 2 +- commitizen/git.py | 7 +++++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 7fe01393a2..ec4cb0b0b6 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -253,10 +253,7 @@ def __call__(self) -> None: ) from exc else: if increment is None: - if current_tag: - commits = git.get_commits(current_tag.name) - else: - commits = git.get_commits() + commits = git.get_commits(current_tag.name if current_tag else None) # No commits, there is no need to create an empty tag. # Unless we previously had a prerelease. diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index 8a7d0dd019..ba003cf3cc 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -110,7 +110,7 @@ def _get_commits(self) -> list[git.GitCommit]: return [git.GitCommit(rev="", title="", body=self._filter_comments(msg))] # Get commit messages from git log (--rev-range) - return git.get_commits(end=self.rev_range or "HEAD") + return git.get_commits(end=self.rev_range) @staticmethod def _filter_comments(msg: str) -> str: diff --git a/commitizen/git.py b/commitizen/git.py index 0f5f820eb2..8025041abb 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -201,15 +201,18 @@ def _create_commit_cmd_string(args: str, committer_date: str | None, name: str) def get_commits( start: str | None = None, - end: str = "HEAD", + end: str | None = None, *, args: str = "", ) -> list[GitCommit]: """Get the commits between start and end.""" + if end is None: + end = "HEAD" git_log_entries = _get_log_as_str_list(start, end, args) return [ GitCommit.from_rev_and_commit(rev_and_commit) - for rev_and_commit in filter(None, git_log_entries) + for rev_and_commit in git_log_entries + if rev_and_commit ] From 6abbc530b02e3d6d5c3def020b18fd771ed111c3 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 6 Jun 2025 01:33:04 +0800 Subject: [PATCH 579/598] refactor(bump): simplify nested if --- commitizen/commands/bump.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index ec4cb0b0b6..ba252fcf21 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -206,17 +206,13 @@ def __call__(self) -> None: if get_next: raise NotAllowed("--get-next cannot be combined with MANUAL_VERSION") - if self.bump_settings["major_version_zero"]: - if not current_version.release[0] == 0: - raise NotAllowed( - f"--major-version-zero is meaningless for current version {current_version}" - ) + if self.bump_settings["major_version_zero"] and current_version.release[0]: + raise NotAllowed( + f"--major-version-zero is meaningless for current version {current_version}" + ) - if build_metadata: - if is_local_version: - raise NotAllowed( - "--local-version cannot be combined with --build-metadata" - ) + if build_metadata and is_local_version: + raise NotAllowed("--local-version cannot be combined with --build-metadata") if get_next: # if trying to use --get-next, we should not allow --changelog or --changelog-to-stdout From f4fe43c363bf7d37e02e8fb633e197e3eab85f1e Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 2 Jun 2025 00:11:57 +0800 Subject: [PATCH 580/598] fix(commit): emit deprecated warning of cz commit -s --- commitizen/commands/commit.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index 43feb272ba..bb4c2fdc94 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -125,6 +125,11 @@ def __call__(self) -> None: write_message_to_file = self.arguments.get("write_message_to_file") signoff = bool(self.arguments.get("signoff")) + if signoff: + out.warn( + "Deprecated warning: `cz commit -s` is deprecated and will be removed in v5, please use `cz commit -- -s` instead." + ) + if self.arguments.get("all"): git.add("-u") @@ -147,11 +152,6 @@ def __call__(self) -> None: if dry_run: raise DryRunExit() - if signoff: - out.warn( - "signoff mechanic is deprecated, please use `cz commit -- -s` instead." - ) - if self.config.settings["always_signoff"] or signoff: extra_args = f"{extra_args} -s".strip() From a9c4e0a87eb3004cb02181d536fcb9d117aff2d6 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 2 Jun 2025 00:26:32 +0800 Subject: [PATCH 581/598] fix(cli): update description for deprecate warning Closes #1135 --- commitizen/cli.py | 4 ++-- ...st_bump_command_shows_description_when_use_help_option.txt | 2 +- ..._commit_command_shows_description_when_use_help_option.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index 12db01711c..6f7556df49 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -147,7 +147,7 @@ def __call__( { "name": ["-s", "--signoff"], "action": "store_true", - "help": "sign off the commit", + "help": "Deprecated, use 'cz commit -- -s' instead", }, { "name": ["-a", "--all"], @@ -347,7 +347,7 @@ def __call__( }, { "name": ["--version-type"], - "help": "Deprecated, use --version-scheme", + "help": "Deprecated, use --version-scheme instead", "default": None, "choices": version_schemes.KNOWN_SCHEMES, }, diff --git a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt index 5d4438875d..4cf8e6c91b 100644 --- a/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_bump_command/test_bump_command_shows_description_when_use_help_option.txt @@ -74,7 +74,7 @@ options: --version-scheme {pep440,semver,semver2} choose version scheme --version-type {pep440,semver,semver2} - Deprecated, use --version-scheme + Deprecated, use --version-scheme instead --build-metadata BUILD_METADATA Add additional build-metadata to the version-number --get-next Determine the next version and write to stdout diff --git a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt index dd1f53f3da..ba531042aa 100644 --- a/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt +++ b/tests/commands/test_commit_command/test_commit_command_shows_description_when_use_help_option.txt @@ -12,7 +12,7 @@ options: --write-message-to-file FILE_PATH write message to file before committing (can be combined with --dry-run) - -s, --signoff sign off the commit + -s, --signoff Deprecated, use 'cz commit -- -s' instead -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. From fa5f3c8062bfde36fa3bdb79d9e06c5a3dfe7dd6 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sat, 31 May 2025 23:30:27 +0800 Subject: [PATCH 582/598] refactor(questions): type questions with TypedDict --- commitizen/commands/commit.py | 2 +- commitizen/cz/base.py | 4 +-- .../conventional_commits.py | 6 ++-- commitizen/cz/customize/customize.py | 7 ++-- commitizen/cz/jira/jira.py | 4 +-- commitizen/defaults.py | 6 ++-- commitizen/question.py | 32 +++++++++++++++++++ tests/conftest.py | 3 +- 8 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 commitizen/question.py diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index bb4c2fdc94..19bb72fb00 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -66,7 +66,7 @@ def _prompt_commit_questions(self) -> str: # Prompt user for the commit message cz = self.cz questions = cz.questions() - for question in filter(lambda q: q["type"] == "list", questions): + for question in (q for q in questions if q["type"] == "list"): question["use_shortcuts"] = self.config.settings["use_shortcuts"] try: answers = questionary.prompt(questions, style=cz.style) diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 9e803c3d01..a30540cae6 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -9,7 +9,7 @@ from commitizen import git from commitizen.config.base_config import BaseConfig -from commitizen.defaults import Questions +from commitizen.question import CzQuestion class MessageBuilderHook(Protocol): @@ -68,7 +68,7 @@ def __init__(self, config: BaseConfig) -> None: self.config.settings.update({"style": BaseCommitizen.default_style_config}) @abstractmethod - def questions(self) -> Questions: + def questions(self) -> Iterable[CzQuestion]: """Questions regarding the commit message.""" @abstractmethod diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 912770a726..ca4809a90e 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -3,7 +3,7 @@ from commitizen import defaults from commitizen.cz.base import BaseCommitizen from commitizen.cz.utils import multiple_line_breaker, required_validator -from commitizen.defaults import Questions +from commitizen.question import CzQuestion __all__ = ["ConventionalCommitsCz"] @@ -29,7 +29,7 @@ class ConventionalCommitsCz(BaseCommitizen): } changelog_pattern = defaults.BUMP_PATTERN - def questions(self) -> Questions: + def questions(self) -> list[CzQuestion]: return [ { "type": "list", @@ -122,8 +122,8 @@ def questions(self) -> Questions: }, { "type": "confirm", - "message": "Is this a BREAKING CHANGE? Correlates with MAJOR in SemVer", "name": "is_breaking_change", + "message": "Is this a BREAKING CHANGE? Correlates with MAJOR in SemVer", "default": False, }, { diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index 8f844501ec..6581ad444e 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -2,6 +2,8 @@ from typing import TYPE_CHECKING +from commitizen.question import CzQuestion + if TYPE_CHECKING: from jinja2 import Template else: @@ -14,7 +16,6 @@ from commitizen import defaults from commitizen.config import BaseConfig from commitizen.cz.base import BaseCommitizen -from commitizen.defaults import Questions from commitizen.exceptions import MissingCzCustomizeConfigError __all__ = ["CustomizeCommitsCz"] @@ -45,8 +46,8 @@ def __init__(self, config: BaseConfig) -> None: if value := self.custom_settings.get(attr_name): setattr(self, attr_name, value) - def questions(self) -> Questions: - return self.custom_settings.get("questions", [{}]) + def questions(self) -> list[CzQuestion]: + return self.custom_settings.get("questions", [{}]) # type: ignore def message(self, answers: dict) -> str: message_template = Template(self.custom_settings.get("message_template", "")) diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index 05e23e1690..eafded615e 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -1,13 +1,13 @@ import os from commitizen.cz.base import BaseCommitizen -from commitizen.defaults import Questions +from commitizen.question import CzQuestion __all__ = ["JiraSmartCz"] class JiraSmartCz(BaseCommitizen): - def questions(self) -> Questions: + def questions(self) -> list[CzQuestion]: return [ { "type": "input", diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 7a51389b7a..a49d6d9428 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -6,8 +6,10 @@ from collections.abc import Iterable, MutableMapping, Sequence from typing import Any, TypedDict +from commitizen.question import CzQuestion + # Type -Questions = Iterable[MutableMapping[str, Any]] +Questions = Iterable[MutableMapping[str, Any]] # TODO: deprecate this? class CzSettings(TypedDict, total=False): @@ -16,7 +18,7 @@ class CzSettings(TypedDict, total=False): bump_map_major_version_zero: OrderedDict[str, str] change_type_order: list[str] - questions: Questions + questions: Iterable[CzQuestion] example: str | None schema_pattern: str | None schema: str | None diff --git a/commitizen/question.py b/commitizen/question.py new file mode 100644 index 0000000000..393e386092 --- /dev/null +++ b/commitizen/question.py @@ -0,0 +1,32 @@ +from typing import Callable, Literal, TypedDict, Union + + +class Choice(TypedDict, total=False): + value: str + name: str + key: str + + +class ListQuestion(TypedDict, total=False): + type: Literal["list"] + name: str + message: str + choices: list[Choice] + use_shortcuts: bool + + +class InputQuestion(TypedDict, total=False): + type: Literal["input"] + name: str + message: str + filter: Callable[[str], str] + + +class ConfirmQuestion(TypedDict): + type: Literal["confirm"] + name: str + message: str + default: bool + + +CzQuestion = Union[ListQuestion, InputQuestion, ConfirmQuestion] diff --git a/tests/conftest.py b/tests/conftest.py index 1b49dcbfaa..a4815b3d5a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,6 +17,7 @@ from commitizen.config import BaseConfig from commitizen.cz import registry from commitizen.cz.base import BaseCommitizen +from commitizen.question import CzQuestion from tests.utils import create_file_and_commit SIGNER = "GitHub Action" @@ -222,7 +223,7 @@ def use_cz_semver(mocker): class MockPlugin(BaseCommitizen): - def questions(self) -> defaults.Questions: + def questions(self) -> list[CzQuestion]: return [] def message(self, answers: dict) -> str: From 547836617d8fbae1197a7e7306f554c4446dea35 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 12:31:14 +0800 Subject: [PATCH 583/598] refactor(check): compile once and rename variable --- commitizen/commands/check.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/commitizen/commands/check.py b/commitizen/commands/check.py index ba003cf3cc..69147bcfbe 100644 --- a/commitizen/commands/check.py +++ b/commitizen/commands/check.py @@ -79,20 +79,19 @@ def __call__(self) -> None: if not commits: raise NoCommitsFoundError(f"No commit found with range: '{self.rev_range}'") - pattern = self.cz.schema_pattern() - displayed_msgs_content = "\n".join( - [ - f'commit "{commit.rev}": "{commit.message}"' - for commit in commits - if not self.validate_commit_message(commit.message, pattern) - ] + pattern = re.compile(self.cz.schema_pattern()) + invalid_msgs_content = "\n".join( + f'commit "{commit.rev}": "{commit.message}"' + for commit in commits + if not self._validate_commit_message(commit.message, pattern) ) - if displayed_msgs_content: + if invalid_msgs_content: + # TODO: capitalize the first letter of the error message for consistency in v5 raise InvalidCommitMessageError( "commit validation: failed!\n" "please enter a commit message in the commitizen format.\n" - f"{displayed_msgs_content}\n" - f"pattern: {pattern}" + f"{invalid_msgs_content}\n" + f"pattern: {pattern.pattern}" ) out.success("Commit validation: successful!") @@ -143,14 +142,18 @@ def _filter_comments(msg: str) -> str: lines.append(line) return "\n".join(lines) - def validate_commit_message(self, commit_msg: str, pattern: str) -> bool: + def _validate_commit_message( + self, commit_msg: str, pattern: re.Pattern[str] + ) -> bool: if not commit_msg: return self.allow_abort if any(map(commit_msg.startswith, self.allowed_prefixes)): return True + if self.max_msg_length: msg_len = len(commit_msg.partition("\n")[0].strip()) if msg_len > self.max_msg_length: return False - return bool(re.match(pattern, commit_msg)) + + return bool(pattern.match(commit_msg)) From 7fc35151829335d09a9428e306ad18a161810a91 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 21:10:05 +0800 Subject: [PATCH 584/598] refactor: do not guess if changelog format is provided --- commitizen/changelog_formats/__init__.py | 17 +++++++++++------ commitizen/factory.py | 4 +--- tests/test_changelog_formats.py | 8 ++++---- tests/{test_defaults.py => test_deprecated.py} | 6 +++++- 4 files changed, 21 insertions(+), 14 deletions(-) rename tests/{test_defaults.py => test_deprecated.py} (84%) diff --git a/commitizen/changelog_formats/__init__.py b/commitizen/changelog_formats/__init__.py index b7b3cac01d..9a5eea7ab2 100644 --- a/commitizen/changelog_formats/__init__.py +++ b/commitizen/changelog_formats/__init__.py @@ -1,7 +1,7 @@ from __future__ import annotations import sys -from typing import ClassVar, Protocol +from typing import Callable, ClassVar, Protocol if sys.version_info >= (3, 10): from importlib import metadata @@ -64,10 +64,9 @@ def get_changelog_format( :raises FormatUnknown: if a non-empty name is provided but cannot be found in the known formats """ name: str | None = config.settings.get("changelog_format") - format: type[ChangelogFormat] | None = guess_changelog_format(filename) - - if name and name in KNOWN_CHANGELOG_FORMATS: - format = KNOWN_CHANGELOG_FORMATS[name] + format = ( + name and KNOWN_CHANGELOG_FORMATS.get(name) or _guess_changelog_format(filename) + ) if not format: raise ChangelogFormatUnknown(f"Unknown changelog format '{name}'") @@ -75,7 +74,7 @@ def get_changelog_format( return format(config) -def guess_changelog_format(filename: str | None) -> type[ChangelogFormat] | None: +def _guess_changelog_format(filename: str | None) -> type[ChangelogFormat] | None: """ Try guessing the file format from the filename. @@ -91,3 +90,9 @@ def guess_changelog_format(filename: str | None) -> type[ChangelogFormat] | None if filename.endswith(f".{alt_extension}"): return format return None + + +def __getattr__(name: str) -> Callable[[str], type[ChangelogFormat] | None]: + if name == "guess_changelog_format": + return _guess_changelog_format + raise AttributeError(f"module {__name__} has no attribute {name}") diff --git a/commitizen/factory.py b/commitizen/factory.py index b5d665b65e..d9e99fb771 100644 --- a/commitizen/factory.py +++ b/commitizen/factory.py @@ -8,12 +8,10 @@ def committer_factory(config: BaseConfig) -> BaseCommitizen: """Return the correct commitizen existing in the registry.""" name: str = config.settings["name"] try: - _cz = registry[name](config) + return registry[name](config) except KeyError: msg_error = ( "The committer has not been found in the system.\n\n" f"Try running 'pip install {name}'\n" ) raise NoCommitizenFoundException(msg_error) - else: - return _cz diff --git a/tests/test_changelog_formats.py b/tests/test_changelog_formats.py index dec23720dc..e0d99e0325 100644 --- a/tests/test_changelog_formats.py +++ b/tests/test_changelog_formats.py @@ -6,8 +6,8 @@ from commitizen.changelog_formats import ( KNOWN_CHANGELOG_FORMATS, ChangelogFormat, + _guess_changelog_format, get_changelog_format, - guess_changelog_format, ) from commitizen.config.base_config import BaseConfig from commitizen.exceptions import ChangelogFormatUnknown @@ -15,14 +15,14 @@ @pytest.mark.parametrize("format", KNOWN_CHANGELOG_FORMATS.values()) def test_guess_format(format: type[ChangelogFormat]): - assert guess_changelog_format(f"CHANGELOG.{format.extension}") is format + assert _guess_changelog_format(f"CHANGELOG.{format.extension}") is format for ext in format.alternative_extensions: - assert guess_changelog_format(f"CHANGELOG.{ext}") is format + assert _guess_changelog_format(f"CHANGELOG.{ext}") is format @pytest.mark.parametrize("filename", ("CHANGELOG", "NEWS", "file.unknown", None)) def test_guess_format_unknown(filename: str): - assert guess_changelog_format(filename) is None + assert _guess_changelog_format(filename) is None @pytest.mark.parametrize( diff --git a/tests/test_defaults.py b/tests/test_deprecated.py similarity index 84% rename from tests/test_defaults.py rename to tests/test_deprecated.py index 73cd35b80c..41bea81a73 100644 --- a/tests/test_defaults.py +++ b/tests/test_deprecated.py @@ -1,6 +1,6 @@ import pytest -from commitizen import defaults +from commitizen import changelog_formats, defaults def test_getattr_deprecated_vars(): @@ -15,6 +15,10 @@ def test_getattr_deprecated_vars(): assert defaults.change_type_order == defaults.CHANGE_TYPE_ORDER assert defaults.encoding == defaults.ENCODING assert defaults.name == defaults.DEFAULT_SETTINGS["name"] + assert ( + changelog_formats._guess_changelog_format + == changelog_formats.guess_changelog_format + ) # Verify warning messages assert len(record) == 7 From 2d23942fe77e547bb0ecb65e883a9921e094eca9 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 12:37:11 +0800 Subject: [PATCH 585/598] refactor(conventional_commits): make schema_pattern more readable --- .../conventional_commits.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index ca4809a90e..8e6caac1f5 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -174,11 +174,27 @@ def schema(self) -> str: ) def schema_pattern(self) -> str: + change_types = ( + "build", + "bump", + "chore", + "ci", + "docs", + "feat", + "fix", + "perf", + "refactor", + "revert", + "style", + "test", + ) return ( r"(?s)" # To explicitly make . match new line - r"(build|ci|docs|feat|fix|perf|refactor|style|test|chore|revert|bump)" # type - r"(\(\S+\))?!?:" # scope - r"( [^\n\r]+)" # subject + r"(" + "|".join(change_types) + r")" # type + r"(\(\S+\))?" # scope + r"!?" + r": " + r"([^\n\r]+)" # subject r"((\n\n.*)|(\s*))?$" ) From 451e0fc50577d9081266b8bd0c36b82d903bc21d Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 21:46:10 +0800 Subject: [PATCH 586/598] refactor(conventional_commits): use TypedDict for answers --- .../cz/conventional_commits/conventional_commits.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 8e6caac1f5..6893423478 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -1,4 +1,5 @@ import os +from typing import TypedDict from commitizen import defaults from commitizen.cz.base import BaseCommitizen @@ -16,6 +17,15 @@ def _parse_subject(text: str) -> str: return required_validator(text.strip(".").strip(), msg="Subject is required.") +class ConventionalCommitsAnswers(TypedDict): + prefix: str + scope: str + subject: str + body: str + footer: str + is_breaking_change: bool + + class ConventionalCommitsCz(BaseCommitizen): bump_pattern = defaults.BUMP_PATTERN bump_map = defaults.BUMP_MAP @@ -136,7 +146,7 @@ def questions(self) -> list[CzQuestion]: }, ] - def message(self, answers: dict) -> str: + def message(self, answers: ConventionalCommitsAnswers) -> str: # type: ignore[override] prefix = answers["prefix"] scope = answers["scope"] subject = answers["subject"] From 18b9729640b7c311831475af7c91d0360de527d7 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 21:46:31 +0800 Subject: [PATCH 587/598] refactor(jira): refactor message --- commitizen/cz/jira/jira.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index eafded615e..8bf8c210b3 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -43,18 +43,11 @@ def questions(self) -> list[CzQuestion]: }, ] - def message(self, answers: dict) -> str: + def message(self, answers: dict[str, str]) -> str: return " ".join( - filter( - bool, - [ - answers["message"], - answers["issues"], - answers["workflow"], - answers["time"], - answers["comment"], - ], - ) + x + for k in ("message", "issues", "workflow", "time", "comment") + if (x := answers.get(k)) ) def example(self) -> str: From c1eea63240c1b24f39699f7001717bcc7cd80e93 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Fri, 30 May 2025 22:04:34 +0800 Subject: [PATCH 588/598] style: replace dict with Mapping --- commitizen/cz/base.py | 4 ++-- commitizen/cz/customize/customize.py | 5 +++-- commitizen/cz/jira/jira.py | 3 ++- tests/conftest.py | 6 +++--- tests/test_cz_base.py | 4 +++- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index a30540cae6..cdc1476694 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -1,7 +1,7 @@ from __future__ import annotations from abc import ABCMeta, abstractmethod -from collections.abc import Iterable +from collections.abc import Iterable, Mapping from typing import Any, Callable, Protocol from jinja2 import BaseLoader, PackageLoader @@ -72,7 +72,7 @@ def questions(self) -> Iterable[CzQuestion]: """Questions regarding the commit message.""" @abstractmethod - def message(self, answers: dict) -> str: + def message(self, answers: Mapping[str, Any]) -> str: """Format your git message.""" @property diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index 6581ad444e..d6e9f9a5c3 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any from commitizen.question import CzQuestion @@ -49,7 +50,7 @@ def __init__(self, config: BaseConfig) -> None: def questions(self) -> list[CzQuestion]: return self.custom_settings.get("questions", [{}]) # type: ignore - def message(self, answers: dict) -> str: + def message(self, answers: Mapping[str, Any]) -> str: message_template = Template(self.custom_settings.get("message_template", "")) if getattr(Template, "substitute", None): return message_template.substitute(**answers) # type: ignore diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index 8bf8c210b3..4e6024ff74 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -1,4 +1,5 @@ import os +from collections.abc import Mapping from commitizen.cz.base import BaseCommitizen from commitizen.question import CzQuestion @@ -43,7 +44,7 @@ def questions(self) -> list[CzQuestion]: }, ] - def message(self, answers: dict[str, str]) -> str: + def message(self, answers: Mapping[str, str]) -> str: return " ".join( x for k in ("message", "issues", "workflow", "time", "comment") diff --git a/tests/conftest.py b/tests/conftest.py index a4815b3d5a..324ef9bebb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,7 +3,7 @@ import os import re import tempfile -from collections.abc import Iterator +from collections.abc import Iterator, Mapping from pathlib import Path import pytest @@ -210,7 +210,7 @@ def questions(self) -> list: }, ] - def message(self, answers: dict) -> str: + def message(self, answers: Mapping) -> str: prefix = answers["prefix"] subject = answers.get("subject", "default message").trim() return f"{prefix}: {subject}" @@ -226,7 +226,7 @@ class MockPlugin(BaseCommitizen): def questions(self) -> list[CzQuestion]: return [] - def message(self, answers: dict) -> str: + def message(self, answers: Mapping) -> str: return "" diff --git a/tests/test_cz_base.py b/tests/test_cz_base.py index be93b4ca0f..0ee5a23fb8 100644 --- a/tests/test_cz_base.py +++ b/tests/test_cz_base.py @@ -1,3 +1,5 @@ +from collections.abc import Mapping + import pytest from commitizen.cz.base import BaseCommitizen @@ -7,7 +9,7 @@ class DummyCz(BaseCommitizen): def questions(self): return [{"type": "input", "name": "commit", "message": "Initial commit:\n"}] - def message(self, answers: dict): + def message(self, answers: Mapping): return answers["commit"] From 5df4b1651d58037d604fda1af7b3eca724dfc2c9 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 2 Jun 2025 13:33:19 +0800 Subject: [PATCH 589/598] ci(pyproject.toml): strict check for invalid commit messages --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ee0ecc9ced..58425a81ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -249,8 +249,8 @@ lint.sequence = [ { cmd = "mypy" }, ] -check-commit.help = "Check the commit message" -check-commit.cmd = "cz -nr 3 check --rev-range origin/master.." +check-commit.help = "Check the commit messages" +check-commit.cmd = "poetry run cz --no-raise 3 check --rev-range origin/master.." test.help = "Run the test suite" test.cmd = "pytest -n 3 --dist=loadfile" @@ -262,7 +262,7 @@ cover.help = "Run the test suite with coverage" cover.ref = "test --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen" all.help = "Run all tasks" -all.sequence = ["format", "lint", "cover", "check-commit"] +all.sequence = ["check-commit", "format", "lint", "cover"] "doc:screenshots".help = "Render documentation screenshots" "doc:screenshots".script = "scripts.gen_cli_help_screenshots:gen_cli_help_screenshots" @@ -274,7 +274,7 @@ doc.help = "Live documentation server" doc.cmd = "mkdocs serve" ci.help = "Run all tasks in CI" -ci.sequence = [{ cmd = "pre-commit run --all-files" }, "cover"] +ci.sequence = ["check-commit", { cmd = "pre-commit run --all-files" }, "cover"] ci.env = { SKIP = "no-commit-to-branch" } setup-pre-commit.help = "Install pre-commit hooks" From 188bc3faf96ea2f7eac34b5eee65bf9fcc2648c3 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 2 Jun 2025 14:30:22 +0800 Subject: [PATCH 590/598] docs(pyproject.toml): move check-commit before cover --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 58425a81ac..1de17464a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -262,7 +262,7 @@ cover.help = "Run the test suite with coverage" cover.ref = "test --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen" all.help = "Run all tasks" -all.sequence = ["check-commit", "format", "lint", "cover"] +all.sequence = ["format", "lint", "check-commit", "cover"] "doc:screenshots".help = "Render documentation screenshots" "doc:screenshots".script = "scripts.gen_cli_help_screenshots:gen_cli_help_screenshots" From 8675c289df0e5c37b2867bf16c7c2c41f7eef438 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Sun, 8 Jun 2025 23:10:04 +0800 Subject: [PATCH 591/598] build: add PGH003 and PGH004, add types-colorama --- commitizen/__init__.py | 2 +- commitizen/commands/bump.py | 4 ++-- commitizen/commands/changelog.py | 4 ++-- commitizen/config/base_config.py | 2 +- commitizen/config/toml_config.py | 6 +++--- commitizen/cz/customize/__init__.py | 2 +- commitizen/cz/customize/customize.py | 4 ++-- commitizen/providers/base_provider.py | 4 ++-- commitizen/providers/cargo_provider.py | 12 ++++++------ commitizen/providers/commitizen_provider.py | 2 +- commitizen/providers/poetry_provider.py | 4 ++-- commitizen/version_schemes.py | 4 ++-- poetry.lock | 14 +++++++++++++- pyproject.toml | 14 ++++++-------- tests/commands/test_bump_command.py | 2 +- 15 files changed, 45 insertions(+), 35 deletions(-) diff --git a/commitizen/__init__.py b/commitizen/__init__.py index f16def4441..6db9e6e7db 100644 --- a/commitizen/__init__.py +++ b/commitizen/__init__.py @@ -1,7 +1,7 @@ import logging import logging.config -from colorama import init # type: ignore +from colorama import init from commitizen.cz.base import BaseCommitizen diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index ba252fcf21..2a84483c94 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -331,14 +331,14 @@ def __call__(self) -> None: "dry_run": dry_run, } if self.changelog_to_stdout: - changelog_cmd = Changelog(self.config, {**args, "dry_run": True}) # type: ignore + changelog_cmd = Changelog(self.config, {**args, "dry_run": True}) # type: ignore[typeddict-item] try: changelog_cmd() except DryRunExit: pass args["file_name"] = self.file_name - changelog_cmd = Changelog(self.config, args) # type: ignore + changelog_cmd = Changelog(self.config, args) # type: ignore[arg-type] changelog_cmd() files.append(changelog_cmd.file_name) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 8ca36bdb9a..dc50eb3ad2 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -177,8 +177,8 @@ def _write_changelog( def _export_template(self) -> None: tpl = changelog.get_changelog_template(self.cz.template_loader, self.template) # TODO: fix the following type ignores - src = Path(tpl.filename) # type: ignore - Path(self.export_template_to).write_text(src.read_text()) # type: ignore + src = Path(tpl.filename) # type: ignore[arg-type] + Path(self.export_template_to).write_text(src.read_text()) # type: ignore[arg-type] def __call__(self) -> None: commit_parser = self.cz.commit_parser diff --git a/commitizen/config/base_config.py b/commitizen/config/base_config.py index 59c0d16a06..4b8f5f05fc 100644 --- a/commitizen/config/base_config.py +++ b/commitizen/config/base_config.py @@ -27,7 +27,7 @@ def settings(self) -> Settings: @property def path(self) -> Path: - return self._path # type: ignore + return self._path # type: ignore[return-value] @path.setter def path(self, path: str | Path) -> None: diff --git a/commitizen/config/toml_config.py b/commitizen/config/toml_config.py index 3571c9c882..2164d3f992 100644 --- a/commitizen/config/toml_config.py +++ b/commitizen/config/toml_config.py @@ -37,7 +37,7 @@ def init_empty_config_content(self) -> None: with open(self.path, "wb") as output_toml_file: if parser.get("tool") is None: parser["tool"] = table() - parser["tool"]["commitizen"] = table() # type: ignore + parser["tool"]["commitizen"] = table() # type: ignore[index] output_toml_file.write(parser.as_string().encode(self.encoding)) def set_key(self, key: str, value: Any) -> Self: @@ -49,7 +49,7 @@ def set_key(self, key: str, value: Any) -> Self: with open(self.path, "rb") as f: parser = parse(f.read()) - parser["tool"]["commitizen"][key] = value # type: ignore + parser["tool"]["commitizen"][key] = value # type: ignore[index] with open(self.path, "wb") as f: f.write(parser.as_string().encode(self.encoding)) return self @@ -68,6 +68,6 @@ def _parse_setting(self, data: bytes | str) -> None: raise InvalidConfigurationError(f"Failed to parse {self.path}: {e}") try: - self.settings.update(doc["tool"]["commitizen"]) # type: ignore + self.settings.update(doc["tool"]["commitizen"]) # type: ignore[index,typeddict-item] # TODO: fix this except exceptions.NonExistentKey: self.is_empty_config = True diff --git a/commitizen/cz/customize/__init__.py b/commitizen/cz/customize/__init__.py index c5af001a79..0aedb9337a 100644 --- a/commitizen/cz/customize/__init__.py +++ b/commitizen/cz/customize/__init__.py @@ -1 +1 @@ -from .customize import CustomizeCommitsCz # noqa +from .customize import CustomizeCommitsCz # noqa: F401 diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index d6e9f9a5c3..dde2685496 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -48,12 +48,12 @@ def __init__(self, config: BaseConfig) -> None: setattr(self, attr_name, value) def questions(self) -> list[CzQuestion]: - return self.custom_settings.get("questions", [{}]) # type: ignore + return self.custom_settings.get("questions", [{}]) # type: ignore[return-value] def message(self, answers: Mapping[str, Any]) -> str: message_template = Template(self.custom_settings.get("message_template", "")) if getattr(Template, "substitute", None): - return message_template.substitute(**answers) # type: ignore + return message_template.substitute(**answers) # type: ignore[attr-defined,no-any-return] # pragma: no cover # TODO: check if we can fix this return message_template.render(**answers) def example(self) -> str: diff --git a/commitizen/providers/base_provider.py b/commitizen/providers/base_provider.py index 27c3123416..c91bfdae20 100644 --- a/commitizen/providers/base_provider.py +++ b/commitizen/providers/base_provider.py @@ -86,7 +86,7 @@ def set_version(self, version: str) -> None: self.file.write_text(tomlkit.dumps(document)) def get(self, document: tomlkit.TOMLDocument) -> str: - return document["project"]["version"] # type: ignore + return document["project"]["version"] # type: ignore[index,return-value] def set(self, document: tomlkit.TOMLDocument, version: str) -> None: - document["project"]["version"] = version # type: ignore + document["project"]["version"] = version # type: ignore[index] diff --git a/commitizen/providers/cargo_provider.py b/commitizen/providers/cargo_provider.py index 87e45cd71c..d453a4aa5b 100644 --- a/commitizen/providers/cargo_provider.py +++ b/commitizen/providers/cargo_provider.py @@ -23,18 +23,18 @@ def lock_file(self) -> Path: def get(self, document: tomlkit.TOMLDocument) -> str: try: - return document["package"]["version"] # type: ignore + return document["package"]["version"] # type: ignore[index,return-value] except tomlkit.exceptions.NonExistentKey: ... - return document["workspace"]["package"]["version"] # type: ignore + return document["workspace"]["package"]["version"] # type: ignore[index,return-value] def set(self, document: tomlkit.TOMLDocument, version: str) -> None: try: - document["workspace"]["package"]["version"] = version # type: ignore + document["workspace"]["package"]["version"] = version # type: ignore[index] return except tomlkit.exceptions.NonExistentKey: ... - document["package"]["version"] = version # type: ignore + document["package"]["version"] = version # type: ignore[index] def set_version(self, version: str) -> None: super().set_version(version) @@ -44,9 +44,9 @@ def set_version(self, version: str) -> None: def set_lock_version(self, version: str) -> None: cargo_toml_content = tomlkit.parse(self.file.read_text()) try: - package_name = cargo_toml_content["package"]["name"] # type: ignore + package_name = cargo_toml_content["package"]["name"] # type: ignore[index] except tomlkit.exceptions.NonExistentKey: - package_name = cargo_toml_content["workspace"]["package"]["name"] # type: ignore + package_name = cargo_toml_content["workspace"]["package"]["name"] # type: ignore[index] cargo_lock_content = tomlkit.parse(self.lock_file.read_text()) packages: tomlkit.items.AoT = cargo_lock_content["package"] # type: ignore[assignment] diff --git a/commitizen/providers/commitizen_provider.py b/commitizen/providers/commitizen_provider.py index 7ce177a604..d9207b19ff 100644 --- a/commitizen/providers/commitizen_provider.py +++ b/commitizen/providers/commitizen_provider.py @@ -9,7 +9,7 @@ class CommitizenProvider(VersionProvider): """ def get_version(self) -> str: - return self.config.settings["version"] # type: ignore + return self.config.settings["version"] # type: ignore[return-value] # TODO: check if we can fix this by tweaking the `Settings` type def set_version(self, version: str) -> None: self.config.set_key("version", version) diff --git a/commitizen/providers/poetry_provider.py b/commitizen/providers/poetry_provider.py index 1dd33f053e..f63b13b793 100644 --- a/commitizen/providers/poetry_provider.py +++ b/commitizen/providers/poetry_provider.py @@ -13,7 +13,7 @@ class PoetryProvider(TomlProvider): filename = "pyproject.toml" def get(self, pyproject: tomlkit.TOMLDocument) -> str: - return pyproject["tool"]["poetry"]["version"] # type: ignore + return pyproject["tool"]["poetry"]["version"] # type: ignore[index,return-value] def set(self, pyproject: tomlkit.TOMLDocument, version: str) -> None: - pyproject["tool"]["poetry"]["version"] = version # type: ignore + pyproject["tool"]["poetry"]["version"] = version # type: ignore[index] diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index a59d3c0aa0..e9f99c5514 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -266,7 +266,7 @@ def bump( if self.local and is_local_version: local_version = self.scheme(self.local).bump(increment) - return self.scheme(f"{self.public}+{local_version}") # type: ignore + return self.scheme(f"{self.public}+{local_version}") # type: ignore[return-value] base = self._get_increment_base(increment, exact_increment) dev_version = self.generate_devrelease(devrelease) @@ -283,7 +283,7 @@ def bump( # TODO: post version return self.scheme( f"{base}{pre_version}{dev_version}{self.generate_build_metadata(build_metadata)}" - ) # type: ignore + ) # type: ignore[return-value] def _get_increment_base( self, increment: Increment | None, exact_increment: bool diff --git a/poetry.lock b/poetry.lock index f9f74513a8..c5c893931a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1746,6 +1746,18 @@ files = [ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] +[[package]] +name = "types-colorama" +version = "0.4.15.20240311" +description = "Typing stubs for colorama" +optional = false +python-versions = ">=3.8" +groups = ["linters"] +files = [ + {file = "types-colorama-0.4.15.20240311.tar.gz", hash = "sha256:a28e7f98d17d2b14fb9565d32388e419f4108f557a7d939a66319969b2b99c7a"}, + {file = "types_colorama-0.4.15.20240311-py3-none-any.whl", hash = "sha256:6391de60ddc0db3f147e31ecb230006a6823e81e380862ffca1e4695c13a0b8e"}, +] + [[package]] name = "types-deprecated" version = "1.2.15.20250304" @@ -2014,4 +2026,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "10e298e9b4d2f2d81a82b43649a68d557ed3e9824b3b210b5b6a607935f9fe9d" +content-hash = "f35cf57718e28836cf1e70b33edab9ce623b01a7f2d31d712585554721f6d403" diff --git a/pyproject.toml b/pyproject.toml index 1de17464a3..0d135954a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -126,6 +126,7 @@ types-deprecated = "^1.2.9.2" types-python-dateutil = "^2.8.19.13" types-PyYAML = ">=5.4.3,<7.0.0" types-termcolor = "^0.1.1" +types-colorama = "^0.4.15.20240311" [tool.poetry.group.documentation.dependencies] mkdocs = "^1.4.2" @@ -198,6 +199,9 @@ select = [ "UP", # isort "I", + # pygrep-hooks + "PGH003", + "PGH004", # unsorted-dunder-all "RUF022", # unused-noqa @@ -238,16 +242,10 @@ poetry_command = "" [tool.poe.tasks] format.help = "Format the code" -format.sequence = [ - { cmd = "ruff check --fix" }, - { cmd = "ruff format" }, -] +format.sequence = [{ cmd = "ruff check --fix" }, { cmd = "ruff format" }] lint.help = "Lint the code" -lint.sequence = [ - { cmd = "ruff check" }, - { cmd = "mypy" }, -] +lint.sequence = [{ cmd = "ruff check" }, { cmd = "mypy" }] check-commit.help = "Check the commit messages" check-commit.cmd = "poetry run cz --no-raise 3 check --rev-range origin/master.." diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 64b810e4de..59297b1726 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1721,7 +1721,7 @@ def test_is_initial_tag(mocker: MockFixture, tmp_commitizen_project): "extras": None, } - bump_cmd = bump.Bump(config, arguments) # type: ignore + bump_cmd = bump.Bump(config, arguments) # type: ignore[arg-type] # Test case 1: No current tag, not yes mode mocker.patch("questionary.confirm", return_value=mocker.Mock(ask=lambda: True)) From c710c9f541ae452547fdce5c360929f007ec4867 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:18:28 +0000 Subject: [PATCH 592/598] =?UTF-8?q?bump:=20version=204.8.2=20=E2=86=92=204?= =?UTF-8?q?.8.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 60 +++++++++++++++++++++++++++++++++++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 +-- 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e108eb9b9..9e09fb63e8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - tomli - repo: https://github.com/commitizen-tools/commitizen - rev: v4.8.2 # automatically updated by Commitizen + rev: v4.8.3 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b737a851a..76b6e36e94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,63 @@ +## v4.8.3 (2025-06-09) + +### Fix + +- **cli**: update description for deprecate warning +- **commit**: emit deprecated warning of cz commit -s +- **Check**: make parameters backward compatiable +- **BaseConfig**: mypy error +- **deprecated**: mark deprecate in v5 +- **defaults**: add non-capitalized default constants back and deprecated warning + +### Refactor + +- **jira**: refactor message +- **conventional_commits**: use TypedDict for answers +- **conventional_commits**: make schema_pattern more readable +- do not guess if changelog format is provided +- **check**: compile once and rename variable +- **questions**: type questions with TypedDict +- **bump**: simplify nested if +- **git**: retype get_commits parameter to make it more friendly to call sites +- **git**: simplify tag logic +- **bump**: eliminate similar patterns in code +- **bump**: use any to replace 'or' chain +- remove unnecessary bool() and remove Any type from TypedDict get +- **bump**: improve readability and still bypass mypy check +- **commands**: remove unused args, type version command args +- **commit**: type commit args +- **check**: type CheckArgs arguments +- **check**: remove unused argument +- **changelog**: type untyped arguments +- **bump**: TypedDict for bump argument +- make methods protected, better type +- **conventional_commits**: remove unnecessary checks +- fix mypy output and better type +- **BaseCommitizen**: remove unused process_commit +- remove `TypeError` handling since `Python >=3.9` is required +- add comment clarifying `no_raise` parsing to `list[int]` +- **cli.py**: add type hints +- **mypy**: remove `unused-ignore` +- **changelog**: better typing, yield +- **cli**: early return and improve test coverage +- **git**: extract _create_commit_cmd_string +- misc cleanup +- **bump**: clean up +- **bump**: add type for out, replace function with re escape +- **BaseConfig**: use setter +- **changelog**: minor cleanup +- **git**: refactor get_tag_names +- **EOLType**: add eol enum back and reorganize methods +- **git**: code cleanup and better test coverage +- **commit**: simplify call +- **version_scheme**: cleanup +- improve readability and fix typos + +### Perf + +- **bump**: avoid unnecessary list construction and rename variable to avoid confusion +- **tags**: use set + ## v4.8.2 (2025-05-22) ### Refactor diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 8e288a597c..af82c57223 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "4.8.2" +__version__ = "4.8.3" diff --git a/pyproject.toml b/pyproject.toml index 0d135954a5..6990741957 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "commitizen" -version = "4.8.2" +version = "4.8.3" description = "Python commitizen client tool" authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }] maintainers = [ @@ -88,7 +88,7 @@ build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "4.8.2" +version = "4.8.3" tag_format = "v$version" version_files = [ "pyproject.toml:version", From a5e3cc6e11148f4978a4771cb9ed46137ee61b0e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:18:53 +0000 Subject: [PATCH 593/598] docs(cli/screenshots): update CLI screenshots [skip ci] --- docs/images/cli_help/cz_bump___help.svg | 348 +++++++++++----------- docs/images/cli_help/cz_commit___help.svg | 111 +++---- 2 files changed, 230 insertions(+), 229 deletions(-) diff --git a/docs/images/cli_help/cz_bump___help.svg b/docs/images/cli_help/cz_bump___help.svg index 7f27636ddf..7d007df312 100644 --- a/docs/images/cli_help/cz_bump___help.svg +++ b/docs/images/cli_help/cz_bump___help.svg @@ -19,273 +19,273 @@ font-weight: 700; } - .terminal-243650528-matrix { + .terminal-1655558888-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-243650528-title { + .terminal-1655558888-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-243650528-r1 { fill: #c5c8c6 } -.terminal-243650528-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-243650528-r3 { fill: #68a0b3;font-weight: bold } -.terminal-243650528-r4 { fill: #98a84b } + .terminal-1655558888-r1 { fill: #c5c8c6 } +.terminal-1655558888-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-1655558888-r3 { fill: #68a0b3;font-weight: bold } +.terminal-1655558888-r4 { fill: #98a84b } </style> <defs> - <clipPath id="terminal-243650528-clip-terminal"> + <clipPath id="terminal-1655558888-clip-terminal"> <rect x="0" y="0" width="975.0" height="2024.1999999999998" /> </clipPath> - <clipPath id="terminal-243650528-line-0"> + <clipPath id="terminal-1655558888-line-0"> <rect x="0" y="1.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-1"> +<clipPath id="terminal-1655558888-line-1"> <rect x="0" y="25.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-2"> +<clipPath id="terminal-1655558888-line-2"> <rect x="0" y="50.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-3"> +<clipPath id="terminal-1655558888-line-3"> <rect x="0" y="74.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-4"> +<clipPath id="terminal-1655558888-line-4"> <rect x="0" y="99.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-5"> +<clipPath id="terminal-1655558888-line-5"> <rect x="0" y="123.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-6"> +<clipPath id="terminal-1655558888-line-6"> <rect x="0" y="147.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-7"> +<clipPath id="terminal-1655558888-line-7"> <rect x="0" y="172.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-8"> +<clipPath id="terminal-1655558888-line-8"> <rect x="0" y="196.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-9"> +<clipPath id="terminal-1655558888-line-9"> <rect x="0" y="221.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-10"> +<clipPath id="terminal-1655558888-line-10"> <rect x="0" y="245.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-11"> +<clipPath id="terminal-1655558888-line-11"> <rect x="0" y="269.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-12"> +<clipPath id="terminal-1655558888-line-12"> <rect x="0" y="294.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-13"> +<clipPath id="terminal-1655558888-line-13"> <rect x="0" y="318.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-14"> +<clipPath id="terminal-1655558888-line-14"> <rect x="0" y="343.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-15"> +<clipPath id="terminal-1655558888-line-15"> <rect x="0" y="367.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-16"> +<clipPath id="terminal-1655558888-line-16"> <rect x="0" y="391.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-17"> +<clipPath id="terminal-1655558888-line-17"> <rect x="0" y="416.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-18"> +<clipPath id="terminal-1655558888-line-18"> <rect x="0" y="440.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-19"> +<clipPath id="terminal-1655558888-line-19"> <rect x="0" y="465.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-20"> +<clipPath id="terminal-1655558888-line-20"> <rect x="0" y="489.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-21"> +<clipPath id="terminal-1655558888-line-21"> <rect x="0" y="513.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-22"> +<clipPath id="terminal-1655558888-line-22"> <rect x="0" y="538.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-23"> +<clipPath id="terminal-1655558888-line-23"> <rect x="0" y="562.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-24"> +<clipPath id="terminal-1655558888-line-24"> <rect x="0" y="587.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-25"> +<clipPath id="terminal-1655558888-line-25"> <rect x="0" y="611.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-26"> +<clipPath id="terminal-1655558888-line-26"> <rect x="0" y="635.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-27"> +<clipPath id="terminal-1655558888-line-27"> <rect x="0" y="660.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-28"> +<clipPath id="terminal-1655558888-line-28"> <rect x="0" y="684.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-29"> +<clipPath id="terminal-1655558888-line-29"> <rect x="0" y="709.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-30"> +<clipPath id="terminal-1655558888-line-30"> <rect x="0" y="733.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-31"> +<clipPath id="terminal-1655558888-line-31"> <rect x="0" y="757.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-32"> +<clipPath id="terminal-1655558888-line-32"> <rect x="0" y="782.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-33"> +<clipPath id="terminal-1655558888-line-33"> <rect x="0" y="806.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-34"> +<clipPath id="terminal-1655558888-line-34"> <rect x="0" y="831.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-35"> +<clipPath id="terminal-1655558888-line-35"> <rect x="0" y="855.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-36"> +<clipPath id="terminal-1655558888-line-36"> <rect x="0" y="879.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-37"> +<clipPath id="terminal-1655558888-line-37"> <rect x="0" y="904.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-38"> +<clipPath id="terminal-1655558888-line-38"> <rect x="0" y="928.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-39"> +<clipPath id="terminal-1655558888-line-39"> <rect x="0" y="953.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-40"> +<clipPath id="terminal-1655558888-line-40"> <rect x="0" y="977.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-41"> +<clipPath id="terminal-1655558888-line-41"> <rect x="0" y="1001.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-42"> +<clipPath id="terminal-1655558888-line-42"> <rect x="0" y="1026.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-43"> +<clipPath id="terminal-1655558888-line-43"> <rect x="0" y="1050.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-44"> +<clipPath id="terminal-1655558888-line-44"> <rect x="0" y="1075.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-45"> +<clipPath id="terminal-1655558888-line-45"> <rect x="0" y="1099.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-46"> +<clipPath id="terminal-1655558888-line-46"> <rect x="0" y="1123.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-47"> +<clipPath id="terminal-1655558888-line-47"> <rect x="0" y="1148.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-48"> +<clipPath id="terminal-1655558888-line-48"> <rect x="0" y="1172.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-49"> +<clipPath id="terminal-1655558888-line-49"> <rect x="0" y="1197.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-50"> +<clipPath id="terminal-1655558888-line-50"> <rect x="0" y="1221.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-51"> +<clipPath id="terminal-1655558888-line-51"> <rect x="0" y="1245.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-52"> +<clipPath id="terminal-1655558888-line-52"> <rect x="0" y="1270.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-53"> +<clipPath id="terminal-1655558888-line-53"> <rect x="0" y="1294.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-54"> +<clipPath id="terminal-1655558888-line-54"> <rect x="0" y="1319.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-55"> +<clipPath id="terminal-1655558888-line-55"> <rect x="0" y="1343.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-56"> +<clipPath id="terminal-1655558888-line-56"> <rect x="0" y="1367.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-57"> +<clipPath id="terminal-1655558888-line-57"> <rect x="0" y="1392.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-58"> +<clipPath id="terminal-1655558888-line-58"> <rect x="0" y="1416.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-59"> +<clipPath id="terminal-1655558888-line-59"> <rect x="0" y="1441.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-60"> +<clipPath id="terminal-1655558888-line-60"> <rect x="0" y="1465.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-61"> +<clipPath id="terminal-1655558888-line-61"> <rect x="0" y="1489.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-62"> +<clipPath id="terminal-1655558888-line-62"> <rect x="0" y="1514.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-63"> +<clipPath id="terminal-1655558888-line-63"> <rect x="0" y="1538.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-64"> +<clipPath id="terminal-1655558888-line-64"> <rect x="0" y="1563.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-65"> +<clipPath id="terminal-1655558888-line-65"> <rect x="0" y="1587.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-66"> +<clipPath id="terminal-1655558888-line-66"> <rect x="0" y="1611.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-67"> +<clipPath id="terminal-1655558888-line-67"> <rect x="0" y="1636.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-68"> +<clipPath id="terminal-1655558888-line-68"> <rect x="0" y="1660.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-69"> +<clipPath id="terminal-1655558888-line-69"> <rect x="0" y="1685.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-70"> +<clipPath id="terminal-1655558888-line-70"> <rect x="0" y="1709.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-71"> +<clipPath id="terminal-1655558888-line-71"> <rect x="0" y="1733.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-72"> +<clipPath id="terminal-1655558888-line-72"> <rect x="0" y="1758.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-73"> +<clipPath id="terminal-1655558888-line-73"> <rect x="0" y="1782.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-74"> +<clipPath id="terminal-1655558888-line-74"> <rect x="0" y="1807.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-75"> +<clipPath id="terminal-1655558888-line-75"> <rect x="0" y="1831.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-76"> +<clipPath id="terminal-1655558888-line-76"> <rect x="0" y="1855.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-77"> +<clipPath id="terminal-1655558888-line-77"> <rect x="0" y="1880.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-78"> +<clipPath id="terminal-1655558888-line-78"> <rect x="0" y="1904.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-79"> +<clipPath id="terminal-1655558888-line-79"> <rect x="0" y="1929.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-80"> +<clipPath id="terminal-1655558888-line-80"> <rect x="0" y="1953.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-243650528-line-81"> +<clipPath id="terminal-1655558888-line-81"> <rect x="0" y="1977.9" width="976" height="24.65"/> </clipPath> </defs> @@ -297,92 +297,92 @@ <circle cx="44" cy="0" r="7" fill="#28c840"/> </g> - <g transform="translate(9, 41)" clip-path="url(#terminal-243650528-clip-terminal)"> + <g transform="translate(9, 41)" clip-path="url(#terminal-1655558888-clip-terminal)"> - <g class="terminal-243650528-matrix"> - <text class="terminal-243650528-r1" x="0" y="20" textLength="195.2" clip-path="url(#terminal-243650528-line-0)">$ cz bump --help</text><text class="terminal-243650528-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-243650528-line-0)"> -</text><text class="terminal-243650528-r1" x="0" y="44.4" textLength="183" clip-path="url(#terminal-243650528-line-1)">usage: cz bump </text><text class="terminal-243650528-r2" x="183" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">[</text><text class="terminal-243650528-r1" x="195.2" y="44.4" textLength="24.4" clip-path="url(#terminal-243650528-line-1)">-h</text><text class="terminal-243650528-r2" x="219.6" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">]</text><text class="terminal-243650528-r2" x="244" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">[</text><text class="terminal-243650528-r1" x="256.2" y="44.4" textLength="109.8" clip-path="url(#terminal-243650528-line-1)">--dry-run</text><text class="terminal-243650528-r2" x="366" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">]</text><text class="terminal-243650528-r2" x="390.4" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">[</text><text class="terminal-243650528-r1" x="402.6" y="44.4" textLength="146.4" clip-path="url(#terminal-243650528-line-1)">--files-only</text><text class="terminal-243650528-r2" x="549" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">]</text><text class="terminal-243650528-r2" x="573.4" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">[</text><text class="terminal-243650528-r1" x="585.6" y="44.4" textLength="183" clip-path="url(#terminal-243650528-line-1)">--local-version</text><text class="terminal-243650528-r2" x="768.6" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">]</text><text class="terminal-243650528-r2" x="793" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">[</text><text class="terminal-243650528-r1" x="805.2" y="44.4" textLength="134.2" clip-path="url(#terminal-243650528-line-1)">--changelog</text><text class="terminal-243650528-r2" x="939.4" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)">]</text><text class="terminal-243650528-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-243650528-line-1)"> -</text><text class="terminal-243650528-r2" x="183" y="68.8" textLength="12.2" clip-path="url(#terminal-243650528-line-2)">[</text><text class="terminal-243650528-r1" x="195.2" y="68.8" textLength="134.2" clip-path="url(#terminal-243650528-line-2)">--no-verify</text><text class="terminal-243650528-r2" x="329.4" y="68.8" textLength="12.2" clip-path="url(#terminal-243650528-line-2)">]</text><text class="terminal-243650528-r2" x="353.8" y="68.8" textLength="12.2" clip-path="url(#terminal-243650528-line-2)">[</text><text class="terminal-243650528-r1" x="366" y="68.8" textLength="61" clip-path="url(#terminal-243650528-line-2)">--yes</text><text class="terminal-243650528-r2" x="427" y="68.8" textLength="12.2" clip-path="url(#terminal-243650528-line-2)">]</text><text class="terminal-243650528-r2" x="451.4" y="68.8" textLength="12.2" clip-path="url(#terminal-243650528-line-2)">[</text><text class="terminal-243650528-r1" x="463.6" y="68.8" textLength="280.6" clip-path="url(#terminal-243650528-line-2)">--tag-format TAG_FORMAT</text><text class="terminal-243650528-r2" x="744.2" y="68.8" textLength="12.2" clip-path="url(#terminal-243650528-line-2)">]</text><text class="terminal-243650528-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-243650528-line-2)"> -</text><text class="terminal-243650528-r2" x="183" y="93.2" textLength="12.2" clip-path="url(#terminal-243650528-line-3)">[</text><text class="terminal-243650528-r1" x="195.2" y="93.2" textLength="329.4" clip-path="url(#terminal-243650528-line-3)">--bump-message BUMP_MESSAGE</text><text class="terminal-243650528-r2" x="524.6" y="93.2" textLength="12.2" clip-path="url(#terminal-243650528-line-3)">]</text><text class="terminal-243650528-r2" x="549" y="93.2" textLength="12.2" clip-path="url(#terminal-243650528-line-3)">[</text><text class="terminal-243650528-r1" x="561.2" y="93.2" textLength="158.6" clip-path="url(#terminal-243650528-line-3)">--prerelease </text><text class="terminal-243650528-r2" x="719.8" y="93.2" textLength="12.2" clip-path="url(#terminal-243650528-line-3)">{</text><text class="terminal-243650528-r1" x="732" y="93.2" textLength="158.6" clip-path="url(#terminal-243650528-line-3)">alpha,beta,rc</text><text class="terminal-243650528-r2" x="890.6" y="93.2" textLength="12.2" clip-path="url(#terminal-243650528-line-3)">}</text><text class="terminal-243650528-r2" x="902.8" y="93.2" textLength="12.2" clip-path="url(#terminal-243650528-line-3)">]</text><text class="terminal-243650528-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-243650528-line-3)"> -</text><text class="terminal-243650528-r2" x="183" y="117.6" textLength="12.2" clip-path="url(#terminal-243650528-line-4)">[</text><text class="terminal-243650528-r1" x="195.2" y="117.6" textLength="280.6" clip-path="url(#terminal-243650528-line-4)">--devrelease DEVRELEASE</text><text class="terminal-243650528-r2" x="475.8" y="117.6" textLength="12.2" clip-path="url(#terminal-243650528-line-4)">]</text><text class="terminal-243650528-r2" x="500.2" y="117.6" textLength="12.2" clip-path="url(#terminal-243650528-line-4)">[</text><text class="terminal-243650528-r1" x="512.4" y="117.6" textLength="146.4" clip-path="url(#terminal-243650528-line-4)">--increment </text><text class="terminal-243650528-r2" x="658.8" y="117.6" textLength="12.2" clip-path="url(#terminal-243650528-line-4)">{</text><text class="terminal-243650528-r1" x="671" y="117.6" textLength="207.4" clip-path="url(#terminal-243650528-line-4)">MAJOR,MINOR,PATCH</text><text class="terminal-243650528-r2" x="878.4" y="117.6" textLength="12.2" clip-path="url(#terminal-243650528-line-4)">}</text><text class="terminal-243650528-r2" x="890.6" y="117.6" textLength="12.2" clip-path="url(#terminal-243650528-line-4)">]</text><text class="terminal-243650528-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-243650528-line-4)"> -</text><text class="terminal-243650528-r2" x="183" y="142" textLength="12.2" clip-path="url(#terminal-243650528-line-5)">[</text><text class="terminal-243650528-r1" x="195.2" y="142" textLength="207.4" clip-path="url(#terminal-243650528-line-5)">--increment-mode </text><text class="terminal-243650528-r2" x="402.6" y="142" textLength="12.2" clip-path="url(#terminal-243650528-line-5)">{</text><text class="terminal-243650528-r1" x="414.8" y="142" textLength="146.4" clip-path="url(#terminal-243650528-line-5)">linear,exact</text><text class="terminal-243650528-r2" x="561.2" y="142" textLength="12.2" clip-path="url(#terminal-243650528-line-5)">}</text><text class="terminal-243650528-r2" x="573.4" y="142" textLength="12.2" clip-path="url(#terminal-243650528-line-5)">]</text><text class="terminal-243650528-r2" x="597.8" y="142" textLength="12.2" clip-path="url(#terminal-243650528-line-5)">[</text><text class="terminal-243650528-r1" x="610" y="142" textLength="231.8" clip-path="url(#terminal-243650528-line-5)">--check-consistency</text><text class="terminal-243650528-r2" x="841.8" y="142" textLength="12.2" clip-path="url(#terminal-243650528-line-5)">]</text><text class="terminal-243650528-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-243650528-line-5)"> -</text><text class="terminal-243650528-r2" x="183" y="166.4" textLength="12.2" clip-path="url(#terminal-243650528-line-6)">[</text><text class="terminal-243650528-r1" x="195.2" y="166.4" textLength="183" clip-path="url(#terminal-243650528-line-6)">--annotated-tag</text><text class="terminal-243650528-r2" x="378.2" y="166.4" textLength="12.2" clip-path="url(#terminal-243650528-line-6)">]</text><text class="terminal-243650528-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-243650528-line-6)"> -</text><text class="terminal-243650528-r2" x="183" y="190.8" textLength="12.2" clip-path="url(#terminal-243650528-line-7)">[</text><text class="terminal-243650528-r1" x="195.2" y="190.8" textLength="549" clip-path="url(#terminal-243650528-line-7)">--annotated-tag-message ANNOTATED_TAG_MESSAGE</text><text class="terminal-243650528-r2" x="744.2" y="190.8" textLength="12.2" clip-path="url(#terminal-243650528-line-7)">]</text><text class="terminal-243650528-r2" x="768.6" y="190.8" textLength="12.2" clip-path="url(#terminal-243650528-line-7)">[</text><text class="terminal-243650528-r1" x="780.8" y="190.8" textLength="122" clip-path="url(#terminal-243650528-line-7)">--gpg-sign</text><text class="terminal-243650528-r2" x="902.8" y="190.8" textLength="12.2" clip-path="url(#terminal-243650528-line-7)">]</text><text class="terminal-243650528-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-243650528-line-7)"> -</text><text class="terminal-243650528-r2" x="183" y="215.2" textLength="12.2" clip-path="url(#terminal-243650528-line-8)">[</text><text class="terminal-243650528-r1" x="195.2" y="215.2" textLength="256.2" clip-path="url(#terminal-243650528-line-8)">--changelog-to-stdout</text><text class="terminal-243650528-r2" x="451.4" y="215.2" textLength="12.2" clip-path="url(#terminal-243650528-line-8)">]</text><text class="terminal-243650528-r2" x="475.8" y="215.2" textLength="12.2" clip-path="url(#terminal-243650528-line-8)">[</text><text class="terminal-243650528-r1" x="488" y="215.2" textLength="268.4" clip-path="url(#terminal-243650528-line-8)">--git-output-to-stderr</text><text class="terminal-243650528-r2" x="756.4" y="215.2" textLength="12.2" clip-path="url(#terminal-243650528-line-8)">]</text><text class="terminal-243650528-r2" x="780.8" y="215.2" textLength="12.2" clip-path="url(#terminal-243650528-line-8)">[</text><text class="terminal-243650528-r1" x="793" y="215.2" textLength="85.4" clip-path="url(#terminal-243650528-line-8)">--retry</text><text class="terminal-243650528-r2" x="878.4" y="215.2" textLength="12.2" clip-path="url(#terminal-243650528-line-8)">]</text><text class="terminal-243650528-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-243650528-line-8)"> -</text><text class="terminal-243650528-r2" x="183" y="239.6" textLength="12.2" clip-path="url(#terminal-243650528-line-9)">[</text><text class="terminal-243650528-r1" x="195.2" y="239.6" textLength="244" clip-path="url(#terminal-243650528-line-9)">--major-version-zero</text><text class="terminal-243650528-r2" x="439.2" y="239.6" textLength="12.2" clip-path="url(#terminal-243650528-line-9)">]</text><text class="terminal-243650528-r2" x="463.6" y="239.6" textLength="12.2" clip-path="url(#terminal-243650528-line-9)">[</text><text class="terminal-243650528-r1" x="475.8" y="239.6" textLength="231.8" clip-path="url(#terminal-243650528-line-9)">--template TEMPLATE</text><text class="terminal-243650528-r2" x="707.6" y="239.6" textLength="12.2" clip-path="url(#terminal-243650528-line-9)">]</text><text class="terminal-243650528-r2" x="732" y="239.6" textLength="12.2" clip-path="url(#terminal-243650528-line-9)">[</text><text class="terminal-243650528-r1" x="744.2" y="239.6" textLength="158.6" clip-path="url(#terminal-243650528-line-9)">--extra EXTRA</text><text class="terminal-243650528-r2" x="902.8" y="239.6" textLength="12.2" clip-path="url(#terminal-243650528-line-9)">]</text><text class="terminal-243650528-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-243650528-line-9)"> -</text><text class="terminal-243650528-r2" x="183" y="264" textLength="12.2" clip-path="url(#terminal-243650528-line-10)">[</text><text class="terminal-243650528-r1" x="195.2" y="264" textLength="256.2" clip-path="url(#terminal-243650528-line-10)">--file-name FILE_NAME</text><text class="terminal-243650528-r2" x="451.4" y="264" textLength="12.2" clip-path="url(#terminal-243650528-line-10)">]</text><text class="terminal-243650528-r2" x="475.8" y="264" textLength="12.2" clip-path="url(#terminal-243650528-line-10)">[</text><text class="terminal-243650528-r1" x="488" y="264" textLength="451.4" clip-path="url(#terminal-243650528-line-10)">--prerelease-offset PRERELEASE_OFFSET</text><text class="terminal-243650528-r2" x="939.4" y="264" textLength="12.2" clip-path="url(#terminal-243650528-line-10)">]</text><text class="terminal-243650528-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-243650528-line-10)"> -</text><text class="terminal-243650528-r2" x="183" y="288.4" textLength="12.2" clip-path="url(#terminal-243650528-line-11)">[</text><text class="terminal-243650528-r1" x="195.2" y="288.4" textLength="207.4" clip-path="url(#terminal-243650528-line-11)">--version-scheme </text><text class="terminal-243650528-r2" x="402.6" y="288.4" textLength="12.2" clip-path="url(#terminal-243650528-line-11)">{</text><text class="terminal-243650528-r1" x="414.8" y="288.4" textLength="256.2" clip-path="url(#terminal-243650528-line-11)">pep440,semver,semver2</text><text class="terminal-243650528-r2" x="671" y="288.4" textLength="12.2" clip-path="url(#terminal-243650528-line-11)">}</text><text class="terminal-243650528-r2" x="683.2" y="288.4" textLength="12.2" clip-path="url(#terminal-243650528-line-11)">]</text><text class="terminal-243650528-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-243650528-line-11)"> -</text><text class="terminal-243650528-r2" x="183" y="312.8" textLength="12.2" clip-path="url(#terminal-243650528-line-12)">[</text><text class="terminal-243650528-r1" x="195.2" y="312.8" textLength="183" clip-path="url(#terminal-243650528-line-12)">--version-type </text><text class="terminal-243650528-r2" x="378.2" y="312.8" textLength="12.2" clip-path="url(#terminal-243650528-line-12)">{</text><text class="terminal-243650528-r1" x="390.4" y="312.8" textLength="256.2" clip-path="url(#terminal-243650528-line-12)">pep440,semver,semver2</text><text class="terminal-243650528-r2" x="646.6" y="312.8" textLength="12.2" clip-path="url(#terminal-243650528-line-12)">}</text><text class="terminal-243650528-r2" x="658.8" y="312.8" textLength="12.2" clip-path="url(#terminal-243650528-line-12)">]</text><text class="terminal-243650528-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-243650528-line-12)"> -</text><text class="terminal-243650528-r2" x="183" y="337.2" textLength="12.2" clip-path="url(#terminal-243650528-line-13)">[</text><text class="terminal-243650528-r1" x="195.2" y="337.2" textLength="378.2" clip-path="url(#terminal-243650528-line-13)">--build-metadata BUILD_METADATA</text><text class="terminal-243650528-r2" x="573.4" y="337.2" textLength="12.2" clip-path="url(#terminal-243650528-line-13)">]</text><text class="terminal-243650528-r2" x="597.8" y="337.2" textLength="12.2" clip-path="url(#terminal-243650528-line-13)">[</text><text class="terminal-243650528-r1" x="610" y="337.2" textLength="122" clip-path="url(#terminal-243650528-line-13)">--get-next</text><text class="terminal-243650528-r2" x="732" y="337.2" textLength="12.2" clip-path="url(#terminal-243650528-line-13)">]</text><text class="terminal-243650528-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-243650528-line-13)"> -</text><text class="terminal-243650528-r2" x="183" y="361.6" textLength="12.2" clip-path="url(#terminal-243650528-line-14)">[</text><text class="terminal-243650528-r1" x="195.2" y="361.6" textLength="207.4" clip-path="url(#terminal-243650528-line-14)">--allow-no-commit</text><text class="terminal-243650528-r2" x="402.6" y="361.6" textLength="12.2" clip-path="url(#terminal-243650528-line-14)">]</text><text class="terminal-243650528-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-243650528-line-14)"> -</text><text class="terminal-243650528-r2" x="183" y="386" textLength="12.2" clip-path="url(#terminal-243650528-line-15)">[</text><text class="terminal-243650528-r1" x="195.2" y="386" textLength="170.8" clip-path="url(#terminal-243650528-line-15)">MANUAL_VERSION</text><text class="terminal-243650528-r2" x="366" y="386" textLength="12.2" clip-path="url(#terminal-243650528-line-15)">]</text><text class="terminal-243650528-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-243650528-line-15)"> -</text><text class="terminal-243650528-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-243650528-line-16)"> -</text><text class="terminal-243650528-r1" x="0" y="434.8" textLength="512.4" clip-path="url(#terminal-243650528-line-17)">bump semantic version based on the git log</text><text class="terminal-243650528-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-243650528-line-17)"> -</text><text class="terminal-243650528-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-243650528-line-18)"> -</text><text class="terminal-243650528-r1" x="0" y="483.6" textLength="256.2" clip-path="url(#terminal-243650528-line-19)">positional arguments:</text><text class="terminal-243650528-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-243650528-line-19)"> -</text><text class="terminal-243650528-r1" x="0" y="508" textLength="610" clip-path="url(#terminal-243650528-line-20)">  MANUAL_VERSION        bump to the given version </text><text class="terminal-243650528-r2" x="610" y="508" textLength="12.2" clip-path="url(#terminal-243650528-line-20)">(</text><text class="terminal-243650528-r1" x="622.2" y="508" textLength="61" clip-path="url(#terminal-243650528-line-20)">e.g: </text><text class="terminal-243650528-r3" x="683.2" y="508" textLength="36.6" clip-path="url(#terminal-243650528-line-20)">1.5</text><text class="terminal-243650528-r1" x="719.8" y="508" textLength="12.2" clip-path="url(#terminal-243650528-line-20)">.</text><text class="terminal-243650528-r3" x="732" y="508" textLength="12.2" clip-path="url(#terminal-243650528-line-20)">3</text><text class="terminal-243650528-r2" x="744.2" y="508" textLength="12.2" clip-path="url(#terminal-243650528-line-20)">)</text><text class="terminal-243650528-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-243650528-line-20)"> -</text><text class="terminal-243650528-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-243650528-line-21)"> -</text><text class="terminal-243650528-r1" x="0" y="556.8" textLength="97.6" clip-path="url(#terminal-243650528-line-22)">options:</text><text class="terminal-243650528-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-243650528-line-22)"> -</text><text class="terminal-243650528-r1" x="0" y="581.2" textLength="671" clip-path="url(#terminal-243650528-line-23)">  -h, --help            show this help message and exit</text><text class="terminal-243650528-r1" x="976" y="581.2" textLength="12.2" clip-path="url(#terminal-243650528-line-23)"> -</text><text class="terminal-243650528-r1" x="0" y="605.6" textLength="915" clip-path="url(#terminal-243650528-line-24)">  --dry-run             show output to stdout, no commit, no modified files</text><text class="terminal-243650528-r1" x="976" y="605.6" textLength="12.2" clip-path="url(#terminal-243650528-line-24)"> -</text><text class="terminal-243650528-r1" x="0" y="630" textLength="793" clip-path="url(#terminal-243650528-line-25)">  --files-only          bump version in the files from the config</text><text class="terminal-243650528-r1" x="976" y="630" textLength="12.2" clip-path="url(#terminal-243650528-line-25)"> -</text><text class="terminal-243650528-r1" x="0" y="654.4" textLength="719.8" clip-path="url(#terminal-243650528-line-26)">  --local-version       bump only the local version portion</text><text class="terminal-243650528-r1" x="976" y="654.4" textLength="12.2" clip-path="url(#terminal-243650528-line-26)"> -</text><text class="terminal-243650528-r1" x="0" y="678.8" textLength="841.8" clip-path="url(#terminal-243650528-line-27)">  --changelog, -ch      generate the changelog for the newest version</text><text class="terminal-243650528-r1" x="976" y="678.8" textLength="12.2" clip-path="url(#terminal-243650528-line-27)"> -</text><text class="terminal-243650528-r1" x="0" y="703.2" textLength="902.8" clip-path="url(#terminal-243650528-line-28)">  --no-verify           this option bypasses the pre-commit and commit-msg</text><text class="terminal-243650528-r1" x="976" y="703.2" textLength="12.2" clip-path="url(#terminal-243650528-line-28)"> -</text><text class="terminal-243650528-r1" x="0" y="727.6" textLength="353.8" clip-path="url(#terminal-243650528-line-29)">                        hooks</text><text class="terminal-243650528-r1" x="976" y="727.6" textLength="12.2" clip-path="url(#terminal-243650528-line-29)"> -</text><text class="terminal-243650528-r1" x="0" y="752" textLength="719.8" clip-path="url(#terminal-243650528-line-30)">  --yes                 accept automatically questions done</text><text class="terminal-243650528-r1" x="976" y="752" textLength="12.2" clip-path="url(#terminal-243650528-line-30)"> -</text><text class="terminal-243650528-r1" x="0" y="776.4" textLength="305" clip-path="url(#terminal-243650528-line-31)">  --tag-format TAG_FORMAT</text><text class="terminal-243650528-r1" x="976" y="776.4" textLength="12.2" clip-path="url(#terminal-243650528-line-31)"> -</text><text class="terminal-243650528-r1" x="0" y="800.8" textLength="939.4" clip-path="url(#terminal-243650528-line-32)">                        the format used to tag the commit and read it, use it</text><text class="terminal-243650528-r1" x="976" y="800.8" textLength="12.2" clip-path="url(#terminal-243650528-line-32)"> -</text><text class="terminal-243650528-r1" x="0" y="825.2" textLength="866.2" clip-path="url(#terminal-243650528-line-33)">                        in existing projects, wrap around simple quotes</text><text class="terminal-243650528-r1" x="976" y="825.2" textLength="12.2" clip-path="url(#terminal-243650528-line-33)"> -</text><text class="terminal-243650528-r1" x="0" y="849.6" textLength="353.8" clip-path="url(#terminal-243650528-line-34)">  --bump-message BUMP_MESSAGE</text><text class="terminal-243650528-r1" x="976" y="849.6" textLength="12.2" clip-path="url(#terminal-243650528-line-34)"> -</text><text class="terminal-243650528-r1" x="0" y="874" textLength="902.8" clip-path="url(#terminal-243650528-line-35)">                        template used to create the release commit, useful</text><text class="terminal-243650528-r1" x="976" y="874" textLength="12.2" clip-path="url(#terminal-243650528-line-35)"> -</text><text class="terminal-243650528-r1" x="0" y="898.4" textLength="536.8" clip-path="url(#terminal-243650528-line-36)">                        when working with CI</text><text class="terminal-243650528-r1" x="976" y="898.4" textLength="12.2" clip-path="url(#terminal-243650528-line-36)"> -</text><text class="terminal-243650528-r1" x="0" y="922.8" textLength="244" clip-path="url(#terminal-243650528-line-37)">  --prerelease, -pr </text><text class="terminal-243650528-r2" x="244" y="922.8" textLength="12.2" clip-path="url(#terminal-243650528-line-37)">{</text><text class="terminal-243650528-r1" x="256.2" y="922.8" textLength="158.6" clip-path="url(#terminal-243650528-line-37)">alpha,beta,rc</text><text class="terminal-243650528-r2" x="414.8" y="922.8" textLength="12.2" clip-path="url(#terminal-243650528-line-37)">}</text><text class="terminal-243650528-r1" x="976" y="922.8" textLength="12.2" clip-path="url(#terminal-243650528-line-37)"> -</text><text class="terminal-243650528-r1" x="0" y="947.2" textLength="597.8" clip-path="url(#terminal-243650528-line-38)">                        choose type of prerelease</text><text class="terminal-243650528-r1" x="976" y="947.2" textLength="12.2" clip-path="url(#terminal-243650528-line-38)"> -</text><text class="terminal-243650528-r1" x="0" y="971.6" textLength="353.8" clip-path="url(#terminal-243650528-line-39)">  --devrelease, -d DEVRELEASE</text><text class="terminal-243650528-r1" x="976" y="971.6" textLength="12.2" clip-path="url(#terminal-243650528-line-39)"> -</text><text class="terminal-243650528-r1" x="0" y="996" textLength="841.8" clip-path="url(#terminal-243650528-line-40)">                        specify non-negative integer for dev. release</text><text class="terminal-243650528-r1" x="976" y="996" textLength="12.2" clip-path="url(#terminal-243650528-line-40)"> -</text><text class="terminal-243650528-r1" x="0" y="1020.4" textLength="170.8" clip-path="url(#terminal-243650528-line-41)">  --increment </text><text class="terminal-243650528-r2" x="170.8" y="1020.4" textLength="12.2" clip-path="url(#terminal-243650528-line-41)">{</text><text class="terminal-243650528-r1" x="183" y="1020.4" textLength="207.4" clip-path="url(#terminal-243650528-line-41)">MAJOR,MINOR,PATCH</text><text class="terminal-243650528-r2" x="390.4" y="1020.4" textLength="12.2" clip-path="url(#terminal-243650528-line-41)">}</text><text class="terminal-243650528-r1" x="976" y="1020.4" textLength="12.2" clip-path="url(#terminal-243650528-line-41)"> -</text><text class="terminal-243650528-r1" x="0" y="1044.8" textLength="756.4" clip-path="url(#terminal-243650528-line-42)">                        manually specify the desired increment</text><text class="terminal-243650528-r1" x="976" y="1044.8" textLength="12.2" clip-path="url(#terminal-243650528-line-42)"> -</text><text class="terminal-243650528-r1" x="0" y="1069.2" textLength="231.8" clip-path="url(#terminal-243650528-line-43)">  --increment-mode </text><text class="terminal-243650528-r2" x="231.8" y="1069.2" textLength="12.2" clip-path="url(#terminal-243650528-line-43)">{</text><text class="terminal-243650528-r1" x="244" y="1069.2" textLength="146.4" clip-path="url(#terminal-243650528-line-43)">linear,exact</text><text class="terminal-243650528-r2" x="390.4" y="1069.2" textLength="12.2" clip-path="url(#terminal-243650528-line-43)">}</text><text class="terminal-243650528-r1" x="976" y="1069.2" textLength="12.2" clip-path="url(#terminal-243650528-line-43)"> -</text><text class="terminal-243650528-r1" x="0" y="1093.6" textLength="902.8" clip-path="url(#terminal-243650528-line-44)">                        set the method by which the new version is chosen.</text><text class="terminal-243650528-r1" x="976" y="1093.6" textLength="12.2" clip-path="url(#terminal-243650528-line-44)"> -</text><text class="terminal-243650528-r4" x="292.8" y="1118" textLength="97.6" clip-path="url(#terminal-243650528-line-45)">'linear'</text><text class="terminal-243650528-r2" x="402.6" y="1118" textLength="12.2" clip-path="url(#terminal-243650528-line-45)">(</text><text class="terminal-243650528-r1" x="414.8" y="1118" textLength="85.4" clip-path="url(#terminal-243650528-line-45)">default</text><text class="terminal-243650528-r2" x="500.2" y="1118" textLength="12.2" clip-path="url(#terminal-243650528-line-45)">)</text><text class="terminal-243650528-r1" x="512.4" y="1118" textLength="414.8" clip-path="url(#terminal-243650528-line-45)"> guesses the next version based on</text><text class="terminal-243650528-r1" x="976" y="1118" textLength="12.2" clip-path="url(#terminal-243650528-line-45)"> -</text><text class="terminal-243650528-r1" x="0" y="1142.4" textLength="939.4" clip-path="url(#terminal-243650528-line-46)">                        typical linear version progression, such that bumping</text><text class="terminal-243650528-r1" x="976" y="1142.4" textLength="12.2" clip-path="url(#terminal-243650528-line-46)"> -</text><text class="terminal-243650528-r1" x="0" y="1166.8" textLength="866.2" clip-path="url(#terminal-243650528-line-47)">                        of a pre-release with lower precedence than the</text><text class="terminal-243650528-r1" x="976" y="1166.8" textLength="12.2" clip-path="url(#terminal-243650528-line-47)"> -</text><text class="terminal-243650528-r1" x="0" y="1191.2" textLength="939.4" clip-path="url(#terminal-243650528-line-48)">                        current pre-release phase maintains the current phase</text><text class="terminal-243650528-r1" x="976" y="1191.2" textLength="12.2" clip-path="url(#terminal-243650528-line-48)"> -</text><text class="terminal-243650528-r1" x="0" y="1215.6" textLength="561.2" clip-path="url(#terminal-243650528-line-49)">                        of higher precedence. </text><text class="terminal-243650528-r4" x="561.2" y="1215.6" textLength="85.4" clip-path="url(#terminal-243650528-line-49)">'exact'</text><text class="terminal-243650528-r1" x="646.6" y="1215.6" textLength="305" clip-path="url(#terminal-243650528-line-49)"> applies the changes that</text><text class="terminal-243650528-r1" x="976" y="1215.6" textLength="12.2" clip-path="url(#terminal-243650528-line-49)"> -</text><text class="terminal-243650528-r1" x="0" y="1240" textLength="536.8" clip-path="url(#terminal-243650528-line-50)">                        have been specified </text><text class="terminal-243650528-r2" x="536.8" y="1240" textLength="12.2" clip-path="url(#terminal-243650528-line-50)">(</text><text class="terminal-243650528-r1" x="549" y="1240" textLength="353.8" clip-path="url(#terminal-243650528-line-50)">or determined from the commit</text><text class="terminal-243650528-r1" x="976" y="1240" textLength="12.2" clip-path="url(#terminal-243650528-line-50)"> -</text><text class="terminal-243650528-r1" x="0" y="1264.4" textLength="329.4" clip-path="url(#terminal-243650528-line-51)">                        log</text><text class="terminal-243650528-r2" x="329.4" y="1264.4" textLength="12.2" clip-path="url(#terminal-243650528-line-51)">)</text><text class="terminal-243650528-r1" x="341.6" y="1264.4" textLength="585.6" clip-path="url(#terminal-243650528-line-51)"> without interpretation, such that the increment</text><text class="terminal-243650528-r1" x="976" y="1264.4" textLength="12.2" clip-path="url(#terminal-243650528-line-51)"> -</text><text class="terminal-243650528-r1" x="0" y="1288.8" textLength="707.6" clip-path="url(#terminal-243650528-line-52)">                        and pre-release are always honored</text><text class="terminal-243650528-r1" x="976" y="1288.8" textLength="12.2" clip-path="url(#terminal-243650528-line-52)"> -</text><text class="terminal-243650528-r1" x="0" y="1313.2" textLength="317.2" clip-path="url(#terminal-243650528-line-53)">  --check-consistency, -cc</text><text class="terminal-243650528-r1" x="976" y="1313.2" textLength="12.2" clip-path="url(#terminal-243650528-line-53)"> -</text><text class="terminal-243650528-r1" x="0" y="1337.6" textLength="951.6" clip-path="url(#terminal-243650528-line-54)">                        check consistency among versions defined in commitizen</text><text class="terminal-243650528-r1" x="976" y="1337.6" textLength="12.2" clip-path="url(#terminal-243650528-line-54)"> -</text><text class="terminal-243650528-r1" x="0" y="1362" textLength="671" clip-path="url(#terminal-243650528-line-55)">                        configuration and version_files</text><text class="terminal-243650528-r1" x="976" y="1362" textLength="12.2" clip-path="url(#terminal-243650528-line-55)"> -</text><text class="terminal-243650528-r1" x="0" y="1386.4" textLength="866.2" clip-path="url(#terminal-243650528-line-56)">  --annotated-tag, -at  create annotated tag instead of lightweight one</text><text class="terminal-243650528-r1" x="976" y="1386.4" textLength="12.2" clip-path="url(#terminal-243650528-line-56)"> -</text><text class="terminal-243650528-r1" x="0" y="1410.8" textLength="646.6" clip-path="url(#terminal-243650528-line-57)">  --annotated-tag-message, -atm ANNOTATED_TAG_MESSAGE</text><text class="terminal-243650528-r1" x="976" y="1410.8" textLength="12.2" clip-path="url(#terminal-243650528-line-57)"> -</text><text class="terminal-243650528-r1" x="0" y="1435.2" textLength="634.4" clip-path="url(#terminal-243650528-line-58)">                        create annotated tag message</text><text class="terminal-243650528-r1" x="976" y="1435.2" textLength="12.2" clip-path="url(#terminal-243650528-line-58)"> -</text><text class="terminal-243650528-r1" x="0" y="1459.6" textLength="719.8" clip-path="url(#terminal-243650528-line-59)">  --gpg-sign, -s        sign tag instead of lightweight one</text><text class="terminal-243650528-r1" x="976" y="1459.6" textLength="12.2" clip-path="url(#terminal-243650528-line-59)"> -</text><text class="terminal-243650528-r1" x="0" y="1484" textLength="280.6" clip-path="url(#terminal-243650528-line-60)">  --changelog-to-stdout</text><text class="terminal-243650528-r1" x="976" y="1484" textLength="12.2" clip-path="url(#terminal-243650528-line-60)"> -</text><text class="terminal-243650528-r1" x="0" y="1508.4" textLength="658.8" clip-path="url(#terminal-243650528-line-61)">                        Output changelog to the stdout</text><text class="terminal-243650528-r1" x="976" y="1508.4" textLength="12.2" clip-path="url(#terminal-243650528-line-61)"> -</text><text class="terminal-243650528-r1" x="0" y="1532.8" textLength="292.8" clip-path="url(#terminal-243650528-line-62)">  --git-output-to-stderr</text><text class="terminal-243650528-r1" x="976" y="1532.8" textLength="12.2" clip-path="url(#terminal-243650528-line-62)"> -</text><text class="terminal-243650528-r1" x="0" y="1557.2" textLength="646.6" clip-path="url(#terminal-243650528-line-63)">                        Redirect git output to stderr</text><text class="terminal-243650528-r1" x="976" y="1557.2" textLength="12.2" clip-path="url(#terminal-243650528-line-63)"> -</text><text class="terminal-243650528-r1" x="0" y="1581.6" textLength="744.2" clip-path="url(#terminal-243650528-line-64)">  --retry               retry commit if it fails the 1st time</text><text class="terminal-243650528-r1" x="976" y="1581.6" textLength="12.2" clip-path="url(#terminal-243650528-line-64)"> -</text><text class="terminal-243650528-r1" x="0" y="1606" textLength="939.4" clip-path="url(#terminal-243650528-line-65)">  --major-version-zero  keep major version at zero, even for breaking changes</text><text class="terminal-243650528-r1" x="976" y="1606" textLength="12.2" clip-path="url(#terminal-243650528-line-65)"> -</text><text class="terminal-243650528-r1" x="0" y="1630.4" textLength="305" clip-path="url(#terminal-243650528-line-66)">  --template, -t TEMPLATE</text><text class="terminal-243650528-r1" x="976" y="1630.4" textLength="12.2" clip-path="url(#terminal-243650528-line-66)"> -</text><text class="terminal-243650528-r1" x="0" y="1654.8" textLength="646.6" clip-path="url(#terminal-243650528-line-67)">                        changelog template file name </text><text class="terminal-243650528-r2" x="646.6" y="1654.8" textLength="12.2" clip-path="url(#terminal-243650528-line-67)">(</text><text class="terminal-243650528-r1" x="658.8" y="1654.8" textLength="280.6" clip-path="url(#terminal-243650528-line-67)">relative to the current</text><text class="terminal-243650528-r1" x="976" y="1654.8" textLength="12.2" clip-path="url(#terminal-243650528-line-67)"> -</text><text class="terminal-243650528-r1" x="0" y="1679.2" textLength="500.2" clip-path="url(#terminal-243650528-line-68)">                        working directory</text><text class="terminal-243650528-r2" x="500.2" y="1679.2" textLength="12.2" clip-path="url(#terminal-243650528-line-68)">)</text><text class="terminal-243650528-r1" x="976" y="1679.2" textLength="12.2" clip-path="url(#terminal-243650528-line-68)"> -</text><text class="terminal-243650528-r1" x="0" y="1703.6" textLength="622.2" clip-path="url(#terminal-243650528-line-69)">  --extra, -e EXTRA     a changelog extra variable </text><text class="terminal-243650528-r2" x="622.2" y="1703.6" textLength="12.2" clip-path="url(#terminal-243650528-line-69)">(</text><text class="terminal-243650528-r1" x="634.4" y="1703.6" textLength="146.4" clip-path="url(#terminal-243650528-line-69)">in the form </text><text class="terminal-243650528-r4" x="780.8" y="1703.6" textLength="12.2" clip-path="url(#terminal-243650528-line-69)">'</text><text class="terminal-243650528-r4" x="793" y="1703.6" textLength="36.6" clip-path="url(#terminal-243650528-line-69)">key</text><text class="terminal-243650528-r4" x="829.6" y="1703.6" textLength="12.2" clip-path="url(#terminal-243650528-line-69)">=</text><text class="terminal-243650528-r4" x="841.8" y="1703.6" textLength="61" clip-path="url(#terminal-243650528-line-69)">value</text><text class="terminal-243650528-r4" x="902.8" y="1703.6" textLength="12.2" clip-path="url(#terminal-243650528-line-69)">'</text><text class="terminal-243650528-r2" x="915" y="1703.6" textLength="12.2" clip-path="url(#terminal-243650528-line-69)">)</text><text class="terminal-243650528-r1" x="976" y="1703.6" textLength="12.2" clip-path="url(#terminal-243650528-line-69)"> -</text><text class="terminal-243650528-r1" x="0" y="1728" textLength="280.6" clip-path="url(#terminal-243650528-line-70)">  --file-name FILE_NAME</text><text class="terminal-243650528-r1" x="976" y="1728" textLength="12.2" clip-path="url(#terminal-243650528-line-70)"> -</text><text class="terminal-243650528-r1" x="0" y="1752.4" textLength="573.4" clip-path="url(#terminal-243650528-line-71)">                        file name of changelog </text><text class="terminal-243650528-r2" x="573.4" y="1752.4" textLength="12.2" clip-path="url(#terminal-243650528-line-71)">(</text><text class="terminal-243650528-r1" x="585.6" y="1752.4" textLength="109.8" clip-path="url(#terminal-243650528-line-71)">default: </text><text class="terminal-243650528-r4" x="695.4" y="1752.4" textLength="170.8" clip-path="url(#terminal-243650528-line-71)">'CHANGELOG.md'</text><text class="terminal-243650528-r2" x="866.2" y="1752.4" textLength="12.2" clip-path="url(#terminal-243650528-line-71)">)</text><text class="terminal-243650528-r1" x="976" y="1752.4" textLength="12.2" clip-path="url(#terminal-243650528-line-71)"> -</text><text class="terminal-243650528-r1" x="0" y="1776.8" textLength="475.8" clip-path="url(#terminal-243650528-line-72)">  --prerelease-offset PRERELEASE_OFFSET</text><text class="terminal-243650528-r1" x="976" y="1776.8" textLength="12.2" clip-path="url(#terminal-243650528-line-72)"> -</text><text class="terminal-243650528-r1" x="0" y="1801.2" textLength="719.8" clip-path="url(#terminal-243650528-line-73)">                        start pre-releases with this offset</text><text class="terminal-243650528-r1" x="976" y="1801.2" textLength="12.2" clip-path="url(#terminal-243650528-line-73)"> -</text><text class="terminal-243650528-r1" x="0" y="1825.6" textLength="231.8" clip-path="url(#terminal-243650528-line-74)">  --version-scheme </text><text class="terminal-243650528-r2" x="231.8" y="1825.6" textLength="12.2" clip-path="url(#terminal-243650528-line-74)">{</text><text class="terminal-243650528-r1" x="244" y="1825.6" textLength="256.2" clip-path="url(#terminal-243650528-line-74)">pep440,semver,semver2</text><text class="terminal-243650528-r2" x="500.2" y="1825.6" textLength="12.2" clip-path="url(#terminal-243650528-line-74)">}</text><text class="terminal-243650528-r1" x="976" y="1825.6" textLength="12.2" clip-path="url(#terminal-243650528-line-74)"> -</text><text class="terminal-243650528-r1" x="0" y="1850" textLength="549" clip-path="url(#terminal-243650528-line-75)">                        choose version scheme</text><text class="terminal-243650528-r1" x="976" y="1850" textLength="12.2" clip-path="url(#terminal-243650528-line-75)"> -</text><text class="terminal-243650528-r1" x="0" y="1874.4" textLength="207.4" clip-path="url(#terminal-243650528-line-76)">  --version-type </text><text class="terminal-243650528-r2" x="207.4" y="1874.4" textLength="12.2" clip-path="url(#terminal-243650528-line-76)">{</text><text class="terminal-243650528-r1" x="219.6" y="1874.4" textLength="256.2" clip-path="url(#terminal-243650528-line-76)">pep440,semver,semver2</text><text class="terminal-243650528-r2" x="475.8" y="1874.4" textLength="12.2" clip-path="url(#terminal-243650528-line-76)">}</text><text class="terminal-243650528-r1" x="976" y="1874.4" textLength="12.2" clip-path="url(#terminal-243650528-line-76)"> -</text><text class="terminal-243650528-r1" x="0" y="1898.8" textLength="683.2" clip-path="url(#terminal-243650528-line-77)">                        Deprecated, use --version-scheme</text><text class="terminal-243650528-r1" x="976" y="1898.8" textLength="12.2" clip-path="url(#terminal-243650528-line-77)"> -</text><text class="terminal-243650528-r1" x="0" y="1923.2" textLength="402.6" clip-path="url(#terminal-243650528-line-78)">  --build-metadata BUILD_METADATA</text><text class="terminal-243650528-r1" x="976" y="1923.2" textLength="12.2" clip-path="url(#terminal-243650528-line-78)"> -</text><text class="terminal-243650528-r1" x="0" y="1947.6" textLength="915" clip-path="url(#terminal-243650528-line-79)">                        Add additional build-metadata to the version-number</text><text class="terminal-243650528-r1" x="976" y="1947.6" textLength="12.2" clip-path="url(#terminal-243650528-line-79)"> -</text><text class="terminal-243650528-r1" x="0" y="1972" textLength="854" clip-path="url(#terminal-243650528-line-80)">  --get-next            Determine the next version and write to stdout</text><text class="terminal-243650528-r1" x="976" y="1972" textLength="12.2" clip-path="url(#terminal-243650528-line-80)"> -</text><text class="terminal-243650528-r1" x="0" y="1996.4" textLength="744.2" clip-path="url(#terminal-243650528-line-81)">  --allow-no-commit     bump version without eligible commits</text><text class="terminal-243650528-r1" x="976" y="1996.4" textLength="12.2" clip-path="url(#terminal-243650528-line-81)"> -</text><text class="terminal-243650528-r1" x="976" y="2020.8" textLength="12.2" clip-path="url(#terminal-243650528-line-82)"> + <g class="terminal-1655558888-matrix"> + <text class="terminal-1655558888-r1" x="0" y="20" textLength="195.2" clip-path="url(#terminal-1655558888-line-0)">$ cz bump --help</text><text class="terminal-1655558888-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-1655558888-line-0)"> +</text><text class="terminal-1655558888-r1" x="0" y="44.4" textLength="183" clip-path="url(#terminal-1655558888-line-1)">usage: cz bump </text><text class="terminal-1655558888-r2" x="183" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">[</text><text class="terminal-1655558888-r1" x="195.2" y="44.4" textLength="24.4" clip-path="url(#terminal-1655558888-line-1)">-h</text><text class="terminal-1655558888-r2" x="219.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">]</text><text class="terminal-1655558888-r2" x="244" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">[</text><text class="terminal-1655558888-r1" x="256.2" y="44.4" textLength="109.8" clip-path="url(#terminal-1655558888-line-1)">--dry-run</text><text class="terminal-1655558888-r2" x="366" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">]</text><text class="terminal-1655558888-r2" x="390.4" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">[</text><text class="terminal-1655558888-r1" x="402.6" y="44.4" textLength="146.4" clip-path="url(#terminal-1655558888-line-1)">--files-only</text><text class="terminal-1655558888-r2" x="549" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">]</text><text class="terminal-1655558888-r2" x="573.4" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">[</text><text class="terminal-1655558888-r1" x="585.6" y="44.4" textLength="183" clip-path="url(#terminal-1655558888-line-1)">--local-version</text><text class="terminal-1655558888-r2" x="768.6" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">]</text><text class="terminal-1655558888-r2" x="793" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">[</text><text class="terminal-1655558888-r1" x="805.2" y="44.4" textLength="134.2" clip-path="url(#terminal-1655558888-line-1)">--changelog</text><text class="terminal-1655558888-r2" x="939.4" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)">]</text><text class="terminal-1655558888-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-1)"> +</text><text class="terminal-1655558888-r2" x="183" y="68.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-2)">[</text><text class="terminal-1655558888-r1" x="195.2" y="68.8" textLength="134.2" clip-path="url(#terminal-1655558888-line-2)">--no-verify</text><text class="terminal-1655558888-r2" x="329.4" y="68.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-2)">]</text><text class="terminal-1655558888-r2" x="353.8" y="68.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-2)">[</text><text class="terminal-1655558888-r1" x="366" y="68.8" textLength="61" clip-path="url(#terminal-1655558888-line-2)">--yes</text><text class="terminal-1655558888-r2" x="427" y="68.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-2)">]</text><text class="terminal-1655558888-r2" x="451.4" y="68.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-2)">[</text><text class="terminal-1655558888-r1" x="463.6" y="68.8" textLength="280.6" clip-path="url(#terminal-1655558888-line-2)">--tag-format TAG_FORMAT</text><text class="terminal-1655558888-r2" x="744.2" y="68.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-2)">]</text><text class="terminal-1655558888-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-2)"> +</text><text class="terminal-1655558888-r2" x="183" y="93.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-3)">[</text><text class="terminal-1655558888-r1" x="195.2" y="93.2" textLength="329.4" clip-path="url(#terminal-1655558888-line-3)">--bump-message BUMP_MESSAGE</text><text class="terminal-1655558888-r2" x="524.6" y="93.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-3)">]</text><text class="terminal-1655558888-r2" x="549" y="93.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-3)">[</text><text class="terminal-1655558888-r1" x="561.2" y="93.2" textLength="158.6" clip-path="url(#terminal-1655558888-line-3)">--prerelease </text><text class="terminal-1655558888-r2" x="719.8" y="93.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-3)">{</text><text class="terminal-1655558888-r1" x="732" y="93.2" textLength="158.6" clip-path="url(#terminal-1655558888-line-3)">alpha,beta,rc</text><text class="terminal-1655558888-r2" x="890.6" y="93.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-3)">}</text><text class="terminal-1655558888-r2" x="902.8" y="93.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-3)">]</text><text class="terminal-1655558888-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-3)"> +</text><text class="terminal-1655558888-r2" x="183" y="117.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-4)">[</text><text class="terminal-1655558888-r1" x="195.2" y="117.6" textLength="280.6" clip-path="url(#terminal-1655558888-line-4)">--devrelease DEVRELEASE</text><text class="terminal-1655558888-r2" x="475.8" y="117.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-4)">]</text><text class="terminal-1655558888-r2" x="500.2" y="117.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-4)">[</text><text class="terminal-1655558888-r1" x="512.4" y="117.6" textLength="146.4" clip-path="url(#terminal-1655558888-line-4)">--increment </text><text class="terminal-1655558888-r2" x="658.8" y="117.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-4)">{</text><text class="terminal-1655558888-r1" x="671" y="117.6" textLength="207.4" clip-path="url(#terminal-1655558888-line-4)">MAJOR,MINOR,PATCH</text><text class="terminal-1655558888-r2" x="878.4" y="117.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-4)">}</text><text class="terminal-1655558888-r2" x="890.6" y="117.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-4)">]</text><text class="terminal-1655558888-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-4)"> +</text><text class="terminal-1655558888-r2" x="183" y="142" textLength="12.2" clip-path="url(#terminal-1655558888-line-5)">[</text><text class="terminal-1655558888-r1" x="195.2" y="142" textLength="207.4" clip-path="url(#terminal-1655558888-line-5)">--increment-mode </text><text class="terminal-1655558888-r2" x="402.6" y="142" textLength="12.2" clip-path="url(#terminal-1655558888-line-5)">{</text><text class="terminal-1655558888-r1" x="414.8" y="142" textLength="146.4" clip-path="url(#terminal-1655558888-line-5)">linear,exact</text><text class="terminal-1655558888-r2" x="561.2" y="142" textLength="12.2" clip-path="url(#terminal-1655558888-line-5)">}</text><text class="terminal-1655558888-r2" x="573.4" y="142" textLength="12.2" clip-path="url(#terminal-1655558888-line-5)">]</text><text class="terminal-1655558888-r2" x="597.8" y="142" textLength="12.2" clip-path="url(#terminal-1655558888-line-5)">[</text><text class="terminal-1655558888-r1" x="610" y="142" textLength="231.8" clip-path="url(#terminal-1655558888-line-5)">--check-consistency</text><text class="terminal-1655558888-r2" x="841.8" y="142" textLength="12.2" clip-path="url(#terminal-1655558888-line-5)">]</text><text class="terminal-1655558888-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-1655558888-line-5)"> +</text><text class="terminal-1655558888-r2" x="183" y="166.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-6)">[</text><text class="terminal-1655558888-r1" x="195.2" y="166.4" textLength="183" clip-path="url(#terminal-1655558888-line-6)">--annotated-tag</text><text class="terminal-1655558888-r2" x="378.2" y="166.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-6)">]</text><text class="terminal-1655558888-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-6)"> +</text><text class="terminal-1655558888-r2" x="183" y="190.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-7)">[</text><text class="terminal-1655558888-r1" x="195.2" y="190.8" textLength="549" clip-path="url(#terminal-1655558888-line-7)">--annotated-tag-message ANNOTATED_TAG_MESSAGE</text><text class="terminal-1655558888-r2" x="744.2" y="190.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-7)">]</text><text class="terminal-1655558888-r2" x="768.6" y="190.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-7)">[</text><text class="terminal-1655558888-r1" x="780.8" y="190.8" textLength="122" clip-path="url(#terminal-1655558888-line-7)">--gpg-sign</text><text class="terminal-1655558888-r2" x="902.8" y="190.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-7)">]</text><text class="terminal-1655558888-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-7)"> +</text><text class="terminal-1655558888-r2" x="183" y="215.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-8)">[</text><text class="terminal-1655558888-r1" x="195.2" y="215.2" textLength="256.2" clip-path="url(#terminal-1655558888-line-8)">--changelog-to-stdout</text><text class="terminal-1655558888-r2" x="451.4" y="215.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-8)">]</text><text class="terminal-1655558888-r2" x="475.8" y="215.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-8)">[</text><text class="terminal-1655558888-r1" x="488" y="215.2" textLength="268.4" clip-path="url(#terminal-1655558888-line-8)">--git-output-to-stderr</text><text class="terminal-1655558888-r2" x="756.4" y="215.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-8)">]</text><text class="terminal-1655558888-r2" x="780.8" y="215.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-8)">[</text><text class="terminal-1655558888-r1" x="793" y="215.2" textLength="85.4" clip-path="url(#terminal-1655558888-line-8)">--retry</text><text class="terminal-1655558888-r2" x="878.4" y="215.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-8)">]</text><text class="terminal-1655558888-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-8)"> +</text><text class="terminal-1655558888-r2" x="183" y="239.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-9)">[</text><text class="terminal-1655558888-r1" x="195.2" y="239.6" textLength="244" clip-path="url(#terminal-1655558888-line-9)">--major-version-zero</text><text class="terminal-1655558888-r2" x="439.2" y="239.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-9)">]</text><text class="terminal-1655558888-r2" x="463.6" y="239.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-9)">[</text><text class="terminal-1655558888-r1" x="475.8" y="239.6" textLength="231.8" clip-path="url(#terminal-1655558888-line-9)">--template TEMPLATE</text><text class="terminal-1655558888-r2" x="707.6" y="239.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-9)">]</text><text class="terminal-1655558888-r2" x="732" y="239.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-9)">[</text><text class="terminal-1655558888-r1" x="744.2" y="239.6" textLength="158.6" clip-path="url(#terminal-1655558888-line-9)">--extra EXTRA</text><text class="terminal-1655558888-r2" x="902.8" y="239.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-9)">]</text><text class="terminal-1655558888-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-9)"> +</text><text class="terminal-1655558888-r2" x="183" y="264" textLength="12.2" clip-path="url(#terminal-1655558888-line-10)">[</text><text class="terminal-1655558888-r1" x="195.2" y="264" textLength="256.2" clip-path="url(#terminal-1655558888-line-10)">--file-name FILE_NAME</text><text class="terminal-1655558888-r2" x="451.4" y="264" textLength="12.2" clip-path="url(#terminal-1655558888-line-10)">]</text><text class="terminal-1655558888-r2" x="475.8" y="264" textLength="12.2" clip-path="url(#terminal-1655558888-line-10)">[</text><text class="terminal-1655558888-r1" x="488" y="264" textLength="451.4" clip-path="url(#terminal-1655558888-line-10)">--prerelease-offset PRERELEASE_OFFSET</text><text class="terminal-1655558888-r2" x="939.4" y="264" textLength="12.2" clip-path="url(#terminal-1655558888-line-10)">]</text><text class="terminal-1655558888-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-1655558888-line-10)"> +</text><text class="terminal-1655558888-r2" x="183" y="288.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-11)">[</text><text class="terminal-1655558888-r1" x="195.2" y="288.4" textLength="207.4" clip-path="url(#terminal-1655558888-line-11)">--version-scheme </text><text class="terminal-1655558888-r2" x="402.6" y="288.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-11)">{</text><text class="terminal-1655558888-r1" x="414.8" y="288.4" textLength="256.2" clip-path="url(#terminal-1655558888-line-11)">pep440,semver,semver2</text><text class="terminal-1655558888-r2" x="671" y="288.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-11)">}</text><text class="terminal-1655558888-r2" x="683.2" y="288.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-11)">]</text><text class="terminal-1655558888-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-11)"> +</text><text class="terminal-1655558888-r2" x="183" y="312.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-12)">[</text><text class="terminal-1655558888-r1" x="195.2" y="312.8" textLength="183" clip-path="url(#terminal-1655558888-line-12)">--version-type </text><text class="terminal-1655558888-r2" x="378.2" y="312.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-12)">{</text><text class="terminal-1655558888-r1" x="390.4" y="312.8" textLength="256.2" clip-path="url(#terminal-1655558888-line-12)">pep440,semver,semver2</text><text class="terminal-1655558888-r2" x="646.6" y="312.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-12)">}</text><text class="terminal-1655558888-r2" x="658.8" y="312.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-12)">]</text><text class="terminal-1655558888-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-12)"> +</text><text class="terminal-1655558888-r2" x="183" y="337.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-13)">[</text><text class="terminal-1655558888-r1" x="195.2" y="337.2" textLength="378.2" clip-path="url(#terminal-1655558888-line-13)">--build-metadata BUILD_METADATA</text><text class="terminal-1655558888-r2" x="573.4" y="337.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-13)">]</text><text class="terminal-1655558888-r2" x="597.8" y="337.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-13)">[</text><text class="terminal-1655558888-r1" x="610" y="337.2" textLength="122" clip-path="url(#terminal-1655558888-line-13)">--get-next</text><text class="terminal-1655558888-r2" x="732" y="337.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-13)">]</text><text class="terminal-1655558888-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-13)"> +</text><text class="terminal-1655558888-r2" x="183" y="361.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-14)">[</text><text class="terminal-1655558888-r1" x="195.2" y="361.6" textLength="207.4" clip-path="url(#terminal-1655558888-line-14)">--allow-no-commit</text><text class="terminal-1655558888-r2" x="402.6" y="361.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-14)">]</text><text class="terminal-1655558888-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-14)"> +</text><text class="terminal-1655558888-r2" x="183" y="386" textLength="12.2" clip-path="url(#terminal-1655558888-line-15)">[</text><text class="terminal-1655558888-r1" x="195.2" y="386" textLength="170.8" clip-path="url(#terminal-1655558888-line-15)">MANUAL_VERSION</text><text class="terminal-1655558888-r2" x="366" y="386" textLength="12.2" clip-path="url(#terminal-1655558888-line-15)">]</text><text class="terminal-1655558888-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-1655558888-line-15)"> +</text><text class="terminal-1655558888-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-16)"> +</text><text class="terminal-1655558888-r1" x="0" y="434.8" textLength="512.4" clip-path="url(#terminal-1655558888-line-17)">bump semantic version based on the git log</text><text class="terminal-1655558888-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-17)"> +</text><text class="terminal-1655558888-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-18)"> +</text><text class="terminal-1655558888-r1" x="0" y="483.6" textLength="256.2" clip-path="url(#terminal-1655558888-line-19)">positional arguments:</text><text class="terminal-1655558888-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-19)"> +</text><text class="terminal-1655558888-r1" x="0" y="508" textLength="610" clip-path="url(#terminal-1655558888-line-20)">  MANUAL_VERSION        bump to the given version </text><text class="terminal-1655558888-r2" x="610" y="508" textLength="12.2" clip-path="url(#terminal-1655558888-line-20)">(</text><text class="terminal-1655558888-r1" x="622.2" y="508" textLength="61" clip-path="url(#terminal-1655558888-line-20)">e.g: </text><text class="terminal-1655558888-r3" x="683.2" y="508" textLength="36.6" clip-path="url(#terminal-1655558888-line-20)">1.5</text><text class="terminal-1655558888-r1" x="719.8" y="508" textLength="12.2" clip-path="url(#terminal-1655558888-line-20)">.</text><text class="terminal-1655558888-r3" x="732" y="508" textLength="12.2" clip-path="url(#terminal-1655558888-line-20)">3</text><text class="terminal-1655558888-r2" x="744.2" y="508" textLength="12.2" clip-path="url(#terminal-1655558888-line-20)">)</text><text class="terminal-1655558888-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-1655558888-line-20)"> +</text><text class="terminal-1655558888-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-21)"> +</text><text class="terminal-1655558888-r1" x="0" y="556.8" textLength="97.6" clip-path="url(#terminal-1655558888-line-22)">options:</text><text class="terminal-1655558888-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-22)"> +</text><text class="terminal-1655558888-r1" x="0" y="581.2" textLength="671" clip-path="url(#terminal-1655558888-line-23)">  -h, --help            show this help message and exit</text><text class="terminal-1655558888-r1" x="976" y="581.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-23)"> +</text><text class="terminal-1655558888-r1" x="0" y="605.6" textLength="915" clip-path="url(#terminal-1655558888-line-24)">  --dry-run             show output to stdout, no commit, no modified files</text><text class="terminal-1655558888-r1" x="976" y="605.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-24)"> +</text><text class="terminal-1655558888-r1" x="0" y="630" textLength="793" clip-path="url(#terminal-1655558888-line-25)">  --files-only          bump version in the files from the config</text><text class="terminal-1655558888-r1" x="976" y="630" textLength="12.2" clip-path="url(#terminal-1655558888-line-25)"> +</text><text class="terminal-1655558888-r1" x="0" y="654.4" textLength="719.8" clip-path="url(#terminal-1655558888-line-26)">  --local-version       bump only the local version portion</text><text class="terminal-1655558888-r1" x="976" y="654.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-26)"> +</text><text class="terminal-1655558888-r1" x="0" y="678.8" textLength="841.8" clip-path="url(#terminal-1655558888-line-27)">  --changelog, -ch      generate the changelog for the newest version</text><text class="terminal-1655558888-r1" x="976" y="678.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-27)"> +</text><text class="terminal-1655558888-r1" x="0" y="703.2" textLength="902.8" clip-path="url(#terminal-1655558888-line-28)">  --no-verify           this option bypasses the pre-commit and commit-msg</text><text class="terminal-1655558888-r1" x="976" y="703.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-28)"> +</text><text class="terminal-1655558888-r1" x="0" y="727.6" textLength="353.8" clip-path="url(#terminal-1655558888-line-29)">                        hooks</text><text class="terminal-1655558888-r1" x="976" y="727.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-29)"> +</text><text class="terminal-1655558888-r1" x="0" y="752" textLength="719.8" clip-path="url(#terminal-1655558888-line-30)">  --yes                 accept automatically questions done</text><text class="terminal-1655558888-r1" x="976" y="752" textLength="12.2" clip-path="url(#terminal-1655558888-line-30)"> +</text><text class="terminal-1655558888-r1" x="0" y="776.4" textLength="305" clip-path="url(#terminal-1655558888-line-31)">  --tag-format TAG_FORMAT</text><text class="terminal-1655558888-r1" x="976" y="776.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-31)"> +</text><text class="terminal-1655558888-r1" x="0" y="800.8" textLength="939.4" clip-path="url(#terminal-1655558888-line-32)">                        the format used to tag the commit and read it, use it</text><text class="terminal-1655558888-r1" x="976" y="800.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-32)"> +</text><text class="terminal-1655558888-r1" x="0" y="825.2" textLength="866.2" clip-path="url(#terminal-1655558888-line-33)">                        in existing projects, wrap around simple quotes</text><text class="terminal-1655558888-r1" x="976" y="825.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-33)"> +</text><text class="terminal-1655558888-r1" x="0" y="849.6" textLength="353.8" clip-path="url(#terminal-1655558888-line-34)">  --bump-message BUMP_MESSAGE</text><text class="terminal-1655558888-r1" x="976" y="849.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-34)"> +</text><text class="terminal-1655558888-r1" x="0" y="874" textLength="902.8" clip-path="url(#terminal-1655558888-line-35)">                        template used to create the release commit, useful</text><text class="terminal-1655558888-r1" x="976" y="874" textLength="12.2" clip-path="url(#terminal-1655558888-line-35)"> +</text><text class="terminal-1655558888-r1" x="0" y="898.4" textLength="536.8" clip-path="url(#terminal-1655558888-line-36)">                        when working with CI</text><text class="terminal-1655558888-r1" x="976" y="898.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-36)"> +</text><text class="terminal-1655558888-r1" x="0" y="922.8" textLength="244" clip-path="url(#terminal-1655558888-line-37)">  --prerelease, -pr </text><text class="terminal-1655558888-r2" x="244" y="922.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-37)">{</text><text class="terminal-1655558888-r1" x="256.2" y="922.8" textLength="158.6" clip-path="url(#terminal-1655558888-line-37)">alpha,beta,rc</text><text class="terminal-1655558888-r2" x="414.8" y="922.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-37)">}</text><text class="terminal-1655558888-r1" x="976" y="922.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-37)"> +</text><text class="terminal-1655558888-r1" x="0" y="947.2" textLength="597.8" clip-path="url(#terminal-1655558888-line-38)">                        choose type of prerelease</text><text class="terminal-1655558888-r1" x="976" y="947.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-38)"> +</text><text class="terminal-1655558888-r1" x="0" y="971.6" textLength="353.8" clip-path="url(#terminal-1655558888-line-39)">  --devrelease, -d DEVRELEASE</text><text class="terminal-1655558888-r1" x="976" y="971.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-39)"> +</text><text class="terminal-1655558888-r1" x="0" y="996" textLength="841.8" clip-path="url(#terminal-1655558888-line-40)">                        specify non-negative integer for dev. release</text><text class="terminal-1655558888-r1" x="976" y="996" textLength="12.2" clip-path="url(#terminal-1655558888-line-40)"> +</text><text class="terminal-1655558888-r1" x="0" y="1020.4" textLength="170.8" clip-path="url(#terminal-1655558888-line-41)">  --increment </text><text class="terminal-1655558888-r2" x="170.8" y="1020.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-41)">{</text><text class="terminal-1655558888-r1" x="183" y="1020.4" textLength="207.4" clip-path="url(#terminal-1655558888-line-41)">MAJOR,MINOR,PATCH</text><text class="terminal-1655558888-r2" x="390.4" y="1020.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-41)">}</text><text class="terminal-1655558888-r1" x="976" y="1020.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-41)"> +</text><text class="terminal-1655558888-r1" x="0" y="1044.8" textLength="756.4" clip-path="url(#terminal-1655558888-line-42)">                        manually specify the desired increment</text><text class="terminal-1655558888-r1" x="976" y="1044.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-42)"> +</text><text class="terminal-1655558888-r1" x="0" y="1069.2" textLength="231.8" clip-path="url(#terminal-1655558888-line-43)">  --increment-mode </text><text class="terminal-1655558888-r2" x="231.8" y="1069.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-43)">{</text><text class="terminal-1655558888-r1" x="244" y="1069.2" textLength="146.4" clip-path="url(#terminal-1655558888-line-43)">linear,exact</text><text class="terminal-1655558888-r2" x="390.4" y="1069.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-43)">}</text><text class="terminal-1655558888-r1" x="976" y="1069.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-43)"> +</text><text class="terminal-1655558888-r1" x="0" y="1093.6" textLength="902.8" clip-path="url(#terminal-1655558888-line-44)">                        set the method by which the new version is chosen.</text><text class="terminal-1655558888-r1" x="976" y="1093.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-44)"> +</text><text class="terminal-1655558888-r4" x="292.8" y="1118" textLength="97.6" clip-path="url(#terminal-1655558888-line-45)">'linear'</text><text class="terminal-1655558888-r2" x="402.6" y="1118" textLength="12.2" clip-path="url(#terminal-1655558888-line-45)">(</text><text class="terminal-1655558888-r1" x="414.8" y="1118" textLength="85.4" clip-path="url(#terminal-1655558888-line-45)">default</text><text class="terminal-1655558888-r2" x="500.2" y="1118" textLength="12.2" clip-path="url(#terminal-1655558888-line-45)">)</text><text class="terminal-1655558888-r1" x="512.4" y="1118" textLength="414.8" clip-path="url(#terminal-1655558888-line-45)"> guesses the next version based on</text><text class="terminal-1655558888-r1" x="976" y="1118" textLength="12.2" clip-path="url(#terminal-1655558888-line-45)"> +</text><text class="terminal-1655558888-r1" x="0" y="1142.4" textLength="939.4" clip-path="url(#terminal-1655558888-line-46)">                        typical linear version progression, such that bumping</text><text class="terminal-1655558888-r1" x="976" y="1142.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-46)"> +</text><text class="terminal-1655558888-r1" x="0" y="1166.8" textLength="866.2" clip-path="url(#terminal-1655558888-line-47)">                        of a pre-release with lower precedence than the</text><text class="terminal-1655558888-r1" x="976" y="1166.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-47)"> +</text><text class="terminal-1655558888-r1" x="0" y="1191.2" textLength="939.4" clip-path="url(#terminal-1655558888-line-48)">                        current pre-release phase maintains the current phase</text><text class="terminal-1655558888-r1" x="976" y="1191.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-48)"> +</text><text class="terminal-1655558888-r1" x="0" y="1215.6" textLength="561.2" clip-path="url(#terminal-1655558888-line-49)">                        of higher precedence. </text><text class="terminal-1655558888-r4" x="561.2" y="1215.6" textLength="85.4" clip-path="url(#terminal-1655558888-line-49)">'exact'</text><text class="terminal-1655558888-r1" x="646.6" y="1215.6" textLength="305" clip-path="url(#terminal-1655558888-line-49)"> applies the changes that</text><text class="terminal-1655558888-r1" x="976" y="1215.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-49)"> +</text><text class="terminal-1655558888-r1" x="0" y="1240" textLength="536.8" clip-path="url(#terminal-1655558888-line-50)">                        have been specified </text><text class="terminal-1655558888-r2" x="536.8" y="1240" textLength="12.2" clip-path="url(#terminal-1655558888-line-50)">(</text><text class="terminal-1655558888-r1" x="549" y="1240" textLength="353.8" clip-path="url(#terminal-1655558888-line-50)">or determined from the commit</text><text class="terminal-1655558888-r1" x="976" y="1240" textLength="12.2" clip-path="url(#terminal-1655558888-line-50)"> +</text><text class="terminal-1655558888-r1" x="0" y="1264.4" textLength="329.4" clip-path="url(#terminal-1655558888-line-51)">                        log</text><text class="terminal-1655558888-r2" x="329.4" y="1264.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-51)">)</text><text class="terminal-1655558888-r1" x="341.6" y="1264.4" textLength="585.6" clip-path="url(#terminal-1655558888-line-51)"> without interpretation, such that the increment</text><text class="terminal-1655558888-r1" x="976" y="1264.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-51)"> +</text><text class="terminal-1655558888-r1" x="0" y="1288.8" textLength="707.6" clip-path="url(#terminal-1655558888-line-52)">                        and pre-release are always honored</text><text class="terminal-1655558888-r1" x="976" y="1288.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-52)"> +</text><text class="terminal-1655558888-r1" x="0" y="1313.2" textLength="317.2" clip-path="url(#terminal-1655558888-line-53)">  --check-consistency, -cc</text><text class="terminal-1655558888-r1" x="976" y="1313.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-53)"> +</text><text class="terminal-1655558888-r1" x="0" y="1337.6" textLength="951.6" clip-path="url(#terminal-1655558888-line-54)">                        check consistency among versions defined in commitizen</text><text class="terminal-1655558888-r1" x="976" y="1337.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-54)"> +</text><text class="terminal-1655558888-r1" x="0" y="1362" textLength="671" clip-path="url(#terminal-1655558888-line-55)">                        configuration and version_files</text><text class="terminal-1655558888-r1" x="976" y="1362" textLength="12.2" clip-path="url(#terminal-1655558888-line-55)"> +</text><text class="terminal-1655558888-r1" x="0" y="1386.4" textLength="866.2" clip-path="url(#terminal-1655558888-line-56)">  --annotated-tag, -at  create annotated tag instead of lightweight one</text><text class="terminal-1655558888-r1" x="976" y="1386.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-56)"> +</text><text class="terminal-1655558888-r1" x="0" y="1410.8" textLength="646.6" clip-path="url(#terminal-1655558888-line-57)">  --annotated-tag-message, -atm ANNOTATED_TAG_MESSAGE</text><text class="terminal-1655558888-r1" x="976" y="1410.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-57)"> +</text><text class="terminal-1655558888-r1" x="0" y="1435.2" textLength="634.4" clip-path="url(#terminal-1655558888-line-58)">                        create annotated tag message</text><text class="terminal-1655558888-r1" x="976" y="1435.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-58)"> +</text><text class="terminal-1655558888-r1" x="0" y="1459.6" textLength="719.8" clip-path="url(#terminal-1655558888-line-59)">  --gpg-sign, -s        sign tag instead of lightweight one</text><text class="terminal-1655558888-r1" x="976" y="1459.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-59)"> +</text><text class="terminal-1655558888-r1" x="0" y="1484" textLength="280.6" clip-path="url(#terminal-1655558888-line-60)">  --changelog-to-stdout</text><text class="terminal-1655558888-r1" x="976" y="1484" textLength="12.2" clip-path="url(#terminal-1655558888-line-60)"> +</text><text class="terminal-1655558888-r1" x="0" y="1508.4" textLength="658.8" clip-path="url(#terminal-1655558888-line-61)">                        Output changelog to the stdout</text><text class="terminal-1655558888-r1" x="976" y="1508.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-61)"> +</text><text class="terminal-1655558888-r1" x="0" y="1532.8" textLength="292.8" clip-path="url(#terminal-1655558888-line-62)">  --git-output-to-stderr</text><text class="terminal-1655558888-r1" x="976" y="1532.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-62)"> +</text><text class="terminal-1655558888-r1" x="0" y="1557.2" textLength="646.6" clip-path="url(#terminal-1655558888-line-63)">                        Redirect git output to stderr</text><text class="terminal-1655558888-r1" x="976" y="1557.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-63)"> +</text><text class="terminal-1655558888-r1" x="0" y="1581.6" textLength="744.2" clip-path="url(#terminal-1655558888-line-64)">  --retry               retry commit if it fails the 1st time</text><text class="terminal-1655558888-r1" x="976" y="1581.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-64)"> +</text><text class="terminal-1655558888-r1" x="0" y="1606" textLength="939.4" clip-path="url(#terminal-1655558888-line-65)">  --major-version-zero  keep major version at zero, even for breaking changes</text><text class="terminal-1655558888-r1" x="976" y="1606" textLength="12.2" clip-path="url(#terminal-1655558888-line-65)"> +</text><text class="terminal-1655558888-r1" x="0" y="1630.4" textLength="305" clip-path="url(#terminal-1655558888-line-66)">  --template, -t TEMPLATE</text><text class="terminal-1655558888-r1" x="976" y="1630.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-66)"> +</text><text class="terminal-1655558888-r1" x="0" y="1654.8" textLength="646.6" clip-path="url(#terminal-1655558888-line-67)">                        changelog template file name </text><text class="terminal-1655558888-r2" x="646.6" y="1654.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-67)">(</text><text class="terminal-1655558888-r1" x="658.8" y="1654.8" textLength="280.6" clip-path="url(#terminal-1655558888-line-67)">relative to the current</text><text class="terminal-1655558888-r1" x="976" y="1654.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-67)"> +</text><text class="terminal-1655558888-r1" x="0" y="1679.2" textLength="500.2" clip-path="url(#terminal-1655558888-line-68)">                        working directory</text><text class="terminal-1655558888-r2" x="500.2" y="1679.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-68)">)</text><text class="terminal-1655558888-r1" x="976" y="1679.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-68)"> +</text><text class="terminal-1655558888-r1" x="0" y="1703.6" textLength="622.2" clip-path="url(#terminal-1655558888-line-69)">  --extra, -e EXTRA     a changelog extra variable </text><text class="terminal-1655558888-r2" x="622.2" y="1703.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-69)">(</text><text class="terminal-1655558888-r1" x="634.4" y="1703.6" textLength="146.4" clip-path="url(#terminal-1655558888-line-69)">in the form </text><text class="terminal-1655558888-r4" x="780.8" y="1703.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-69)">'</text><text class="terminal-1655558888-r4" x="793" y="1703.6" textLength="36.6" clip-path="url(#terminal-1655558888-line-69)">key</text><text class="terminal-1655558888-r4" x="829.6" y="1703.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-69)">=</text><text class="terminal-1655558888-r4" x="841.8" y="1703.6" textLength="61" clip-path="url(#terminal-1655558888-line-69)">value</text><text class="terminal-1655558888-r4" x="902.8" y="1703.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-69)">'</text><text class="terminal-1655558888-r2" x="915" y="1703.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-69)">)</text><text class="terminal-1655558888-r1" x="976" y="1703.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-69)"> +</text><text class="terminal-1655558888-r1" x="0" y="1728" textLength="280.6" clip-path="url(#terminal-1655558888-line-70)">  --file-name FILE_NAME</text><text class="terminal-1655558888-r1" x="976" y="1728" textLength="12.2" clip-path="url(#terminal-1655558888-line-70)"> +</text><text class="terminal-1655558888-r1" x="0" y="1752.4" textLength="573.4" clip-path="url(#terminal-1655558888-line-71)">                        file name of changelog </text><text class="terminal-1655558888-r2" x="573.4" y="1752.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-71)">(</text><text class="terminal-1655558888-r1" x="585.6" y="1752.4" textLength="109.8" clip-path="url(#terminal-1655558888-line-71)">default: </text><text class="terminal-1655558888-r4" x="695.4" y="1752.4" textLength="170.8" clip-path="url(#terminal-1655558888-line-71)">'CHANGELOG.md'</text><text class="terminal-1655558888-r2" x="866.2" y="1752.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-71)">)</text><text class="terminal-1655558888-r1" x="976" y="1752.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-71)"> +</text><text class="terminal-1655558888-r1" x="0" y="1776.8" textLength="475.8" clip-path="url(#terminal-1655558888-line-72)">  --prerelease-offset PRERELEASE_OFFSET</text><text class="terminal-1655558888-r1" x="976" y="1776.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-72)"> +</text><text class="terminal-1655558888-r1" x="0" y="1801.2" textLength="719.8" clip-path="url(#terminal-1655558888-line-73)">                        start pre-releases with this offset</text><text class="terminal-1655558888-r1" x="976" y="1801.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-73)"> +</text><text class="terminal-1655558888-r1" x="0" y="1825.6" textLength="231.8" clip-path="url(#terminal-1655558888-line-74)">  --version-scheme </text><text class="terminal-1655558888-r2" x="231.8" y="1825.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-74)">{</text><text class="terminal-1655558888-r1" x="244" y="1825.6" textLength="256.2" clip-path="url(#terminal-1655558888-line-74)">pep440,semver,semver2</text><text class="terminal-1655558888-r2" x="500.2" y="1825.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-74)">}</text><text class="terminal-1655558888-r1" x="976" y="1825.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-74)"> +</text><text class="terminal-1655558888-r1" x="0" y="1850" textLength="549" clip-path="url(#terminal-1655558888-line-75)">                        choose version scheme</text><text class="terminal-1655558888-r1" x="976" y="1850" textLength="12.2" clip-path="url(#terminal-1655558888-line-75)"> +</text><text class="terminal-1655558888-r1" x="0" y="1874.4" textLength="207.4" clip-path="url(#terminal-1655558888-line-76)">  --version-type </text><text class="terminal-1655558888-r2" x="207.4" y="1874.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-76)">{</text><text class="terminal-1655558888-r1" x="219.6" y="1874.4" textLength="256.2" clip-path="url(#terminal-1655558888-line-76)">pep440,semver,semver2</text><text class="terminal-1655558888-r2" x="475.8" y="1874.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-76)">}</text><text class="terminal-1655558888-r1" x="976" y="1874.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-76)"> +</text><text class="terminal-1655558888-r1" x="0" y="1898.8" textLength="780.8" clip-path="url(#terminal-1655558888-line-77)">                        Deprecated, use --version-scheme instead</text><text class="terminal-1655558888-r1" x="976" y="1898.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-77)"> +</text><text class="terminal-1655558888-r1" x="0" y="1923.2" textLength="402.6" clip-path="url(#terminal-1655558888-line-78)">  --build-metadata BUILD_METADATA</text><text class="terminal-1655558888-r1" x="976" y="1923.2" textLength="12.2" clip-path="url(#terminal-1655558888-line-78)"> +</text><text class="terminal-1655558888-r1" x="0" y="1947.6" textLength="915" clip-path="url(#terminal-1655558888-line-79)">                        Add additional build-metadata to the version-number</text><text class="terminal-1655558888-r1" x="976" y="1947.6" textLength="12.2" clip-path="url(#terminal-1655558888-line-79)"> +</text><text class="terminal-1655558888-r1" x="0" y="1972" textLength="854" clip-path="url(#terminal-1655558888-line-80)">  --get-next            Determine the next version and write to stdout</text><text class="terminal-1655558888-r1" x="976" y="1972" textLength="12.2" clip-path="url(#terminal-1655558888-line-80)"> +</text><text class="terminal-1655558888-r1" x="0" y="1996.4" textLength="744.2" clip-path="url(#terminal-1655558888-line-81)">  --allow-no-commit     bump version without eligible commits</text><text class="terminal-1655558888-r1" x="976" y="1996.4" textLength="12.2" clip-path="url(#terminal-1655558888-line-81)"> +</text><text class="terminal-1655558888-r1" x="976" y="2020.8" textLength="12.2" clip-path="url(#terminal-1655558888-line-82)"> </text> </g> </g> diff --git a/docs/images/cli_help/cz_commit___help.svg b/docs/images/cli_help/cz_commit___help.svg index 5aea02232f..59cdd12b9b 100644 --- a/docs/images/cli_help/cz_commit___help.svg +++ b/docs/images/cli_help/cz_commit___help.svg @@ -19,95 +19,96 @@ font-weight: 700; } - .terminal-463778956-matrix { + .terminal-905765158-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-463778956-title { + .terminal-905765158-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-463778956-r1 { fill: #c5c8c6 } -.terminal-463778956-r2 { fill: #c5c8c6;font-weight: bold } -.terminal-463778956-r3 { fill: #68a0b3;font-weight: bold } + .terminal-905765158-r1 { fill: #c5c8c6 } +.terminal-905765158-r2 { fill: #c5c8c6;font-weight: bold } +.terminal-905765158-r3 { fill: #98a84b } +.terminal-905765158-r4 { fill: #68a0b3;font-weight: bold } </style> <defs> - <clipPath id="terminal-463778956-clip-terminal"> + <clipPath id="terminal-905765158-clip-terminal"> <rect x="0" y="0" width="975.0" height="584.5999999999999" /> </clipPath> - <clipPath id="terminal-463778956-line-0"> + <clipPath id="terminal-905765158-line-0"> <rect x="0" y="1.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-1"> +<clipPath id="terminal-905765158-line-1"> <rect x="0" y="25.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-2"> +<clipPath id="terminal-905765158-line-2"> <rect x="0" y="50.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-3"> +<clipPath id="terminal-905765158-line-3"> <rect x="0" y="74.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-4"> +<clipPath id="terminal-905765158-line-4"> <rect x="0" y="99.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-5"> +<clipPath id="terminal-905765158-line-5"> <rect x="0" y="123.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-6"> +<clipPath id="terminal-905765158-line-6"> <rect x="0" y="147.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-7"> +<clipPath id="terminal-905765158-line-7"> <rect x="0" y="172.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-8"> +<clipPath id="terminal-905765158-line-8"> <rect x="0" y="196.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-9"> +<clipPath id="terminal-905765158-line-9"> <rect x="0" y="221.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-10"> +<clipPath id="terminal-905765158-line-10"> <rect x="0" y="245.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-11"> +<clipPath id="terminal-905765158-line-11"> <rect x="0" y="269.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-12"> +<clipPath id="terminal-905765158-line-12"> <rect x="0" y="294.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-13"> +<clipPath id="terminal-905765158-line-13"> <rect x="0" y="318.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-14"> +<clipPath id="terminal-905765158-line-14"> <rect x="0" y="343.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-15"> +<clipPath id="terminal-905765158-line-15"> <rect x="0" y="367.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-16"> +<clipPath id="terminal-905765158-line-16"> <rect x="0" y="391.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-17"> +<clipPath id="terminal-905765158-line-17"> <rect x="0" y="416.3" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-18"> +<clipPath id="terminal-905765158-line-18"> <rect x="0" y="440.7" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-19"> +<clipPath id="terminal-905765158-line-19"> <rect x="0" y="465.1" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-20"> +<clipPath id="terminal-905765158-line-20"> <rect x="0" y="489.5" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-21"> +<clipPath id="terminal-905765158-line-21"> <rect x="0" y="513.9" width="976" height="24.65"/> </clipPath> -<clipPath id="terminal-463778956-line-22"> +<clipPath id="terminal-905765158-line-22"> <rect x="0" y="538.3" width="976" height="24.65"/> </clipPath> </defs> @@ -119,33 +120,33 @@ <circle cx="44" cy="0" r="7" fill="#28c840"/> </g> - <g transform="translate(9, 41)" clip-path="url(#terminal-463778956-clip-terminal)"> + <g transform="translate(9, 41)" clip-path="url(#terminal-905765158-clip-terminal)"> - <g class="terminal-463778956-matrix"> - <text class="terminal-463778956-r1" x="0" y="20" textLength="219.6" clip-path="url(#terminal-463778956-line-0)">$ cz commit --help</text><text class="terminal-463778956-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-463778956-line-0)"> -</text><text class="terminal-463778956-r1" x="0" y="44.4" textLength="207.4" clip-path="url(#terminal-463778956-line-1)">usage: cz commit </text><text class="terminal-463778956-r2" x="207.4" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)">[</text><text class="terminal-463778956-r1" x="219.6" y="44.4" textLength="24.4" clip-path="url(#terminal-463778956-line-1)">-h</text><text class="terminal-463778956-r2" x="244" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)">]</text><text class="terminal-463778956-r2" x="268.4" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)">[</text><text class="terminal-463778956-r1" x="280.6" y="44.4" textLength="85.4" clip-path="url(#terminal-463778956-line-1)">--retry</text><text class="terminal-463778956-r2" x="366" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)">]</text><text class="terminal-463778956-r2" x="390.4" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)">[</text><text class="terminal-463778956-r1" x="402.6" y="44.4" textLength="122" clip-path="url(#terminal-463778956-line-1)">--no-retry</text><text class="terminal-463778956-r2" x="524.6" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)">]</text><text class="terminal-463778956-r2" x="549" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)">[</text><text class="terminal-463778956-r1" x="561.2" y="44.4" textLength="109.8" clip-path="url(#terminal-463778956-line-1)">--dry-run</text><text class="terminal-463778956-r2" x="671" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)">]</text><text class="terminal-463778956-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-463778956-line-1)"> -</text><text class="terminal-463778956-r2" x="207.4" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)">[</text><text class="terminal-463778956-r1" x="219.6" y="68.8" textLength="402.6" clip-path="url(#terminal-463778956-line-2)">--write-message-to-file FILE_PATH</text><text class="terminal-463778956-r2" x="622.2" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)">]</text><text class="terminal-463778956-r2" x="646.6" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)">[</text><text class="terminal-463778956-r1" x="658.8" y="68.8" textLength="24.4" clip-path="url(#terminal-463778956-line-2)">-s</text><text class="terminal-463778956-r2" x="683.2" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)">]</text><text class="terminal-463778956-r2" x="707.6" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)">[</text><text class="terminal-463778956-r1" x="719.8" y="68.8" textLength="24.4" clip-path="url(#terminal-463778956-line-2)">-a</text><text class="terminal-463778956-r2" x="744.2" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)">]</text><text class="terminal-463778956-r2" x="768.6" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)">[</text><text class="terminal-463778956-r1" x="780.8" y="68.8" textLength="24.4" clip-path="url(#terminal-463778956-line-2)">-e</text><text class="terminal-463778956-r2" x="805.2" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)">]</text><text class="terminal-463778956-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-463778956-line-2)"> -</text><text class="terminal-463778956-r2" x="207.4" y="93.2" textLength="12.2" clip-path="url(#terminal-463778956-line-3)">[</text><text class="terminal-463778956-r1" x="219.6" y="93.2" textLength="280.6" clip-path="url(#terminal-463778956-line-3)">-l MESSAGE_LENGTH_LIMIT</text><text class="terminal-463778956-r2" x="500.2" y="93.2" textLength="12.2" clip-path="url(#terminal-463778956-line-3)">]</text><text class="terminal-463778956-r2" x="524.6" y="93.2" textLength="12.2" clip-path="url(#terminal-463778956-line-3)">[</text><text class="terminal-463778956-r1" x="536.8" y="93.2" textLength="24.4" clip-path="url(#terminal-463778956-line-3)">--</text><text class="terminal-463778956-r2" x="561.2" y="93.2" textLength="12.2" clip-path="url(#terminal-463778956-line-3)">]</text><text class="terminal-463778956-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-463778956-line-3)"> -</text><text class="terminal-463778956-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-463778956-line-4)"> -</text><text class="terminal-463778956-r1" x="0" y="142" textLength="207.4" clip-path="url(#terminal-463778956-line-5)">create new commit</text><text class="terminal-463778956-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-463778956-line-5)"> -</text><text class="terminal-463778956-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-463778956-line-6)"> -</text><text class="terminal-463778956-r1" x="0" y="190.8" textLength="97.6" clip-path="url(#terminal-463778956-line-7)">options:</text><text class="terminal-463778956-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-463778956-line-7)"> -</text><text class="terminal-463778956-r1" x="0" y="215.2" textLength="671" clip-path="url(#terminal-463778956-line-8)">  -h, --help            show this help message and exit</text><text class="terminal-463778956-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-463778956-line-8)"> -</text><text class="terminal-463778956-r1" x="0" y="239.6" textLength="500.2" clip-path="url(#terminal-463778956-line-9)">  --retry               retry last commit</text><text class="terminal-463778956-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-463778956-line-9)"> -</text><text class="terminal-463778956-r1" x="0" y="264" textLength="878.4" clip-path="url(#terminal-463778956-line-10)">  --no-retry            skip retry if retry_after_failure is set to true</text><text class="terminal-463778956-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-463778956-line-10)"> -</text><text class="terminal-463778956-r1" x="0" y="288.4" textLength="915" clip-path="url(#terminal-463778956-line-11)">  --dry-run             show output to stdout, no commit, no modified files</text><text class="terminal-463778956-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-463778956-line-11)"> -</text><text class="terminal-463778956-r1" x="0" y="312.8" textLength="427" clip-path="url(#terminal-463778956-line-12)">  --write-message-to-file FILE_PATH</text><text class="terminal-463778956-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-463778956-line-12)"> -</text><text class="terminal-463778956-r1" x="0" y="337.2" textLength="780.8" clip-path="url(#terminal-463778956-line-13)">                        write message to file before committing </text><text class="terminal-463778956-r2" x="780.8" y="337.2" textLength="12.2" clip-path="url(#terminal-463778956-line-13)">(</text><text class="terminal-463778956-r1" x="793" y="337.2" textLength="73.2" clip-path="url(#terminal-463778956-line-13)">can be</text><text class="terminal-463778956-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-463778956-line-13)"> -</text><text class="terminal-463778956-r1" x="0" y="361.6" textLength="573.4" clip-path="url(#terminal-463778956-line-14)">                        combined with --dry-run</text><text class="terminal-463778956-r2" x="573.4" y="361.6" textLength="12.2" clip-path="url(#terminal-463778956-line-14)">)</text><text class="terminal-463778956-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-463778956-line-14)"> -</text><text class="terminal-463778956-r1" x="0" y="386" textLength="524.6" clip-path="url(#terminal-463778956-line-15)">  -s, --signoff         sign off the commit</text><text class="terminal-463778956-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-463778956-line-15)"> -</text><text class="terminal-463778956-r1" x="0" y="410.4" textLength="902.8" clip-path="url(#terminal-463778956-line-16)">  -a, --all             Tell the command to automatically stage files that</text><text class="terminal-463778956-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-463778956-line-16)"> -</text><text class="terminal-463778956-r1" x="0" y="434.8" textLength="951.6" clip-path="url(#terminal-463778956-line-17)">                        have been modified and deleted, but new files you have</text><text class="terminal-463778956-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-463778956-line-17)"> -</text><text class="terminal-463778956-r1" x="0" y="459.2" textLength="732" clip-path="url(#terminal-463778956-line-18)">                        not told Git about are not affected.</text><text class="terminal-463778956-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-463778956-line-18)"> -</text><text class="terminal-463778956-r1" x="0" y="483.6" textLength="793" clip-path="url(#terminal-463778956-line-19)">  -e, --edit            edit the commit message before committing</text><text class="terminal-463778956-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-463778956-line-19)"> -</text><text class="terminal-463778956-r1" x="0" y="508" textLength="597.8" clip-path="url(#terminal-463778956-line-20)">  -l, --message-length-limit MESSAGE_LENGTH_LIMIT</text><text class="terminal-463778956-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-463778956-line-20)"> -</text><text class="terminal-463778956-r1" x="0" y="532.4" textLength="732" clip-path="url(#terminal-463778956-line-21)">                        length limit of the commit message; </text><text class="terminal-463778956-r3" x="732" y="532.4" textLength="12.2" clip-path="url(#terminal-463778956-line-21)">0</text><text class="terminal-463778956-r1" x="744.2" y="532.4" textLength="158.6" clip-path="url(#terminal-463778956-line-21)"> for no limit</text><text class="terminal-463778956-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-463778956-line-21)"> -</text><text class="terminal-463778956-r1" x="0" y="556.8" textLength="671" clip-path="url(#terminal-463778956-line-22)">  --                    Positional arguments separator </text><text class="terminal-463778956-r2" x="671" y="556.8" textLength="12.2" clip-path="url(#terminal-463778956-line-22)">(</text><text class="terminal-463778956-r1" x="683.2" y="556.8" textLength="134.2" clip-path="url(#terminal-463778956-line-22)">recommended</text><text class="terminal-463778956-r2" x="817.4" y="556.8" textLength="12.2" clip-path="url(#terminal-463778956-line-22)">)</text><text class="terminal-463778956-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-463778956-line-22)"> -</text><text class="terminal-463778956-r1" x="976" y="581.2" textLength="12.2" clip-path="url(#terminal-463778956-line-23)"> + <g class="terminal-905765158-matrix"> + <text class="terminal-905765158-r1" x="0" y="20" textLength="219.6" clip-path="url(#terminal-905765158-line-0)">$ cz commit --help</text><text class="terminal-905765158-r1" x="976" y="20" textLength="12.2" clip-path="url(#terminal-905765158-line-0)"> +</text><text class="terminal-905765158-r1" x="0" y="44.4" textLength="207.4" clip-path="url(#terminal-905765158-line-1)">usage: cz commit </text><text class="terminal-905765158-r2" x="207.4" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)">[</text><text class="terminal-905765158-r1" x="219.6" y="44.4" textLength="24.4" clip-path="url(#terminal-905765158-line-1)">-h</text><text class="terminal-905765158-r2" x="244" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)">]</text><text class="terminal-905765158-r2" x="268.4" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)">[</text><text class="terminal-905765158-r1" x="280.6" y="44.4" textLength="85.4" clip-path="url(#terminal-905765158-line-1)">--retry</text><text class="terminal-905765158-r2" x="366" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)">]</text><text class="terminal-905765158-r2" x="390.4" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)">[</text><text class="terminal-905765158-r1" x="402.6" y="44.4" textLength="122" clip-path="url(#terminal-905765158-line-1)">--no-retry</text><text class="terminal-905765158-r2" x="524.6" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)">]</text><text class="terminal-905765158-r2" x="549" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)">[</text><text class="terminal-905765158-r1" x="561.2" y="44.4" textLength="109.8" clip-path="url(#terminal-905765158-line-1)">--dry-run</text><text class="terminal-905765158-r2" x="671" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)">]</text><text class="terminal-905765158-r1" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-905765158-line-1)"> +</text><text class="terminal-905765158-r2" x="207.4" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)">[</text><text class="terminal-905765158-r1" x="219.6" y="68.8" textLength="402.6" clip-path="url(#terminal-905765158-line-2)">--write-message-to-file FILE_PATH</text><text class="terminal-905765158-r2" x="622.2" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)">]</text><text class="terminal-905765158-r2" x="646.6" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)">[</text><text class="terminal-905765158-r1" x="658.8" y="68.8" textLength="24.4" clip-path="url(#terminal-905765158-line-2)">-s</text><text class="terminal-905765158-r2" x="683.2" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)">]</text><text class="terminal-905765158-r2" x="707.6" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)">[</text><text class="terminal-905765158-r1" x="719.8" y="68.8" textLength="24.4" clip-path="url(#terminal-905765158-line-2)">-a</text><text class="terminal-905765158-r2" x="744.2" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)">]</text><text class="terminal-905765158-r2" x="768.6" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)">[</text><text class="terminal-905765158-r1" x="780.8" y="68.8" textLength="24.4" clip-path="url(#terminal-905765158-line-2)">-e</text><text class="terminal-905765158-r2" x="805.2" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)">]</text><text class="terminal-905765158-r1" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-905765158-line-2)"> +</text><text class="terminal-905765158-r2" x="207.4" y="93.2" textLength="12.2" clip-path="url(#terminal-905765158-line-3)">[</text><text class="terminal-905765158-r1" x="219.6" y="93.2" textLength="280.6" clip-path="url(#terminal-905765158-line-3)">-l MESSAGE_LENGTH_LIMIT</text><text class="terminal-905765158-r2" x="500.2" y="93.2" textLength="12.2" clip-path="url(#terminal-905765158-line-3)">]</text><text class="terminal-905765158-r2" x="524.6" y="93.2" textLength="12.2" clip-path="url(#terminal-905765158-line-3)">[</text><text class="terminal-905765158-r1" x="536.8" y="93.2" textLength="24.4" clip-path="url(#terminal-905765158-line-3)">--</text><text class="terminal-905765158-r2" x="561.2" y="93.2" textLength="12.2" clip-path="url(#terminal-905765158-line-3)">]</text><text class="terminal-905765158-r1" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-905765158-line-3)"> +</text><text class="terminal-905765158-r1" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-905765158-line-4)"> +</text><text class="terminal-905765158-r1" x="0" y="142" textLength="207.4" clip-path="url(#terminal-905765158-line-5)">create new commit</text><text class="terminal-905765158-r1" x="976" y="142" textLength="12.2" clip-path="url(#terminal-905765158-line-5)"> +</text><text class="terminal-905765158-r1" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-905765158-line-6)"> +</text><text class="terminal-905765158-r1" x="0" y="190.8" textLength="97.6" clip-path="url(#terminal-905765158-line-7)">options:</text><text class="terminal-905765158-r1" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-905765158-line-7)"> +</text><text class="terminal-905765158-r1" x="0" y="215.2" textLength="671" clip-path="url(#terminal-905765158-line-8)">  -h, --help            show this help message and exit</text><text class="terminal-905765158-r1" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-905765158-line-8)"> +</text><text class="terminal-905765158-r1" x="0" y="239.6" textLength="500.2" clip-path="url(#terminal-905765158-line-9)">  --retry               retry last commit</text><text class="terminal-905765158-r1" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-905765158-line-9)"> +</text><text class="terminal-905765158-r1" x="0" y="264" textLength="878.4" clip-path="url(#terminal-905765158-line-10)">  --no-retry            skip retry if retry_after_failure is set to true</text><text class="terminal-905765158-r1" x="976" y="264" textLength="12.2" clip-path="url(#terminal-905765158-line-10)"> +</text><text class="terminal-905765158-r1" x="0" y="288.4" textLength="915" clip-path="url(#terminal-905765158-line-11)">  --dry-run             show output to stdout, no commit, no modified files</text><text class="terminal-905765158-r1" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-905765158-line-11)"> +</text><text class="terminal-905765158-r1" x="0" y="312.8" textLength="427" clip-path="url(#terminal-905765158-line-12)">  --write-message-to-file FILE_PATH</text><text class="terminal-905765158-r1" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-905765158-line-12)"> +</text><text class="terminal-905765158-r1" x="0" y="337.2" textLength="780.8" clip-path="url(#terminal-905765158-line-13)">                        write message to file before committing </text><text class="terminal-905765158-r2" x="780.8" y="337.2" textLength="12.2" clip-path="url(#terminal-905765158-line-13)">(</text><text class="terminal-905765158-r1" x="793" y="337.2" textLength="73.2" clip-path="url(#terminal-905765158-line-13)">can be</text><text class="terminal-905765158-r1" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-905765158-line-13)"> +</text><text class="terminal-905765158-r1" x="0" y="361.6" textLength="573.4" clip-path="url(#terminal-905765158-line-14)">                        combined with --dry-run</text><text class="terminal-905765158-r2" x="573.4" y="361.6" textLength="12.2" clip-path="url(#terminal-905765158-line-14)">)</text><text class="terminal-905765158-r1" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-905765158-line-14)"> +</text><text class="terminal-905765158-r1" x="0" y="386" textLength="488" clip-path="url(#terminal-905765158-line-15)">  -s, --signoff         Deprecated, use </text><text class="terminal-905765158-r3" x="488" y="386" textLength="207.4" clip-path="url(#terminal-905765158-line-15)">'cz commit -- -s'</text><text class="terminal-905765158-r1" x="695.4" y="386" textLength="97.6" clip-path="url(#terminal-905765158-line-15)"> instead</text><text class="terminal-905765158-r1" x="976" y="386" textLength="12.2" clip-path="url(#terminal-905765158-line-15)"> +</text><text class="terminal-905765158-r1" x="0" y="410.4" textLength="902.8" clip-path="url(#terminal-905765158-line-16)">  -a, --all             Tell the command to automatically stage files that</text><text class="terminal-905765158-r1" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-905765158-line-16)"> +</text><text class="terminal-905765158-r1" x="0" y="434.8" textLength="951.6" clip-path="url(#terminal-905765158-line-17)">                        have been modified and deleted, but new files you have</text><text class="terminal-905765158-r1" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-905765158-line-17)"> +</text><text class="terminal-905765158-r1" x="0" y="459.2" textLength="732" clip-path="url(#terminal-905765158-line-18)">                        not told Git about are not affected.</text><text class="terminal-905765158-r1" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-905765158-line-18)"> +</text><text class="terminal-905765158-r1" x="0" y="483.6" textLength="793" clip-path="url(#terminal-905765158-line-19)">  -e, --edit            edit the commit message before committing</text><text class="terminal-905765158-r1" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-905765158-line-19)"> +</text><text class="terminal-905765158-r1" x="0" y="508" textLength="597.8" clip-path="url(#terminal-905765158-line-20)">  -l, --message-length-limit MESSAGE_LENGTH_LIMIT</text><text class="terminal-905765158-r1" x="976" y="508" textLength="12.2" clip-path="url(#terminal-905765158-line-20)"> +</text><text class="terminal-905765158-r1" x="0" y="532.4" textLength="732" clip-path="url(#terminal-905765158-line-21)">                        length limit of the commit message; </text><text class="terminal-905765158-r4" x="732" y="532.4" textLength="12.2" clip-path="url(#terminal-905765158-line-21)">0</text><text class="terminal-905765158-r1" x="744.2" y="532.4" textLength="158.6" clip-path="url(#terminal-905765158-line-21)"> for no limit</text><text class="terminal-905765158-r1" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-905765158-line-21)"> +</text><text class="terminal-905765158-r1" x="0" y="556.8" textLength="671" clip-path="url(#terminal-905765158-line-22)">  --                    Positional arguments separator </text><text class="terminal-905765158-r2" x="671" y="556.8" textLength="12.2" clip-path="url(#terminal-905765158-line-22)">(</text><text class="terminal-905765158-r1" x="683.2" y="556.8" textLength="134.2" clip-path="url(#terminal-905765158-line-22)">recommended</text><text class="terminal-905765158-r2" x="817.4" y="556.8" textLength="12.2" clip-path="url(#terminal-905765158-line-22)">)</text><text class="terminal-905765158-r1" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-905765158-line-22)"> +</text><text class="terminal-905765158-r1" x="976" y="581.2" textLength="12.2" clip-path="url(#terminal-905765158-line-23)"> </text> </g> </g> From 6b4f8b0c888e0b59a95f12826c6466227e221da8 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Mon, 9 Jun 2025 22:49:58 +0800 Subject: [PATCH 594/598] docs(CHANGELOG): run `pre-commit run --all-files` to fix CI --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76b6e36e94..9d7a31cc40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ - **cli**: update description for deprecate warning - **commit**: emit deprecated warning of cz commit -s -- **Check**: make parameters backward compatiable +- **Check**: make parameters backward compatible - **BaseConfig**: mypy error - **deprecated**: mark deprecate in v5 - **defaults**: add non-capitalized default constants back and deprecated warning From 98a81f89bd3f512067835cfa77fc55701673fbb6 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Tue, 10 Jun 2025 19:13:10 +0800 Subject: [PATCH 595/598] build: remove not needed importlib-metadata dependency for python >= 3.10 --- poetry.lock | 93 +++----------------------------------------------- pyproject.toml | 3 +- 2 files changed, 6 insertions(+), 90 deletions(-) diff --git a/poetry.lock b/poetry.lock index c5c893931a..e7f0e96e51 100644 --- a/poetry.lock +++ b/poetry.lock @@ -222,7 +222,6 @@ description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" groups = ["documentation"] -markers = "python_version == \"3.9\"" files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -231,22 +230,6 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -[[package]] -name = "click" -version = "8.2.1" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.10" -groups = ["documentation"] -markers = "python_version != \"3.9\"" -files = [ - {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, - {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - [[package]] name = "colorama" version = "0.4.6" @@ -550,31 +533,6 @@ perf = ["ipython"] test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] type = ["pytest-mypy"] -[[package]] -name = "importlib-metadata" -version = "8.7.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.9" -groups = ["main"] -markers = "python_version != \"3.9\"" -files = [ - {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, - {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, -] - -[package.dependencies] -zipp = ">=3.20" - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -perf = ["ipython"] -test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] -type = ["pytest-mypy"] - [[package]] name = "iniconfig" version = "2.1.0" @@ -594,7 +552,6 @@ description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version == \"3.9\"" files = [ {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, @@ -626,46 +583,6 @@ qtconsole = ["qtconsole"] test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] -[[package]] -name = "ipython" -version = "8.37.0" -description = "IPython: Productive Interactive Computing" -optional = false -python-versions = ">=3.10" -groups = ["dev"] -markers = "python_version != \"3.9\"" -files = [ - {file = "ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2"}, - {file = "ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} -prompt_toolkit = ">=3.0.41,<3.1.0" -pygments = ">=2.4.0" -stack_data = "*" -traitlets = ">=5.13.0" -typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} - -[package.extras] -all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] -black = ["black"] -doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli ; python_version < \"3.11\"", "typing_extensions"] -kernel = ["ipykernel"] -matplotlib = ["matplotlib"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["packaging", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] -test-extra = ["curio", "ipython[test]", "jupyter_ai", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"] - [[package]] name = "jedi" version = "0.19.2" @@ -1104,7 +1021,7 @@ description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" groups = ["dev"] -markers = "python_version == \"3.9\" and sys_platform != \"win32\" or sys_platform != \"win32\" and sys_platform != \"emscripten\"" +markers = "sys_platform != \"win32\"" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, @@ -1207,7 +1124,7 @@ description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" groups = ["dev"] -markers = "python_version == \"3.9\" and sys_platform != \"win32\" or sys_platform != \"win32\" and sys_platform != \"emscripten\"" +markers = "sys_platform != \"win32\"" files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, @@ -1817,7 +1734,7 @@ files = [ {file = "typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af"}, {file = "typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4"}, ] -markers = {main = "python_version < \"3.11\"", dev = "python_version < \"3.12\"", script = "python_version < \"3.11\"", test = "python_version < \"3.11\""} +markers = {main = "python_version < \"3.11\"", dev = "python_version < \"3.11\"", script = "python_version < \"3.11\"", test = "python_version < \"3.11\""} [[package]] name = "urllib3" @@ -2009,11 +1926,11 @@ description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" groups = ["main", "documentation"] +markers = "python_version == \"3.9\"" files = [ {file = "zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343"}, {file = "zipp-3.22.0.tar.gz", hash = "sha256:dd2f28c3ce4bc67507bfd3781d21b7bb2be31103b51a4553ad7d90b84e57ace5"}, ] -markers = {documentation = "python_version == \"3.9\""} [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] @@ -2026,4 +1943,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "f35cf57718e28836cf1e70b33edab9ce623b01a7f2d31d712585554721f6d403" +content-hash = "c98af83d4ce726bbfba04eea3de90e642fb7bdb08bedf0bf1b00b92a1b140e76" diff --git a/pyproject.toml b/pyproject.toml index 6990741957..ab3ba39ee1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,8 +23,7 @@ dependencies = [ "typing-extensions (>=4.0.1,<5.0.0) ; python_version < '3.11'", "charset-normalizer (>=2.1.0,<4)", # Use the Python 3.11 and 3.12 compatible API: https://github.com/python/importlib_metadata#compatibility - "importlib-metadata >=8.0.0,!=8.7.0,<9.0.0 ; python_version == '3.9'", # importlib-metadata@8.7.0 + python3.9 breaks our unit test - "importlib-metadata >=8.0.0,<9.0.0 ; python_version != '3.9'", + "importlib-metadata >=8.0.0,<8.7.0 ; python_version < '3.10'", ] keywords = ["commitizen", "conventional", "commits", "git"] # See also: https://pypi.org/classifiers/ From db94c4dbc12f153cb340654ba7f2458c3c652d3d Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Tue, 10 Jun 2025 19:31:34 +0800 Subject: [PATCH 596/598] docs(defaults): deprecate type Questions --- commitizen/defaults.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/commitizen/defaults.py b/commitizen/defaults.py index a49d6d9428..94d4d97b22 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -8,9 +8,6 @@ from commitizen.question import CzQuestion -# Type -Questions = Iterable[MutableMapping[str, Any]] # TODO: deprecate this? - class CzSettings(TypedDict, total=False): bump_pattern: str @@ -161,6 +158,10 @@ def get_tag_regexes( } +# Type +Questions = Iterable[MutableMapping[str, Any]] # TODO: remove this in v5 + + def __getattr__(name: str) -> Any: # PEP-562: deprecate module-level variable @@ -176,6 +177,7 @@ def __getattr__(name: str) -> Any: "change_type_order": (CHANGE_TYPE_ORDER, "CHANGE_TYPE_ORDER"), "encoding": (ENCODING, "ENCODING"), "name": (DEFAULT_SETTINGS["name"], "DEFAULT_SETTINGS['name']"), + "Questions": (Questions, "Iterable[CzQuestion]"), } if name in deprecated_vars: value, replacement = deprecated_vars[name] From f80292e15be28014c820eabc5ec652f46fe5a3a4 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Tue, 10 Jun 2025 20:44:06 +0800 Subject: [PATCH 597/598] docs(customization.md): fix grammar mistake, add title to code blocks --- docs/customization.md | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/docs/customization.md b/docs/customization.md index e97558a308..df77171077 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -10,7 +10,7 @@ The basic steps are: Example: -```toml +```toml title="pyproject.toml" [tool.commitizen] name = "cz_customize" @@ -50,7 +50,7 @@ message = "Do you want to add body message in commit?" The equivalent example for a json config file: -```json +```json title=".cz.json" { "commitizen": { "name": "cz_customize", @@ -106,7 +106,7 @@ The equivalent example for a json config file: And the correspondent example for a yaml file: -```yaml +```yaml title=".cz.yaml" commitizen: name: cz_customize customize: @@ -149,16 +149,16 @@ commitizen: | Parameter | Type | Default | Description | | ------------------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `questions` | `Questions` | `None` | Questions regarding the commit message. Detailed below. The type `Questions` is an alias to `Iterable[MutableMapping[str, Any]]` which is defined in `commitizen.defaults`. It expects a list of dictionaries. | +| `questions` | `Questions` | `None` | Questions regarding the commit message. Detailed below. The type `Questions` is an alias to `Iterable[MutableMapping[str, Any]]` which is defined in `commitizen.defaults`. It expects a list of dictionaries. | | `message_template` | `str` | `None` | The template for generating message from the given answers. `message_template` should either follow [Jinja2][jinja2] formatting specification, and all the variables in this template should be defined in `name` in `questions` | -| `example` | `str` | `""` | (OPTIONAL) Provide an example to help understand the style. Used by `cz example`. | -| `schema` | `str` | `""` | (OPTIONAL) Show the schema used. Used by `cz schema`. | -| `schema_pattern` | `str` | `""` | (OPTIONAL) The regular expression used to do commit message validation. Used by `cz check`. | -| `info_path` | `str` | `""` | (OPTIONAL) The path to the file that contains explanation of the commit rules. Used by `cz info`. If not provided `cz info`, will load `info` instead. | -| `info` | `str` | `""` | (OPTIONAL) Explanation of the commit rules. Used by `cz info`. | +| `example` | `str` | `""` | (OPTIONAL) Provide an example to help understand the style. Used by `cz example`. | +| `schema` | `str` | `""` | (OPTIONAL) Show the schema used. Used by `cz schema`. | +| `schema_pattern` | `str` | `""` | (OPTIONAL) The regular expression used to do commit message validation. Used by `cz check`. | +| `info_path` | `str` | `""` | (OPTIONAL) The path to the file that contains explanation of the commit rules. Used by `cz info`. If not provided `cz info`, will load `info` instead. | +| `info` | `str` | `""` | (OPTIONAL) Explanation of the commit rules. Used by `cz info`. | | `bump_map` | `dict` | `None` | (OPTIONAL) Dictionary mapping the extracted information to a `SemVer` increment type (`MAJOR`, `MINOR`, `PATCH`) | | `bump_pattern` | `str` | `None` | (OPTIONAL) Regex to extract information from commit (subject and body) | -| `change_type_order`| `str` | `None` | (OPTIONAL) List of strings used to order the Changelog. All other types will be sorted alphabetically. Default is `["BREAKING CHANGE", "Feat", "Fix", "Refactor", "Perf"]` | +| `change_type_order` | `str` | `None` | (OPTIONAL) List of strings used to order the Changelog. All other types will be sorted alphabetically. Default is `["BREAKING CHANGE", "Feat", "Fix", "Refactor", "Perf"]` | | `commit_parser` | `str` | `None` | (OPTIONAL) Regex to extract information used in creating changelog. [See more][changelog-spec] | | `changelog_pattern` | `str` | `None` | (OPTIONAL) Regex to understand which commits to include in the changelog | | `change_type_map` | `dict` | `None` | (OPTIONAL) Dictionary mapping the type of the commit to a changelog entry | @@ -215,7 +215,7 @@ Create a Python module, for example `cz_jira.py`. Inherit from `BaseCommitizen`, and you must define `questions` and `message`. The others are optional. -```python +```python title="cz_jira.py" from commitizen.cz.base import BaseCommitizen from commitizen.defaults import Questions @@ -259,7 +259,7 @@ class JiraCz(BaseCommitizen): The next file required is `setup.py` modified from flask version. -```python +```python title="setup.py" from setuptools import setup setup( @@ -295,7 +295,7 @@ You need to define 2 parameters inside your custom `BaseCommitizen`. Let's see an example. -```python +```python title="cz_strange.py" from commitizen.cz.base import BaseCommitizen @@ -315,7 +315,7 @@ cz -n cz_strange bump ### Custom changelog generator The changelog generator should just work in a very basic manner without touching anything. -You can customize it of course, and this are the variables you need to add to your custom `BaseCommitizen`. +You can customize it of course, and the following variables are the ones you need to add to your custom `BaseCommitizen`. | Parameter | Type | Required | Description | | -------------------------------- | ------------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -326,7 +326,7 @@ You can customize it of course, and this are the variables you need to add to yo | `changelog_hook` | `method: (full_changelog: str, partial_changelog: Optional[str]) -> str` | NO | Receives the whole and partial (if used incremental) changelog. Useful to send slack messages or notify a compliance department. Must return the full_changelog | | `changelog_release_hook` | `method: (release: dict, tag: git.GitTag) -> dict` | NO | Receives each generated changelog release and its associated tag. Useful to enrich releases before they are rendered. Must return the update release -```python +```python title="cz_strange.py" from commitizen.cz.base import BaseCommitizen import chat import compliance @@ -376,8 +376,6 @@ class StrangeCommitizen(BaseCommitizen): return full_changelog ``` -[changelog-des]: ./commands/changelog.md#description - ### Raise Customize Exception If you want `commitizen` to catch your exception and print the message, you'll have to inherit `CzException`. @@ -528,3 +526,4 @@ by: [template-config]: config.md#template [extras-config]: config.md#extras +[changelog-des]: ./commands/changelog.md#description From 7ef1f7e8d6519270df63387b50c2c0cd2591c832 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung <bear890707@gmail.com> Date: Wed, 11 Jun 2025 14:21:02 +0800 Subject: [PATCH 598/598] docs(bump.md): add titles to code blocks and fix minor grammar issues --- docs/commands/bump.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/commands/bump.md b/docs/commands/bump.md index 8219cc3461..1320e30a7a 100644 --- a/docs/commands/bump.md +++ b/docs/commands/bump.md @@ -31,7 +31,7 @@ cz bump --version-scheme semver ``` 2. Configuration file: -```toml +```toml title="pyproject.toml" [tool.commitizen] version_scheme = "semver" ``` @@ -113,7 +113,7 @@ Note that as per [semantic versioning spec](https://semver.org/#spec-item-9) For example, the following versions (using the [PEP 440](https://peps.python.org/pep-0440/) scheme) are ordered by their precedence and showcase how a release might flow through a development cycle: -- `1.0.0` is the current published version +- `1.0.0` is the currently published version - `1.0.1a0` after committing a `fix:` for pre-release - `1.1.0a1` after committing an additional `feat:` for pre-release - `1.1.0b0` after bumping a beta release @@ -153,7 +153,7 @@ cz bump --check-consistency For example, if we have `pyproject.toml` -```toml +```toml title="pyproject.toml" [tool.commitizen] version = "1.21.0" version_files = [ @@ -162,15 +162,16 @@ version_files = [ ] ``` -`src/__version__.py`, +`src/__version__.py` -```python + +```python title="src/__version__.py" __version__ = "1.21.0" ``` -and `setup.py`. +and `setup.py` -```python +```python title="setup.py" from setuptools import setup setup(..., version="1.0.5", ...) @@ -193,7 +194,7 @@ cz bump --local-version For example, if we have `pyproject.toml` -```toml +```toml title="pyproject.toml" [tool.commitizen] version = "5.3.5+0.1.0" ``` @@ -454,7 +455,7 @@ In your `pyproject.toml` or `.cz.toml` tag_format = "v$major.$minor.$patch$prerelease" ``` -The variables must be preceded by a `$` sign and optionally can be wrapped in `{}` . Default is `$version`. +The variables must be preceded by a `$` sign and optionally can be wrapped in `{}`. The default is `$version`. Supported variables: @@ -483,7 +484,7 @@ Some examples `pyproject.toml`, `.cz.toml` or `cz.toml` -```toml +```toml title="pyproject.toml" [tool.commitizen] version_files = [ "src/__version__.py", @@ -496,8 +497,7 @@ This means that it will find a file `setup.py` and will only make a change in a line containing the `version` substring. !!! note - Files can be specified using relative (to the execution) paths, absolute paths - or glob patterns. + Files can be specified using relative (to the execution) paths, absolute paths, or glob patterns. --- @@ -516,7 +516,7 @@ Some examples `pyproject.toml`, `.cz.toml` or `cz.toml` -```toml +```toml title="pyproject.toml" [tool.commitizen] bump_message = "release $current_version → $new_version [skip-ci]" ``` @@ -529,7 +529,7 @@ When set to `true` the changelog is always updated incrementally when running `c Defaults to: `false` -```toml +```toml title="pyproject.toml" [tool.commitizen] update_changelog_on_bump = true ``` @@ -540,7 +540,7 @@ update_changelog_on_bump = true When set to `true`, Commitizen will create annotated tags. -```toml +```toml title="pyproject.toml" [tool.commitizen] annotated_tag = true ``` @@ -551,7 +551,7 @@ annotated_tag = true When set to `true`, Commitizen will create gpg signed tags. -```toml +```toml title="pyproject.toml" [tool.commitizen] gpg_sign = true ``` @@ -565,7 +565,7 @@ Useful during the initial development stage of your project. Defaults to: `false` -```toml +```toml title="pyproject.toml" [tool.commitizen] major_version_zero = true ``` @@ -591,7 +591,7 @@ execution of the script, some environment variables are available: | `CZ_PRE_INCREMENT` | Whether this is a `MAJOR`, `MINOR` or `PATH` release | | `CZ_PRE_CHANGELOG_FILE_NAME` | Path to the changelog file, if available | -```toml +```toml title="pyproject.toml" [tool.commitizen] pre_bump_hooks = [ "scripts/generate_documentation.sh" @@ -618,7 +618,7 @@ release. During execution of the script, some environment variables are availabl | `CZ_POST_INCREMENT` | Whether this was a `MAJOR`, `MINOR` or `PATH` release | | `CZ_POST_CHANGELOG_FILE_NAME` | Path to the changelog file, if available | -```toml +```toml title="pyproject.toml" [tool.commitizen] post_bump_hooks = [ "scripts/slack_notification.sh" @@ -631,7 +631,7 @@ Offset with which to start counting prereleases. Defaults to: `0` -```toml +```toml title="pyproject.toml" [tool.commitizen] prerelease_offset = 1 ``` @@ -651,7 +651,7 @@ Options: `pep440`, `semver`, `semver2` Defaults to: `pep440` -```toml +```toml title="pyproject.toml" [tool.commitizen] version_scheme = "semver" ```

N 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