1633 lines
54 KiB
Python
1633 lines
54 KiB
Python
import re
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import Any, Optional
|
|
|
|
import pytest
|
|
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.version_schemes import Pep440
|
|
|
|
COMMITS_DATA: list[dict[str, Any]] = [
|
|
{
|
|
"rev": "141ee441c9c9da0809c554103a558eb17c30ed17",
|
|
"parents": ["6c4948501031b7d6405b54b21d3d635827f9421b"],
|
|
"title": "bump: version 1.1.1 → 1.2.0",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "6c4948501031b7d6405b54b21d3d635827f9421b",
|
|
"parents": ["ddd220ad515502200fe2dde443614c1075d26238"],
|
|
"title": "docs: how to create custom bumps",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "ddd220ad515502200fe2dde443614c1075d26238",
|
|
"parents": ["ad17acff2e3a2e141cbc3c6efd7705e4e6de9bfc"],
|
|
"title": "feat: custom cz plugins now support bumping version",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "ad17acff2e3a2e141cbc3c6efd7705e4e6de9bfc",
|
|
"parents": ["56c8a8da84e42b526bcbe130bd194306f7c7e813"],
|
|
"title": "docs: added bump gif",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "56c8a8da84e42b526bcbe130bd194306f7c7e813",
|
|
"parents": ["74c6134b1b2e6bb8b07ed53410faabe99b204f36"],
|
|
"title": "bump: version 1.1.0 → 1.1.1",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "74c6134b1b2e6bb8b07ed53410faabe99b204f36",
|
|
"parents": ["cbc7b5f22c4e74deff4bc92d14e19bd93524711e"],
|
|
"title": "refactor: changed stdout statements",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "cbc7b5f22c4e74deff4bc92d14e19bd93524711e",
|
|
"parents": ["1ba46f2a63cb9d6e7472eaece21528c8cd28b118"],
|
|
"title": "fix(bump): commit message now fits better with semver",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "1ba46f2a63cb9d6e7472eaece21528c8cd28b118",
|
|
"parents": ["c35dbffd1bb98bb0b3d1593797e79d1c3366af8f"],
|
|
"title": "fix: conventional commit 'breaking change' in body instead of title",
|
|
"body": "closes #16",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "c35dbffd1bb98bb0b3d1593797e79d1c3366af8f",
|
|
"parents": ["25313397a4ac3dc5b5c986017bee2a614399509d"],
|
|
"title": "refactor(schema): command logic removed from commitizen base",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "25313397a4ac3dc5b5c986017bee2a614399509d",
|
|
"parents": ["d2f13ac41b4e48995b3b619d931c82451886e6ff"],
|
|
"title": "refactor(info): command logic removed from commitizen base",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "d2f13ac41b4e48995b3b619d931c82451886e6ff",
|
|
"parents": ["d839e317e5b26671b010584ad8cc6bf362400fa1"],
|
|
"title": "refactor(example): command logic removed from commitizen base",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "d839e317e5b26671b010584ad8cc6bf362400fa1",
|
|
"parents": ["12d0e65beda969f7983c444ceedc2a01584f4e08"],
|
|
"title": "refactor(commit): moved most of the commit logic to the commit command",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "12d0e65beda969f7983c444ceedc2a01584f4e08",
|
|
"parents": ["fb4c85abe51c228e50773e424cbd885a8b6c610d"],
|
|
"title": "docs(README): updated documentation url)",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "fb4c85abe51c228e50773e424cbd885a8b6c610d",
|
|
"parents": ["17efb44d2cd16f6621413691a543e467c7d2dda6"],
|
|
"title": "docs: mkdocs documentation",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "17efb44d2cd16f6621413691a543e467c7d2dda6",
|
|
"parents": ["6012d9eecfce8163d75c8fff179788e9ad5347da"],
|
|
"title": "Bump version 1.0.0 → 1.1.0",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "6012d9eecfce8163d75c8fff179788e9ad5347da",
|
|
"parents": ["0c7fb0ca0168864dfc55d83c210da57771a18319"],
|
|
"title": "test: fixed issues with conf",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "0c7fb0ca0168864dfc55d83c210da57771a18319",
|
|
"parents": ["cb1dd2019d522644da5bdc2594dd6dee17122d7f"],
|
|
"title": "docs(README): some new information about bump",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "cb1dd2019d522644da5bdc2594dd6dee17122d7f",
|
|
"parents": ["9c7450f85df6bf6be508e79abf00855a30c3c73c"],
|
|
"title": "feat: new working bump command",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "9c7450f85df6bf6be508e79abf00855a30c3c73c",
|
|
"parents": ["9f3af3772baab167e3fd8775d37f041440184251"],
|
|
"title": "feat: create version tag",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "9f3af3772baab167e3fd8775d37f041440184251",
|
|
"parents": ["b0d6a3defbfde14e676e7eb34946409297d0221b"],
|
|
"title": "docs: added new changelog",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "b0d6a3defbfde14e676e7eb34946409297d0221b",
|
|
"parents": ["d630d07d912e420f0880551f3ac94e933f9d3beb"],
|
|
"title": "feat: update given files with new version",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "d630d07d912e420f0880551f3ac94e933f9d3beb",
|
|
"parents": ["1792b8980c58787906dbe6836f93f31971b1ec2d"],
|
|
"title": "fix: removed all from commit",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "1792b8980c58787906dbe6836f93f31971b1ec2d",
|
|
"parents": ["52def1ea3555185ba4b936b463311949907e31ec"],
|
|
"title": "feat(config): new set key, used to set version to cfg",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "52def1ea3555185ba4b936b463311949907e31ec",
|
|
"parents": ["3127e05077288a5e2b62893345590bf1096141b7"],
|
|
"title": "feat: support for pyproject.toml",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "3127e05077288a5e2b62893345590bf1096141b7",
|
|
"parents": ["fd480ed90a80a6ffa540549408403d5b60d0e90c"],
|
|
"title": "feat: first semantic version bump implementation",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "fd480ed90a80a6ffa540549408403d5b60d0e90c",
|
|
"parents": ["e4840a059731c0bf488381ffc77e989e85dd81ad"],
|
|
"title": "fix: fix config file not working",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "e4840a059731c0bf488381ffc77e989e85dd81ad",
|
|
"parents": ["aa44a92d68014d0da98965c0c2cb8c07957d4362"],
|
|
"title": "refactor: added commands folder, better integration with decli",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "aa44a92d68014d0da98965c0c2cb8c07957d4362",
|
|
"parents": ["58bb709765380dbd46b74ce6e8978515764eb955"],
|
|
"title": "Bump version: 1.0.0b2 → 1.0.0",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "58bb709765380dbd46b74ce6e8978515764eb955",
|
|
"parents": ["97afb0bb48e72b6feca793091a8a23c706693257"],
|
|
"title": "docs(README): new badges",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "97afb0bb48e72b6feca793091a8a23c706693257",
|
|
"parents": [
|
|
"9cecb9224aa7fa68d4afeac37eba2a25770ef251",
|
|
"e004a90b81ea5b374f118759bce5951202d03d69",
|
|
],
|
|
"title": "Merge pull request #10 from Woile/feat/decli",
|
|
"body": "Feat/decli",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "9cecb9224aa7fa68d4afeac37eba2a25770ef251",
|
|
"parents": ["f5781d1a2954d71c14ade2a6a1a95b91310b2577"],
|
|
"title": "style: black to files",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "f5781d1a2954d71c14ade2a6a1a95b91310b2577",
|
|
"parents": ["80105fb3c6d45369bc0cbf787bd329fba603864c"],
|
|
"title": "ci: added travis",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "80105fb3c6d45369bc0cbf787bd329fba603864c",
|
|
"parents": ["a96008496ffefb6b1dd9b251cb479eac6a0487f7"],
|
|
"title": "refactor: removed delegator, added decli and many tests",
|
|
"body": "BREAKING CHANGE: API is stable",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "a96008496ffefb6b1dd9b251cb479eac6a0487f7",
|
|
"parents": ["aab33d13110f26604fb786878856ec0b9e5fc32b"],
|
|
"title": "docs: updated test command",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "aab33d13110f26604fb786878856ec0b9e5fc32b",
|
|
"parents": ["b73791563d2f218806786090fb49ef70faa51a3a"],
|
|
"title": "Bump version: 1.0.0b1 → 1.0.0b2",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "b73791563d2f218806786090fb49ef70faa51a3a",
|
|
"parents": ["7aa06a454fb717408b3657faa590731fb4ab3719"],
|
|
"title": "docs(README): updated to reflect current state",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"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",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "7c7e96b723c2aaa1aec3a52561f680adf0b60e97",
|
|
"parents": ["ed830019581c83ba633bfd734720e6758eca6061"],
|
|
"title": "Bump version: 0.9.11 → 1.0.0b1",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"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",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "c52eca6f74f844ab3ffbde61d98ef96071e132b7",
|
|
"parents": ["0326652b2657083929507ee66d4d1a0899e861ba"],
|
|
"title": "Bump version: 0.9.10 → 0.9.11",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"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",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "b3f89892222340150e32631ae6b7aab65230036f",
|
|
"parents": ["5e837bf8ef0735193597372cd2d85e31a8f715b9"],
|
|
"title": "Bump version: 0.9.9 → 0.9.10",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "5e837bf8ef0735193597372cd2d85e31a8f715b9",
|
|
"parents": ["684e0259cc95c7c5e94854608cd3dcebbd53219e"],
|
|
"title": "fix: parse scope (this is my punishment for not having tests)",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "684e0259cc95c7c5e94854608cd3dcebbd53219e",
|
|
"parents": ["ca38eac6ff09870851b5c76a6ff0a2a8e5ecda15"],
|
|
"title": "Bump version: 0.9.8 → 0.9.9",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "ca38eac6ff09870851b5c76a6ff0a2a8e5ecda15",
|
|
"parents": ["64168f18d4628718c49689ee16430549e96c5d4b"],
|
|
"title": "fix: parse scope empty",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "64168f18d4628718c49689ee16430549e96c5d4b",
|
|
"parents": ["9d4def716ef235a1fa5ae61614366423fbc8256f"],
|
|
"title": "Bump version: 0.9.7 → 0.9.8",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "9d4def716ef235a1fa5ae61614366423fbc8256f",
|
|
"parents": ["33b0bf1a0a4dc60aac45ed47476d2e5473add09e"],
|
|
"title": "fix(scope): parse correctly again",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "33b0bf1a0a4dc60aac45ed47476d2e5473add09e",
|
|
"parents": ["696885e891ec35775daeb5fec3ba2ab92c2629e1"],
|
|
"title": "Bump version: 0.9.6 → 0.9.7",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "696885e891ec35775daeb5fec3ba2ab92c2629e1",
|
|
"parents": ["bef4a86761a3bda309c962bae5d22ce9b57119e4"],
|
|
"title": "fix(scope): parse correctly",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "bef4a86761a3bda309c962bae5d22ce9b57119e4",
|
|
"parents": ["72472efb80f08ee3fd844660afa012c8cb256e4b"],
|
|
"title": "Bump version: 0.9.5 → 0.9.6",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "72472efb80f08ee3fd844660afa012c8cb256e4b",
|
|
"parents": ["b5561ce0ab3b56bb87712c8f90bcf37cf2474f1b"],
|
|
"title": "refactor(conventionalCommit): moved filters to questions instead of message",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "b5561ce0ab3b56bb87712c8f90bcf37cf2474f1b",
|
|
"parents": ["3e31714dc737029d96898f412e4ecd2be1bcd0ce"],
|
|
"title": "fix(manifest): included missing files",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "3e31714dc737029d96898f412e4ecd2be1bcd0ce",
|
|
"parents": ["9df721e06595fdd216884c36a28770438b4f4a39"],
|
|
"title": "Bump version: 0.9.4 → 0.9.5",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "9df721e06595fdd216884c36a28770438b4f4a39",
|
|
"parents": ["0cf6ada372470c8d09e6c9e68ebf94bbd5a1656f"],
|
|
"title": "fix(config): home path for python versions between 3.0 and 3.5",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "0cf6ada372470c8d09e6c9e68ebf94bbd5a1656f",
|
|
"parents": ["973c6b3e100f6f69a3fe48bd8ee55c135b96c318"],
|
|
"title": "Bump version: 0.9.3 → 0.9.4",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "973c6b3e100f6f69a3fe48bd8ee55c135b96c318",
|
|
"parents": ["dacc86159b260ee98eb5f57941c99ba731a01399"],
|
|
"title": "feat(cli): added version",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "dacc86159b260ee98eb5f57941c99ba731a01399",
|
|
"parents": ["4368f3c3cbfd4a1ced339212230d854bc5bab496"],
|
|
"title": "Bump version: 0.9.2 → 0.9.3",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "4368f3c3cbfd4a1ced339212230d854bc5bab496",
|
|
"parents": ["da94133288727d35dae9b91866a25045038f2d38"],
|
|
"title": "feat(committer): conventional commit is a bit more intelligent now",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "da94133288727d35dae9b91866a25045038f2d38",
|
|
"parents": ["1541f54503d2e1cf39bd777c0ca5ab5eb78772ba"],
|
|
"title": "docs(README): motivation",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "1541f54503d2e1cf39bd777c0ca5ab5eb78772ba",
|
|
"parents": ["ddc855a637b7879108308b8dbd85a0fd27c7e0e7"],
|
|
"title": "Bump version: 0.9.1 → 0.9.2",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "ddc855a637b7879108308b8dbd85a0fd27c7e0e7",
|
|
"parents": ["46e9032e18a819e466618c7a014bcb0e9981af9e"],
|
|
"title": "refactor: renamed conventional_changelog to conventional_commits, not backward compatible",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "46e9032e18a819e466618c7a014bcb0e9981af9e",
|
|
"parents": ["0fef73cd7dc77a25b82e197e7c1d3144a58c1350"],
|
|
"title": "Bump version: 0.9.0 → 0.9.1",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
{
|
|
"rev": "0fef73cd7dc77a25b82e197e7c1d3144a58c1350",
|
|
"parents": [],
|
|
"title": "fix(setup.py): future is now required for every python version",
|
|
"body": "",
|
|
"author": "Commitizen",
|
|
"author_email": "author@cz.dev",
|
|
},
|
|
]
|
|
|
|
|
|
TAGS = [
|
|
("v1.2.0", "141ee441c9c9da0809c554103a558eb17c30ed17", "2019-04-19"),
|
|
("v1.1.1", "56c8a8da84e42b526bcbe130bd194306f7c7e813", "2019-04-18"),
|
|
("v1.1.0", "17efb44d2cd16f6621413691a543e467c7d2dda6", "2019-04-14"),
|
|
("v1.0.0", "aa44a92d68014d0da98965c0c2cb8c07957d4362", "2019-03-01"),
|
|
("1.0.0b2", "aab33d13110f26604fb786878856ec0b9e5fc32b", "2019-01-18"),
|
|
("v1.0.0b1", "7c7e96b723c2aaa1aec3a52561f680adf0b60e97", "2019-01-17"),
|
|
("v0.9.11", "c52eca6f74f844ab3ffbde61d98ef96071e132b7", "2018-12-17"),
|
|
("v0.9.10", "b3f89892222340150e32631ae6b7aab65230036f", "2018-09-22"),
|
|
("v0.9.9", "684e0259cc95c7c5e94854608cd3dcebbd53219e", "2018-09-22"),
|
|
("v0.9.8", "64168f18d4628718c49689ee16430549e96c5d4b", "2018-09-22"),
|
|
("v0.9.7", "33b0bf1a0a4dc60aac45ed47476d2e5473add09e", "2018-09-22"),
|
|
("v0.9.6", "bef4a86761a3bda309c962bae5d22ce9b57119e4", "2018-09-19"),
|
|
("v0.9.5", "3e31714dc737029d96898f412e4ecd2be1bcd0ce", "2018-08-24"),
|
|
("v0.9.4", "0cf6ada372470c8d09e6c9e68ebf94bbd5a1656f", "2018-08-02"),
|
|
("v0.9.3", "dacc86159b260ee98eb5f57941c99ba731a01399", "2018-07-28"),
|
|
("v0.9.2", "1541f54503d2e1cf39bd777c0ca5ab5eb78772ba", "2017-11-11"),
|
|
("v0.9.1", "46e9032e18a819e466618c7a014bcb0e9981af9e", "2017-11-11"),
|
|
]
|
|
|
|
|
|
@pytest.fixture
|
|
def gitcommits() -> list:
|
|
commits = [
|
|
git.GitCommit(
|
|
commit["rev"],
|
|
commit["title"],
|
|
commit["body"],
|
|
commit["author"],
|
|
commit["author_email"],
|
|
commit["parents"],
|
|
)
|
|
for commit in COMMITS_DATA
|
|
]
|
|
return commits
|
|
|
|
|
|
@pytest.fixture
|
|
def tags() -> list:
|
|
tags = [git.GitTag(*tag) for tag in TAGS]
|
|
return tags
|
|
|
|
|
|
@pytest.fixture
|
|
def changelog_content() -> str:
|
|
changelog_path = "tests/CHANGELOG_FOR_TEST.md"
|
|
with open(changelog_path, encoding="utf-8") as f:
|
|
return f.read()
|
|
|
|
|
|
def test_get_commit_tag_is_a_version(gitcommits, tags):
|
|
commit = gitcommits[0]
|
|
tag = git.GitTag(*TAGS[0])
|
|
current_key = changelog.get_commit_tag(commit, tags)
|
|
assert current_key == tag
|
|
|
|
|
|
def test_get_commit_tag_is_None(gitcommits, tags):
|
|
commit = gitcommits[1]
|
|
current_key = changelog.get_commit_tag(commit, tags)
|
|
assert current_key is None
|
|
|
|
|
|
@pytest.mark.parametrize("test_input", TAGS)
|
|
def test_valid_tag_included_in_changelog(test_input):
|
|
tag = git.GitTag(*test_input)
|
|
rules = changelog.TagRules()
|
|
assert rules.include_in_changelog(tag)
|
|
|
|
|
|
def test_invalid_tag_included_in_changelog():
|
|
tag = git.GitTag("not_a_version", "rev", "date")
|
|
rules = changelog.TagRules()
|
|
assert not rules.include_in_changelog(tag)
|
|
|
|
|
|
COMMITS_TREE = (
|
|
{
|
|
"version": "v1.2.0",
|
|
"date": "2019-04-19",
|
|
"changes": {
|
|
"feat": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "custom cz plugins now support bumping version",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v1.1.1",
|
|
"date": "2019-04-18",
|
|
"changes": {
|
|
"refactor": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "changed stdout statements",
|
|
},
|
|
{
|
|
"scope": "schema",
|
|
"breaking": None,
|
|
"message": "command logic removed from commitizen base",
|
|
},
|
|
{
|
|
"scope": "info",
|
|
"breaking": None,
|
|
"message": "command logic removed from commitizen base",
|
|
},
|
|
{
|
|
"scope": "example",
|
|
"breaking": None,
|
|
"message": "command logic removed from commitizen base",
|
|
},
|
|
{
|
|
"scope": "commit",
|
|
"breaking": None,
|
|
"message": "moved most of the commit logic to the commit command",
|
|
},
|
|
],
|
|
"fix": [
|
|
{
|
|
"scope": "bump",
|
|
"breaking": None,
|
|
"message": "commit message now fits better with semver",
|
|
},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "conventional commit 'breaking change' in body instead of title",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"version": "v1.1.0",
|
|
"date": "2019-04-14",
|
|
"changes": {
|
|
"feat": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "new working bump command",
|
|
},
|
|
{"scope": None, "breaking": None, "message": "create version tag"},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "update given files with new version",
|
|
},
|
|
{
|
|
"scope": "config",
|
|
"breaking": None,
|
|
"message": "new set key, used to set version to cfg",
|
|
},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "support for pyproject.toml",
|
|
},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "first semantic version bump implementation",
|
|
},
|
|
],
|
|
"fix": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "removed all from commit",
|
|
},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "fix config file not working",
|
|
},
|
|
],
|
|
"refactor": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "added commands folder, better integration with decli",
|
|
}
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"version": "v1.0.0",
|
|
"date": "2019-03-01",
|
|
"changes": {
|
|
"refactor": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "removed delegator, added decli and many tests",
|
|
}
|
|
],
|
|
"BREAKING CHANGE": [
|
|
{"scope": None, "breaking": None, "message": "API is stable"}
|
|
],
|
|
},
|
|
},
|
|
{"version": "1.0.0b2", "date": "2019-01-18", "changes": {}},
|
|
{
|
|
"version": "v1.0.0b1",
|
|
"date": "2019-01-17",
|
|
"changes": {
|
|
"feat": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "py3 only, tests and conventional commits 1.0",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.11",
|
|
"date": "2018-12-17",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": "config",
|
|
"breaking": None,
|
|
"message": "load config reads in order without failing if there is no commitizen section",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.10",
|
|
"date": "2018-09-22",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "parse scope (this is my punishment for not having tests)",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.9",
|
|
"date": "2018-09-22",
|
|
"changes": {
|
|
"fix": [{"scope": None, "breaking": None, "message": "parse scope empty"}]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.8",
|
|
"date": "2018-09-22",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": "scope",
|
|
"breaking": None,
|
|
"message": "parse correctly again",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.7",
|
|
"date": "2018-09-22",
|
|
"changes": {
|
|
"fix": [{"scope": "scope", "breaking": None, "message": "parse correctly"}]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.6",
|
|
"date": "2018-09-19",
|
|
"changes": {
|
|
"refactor": [
|
|
{
|
|
"scope": "conventionalCommit",
|
|
"breaking": None,
|
|
"message": "moved filters to questions instead of message",
|
|
}
|
|
],
|
|
"fix": [
|
|
{
|
|
"scope": "manifest",
|
|
"breaking": None,
|
|
"message": "included missing files",
|
|
}
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.5",
|
|
"date": "2018-08-24",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": "config",
|
|
"breaking": None,
|
|
"message": "home path for python versions between 3.0 and 3.5",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.4",
|
|
"date": "2018-08-02",
|
|
"changes": {
|
|
"feat": [{"scope": "cli", "breaking": None, "message": "added version"}]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.3",
|
|
"date": "2018-07-28",
|
|
"changes": {
|
|
"feat": [
|
|
{
|
|
"scope": "committer",
|
|
"breaking": None,
|
|
"message": "conventional commit is a bit more intelligent now",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.2",
|
|
"date": "2017-11-11",
|
|
"changes": {
|
|
"refactor": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "renamed conventional_changelog to conventional_commits, not backward compatible",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.1",
|
|
"date": "2017-11-11",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": "setup.py",
|
|
"breaking": None,
|
|
"message": "future is now required for every python version",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
)
|
|
|
|
COMMITS_TREE_AFTER_MERGED_PRERELEASES = (
|
|
{
|
|
"version": "v1.2.0",
|
|
"date": "2019-04-19",
|
|
"changes": {
|
|
"feat": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "custom cz plugins now support bumping version",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v1.1.1",
|
|
"date": "2019-04-18",
|
|
"changes": {
|
|
"refactor": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "changed stdout statements",
|
|
},
|
|
{
|
|
"scope": "schema",
|
|
"breaking": None,
|
|
"message": "command logic removed from commitizen base",
|
|
},
|
|
{
|
|
"scope": "info",
|
|
"breaking": None,
|
|
"message": "command logic removed from commitizen base",
|
|
},
|
|
{
|
|
"scope": "example",
|
|
"breaking": None,
|
|
"message": "command logic removed from commitizen base",
|
|
},
|
|
{
|
|
"scope": "commit",
|
|
"breaking": None,
|
|
"message": "moved most of the commit logic to the commit command",
|
|
},
|
|
],
|
|
"fix": [
|
|
{
|
|
"scope": "bump",
|
|
"breaking": None,
|
|
"message": "commit message now fits better with semver",
|
|
},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "conventional commit 'breaking change' in body instead of title",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"version": "v1.1.0",
|
|
"date": "2019-04-14",
|
|
"changes": {
|
|
"feat": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "new working bump command",
|
|
},
|
|
{"scope": None, "breaking": None, "message": "create version tag"},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "update given files with new version",
|
|
},
|
|
{
|
|
"scope": "config",
|
|
"breaking": None,
|
|
"message": "new set key, used to set version to cfg",
|
|
},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "support for pyproject.toml",
|
|
},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "first semantic version bump implementation",
|
|
},
|
|
],
|
|
"fix": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "removed all from commit",
|
|
},
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "fix config file not working",
|
|
},
|
|
],
|
|
"refactor": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "added commands folder, better integration with decli",
|
|
}
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"version": "v1.0.0",
|
|
"date": "2019-03-01",
|
|
"changes": {
|
|
"refactor": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "removed delegator, added decli and many tests",
|
|
}
|
|
],
|
|
"feat": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "py3 only, tests and conventional commits 1.0",
|
|
}
|
|
],
|
|
"BREAKING CHANGE": [
|
|
{"scope": None, "breaking": None, "message": "API is stable"}
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.11",
|
|
"date": "2018-12-17",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": "config",
|
|
"breaking": None,
|
|
"message": "load config reads in order without failing if there is no commitizen section",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.10",
|
|
"date": "2018-09-22",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "parse scope (this is my punishment for not having tests)",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.9",
|
|
"date": "2018-09-22",
|
|
"changes": {
|
|
"fix": [{"scope": None, "breaking": None, "message": "parse scope empty"}]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.8",
|
|
"date": "2018-09-22",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": "scope",
|
|
"breaking": None,
|
|
"message": "parse correctly again",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.7",
|
|
"date": "2018-09-22",
|
|
"changes": {
|
|
"fix": [{"scope": "scope", "breaking": None, "message": "parse correctly"}]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.6",
|
|
"date": "2018-09-19",
|
|
"changes": {
|
|
"refactor": [
|
|
{
|
|
"scope": "conventionalCommit",
|
|
"breaking": None,
|
|
"message": "moved filters to questions instead of message",
|
|
}
|
|
],
|
|
"fix": [
|
|
{
|
|
"scope": "manifest",
|
|
"breaking": None,
|
|
"message": "included missing files",
|
|
}
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.5",
|
|
"date": "2018-08-24",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": "config",
|
|
"breaking": None,
|
|
"message": "home path for python versions between 3.0 and 3.5",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.4",
|
|
"date": "2018-08-02",
|
|
"changes": {
|
|
"feat": [{"scope": "cli", "breaking": None, "message": "added version"}]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.3",
|
|
"date": "2018-07-28",
|
|
"changes": {
|
|
"feat": [
|
|
{
|
|
"scope": "committer",
|
|
"breaking": None,
|
|
"message": "conventional commit is a bit more intelligent now",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.2",
|
|
"date": "2017-11-11",
|
|
"changes": {
|
|
"refactor": [
|
|
{
|
|
"scope": None,
|
|
"breaking": None,
|
|
"message": "renamed conventional_changelog to conventional_commits, not backward compatible",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"version": "v0.9.1",
|
|
"date": "2017-11-11",
|
|
"changes": {
|
|
"fix": [
|
|
{
|
|
"scope": "setup.py",
|
|
"breaking": None,
|
|
"message": "future is now required for every python version",
|
|
}
|
|
]
|
|
},
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("merge_prereleases", (True, False))
|
|
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, rules=rules
|
|
)
|
|
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
|
|
assert "parents" in change
|
|
|
|
|
|
def test_generate_tree_from_commits_with_no_commits(tags):
|
|
gitcommits = []
|
|
parser = ConventionalCommitsCz.commit_parser
|
|
changelog_pattern = ConventionalCommitsCz.bump_pattern
|
|
tree = changelog.generate_tree_from_commits(
|
|
gitcommits, tags, parser, changelog_pattern
|
|
)
|
|
|
|
assert tuple(tree) == ({"changes": {}, "date": "", "version": "Unreleased"},)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"change_type_order, expected_reordering",
|
|
(
|
|
([], {}),
|
|
(
|
|
["BREAKING CHANGE", "refactor"],
|
|
{
|
|
"1.1.0": {
|
|
"original": ["feat", "fix", "refactor"],
|
|
"sorted": ["refactor", "feat", "fix"],
|
|
},
|
|
"1.0.0": {
|
|
"original": ["refactor", "BREAKING CHANGE"],
|
|
"sorted": ["BREAKING CHANGE", "refactor"],
|
|
},
|
|
},
|
|
),
|
|
),
|
|
)
|
|
def test_order_changelog_tree(change_type_order, expected_reordering):
|
|
tree = changelog.order_changelog_tree(COMMITS_TREE, change_type_order)
|
|
|
|
for index, entry in enumerate(tuple(tree)):
|
|
version = tree[index]["version"]
|
|
if version in expected_reordering:
|
|
# Verify that all keys are present
|
|
assert [*tree[index].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 [*COMMITS_TREE[index]["changes"].keys()] == expected["original"]
|
|
else:
|
|
assert [*entry["changes"].keys()] == [*tree[index]["changes"].keys()]
|
|
|
|
|
|
def test_order_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)
|
|
|
|
assert "Change types contain duplicates types" in str(excinfo)
|
|
|
|
|
|
def test_render_changelog(
|
|
gitcommits, tags, changelog_content, any_changelog_format: ChangelogFormat
|
|
):
|
|
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
|
|
)
|
|
result = changelog.render_changelog(tree, loader, template)
|
|
assert result == changelog_content
|
|
|
|
|
|
def test_render_changelog_from_default_plugin_values(
|
|
gitcommits, tags, changelog_content, any_changelog_format: ChangelogFormat
|
|
):
|
|
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
|
|
)
|
|
result = changelog.render_changelog(tree, loader, template)
|
|
assert result == changelog_content
|
|
|
|
|
|
def test_render_changelog_override_loader(gitcommits, tags, tmp_path: Path):
|
|
loader = FileSystemLoader(tmp_path)
|
|
template = "tpl.j2"
|
|
tpl = "loader overridden"
|
|
(tmp_path / template).write_text(tpl)
|
|
parser = ConventionalCommitsCz.commit_parser
|
|
changelog_pattern = ConventionalCommitsCz.changelog_pattern
|
|
tree = changelog.generate_tree_from_commits(
|
|
gitcommits, tags, parser, changelog_pattern
|
|
)
|
|
result = changelog.render_changelog(tree, loader, template)
|
|
assert result == tpl
|
|
|
|
|
|
def test_render_changelog_override_template_from_cwd(
|
|
gitcommits, tags, chdir: Path, any_changelog_format: ChangelogFormat
|
|
):
|
|
tpl = "overridden from cwd"
|
|
template = any_changelog_format.template
|
|
(chdir / template).write_text(tpl)
|
|
parser = ConventionalCommitsCz.commit_parser
|
|
changelog_pattern = ConventionalCommitsCz.changelog_pattern
|
|
loader = ConventionalCommitsCz.template_loader
|
|
tree = changelog.generate_tree_from_commits(
|
|
gitcommits, tags, parser, changelog_pattern
|
|
)
|
|
result = changelog.render_changelog(tree, loader, template)
|
|
assert result == tpl
|
|
|
|
|
|
def test_render_changelog_override_template_from_cwd_with_custom_name(
|
|
gitcommits, tags, chdir: Path
|
|
):
|
|
tpl = "template overridden from cwd"
|
|
tpl_name = "tpl.j2"
|
|
(chdir / tpl_name).write_text(tpl)
|
|
parser = ConventionalCommitsCz.commit_parser
|
|
changelog_pattern = ConventionalCommitsCz.changelog_pattern
|
|
loader = ConventionalCommitsCz.template_loader
|
|
tree = changelog.generate_tree_from_commits(
|
|
gitcommits, tags, parser, changelog_pattern
|
|
)
|
|
result = changelog.render_changelog(tree, loader, tpl_name)
|
|
assert result == tpl
|
|
|
|
|
|
def test_render_changelog_override_loader_and_template(
|
|
gitcommits, tags, tmp_path: Path
|
|
):
|
|
loader = FileSystemLoader(tmp_path)
|
|
tpl = "loader and template overridden"
|
|
tpl_name = "tpl.j2"
|
|
(tmp_path / tpl_name).write_text(tpl)
|
|
parser = ConventionalCommitsCz.commit_parser
|
|
changelog_pattern = ConventionalCommitsCz.bump_pattern
|
|
tree = changelog.generate_tree_from_commits(
|
|
gitcommits, tags, parser, changelog_pattern
|
|
)
|
|
result = changelog.render_changelog(tree, loader, tpl_name)
|
|
assert result == tpl
|
|
|
|
|
|
def test_render_changelog_support_arbitrary_kwargs(gitcommits, tags, tmp_path: Path):
|
|
loader = FileSystemLoader(tmp_path)
|
|
tpl_name = "tpl.j2"
|
|
(tmp_path / tpl_name).write_text("{{ key }}")
|
|
parser = ConventionalCommitsCz.commit_parser
|
|
changelog_pattern = ConventionalCommitsCz.changelog_pattern
|
|
tree = changelog.generate_tree_from_commits(
|
|
gitcommits, tags, parser, changelog_pattern
|
|
)
|
|
result = changelog.render_changelog(tree, loader, tpl_name, key="value")
|
|
assert result == "value"
|
|
|
|
|
|
def test_render_changelog_unreleased(gitcommits, any_changelog_format: ChangelogFormat):
|
|
some_commits = gitcommits[:7]
|
|
parser = ConventionalCommitsCz.commit_parser
|
|
changelog_pattern = ConventionalCommitsCz.changelog_pattern
|
|
loader = ConventionalCommitsCz.template_loader
|
|
template = any_changelog_format.template
|
|
tree = changelog.generate_tree_from_commits(
|
|
some_commits, [], parser, changelog_pattern
|
|
)
|
|
result = changelog.render_changelog(tree, loader, template)
|
|
assert "Unreleased" in result
|
|
|
|
|
|
def test_render_changelog_tag_and_unreleased(
|
|
gitcommits, tags, any_changelog_format: ChangelogFormat
|
|
):
|
|
some_commits = gitcommits[:7]
|
|
single_tag = [
|
|
tag for tag in tags if tag.rev == "56c8a8da84e42b526bcbe130bd194306f7c7e813"
|
|
]
|
|
|
|
parser = ConventionalCommitsCz.commit_parser
|
|
changelog_pattern = ConventionalCommitsCz.changelog_pattern
|
|
loader = ConventionalCommitsCz.template_loader
|
|
template = any_changelog_format.template
|
|
tree = changelog.generate_tree_from_commits(
|
|
some_commits, single_tag, parser, changelog_pattern
|
|
)
|
|
result = changelog.render_changelog(tree, loader, template)
|
|
|
|
assert "Unreleased" in result
|
|
assert "## v1.1.1" in result
|
|
|
|
|
|
def test_render_changelog_with_change_type(
|
|
gitcommits, tags, any_changelog_format: ChangelogFormat
|
|
):
|
|
new_title = ":some-emoji: feature"
|
|
change_type_map = {"feat": new_title}
|
|
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, change_type_map=change_type_map
|
|
)
|
|
result = changelog.render_changelog(tree, loader, template)
|
|
assert new_title in result
|
|
|
|
|
|
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}"
|
|
)
|
|
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)
|
|
|
|
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_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
|
|
):
|
|
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<type>.+)$")
|
|
# 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_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],
|
|
tags[2],
|
|
) # len here is 3, but we expect one more tag as designed
|
|
res = changelog.get_smart_tag_range(tags, start.name, end.name)
|
|
assert 4 == len(res)
|
|
|
|
|
|
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
|