00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import os
00036 import sys
00037 import traceback
00038 import yaml
00039
00040 import types
00041
00042 import rospkg
00043
00044 from subprocess import call, check_call, Popen
00045 from xml.dom.minidom import getDOMImplementation, parse, _write_data, Node
00046
00047 from .repo_util import guess_vcs_uri, get_svn_url
00048
00049
00050
00051 def _override_write_data(writer, data):
00052 "Writes datachars to writer."
00053 if data is None:
00054 return
00055 data = data.replace("&", "&").replace("<", "<")
00056 data = data.replace("\"", """).replace(">", ">")
00057 writer.write(data)
00058
00059
00060
00061
00062 def _Element__writexml(self, writer, indent="", addindent="", newl=""):
00063
00064
00065
00066 writer.write(indent+"<" + self.tagName)
00067
00068 attrs = self._get_attributes()
00069 a_names = attrs.keys()
00070 a_names.sort()
00071
00072 for a_name in a_names:
00073 writer.write(" %s=\"" % a_name)
00074 v = attrs[a_name].value
00075 if v is None:
00076 v = ""
00077 _write_data(writer, v)
00078 writer.write("\"")
00079 if self.childNodes:
00080 writer.write(">%s"%(newl))
00081 for node in self.childNodes:
00082
00083 if node.nodeType == Node.ELEMENT_NODE:
00084 node.writexml = types.MethodType(_Element__writexml, node)
00085
00086 node.writexml(writer,indent+addindent,addindent,newl)
00087 writer.write("%s</%s>%s" % (indent,self.tagName,newl))
00088 else:
00089 writer.write("/>%s"%(newl))
00090
00091
00092 def generate_megamanifest(ctx, repos, checkouts_dir):
00093 all_pkgs = { }
00094 for repo_name, repo in repos:
00095 name = repo_name
00096 vcs = repo.type
00097 uri = repo.uri
00098
00099 assert uri, "repo [%s] has invalid uri [%s]"%(repo_name, uri)
00100
00101 print "snarfing manifests in local copy of %s"%name
00102
00103 if repo_name == 'ros':
00104 rel_path = os.path.join(checkouts_dir, 'ros-repo')
00105 else:
00106 rel_path = os.path.join(checkouts_dir, repo_name)
00107
00108 abs_co_path = os.path.abspath(rel_path)
00109
00110 repos_pkgs = {}
00111
00112 for pkg in rospkg.list_by_path('manifest.xml', rel_path, cache=repos_pkgs):
00113 if pkg not in all_pkgs:
00114
00115
00116
00117
00118 override_path = None
00119 true_uri = uri
00120 try:
00121 pkg_path = repos_pkgs[pkg]
00122 if vcs == 'svn':
00123 vcs0, true_uri = guess_vcs_uri(pkg_path)
00124
00125
00126
00127 if true_uri is None:
00128 print >> sys.stderr, "unable to guess VCS URI of [%s]"%(pkg_path)
00129 elif true_uri != uri:
00130 url_path = get_svn_url(pkg_path)
00131 override_path = url_path[len(true_uri):]
00132 else:
00133
00134
00135
00136 pkg_path = os.path.abspath(pkg_path)
00137 override_path = pkg_path[len(abs_co_path):]
00138 else:
00139
00140 override_path = ''
00141 if vcs == 'git':
00142
00143 vcs1, true_uri = guess_vcs_uri(pkg_path)
00144 if 'github.com/' in uri and uri.endswith('.git'):
00145 true_uri = uri[:-4]
00146 except:
00147 traceback.print_exc()
00148 pass
00149 all_pkgs[pkg] = [pkg, name, true_uri, pkg_path, override_path]
00150
00151 pkgs_dom = getDOMImplementation().createDocument(None, 'pkgs', None)
00152 pkgs_node = pkgs_dom.documentElement
00153
00154 mega_yaml = []
00155
00156 for k, v in all_pkgs.iteritems():
00157 pkg, repo, uri, rel_path, override_path = v
00158 assert (rel_path and rel_path != os.sep), "Relative path calculation is messed up, package is [%s]"%(pkg)
00159
00160 manifest_p = rel_path+os.sep+'manifest.xml'
00161 try:
00162 manifest = parse(manifest_p)
00163 try:
00164 m_obj = ctx.manifests[pkg]
00165 mega_yaml.append({'name': pkg, 'brief': m_obj.brief, 'description': m_obj.description or '', 'repo': repo})
00166 except KeyError:
00167 print >> sys.stderr, "no manifest for [%s]"%(pkg)
00168
00169 manifest_node = manifest.documentElement
00170 manifest_node.setAttribute("name", k)
00171 manifest_node.setAttribute("repo", repo)
00172 manifest_node.setAttribute("repo_host", uri)
00173
00174 base_rel_path = os.path.join(checkouts_dir, name)
00175 rel_path = rel_path[len(base_rel_path):]
00176 if override_path is not None:
00177 manifest_node.setAttribute("path", override_path)
00178 else:
00179 manifest_node.setAttribute("path", rel_path)
00180
00181 if manifest_node is None:
00182 print >> sys.stderr, "manifest_node empty", pkg, repo, uri, rel_path, override_path
00183 else:
00184 pkgs_node.appendChild(manifest_node)
00185 except Exception as e:
00186 print "error parsing %s [%s]: %s"%(pkg, manifest_p, str(e))
00187
00188 print "writing megamanifest..."
00189 try:
00190 os.makedirs(ctx.docdir)
00191 except:
00192 pass
00193 fname = os.path.join(ctx.docdir, 'megamanifest.xml')
00194 with open(fname, 'w') as f:
00195 print "pkgs_node is ", pkgs_node
00196
00197 if pkgs_node.nodeType == Node.ELEMENT_NODE:
00198 pkgs_node.writexml = types.MethodType(_Element__writexml, pkgs_node)
00199 else:
00200 print "OTHER NODE TYPE", pkgs_node.nodeType
00201 print "successfully changed method"
00202 text = pkgs_node.toxml(encoding='utf-8')
00203 print "text is", text
00204 f.write(text)
00205
00206 fname2 = os.path.join(ctx.docdir, 'megamanifest.yaml')
00207 with open(fname2, 'w') as f:
00208 f.write(yaml.safe_dump(mega_yaml, default_style="'"))
00209
00210 return [fname, fname2]