From f85909e6eedba3ac6133017e858efe2c871ccfd7 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sun, 2 Nov 2014 23:20:12 -0500 Subject: [PATCH 1/5] ignore package files --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 6d6fa31..0d6c274 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ records/ +*.egg-info/ +__pycache__/ +/build/ +*.pyc +*.pyo From ff7f3c65f9dfa44e365c84000b6d8a9ba17f1a96 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Mon, 3 Nov 2014 01:42:17 -0500 Subject: [PATCH 2/5] add vcs version checker --- nvchecker/get_version.py | 2 +- nvchecker/source/vcs.py | 50 ++++++++++++++++++ nvchecker/source/vcs.sh | 106 +++++++++++++++++++++++++++++++++++++++ setup.py | 1 + 4 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 nvchecker/source/vcs.py create mode 100644 nvchecker/source/vcs.sh diff --git a/nvchecker/get_version.py b/nvchecker/get_version.py index 93e0fb8..6bedf54 100644 --- a/nvchecker/get_version.py +++ b/nvchecker/get_version.py @@ -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): diff --git a/nvchecker/source/vcs.py b/nvchecker/source/vcs.py new file mode 100644 index 0000000..e968237 --- /dev/null +++ b/nvchecker/source/vcs.py @@ -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)) diff --git a/nvchecker/source/vcs.sh b/nvchecker/source/vcs.sh new file mode 100644 index 0000000..a807cf1 --- /dev/null +++ b/nvchecker/source/vcs.sh @@ -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 diff --git a/setup.py b/setup.py index c228be4..7d8657e 100755 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ setup( 'nvcmp = nvchecker.tools:cmp', ], }, + package_data={'nvchecker': ['source/vcs.sh']}, author = 'lilydjwg', author_email = 'lilydjwg@gmail.com', From 5457360858d0b6e8a51bcce4e55b9628684553fa Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Mon, 3 Nov 2014 07:39:56 -0500 Subject: [PATCH 3/5] Update README --- README.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.rst b/README.rst index 6e1cf92..3730e96 100644 --- a/README.rst +++ b/README.rst @@ -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 commit. The version returned is currently not related to the version of the package and will increase whenever the commit changes. + +vcs + The url of the remote VCS repo, using the same syntax with a VCS url in PKGBUILD. 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 package under the path where nvchecker is run. Also, all the command, 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 :-) From 0863ff5adf89dfd5648ba307cc654976db2e3533 Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Mon, 3 Nov 2014 16:15:35 +0800 Subject: [PATCH 4/5] fix coding style for vcs.py --- nvchecker/source/vcs.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nvchecker/source/vcs.py b/nvchecker/source/vcs.py index e968237..75e5e4a 100644 --- a/nvchecker/source/vcs.py +++ b/nvchecker/source/vcs.py @@ -8,22 +8,22 @@ 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')] +_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, '') + 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, '') + return PROT_VER, 0, '' if prot_ver != PROT_VER: - return (PROT_VER, 0, ver) - return (PROT_VER, count, ver) + return PROT_VER, 0, ver + return PROT_VER, count, ver def get_version(name, conf, callback): vcs = conf['vcs'] From 369f75949df53515b33706946ae7c75cdb032181 Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Mon, 3 Nov 2014 22:08:26 +0800 Subject: [PATCH 5/5] minor update for README --- README.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 3730e96..3d5ec42 100644 --- a/README.rst +++ b/README.rst @@ -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 `_. +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. @@ -159,10 +159,10 @@ manual Version Control System (VCS) (git, hg, svn, bzr) ------------------------------------------------ -Check a VCS repo for new commit. The version returned is currently not related to the version of the package and will increase whenever the commit changes. +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. 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 package under the path where nvchecker is run. Also, all the command, 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). Other ----- @@ -180,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