PK!z,,commitizen/__init__.pyimport logging import logging.config from commitizen.cz.base import BaseCommitizen LOGGING = { "version": 1, "disable_existing_loggers": True, "formatters": {"standard": {"format": "%(message)s"}}, "handlers": { "default": { "level": "DEBUG", "formatter": "standard", "class": "logging.StreamHandler", } }, "loggers": { "commitizen": {"handlers": ["default"], "level": "INFO", "propagate": True} }, } logging.config.dictConfig(LOGGING) __all__ = ["BaseCommitizen"] PK!dqHHcommitizen/__main__.pyfrom commitizen.cli import main if __name__ == "__main__": main() PK!Gcommitizen/__version__.py__version__ = "1.0.0" PK!PfW66commitizen/application.pyimport logging from typing import Optional from commitizen.cz import registry from commitizen.__version__ import __version__ logger = logging.getLogger(__name__) class Application: name: Optional[str] = None def __init__(self, name: str): self.name = name @property def cz(self): try: _cz = registry[self.name]() except KeyError: msg_error = ( "The commiter has not been found in the system.\n\n" "Try running 'pip install {name}'\n" ) logger.info(msg_error.format(name=self.name)) raise SystemExit(1) else: return _cz @property def version(self): return __version__ def detected_cz(*args, **kwargs): print("\n".join(registry.keys())) PK! % % commitizen/cli.pyimport io import os import sys import logging import argparse from decli import cli from pathlib import Path from configparser import RawConfigParser, NoSectionError from commitizen.application import Application from commitizen import deafults logger = logging.getLogger(__name__) 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/" ), "formatter_class": argparse.RawDescriptionHelpFormatter, "arguments": [ {"name": "--debug", "action": "store_true", "help": "use debug mode"}, { "name": ["-n", "--name"], "default": deafults.NAME, "help": "use the given commitizen", }, { "name": ["--version"], "action": "store_true", "help": "get the version of the installed commitizen", }, ], "subcommands": { "title": "commands", "commands": [ { "name": "ls", "help": "show available commitizens", "func": lambda app: app.detected_cz, }, { "name": ["commit", "c"], "help": "create new commit", "func": lambda app: app.cz.run, }, { "name": "example", "help": "show commit example", "func": lambda app: app.cz.show_example, }, { "name": "info", "help": "show information about the cz", "func": lambda app: app.cz.show_info, }, { "name": "schema", "help": "show commit schema", "func": lambda app: app.cz.show_schema, }, ], }, } def load_cfg(): settings = {"name": deafults.NAME} config = RawConfigParser("") home = str(Path.home()) config_file = ".cz" global_cfg = os.path.join(home, config_file) # load cfg from current project configs = ["setup.cfg", ".cz.cfg", config_file, global_cfg] for cfg in configs: if not os.path.exists(config_file) and os.path.exists(cfg): config_file = cfg break config_file_exists = os.path.exists(config_file) if config_file_exists: logger.debug('Reading file "%s"', config_file) config.readfp(io.open(config_file, "rt", encoding="utf-8")) log_config = io.StringIO() config.write(log_config) try: settings.update(dict(config.items("commitizen"))) break except NoSectionError: # The file does not have commitizen section continue return settings def main(): config = load_cfg() parser = cli(data) # Show help if no arg provided if len(sys.argv) == 1: parser.print_help(sys.stderr) raise SystemExit(1) args = parser.parse_args() app = Application(**config) if args.name: app.name = args.name if args.debug: logging.getLogger("commitizen").setLevel(logging.DEBUG) if args.version: logger.info(app.version) sys.exit(0) args.func(app)(args) PK!dTŕcommitizen/cmd.pyimport subprocess from typing import NamedTuple class Command(NamedTuple): out: str err: str stdout: bytes stderr: bytes def run(cmd: str) -> Command: cmd.split() process = subprocess.Popen( cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout, stderr = process.communicate() return Command(stdout.decode(), stderr.decode(), stdout, stderr) PK!|jcommitizen/cz/__init__.pyimport importlib import pkgutil from commitizen.cz.conventional_commits import ConventionalCommitsCz from commitizen.cz.jira import JiraSmartCz registry = { name: importlib.import_module(name).discover_this for finder, name, ispkg in pkgutil.iter_modules() if name.startswith("cz_") } registry.update( {"cz_conventional_commits": ConventionalCommitsCz, "cz_jira": JiraSmartCz} ) PK!j Dbbcommitizen/cz/base.pyimport os import sys import logging from commitizen import cmd from abc import ABCMeta, abstractmethod from tempfile import NamedTemporaryFile from questionary import prompt logger = logging.getLogger(__name__) class BaseCommitizen(metaclass=ABCMeta): @abstractmethod def questions(self): """Questions regarding the commit message. Must have 'whaaaaat' format. More info: https://github.com/finklabs/whaaaaat/ :rtype: list """ @abstractmethod def message(self, answers): """Format your git message. :param answers: Use answers :type answers: dict :rtype: string """ def commit(self, message: str): f = NamedTemporaryFile("wb", delete=False) f.write(message.encode("utf-8")) f.close() c = cmd.run(f"git commit -a -F {f.name}") print(c.out or c.err) os.unlink(f.name) return c def example(self): """Example of the commit message. :rtype: string """ raise NotImplementedError("Not Implemented yet") def schema(self): """Schema definition of the commit message. :rtype: string """ raise NotImplementedError("Not Implemented yet") def info(self): """Information about the standardized commit message. :rtype: string """ raise NotImplementedError("Not Implemented yet") def show_example(self, *args, **kwargs): logger.info(self.example()) def show_schema(self, *args, **kwargs): logger.info(self.schema()) def show_info(self, *args, **kwargs): logger.info(self.info()) def run(self, *args, **kwargs): questions = self.questions() answers = prompt(questions) logger.debug("Answers:\n %s", answers) m = self.message(answers) logger.debug("Commit message generated:\n %s", m) c = self.commit(m) if c.err: logger.warning(c.err) sys.exit(1) if "nothing added" not in c.out: logger.info("Commit successful!") sys.exit(0) PK!<@@.commitizen/cz/conventional_commits/__init__.pyfrom .conventional_commits import ConventionalCommitsCz # noqa PK!6:commitizen/cz/conventional_commits/conventional_commits.pyimport os from commitizen.cz.base import BaseCommitizen __all__ = ["ConventionalCommitsCz"] class NoSubjectException(Exception): ... def parse_scope(text): if not text: return "" scope = text.strip().split() if len(scope) == 1: return scope[0] return "-".join(scope) def parse_subject(text): if isinstance(text, str): text = text.strip(".").strip() if not text: raise NoSubjectException return text class ConventionalCommitsCz(BaseCommitizen): def questions(self): questions = [ { "type": "list", "name": "prefix", "message": "Select the type of change you are committing", "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": "BREAKING CHANGE", "name": ( "BREAKING CHANGE: introduces a breaking API change. " "Correlates with MAJOR in SemVer" ), }, {"value": "docs", "name": "docs: Documentation only changes"}, { "value": "style", "name": ( "style: Changes that do not affect the " "meaning of the code (white-space, formatting," " missing semi-colons, etc)" ), }, { "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 (example scopes: pip, docker, npm)" ), }, { "value": "ci", "name": ( "ci: Changes to our CI configuration files and " "scripts (example scopes: GitLabCI)" ), }, ], }, { "type": "input", "name": "scope", "message": ( "Scope. Could be anything specifying place of the " "commit change (users, db, poll):\n" ), "filter": parse_scope, }, { "type": "input", "name": "subject", "filter": parse_subject, "message": ( "Subject. Concise description of the changes. " "Imperative, lower case and no final dot:\n" ), }, { "type": "input", "name": "body", "message": ( "Body. Motivation for the change and contrast this " "with previous behavior:\n" ), }, { "type": "input", "name": "footer", "message": ( "Footer. Information about Breaking Changes and " "reference issues that this commit closes:\n" ), }, ] return questions def message(self, answers): prefix = answers["prefix"] scope = answers["scope"] subject = answers["subject"] body = answers["body"] footer = answers["footer"] message = "" if prefix: message += "{0}".format(prefix) if scope: message += "({0})".format(scope) message += ": " if subject: message += "{0}".format(subject) if body: message += "\n\n{0}".format(body) if footer: message += "\n\n{0}".format(footer) return message def example(self): return ( "feat($injector): ability to load new modules after bootstrapping\n" "\nThe new method `$injector.loadNewModules(modules)` will add " "each of the\ninjectables to the injector and execute all of the " "config and run blocks\nfor each module passed to the method.\n" "\nCloses #324" ) def schema(self): return ( "(): \n" "\n" "\n" "\n" "