$search
00001 #!/usr/bin/env python 00002 # Software License Agreement (BSD License) 00003 # 00004 # Copyright (c) 2008, Willow Garage, Inc. 00005 # All rights reserved. 00006 # 00007 # Redistribution and use in source and binary forms, with or without 00008 # modification, are permitted provided that the following conditions 00009 # are met: 00010 # 00011 # * Redistributions of source code must retain the above copyright 00012 # notice, this list of conditions and the following disclaimer. 00013 # * Redistributions in binary form must reproduce the above 00014 # copyright notice, this list of conditions and the following 00015 # disclaimer in the documentation and/or other materials provided 00016 # with the distribution. 00017 # * Neither the name of Willow Garage, Inc. nor the names of its 00018 # contributors may be used to endorse or promote products derived 00019 # from this software without specific prior written permission. 00020 # 00021 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 # POSSIBILITY OF SUCH DAMAGE. 00033 # 00034 # Revision $Id: __init__.py 16886 2012-08-23 00:20:42Z tfoote $ 00035 00036 import sys 00037 import os 00038 import time 00039 import traceback 00040 import collections 00041 00042 import rospkg 00043 00044 import rosdoc 00045 import rosdoc.upload 00046 00047 from .core import load_repos, Repo, repo_packages, repo_stacks 00048 from . import package_header 00049 from . import stack_header 00050 from . import repo_header 00051 from . import megamanifest 00052 from . import megastack 00053 00054 def generate_docs(ctx, repos, checkout_dir, test=False): 00055 if not test: 00056 # when we are testing just rosdoc_rosorg, we don't want to do 00057 # the more expensive rosdoc build 00058 artifacts = rosdoc.generate_docs(ctx) 00059 else: 00060 artifacts = [] 00061 00062 stack_dirs = [] 00063 00064 timings = ctx.timings 00065 timings['package-header'] = 0. 00066 timings['stack-header'] = 0. 00067 timings['repo-header'] = 0. 00068 00069 # first package/stack to be documented wins 00070 completed_packages = set() 00071 completed_stacks = set() 00072 00073 meta_repos = collections.defaultdict(list) 00074 00075 rosstack = rospkg.RosStack() 00076 for repo_name, repo in repos: 00077 print "repo", repo_name 00078 00079 # Packages 00080 start = time.time() 00081 packages = repo_packages(repo, checkout_dir) 00082 print "repo packages: %s"%(packages) 00083 00084 # ros-repo doesn't include the ros stack, so we have to add it back in 00085 if repo_name == 'ros': 00086 packages = packages + rosstack.packages_of('ros') 00087 # only document requested packages, and don't document anything already documented (name collisions) 00088 packages = list((set(packages) & set(ctx.packages)) - completed_packages) 00089 00090 print "[%s] Generating manifest.yaml files for [%s]"%(repo_name, ','.join(packages)) 00091 package_files = package_header.generate_package_headers(ctx, repo, packages) 00092 for p_f in package_files: 00093 # workaround bug in the indexer where 'external' packages 00094 # don't generate artifacts, and thus the manifest.yaml is 00095 # not updated. We generally assume that artifacts is 00096 # redundant because most packages generate a full 00097 # directory during the normal rosdoc. In this case, we 00098 # manually add to the artifacts so that it will get 00099 # uploaded. 00100 pfd = os.path.dirname(p_f) 00101 package = os.path.basename(pfd) 00102 # check both full path and package name 00103 if not pfd in artifacts and package not in artifacts: 00104 artifacts.append(pfd) 00105 timings['package-header'] += time.time() - start 00106 00107 # Stacks 00108 start = time.time() 00109 stacks = repo_stacks(repo, checkout_dir) 00110 # NOTE: we ignore ctx.stacks as we assume we document 00111 # everything in the repo. Don't document anything already 00112 # documented (name collisions) 00113 stacks = list(set(stacks) - completed_stacks) 00114 print "repo stacks: %s"%(stacks) 00115 timings['stack-header'] += time.time() - start 00116 00117 # - generate 00118 print "[%s] Generating stack.yaml files for [%s]"%(repo_name, ','.join(stacks)) 00119 stack_files = stack_header.generate_stack_headers(ctx, repo, stacks) 00120 # - simplify artifacts to the directory name 00121 stack_dirs.extend([os.path.dirname(f) for f in stack_files]) 00122 00123 # Repos 00124 start = time.time() 00125 artifacts.extend(repo_header.generate_repo_header(ctx, repo, stack_files, package_files)) 00126 if repo.aggregate_name is not None and repo.name != repo.aggregate_name: 00127 meta_repos[repo.aggregate_name].append((repo, stack_files, package_files)) 00128 timings['repo-header'] += time.time() - start 00129 00130 completed_packages.update(packages) 00131 completed_stacks.update(stacks) 00132 00133 #print "completed packages: %s"%(completed_packages) 00134 #print "completed stacks: %s"%(completed_stacks) 00135 00136 # meta repo generation 00137 start = time.time() 00138 for aggregate_name, repo_assets in meta_repos.iteritems(): 00139 print "processing meta repo [%s]"%(aggregate_name) 00140 00141 # generate union of sub-repos 00142 stack_files = [] 00143 package_files = [] 00144 for _, s, p in repo_assets: 00145 stack_files.extend(s) 00146 package_files.extend(s) 00147 00148 uri = type_ = '' 00149 rosinstall = {} 00150 name = local_path = aggregate_name 00151 repo = Repo(name, type_, uri, rosinstall, local_path) 00152 artifacts.extend(repo_header.generate_repo_header(ctx, repo, stack_files, package_files)) 00153 timings['repo-header'] += time.time() - start 00154 00155 # we don't include package artifacts because they are already covered elsewhere 00156 return artifacts + stack_dirs 00157 00158 def generate_rosbrowse(ctx, repos, checkout_dir, test=False): 00159 timings = ctx.timings 00160 timings['megamanifest'] = 0. 00161 timings['megastack'] = 0. 00162 00163 artifacts = [] 00164 try: 00165 start = time.time() 00166 artifacts.extend(megamanifest.generate_megamanifest(ctx, repos, checkout_dir)) 00167 timings['megamanifest'] += time.time() - start 00168 00169 except: 00170 print >> sys.stderr, "megamanifest generation failed" 00171 traceback.print_exc() 00172 00173 try: 00174 start = time.time() 00175 artifacts.extend(megastack.generate_megastack(ctx, repos, checkout_dir)) 00176 timings['megastack'] += time.time() - start 00177 except: 00178 print >> sys.stderr, "megastack generation failed" 00179 traceback.print_exc() 00180 00181 return artifacts 00182 00183 def rosorg_main(): 00184 parser = rosdoc.get_optparse('rosdoc_rosorg') 00185 parser.add_option("--repos", default=None, 00186 dest="repos", metavar="ROSBROWSE_REPOS_FILE", 00187 help="repos list from rosbrowse for determining repository names/roots") 00188 parser.add_option("--distro-index", default=None, 00189 dest="distro_index", metavar="DISTRO_INDEX_FILE", 00190 help="distro index for determining repository contents for binary installs") 00191 parser.add_option("--checkout", default='checkouts', 00192 dest="checkout_dir", metavar="CHECKOUT_DIR", 00193 help="path to checkout directory for repos file") 00194 parser.add_option("--test", default=False, 00195 dest="test", action="store_true", 00196 help="run in test mode") 00197 parser.add_option("--rosbrowse", default=False, 00198 dest="rosbrowse", action="store_true", 00199 help="run rosbrowse indexer instead") 00200 00201 options, package_filters = parser.parse_args() 00202 00203 # Load the repository file 00204 if options.repos: 00205 repos_file = options.repos 00206 else: 00207 parser.error("please specify a --repos file") 00208 repos = load_repos(repos_file, options.distro_index) 00209 00210 # Load the rosdoc environment 00211 ctx = rosdoc.RosdocContext(options.name, options.docdir, 00212 package_filters=package_filters, path_filters=options.paths) 00213 ctx.allow_rosmake = False 00214 try: 00215 ctx.quiet = options.quiet 00216 ctx.init() 00217 00218 if not options.rosbrowse: 00219 artifacts = generate_docs(ctx, repos, options.checkout_dir, options.test) 00220 else: 00221 artifacts = generate_rosbrowse(ctx, repos, options.checkout_dir) 00222 00223 if options.upload: 00224 rosdoc.upload.upload(ctx, artifacts, options.upload) 00225 00226 print "Timings" 00227 for k, v in ctx.timings.iteritems(): 00228 print " * %.2f %s"%(v, k) 00229 00230 except KeyboardInterrupt: 00231 pass 00232 except: 00233 traceback.print_exc() 00234 sys.exit(1)