Source code for rosdistro.manifest_provider.github

# Software License Agreement (BSD License)
#
# Copyright (c) 2013, Open Source Robotics Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of Open Source Robotics Foundation, Inc. nor
#    the names of its contributors may be used to endorse or promote
#    products derived from this software without specific prior
#    written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

try:
    from urllib.request import urlopen, Request
    from urllib.error import URLError
except ImportError:
    from urllib2 import urlopen, Request
    from urllib2 import URLError

import base64
import json
import os

from catkin_pkg.package import parse_package_string

from rosdistro.source_repository_cache import SourceRepositoryCache
from rosdistro import logger

GITHUB_USER = os.getenv('GITHUB_USER', None)
GITHUB_PASSWORD = os.getenv('GITHUB_PASSWORD', None)

def _get_url_contents(url):
    return urlopen(url).read().decode('utf-8')

[docs]def github_manifest_provider(_dist_name, repo, pkg_name): assert repo.version server, path = repo.get_url_parts() if not server.endswith('github.com'): logger.debug('Skip non-github url "%s"' % repo.url) raise RuntimeError('can not handle non github urls') release_tag = repo.get_release_tag(pkg_name) if not repo.has_remote_tag(release_tag): raise RuntimeError('specified tag "%s" is not a git tag' % release_tag) url = 'https://raw.githubusercontent.com/%s/%s/package.xml' % (path, release_tag) try: logger.debug('Load package.xml file from url "%s"' % url) return _get_url_contents(url) except URLError as e: logger.debug('- failed (%s), trying "%s"' % (e, url)) raise RuntimeError()
[docs]def github_source_manifest_provider(repo): server, path = repo.get_url_parts() if not server.endswith('github.com'): logger.debug('Skip non-github url "%s"' % repo.url) raise RuntimeError('can not handle non github urls') tree_url = 'https://api.github.com/repos/%s/git/trees/%s?recursive=1' % (path, repo.version) req = Request(tree_url) if GITHUB_USER and GITHUB_PASSWORD: logger.debug('- using http basic auth from supplied environment variables.') credential_pair = '%s:%s' % (GITHUB_USER, GITHUB_PASSWORD) authheader = 'Basic %s' % base64.b64encode(credential_pair.encode()).decode() req.add_header('Authorization', authheader) try: tree_json = json.loads(_get_url_contents(req)) logger.debug('- load repo tree from %s' % tree_url) except URLError as e: raise RuntimeError('Unable to fetch JSON tree from %s: %s' % (tree_url, e)) if tree_json['truncated']: raise RuntimeError('JSON tree is truncated, must perform full clone.') package_xml_paths = set() for obj in tree_json['tree']: if obj['path'].split('/')[-1] == 'package.xml': package_xml_paths.add(os.path.dirname(obj['path'])) # Filter out ones that are inside other packages (eg, part of tests) def package_xml_in_parent(path): if path == '': return True parent = path while True: parent = os.path.dirname(parent) if parent in package_xml_paths: return False if parent == '': return True package_xml_paths = list(filter(package_xml_in_parent, package_xml_paths)) cache = SourceRepositoryCache.from_ref(tree_json['sha']) for package_xml_path in package_xml_paths: url = 'https://raw.githubusercontent.com/%s/%s/%s' % \ (path, cache.ref(), package_xml_path + '/package.xml' if package_xml_path else 'package.xml') logger.debug('- load package.xml from %s' % url) package_xml = _get_url_contents(url) name = parse_package_string(package_xml).name cache.add(name, package_xml_path, package_xml) return cache