diff --git a/README.rst b/README.rst index f129378..da6ba39 100644 --- a/README.rst +++ b/README.rst @@ -126,10 +126,15 @@ branch Which branch to track? Default: ``master``. use_latest_release - Set this to ``true`` to check for the latest relase on GitHub. An annotated + Set this to ``true`` to check for the latest release on GitHub. An annotated tag creates a "release" on GitHub. It's not the same with git tags, which includes both annotated tags and lightweight ones. +use_max_tag + Set this to ``true`` to check for the max tag on GitHub. Unlike ``use_latest_release``, + this option includes both annotated tags and lightweight ones, and return the biggest one + sorted by ``pkg_resources.parse_version``. + An environment variable ``NVCHECKER_GITHUB_TOKEN`` can be set to a GitHub OAuth token in order to request more frequently than anonymously. Check BitBucket diff --git a/nvchecker/source/github.py b/nvchecker/source/github.py index 7ed254c..7665cbc 100644 --- a/nvchecker/source/github.py +++ b/nvchecker/source/github.py @@ -2,17 +2,22 @@ import os import json from functools import partial +from pkg_resources import parse_version from tornado.httpclient import AsyncHTTPClient, HTTPRequest GITHUB_URL = 'https://api.github.com/repos/%s/commits?sha=%s' GITHUB_LATEST_RELEASE = 'https://api.github.com/repos/%s/releases/latest' +GITHUB_MAX_TAG = 'https://api.github.com/repos/%s/tags' def get_version(name, conf, callback): repo = conf.get('github') br = conf.get('branch', 'master') use_latest_release = conf.getboolean('use_latest_release', False) + use_max_tag = conf.getboolean('use_max_tag', False) if use_latest_release: url = GITHUB_LATEST_RELEASE % repo + elif use_max_tag: + url = GITHUB_MAX_TAG % repo else: url = GITHUB_URL % (repo, br) headers = {'Accept': "application/vnd.github.quicksilver-preview+json"} @@ -20,12 +25,15 @@ def get_version(name, conf, callback): headers['Authorization'] = 'token %s' % os.environ['NVCHECKER_GITHUB_TOKEN'] request = HTTPRequest(url, headers=headers, user_agent='lilydjwg/nvchecker') AsyncHTTPClient().fetch(request, - callback=partial(_github_done, name, use_latest_release, callback)) + callback=partial(_github_done, name, use_latest_release, use_max_tag, callback)) -def _github_done(name, use_latest_release, callback, res): +def _github_done(name, use_latest_release, use_max_tag, callback, res): data = json.loads(res.body.decode('utf-8')) if use_latest_release: version = data['tag_name'] + elif use_max_tag: + data.sort(key=lambda tag: parse_version(tag["name"])) + version = data[-1]["name"] else: version = data[0]['commit']['committer']['date'].split('T', 1)[0].replace('-', '') callback(name, version) diff --git a/tests/test_github.py b/tests/test_github.py new file mode 100644 index 0000000..160bed6 --- /dev/null +++ b/tests/test_github.py @@ -0,0 +1,12 @@ +from tests.helper import ExternalVersionTestCase + + +class GitHubTest(ExternalVersionTestCase): + def test_github(self): + self.assertEqual(self.sync_get_version("example", {"github": "harry-sanabria/ReleaseTestRepo"}), "20140122") + + def test_github_latest_release(self): + self.assertEqual(self.sync_get_version("example", {"github": "harry-sanabria/ReleaseTestRepo", "use_latest_release": 1}), "release3") + + def test_github_max_tag(self): + self.assertEqual(self.sync_get_version("example", {"github": "harry-sanabria/ReleaseTestRepo", "use_max_tag": 1}), "second_release")