Skip to content

Commit

Permalink
Add support for build_extensions configuration of builders producin…
Browse files Browse the repository at this point in the history
…g multiple files (dart-lang/source_gen#647)

Allow lists or single strings in the options.
  • Loading branch information
d-markey authored Feb 23, 2023
1 parent ad1bf9f commit a7fa12b
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 13 deletions.
5 changes: 5 additions & 0 deletions pkgs/source_gen/source_gen/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.3.0

* Add support for `build_extensions` configuration of builders producing multiple files. Eg:
`build_extensions: { '.dart': ['.stub.dart', '.web.dart', '.vm.dart'] }`

## 1.2.7

* Update the value of the pubspec `repository` field.
Expand Down
24 changes: 16 additions & 8 deletions pkgs/source_gen/source_gen/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,11 @@ Map<String, List<String>> validatedBuildExtensionsFrom(
Map<String, List<String>> defaultExtensions,
) {
final extensionsOption = optionsMap?.remove('build_extensions');
if (extensionsOption == null) return defaultExtensions;
if (extensionsOption == null) {
// defaultExtensions are provided by the builder author, not the end user.
// It should be safe to skip validation.
return defaultExtensions;
}

if (extensionsOption is! Map) {
throw ArgumentError(
Expand All @@ -195,15 +199,19 @@ Map<String, List<String>> validatedBuildExtensionsFrom(
);
}

final output = entry.value;
if (output is! String || !output.endsWith('.dart')) {
throw ArgumentError(
'Invalid output extension `$output`. It should be a '
'string ending with `.dart`',
);
final output = (entry.value is List) ? entry.value as List : [entry.value];

for (var i = 0; i < output.length; i++) {
final o = output[i];
if (o is! String || (i == 0 && !o.endsWith('.dart'))) {
throw ArgumentError(
'Invalid output extension `${entry.value}`. It should be a string '
'or a list of strings with the first ending with `.dart`',
);
}
}

result[input] = [output];
result[input] = output.cast<String>().toList();
}

if (result.isEmpty) {
Expand Down
2 changes: 1 addition & 1 deletion pkgs/source_gen/source_gen/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: source_gen
version: 1.2.7
version: 1.3.0
description: >-
Source code generation builders and utilities for the Dart build system
repository: https://github.com/dart-lang/source_gen/tree/master/source_gen
Expand Down
56 changes: 52 additions & 4 deletions pkgs/source_gen/source_gen/test/utils_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,42 @@ void main() {

group('validatedBuildExtensionsFrom', () {
test('no option given -> return defaultBuildExtension ', () {
final buildEtension = validatedBuildExtensionsFrom({}, {
final buildExtension = validatedBuildExtensionsFrom({}, {
'.dart': ['.foo.dart'],
});
expect(buildEtension, {
expect(buildExtension, {
'.dart': ['.foo.dart'],
});
});

test('allows multiple output extensions', () {
final buildExtensions = validatedBuildExtensionsFrom(
{
'build_extensions': {
'.dart': ['.g.dart', '.h.dart']
}
},
{},
);
expect(buildExtensions, {
'.dart': ['.g.dart', '.h.dart'],
});
});

test('allows multiple output extensions of various types ', () {
final buildExtensions = validatedBuildExtensionsFrom(
{
'build_extensions': {
'.dart': ['.g.dart', '.swagger.json']
}
},
{},
);
expect(buildExtensions, {
'.dart': ['.g.dart', '.swagger.json'],
});
});

test("disallows options that aren't a map", () {
expect(
() => validatedBuildExtensionsFrom({'build_extensions': 'foo'}, {}),
Expand Down Expand Up @@ -104,8 +132,28 @@ void main() {
isArgumentError.having(
(e) => e.message,
'message',
'Invalid output extension `.out`. It should be a string ending '
'with `.dart`',
'Invalid output extension `.out`. It should be a string or a list '
'of strings with the first ending with `.dart`',
),
),
);

expect(
() => validatedBuildExtensionsFrom(
{
'build_extensions': {
'.dart': ['.out', '.g.dart']
}
},
{},
),
throwsA(
isArgumentError.having(
(e) => e.message,
'message',
'Invalid output extension `[.out, .g.dart]`. It should be a '
'string or a list of strings with the first ending with '
'`.dart`',
),
),
);
Expand Down

0 comments on commit a7fa12b

Please sign in to comment.