Skip to content

Commit 0b0f715

Browse files
authored
Override packagemeta using a provider rather than statically (#2219)
1 parent f32f483 commit 0b0f715

13 files changed

+101
-82
lines changed

bin/dartdoc.dart

+1-7
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,11 @@ import 'package:dartdoc/options.dart';
1212
/// Analyzes Dart files and generates a representation of included libraries,
1313
/// classes, and members. Uses the current directory to look for libraries.
1414
Future<void> main(List<String> arguments) async {
15-
var config = await parseOptions(arguments);
15+
var config = await parseOptions(pubPackageMetaProvider, arguments);
1616
if (config == null) {
1717
// There was an error while parsing options.
1818
return;
1919
}
20-
// Set the default way to construct [PackageMeta].
21-
PackageMeta.setPackageMetaFactories(
22-
PubPackageMeta.fromElement,
23-
PubPackageMeta.fromFilename,
24-
PubPackageMeta.fromDir,
25-
);
2620
final packageBuilder = PubPackageBuilder(config);
2721
final dartdoc = config.generateDocs
2822
? await Dartdoc.fromContext(config, packageBuilder)

lib/options.dart

+5-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ Future<List<DartdocOption>> createDartdocProgramOptions() async {
2828
];
2929
}
3030

31-
Future<DartdocProgramOptionContext> parseOptions(List<String> arguments) async {
31+
Future<DartdocProgramOptionContext> parseOptions(
32+
PackageMetaProvider packageMetaProvider,
33+
List<String> arguments,
34+
) async {
3235
var optionSet = await DartdocOptionSet.fromOptionGenerators('dartdoc', [
33-
createDartdocOptions,
36+
() => createDartdocOptions(packageMetaProvider),
3437
createDartdocProgramOptions,
3538
createLoggingOptions,
3639
createGeneratorOptions,

lib/src/dartdoc_options.dart

+7-5
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,9 @@ class DartdocOptionContext extends DartdocOptionContextBase
14291429

14301430
/// Instantiate dartdoc's configuration file and options parser with the
14311431
/// given command line arguments.
1432-
Future<List<DartdocOption>> createDartdocOptions() async {
1432+
Future<List<DartdocOption>> createDartdocOptions(
1433+
PackageMetaProvider packageMetaProvider,
1434+
) async {
14331435
return <DartdocOption>[
14341436
DartdocOptionArgOnly<bool>('allowTools', false,
14351437
help: 'Execute user-defined tools to fill in @tool directives.',
@@ -1562,7 +1564,7 @@ Future<List<DartdocOption>> createDartdocOptions() async {
15621564
DartdocOptionSyntheticOnly<PackageMeta>(
15631565
'packageMeta',
15641566
(DartdocSyntheticOption<PackageMeta> option, Directory dir) {
1565-
var packageMeta = PackageMeta.fromDir(dir);
1567+
var packageMeta = packageMetaProvider.fromDir(dir);
15661568
if (packageMeta == null) {
15671569
throw DartdocOptionError(
15681570
'Unable to determine package for directory: ${dir.path}');
@@ -1590,8 +1592,8 @@ Future<List<DartdocOption>> createDartdocOptions() async {
15901592
help: "Label categories that aren't documented", negatable: true),
15911593
DartdocOptionSyntheticOnly<PackageMeta>('topLevelPackageMeta',
15921594
(DartdocSyntheticOption<PackageMeta> option, Directory dir) {
1593-
var packageMeta = PackageMeta.fromDir(
1594-
Directory(option.parent['inputDir'].valueAt(dir)));
1595+
var packageMeta = packageMetaProvider
1596+
.fromDir(Directory(option.parent['inputDir'].valueAt(dir)));
15951597
if (packageMeta == null) {
15961598
throw DartdocOptionError(
15971599
'Unable to generate documentation: no package found');
@@ -1632,7 +1634,7 @@ Future<List<DartdocOption>> createDartdocOptions() async {
16321634
// TODO(jcollins-g): refactor so there is a single static "create" for
16331635
// each DartdocOptionContext that traverses the inheritance tree itself.
16341636
...await createExperimentOptions(),
1635-
...await createPackageWarningOptions(),
1637+
...await createPackageWarningOptions(packageMetaProvider),
16361638
...await createSourceLinkerOptions(),
16371639
];
16381640
}

lib/src/model/library.dart

+4-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,10 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
426426
PackageMeta _packageMeta;
427427

428428
PackageMeta get packageMeta {
429-
_packageMeta ??= PackageMeta.fromElement(element, config.sdkDir);
429+
_packageMeta ??= packageGraph.packageMetaProvider.fromElement(
430+
element,
431+
config.sdkDir,
432+
);
430433
return _packageMeta;
431434
}
432435

lib/src/model/package_builder.dart

+9-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import 'package:dartdoc/src/dartdoc_options.dart';
2626
import 'package:dartdoc/src/io_utils.dart';
2727
import 'package:dartdoc/src/logging.dart';
2828
import 'package:dartdoc/src/model/model.dart';
29-
import 'package:dartdoc/src/package_meta.dart' show PackageMeta;
29+
import 'package:dartdoc/src/package_meta.dart'
30+
show PackageMeta, pubPackageMetaProvider;
3031
import 'package:dartdoc/src/render/renderer_factory.dart';
3132
import 'package:dartdoc/src/special_elements.dart';
3233
import 'package:package_config/discovery.dart' as package_config;
@@ -62,7 +63,12 @@ class PubPackageBuilder implements PackageBuilder {
6263
var rendererFactory = RendererFactory.forFormat(config.format);
6364

6465
var newGraph = PackageGraph.UninitializedPackageGraph(
65-
config, sdk, hasEmbedderSdkFiles, rendererFactory);
66+
config,
67+
sdk,
68+
hasEmbedderSdkFiles,
69+
rendererFactory,
70+
pubPackageMetaProvider,
71+
);
6672
await getLibraries(newGraph);
6773
await newGraph.initializePackageGraph();
6874
return newGraph;
@@ -238,7 +244,7 @@ class PubPackageBuilder implements PackageBuilder {
238244
Set<PackageMeta> _packageMetasForFiles(Iterable<String> files) {
239245
var metas = <PackageMeta>{};
240246
for (var filename in files) {
241-
metas.add(PackageMeta.fromFilename(filename));
247+
metas.add(pubPackageMetaProvider.fromFilename(filename));
242248
}
243249
return metas;
244250
}

lib/src/model/package_graph.dart

+13-5
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@ import 'package:dartdoc/src/dartdoc_options.dart';
1414
import 'package:dartdoc/src/logging.dart';
1515
import 'package:dartdoc/src/model/model.dart';
1616
import 'package:dartdoc/src/model_utils.dart' as utils;
17-
import 'package:dartdoc/src/package_meta.dart' show PackageMeta;
17+
import 'package:dartdoc/src/package_meta.dart'
18+
show PackageMeta, PackageMetaProvider;
1819
import 'package:dartdoc/src/render/renderer_factory.dart';
1920
import 'package:dartdoc/src/special_elements.dart';
2021
import 'package:dartdoc/src/tuple.dart';
2122
import 'package:dartdoc/src/warnings.dart';
2223

2324
class PackageGraph {
2425
PackageGraph.UninitializedPackageGraph(
25-
this.config, this.sdk, this.hasEmbedderSdk, this.rendererFactory)
26-
: packageMeta = config.topLevelPackageMeta {
26+
this.config,
27+
this.sdk,
28+
this.hasEmbedderSdk,
29+
this.rendererFactory,
30+
this.packageMetaProvider,
31+
) : packageMeta = config.topLevelPackageMeta {
2732
_packageWarningCounter = PackageWarningCounter(this);
2833
// Make sure the default package exists, even if it has no libraries.
2934
// This can happen for packages that only contain embedder SDKs.
@@ -38,7 +43,7 @@ class PackageGraph {
3843
void addLibraryToGraph(DartDocResolvedLibrary resolvedLibrary) {
3944
assert(!allLibrariesAdded);
4045
var element = resolvedLibrary.element;
41-
var packageMeta = PackageMeta.fromElement(element, config.sdkDir);
46+
var packageMeta = packageMetaProvider.fromElement(element, config.sdkDir);
4247
var lib = Library.fromLibraryResult(
4348
resolvedLibrary, this, Package.fromPackageMeta(packageMeta, this));
4449
packageMap[packageMeta.name].libraries.add(lib);
@@ -214,6 +219,9 @@ class PackageGraph {
214219
/// Factory for renderers
215220
final RendererFactory rendererFactory;
216221

222+
/// PackageMeta Provider for building [PackageMeta]s.
223+
final PackageMetaProvider packageMetaProvider;
224+
217225
Package _defaultPackage;
218226

219227
Package get defaultPackage {
@@ -849,7 +857,7 @@ class PackageGraph {
849857
resolvedLibrary,
850858
this,
851859
Package.fromPackageMeta(
852-
PackageMeta.fromElement(elementLibrary, config.sdkDir),
860+
packageMetaProvider.fromElement(elementLibrary, config.sdkDir),
853861
packageGraph));
854862
allLibraries[elementLibrary] = foundLibrary;
855863
return foundLibrary;

lib/src/package_meta.dart

+22-40
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,28 @@ final List<List<String>> __sdkDirFilePathsPosix = [
3535
['lib/core/core.dart'],
3636
];
3737

38+
final PackageMetaProvider pubPackageMetaProvider = PackageMetaProvider(
39+
PubPackageMeta.fromElement,
40+
PubPackageMeta.fromFilename,
41+
PubPackageMeta.fromDir,
42+
);
43+
44+
/// Sets the supported way of constructing [PackageMeta] objects.
45+
///
46+
/// These objects can be constructed from a filename, a directory
47+
/// or a [LibraryElement]. We allow different dartdoc implementations to
48+
/// provide their own [PackageMeta] types.
49+
///
50+
/// By using a different provider, these implementations can control how
51+
/// [PackageMeta] objects is built.
52+
class PackageMetaProvider {
53+
final PackageMeta Function(LibraryElement, String) fromElement;
54+
final PackageMeta Function(String) fromFilename;
55+
final PackageMeta Function(Directory) fromDir;
56+
57+
PackageMetaProvider(this.fromElement, this.fromFilename, this.fromDir);
58+
}
59+
3860
/// Describes a single package in the context of `dartdoc`.
3961
///
4062
/// The primary function of this class is to allow canonicalization of packages
@@ -104,46 +126,6 @@ abstract class PackageMeta {
104126

105127
@override
106128
String toString() => name;
107-
108-
/// Sets the supported ways of constructing [PackageMeta] objects.
109-
///
110-
/// These objects can be constructed from a filename, a directory
111-
/// or a [LibraryElement]. We allow different dartdoc implementations to
112-
/// provide their own [PackageMeta] types.
113-
///
114-
/// By calling this function, these implementations can control how
115-
/// [PackageMeta] is built.
116-
static void setPackageMetaFactories(
117-
PackageMeta Function(LibraryElement, String) fromElementFactory,
118-
PackageMeta Function(String) fromFilenameFactory,
119-
PackageMeta Function(Directory) fromDirFactory,
120-
) {
121-
assert(fromElementFactory != null);
122-
assert(fromFilenameFactory != null);
123-
assert(fromDirFactory != null);
124-
if (_fromElement == fromElementFactory &&
125-
_fromFilename == fromFilenameFactory &&
126-
_fromDir == fromDirFactory) {
127-
// Nothing to do.
128-
return;
129-
}
130-
if (_fromElement != null || _fromFilename != null || _fromDir != null) {
131-
throw StateError('PackageMeta factories cannot be changed once defined.');
132-
}
133-
_fromElement = fromElementFactory;
134-
_fromFilename = fromFilenameFactory;
135-
_fromDir = fromDirFactory;
136-
}
137-
138-
static PackageMeta Function(LibraryElement, String) _fromElement;
139-
static PackageMeta Function(String) _fromFilename;
140-
static PackageMeta Function(Directory) _fromDir;
141-
static PackageMeta Function(LibraryElement, String) get fromElement =>
142-
_fromElement ?? PubPackageMeta.fromElement;
143-
static PackageMeta Function(String) get fromFilename =>
144-
_fromFilename ?? PubPackageMeta.fromFilename;
145-
static PackageMeta Function(Directory) get fromDir =>
146-
_fromDir ?? PubPackageMeta.fromDir;
147129
}
148130

149131
/// Default implementation of [PackageMeta] depends on pub packages.

lib/src/warnings.dart

+12-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ abstract class PackageWarningOptionContext implements DartdocOptionContextBase {
2323
bool get verboseWarnings => optionSet['verboseWarnings'].valueAt(context);
2424
}
2525

26-
Future<List<DartdocOption>> createPackageWarningOptions() async {
26+
Future<List<DartdocOption>> createPackageWarningOptions(
27+
PackageMetaProvider packageMetaProvider,
28+
) async {
2729
return <DartdocOption>[
2830
DartdocOptionArgOnly<bool>('allowNonLocalWarnings', false,
2931
negatable: true,
@@ -79,7 +81,10 @@ Future<List<DartdocOption>> createPackageWarningOptions() async {
7981
.join('\n')),
8082
// Synthetic option uses a factory to build a PackageWarningOptions from all the above flags.
8183
DartdocOptionSyntheticOnly<PackageWarningOptions>(
82-
'packageWarningOptions', PackageWarningOptions.fromOptions),
84+
'packageWarningOptions',
85+
(DartdocSyntheticOption<PackageWarningOptions> option, Directory dir) =>
86+
PackageWarningOptions.fromOptions(option, dir, packageMetaProvider),
87+
),
8388
];
8489
}
8590

@@ -303,10 +308,13 @@ class PackageWarningOptions {
303308

304309
/// [packageMeta] parameter is for testing.
305310
static PackageWarningOptions fromOptions(
306-
DartdocSyntheticOption<PackageWarningOptions> option, Directory dir) {
311+
DartdocSyntheticOption<PackageWarningOptions> option,
312+
Directory dir,
313+
PackageMetaProvider packageMetaProvider,
314+
) {
307315
// First, initialize defaults.
308316
var newOptions = PackageWarningOptions();
309-
var packageMeta = PackageMeta.fromDir(dir);
317+
var packageMeta = packageMetaProvider.fromDir(dir);
310318

311319
// Interpret errors/warnings/ignore options. In the event of conflict, warning overrides error and
312320
// ignore overrides warning.

test/dartdoc_integration_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ void main() {
164164
await subprocessLauncher.runStreamed(Platform.resolvedExecutable, args,
165165
workingDirectory: _testPackagePath,
166166
perLine: (s) => output.writeln(s));
167-
var dartdocMeta = PackageMeta.fromFilename(dartdocPath);
167+
var dartdocMeta = pubPackageMetaProvider.fromFilename(dartdocPath);
168168
expect(output.toString(),
169169
endsWith('dartdoc version: ${dartdocMeta.version}\n'));
170170
});

test/package_meta_test.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void main() {
1616

1717
setUp(() {
1818
var d = Directory.systemTemp.createTempSync('test_package_not_valid');
19-
p = PackageMeta.fromDir(d);
19+
p = pubPackageMetaProvider.fromDir(d);
2020
});
2121

2222
test('is not valid', () {
@@ -25,7 +25,7 @@ void main() {
2525
});
2626

2727
group('PackageMeta for the test package', () {
28-
var p = PackageMeta.fromDir(Directory(
28+
var p = pubPackageMetaProvider.fromDir(Directory(
2929
path.join(Directory.current.path, 'testing', 'test_package')));
3030

3131
test('readme with corrupt UTF-8 loads without throwing', () {
@@ -35,7 +35,7 @@ void main() {
3535
});
3636

3737
group('PackageMeta.fromDir for this package', () {
38-
var p = PackageMeta.fromDir(Directory.current);
38+
var p = pubPackageMetaProvider.fromDir(Directory.current);
3939

4040
test('has a name', () {
4141
expect(p.name, 'dartdoc');
@@ -82,7 +82,7 @@ void main() {
8282
});
8383

8484
group('PackageMeta.fromSdk', () {
85-
var p = PackageMeta.fromDir(defaultSdkDir);
85+
var p = pubPackageMetaProvider.fromDir(defaultSdkDir);
8686

8787
test('has a name', () {
8888
expect(p.name, 'Dart');

test/src/utils.dart

+8-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ final RegExp observatoryPortRegexp =
2424
RegExp(r'^Observatory listening on http://.*:(\d+)');
2525

2626
Directory sdkDir = defaultSdkDir;
27-
PackageMeta sdkPackageMeta = PackageMeta.fromDir(sdkDir);
27+
PackageMeta sdkPackageMeta = pubPackageMetaProvider.fromDir(sdkDir);
2828

2929
final _testPackageGraphMemo = AsyncMemoizer<PackageGraph>();
3030
Future<PackageGraph> get testPackageGraph => _testPackageGraphMemo.runOnce(() =>
@@ -98,17 +98,20 @@ final Directory testPackageCustomTemplates =
9898
/// the '--input' flag.
9999
Future<DartdocGeneratorOptionContext> generatorContextFromArgv(
100100
List<String> argv) async {
101-
var optionSet = await DartdocOptionSet.fromOptionGenerators(
102-
'dartdoc', [createDartdocOptions, createGeneratorOptions]);
101+
var optionSet = await DartdocOptionSet.fromOptionGenerators('dartdoc', [
102+
() => createDartdocOptions(pubPackageMetaProvider),
103+
createGeneratorOptions,
104+
]);
103105
optionSet.parseArguments(argv);
104106
return DartdocGeneratorOptionContext(optionSet, null);
105107
}
106108

107109
/// Convenience factory to build a [DartdocOptionContext] and associate it with a
108110
/// [DartdocOptionSet] based on the current working directory.
109111
Future<DartdocOptionContext> contextFromArgv(List<String> argv) async {
110-
var optionSet = await DartdocOptionSet.fromOptionGenerators(
111-
'dartdoc', [createDartdocOptions]);
112+
var optionSet = await DartdocOptionSet.fromOptionGenerators('dartdoc', [
113+
() => createDartdocOptions(pubPackageMetaProvider),
114+
]);
112115
optionSet.parseArguments(argv);
113116
return DartdocOptionContext(optionSet, Directory.current);
114117
}

test/warnings_test.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ library dartdoc.warnings_test;
88
import 'dart:io';
99

1010
import 'package:dartdoc/src/dartdoc_options.dart';
11+
import 'package:dartdoc/src/package_meta.dart';
1112
import 'package:dartdoc/src/warnings.dart';
1213
import 'package:path/path.dart' as path;
1314
import 'package:test/test.dart';
@@ -47,7 +48,7 @@ dartdoc:
4748

4849
setUp(() async {
4950
optionSet = await DartdocOptionSet.fromOptionGenerators(
50-
'dartdoc', [createDartdocOptions]);
51+
'dartdoc', [() => createDartdocOptions(pubPackageMetaProvider)]);
5152
});
5253

5354
test('Verify that options for enabling/disabling packages work', () {

0 commit comments

Comments
 (0)