diff --git a/bin/dartdoc.dart b/bin/dartdoc.dart index 5187c04d0c..b8d06d555f 100644 --- a/bin/dartdoc.dart +++ b/bin/dartdoc.dart @@ -52,14 +52,15 @@ main(List arguments) async { final bool sdkDocs = args['sdk-docs']; final bool showProgress = args['show-progress']; - final String readme = args['sdk-readme']; - if (readme != null && !(new File(readme).existsSync())) { - stderr.writeln( - " fatal error: unable to locate the SDK description file at $readme."); - exit(1); + Directory inputDir; + if (sdkDocs) { + inputDir = sdkDir; + } else if (args['input'] == null) { + inputDir = Directory.current; + } else { + inputDir = args['input']; } - Directory inputDir = new Directory(args['input']); if (!inputDir.existsSync()) { stderr.writeln( " fatal error: unable to locate the input directory at ${inputDir @@ -188,12 +189,12 @@ main(List arguments) async { }); } - PackageMeta packageMeta = sdkDocs - ? new PackageMeta.fromSdk(sdkDir, - sdkReadmePath: readme, - displayAsPackages: - args['use-categories'] || args['display-as-packages']) - : new PackageMeta.fromDir(inputDir); + PackageMeta packageMeta = new PackageMeta.fromDir(inputDir); + + if (packageMeta == null) { + stderr.writeln(' fatal error: Unable to generate documentation: no pubspec.yaml found'); + exit(1); + } if (!packageMeta.isValid) { final String firstError = packageMeta.getInvalidReasons().first; @@ -211,6 +212,7 @@ main(List arguments) async { } } + logInfo("Generating documentation for '${packageMeta}' into " "${outputDir.absolute.path}${Platform.pathSeparator}"); @@ -310,9 +312,9 @@ ArgParser _createArgsParser() { help: 'Display progress indications to console stdout', negatable: false); parser.addOption('sdk-readme', help: - 'Path to the SDK description file; use if generating Dart SDK docs.'); + 'Path to the SDK description file. Deprecated (ignored)'); parser.addOption('input', - help: 'Path to source directory.', defaultsTo: Directory.current.path); + help: 'Path to source directory.'); parser.addOption('output', help: 'Path to output directory.', defaultsTo: defaultOutDir); parser.addMultiOption('header', diff --git a/lib/src/model.dart b/lib/src/model.dart index 33d5ab4496..346238980c 100644 --- a/lib/src/model.dart +++ b/lib/src/model.dart @@ -1710,7 +1710,6 @@ class Library extends ModelElement { List _variables; Namespace _exportedNamespace; String _name; - String _packageName; factory Library(LibraryElement element, PackageGraph packageGraph) { return packageGraph.findOrCreateLibraryFor(element); } @@ -2015,16 +2014,7 @@ class Library extends ModelElement { /// The real package, as opposed to the package we are documenting it with, /// [PackageGraph.name] - String get packageName { - if (_packageName == null) { - if (name.startsWith('dart:')) { - _packageName = 'Dart Core'; - } else { - _packageName = packageMeta?.name ?? ''; - } - } - return _packageName; - } + String get packageName => packageMeta?.name ?? ''; /// The real packageMeta, as opposed to the package we are documenting with. PackageMeta _packageMeta; @@ -2187,16 +2177,7 @@ class Library extends ModelElement { static PackageMeta getPackageMeta(LibraryElement element) { String sourcePath = element.source.fullName; - File file = new File(pathLib.canonicalize(sourcePath)); - Directory dir = file.parent; - while (dir.parent.path != dir.path && dir.existsSync()) { - File pubspec = new File(pathLib.join(dir.path, 'pubspec.yaml')); - if (pubspec.existsSync()) { - return new PackageMeta.fromDir(dir); - } - dir = dir.parent; - } - return null; + return new PackageMeta.fromDir(new File(pathLib.canonicalize(sourcePath)).parent); } static String getLibraryName(LibraryElement element) { @@ -4204,7 +4185,7 @@ class PackageGraph extends Canonicalization with Nameable, Warnable { String get name => packageMeta.name; String get kind => - (packageMeta.displayAsPackages || packageGraph.isSdk) ? '' : 'package'; + (packageGraph.isSdk) ? 'SDK' : 'package'; @override String get oneLineDoc => ''; @@ -4543,14 +4524,14 @@ class Package implements Comparable { /// Returns: /// -1 if this package is listed in --package-order. /// 0 if this package is the original package we are documenting. - /// 1 if this group represents the Dart SDK. - /// 2 if this group has a name that contains the name of the original + /// 1 if this package represents the Dart SDK. + /// 2 if this package has a name that contains the name of the original /// package we are documenting. /// 3 otherwise. int get _group { if (config.packageOrder.contains(name)) return -1; if (name.toLowerCase() == packageGraph.name.toLowerCase()) return 0; - if (name == "Dart Core") return 1; + if (isSdk) return 1; if (name.toLowerCase().contains(packageGraph.name.toLowerCase())) return 2; return 3; } diff --git a/lib/src/package_meta.dart b/lib/src/package_meta.dart index 46e8bd8649..12562e4a6e 100644 --- a/lib/src/package_meta.dart +++ b/lib/src/package_meta.dart @@ -6,22 +6,49 @@ library dartdoc.package_meta; import 'dart:io'; +import 'package:dartdoc/src/sdk.dart'; import 'package:path/path.dart' as pathLib; import 'package:yaml/yaml.dart'; import 'logging.dart'; + +Map _packageMetaCache = {}; + abstract class PackageMeta { final Directory dir; - final bool displayAsPackages; - - PackageMeta(this.dir, {this.displayAsPackages: false}); - factory PackageMeta.fromDir(Directory dir) => new _FilePackageMeta(dir); - factory PackageMeta.fromSdk(Directory sdkDir, - {String sdkReadmePath, bool displayAsPackages}) => - new _SdkMeta(sdkDir, - sdkReadmePath: sdkReadmePath, displayAsPackages: displayAsPackages); + PackageMeta(this.dir); + + /// This factory is guaranteed to return the same object for any given + /// [dir.absolute.path]. Multiple [dir.absolute.path]s will resolve to the + /// same object if they are part of the same package. Returns null + /// if the directory is not part of a known package. + factory PackageMeta.fromDir(Directory dir) { + Directory original = dir.absolute; + dir = original; + if (!_packageMetaCache.containsKey(dir.path)) { + PackageMeta packageMeta; + // There are pubspec.yaml files inside the SDK. Ignore them. + if (pathLib.isWithin(getSdkDir().absolute.path, dir.path) || getSdkDir().path == dir.path) { + packageMeta = new _SdkMeta(getSdkDir()); + } else { + while (dir.existsSync()) { + File pubspec = new File(pathLib.join(dir.path, 'pubspec.yaml')); + if (pubspec.existsSync()) { + packageMeta = new _FilePackageMeta(dir); + break; + } + // Allow a package to be at root (possible in a Windows setting with + // drive letter mappings). + if (dir.path == dir.parent.absolute.path) break; + dir = dir.parent.absolute; + } + } + _packageMetaCache[dir.absolute.path] = packageMeta; + } + return _packageMetaCache[dir.absolute.path]; + } bool get isSdk; bool get needsPubGet => false; @@ -46,7 +73,7 @@ abstract class PackageMeta { FileContents getChangelogContents(); /// Returns true if we are a valid package, valid enough to generate docs. - bool get isValid; + bool get isValid => getInvalidReasons().isEmpty; /// Returns a list of reasons this package is invalid, or an /// empty list if no reasons found. @@ -151,8 +178,6 @@ class _FilePackageMeta extends PackageMeta { return _changelog; } - @override - bool get isValid => getInvalidReasons().isEmpty; /// Returns a list of reasons this package is invalid, or an /// empty list if no reasons found. @@ -184,10 +209,12 @@ File _locate(Directory dir, List fileNames) { } class _SdkMeta extends PackageMeta { - final String sdkReadmePath; + String sdkReadmePath; - _SdkMeta(Directory dir, {this.sdkReadmePath, bool displayAsPackages}) - : super(dir, displayAsPackages: displayAsPackages); + _SdkMeta(Directory dir) + : super(dir) { + sdkReadmePath = pathLib.join(dir.path, 'lib', 'api_readme.md'); + } @override bool get isSdk => true; @@ -198,7 +225,7 @@ class _SdkMeta extends PackageMeta { } @override - String get name => 'Dart SDK'; + String get name => 'Dart'; @override String get version => new File(pathLib.join(dir.path, 'version')).readAsStringSync().trim(); @@ -211,15 +238,10 @@ class _SdkMeta extends PackageMeta { @override FileContents getReadmeContents() { - File f = sdkReadmePath != null - ? new File(sdkReadmePath) - : new File(pathLib.join(dir.path, 'lib', 'api_readme.md')); + File f = new File(pathLib.join(dir.path, 'lib', 'api_readme.md')); return f.existsSync() ? new FileContents(f) : null; } - @override - bool get isValid => true; - @override List getInvalidReasons() => []; diff --git a/lib/templates/index.html b/lib/templates/index.html index 56066b3f55..0b7ec93e85 100644 --- a/lib/templates/index.html +++ b/lib/templates/index.html @@ -1,7 +1,7 @@ {{>head}}