From 19d78411a59aeb043b86cf8203c76686c3f2acb6 Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Thu, 5 Nov 2015 15:31:56 +0800 Subject: [PATCH] Add GitLab support --- README.rst | 19 ++++++++++++++++ nvchecker/get_version.py | 2 +- nvchecker/source/gitlab.py | 45 ++++++++++++++++++++++++++++++++++++++ tests/test_gitlab.py | 13 +++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 nvchecker/source/gitlab.py create mode 100644 tests/test_gitlab.py diff --git a/README.rst b/README.rst index 4c2bce4..9a8c7d6 100644 --- a/README.rst +++ b/README.rst @@ -163,6 +163,25 @@ branch Anonymously only. Authorization is not supported yet. +Check GitLab +------------- +Check `GitLab `_ for updates. The version returned is in date format ``%Y%m%d``, e.g. ``20130701``. + +gitlab + The gitlab repository, with author, e.g. ``Deepin/deepin-music``. + +branch + Which branch to track? Default: ``master``. + +use_max_tag + Set this to ``true`` to check for the max tag on BitBucket. Will return the biggest one + sorted by ``pkg_resources.parse_version``. + +host + Hostname for self-hosted GitLab instance. + +Authenticated only. + Check PyPI ---------- Check `PyPI `_ for updates. diff --git a/nvchecker/get_version.py b/nvchecker/get_version.py index ed58ef2..c403d8e 100644 --- a/nvchecker/get_version.py +++ b/nvchecker/get_version.py @@ -5,7 +5,7 @@ logger = logging.getLogger(__name__) handler_precedence = ( 'github', 'gitcafe', 'aur', 'pypi', 'archpkg', 'gems', 'pacman', 'cmd', 'bitbucket', 'gcode_hg', 'gcode_svn', 'regex', 'manual', 'vcs', - 'npm', 'hackage', 'cpan', + 'npm', 'hackage', 'cpan', 'gitlab', ) def get_version(name, conf, callback): diff --git a/nvchecker/source/gitlab.py b/nvchecker/source/gitlab.py new file mode 100644 index 0000000..34fade7 --- /dev/null +++ b/nvchecker/source/gitlab.py @@ -0,0 +1,45 @@ +import os +import json +from functools import partial +import logging +import urllib.parse + +from pkg_resources import parse_version +from tornado.httpclient import AsyncHTTPClient, HTTPRequest + +GITLAB_URL = 'https://%s/api/v3/projects/%s/repository/commits?ref_name=%s' +GITLAB_MAX_TAG = 'https://%s/api/v3/projects/%s/repository/tags' + +logger = logging.getLogger(__name__) + +def get_version(name, conf, callback): + repo = urllib.parse.quote_plus(conf.get('gitlab')) + br = conf.get('branch', 'master') + host = conf.get('host', "gitlab.com") + use_max_tag = conf.getboolean('use_max_tag', False) + + env_name = "NVCHECKER_GITLAB_TOKEN_" + host.upper().replace(".", "_").replace("/", "_") + token = conf.get('token', os.environ.get(env_name, None)) + if token is None: + logger.error('%s: No gitlab token specified.', name) + callback(name, None) + return + + if use_max_tag: + url = GITLAB_MAX_TAG % (host, repo) + else: + url = GITLAB_URL % (host, repo, br) + + headers = {"PRIVATE-TOKEN": token} + request = HTTPRequest(url, headers=headers, user_agent='lilydjwg/nvchecker') + AsyncHTTPClient().fetch(request, + callback=partial(_gitlab_done, name, use_max_tag, callback)) + +def _gitlab_done(name, use_max_tag, callback, res): + data = json.loads(res.body.decode('utf-8')) + if use_max_tag: + data.sort(key=lambda tag: parse_version(tag["name"])) + version = data[-1]["name"] + else: + version = data[0]['created_at'].split('T', 1)[0].replace('-', '') + callback(name, version) diff --git a/tests/test_gitlab.py b/tests/test_gitlab.py new file mode 100644 index 0000000..1aca3bc --- /dev/null +++ b/tests/test_gitlab.py @@ -0,0 +1,13 @@ +import os +import pytest +from tests.helper import ExternalVersionTestCase + + +@pytest.mark.skipif("NVCHECKER_GITLAB_TOKEN_GITLAB_COM" not in os.environ, + reason="requires NVCHECKER_GITLAB_TOKEN_GITLAB_COM") +class GitLabTest(ExternalVersionTestCase): + def test_gitlab(self): + self.assertEqual(self.sync_get_version("example", {"gitlab": "gitlab-org/gitlab-test"}), "20150825") + + def test_gitlab_max_tag(self): + self.assertEqual(self.sync_get_version("example", {"gitlab": "gitlab-org/gitlab-test", "use_max_tag": 1}), "v1.1.0")