Skip to content

Commit fc3fe59

Browse files
authored
Move generator options into generator.dart (#2100)
* Remove --hosted-url as it is actually unused * Move templatesDir option to generator context * Separate html generator options from generic ones * Move base generator context options to generator.dart * Move initEmptyGenerators * Make initHtmlGenerators take HtmlGeneratorContext instead * Recombine options into one GeneratorContext * Temporarily dupe useBaseHrefs in GeneratorContext
1 parent c7f7ec5 commit fc3fe59

File tree

5 files changed

+130
-114
lines changed

5 files changed

+130
-114
lines changed

lib/dartdoc.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'dart:convert';
1313
import 'dart:io';
1414

1515
import 'package:dartdoc/src/dartdoc_options.dart';
16+
import 'package:dartdoc/src/empty_generator.dart';
1617
import 'package:dartdoc/src/generator.dart';
1718
import 'package:dartdoc/src/html/html_generator.dart';
1819
import 'package:dartdoc/src/logging.dart';
@@ -36,8 +37,7 @@ const String programName = 'dartdoc';
3637
// Update when pubspec version changes by running `pub run build_runner build`
3738
const String dartdocVersion = packageVersion;
3839

39-
/// Helper class to initialize the default generators since they require
40-
/// GeneratorContext.
40+
/// Helper class that consolidates option contexts for instantiating generators.
4141
class DartdocGeneratorOptionContext extends DartdocOptionContext
4242
with GeneratorContext {
4343
DartdocGeneratorOptionContext(DartdocOptionSet optionSet, Directory dir)
@@ -64,7 +64,7 @@ class Dartdoc extends PackageBuilder {
6464
/// and returns a Dartdoc object with them.
6565
static Future<Dartdoc> withDefaultGenerators(
6666
DartdocGeneratorOptionContext config) async {
67-
List<Generator> generators = await initGenerators(config);
67+
List<Generator> generators = await initHtmlGenerators(config);
6868
return Dartdoc._(config, generators);
6969
}
7070

lib/src/dartdoc_options.dart

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,8 +1421,6 @@ class DartdocOptionContext extends DartdocOptionContextBase
14211421
bool isPackageExcluded(String name) =>
14221422
excludePackages.any((pattern) => name == pattern);
14231423

1424-
String get templatesDir => optionSet['templatesDir'].valueAt(context);
1425-
14261424
// TODO(jdkoren): temporary while we confirm href base behavior doesn't break important clients
14271425
bool get useBaseHref => optionSet['useBaseHref'].valueAt(context);
14281426
}
@@ -1627,17 +1625,6 @@ Future<List<DartdocOption>> createDartdocOptions() async {
16271625
'exist. Executables for different platforms are specified by '
16281626
'giving the platform name as a key, and a list of strings as the '
16291627
'command.'),
1630-
DartdocOptionArgOnly<String>("templatesDir", null,
1631-
isDir: true,
1632-
mustExist: true,
1633-
hide: true,
1634-
help:
1635-
'Path to a directory containing templates to use instead of the default ones. '
1636-
'Directory must contain an html file for each of the following: 404error, category, '
1637-
'class, constant, constructor, enum, function, index, library, method, mixin, '
1638-
'property, top_level_constant, top_level_property, typedef. Partial templates are '
1639-
'supported; they must begin with an underscore, and references to them must omit the '
1640-
'leading underscore (e.g. use {{>foo}} to reference the partial template _foo.html).'),
16411628
DartdocOptionArgOnly<bool>('useBaseHref', false,
16421629
help:
16431630
'Use <base href> in generated files (legacy behavior). This option '

lib/src/empty_generator.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library dartdoc.empty_generator;
22

33
import 'dart:async';
44

5+
import 'package:dartdoc/src/dartdoc_options.dart';
56
import 'package:dartdoc/src/generator.dart';
67
import 'package:dartdoc/src/model/model.dart';
78
import 'package:dartdoc/src/model_utils.dart';
@@ -39,3 +40,7 @@ class EmptyGenerator extends Generator {
3940
@override
4041
final Map<String, Warnable> writtenFiles = {};
4142
}
43+
44+
Future<List<Generator>> initEmptyGenerators(DartdocOptionContext config) async {
45+
return [EmptyGenerator()];
46+
}

lib/src/generator.dart

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
library dartdoc.generator;
77

88
import 'dart:async' show Stream, Future;
9+
import 'dart:io' show Directory;
10+
import 'dart:isolate';
911

12+
import 'package:dartdoc/src/dartdoc_options.dart';
1013
import 'package:dartdoc/src/model/model.dart' show PackageGraph;
14+
import 'package:dartdoc/src/package_meta.dart';
1115
import 'package:dartdoc/src/warnings.dart';
16+
import 'package:path/path.dart' as path;
1217

1318
/// An abstract class that defines a generator that generates documentation for
1419
/// a given package.
@@ -25,3 +30,110 @@ abstract class Generator {
2530
/// Fetches all filenames written by this generator.
2631
Map<String, Warnable> get writtenFiles;
2732
}
33+
34+
/// Dartdoc options related to generators generally.
35+
mixin GeneratorContext on DartdocOptionContextBase {
36+
List<String> get footer => optionSet['footer'].valueAt(context);
37+
38+
/// _footerText is only used to construct synthetic options.
39+
// ignore: unused_element
40+
List<String> get _footerText => optionSet['footerText'].valueAt(context);
41+
42+
List<String> get footerTextPaths =>
43+
optionSet['footerTextPaths'].valueAt(context);
44+
45+
List<String> get header => optionSet['header'].valueAt(context);
46+
47+
bool get prettyIndexJson => optionSet['prettyIndexJson'].valueAt(context);
48+
49+
String get favicon => optionSet['favicon'].valueAt(context);
50+
51+
String get relCanonicalPrefix =>
52+
optionSet['relCanonicalPrefix'].valueAt(context);
53+
54+
String get templatesDir => optionSet['templatesDir'].valueAt(context);
55+
56+
// TODO(jdkoren): duplicated temporarily so that GeneratorContext is enough for configuration.
57+
bool get useBaseHref => optionSet['useBaseHref'].valueAt(context);
58+
}
59+
60+
Uri _sdkFooterCopyrightUri;
61+
62+
Future<void> _setSdkFooterCopyrightUri() async {
63+
if (_sdkFooterCopyrightUri == null) {
64+
// TODO(jdkoren): find a way to make this not specific to HTML, or have
65+
// alternatives for other supported formats.
66+
_sdkFooterCopyrightUri = await Isolate.resolvePackageUri(
67+
Uri.parse('package:dartdoc/resources/sdk_footer_text.html'));
68+
}
69+
}
70+
71+
Future<List<DartdocOption>> createGeneratorOptions() async {
72+
await _setSdkFooterCopyrightUri();
73+
return <DartdocOption>[
74+
DartdocOptionArgFile<List<String>>('footer', [],
75+
isFile: true,
76+
help:
77+
'Paths to files with content to add to page footers, but possibly '
78+
'outside of dedicated footer elements for the generator (e.g. '
79+
'outside of <footer> for an HTML generator). To add text content '
80+
'to dedicated footer elements, use --footer-text instead.',
81+
mustExist: true,
82+
splitCommas: true),
83+
DartdocOptionArgFile<List<String>>('footerText', [],
84+
isFile: true,
85+
help: 'Paths to files with content to add to page footers (next to the '
86+
'package name and version).',
87+
mustExist: true,
88+
splitCommas: true),
89+
DartdocOptionSyntheticOnly<List<String>>(
90+
'footerTextPaths',
91+
(DartdocSyntheticOption<List<String>> option, Directory dir) {
92+
final List<String> footerTextPaths = <String>[];
93+
final PackageMeta topLevelPackageMeta =
94+
option.root['topLevelPackageMeta'].valueAt(dir);
95+
// TODO(jcollins-g): Eliminate special casing for SDK and use config file.
96+
if (topLevelPackageMeta.isSdk == true) {
97+
footerTextPaths
98+
.add(path.canonicalize(_sdkFooterCopyrightUri.toFilePath()));
99+
}
100+
footerTextPaths.addAll(option.parent['footerText'].valueAt(dir));
101+
return footerTextPaths;
102+
},
103+
isFile: true,
104+
help: 'paths to footer-text-files (adding special case for SDK)',
105+
mustExist: true,
106+
),
107+
DartdocOptionArgFile<List<String>>('header', [],
108+
isFile: true,
109+
help: 'Paths to files with content to add to page headers.',
110+
splitCommas: true),
111+
DartdocOptionArgOnly<bool>('prettyIndexJson', false,
112+
help:
113+
'Generates `index.json` with indentation and newlines. The file is '
114+
'larger, but it\'s also easier to diff.',
115+
negatable: false),
116+
DartdocOptionArgFile<String>('favicon', null,
117+
isFile: true,
118+
help: 'A path to a favicon for the generated docs.',
119+
mustExist: true),
120+
DartdocOptionArgOnly<String>('relCanonicalPrefix', null,
121+
help:
122+
'If provided, add a rel="canonical" prefixed with provided value. '
123+
'Consider using if building many versions of the docs for public '
124+
'SEO; learn more at https://goo.gl/gktN6F.'),
125+
DartdocOptionArgOnly<String>("templatesDir", null,
126+
isDir: true,
127+
mustExist: true,
128+
hide: true,
129+
help:
130+
'Path to a directory with templates to use instead of the default '
131+
'ones. Directory must contain a file for each of the following: '
132+
'404error, category, class, constant, constructor, enum, function, '
133+
'index, library, method, mixin, property, top_level_constant, '
134+
'top_level_property, typedef. Partial templates are supported; '
135+
'they must begin with an underscore, and references to them must '
136+
'omit the leading underscore (e.g. use {{>foo}} to reference the '
137+
'partial template _foo.html).'),
138+
];
139+
}

lib/src/html/html_generator.dart

Lines changed: 10 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ class HtmlGenerator extends Generator {
131131
}
132132

133133
class HtmlGeneratorOptions implements HtmlOptions {
134-
final String url;
135134
final String faviconPath;
136135
final bool prettyIndexJson;
137136
final String templatesDir;
@@ -146,8 +145,7 @@ class HtmlGeneratorOptions implements HtmlOptions {
146145
final bool useBaseHref;
147146

148147
HtmlGeneratorOptions(
149-
{this.url,
150-
this.relCanonicalPrefix,
148+
{this.relCanonicalPrefix,
151149
this.faviconPath,
152150
String toolVersion,
153151
this.prettyIndexJson = false,
@@ -156,109 +154,23 @@ class HtmlGeneratorOptions implements HtmlOptions {
156154
: this.toolVersion = toolVersion ?? 'unknown';
157155
}
158156

159-
Future<List<Generator>> initEmptyGenerators(DartdocOptionContext config) async {
160-
return [EmptyGenerator()];
161-
}
162-
163157
/// Initialize and setup the generators.
164-
Future<List<Generator>> initGenerators(GeneratorContext config) async {
158+
Future<List<Generator>> initHtmlGenerators(GeneratorContext context) async {
165159
// TODO(jcollins-g): Rationalize based on GeneratorContext all the way down
166160
// through the generators.
167161
HtmlGeneratorOptions options = HtmlGeneratorOptions(
168-
url: config.hostedUrl,
169-
relCanonicalPrefix: config.relCanonicalPrefix,
162+
relCanonicalPrefix: context.relCanonicalPrefix,
170163
toolVersion: dartdocVersion,
171-
faviconPath: config.favicon,
172-
prettyIndexJson: config.prettyIndexJson,
173-
templatesDir: config.templatesDir,
174-
useBaseHref: config.useBaseHref);
175-
164+
faviconPath: context.favicon,
165+
prettyIndexJson: context.prettyIndexJson,
166+
templatesDir: context.templatesDir,
167+
useBaseHref: context.useBaseHref);
176168
return [
177169
await HtmlGenerator.create(
178170
options: options,
179-
headers: config.header,
180-
footers: config.footer,
181-
footerTexts: config.footerTextPaths,
171+
headers: context.header,
172+
footers: context.footer,
173+
footerTexts: context.footerTextPaths,
182174
)
183175
];
184176
}
185-
186-
Uri _sdkFooterCopyrightUri;
187-
Future<void> _setSdkFooterCopyrightUri() async {
188-
if (_sdkFooterCopyrightUri == null) {
189-
_sdkFooterCopyrightUri = await Isolate.resolvePackageUri(
190-
Uri.parse('package:dartdoc/resources/sdk_footer_text.html'));
191-
}
192-
}
193-
194-
abstract class GeneratorContext implements DartdocOptionContext {
195-
String get favicon => optionSet['favicon'].valueAt(context);
196-
List<String> get footer => optionSet['footer'].valueAt(context);
197-
198-
/// _footerText is only used to construct synthetic options.
199-
// ignore: unused_element
200-
List<String> get _footerText => optionSet['footerText'].valueAt(context);
201-
List<String> get footerTextPaths =>
202-
optionSet['footerTextPaths'].valueAt(context);
203-
List<String> get header => optionSet['header'].valueAt(context);
204-
String get hostedUrl => optionSet['hostedUrl'].valueAt(context);
205-
bool get prettyIndexJson => optionSet['prettyIndexJson'].valueAt(context);
206-
String get relCanonicalPrefix =>
207-
optionSet['relCanonicalPrefix'].valueAt(context);
208-
}
209-
210-
Future<List<DartdocOption>> createGeneratorOptions() async {
211-
await _setSdkFooterCopyrightUri();
212-
return <DartdocOption>[
213-
DartdocOptionArgFile<String>('favicon', null,
214-
isFile: true,
215-
help: 'A path to a favicon for the generated docs.',
216-
mustExist: true),
217-
DartdocOptionArgFile<List<String>>('footer', [],
218-
isFile: true,
219-
help: 'paths to footer files containing HTML text.',
220-
mustExist: true,
221-
splitCommas: true),
222-
DartdocOptionArgFile<List<String>>('footerText', [],
223-
isFile: true,
224-
help:
225-
'paths to footer-text files (optional text next to the package name '
226-
'and version).',
227-
mustExist: true,
228-
splitCommas: true),
229-
DartdocOptionSyntheticOnly<List<String>>(
230-
'footerTextPaths',
231-
(DartdocSyntheticOption<List<String>> option, Directory dir) {
232-
final List<String> footerTextPaths = <String>[];
233-
final PackageMeta topLevelPackageMeta =
234-
option.root['topLevelPackageMeta'].valueAt(dir);
235-
// TODO(jcollins-g): Eliminate special casing for SDK and use config file.
236-
if (topLevelPackageMeta.isSdk == true) {
237-
footerTextPaths
238-
.add(path.canonicalize(_sdkFooterCopyrightUri.toFilePath()));
239-
}
240-
footerTextPaths.addAll(option.parent['footerText'].valueAt(dir));
241-
return footerTextPaths;
242-
},
243-
isFile: true,
244-
help: 'paths to footer-text-files (adding special case for SDK)',
245-
mustExist: true,
246-
),
247-
DartdocOptionArgFile<List<String>>('header', [],
248-
isFile: true,
249-
help: 'paths to header files containing HTML text.',
250-
splitCommas: true),
251-
DartdocOptionArgOnly<String>('hostedUrl', null,
252-
help:
253-
'URL where the docs will be hosted (used to generate the sitemap).'),
254-
DartdocOptionArgOnly<bool>('prettyIndexJson', false,
255-
help:
256-
"Generates `index.json` with indentation and newlines. The file is larger, but it's also easier to diff.",
257-
negatable: false),
258-
DartdocOptionArgOnly<String>('relCanonicalPrefix', null,
259-
help:
260-
'If provided, add a rel="canonical" prefixed with provided value. '
261-
'Consider using if\nbuilding many versions of the docs for public '
262-
'SEO; learn more at https://goo.gl/gktN6F.'),
263-
];
264-
}

0 commit comments

Comments
 (0)