Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Optionally omit generated description comments in output #720

1 change: 1 addition & 0 deletions source_gen/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Support all the glob quotes.
- Require `analyzer: ^6.9.0`
- Require Dart 3.5.0
- `LibraryBuilder`, `PartBuilder`, and `SharedPartBuilder` now take an optional `writeDescriptions` boolean. When set to `false`, headers and generator descriptions for the files will not be included in the builder output.

## 1.5.0

Expand Down
49 changes: 39 additions & 10 deletions source_gen/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class _Builder extends Builder {

final String _header;

/// Whether to include or emit the gen part descriptions. Defaults to true.
final bool _writeDescriptions;

/// Whether to allow syntax errors in input libraries.
final bool allowSyntaxErrors;

Expand All @@ -51,6 +54,7 @@ class _Builder extends Builder {
String generatedExtension = '.g.dart',
List<String> additionalOutputExtensions = const [],
String? header,
bool? writeDescriptions,
this.allowSyntaxErrors = false,
BuilderOptions? options,
}) : _generatedExtension = generatedExtension,
Expand All @@ -61,6 +65,7 @@ class _Builder extends Builder {
...additionalOutputExtensions,
],
}),
_writeDescriptions = writeDescriptions ?? true,
_header = (header ?? defaultFileHeader).trim() {
if (_generatedExtension.isEmpty || !_generatedExtension.startsWith('.')) {
throw ArgumentError.value(
Expand Down Expand Up @@ -153,16 +158,19 @@ class _Builder extends Builder {
}

for (var item in generatedOutputs) {
contentBuffer
..writeln()
..writeln(_headerLine)
..writeAll(
LineSplitter.split(item.generatorDescription)
.map((line) => '// $line\n'),
)
..writeln(_headerLine)
..writeln()
..writeln(item.output);
if (_writeDescriptions) {
contentBuffer
..writeln()
..writeln(_headerLine)
..writeAll(
LineSplitter.split(item.generatorDescription)
.map((line) => '// $line\n'),
)
..writeln(_headerLine)
..writeln();
}

contentBuffer.writeln(item.output);
}

var genPartContent = contentBuffer.toString();
Expand Down Expand Up @@ -219,12 +227,19 @@ class SharedPartBuilder extends _Builder {
///
/// [allowSyntaxErrors] indicates whether to allow syntax errors in input
/// libraries.
///
/// [writeDescriptions] adds comments to the output used to separate the
/// sections of the file generated from different generators, and reveals
/// which generator produced the following output.
/// If `null`, [writeDescriptions] is set to true which is the default value.
/// If [writeDescriptions] is false, no generator descriptions are added.
SharedPartBuilder(
super.generators,
String partId, {
super.formatOutput,
super.additionalOutputExtensions,
super.allowSyntaxErrors,
super.writeDescriptions,
}) : super(
generatedExtension: '.$partId.g.part',
header: '',
Expand Down Expand Up @@ -265,6 +280,12 @@ class PartBuilder extends _Builder {
/// [formatOutput] is called to format the generated code. Defaults to
/// [DartFormatter.format].
///
/// [writeDescriptions] adds comments to the output used to separate the
/// sections of the file generated from different generators, and reveals
/// which generator produced the following output.
/// If `null`, [writeDescriptions] is set to true which is the default value.
/// If [writeDescriptions] is false, no generator descriptions are added.
///
/// [header] is used to specify the content at the top of each generated file.
/// If `null`, the content of [defaultFileHeader] is used.
/// If [header] is an empty `String` no header is added.
Expand All @@ -279,6 +300,7 @@ class PartBuilder extends _Builder {
String generatedExtension, {
super.formatOutput,
super.additionalOutputExtensions,
super.writeDescriptions,
super.header,
super.allowSyntaxErrors,
super.options,
Expand All @@ -305,6 +327,12 @@ class LibraryBuilder extends _Builder {
/// [formatOutput] is called to format the generated code. Defaults to
/// using the standard [DartFormatter].
///
/// [writeDescriptions] adds comments to the output used to separate the
/// sections of the file generated from different generators, and reveals
/// which generator produced the following output.
/// If `null`, [writeDescriptions] is set to true which is the default value.
/// If [writeDescriptions] is false, no generator descriptions are added.
///
/// [header] is used to specify the content at the top of each generated file.
/// If `null`, the content of [defaultFileHeader] is used.
/// If [header] is an empty `String` no header is added.
Expand All @@ -316,6 +344,7 @@ class LibraryBuilder extends _Builder {
super.formatOutput,
super.generatedExtension,
super.additionalOutputExtensions,
super.writeDescriptions,
super.header,
super.allowSyntaxErrors,
super.options,
Expand Down
53 changes: 53 additions & 0 deletions source_gen/test/builder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,59 @@ void main() {
);
});

test('Omits generated comments if writeDescriptions is explicitly false',
() async {
final srcs = _createPackageStub();

// Explicitly empty header
final builderEmptyHeader = LibraryBuilder(
const CommentGenerator(),
header: '',
writeDescriptions: false,
);

const expected = '''
// Code for "class Person"
// Code for "class Customer"
''';

await testBuilder(
builderEmptyHeader,
srcs,
generateFor: {'$_pkgName|lib/test_lib.dart'},
outputs: {
'$_pkgName|lib/test_lib.g.dart': decodedMatches(startsWith(expected)),
},
);
});

test('When writeDescriptions is true, generated comments are present',
() async {
final srcs = _createPackageStub();

// Null value for writeDescriptions resolves to true
final builder = LibraryBuilder(
const CommentGenerator(),
// We omit header to inspect the generator descriptions
header: '',
);

const expected = '''
// **************************************************************************
// CommentGenerator
// **************************************************************************
''';

await testBuilder(
builder,
srcs,
generateFor: {'$_pkgName|lib/test_lib.dart'},
outputs: {
'$_pkgName|lib/test_lib.g.dart': decodedMatches(contains(expected)),
},
);
});

test('Expect no error when multiple generators used on nonstandalone builder',
() async {
expect(
Expand Down