$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$ 00035 00036 import sys 00037 import os 00038 import time 00039 import traceback 00040 from subprocess import Popen, PIPE 00041 00042 NAME='rosdoc' 00043 00044 from . rdcore import * 00045 from . import upload 00046 00047 from . import msgenator 00048 from . import docindex 00049 from . import licenseindex 00050 from . import epyenator 00051 from . import sphinxenator 00052 from . import landing_page 00053 00054 def get_optparse(name): 00055 """ 00056 Retrieve default option parser for rosdoc. Useful if building an 00057 extended rosdoc tool with additional options. 00058 """ 00059 from optparse import OptionParser 00060 parser = OptionParser(usage="usage: %prog [options] [packages...]", prog=name) 00061 parser.add_option("-n", "--name",metavar="NAME", 00062 dest="name", default="ROS Package", 00063 help="Name for documentation set") 00064 parser.add_option("-q", "--quiet",action="store_true", default=False, 00065 dest="quiet", 00066 help="Suppress doxygen errors") 00067 parser.add_option("--paths",metavar="PATHS", 00068 dest="paths", default=None, 00069 help="package paths to document") 00070 parser.add_option("--no-rxdeps", action="store_true", 00071 dest="no_rxdeps", default=False, 00072 help="disable rxdeps") 00073 parser.add_option("-o",metavar="OUTPUT_DIRECTORY", 00074 dest="docdir", default='doc', 00075 help="directory to write documentation to") 00076 parser.add_option("--upload",action="store", default=None, 00077 dest="upload", metavar="RSYNC_TARGET", 00078 help="rsync target argument") 00079 return parser 00080 00081 def generate_docs(ctx, quiet=True, no_rxdeps=True): 00082 timings = ctx.timings 00083 artifacts = [] 00084 00085 # Collect all packages that mention rosmake as a builder, and build them first 00086 start = time.time() 00087 to_rosmake = [] 00088 for package in ctx.rd_configs: 00089 if (package in ctx.doc_packages and 00090 ctx.should_document(package) and 00091 ctx.has_builder(package, 'rosmake')): 00092 to_rosmake.append(package) 00093 00094 if to_rosmake and ctx.allow_rosmake: 00095 # command = ['rosmake', '--status-rate=0'] + to_rosmake 00096 command = ['rosmake', '-V'] + to_rosmake 00097 print " ".join(command) 00098 started = time.time() 00099 try: 00100 (stdoutdata, _) = Popen(command, stdout=PIPE).communicate() 00101 print stdoutdata 00102 except: 00103 print "command failed" 00104 print "rosmake took %ds" % (time.time() - started) 00105 timings['rosmake'] = time.time() - start 00106 00107 # Generate Doxygen 00108 # - this can become a plugin once we move rxdeps out of it 00109 start = time.time() 00110 import doxygenator 00111 try: 00112 artifacts.extend(doxygenator.generate_doxygen(ctx, disable_rxdeps=no_rxdeps)) 00113 except Exception, e: 00114 traceback.print_exc() 00115 print >> sys.stderr, "doxygenator completely failed" 00116 doxy_success = [] 00117 timings['doxygen'] = time.time() - start 00118 00119 plugins = [ 00120 ('epydoc', epyenator.generate_epydoc), 00121 ('sphinx', sphinxenator.generate_sphinx), 00122 ('msg', msgenator.generate_msg_docs), 00123 ('landing-page', landing_page.generate_landing_page), 00124 ('doc-index', docindex.generate_doc_index), 00125 ('license-index', licenseindex.generate_license_index), 00126 ] 00127 00128 for plugin_name, plugin in plugins: 00129 start = time.time() 00130 try: 00131 artifacts.extend(plugin(ctx)) 00132 except Exception, e: 00133 traceback.print_exc() 00134 print >> sys.stderr, "plugin [%s] failed"%(plugin_name) 00135 timings[plugin_name] = time.time() - start 00136 00137 # support files 00138 # TODO: convert to plugin 00139 start = time.time() 00140 import shutil 00141 for f in ['styles.css', 'msg-styles.css']: 00142 styles_in = os.path.join(ctx.template_dir, f) 00143 styles_css = os.path.join(ctx.docdir, f) 00144 print "copying",styles_in, "to", styles_css 00145 shutil.copyfile(styles_in, styles_css) 00146 artifacts.append(styles_css) 00147 timings['support_files'] = time.time() - start 00148 00149 return list(set(artifacts)) 00150 00151 00152 def main(): 00153 parser = get_optparse(NAME) 00154 options, package_filters = parser.parse_args() 00155 00156 # Load the ROS environment 00157 ctx = RosdocContext(options.name, options.docdir, 00158 package_filters=package_filters, path_filters=options.paths) 00159 ctx.quiet = options.quiet 00160 try: 00161 ctx.init() 00162 00163 artifacts = generate_docs(ctx) 00164 00165 start = time.time() 00166 if options.upload: 00167 upload.upload(ctx, artifacts, options.upload) 00168 ctx.timings['upload'] = time.time() - start 00169 00170 print "Timings" 00171 for k, v in ctx.timings.iteritems(): 00172 print " * %.2f %s"%(v, k) 00173 00174 except: 00175 traceback.print_exc() 00176 sys.exit(1)