support for glob patterns

This commit is contained in:
Manuel Barkhau 2020-09-18 19:52:40 +00:00
parent a8e658d1c4
commit e1aaf7629b
7 changed files with 147 additions and 72 deletions

View file

@ -17,13 +17,14 @@ import subprocess as sp
import click
import pycalver.cli as v1cli
import pycalver2.cli as v2cli
import pycalver.version as v1version
import pycalver2.version as v2version
import pycalver.rewrite as v1rewrite
from pycalver import vcs
from pycalver import config
# import pycalver2.cli as v2cli
_VERBOSE = 0
@ -149,31 +150,21 @@ def show(verbose: int = 0, fetch: bool = True) -> None:
click.echo(f"PEP440 : {cfg.pep440_version}")
def _try_print_diff(cfg: config.Config, new_version: str) -> None:
try:
# TODO (mb 2020-09-05): version switch
diff = v1cli.get_diff(cfg, new_version)
# diff = v2cli.get_diff(cfg, new_version)
if sys.stdout.isatty():
for line in diff.splitlines():
if line.startswith("+++") or line.startswith("---"):
click.echo(line)
elif line.startswith("+"):
click.echo("\u001b[32m" + line + "\u001b[0m")
elif line.startswith("-"):
click.echo("\u001b[31m" + line + "\u001b[0m")
elif line.startswith("@"):
click.echo("\u001b[36m" + line + "\u001b[0m")
else:
click.echo(line)
else:
click.echo(diff)
except Exception as ex:
# pylint:disable=broad-except; Mostly we expect IOError here, but
# could be other things and there's no option to recover anyway.
logger.error(str(ex), exc_info=True)
sys.exit(1)
def _print_diff(diff: str) -> None:
if sys.stdout.isatty():
for line in diff.splitlines():
if line.startswith("+++") or line.startswith("---"):
click.echo(line)
elif line.startswith("+"):
click.echo("\u001b[32m" + line + "\u001b[0m")
elif line.startswith("-"):
click.echo("\u001b[31m" + line + "\u001b[0m")
elif line.startswith("@"):
click.echo("\u001b[36m" + line + "\u001b[0m")
else:
click.echo(line)
else:
click.echo(diff)
def _incr(
@ -229,10 +220,15 @@ def _bump(
vcs.assert_not_dirty(vcs_api, filepaths, allow_dirty)
try:
# TODO (mb 2020-09-05): version switch
v1cli.rewrite(cfg, new_version)
# v2cli.rewrite(cfg, new_version)
if cfg.is_new_pattern:
v2cli.rewrite(cfg, new_version)
else:
v1cli.rewrite(cfg, new_version)
except v1rewrite.NoPatternMatch as ex:
logger.error(str(ex))
sys.exit(1)
except Exception as ex:
# TODO (mb 2020-09-18): Investigate error messages
logger.error(str(ex))
sys.exit(1)
@ -285,10 +281,10 @@ def init(verbose: int = 0, dry: bool = False) -> None:
def _update_cfg_from_vcs(cfg: config.Config, fetch: bool) -> config.Config:
all_tags = vcs.get_tags(fetch=fetch)
# TODO (mb 2020-09-05): version switch
cfg = v1cli.update_cfg_from_vcs(cfg, all_tags)
# cfg = v2cli.update_cfg_from_vcs(cfg, all_tags)
return cfg
if cfg.is_new_pattern:
return v2cli.update_cfg_from_vcs(cfg, all_tags)
else:
return v1cli.update_cfg_from_vcs(cfg, all_tags)
@cli.command()
@ -375,7 +371,11 @@ def bump(
)
if new_version is None:
is_semver = "{semver}" in cfg.version_pattern
is_semver = "{semver}" in cfg.version_pattern or (
"MAJOR" in cfg.version_pattern
and "MAJOR" in cfg.version_pattern
and "PATCH" in cfg.version_pattern
)
has_semver_inc = major or minor or patch
if is_semver and not has_semver_inc:
logger.warning("bump --major/--minor/--patch required when using semver.")
@ -387,7 +387,20 @@ def bump(
logger.info(f"New Version: {new_version}")
if dry or verbose >= 2:
_try_print_diff(cfg, new_version)
try:
if cfg.is_new_pattern:
diff = v2cli.get_diff(cfg, new_version)
else:
diff = v1cli.get_diff(cfg, new_version)
_print_diff(diff)
except v1rewrite.NoPatternMatch as ex:
logger.error(str(ex))
sys.exit(1)
except Exception as ex:
# pylint:disable=broad-except; Mostly we expect IOError here, but
# could be other things and there's no option to recover anyway.
logger.error(str(ex))
sys.exit(1)
if dry:
return

View file

@ -5,7 +5,7 @@
# SPDX-License-Identifier: MIT
"""Parse setup.cfg or pycalver.cfg files."""
import os
import glob
import typing as typ
import logging
import datetime as dt
@ -14,7 +14,8 @@ import configparser
import toml
import pathlib2 as pl
from . import version
import pycalver.version as v1version
import pycalver2.version as v2version
logger = logging.getLogger("pycalver.config")
@ -82,9 +83,10 @@ class Config(typ.NamedTuple):
pep440_version : str
commit_message : str
commit: bool
tag : bool
push : bool
commit : bool
tag : bool
push : bool
is_new_pattern: bool
file_patterns: PatternsByGlob
@ -93,12 +95,13 @@ def _debug_str(cfg: Config) -> str:
cfg_str_parts = [
"Config Parsed: Config(",
f"current_version='{cfg.current_version}'",
"version_pattern='{pycalver}'",
f"version_pattern='{cfg.version_pattern}'",
f"pep440_version='{cfg.pep440_version}'",
f"commit_message='{cfg.commit_message}'",
f"commit={cfg.commit}",
f"tag={cfg.tag}",
f"push={cfg.push}",
f"is_new_pattern={cfg.is_new_pattern}",
"file_patterns={",
]
@ -197,7 +200,7 @@ def _normalize_file_patterns(raw_cfg: RawConfig) -> FilePatterns:
"""
version_str : str = raw_cfg['current_version']
version_pattern: str = raw_cfg['version_pattern']
pep440_version : str = version.to_pep440(version_str)
pep440_version : str = v1version.to_pep440(version_str)
file_patterns: FilePatterns
if 'file_patterns' in raw_cfg:
@ -205,9 +208,12 @@ def _normalize_file_patterns(raw_cfg: RawConfig) -> FilePatterns:
else:
file_patterns = {}
for filepath, patterns in list(file_patterns.items()):
if not os.path.exists(filepath):
logger.warning(f"Invalid config, no such file: {filepath}")
for filepath_glob, patterns in list(file_patterns.items()):
filepaths = glob.glob(filepath_glob)
if not filepaths:
logger.warning(f"Invalid config, no such file: {filepath_glob}")
# fallback to treating it as a simple path
filepaths = [filepath_glob]
normalized_patterns: typ.List[str] = []
for pattern in patterns:
@ -219,11 +225,12 @@ def _normalize_file_patterns(raw_cfg: RawConfig) -> FilePatterns:
elif version_pattern == "{semver}":
normalized_pattern = normalized_pattern.replace("{pep440_version}", "{semver}")
elif "{pep440_version}" in pattern:
logger.warning(f"Invalid config, cannot match '{pattern}' for '{filepath}'.")
logger.warning(f"Invalid config, cannot match '{pattern}' for '{filepath_glob}'.")
logger.warning(f"No mapping of '{version_pattern}' to '{pep440_version}'")
normalized_patterns.append(normalized_pattern)
file_patterns[filepath] = normalized_patterns
for filepath in filepaths:
file_patterns[filepath] = normalized_patterns
return file_patterns
@ -237,18 +244,27 @@ def _parse_config(raw_cfg: RawConfig) -> Config:
version_str: str = raw_cfg['current_version']
version_str = raw_cfg['current_version'] = version_str.strip("'\" ")
# TODO (mb 2020-09-06): new style pattern by default
# version_pattern: str = raw_cfg.get('version_pattern', "vYYYY0M.BUILD[-TAG]")
version_pattern: str = raw_cfg.get('version_pattern', "{pycalver}")
version_pattern = raw_cfg['version_pattern'] = version_pattern.strip("'\" ")
commit_message: str = raw_cfg.get('commit_message', DEFAULT_COMMIT_MESSAGE)
commit_message = raw_cfg['commit_message'] = commit_message.strip("'\" ")
is_new_pattern = not ("{" in version_pattern or "}" in version_pattern)
# TODO (mb 2020-09-18): Validate Pattern
# detect YY with WW or UU -> suggest GG with VV
# detect YYMM -> suggest YY0M
# detect YYWW -> suggest YY0W
# NOTE (mb 2019-01-05): Provoke ValueError if version_pattern
# and current_version are not compatible.
version.parse_version_info(version_str, version_pattern)
if is_new_pattern:
v2version.parse_version_info(version_str, version_pattern)
else:
v1version.parse_version_info(version_str, version_pattern)
pep440_version = version.to_pep440(version_str)
pep440_version = v1version.to_pep440(version_str)
commit = raw_cfg['commit']
tag = raw_cfg['tag']
@ -275,6 +291,7 @@ def _parse_config(raw_cfg: RawConfig) -> Config:
commit=commit,
tag=tag,
push=push,
is_new_pattern=is_new_pattern,
file_patterns=file_patterns,
)
logger.debug(_debug_str(cfg))