Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:io'; | 5 import 'dart:io'; |
| 6 | 6 |
| 7 import 'package:args/args.dart'; | 7 import 'package:args/args.dart'; |
| 8 import 'package:logging/logging.dart'; | 8 import 'package:logging/logging.dart'; |
| 9 | 9 |
| 10 import '../lib/docgen.dart'; | 10 import '../lib/docgen.dart'; |
| 11 import 'package:path/path.dart' as path; | 11 import 'package:path/path.dart' as path; |
| 12 | 12 |
| 13 List<String> excludedLibraries = []; | 13 List<String> excludedLibraries = []; |
| 14 | 14 |
| 15 /** | 15 /** |
| 16 * If we look like we're asking to document a single package without | |
| 17 * any other options being set, do the sensible thing. | |
| 18 */ | |
| 19 bool _useSinglePackageDefaults = false; | |
| 20 | |
| 21 /** | |
| 22 * If we've specified just a package and no other command-line options, | |
| 23 * use the single package name as the start page. | |
| 24 */ | |
| 25 String get _defaultStartPage { | |
|
Emily Fortuna
2014/02/11 22:35:32
nit: I'd put this function down below the main, so
| |
| 26 if (_useSinglePackageDefaults) { | |
| 27 var pubspec = new File(path.join(_files.first, 'pubspec.yaml')); | |
| 28 if (!pubspec.existsSync()) return null; | |
| 29 return Library.packageNameFor(_files.first); | |
| 30 } else { | |
| 31 return null; | |
| 32 } | |
| 33 } | |
| 34 | |
| 35 /** | |
| 36 * The files/directories that we're being asked to document. | |
| 37 */ | |
| 38 List<String> _files; | |
| 39 | |
| 40 /** | |
| 16 * Analyzes Dart files and generates a representation of included libraries, | 41 * Analyzes Dart files and generates a representation of included libraries, |
| 17 * classes, and members. | 42 * classes, and members. |
| 18 */ | 43 */ |
| 19 void main(List<String> arguments) { | 44 void main(List<String> arguments) { |
| 20 var results = _initArgParser().parse(arguments); | 45 var options = _initArgParser().parse(arguments); |
| 46 _files = options.rest.map(path.normalize).toList(); | |
| 47 if (_files.isEmpty) _printHelpAndExit(); | |
| 48 _useSinglePackageDefaults = _singlePackageNoOptions(options, | |
| 49 _initArgParser(), _files); | |
| 50 // If we've changed the options based on it being a single package, | |
| 51 // re-parse the arguments so we get different defaults. Ugh. | |
| 52 options = _initArgParser().parse(arguments); | |
|
Emily Fortuna
2014/02/11 22:35:32
I think you're missing some logic here. (or I'm m
| |
| 53 var includeSdk = options['parse-sdk'] || options['include-sdk']; | |
| 54 var scriptDir = path.dirname(Platform.script.toFilePath()); | |
| 55 var introduction = includeSdk ? '' : options['introduction']; | |
| 21 | 56 |
| 22 var includeSdk = results['parse-sdk'] || results['include-sdk']; | 57 docgen(_files, |
| 23 var scriptDir = path.dirname(Platform.script.toFilePath()); | 58 packageRoot: options['package-root'], |
| 24 var introduction = includeSdk ? '' : results['introduction']; | 59 outputToYaml: !options['json'], |
| 25 var files = results.rest.map(path.normalize).toList(); | 60 includePrivate: options['include-private'], |
| 26 if (files.isEmpty) _printHelpAndExit(); | |
| 27 docgen(files, | |
| 28 packageRoot: results['package-root'], | |
| 29 outputToYaml: !results['json'], | |
| 30 includePrivate: results['include-private'], | |
| 31 includeSdk: includeSdk, | 61 includeSdk: includeSdk, |
| 32 parseSdk: results['parse-sdk'], | 62 parseSdk: options['parse-sdk'], |
| 33 append: results['append'] && new Directory(results['out']).existsSync(), | 63 append: options['append'] && new Directory(options['out']).existsSync(), |
| 34 introFileName: introduction, | 64 introFileName: introduction, |
| 35 out: results['out'], | 65 out: options['out'], |
| 36 excludeLibraries: excludedLibraries, | 66 excludeLibraries: excludedLibraries, |
| 37 includeDependentPackages: results['include-dependent-packages'], | 67 includeDependentPackages: options['include-dependent-packages'], |
| 38 serve: results['serve'], | 68 serve: options['serve'], |
| 39 noDocs: results['no-docs'], | 69 noDocs: options['no-docs'], |
| 40 startPage: results['startPage']); | 70 startPage: options['start-page']); |
| 41 } | 71 } |
| 42 | 72 |
| 43 /** | 73 /** |
| 44 * Print help if we are passed the help option or invalid arguments. | 74 * Print help if we are passed the help option or invalid arguments. |
| 45 */ | 75 */ |
| 46 void _printHelpAndExit() { | 76 void _printHelpAndExit() { |
| 47 print(_initArgParser().getUsage()); | 77 print(_initArgParser().getUsage()); |
| 48 print('Usage: dart docgen.dart [OPTIONS] fooDir/barFile'); | 78 print('Usage: dart docgen.dart [OPTIONS] fooDir/barFile'); |
| 49 exit(0); | 79 exit(0); |
| 50 } | 80 } |
| 51 | 81 |
| 52 /** | 82 /** |
| 83 * If the user provided no arguments and | |
| 84 * seems to have given us a single package to document, use some | |
| 85 * reasonable arguments for what they probably meant. | |
| 86 */ | |
| 87 bool _singlePackageNoOptions(ArgResults options, ArgParser parser, List files) { | |
| 88 if (!_allOptionsAreDefaults(options, parser)) return false; | |
| 89 if (files.length != 1) return false; | |
| 90 var pubspec = new File(path.join(files.first, 'pubspec.yaml')); | |
| 91 if (!pubspec.existsSync()) return false; | |
| 92 var packageName = Library.packageNameFor(files.first); | |
| 93 print("Using default options for documenting a single package: " | |
| 94 "--start-page=$packageName"); | |
| 95 return true; | |
| 96 } | |
| 97 | |
| 98 /** | |
| 99 * Return true if all the options are at their default value. It would | |
| 100 * be nice if there was a simpler way to test this but ArgResult is | |
| 101 * very opaque. | |
| 102 */ | |
| 103 bool _allOptionsAreDefaults(ArgResults options, ArgParser parser) { | |
| 104 for (var optionName in options.options) { | |
| 105 var defaultValue = parser.getDefault(optionName); | |
| 106 var actualValue = options[optionName]; | |
| 107 var matchAnyway = defaultValue == null && | |
| 108 actualValue is List && actualValue.isEmpty; | |
| 109 if (actualValue != null && actualValue != defaultValue && !matchAnyway) { | |
| 110 return false; | |
| 111 } | |
| 112 } | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 /** | |
| 53 * Creates parser for docgen command line arguments. | 117 * Creates parser for docgen command line arguments. |
| 54 */ | 118 */ |
| 55 ArgParser _initArgParser() { | 119 ArgParser _initArgParser() { |
| 56 var parser = new ArgParser(); | 120 var parser = new ArgParser(); |
| 57 parser.addFlag('help', abbr: 'h', | 121 parser.addFlag('help', abbr: 'h', |
| 58 help: 'Prints help and usage information.', | 122 help: 'Prints help and usage information.', |
| 59 negatable: false, | 123 negatable: false, |
| 60 callback: (help) { | 124 callback: (help) { |
| 61 if (help) _printHelpAndExit(); | 125 if (help) _printHelpAndExit(); |
| 62 }); | 126 }); |
| 63 parser.addFlag('verbose', abbr: 'v', | 127 parser.addFlag('verbose', abbr: 'v', |
| 64 help: 'Output more logging information.', negatable: false, | 128 help: 'Output more logging information.', negatable: false, |
| 65 callback: (verbose) { | 129 callback: (verbose) { |
| 66 if (verbose) Logger.root.level = Level.FINEST; | 130 if (verbose) Logger.root.level = Level.FINEST; |
| 67 }); | 131 }); |
| 68 parser.addFlag('json', abbr: 'j', | 132 parser.addFlag('json', abbr: 'j', |
| 69 help: 'Outputs to JSON. Files are outputted to YAML by default. ' | 133 help: 'Outputs to JSON. Files are outputted to YAML by default. ' |
| 70 'If --append is used, it takes the file-format of the previous ' | 134 'If --append is used, it takes the file-format of the previous ' |
| 71 'run stated in library_list.json ignoring the flag.', | 135 'run stated in library_list.json ignoring the flag.', |
| 72 negatable: true); | 136 negatable: true, defaultsTo: true); |
| 73 parser.addFlag('include-private', | 137 parser.addFlag('include-private', |
| 74 help: 'Flag to include private declarations.', negatable: false); | 138 help: 'Flag to include private declarations.', negatable: false); |
| 75 parser.addFlag('include-sdk', | 139 parser.addFlag('include-sdk', |
| 76 help: 'Flag to parse SDK Library files.', negatable: false); | 140 help: 'Flag to parse SDK Library files.', |
| 141 defaultsTo: true, | |
| 142 negatable: true); | |
| 77 parser.addFlag('parse-sdk', | 143 parser.addFlag('parse-sdk', |
| 78 help: 'Parses the SDK libraries only.', | 144 help: 'Parses the SDK libraries only.', |
| 79 defaultsTo: false, negatable: false); | 145 defaultsTo: false, negatable: false); |
| 80 parser.addOption('package-root', | 146 parser.addOption('package-root', |
| 81 help: 'Sets the package root of the library being analyzed.'); | 147 help: 'Sets the package root of the library being analyzed.'); |
| 82 parser.addFlag('append', | 148 parser.addFlag('append', |
| 83 help: 'Append to the docs folder, library_list.json and index.txt', | 149 help: 'Append to the docs folder, library_list.json and index.txt', |
| 84 defaultsTo: false, negatable: false); | 150 defaultsTo: false, negatable: false); |
| 85 parser.addFlag('serve', help: 'Clone the documentation viewer repo locally ' | 151 parser.addFlag('serve', help: 'Clone the documentation viewer repo locally ' |
| 86 '(if not already present) and start a simple server', defaultsTo: false, | 152 '(if not already present) and start a simple server', defaultsTo: false, |
| 87 negatable: false); | 153 negatable: false); |
| 88 parser.addFlag('no-docs', help: 'Do not generate any new documentation', | 154 parser.addFlag('no-docs', help: 'Do not generate any new documentation', |
| 89 defaultsTo: false, negatable: false); | 155 defaultsTo: false, negatable: false); |
| 90 parser.addOption('introduction', | 156 parser.addOption('introduction', |
| 91 help: 'Adds the provided markdown text file as the introduction' | 157 help: 'Adds the provided markdown text file as the introduction' |
| 92 ' for the generated documentation.', defaultsTo: ''); | 158 ' for the generated documentation.', defaultsTo: ''); |
| 93 parser.addOption('out', | 159 parser.addOption('out', |
| 94 help: 'The name of the output directory.', | 160 help: 'The name of the output directory.', |
| 95 defaultsTo: 'docs'); | 161 defaultsTo: 'docs'); |
| 96 parser.addOption('exclude-lib', | 162 parser.addOption('exclude-lib', |
| 97 help: 'Exclude the library by this name from the documentation', | 163 help: 'Exclude the library by this name from the documentation', |
| 98 allowMultiple: true, | 164 allowMultiple: true, |
| 99 callback: (libs) => excludedLibraries.addAll(libs)); | 165 callback: (libs) => excludedLibraries.addAll(libs)); |
| 100 parser.addFlag('include-dependent-packages', | 166 parser.addFlag('include-dependent-packages', |
| 101 help: 'Assumes we are documenting a single package and are running ' | 167 help: 'Assumes we are documenting a single package and are running ' |
| 102 'in the directory with its pubspec. Includes documentation for all ' | 168 'in the directory with its pubspec. Includes documentation for all ' |
| 103 'of its dependent packages.', | 169 'of its dependent packages.', |
| 104 defaultsTo: false, negatable: false); | 170 defaultsTo: true, negatable: true); |
| 105 parser.addOption('startPage', | 171 parser.addOption('start-page', |
| 106 help: 'By default the viewer will start at the SDK introduction page.' | 172 help: 'By default the viewer will start at the SDK introduction page.' |
| 107 'To start at some other page, e.g. for a package, provide the name ' | 173 'To start at some other page, e.g. for a package, provide the name ' |
| 108 'of the package in this argument, e.g. --startPage=intl will make ' | 174 'of the package in this argument, e.g. --start-page=intl will make ' |
| 109 'the start page of the viewer be the intl package.', | 175 'the start page of the viewer be the intl package.', |
| 110 defaultsTo: null); | 176 defaultsTo: _defaultStartPage); |
| 111 | 177 |
| 112 return parser; | 178 return parser; |
| 113 } | 179 } |
| OLD | NEW |