Skip to content

Commit c10cd71

Browse files
authored
Refactor DartDocConfig object usage, part 2 (#1662)
* refactors * Library/Package/PackageGraph constructor shuffle * Not quite there; still need to populate non-local packages * weird vm thing * Got it? * Add another test * tweaks for Flutter * Initialization speedups * Canonicalize path comparisons and increase timeouts on the complex dartdoc tests for travis * Update grind with different parameters * First step complete, now to eliminate dupes * Condense more into config * remove commented out line * Everything but the generator information is moved now. * dartfmt * Restore a commented out test * Use localPublicLibraries in restored test * Move generator into DartDoc pseudo-factory * dartfmt + review comments * dartfmt * Throw correct exception * new is not optional yet
1 parent 9c24147 commit c10cd71

File tree

7 files changed

+138
-79
lines changed

7 files changed

+138
-79
lines changed

bin/dartdoc.dart

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ main(List<String> arguments) async {
4444
}
4545

4646
Directory sdkDir = getSdkDir();
47-
if (sdkDir == null) {
48-
stderr.writeln(" Error: unable to locate the Dart SDK.");
49-
exit(1);
50-
}
51-
5247
final bool sdkDocs = args['sdk-docs'];
5348
final bool showProgress = args['show-progress'];
5449

@@ -61,52 +56,14 @@ main(List<String> arguments) async {
6156
inputDir = args['input'];
6257
}
6358

64-
if (!inputDir.existsSync()) {
65-
stderr.writeln(
66-
" fatal error: unable to locate the input directory at ${inputDir
67-
.path}.");
68-
exit(1);
69-
}
70-
71-
String url = args['hosted-url'];
72-
73-
List<String> headerFilePaths =
74-
args['header'].map(_resolveTildePath).toList() as List<String>;
75-
for (String headerFilePath in headerFilePaths) {
76-
if (!new File(headerFilePath).existsSync()) {
77-
stderr.writeln(
78-
" fatal error: unable to locate header file: ${headerFilePath}.");
79-
exit(1);
80-
}
81-
}
82-
83-
List<String> footerFilePaths =
84-
args['footer'].map(_resolveTildePath).toList() as List<String>;
85-
for (String footerFilePath in footerFilePaths) {
86-
if (!new File(footerFilePath).existsSync()) {
87-
stderr.writeln(
88-
" fatal error: unable to locate footer file: ${footerFilePath}.");
89-
exit(1);
90-
}
91-
}
92-
93-
List<String> footerTextFilePaths =
94-
args['footer-text'].map(_resolveTildePath).toList() as List<String>;
95-
59+
List<String> footerTextFilePaths = [];
9660
// If we're generating docs for the Dart SDK, we insert a copyright footer.
9761
if (sdkDocs) {
9862
Uri footerCopyrightUri = await Isolate.resolvePackageUri(
9963
Uri.parse('package:dartdoc/resources/sdk_footer_text.html'));
10064
footerTextFilePaths = [footerCopyrightUri.toFilePath()];
10165
}
102-
103-
for (String footerFilePath in footerTextFilePaths) {
104-
if (!new File(footerFilePath).existsSync()) {
105-
stderr.writeln(
106-
" fatal error: unable to locate footer-text file: ${footerFilePath}.");
107-
exit(1);
108-
}
109-
}
66+
footerTextFilePaths.addAll(args['footer-text']);
11067

11168
Directory outputDir =
11269
new Directory(pathLib.join(Directory.current.path, defaultOutDir));
@@ -212,17 +169,6 @@ main(List<String> arguments) async {
212169
logInfo("Generating documentation for '${packageMeta}' into "
213170
"${outputDir.absolute.path}${Platform.pathSeparator}");
214171

215-
var generators = await initGenerators(url, args['rel-canonical-prefix'],
216-
headerFilePaths: headerFilePaths,
217-
footerFilePaths: footerFilePaths,
218-
footerTextFilePaths: footerTextFilePaths,
219-
faviconPath: args['favicon'],
220-
prettyIndexJson: args['pretty-index-json']);
221-
222-
for (var generator in generators) {
223-
generator.onFileCreated.listen(logProgress);
224-
}
225-
226172
DartSdk sdk = new FolderBasedDartSdk(PhysicalResourceProvider.INSTANCE,
227173
PhysicalResourceProvider.INSTANCE.getFolder(sdkDir.path));
228174

@@ -255,23 +201,31 @@ main(List<String> arguments) async {
255201
examplePathPrefix: args['example-path-prefix'],
256202
excludeLibraries: args['exclude'],
257203
excludePackages: args['exclude-packages'],
204+
faviconPath: args['favicon'],
205+
footerFilePaths: args['footer'],
206+
footerTextFilePaths: footerTextFilePaths,
207+
headerFilePaths: args['header'],
208+
hostedUrl: args['hosted-url'],
258209
includeExternals: args['include-external'],
259210
includeLibraries: args['include'],
260211
includeSource: args['include-source'],
261212
inputDir: inputDir,
262213
packageOrder: args['package-order'].isEmpty
263214
? args['category-order']
264215
: args['package-order'],
216+
prettyIndexJson: args['pretty-index-json'],
265217
reexportMinConfidence:
266218
double.parse(args['ambiguous-reexport-scorer-min-confidence']),
219+
relCanonicalPrefix: args['rel-canonical-prefix'],
267220
sdkDir: sdkDir,
268221
sdkVersion: sdk.sdkVersion,
269222
showWarnings: args['show-warnings'],
270223
validateLinks: args['validate-links'],
271224
verboseWarnings: args['verbose-warnings'],
272225
);
273226

274-
DartDoc dartdoc = new DartDoc(config, generators, outputDir, packageMeta);
227+
DartDoc dartdoc =
228+
await DartDoc.withDefaultGenerators(config, outputDir, packageMeta);
275229

276230
dartdoc.onCheckProgress.listen(logProgress);
277231
await Chain.capture(() async {

lib/dartdoc.dart

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const String version = '0.18.1';
4141
final String defaultOutDir = pathLib.join('doc', 'api');
4242

4343
/// Initialize and setup the generators.
44-
Future<List<Generator>> initGenerators(String url, String relCanonicalPrefix,
44+
Future<List<Generator>> _initGenerators(String url, String relCanonicalPrefix,
4545
{List<String> headerFilePaths,
4646
List<String> footerFilePaths,
4747
List<String> footerTextFilePaths,
@@ -75,10 +75,32 @@ class DartDoc extends PackageBuilder {
7575
final StreamController<String> _onCheckProgress =
7676
new StreamController(sync: true);
7777

78-
DartDoc(DartDocConfig config, this.generators, this.outputDir,
78+
DartDoc._(DartDocConfig config, this.generators, this.outputDir,
7979
PackageMeta packageMeta)
8080
: super(config, packageMeta);
8181

82+
/// An asynchronous factory method that builds Dartdoc's file writers
83+
/// and returns a DartDoc object with them.
84+
static withDefaultGenerators(DartDocConfig config, Directory outputDir,
85+
PackageMeta packageMeta) async {
86+
var generators = await _initGenerators(
87+
config.hostedUrl, config.relCanonicalPrefix,
88+
headerFilePaths: config.headerFilePaths,
89+
footerFilePaths: config.footerFilePaths,
90+
footerTextFilePaths: config.footerTextFilePaths,
91+
faviconPath: config.faviconPath,
92+
prettyIndexJson: config.prettyIndexJson);
93+
for (var generator in generators) {
94+
generator.onFileCreated.listen(logProgress);
95+
}
96+
return new DartDoc._(config, generators, outputDir, packageMeta);
97+
}
98+
99+
factory DartDoc.withoutGenerators(
100+
DartDocConfig config, Directory outputDir, PackageMeta packageMeta) {
101+
return new DartDoc._(config, [], outputDir, packageMeta);
102+
}
103+
82104
Stream<String> get onCheckProgress => _onCheckProgress.stream;
83105

84106
@override
@@ -146,14 +168,17 @@ class DartDoc extends PackageBuilder {
146168
"in ${seconds.toStringAsFixed(1)} seconds");
147169
_stopwatch.reset();
148170

149-
// Create the out directory.
150-
if (!outputDir.existsSync()) outputDir.createSync(recursive: true);
171+
if (generators.isNotEmpty) {
172+
// Create the out directory.
173+
if (!outputDir.existsSync()) outputDir.createSync(recursive: true);
151174

152-
for (var generator in generators) {
153-
await generator.generate(packageGraph, outputDir.path);
154-
writtenFiles.addAll(generator.writtenFiles.map(pathLib.normalize));
175+
for (var generator in generators) {
176+
await generator.generate(packageGraph, outputDir.path);
177+
writtenFiles.addAll(generator.writtenFiles.map(pathLib.normalize));
178+
}
179+
if (config.validateLinks) validateLinks(packageGraph, outputDir.path);
155180
}
156-
if (config.validateLinks) validateLinks(packageGraph, outputDir.path);
181+
157182
int warnings = packageGraph.packageWarningCounter.warningCount;
158183
int errors = packageGraph.packageWarningCounter.errorCount;
159184
if (warnings == 0 && errors == 0) {

lib/src/config.dart

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,26 @@ import 'dart:io';
88

99
import 'package:analyzer/dart/element/element.dart';
1010
import 'package:dartdoc/dartdoc.dart';
11+
import 'package:path/path.dart' as pathLib;
1112

1213
import 'model.dart';
1314

15+
String _resolveTildePath(String originalPath) {
16+
if (originalPath == null || !originalPath.startsWith('~/')) {
17+
return originalPath;
18+
}
19+
20+
String homeDir;
21+
22+
if (Platform.isWindows) {
23+
homeDir = pathLib.absolute(Platform.environment['USERPROFILE']);
24+
} else {
25+
homeDir = pathLib.absolute(Platform.environment['HOME']);
26+
}
27+
28+
return pathLib.join(homeDir, originalPath.substring(2));
29+
}
30+
1431
/// Class representing values possibly local to a particular [ModelElement].
1532
class LocalConfig {
1633
final Map<String, Set<String>> categoryMap;
@@ -30,12 +47,19 @@ class DartDocConfig {
3047
final List<String> excludeLibraries;
3148
final List<String> excludePackages;
3249
final String examplePathPrefix;
50+
List<String> footerFilePaths;
51+
List<String> footerTextFilePaths;
52+
List<String> headerFilePaths;
53+
final String faviconPath;
3354
final List<String> includeExternals;
3455
final List<String> includeLibraries;
56+
final String hostedUrl;
3557
final bool includeSource;
3658
final Directory inputDir;
3759
final List<String> packageOrder;
60+
final bool prettyIndexJson;
3861
final double reexportMinConfidence;
62+
final String relCanonicalPrefix;
3963
final Directory sdkDir;
4064
final String sdkVersion;
4165
final bool showWarnings;
@@ -48,18 +72,54 @@ class DartDocConfig {
4872
this.examplePathPrefix,
4973
this.excludeLibraries,
5074
this.excludePackages,
75+
this.faviconPath,
76+
this.footerFilePaths,
77+
this.footerTextFilePaths,
78+
this.headerFilePaths,
79+
this.hostedUrl,
5180
this.includeExternals,
5281
this.includeLibraries,
5382
this.includeSource,
5483
this.inputDir,
5584
this.packageOrder,
85+
this.prettyIndexJson,
5686
this.reexportMinConfidence,
87+
this.relCanonicalPrefix,
5788
this.sdkDir,
5889
this.sdkVersion,
5990
this.showWarnings,
6091
this.validateLinks,
6192
this.verboseWarnings,
62-
);
93+
) {
94+
if (sdkDir == null || !sdkDir.existsSync()) {
95+
throw new DartDocFailure("Error: unable to locate the Dart SDK.");
96+
}
97+
98+
footerFilePaths = footerFilePaths.map((p) => _resolveTildePath(p)).toList();
99+
for (String footerFilePath in footerFilePaths) {
100+
if (!new File(footerFilePath).existsSync()) {
101+
throw new DartDocFailure(
102+
"fatal error: unable to locate footer file: ${footerFilePath}.");
103+
}
104+
}
105+
106+
footerTextFilePaths =
107+
footerTextFilePaths.map((p) => _resolveTildePath(p)).toList();
108+
for (String footerTextFilePath in footerTextFilePaths) {
109+
if (!new File(footerTextFilePath).existsSync()) {
110+
throw new DartDocFailure(
111+
"fatal error: unable to locate footer-text file: ${footerTextFilePath}.");
112+
}
113+
}
114+
115+
headerFilePaths = headerFilePaths.map((p) => _resolveTildePath(p)).toList();
116+
for (String headerFilePath in headerFilePaths) {
117+
if (!new File(headerFilePath).existsSync()) {
118+
throw new DartDocFailure(
119+
"fatal error: unable to locate header file: ${headerFilePath}.");
120+
}
121+
}
122+
}
63123

64124
factory DartDocConfig.fromParameters({
65125
bool addCrossdart: false,
@@ -68,12 +128,19 @@ class DartDocConfig {
68128
String examplePathPrefix,
69129
List<String> excludeLibraries,
70130
List<String> excludePackages,
131+
String faviconPath,
132+
List<String> footerFilePaths,
133+
List<String> footerTextFilePaths,
134+
List<String> headerFilePaths,
135+
String hostedUrl,
71136
List<String> includeExternals,
72137
List<String> includeLibraries,
73138
bool includeSource: true,
74139
Directory inputDir,
75140
List<String> packageOrder,
141+
bool prettyIndexJson: false,
76142
double reexportMinConfidence: 0.1,
143+
String relCanonicalPrefix,
77144
Directory sdkDir,
78145
String sdkVersion,
79146
bool showWarnings: false,
@@ -87,12 +154,19 @@ class DartDocConfig {
87154
examplePathPrefix,
88155
excludeLibraries ?? const <String>[],
89156
excludePackages ?? const <String>[],
157+
faviconPath,
158+
footerFilePaths ?? const <String>[],
159+
footerTextFilePaths ?? const <String>[],
160+
headerFilePaths ?? const <String>[],
161+
hostedUrl,
90162
includeExternals ?? const <String>[],
91163
includeLibraries ?? const <String>[],
92164
includeSource,
93165
inputDir,
94166
packageOrder ?? const <String>[],
167+
prettyIndexJson,
95168
reexportMinConfidence,
169+
relCanonicalPrefix,
96170
sdkDir ?? getSdkDir(),
97171
sdkVersion,
98172
showWarnings,

lib/src/package_meta.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ library dartdoc.package_meta;
77
import 'dart:io';
88

99
import 'package:analyzer/dart/element/element.dart';
10+
import 'package:dartdoc/dartdoc.dart';
1011
import 'package:dartdoc/src/sdk.dart';
1112
import 'package:path/path.dart' as pathLib;
1213
import 'package:yaml/yaml.dart';
@@ -15,6 +16,10 @@ import 'logging.dart';
1516

1617
Map<String, PackageMeta> _packageMetaCache = {};
1718

19+
class PackageMetaFailure extends DartDocFailure {
20+
PackageMetaFailure(String message) : super(message);
21+
}
22+
1823
abstract class PackageMeta {
1924
final Directory dir;
2025

@@ -49,9 +54,15 @@ abstract class PackageMeta {
4954
factory PackageMeta.fromDir(Directory dir) {
5055
Directory original = dir.absolute;
5156
dir = original;
57+
if (!original.existsSync()) {
58+
throw new PackageMetaFailure(
59+
"fatal error: unable to locate the input directory at ${original.path}.");
60+
}
61+
5262
if (!_packageMetaCache.containsKey(dir.path)) {
5363
PackageMeta packageMeta;
5464
// There are pubspec.yaml files inside the SDK. Ignore them.
65+
// TODO(jcollins-g): allow specifying alternate SDK directories (#1617)
5566
if (pathLib.isWithin(getSdkDir().absolute.path, dir.path) ||
5667
getSdkDir().path == dir.path) {
5768
packageMeta = new _SdkMeta(getSdkDir());

lib/src/sdk.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'dart:io';
66

77
/// Use config.sdkDir instead outside of initialization.
8+
// TODO(jcollins-g): Avoid this function in PackageMeta, too.
89
Directory getSdkDir() {
910
File vmExecutable = new File(Platform.resolvedExecutable);
1011
return vmExecutable.parent.parent;

pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,4 +408,4 @@ packages:
408408
source: hosted
409409
version: "2.1.13"
410410
sdks:
411-
dart: ">=2.0.0-dev.23.0 <=2.0.0-dev.44.0"
411+
dart: ">=2.0.0-dev.23.0 <=2.0.0-dev.47.0"

0 commit comments

Comments
 (0)