Source code for pyscaffold.contrib.setuptools_scm.hg

import os
from .config import Configuration
from .utils import do, trace, data_from_mime, has_command
from .version import meta, tags_to_versions


def _hg_tagdist_normalize_tagcommit(config, tag, dist, node, branch):
    dirty = node.endswith("+")
    node = "h" + node.strip("+")

    # Detect changes since the specified tag
    revset = (
        "(branch(.)"  # look for revisions in this branch only
        " and tag({tag!r})::."  # after the last tag
        # ignore commits that only modify .hgtags and nothing else:
        " and (merge() or file('re:^(?!\.hgtags).*$'))"
        " and not tag({tag!r}))"  # ignore the tagged commit itself
    ).format(
        tag=tag
    )
    if tag != "0.0":
        commits = do(
            ["hg", "log", "-r", revset, "--template", "{node|short}"],
            config.absolute_root,
        )
    else:
        commits = True
    trace("normalize", locals())
    if commits or dirty:
        return meta(
            tag, distance=dist, node=node, dirty=dirty, branch=branch, config=config
        )
    else:
        return meta(tag, config=config)


[docs]def parse(root, config=None): if not config: config = Configuration(root=root) if not has_command("hg"): return identity_data = do("hg id -i -b -t", config.absolute_root).split() if not identity_data: return node = identity_data.pop(0) branch = identity_data.pop(0) if "tip" in identity_data: # tip is not a real tag identity_data.remove("tip") tags = tags_to_versions(identity_data) dirty = node[-1] == "+" if tags: return meta(tags[0], dirty=dirty, branch=branch, config=config) if node.strip("+") == "0" * 12: trace("initial node", config.absolute_root) return meta("0.0", config=config, dirty=dirty, branch=branch) try: tag = get_latest_normalizable_tag(config.absolute_root) dist = get_graph_distance(config.absolute_root, tag) if tag == "null": tag = "0.0" dist = int(dist) + 1 return _hg_tagdist_normalize_tagcommit(config, tag, dist, node, branch) except ValueError: pass # unpacking failed, old hg
[docs]def get_latest_normalizable_tag(root): # Gets all tags containing a '.' (see #229) from oldest to newest cmd = ["hg", "log", "-r", "ancestors(.) and tag('re:\.')", "--template", "{tags}\n"] outlines = do(cmd, root).split() if not outlines: return "null" tag = outlines[-1].split()[-1] return tag
[docs]def get_graph_distance(root, rev1, rev2="."): cmd = ["hg", "log", "-q", "-r", "%s::%s" % (rev1, rev2)] out = do(cmd, root) return len(out.strip().splitlines()) - 1
[docs]def archival_to_version(data, config=None): trace("data", data) node = data.get("node", "")[:12] if node: node = "h" + node if "tag" in data: return meta(data["tag"], config=config) elif "latesttag" in data: return meta( data["latesttag"], distance=data["latesttagdistance"], node=node, config=config, ) else: return meta("0.0", node=node, config=config)
[docs]def parse_archival(root, config=None): archival = os.path.join(root, ".hg_archival.txt") data = data_from_mime(archival) return archival_to_version(data, config=config)