diff --git a/slapp/commands.py b/slapp/commands.py index 6df2d77..d47d1a0 100644 --- a/slapp/commands.py +++ b/slapp/commands.py @@ -1,13 +1,15 @@ import typer import git -from .main import app -from .config import get_config, set_config -from .utils import ( +from slapp.main import app +from slapp.config import get_config, set_config +from slapp.utils import ( parse_changelogs_from_repo, write_changelogs_to_file, echo_changelog, + get_autoincremented_version, ) +from slapp.constants import VERSION_TYPES @app.command() @@ -15,12 +17,33 @@ def init(): set_config() +def version_type_autocompletion(incomplete: str): + completion = [] + for version_type in VERSION_TYPES: + if version_type.startswith(incomplete): + completion.append(version_type) + return completion + + @app.command() -def release(version: str): +def release( + manual_version: str = typer.Argument( + None, + help="Manually added version name", + ), + version_type: str = typer.Option( + VERSION_TYPES[1], '--type', '-t', + help=f'Version type: {", ".join(VERSION_TYPES)}', + autocompletion=version_type_autocompletion + ), + dry: bool = typer.Option( + False, + help='Do not perform any actions with git repo' + ), +): config = get_config() if not config: return - try: repo = git.Repo(config['repo_directory'].get()) except git.NoSuchPathError: @@ -37,10 +60,17 @@ def release(version: str): changelogs = parse_changelogs_from_repo(repo) changelog_file = config['changelog_file'].get() + version = manual_version or get_autoincremented_version(changelog_file, version_type) + if not version: + return write_changelogs_to_file(version, changelogs, changelog_file) echo_changelog(version, changelogs) + if dry: + typer.echo('Skipping git actions.') + return + try: repo.git.add(changelog_file) repo.index.commit(f'Update {changelog_file}') diff --git a/slapp/constants.py b/slapp/constants.py new file mode 100644 index 0000000..4bab508 --- /dev/null +++ b/slapp/constants.py @@ -0,0 +1,10 @@ +CONFIG_FILE = 'slapp.yml' + +DEFAULT_CONFIG = { + 'repo_directory': '.git', + 'release_branch': 'main', + 'changelog_file': 'CHANGELOG.md', + 'bullet': '*', +} + +VERSION_TYPES = ('major', 'minor', 'patch') diff --git a/slapp/utils.py b/slapp/utils.py index e392c2b..9528f9d 100644 --- a/slapp/utils.py +++ b/slapp/utils.py @@ -1,7 +1,9 @@ import os +import re import git import marko import typer +from slapp.constants import VERSION_TYPES def extract_changelogs_from_commit(message: str or None,): @@ -46,7 +48,7 @@ def echo_changelog(version, changelogs): )) typer.echo('\n'.join(changelogs)) else: - typer.style('No changelog provided.', fg=typer.colors.YELLOW) + typer.echo(typer.style('No changelog provided.', fg=typer.colors.YELLOW)) def write_changelogs_to_file( @@ -67,3 +69,42 @@ def touchopen(filename, *args, **kwargs): f.seek(0) f.write(f'{version}\n{divider}\n{rendered_changelog}\n\n{content}') f.truncate() + + +def get_autoincremented_version(changelog_file: str, version_type: str): + DEFAULT_VERSION = '0.1.0' + VERSION_REGEX = r'\d{1,}\.\d{1,}\.\d{1,}' + + DEFAULT_ERR = "Couldn't generate a version number." + + if version_type not in VERSION_TYPES: + typer.echo( + typer.style( + f'Version type is invalid, you should use one of theese: {", ".join(VERSION_TYPES)}', + fg=typer.colors.RED + ) + ) + return + + if not os.path.isfile(changelog_file): + return DEFAULT_VERSION + try: + with open(changelog_file, "r") as file: + first_line = file.readline() + # TODO: use more specific exception + except Exception: + typer.echo(typer.style(DEFAULT_ERR, fg=typer.colors.RED)) + return + + match = re.match(VERSION_REGEX, first_line) + if not match: + typer.echo(typer.style(DEFAULT_ERR, fg=typer.colors.RED)) + return + + old_version = match.string + n_list = [int(i) for i in old_version.split('.')] + if version_type == 'major': + return f'{n_list[0] + 1}.0.0' + if version_type == 'minor': + return f'{n_list[0]}.{n_list[1] + 1}.0' + return f'{n_list[0]}.{n_list[1]}.{n_list[2] + 1}'