summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpunkadiddle <>2018-06-30 12:02:07 +0200
committerpunkadiddle <>2018-06-30 12:02:07 +0200
commitf22be711987fa47d937c99605a4dd9e9609b76b6 (patch)
tree688d9d224e75b2218dec7b176fb96dc0a6e3c564 /src
parente377112e996ed0adf65f6378475ea360103d947b (diff)
downloadsetuptools-scm-f22be711987fa47d937c99605a4dd9e9609b76b6.tar.gz
tag parsing configurable through tag_regex
Diffstat (limited to 'src')
-rw-r--r--src/setuptools_scm/__init__.py21
-rw-r--r--src/setuptools_scm/config.py49
-rw-r--r--src/setuptools_scm/utils.py17
-rw-r--r--src/setuptools_scm/version.py48
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):