Source code for rosdistro.cli.rosdistro_convert

# 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.

import os
import subprocess
import sys
import tempfile
from urllib.error import HTTPError

from rosdistro.common import rmtree
from rosdistro.loader import load_url
from rosdistro.release_file import ReleaseFile

import yaml


BASE_SRC_URL = 'https://raw.github.com/ros/rosdistro/master'


[docs] def get_targets(): url = BASE_SRC_URL + '/releases/targets.yaml' print('Load "%s"' % url) yaml_str = load_url(url) data = yaml.safe_load(yaml_str) targets = {} for d in data: targets[d.keys()[0]] = d.values()[0] return targets
[docs] def convert_release(dist_name, targets): url = BASE_SRC_URL + '/releases/%s.yaml' % dist_name print('Load "%s"' % url) yaml_str = load_url(url) input_ = yaml.safe_load(yaml_str) # improve conversion performance by reusing results from last run last_dist = None if os.path.exists(dist_name + '/release.yaml'): with open(dist_name + '/release.yaml', 'r') as f: last_data = yaml.safe_load(f.read()) last_dist = ReleaseFile(dist_name, last_data) output = {} output['type'] = 'release' output['version'] = 1 output['platforms'] = {'ubuntu': targets[dist_name]} output['repositories'] = {} for repo_name in sorted(input_['repositories']): input_repo = input_['repositories'][repo_name] output_repo = {} output_repo['url'] = input_repo['url'] output_repo['version'] = input_repo['version'] if output_repo['version'] is None: print('- "' + repo_name + '" has no version') del output_repo['version'] pkg_name = repo_name if 'packages' in input_repo: output_repo['packages'] = {} unary_repo = len(input_repo['packages']) == 1 for pkg_name in input_repo['packages']: if unary_repo: if input_repo['packages'][pkg_name] is None: if pkg_name == repo_name: del output_repo['packages'] else: output_repo['packages'][pkg_name] = {'subfolder': pkg_name} else: output_repo['packages'][pkg_name] = input_repo['packages'][pkg_name] break output_repo['packages'][pkg_name] = None if input_repo['packages'][pkg_name] is not None and input_repo['packages'][pkg_name] != pkg_name: output_repo['packages'][pkg_name] = {'subfolder': input_repo['packages'][pkg_name]} output['repositories'][repo_name] = output_repo if 'version' in output_repo and output_repo['version'] is not None: tag_template = _get_tag_template(dist_name, output_repo, pkg_name, last_dist.repositories[repo_name] if last_dist and repo_name in last_dist.repositories else None) output_repo['tags'] = {'release': tag_template} yaml_str = yaml.dump(output, default_flow_style=False) yaml_str = yaml_str.replace(': null', ':') with open(dist_name + '/release.yaml', 'w') as f: f.write('%YAML 1.1\n') f.write('# ROS release file\n') f.write('# see REP 137: http://ros.org/reps/rep-0137.html\n') f.write('---\n') f.write(yaml_str)
def _get_tag_template(dist_name, repo, pkg_name, last_repo=None): # reuse tag template if fetched before for the same repo and version if last_repo and last_repo.version == repo['version']: if 'release' in last_repo.tags: return last_repo.tags['release'] assert 'github.com' in repo['url'] release_tag = 'release/{0}/{1}/{2}'.format(dist_name, pkg_name, repo['version']) url = _github_raw_url(repo['url'], release_tag) print('- ' + pkg_name + ': ' + url) try: try: load_url(url) return 'release/%s/{package}/{version}' % dist_name except HTTPError: # try alternative tag upstream_version = repo['version'].split('-')[0] release_tag = 'release/{0}/{1}'.format(pkg_name, upstream_version) url = _github_raw_url(repo['url'], release_tag) print('- ' + pkg_name + ': ' + url) load_url(url) return 'release/{package}/{upstream_version}' except HTTPError as e: raise RuntimeError('Could not determine tag using %s, %s, %s: %s' % (dist_name, repo, pkg_name, e)) def _github_raw_url(url, tag): url = url.replace('.git', '/tree/%s/' % tag) url = url.replace('git://', 'https://') # url = url.replace('https://', 'https://raw.') return url
[docs] def convert_source(dist_name): url = BASE_SRC_URL + '/releases/%s-devel.yaml' % dist_name print('Load "%s"' % url) yaml_str = load_url(url) input_ = yaml.safe_load(yaml_str) output = {} output['type'] = 'source' output['version'] = 1 output['repositories'] = {} for repo_name in sorted(input_['repositories']): input_repo = input_['repositories'][repo_name] output_repo = {} output_repo['type'] = input_repo['type'] output_repo['url'] = input_repo['url'] output_repo['version'] = input_repo['version'] if output_repo['type'] == 'svn' and output_repo['version'] is None: output_repo['version'] = 'HEAD' if output_repo['version'] is None: print('- "' + repo_name + '" has no version') del output_repo['version'] output['repositories'][repo_name] = output_repo yaml_str = yaml.dump(output, default_flow_style=False) yaml_str = yaml_str.replace(': null', ':') with open(dist_name + '/source.yaml', 'w') as f: f.write('%YAML 1.1\n') f.write('# ROS source file\n') f.write('# see REP 137: http://ros.org/reps/rep-0137.html\n') f.write('---\n') f.write(yaml_str)
[docs] def convert_doc(dist_name): base = tempfile.mktemp() rc = subprocess.call(['git', 'clone', '--depth', '0', 'git://github.com/ros/rosdistro.git', base]) if rc: print('Failed to checkout rosdistro repo', file=sys.stderr) rmtree(base) return doc_base = os.path.join(base, 'doc', dist_name) rosinstalls = {} rosinstall_depends = {} for filename in os.listdir(doc_base): if filename.endswith('.rosinstall'): name = os.path.splitext(os.path.basename(filename))[0] with open(os.path.join(doc_base, filename)) as f: data = yaml.safe_load(f) if name.endswith('_depends'): rosinstall_depends[name] = data else: rosinstalls[name] = data rmtree(base) # currently no doc has depends in groovy and hydro # assert not rosinstall_depends output = {} output['type'] = 'doc' output['version'] = 1 output['repositories'] = {} for repo_name in sorted(rosinstalls.keys()): for input_repo in rosinstalls[repo_name]: output_repo = {} output_repo['type'] = input_repo.keys()[0] input_data = input_repo[output_repo['type']] output_repo['url'] = input_data['uri'] if 'version' in input_data: output_repo['version'] = input_data['version'] if output_repo['type'] == 'svn' and ('version' not in output_repo or output_repo['version'] is None): output_repo['version'] = 'HEAD' if 'version' not in output_repo or output_repo['version'] is None: print('- "' + repo_name + '" has no version') if 'version' in output_repo: del output_repo['version'] local_name = input_data['local-name'] if local_name in output['repositories']: if output_repo == output['repositories'][local_name]: print('- skip duplicate "%s"' % local_name) continue key = local_name i = 1 while key in output['repositories']: i += 1 key = local_name + '_%d' % i print('- duplicate: %s %s -> %s' % (repo_name, local_name, key)) if i > 1: # ignore duplicates print(' ignoring duplicate') continue output['repositories'][key] = output_repo yaml_str = yaml.dump(output, default_flow_style=False) yaml_str = yaml_str.replace(': null', ':') with open(dist_name + '/doc.yaml', 'w') as f: f.write('%YAML 1.1\n') f.write('# ROS doc file\n') f.write('# see REP 137: http://ros.org/reps/rep-0137.html\n') f.write('---\n') f.write(yaml_str)
[docs] def main(): targets = get_targets() for distro in ['groovy', 'hydro']: print('\nConverting "%s"\n' % distro) convert_release(distro, targets) convert_source(distro) convert_doc(distro)
if __name__ == '__main__': sys.exit(main())