diff options
author | punkadiddle <> | 2018-06-30 12:02:07 +0200 |
---|---|---|
committer | punkadiddle <> | 2018-06-30 12:02:07 +0200 |
commit | f22be711987fa47d937c99605a4dd9e9609b76b6 (patch) | |
tree | 688d9d224e75b2218dec7b176fb96dc0a6e3c564 /src | |
parent | e377112e996ed0adf65f6378475ea360103d947b (diff) | |
download | setuptools-scm-f22be711987fa47d937c99605a4dd9e9609b76b6.tar.gz |
tag parsing configurable through tag_regex
Diffstat (limited to 'src')
-rw-r--r-- | src/setuptools_scm/__init__.py | 21 | ||||
-rw-r--r-- | src/setuptools_scm/config.py | 49 | ||||
-rw-r--r-- | src/setuptools_scm/utils.py | 17 | ||||
-rw-r--r-- | src/setuptools_scm/version.py | 48 |
4 files changed, 111 insertions, 24 deletions
diff --git a/src/setuptools_scm/__init__.py b/src/setuptools_scm/__init__.py index b256289..58dd929 100644 --- a/src/setuptools_scm/__init__.py +++ b/src/setuptools_scm/__init__.py @@ -5,13 +5,13 @@ import os import sys -from .utils import trace +from .config import Configuration +from .utils import trace, string_types from .version import format_version, meta from .discover import iter_matching_entrypoints PRETEND_KEY = "SETUPTOOLS_SCM_PRETEND_VERSION" - TEMPLATES = { ".py": """\ # coding: utf-8 @@ -22,9 +22,6 @@ version = {version!r} ".txt": "{version}", } -PY3 = sys.version_info > (3,) -string_types = (str,) if PY3 else (str, unicode) # noqa - def version_from_scm(root): return _version_from_entrypoint(root, "setuptools_scm.parse_scm") @@ -99,6 +96,7 @@ def get_version( write_to=None, write_to_template=None, relative_to=None, + tag_regex=None, parse=None, ): """ @@ -107,11 +105,22 @@ def get_version( in the root of the repository to direct setuptools_scm to the root of the repository by supplying ``__file__``. """ + if relative_to: root = os.path.join(os.path.dirname(relative_to), root) root = os.path.abspath(root) trace("root", repr(root)) - + + config = Configuration() + config.root = root + config.version_scheme = version_scheme + config.local_scheme = local_scheme + config.write_to = write_to + config.write_to_template = write_to_template + config.relative_to = relative_to + config.tag_regex = tag_regex + config.parse = parse + parsed_version = _do_parse(root, parse) if parsed_version: diff --git a/src/setuptools_scm/config.py b/src/setuptools_scm/config.py new file mode 100644 index 0000000..5107133 --- /dev/null +++ b/src/setuptools_scm/config.py @@ -0,0 +1,49 @@ +""" configuration """ +from __future__ import print_function, unicode_literals +import re +import warnings + +from .utils import singleton + +DEFAULT_TAG_REGEX = r'^(?P<prefix>\w+-)?(?P<version>v?\d+(?:\.\d+){0,2}[^\+]+)(?P<suffix>\+.*)?$' +TAG_REGEX_EXPECTED_GROUPS = set(['prefix', 'version', 'suffix']) + + +@singleton +class Configuration(object): + """ Global Configuration single-instance class """ + + root = '' + version_scheme = '' + local_scheme = '' + write_to = '' + write_to_template = None + relative_to = None + parse = None + _tag_regex = None + + def __init__(self): + self.root = '.' + self.version_scheme = "guess-next-dev" + self.local_scheme = "node-and-date" + self.tag_regex = DEFAULT_TAG_REGEX + + @property + def tag_regex(self): + return self._tag_regex + + @tag_regex.setter + def tag_regex(self, value): + if value is None: + value = DEFAULT_TAG_REGEX + regex = re.compile(value) + + group_names = set(regex.groupindex.keys()) + diff = TAG_REGEX_EXPECTED_GROUPS.difference(group_names) + if diff: + warnings.warn("expected match groups %s missing from regex '%s'" % (diff, regex.pattern)) + diff = group_names.difference(TAG_REGEX_EXPECTED_GROUPS) + if diff: + warnings.warn("additional match groups %s found in regex '%s' (expected: %s)" % (diff, regex.pattern, TAG_REGEX_EXPECTED_GROUPS)) + + self._tag_regex = regex diff --git a/src/setuptools_scm/utils.py b/src/setuptools_scm/utils.py index e6b767c..5db87bf 100644 --- a/src/setuptools_scm/utils.py +++ b/src/setuptools_scm/utils.py @@ -14,6 +14,8 @@ import platform DEBUG = bool(os.environ.get("SETUPTOOLS_SCM_DEBUG")) IS_WINDOWS = platform.system() == "Windows" PY2 = sys.version_info < (3,) +PY3 = sys.version_info > (3,) +string_types = (str,) if PY3 else (str, unicode) # noqa def trace(*k): @@ -103,3 +105,18 @@ def has_command(name): if not res: warnings.warn("%r was not found" % name) return res + + +def singleton(cls): + """ Class decorator to limit to a single global instance. """ + instances = {} + + def _get_instance(*args, **kwargs): + instance = instances.get(cls, None) + if instance is None: + instance = cls(*args, **kwargs) + instances[cls] = instance + + return instance + + return _get_instance diff --git a/src/setuptools_scm/version.py b/src/setuptools_scm/version.py index 5799f1a..85e02be 100644 --- a/src/setuptools_scm/version.py +++ b/src/setuptools_scm/version.py @@ -4,7 +4,8 @@ import warnings import re from itertools import chain, repeat, islice -from .utils import trace +from .config import Configuration +from .utils import trace, string_types from pkg_resources import iter_entry_points @@ -13,7 +14,6 @@ from pkg_resources import parse_version as pkg_parse_version SEMVER_MINOR = 2 SEMVER_PATCH = 3 SEMVER_LEN = 3 -TAG_PREFIX = re.compile(r"^\w+-(.*)") def _pad(iterable, size, padding=None): @@ -21,6 +21,22 @@ def _pad(iterable, size, padding=None): return list(islice(padded, size)) +def _parse_version_tag(tag): + regex = Configuration().tag_regex + if isinstance(tag, string_types): + match = regex.match(tag) + else: + match = regex.match('%s' % tag) + + if match: + result = match.groupdict() + else: + result = None + + trace("'%s' parsed to %s" % (tag, result)) + return result + + def _get_version_class(): modern_version = pkg_parse_version("1.0") if isinstance(modern_version, tuple): @@ -61,23 +77,19 @@ def tag_to_version(tag): take a tag that might be prefixed with a keyword and return only the version part """ trace("tag", tag) - if "+" in tag: - warnings.warn("tag %r will be stripped of the local component" % tag) - tag = tag.split("+")[0] - # lstrip the v because of py2/py3 differences in setuptools - # also required for old versions of setuptools - prefix_match = TAG_PREFIX.match(tag) - if prefix_match is not None: - version = prefix_match.group(1) - else: - version = tag + + tagdict = _parse_version_tag(tag) + if tagdict is None or len(tagdict['version']) < 1: + return None + + version = tagdict['version'] trace("version pre parse", version) - if VERSION_CLASS is None: - return version - version = pkg_parse_version(version) - trace("version", repr(version)) - if isinstance(version, VERSION_CLASS): - return version + + if VERSION_CLASS is not None: + version = pkg_parse_version(version) + trace("version", repr(version)) + + return version def tags_to_versions(tags): |