00001
00002
00003 from __future__ import print_function
00004
00005 import os
00006 import sys
00007 import yaml
00008 import urllib2
00009 import rospkg.distro
00010
00011 def get_base_dir():
00012 return os.getcwd()
00013
00014 def get_repos_list(base_dir):
00015 f = urllib2.urlopen('https://code.ros.org/svn/ros/stacks/rosorg/trunk/rosdoc_rosorg/repos.list')
00016 return yaml.load(f.read())
00017
00018 def _validate(rosinstall_data):
00019 for frag in rosinstall_data:
00020 for vcs_type, data in frag.items():
00021 if vcs_type == 'other' or vcs_type == 'setup-file':
00022 if not 'local-name' in data:
00023 raise TypeError('invalid rosinstall snippet, missing key [local-name]')
00024 continue
00025 for reqd in ['local-name', 'uri']:
00026 if not reqd in data:
00027 raise TypeError('invalid rosinstall snippet, missing key [%s]'%(reqd))
00028 path = data['local-name']
00029 uri = data['uri']
00030 version = data.get('version', '')
00031 for d in [path, uri, version]:
00032 if not type(d) == type('str'):
00033 raise TypeError('invalid rosinstall snippet, entry has bad type: %s'%(data))
00034
00035 def load_rosinstalls(repos_list, distro_name=None):
00036 print("repos list:")
00037 for repo_def in repos_list:
00038 print(yaml.dump(repo_def, default_flow_style=False))
00039
00040 to_download = []
00041 for repo_def in repos_list:
00042 uri = repo_def['uri']
00043 name = repo_def.get('name', None)
00044 to_download.append((uri, name))
00045
00046
00047 rosinstall_text = []
00048
00049
00050
00051
00052
00053 for uri, name in to_download:
00054 try:
00055 print("download rosinstall [%s]"%(uri))
00056 f = urllib2.urlopen(uri)
00057 text = f.read()
00058 rosinstall_text.append((uri, name, text))
00059 except:
00060 print("ERROR: cannot download [%s]"%(uri), file=sys.stderr)
00061
00062
00063 rosinstall_data = []
00064 for uri, name, text in rosinstall_text:
00065 try:
00066 data = yaml.load(text)
00067 if not type(data) == list:
00068 raise TypeError("rosinstall data must be a list")
00069 _validate(data)
00070 rosinstall_data.append((uri, name, data))
00071 except Exception as e:
00072 print("ERROR: invalid YAML format in [%s:%s]: %s\n.Ignoring repo. Text is:\n[%s]"%(name, uri, e, text))
00073
00074 if distro_name:
00075
00076 print("seeding with %s.rosdistro"%distro_name)
00077 distro_obj = rospkg.distro.load_distro(rospkg.distro.distro_uri(distro_name))
00078 text = rospkg.distro.distro_to_rosinstall(distro_obj, 'devel')
00079 rosinstall_data.append(('http://code.ros.org/svn/release/distros/%s.rosdistro'%distro_name, 'rosdistro_%s'%distro_name, text))
00080 return rosinstall_data
00081
00082 def create_repos_data(rosinstalls):
00083 alldata = []
00084
00085 for uri, name, data in reversed(rosinstalls):
00086
00087 if name:
00088 try:
00089 for entry in data:
00090 type_ = entry.keys()[0]
00091 if not 'meta' in entry[type_]:
00092 entry[type_]['meta'] = {}
00093 entry[type_]['meta']['repo-name'] = name
00094 except IndexError:
00095 print("ERROR: Invalid rosinstall file entry in [%s] (IndexError), ignoring\n%s"%(name, entry), file=sys.stderr)
00096 except TypeError:
00097 print("ERROR: Invalid rosinstall file entry in [%s] (TypeError), ignoring\n%s"%(name, entry), file=sys.stderr)
00098
00099 alldata.extend(data)
00100 return alldata
00101
00102 def generate_index(output_file, repo_name=None, rosdistro=None):
00103 base_dir = get_base_dir()
00104 repos_list = get_repos_list(base_dir)
00105 if repo_name:
00106 repos_list = [r for r in repos_list if r.get('name', None) in [repo_name, 'ros', 'ros-docs']]
00107 rosinstalls = load_rosinstalls(repos_list, rosdistro)
00108 data = create_repos_data(rosinstalls)
00109 print("writing %s"%(output_file))
00110 with open(output_file, 'w') as f:
00111 f.write(yaml.dump(data, default_flow_style=False))
00112
00113 if __name__ == '__main__':
00114 from optparse import OptionParser
00115 parser = OptionParser(usage="usage: %prog [options] <output-file>", prog='generate_index.py')
00116 parser.add_option("--repo",
00117 dest="repo_name", default=None,
00118 metavar="REPO-NAME",
00119 help="only generate for a particular repo")
00120 parser.add_option("--rosdistro",
00121 dest="rosdistro", default=None,
00122 metavar="rosdistro to use in the index",
00123 help="add a distro the the index")
00124 options, args = parser.parse_args()
00125 if args:
00126 output_file = args[0]
00127 else:
00128 output_file ='repos.rosinstall'
00129 generate_index(output_file, repo_name=options.repo_name, rosdistro=options.rosdistro)