"""
:copyright: 2010-2015 by Ronny Pfannschmidt
:license: MIT
"""
import os
import sys
import warnings
from .utils import trace
from .version import format_version, meta, ScmVersion
from .discover import iter_matching_entrypoints
PRETEND_KEY = 'SETUPTOOLS_SCM_PRETEND_VERSION'
TEMPLATES = {
'.py': """\
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = {version!r}
""",
'.txt': '{version}',
}
PY3 = sys.version_info > (3,)
string_types = (str,) if PY3 else (str, unicode) # noqa
[docs]def version_from_scm(root):
return _version_from_entrypoint(root, 'setuptools_scm.parse_scm')
def _version_from_entrypoint(root, entrypoint):
for ep in iter_matching_entrypoints(root, entrypoint):
version = ep.load()(root)
if version:
return version
[docs]def dump_version(root, version, write_to, template=None):
assert isinstance(version, string_types)
if not write_to:
return
target = os.path.normpath(os.path.join(root, write_to))
ext = os.path.splitext(target)[1]
template = template or TEMPLATES.get(ext)
if template is not None:
dump = template.format(version=version)
else:
raise ValueError((
"bad file format: '%s' (of %s) \n"
"only *.txt and *.py are supported") % (
os.path.splitext(target)[1],
target
))
with open(target, 'w') as fp:
fp.write(dump)
def _do_parse(root, parse):
pretended = os.environ.get(PRETEND_KEY)
if pretended:
# we use meta here since the pretended version
# must adhere to the pep to begin with
return meta(pretended)
if parse:
parse_result = parse(root)
if isinstance(parse_result, string_types):
warnings.warn(
"version parse result was a string\n"
"please return a parsed version",
category=DeprecationWarning)
# we use ScmVersion here in order to keep legacy code working
# for 2.0 we should use meta
parse_result = ScmVersion(parse_result)
version = parse_result or _version_from_entrypoint(
root, 'setuptools_scm.parse_scm_fallback')
else:
# include fallbacks after dropping them from the main entrypoint
version = version_from_scm(root) or _version_from_entrypoint(
root, 'setuptools_scm.parse_scm_fallback')
if version:
return version
raise LookupError(
"setuptools-scm was unable to detect version for %r.\n\n"
"Make sure you're either building from a fully intact git repository "
"or PyPI tarballs. Most other sources (such as GitHub's tarballs, a "
"git checkout without the .git folder) don't contain the necessary "
"metadata and will not work.\n\n"
"For example, if you're using pip, instead of "
"https://github.com/user/proj/archive/master.zip "
"use git+https://github.com/user/proj.git#egg=proj" % root)
[docs]def get_version(root='.',
version_scheme='guess-next-dev',
local_scheme='node-and-date',
write_to=None,
write_to_template=None,
relative_to=None,
parse=None,
):
"""
If supplied, relative_to should be a file from which root may
be resolved. Typically called by a script or module that is not
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))
parsed_version = _do_parse(root, parse)
if parsed_version:
version_string = format_version(
parsed_version,
version_scheme=version_scheme,
local_scheme=local_scheme)
dump_version(
root=root,
version=version_string,
write_to=write_to,
template=write_to_template)
return version_string