Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Refactor config #457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions commitizen/bump.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,13 @@

from packaging.version import Version

from commitizen.defaults import (
MAJOR,
MINOR,
PATCH,
bump_map,
bump_message,
bump_pattern,
)
from commitizen.defaults import MAJOR, MINOR, PATCH, bump_message
from commitizen.exceptions import CurrentVersionNotFoundError
from commitizen.git import GitCommit


def find_increment(
commits: List[GitCommit],
regex: str = bump_pattern,
increments_map: Union[dict, OrderedDict] = bump_map,
commits: List[GitCommit], regex: str, increments_map: Union[dict, OrderedDict]
) -> Optional[str]:

if isinstance(increments_map, dict):
Expand Down Expand Up @@ -141,7 +132,7 @@ def generate_version(

def update_version_in_files(
current_version: str, new_version: str, files: List[str], *, check_consistency=False
):
) -> None:
"""Change old version to the new one in every file given.

Note that this version is not the tag formatted one.
Expand Down Expand Up @@ -205,7 +196,7 @@ def _version_to_regex(version: str):
return re.compile(f"{clean_regex}")


def create_tag(version: Union[Version, str], tag_format: Optional[str] = None):
def create_tag(version: Union[Version, str], tag_format: Optional[str] = None) -> str:
"""The tag and the software version might be different.

That's why this function exists.
Expand Down
2 changes: 1 addition & 1 deletion commitizen/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def generate_tree_from_commits(
commits: List[GitCommit],
tags: List[GitTag],
commit_parser: str,
changelog_pattern: str = defaults.bump_pattern,
changelog_pattern: str,
unreleased_version: Optional[str] = None,
change_type_map: Optional[Dict[str, str]] = None,
changelog_message_builder_hook: Optional[Callable] = None,
Expand Down
4 changes: 2 additions & 2 deletions commitizen/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def __call__(self):
out.line(f"Config file {self.config.path} already exists")

def _ask_config_path(self) -> str:
name = questionary.select(
name: str = questionary.select(
"Please choose a supported config file: (default: pyproject.toml)",
choices=config_files,
default="pyproject.toml",
Expand All @@ -58,7 +58,7 @@ def _ask_config_path(self) -> str:
return name

def _ask_name(self) -> str:
name = questionary.select(
name: str = questionary.select(
"Please choose a cz (commit rule): (default: cz_conventional_commits)",
choices=list(registry.keys()),
default="cz_conventional_commits",
Expand Down
14 changes: 7 additions & 7 deletions commitizen/config/base_config.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from pathlib import Path
from typing import Any, Dict, Optional, Union
from typing import Optional, Union

from commitizen.defaults import DEFAULT_SETTINGS
from commitizen.defaults import DEFAULT_SETTINGS, Settings


class BaseConfig:
def __init__(self):
self._settings: Dict[str, Any] = DEFAULT_SETTINGS.copy()
self._settings: Settings = DEFAULT_SETTINGS.copy()
self._path: Optional[Path] = None

@property
def settings(self) -> Dict[str, Any]:
def settings(self) -> Settings:
return self._settings

@property
Expand All @@ -25,11 +25,11 @@ def set_key(self, key, value):
"""
raise NotImplementedError()

def update(self, data: dict):
def update(self, data: Settings) -> None:
self._settings.update(data)

def add_path(self, path: Union[str, Path]):
def add_path(self, path: Union[str, Path]) -> None:
self._path = Path(path)

def _parse_setting(self, data: Union[bytes, str]) -> dict:
def _parse_setting(self, data: Union[bytes, str]) -> None:
raise NotImplementedError()
2 changes: 1 addition & 1 deletion commitizen/config/json_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def set_key(self, key, value):
json.dump(parser, f, indent=2)
return self

def _parse_setting(self, data: Union[bytes, str]):
def _parse_setting(self, data: Union[bytes, str]) -> None:
"""We expect to have a section in .cz.json looking like

```
Expand Down
2 changes: 1 addition & 1 deletion commitizen/config/toml_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def set_key(self, key, value):
f.write(parser.as_string().encode("utf-8"))
return self

def _parse_setting(self, data: Union[bytes, str]):
def _parse_setting(self, data: Union[bytes, str]) -> None:
"""We expect to have a section in pyproject looking like

```
Expand Down
2 changes: 1 addition & 1 deletion commitizen/config/yaml_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def init_empty_config_content(self):
with open(self.path, "a") as json_file:
yaml.dump({"commitizen": {}}, json_file)

def _parse_setting(self, data: Union[bytes, str]):
def _parse_setting(self, data: Union[bytes, str]) -> None:
"""We expect to have a section in cz.yaml looking like

```
Expand Down
5 changes: 3 additions & 2 deletions commitizen/cz/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@

from commitizen import git
from commitizen.config.base_config import BaseConfig
from commitizen.defaults import Questions


class BaseCommitizen(metaclass=ABCMeta):
bump_pattern: Optional[str] = None
bump_map: Optional[dict] = None
bump_map: Optional[Dict[str, str]] = None
default_style_config: List[Tuple[str, str]] = [
("qmark", "fg:#ff9d00 bold"),
("question", "bold"),
Expand Down Expand Up @@ -45,7 +46,7 @@ def __init__(self, config: BaseConfig):
self.config.settings.update({"style": BaseCommitizen.default_style_config})

@abstractmethod
def questions(self) -> list:
def questions(self) -> Questions:
"""Questions regarding the commit message."""

@abstractmethod
Expand Down
8 changes: 4 additions & 4 deletions commitizen/cz/conventional_commits/conventional_commits.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import os
import re
from typing import Any, Dict, List

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

__all__ = ["ConventionalCommitsCz"]

Expand All @@ -31,16 +31,16 @@ class ConventionalCommitsCz(BaseCommitizen):
bump_pattern = defaults.bump_pattern
bump_map = defaults.bump_map
commit_parser = defaults.commit_parser
changelog_pattern = defaults.bump_pattern
version_parser = defaults.version_parser
change_type_map = {
"feat": "Feat",
"fix": "Fix",
"refactor": "Refactor",
"perf": "Perf",
}

def questions(self) -> List[Dict[str, Any]]:
questions: List[Dict[str, Any]] = [
def questions(self) -> Questions:
questions: Questions = [
{
"type": "list",
"name": "prefix",
Expand Down
9 changes: 5 additions & 4 deletions commitizen/cz/customize/customize.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
except ImportError:
from string import Template # type: ignore

from typing import Any, Dict, List, Optional
from typing import Optional

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"]
Expand Down Expand Up @@ -37,11 +38,11 @@ def __init__(self, config: BaseConfig):
if custom_change_type_order:
self.change_type_order = custom_change_type_order

def questions(self) -> List[Dict[str, Any]]:
return self.custom_settings.get("questions")
def questions(self) -> Questions:
return self.custom_settings.get("questions", [{}])

def message(self, answers: dict) -> str:
message_template = Template(self.custom_settings.get("message_template"))
message_template = Template(self.custom_settings.get("message_template", ""))
if getattr(Template, "substitute", None):
return message_template.substitute(**answers) # type: ignore
else:
Expand Down
4 changes: 2 additions & 2 deletions commitizen/cz/jira/jira.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import os
from typing import Any, Dict, List

from commitizen.cz.base import BaseCommitizen
from commitizen.defaults import Questions

__all__ = ["JiraSmartCz"]


class JiraSmartCz(BaseCommitizen):
def questions(self) -> List[Dict[str, Any]]:
def questions(self) -> Questions:
questions = [
{
"type": "input",
Expand Down
43 changes: 40 additions & 3 deletions commitizen/defaults.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
import pathlib
from collections import OrderedDict
from typing import Any, Dict, List
from typing import Any, Iterable, List, MutableMapping, Optional, Tuple, Union

from typing_extensions import TypedDict

# Type
Questions = Iterable[MutableMapping[str, Any]]


class CzSettings(TypedDict, total=False):
bump_pattern: str
bump_map: "OrderedDict[str, str]"
change_type_order: List[str]

questions: Questions
example: Optional[str]
schema_pattern: Optional[str]
schema: Optional[str]
info_path: Union[str, pathlib.Path]
info: str
message_template: str


class Settings(TypedDict, total=False):
name: str
version: Optional[str]
version_files: List[str]
tag_format: Optional[str]
bump_message: Optional[str]
changelog_file: str
changelog_incremental: bool
changelog_start_rev: Optional[str]
update_changelog_on_bump: bool
use_shortcuts: bool
style: Optional[List[Tuple[str, str]]]
customize: CzSettings


name: str = "cz_conventional_commits"
config_files: List[str] = [
Expand All @@ -11,7 +47,7 @@
"cz.yaml",
]

DEFAULT_SETTINGS: Dict[str, Any] = {
DEFAULT_SETTINGS: Settings = {
"name": "cz_conventional_commits",
"version": None,
"version_files": [],
Expand Down Expand Up @@ -39,9 +75,10 @@
(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"]

commit_parser = r"^(?P<change_type>feat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P<scope>[^()\r\n]*)\)|\()?(?P<breaking>!)?:\s(?P<message>.*)?" # noqa
version_parser = r"(?P<version>([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?(\w+)?)"
6 changes: 3 additions & 3 deletions commitizen/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class GitObject:
def __eq__(self, other) -> bool:
if not hasattr(other, "rev"):
return False
return self.rev == other.rev
return self.rev == other.rev # type: ignore


class GitCommit(GitObject):
Expand Down Expand Up @@ -54,12 +54,12 @@ def from_line(cls, line: str, inner_delimiter: str) -> "GitTag":
return cls(name=name, rev=obj, date=date)


def tag(tag: str, annotated: bool = False):
def tag(tag: str, annotated: bool = False) -> cmd.Command:
c = cmd.run(f"git tag -a {tag} -m {tag}" if annotated else f"git tag {tag}")
return c


def commit(message: str, args: str = ""):
def commit(message: str, args: str = "") -> cmd.Command:
f = NamedTemporaryFile("wb", delete=False)
f.write(message.encode("utf-8"))
f.close()
Expand Down
10 changes: 5 additions & 5 deletions commitizen/out.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@
from termcolor import colored


def write(value: str, *args):
def write(value: str, *args) -> None:
"""Intended to be used when value is multiline."""
print(value, *args)


def line(value: str, *args, **kwargs):
def line(value: str, *args, **kwargs) -> None:
"""Wrapper in case I want to do something different later."""
print(value, *args, **kwargs)


def error(value: str):
def error(value: str) -> None:
message = colored(value, "red")
line(message, file=sys.stderr)


def success(value: str):
def success(value: str) -> None:
message = colored(value, "green")
line(message)


def info(value: str):
def info(value: str) -> None:
message = colored(value, "blue")
line(message)

Expand Down
13 changes: 7 additions & 6 deletions docs/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ commitizen:

| Parameter | Type | Default | Description |
| ------------------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `questions` | `dict` | `None` | Questions regarding the commit message. Detailed below. |
| `questions` | `Questions` | `None` | Questions regarding the commit message. Detailed below. The type `Questions` is an alias to `Iterable[MutableMapping[str, Any]]` which is definied 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`. |
Expand All @@ -152,6 +152,7 @@ commitizen:
| `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"]` |

[jinja2]: https://jinja.palletsprojects.com/en/2.10.x/

#### Detailed `questions` content

| Parameter | Type | Default | Description |
Expand All @@ -162,7 +163,6 @@ commitizen:
| `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)** |

[different-question-types]: https://github.com/tmbo/questionary#different-question-types

#### Shortcut keys
Expand Down Expand Up @@ -194,15 +194,16 @@ See [commitizen_cz_template](https://github.com/commitizen-tools/commitizen_cz_t

Create a file starting with `cz_`, for example `cz_jira.py`. This prefix is used to detect the plug-in. Same method [flask uses]

Inherit from `BaseCommitizen`, and you must define `questions` and
`message`. The others are optional.
Inherit from `BaseCommitizen`, and you must define `questions` and `message`. The others are optional.

```python
from commitizen.cz.base import BaseCommitizen
from commitizen.defaults import Questions

class JiraCz(BaseCommitizen):

def questions(self) -> list:
# Questions = Iterable[MutableMapping[str, Any]]
# It expects a list with dictionaries.
def questions(self) -> Questions:
"""Questions regarding the commit message."""
questions = [
{
Expand Down
Loading