Merge branch 'source-vcs'

This commit is contained in:
lilydjwg 2014-11-03 22:09:23 +08:00
commit 3194ec374b
6 changed files with 173 additions and 2 deletions

5
.gitignore vendored
View File

@ -1 +1,6 @@
records/
*.egg-info/
__pycache__/
/build/
*.pyc
*.pyo

View File

@ -131,7 +131,7 @@ gems
Check Local Pacman Database
---------------------------
This is used when you run ``nvchecker`` on an Arch Linux system and the program always keeps up with a package in your configured repositories for `Pacman <https://wiki.archlinux.org/index.php/Pacman>`_.
This is used when you run ``nvchecker`` on an Arch Linux system and the program always keeps up with a package in your configured repositories for `Pacman`_.
pacman
The package name to reference to.
@ -157,6 +157,13 @@ This enables you to manually specify the version (maybe because you want to appr
manual
The version string.
Version Control System (VCS) (git, hg, svn, bzr)
------------------------------------------------
Check a VCS repo for new commits. The version returned is currently not related to the version of the software and will increase whenever the referred VCS branch changes. This is mainly for Arch Linux.
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).
Other
-----
More to come. Send me a patch or pull request if you can't wait and have written one yourself :-)
@ -173,3 +180,5 @@ Footnotes
=========
.. [v0.3] Note: with nvchecker <= 0.2, there are one more colon each line. You can use ``sed -i 's/://' FILES...`` to remove them.
.. [v0.4] This is added in version 0.4, and old command-line options are removed.
.. _Pacman: https://wiki.archlinux.org/index.php/Pacman

View File

@ -4,7 +4,7 @@ from importlib import import_module
logger = logging.getLogger(__name__)
handler_precedence = (
'github', 'aur', 'pypi', 'archpkg', 'gems', 'pacman',
'cmd', 'gcode_hg', 'regex', 'manual',
'cmd', 'gcode_hg', 'regex', 'manual', 'vcs'
)
def get_version(name, conf, callback):

50
nvchecker/source/vcs.py Normal file
View File

@ -0,0 +1,50 @@
import logging
from functools import partial
import tornado.process
from tornado.ioloop import IOLoop
import os.path as _path
logger = logging.getLogger(__name__)
_self_path = _path.dirname(_path.abspath(__file__))
_cmd_prefix = ['/bin/bash', _path.join(_self_path, 'vcs.sh')]
PROT_VER = 1
def _parse_oldver(oldver):
if oldver is None:
return PROT_VER, 0, ''
try:
prot_ver, count, ver = oldver.split('.', maxsplit=2)
prot_ver = int(prot_ver)
count = int(count)
except:
return PROT_VER, 0, ''
if prot_ver != PROT_VER:
return PROT_VER, 0, ver
return PROT_VER, count, ver
def get_version(name, conf, callback):
vcs = conf['vcs']
oldver = conf['oldver']
cmd = _cmd_prefix + [name, vcs]
p = tornado.process.Subprocess(cmd, io_loop=IOLoop.instance(),
stdout=tornado.process.Subprocess.STREAM)
p.set_exit_callback(partial(_command_done, name, oldver, callback, p))
def _command_done(name, oldver, callback, process, status):
if status != 0:
logger.error('%s: command exited with %d.', name, status)
callback(name, None)
else:
process.stdout.read_until_close(partial(_got_version_from_cmd,
callback, name, oldver))
def _got_version_from_cmd(callback, name, oldver_str, output):
output = output.strip().decode('latin1')
oldver = _parse_oldver(oldver_str)
if output == oldver[2]:
callback(name, None)
else:
callback(name, "%d.%d.%s" % (oldver[0], oldver[1] + 1, output))

106
nvchecker/source/vcs.sh Normal file
View File

@ -0,0 +1,106 @@
#!/bin/bash
exec 3>&1
exec >&2
dir=$1
vcs=$2
parse_vcs_url() {
local _url=$1
local _out_var=$2
# remove folder::
[[ $_url =~ ^[^/:]*::(.*)$ ]] && _url=${BASH_REMATCH[1]}
[[ $_url =~ ^(bzr|git|hg|svn)([+:])(.*) ]] || return 1
local _proto=${BASH_REMATCH[1]}
[[ ${BASH_REMATCH[2]} = + ]] && _url=${BASH_REMATCH[3]}
local _real_url=${_url%\#*}
local _frag=''
[[ $_real_url = $_url ]] || _frag=${_url##*\#}
eval "${_out_var}"'=("${_proto}" "${_real_url}" "${_frag}")'
}
get_vcs() {
local _vcs=$1
local _out_var=$2
if [[ -z $_vcs ]]; then
_vcs=$(. PKGBUILD &> /dev/null
for src in "${source[@]}"; do
parse_vcs_url "$src" _ && {
echo "$src"
exit 0
}
done
exit 1) || return 1
fi
parse_vcs_url "$_vcs" "$_out_var"
}
git_get_version() {
local _url=$1
local _frag=$2
local _ref=''
if [[ -z $_frag ]]; then
_ref=HEAD
elif [[ $_frag =~ ^commit=(.*)$ ]]; then
echo "${BASH_REMATCH[1]}"
return 0
elif [[ $_frag =~ ^branch=(.*)$ ]]; then
_ref=refs/heads/${BASH_REMATCH[1]}
elif [[ $_frag =~ ^tag=(.*)$ ]]; then
_ref=refs/tags/${BASH_REMATCH[1]}
else
return 1
fi
local _res=$(git ls-remote "$_url" "$_ref")
[[ $_res =~ ^([a-fA-F0-9]*)[[:blank:]] ]] || return 1
echo "${BASH_REMATCH[1]}"
}
hg_get_version() {
local _url=$1
local _frag=$2
local _ref
if [[ -z $_frag ]]; then
_ref=default
elif [[ $_frag =~ ^(revision|tag|branch)=(.*)$ ]]; then
_ref=${BASH_REMATCH[2]}
else
return 1
fi
hg identify "${_url}#${_ref}"
}
svn_get_version() {
local _url=$1
local _frag=$2
local _extra_arg=()
if [[ -z $_frag ]]; then
true
elif [[ $_frag =~ ^(revision)=(.*)$ ]]; then
_extra_arg=(-r "${BASH_REMATCH[2]}")
else
return 1
fi
# Get rid of locale
env -i PATH="${PATH}" svn info "${_extra_arg[@]}" "${_url}" | \
sed -n 's/^Revision:[[:blank:]]*\([0-9]*\)/\1/p'
}
bzr_get_version() {
local _url=$1
local _frag=$2
local _extra_arg=()
if [[ -z $_frag ]]; then
true
elif [[ $_frag =~ ^(revision)=(.*)$ ]]; then
_extra_arg=(-r "${BASH_REMATCH[2]}")
else
return 1
fi
bzr revno -q "${_extra_arg[@]}" "${_url}"
}
cd "${dir}"
get_vcs "${vcs}" components || exit 1
eval "${components[0]}_get_version"' ${components[@]:1}' >&3

View File

@ -16,6 +16,7 @@ setup(
'nvcmp = nvchecker.tools:cmp',
],
},
package_data={'nvchecker': ['source/vcs.sh']},
author = 'lilydjwg',
author_email = 'lilydjwg@gmail.com',