Modified versioneer to allow specification of manual versions based on branches

You can now define a lookup file explicitely mapping virtual version tags to branches via regular expressions and a reference commit from which the commit distance will be calculated.

Format of the file is

  <branch-regex> <tag> <reference commit>

The file is processed from top to bottom, the first matching line wins. If <tag> or <reference commit> are left out, the lookup table does not apply to the matched branches and the regular versioneer resolution (via git describe) takes place.

Current configuration makes "master", "staging" and any branch starting with "fix/" make use the default behaviour, all other branches (so basically all development branches) are defined as "1.2.0-dev"
This commit is contained in:
Gina Häußge 2014-09-02 11:35:42 +02:00
parent 4296b49570
commit 212f40cd1a
4 changed files with 303 additions and 23 deletions

18
.versioneer-lookup Normal file
View file

@ -0,0 +1,18 @@
# Configuration file for the versioneer lookup, manually mapping tags based on branches
#
# Format is
#
# <branch-regex> <tag> <reference commit>
#
# The file is processed from top to bottom, the first matching line wins. If <tag> or <reference commit> are left out,
# the lookup table does not apply to the matched branches
# master and staging shall not use the lookup table
master
staging
# fix/ branches are fixes for master, so we don't handle those either
fix/.*
# every other branch is a development branch and thus gets resolved to 1.2.0-dev for now
.* 1.2.0-dev 50cf776e70b9

View file

@ -7,6 +7,7 @@ versioneer.versionfile_source = 'src/octoprint/_version.py'
versioneer.versionfile_build = 'octoprint/_version.py'
versioneer.tag_prefix = ''
versioneer.parentdir_prefix = ''
versioneer.lookupfile = '.versioneer-lookup'
from setuptools import setup, find_packages, Command
import os

View file

@ -54,6 +54,18 @@ import sys
import re
import os.path
def get_gits(root, verbose=False):
if not os.path.exists(os.path.join(root, ".git")):
if verbose:
print("no .git in %s" % root)
return None
GITS = ["git"]
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
return GITS
def get_expanded_variables(versionfile_abs):
# the code embedded in _version.py can just fetch the value of these
# variables. When used from setup.py, we don't want to import
@ -114,20 +126,60 @@ def versions_from_expanded_variables(variables, tag_prefix, verbose=False):
return { "version": variables["full"].strip(),
"full": variables["full"].strip() }
def versions_from_lookup(lookup, root, verbose=False):
GITS = get_gits(root, verbose=verbose)
if GITS is None:
return {}
stdout = run_command(GITS, ["rev-parse", "--abbrev-ref", "HEAD"],
cwd=root)
if stdout is None:
return {}
current_branch = stdout.strip()
for matcher, tag, ref_commit in lookup:
if matcher.match(current_branch):
if tag is None or ref_commit is None:
return {}
stdout = run_command(GITS, ["rev-list", "%s..HEAD" % ref_commit, "--count"], cwd=root)
if stdout is None:
return {}
num_commits = stdout.strip()
stdout =run_command(GITS, ["rev-parse", "--short", "HEAD"], cwd=root)
if stdout is None:
return {}
short_hash = stdout.strip()
stdout = run_command(GITS, ["describe", "--tags", "--dirty", "--always"], cwd=root)
if stdout is None:
return {}
dirty = stdout.strip().endswith("-dirty")
stdout = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
if stdout is None:
return {}
full = stdout.strip()
version = "%s-%s-g%s" % (tag, num_commits, short_hash)
if dirty:
version += "-dirty"
full += "-dirty"
return {"version": version, "full": full}
return {}
def versions_from_vcs(tag_prefix, root, verbose=False):
# this runs 'git' from the root of the source tree. This only gets called
# if the git-archive 'subst' variables were *not* expanded, and
# _version.py hasn't already been rewritten with a short version string,
# meaning we're inside a checked out source tree.
if not os.path.exists(os.path.join(root, ".git")):
if verbose:
print("no .git in %s" % root)
GITS = get_gits(root, verbose=verbose)
if GITS is None:
return {}
GITS = ["git"]
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
stdout = run_command(GITS, ["describe", "--tags", "--dirty", "--always"],
cwd=root)
if stdout is None:
@ -158,10 +210,39 @@ def versions_from_parentdir(parentdir_prefix, root, verbose=False):
return {"version": dirname[len(parentdir_prefix):], "full": ""}
tag_prefix = ""
parentdir_prefix = "octoprint-"
parentdir_prefix = ""
versionfile_source = "src/octoprint/_version.py"
lookupfile = ".versioneer-lookup"
def get_versions(default={"version": "unknown", "full": ""}, verbose=False):
def parse_lookup_file(root, lookup_path=None):
if not lookup_path:
lookup_path = lookupfile
if not lookup_path:
return []
path = os.path.join(root, lookup_path)
if not os.path.exists(path):
return []
import re
lookup = []
with open(os.path.join(root, lookup_path), "r") as f:
for line in f:
if '#' in line:
line = line[:line.rindex('#')]
line = line.strip()
try:
split_line = line.split()
if len(split_line) == 3:
pattern, tag, ref_commit = split_line
lookup.append([re.compile(pattern), tag, ref_commit])
elif len(split_line) >= 1:
lookup.append([re.compile(split_line[0]), None, None])
except:
break
return lookup
def get_versions(default={"version": "unknown", "full": ""}, lookup_path=None, verbose=False):
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
# __file__, we can work backwards from there to the root. Some
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
@ -182,7 +263,9 @@ def get_versions(default={"version": "unknown", "full": ""}, verbose=False):
except NameError:
return default
return (versions_from_vcs(tag_prefix, root, verbose)
lookup = parse_lookup_file(root, lookup_path=lookup_path)
return (versions_from_lookup(lookup, root, verbose)
or versions_from_vcs(tag_prefix, root, verbose)
or versions_from_parentdir(parentdir_prefix, root, verbose)
or default)

View file

@ -252,6 +252,7 @@ versionfile_source = None
versionfile_build = None
tag_prefix = None
parentdir_prefix = None
lookupfile = None
VCS = "git"
@ -312,6 +313,18 @@ import sys
import re
import os.path
def get_gits(root, verbose=False):
if not os.path.exists(os.path.join(root, ".git")):
if verbose:
print("no .git in %%s" %% root)
return None
GITS = ["git"]
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
return GITS
def get_expanded_variables(versionfile_abs):
# the code embedded in _version.py can just fetch the value of these
# variables. When used from setup.py, we don't want to import
@ -372,20 +385,60 @@ def versions_from_expanded_variables(variables, tag_prefix, verbose=False):
return { "version": variables["full"].strip(),
"full": variables["full"].strip() }
def versions_from_lookup(lookup, root, verbose=False):
GITS = get_gits(root, verbose=verbose)
if GITS is None:
return {}
stdout = run_command(GITS, ["rev-parse", "--abbrev-ref", "HEAD"],
cwd=root)
if stdout is None:
return {}
current_branch = stdout.strip()
for matcher, tag, ref_commit in lookup:
if matcher.match(current_branch):
if tag is None or ref_commit is None:
return {}
stdout = run_command(GITS, ["rev-list", "%%s..HEAD" %% ref_commit, "--count"], cwd=root)
if stdout is None:
return {}
num_commits = stdout.strip()
stdout =run_command(GITS, ["rev-parse", "--short", "HEAD"], cwd=root)
if stdout is None:
return {}
short_hash = stdout.strip()
stdout = run_command(GITS, ["describe", "--tags", "--dirty", "--always"], cwd=root)
if stdout is None:
return {}
dirty = stdout.strip().endswith("-dirty")
stdout = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
if stdout is None:
return {}
full = stdout.strip()
version = "%%s-%%s-g%%s" %% (tag, num_commits, short_hash)
if dirty:
version += "-dirty"
full += "-dirty"
return {"version": version, "full": full}
return {}
def versions_from_vcs(tag_prefix, root, verbose=False):
# this runs 'git' from the root of the source tree. This only gets called
# if the git-archive 'subst' variables were *not* expanded, and
# _version.py hasn't already been rewritten with a short version string,
# meaning we're inside a checked out source tree.
if not os.path.exists(os.path.join(root, ".git")):
if verbose:
print("no .git in %%s" %% root)
GITS = get_gits(root, verbose=verbose)
if GITS is None:
return {}
GITS = ["git"]
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
stdout = run_command(GITS, ["describe", "--tags", "--dirty", "--always"],
cwd=root)
if stdout is None:
@ -418,8 +471,37 @@ def versions_from_parentdir(parentdir_prefix, root, verbose=False):
tag_prefix = "%(TAG_PREFIX)s"
parentdir_prefix = "%(PARENTDIR_PREFIX)s"
versionfile_source = "%(VERSIONFILE_SOURCE)s"
lookupfile = %(LOOKUPFILE)s
def get_versions(default={"version": "unknown", "full": ""}, verbose=False):
def parse_lookup_file(root, lookup_path=None):
if not lookup_path:
lookup_path = lookupfile
if not lookup_path:
return []
path = os.path.join(root, lookup_path)
if not os.path.exists(path):
return []
import re
lookup = []
with open(os.path.join(root, lookup_path), "r") as f:
for line in f:
if '#' in line:
line = line[:line.rindex('#')]
line = line.strip()
try:
split_line = line.split()
if len(split_line) == 3:
pattern, tag, ref_commit = split_line
lookup.append([re.compile(pattern), tag, ref_commit])
elif len(split_line) >= 1:
lookup.append([re.compile(split_line[0]), None, None])
except:
break
return lookup
def get_versions(default={"version": "unknown", "full": ""}, lookup_path=None, verbose=False):
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
# __file__, we can work backwards from there to the root. Some
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
@ -440,7 +522,9 @@ def get_versions(default={"version": "unknown", "full": ""}, verbose=False):
except NameError:
return default
return (versions_from_vcs(tag_prefix, root, verbose)
lookup = parse_lookup_file(root, lookup_path=lookup_path)
return (versions_from_lookup(lookup, root, verbose)
or versions_from_vcs(tag_prefix, root, verbose)
or versions_from_parentdir(parentdir_prefix, root, verbose)
or default)
@ -488,6 +572,18 @@ import sys
import re
import os.path
def get_gits(root, verbose=False):
if not os.path.exists(os.path.join(root, ".git")):
if verbose:
print("no .git in %s" % root)
return None
GITS = ["git"]
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
return GITS
def get_expanded_variables(versionfile_abs):
# the code embedded in _version.py can just fetch the value of these
# variables. When used from setup.py, we don't want to import
@ -548,20 +644,62 @@ def versions_from_expanded_variables(variables, tag_prefix, verbose=False):
return { "version": variables["full"].strip(),
"full": variables["full"].strip() }
def versions_from_lookup(lookup, root, verbose=False):
GITS = get_gits(root, verbose=verbose)
if GITS is None:
return {}
stdout = run_command(GITS, ["rev-parse", "--abbrev-ref", "HEAD"],
cwd=root)
if stdout is None:
return {}
current_branch = stdout.strip()
for matcher, tag, ref_commit in lookup:
if matcher.match(current_branch):
if tag is None or ref_commit is None:
return {}
stdout = run_command(GITS, ["rev-list", "%s..HEAD" % ref_commit, "--count"], cwd=root)
if stdout is None:
return {}
num_commits = stdout.strip()
stdout =run_command(GITS, ["rev-parse", "--short", "HEAD"], cwd=root)
if stdout is None:
return {}
short_hash = stdout.strip()
stdout = run_command(GITS, ["describe", "--tags", "--dirty", "--always"], cwd=root)
if stdout is None:
return {}
dirty = stdout.strip().endswith("-dirty")
stdout = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
if stdout is None:
return {}
full = stdout.strip()
version = "%s-%s-g%s" % (tag, num_commits, short_hash)
if dirty:
version += "-dirty"
full += "-dirty"
return {"version": version, "full": full}
return {}
def versions_from_vcs(tag_prefix, root, verbose=False):
# this runs 'git' from the root of the source tree. This only gets called
# if the git-archive 'subst' variables were *not* expanded, and
# _version.py hasn't already been rewritten with a short version string,
# meaning we're inside a checked out source tree.
if not os.path.exists(os.path.join(root, ".git")):
if verbose:
print("no .git in %s" % root)
GITS = get_gits(root, verbose=verbose)
if GITS is None:
return {}
GITS = ["git"]
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
stdout = run_command(GITS, ["describe", "--tags", "--dirty", "--always"],
cwd=root)
if stdout is None:
@ -684,11 +822,38 @@ def get_root():
except NameError:
return os.path.dirname(os.path.abspath(sys.argv[0]))
def parse_lookup_file(root, lookup_path=None):
if not lookup_path:
lookup_path = lookupfile
path = os.path.join(root, lookup_path)
if not os.path.exists(path):
return []
import re
lookup = []
with open(os.path.join(root, lookup_path), "r") as f:
for line in f:
if '#' in line:
line = line[:line.rindex("#")]
line = line.strip()
try:
split_line = line.split()
if len(split_line) == 3:
pattern, tag, ref_commit = split_line
lookup.append([re.compile(pattern), tag, ref_commit])
elif len(split_line) >= 1:
lookup.append([re.compile(split_line[0]), None, None])
except:
break
return lookup
def get_versions(default=DEFAULT, verbose=False):
# returns dict with two keys: 'version' and 'full'
assert versionfile_source is not None, "please set versioneer.versionfile_source"
assert tag_prefix is not None, "please set versioneer.tag_prefix"
assert parentdir_prefix is not None, "please set versioneer.parentdir_prefix"
# I am in versioneer.py, which must live at the top of the source tree,
# which we use to compute the root directory. py2exe/bbfreeze/non-CPython
# don't have __file__, in which case we fall back to sys.argv[0] (which
@ -697,6 +862,11 @@ def get_versions(default=DEFAULT, verbose=False):
root = get_root()
versionfile_abs = os.path.join(root, versionfile_source)
if lookupfile:
lookup = parse_lookup_file(root, lookup_path = lookupfile)
else:
lookup = None
# extract version from first of _version.py, 'git describe', parentdir.
# This is meant to work for developers using a source checkout, for users
# of a tarball created by 'setup.py sdist', and for users of a
@ -715,6 +885,12 @@ def get_versions(default=DEFAULT, verbose=False):
if verbose: print("got version from file %s %s" % (versionfile_abs,ver))
return ver
if lookup:
ver = versions_from_lookup(lookup, root, verbose=verbose)
if ver:
if verbose: print("got version from lookup %s" % ver)
return ver
ver = versions_from_vcs(tag_prefix, root, verbose)
if ver:
if verbose: print("got version from git %s" % ver)
@ -792,6 +968,7 @@ if 'cx_Freeze' in sys.modules: # cx_freeze enabled?
"TAG_PREFIX": tag_prefix,
"PARENTDIR_PREFIX": parentdir_prefix,
"VERSIONFILE_SOURCE": versionfile_source,
"LOOKUPFILE": '"%s"' % lookupfile if lookupfile is not None else "None",
})
f.close()
@ -835,6 +1012,7 @@ class cmd_update_files(Command):
"TAG_PREFIX": tag_prefix,
"PARENTDIR_PREFIX": parentdir_prefix,
"VERSIONFILE_SOURCE": versionfile_source,
"LOOKUPFILE": '"%s"' % lookupfile if lookupfile is not None else "None",
})
f.close()