blob: cca0aac8e55474e7b0e940498f2925fe243f04b1 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# Run this script to generate documentation for a directory and serve
# the results to localhost for viewing in the browser.
import optparse
import os
from os.path import join, dirname, abspath, exists
import platform
import subprocess
import sys
sys.path.append(abspath(join(dirname(__file__), '../../../tools')))
import utils
DIRECTORY = abspath(dirname(__file__))
DART_DIR = dirname(dirname(dirname(DIRECTORY)))
DART_EXECUTABLE = join(DART_DIR,
'%s/%s/dart-sdk/bin/dart' % (utils.BUILD_ROOT[utils.GuessOS()],
utils.GetBuildConf('release', utils.GuessArchitecture())))
PUB = join(DART_DIR, 'sdk/bin/pub')
DART2JS = join(DART_DIR, 'sdk/bin/dart2js')
PACKAGE_ROOT = join(dirname(dirname(dirname(DART_EXECUTABLE[:-(len('dart'))]))),
'packages/')
EXCLUDED_PACKAGES = ['browser', 'html_import', 'mutation_observer',
'pkg.xcodeproj', 'shadow_dom']
APPSERVER_EXECUTABLE = 'dev_appserver.py'
def SetPackageRoot(path):
global PACKAGE_ROOT
if exists(path):
PACKAGE_ROOT = abspath(path)
def ParseArgs():
parser = optparse.OptionParser(description='Generate documentation and '
'display the resulting documentation in the browser.')
parser.add_option('--full-docs-only', '-d', dest='just_docs',
action='store_true', default=False,
help='Only generate documentation, no html output. (If no other '
'options are specified, will document the SDK and all packages in the '
'repository.)')
parser.add_option('--package-root', '-p', dest='pkg_root',
help='The package root for dart (default is in the build directory).',
action='store', default=PACKAGE_ROOT)
parser.add_option('--docgen-options', '-o',
dest='docgen_options', help='Options to pass to docgen. If no file to '
'document is specified, by default we generate all documenation for the '
'SDK and all packages in the dart repository in JSON.',
default='--json')
parser.add_option('--gae-sdk',
help='The path to the Google App Engine SDK. Defaults to finding the '
'script in the PATH.', default='')
options, _ = parser.parse_args()
SetPackageRoot(options.pkg_root)
return options
def AddUserDocgenOptions(sdk_cmd, docgen_options, all_docs=False):
'''Expand the command with user specified docgen options.'''
specified_pkg = False
remove_append = False
append = '--append'
for option in docgen_options:
if '--package-root' in option:
specified_pkg = True
if option == append and all_docs:
remove_append = True
if remove_append:
docgen_options.remove(append)
if not specified_pkg:
sdk_cmd.extend(['--package-root=%s' % PACKAGE_ROOT])
sdk_cmd.extend(docgen_options)
return sdk_cmd
def GenerateAllDocs(docgen_options):
'''Generate all documentation for the SDK and all packages in the repository.
We first attempt to run the quickest path to generate all docs, but if that
fails, we fall back on a slower option.'''
# TODO(alanknight): The --append option doesn't work properly. It overwrites
# existing files with new information. Known symptom is that it loses subclasses
# from the SDK and includes only the ones from pkg. So right now our only option
# is to do everything in one pass.
doc_dir = join(DART_DIR, 'pkg')
cmd_lst = [DART_EXECUTABLE,
'--package-root=%s' % PACKAGE_ROOT, 'docgen.dart', '--include-sdk' ]
cmd_str = ' '.join(AddUserDocgenOptions(cmd_lst, docgen_options, True))
# Try to run all pkg docs together at once as it's fastest.
(return_code, _) = ExecuteCommandString('%s %s' % (cmd_str, doc_dir))
if return_code != 0:
# We failed to run all the pkg docs, so try to generate docs for each pkg
# individually.
failed_pkgs = []
for directory in os.listdir(join(DART_DIR, 'pkg')):
doc_dir = join(DART_DIR, 'pkg', directory)
if (directory not in EXCLUDED_PACKAGES and
os.path.isdir(doc_dir)):
(return_code, output) = ExecuteCommandString('%s %s' % (cmd_str,
doc_dir))
if return_code != 0:
failed_pkgs += [directory]
print ('Generated documentation, but failed to generate documentation for '
'the following packages, please investigate: %r' % failed_pkgs)
def ExecuteCommandString(cmd):
'''A variant of the ExecuteCommand function that specifically executes a
particular command string in the shell context. When you execute a string, you
must execute in the shell.'''
print 'Executing: %s ' % cmd
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
shell=True)
output = pipe.communicate()
return (pipe.returncode, output)
def main():
options = ParseArgs()
generate_all_docs = True
docgen_options = []
if options.docgen_options:
# If the user specified particular files to generate docs for, then don't
# generate docs for everything.
docgen_options = options.docgen_options.split()
last_option = docgen_options[-1]
if '=' not in last_option and exists(last_option):
generate_all_docs = False
docgen = [DART_EXECUTABLE, '--checked',
'--package-root=' + PACKAGE_ROOT, join(DIRECTORY, 'docgen.dart')]
docgen.extend(options.options.split())
utils.ExecuteCommand(docgen)
if generate_all_docs:
GenerateAllDocs(docgen_options)
if not options.just_docs:
cwd = os.getcwd()
try:
utils.ExecuteCommand(['git', 'clone', '-b', 'master',
'git://github.com/dart-lang/dartdoc-viewer.git'])
utils.ExecuteCommand(['mv', 'docs', 'dartdoc-viewer/client/local'])
os.chdir('dartdoc-viewer/client/')
subprocess.call([PUB, 'install'])
subprocess.call([DART_EXECUTABLE, 'deploy.dart'])
if options.gae_sdk == '':
server = subprocess.Popen(' '.join([APPSERVER_EXECUTABLE, '..']),
shell=True)
else:
path_to_gae = options.gae_sdk
if not path_to_gae.endswith(APPSERVER_EXECUTABLE):
path_to_gae = join(path_to_gae, APPSERVER_EXECUTABLE)
server = subprocess.Popen(join(['python', path_to_gae, '..']))
print (
"\nPoint your browser to the address of the 'default' server below.")
raw_input("Press <RETURN> to terminate the server.\n\n")
server.terminate()
finally:
os.chdir(cwd)
subprocess.call(['rm', '-rf', 'dartdoc-viewer'])
if __name__ == '__main__':
main()