Add use_max_tag and ignored_tags support to vcs source (git only)

This commit is contained in:
Felix Yan 2015-12-29 12:15:19 +08:00
parent e3aae23225
commit aaf375f0bd
4 changed files with 54 additions and 5 deletions

View file

@ -332,6 +332,16 @@ Check a VCS repo for new commits. The version returned is currently not related
vcs vcs
The url of the remote VCS repo, using the same syntax with a VCS url in PKGBUILD (`Pacman`_'s build script). The first VCS url found in the source array of the PKGBUILD will be used if this is left blank. (Note: for a blank ``vcs`` setting to work correctly, the PKGBUILD has to be in a directory with the name of the software under the path where nvchecker is run. Also, all the commands, if any, needed when sourcing the PKGBUILD need to be installed). The url of the remote VCS repo, using the same syntax with a VCS url in PKGBUILD (`Pacman`_'s build script). The first VCS url found in the source array of the PKGBUILD will be used if this is left blank. (Note: for a blank ``vcs`` setting to work correctly, the PKGBUILD has to be in a directory with the name of the software under the path where nvchecker is run. Also, all the commands, if any, needed when sourcing the PKGBUILD need to be installed).
use_max_tag
Set this to ``true`` to check for the max tag. Currently only supported for ``git``.
This option returns the biggest tag sorted by ``pkg_resources.parse_version``.
ignored_tags
Ignore certain tags while computing the max tag. Tags are separate by
whitespaces. This option must be used together with ``use_max_tag``. This can
be useful to avoid some known badly versioned tags, so the newer tags won't
be "overridden" by the old broken ones.
Other Other
----- -----
More to come. Send me a patch or pull request if you can't wait and have written one yourself :-) More to come. Send me a patch or pull request if you can't wait and have written one yourself :-)

View file

@ -4,6 +4,8 @@ from functools import partial
import tornado.process import tornado.process
from tornado.ioloop import IOLoop from tornado.ioloop import IOLoop
from pkg_resources import parse_version
import os.path as _path import os.path as _path
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -27,19 +29,34 @@ def _parse_oldver(oldver):
def get_version(name, conf, callback): def get_version(name, conf, callback):
vcs = conf['vcs'] vcs = conf['vcs']
use_max_tag = conf.getboolean('use_max_tag', False)
ignored_tags = conf.get("ignored_tags", "").split()
oldver = conf.get('oldver') oldver = conf.get('oldver')
cmd = _cmd_prefix + [name, vcs] cmd = _cmd_prefix + [name, vcs]
if use_max_tag:
cmd += ["get_tags"]
p = tornado.process.Subprocess(cmd, io_loop=IOLoop.instance(), p = tornado.process.Subprocess(cmd, io_loop=IOLoop.instance(),
stdout=tornado.process.Subprocess.STREAM) stdout=tornado.process.Subprocess.STREAM)
p.set_exit_callback(partial(_command_done, name, oldver, callback, p)) p.set_exit_callback(partial(_command_done, name, oldver, use_max_tag, ignored_tags, callback, p))
def _command_done(name, oldver, callback, process, status): def _command_done(name, oldver, use_max_tag, ignored_tags, callback, process, status):
if status != 0: if status != 0:
logger.error('%s: command exited with %d.', name, status) logger.error('%s: command exited with %d.', name, status)
callback(name, None) callback(name, None)
else: else:
process.stdout.read_until_close(partial(_got_version_from_cmd, if use_max_tag:
callback, name, oldver)) process.stdout.read_until_close(partial(_got_tags_from_cmd,
callback, name, ignored_tags))
else:
process.stdout.read_until_close(partial(_got_version_from_cmd,
callback, name, oldver))
def _got_tags_from_cmd(callback, name, ignored_tags, output):
output = output.strip().decode('latin1')
data = [tag for tag in output.split("\n") if tag not in ignored_tags]
data.sort(key=parse_version)
version = data[-1]
callback(name, version)
def _got_version_from_cmd(callback, name, oldver_str, output): def _got_version_from_cmd(callback, name, oldver_str, output):
output = output.strip().decode('latin1') output = output.strip().decode('latin1')

View file

@ -5,6 +5,7 @@ exec >&2
dir=$1 dir=$1
vcs=$2 vcs=$2
get_tags=$3
parse_vcs_url() { parse_vcs_url() {
local _url=$1 local _url=$1
@ -101,6 +102,15 @@ bzr_get_version() {
bzr revno -q "${_extra_arg[@]}" "${_url}" bzr revno -q "${_extra_arg[@]}" "${_url}"
} }
git_get_tags() {
local _url=$1
git ls-remote "$_url" | grep -oP '(?<=refs/tags/)[^^]*$'
}
cd "${dir}" cd "${dir}"
get_vcs "${vcs}" components || exit 1 get_vcs "${vcs}" components || exit 1
eval "${components[0]}_get_version"' ${components[@]:1}' >&3 if [[ "x$get_tags" == "xget_tags" ]]; then
eval "${components[0]}_get_tags"' ${components[@]:1}' >&3
else
eval "${components[0]}_get_version"' ${components[@]:1}' >&3
fi

View file

@ -16,3 +16,15 @@ class VCSTest(ExternalVersionTestCase):
def test_mercurial(self): def test_mercurial(self):
os.path.exists("example") or os.mkdir("example") os.path.exists("example") or os.mkdir("example")
self.assertEqual(self.sync_get_version("example", {"vcs": "hg+https://bitbucket.org/pil0t/testrepo"}), "1.1.84679e29c7d9") self.assertEqual(self.sync_get_version("example", {"vcs": "hg+https://bitbucket.org/pil0t/testrepo"}), "1.1.84679e29c7d9")
@pytest.mark.skipif(shutil.which("git") is None,
reason="requires git command")
def test_git_max_tag(self):
os.path.exists("example") or os.mkdir("example")
self.assertEqual(self.sync_get_version("example", {"vcs": "git+https://github.com/harry-sanabria/ReleaseTestRepo.git", "use_max_tag": 1}), "second_release")
@pytest.mark.skipif(shutil.which("git") is None,
reason="requires git command")
def test_git_max_tag_with_ignored_tags(self):
os.path.exists("example") or os.mkdir("example")
self.assertEqual(self.sync_get_version("example", {"vcs": "git+https://github.com/harry-sanabria/ReleaseTestRepo.git", "use_max_tag": 1, "ignored_tags": "second_release release3"}), "first_release")