Skip to content

Commit c1518b5

Browse files
committed
Add an argument to LibraryBuilder and PartBuilder to customize header
Closes #275
1 parent d3490e2 commit c1518b5

File tree

3 files changed

+75
-8
lines changed

3 files changed

+75
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.7.2
2+
3+
* Support an optional `header` argument to `PartBuilder` and `LibraryBuilder`.
4+
15
## 0.7.1
26

37
### `Generator{ForAnnotation}`

lib/src/builder.dart

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class _Builder extends Builder {
3131

3232
final bool _requireLibraryDirective;
3333

34+
final String _header;
35+
3436
@override
3537
final Map<String, List<String>> buildExtensions;
3638

@@ -40,14 +42,16 @@ class _Builder extends Builder {
4042
String generatedExtension: '.g.dart',
4143
List<String> additionalOutputExtensions: const [],
4244
bool isStandalone: false,
43-
bool requireLibraryDirective: true})
45+
bool requireLibraryDirective: true,
46+
String header})
4447
: _generatedExtension = generatedExtension,
4548
buildExtensions = {
4649
'.dart': [generatedExtension]..addAll(additionalOutputExtensions)
4750
},
4851
_isStandalone = isStandalone,
4952
formatOutput = formatOutput ?? _formatter.format,
50-
_requireLibraryDirective = requireLibraryDirective {
53+
_requireLibraryDirective = requireLibraryDirective,
54+
_header = header ?? defaultFileHeader {
5155
if (_generatedExtension == null) {
5256
throw new ArgumentError.notNull('generatedExtension');
5357
}
@@ -87,6 +91,11 @@ class _Builder extends Builder {
8791
final outputId = _generatedFile(buildStep.inputId);
8892

8993
var contentBuffer = new StringBuffer();
94+
95+
if (_header.isNotEmpty) {
96+
contentBuffer.writeln(_header);
97+
}
98+
9099
if (!_isStandalone) {
91100
var asset = buildStep.inputId;
92101
var name = nameOfPartial(
@@ -137,7 +146,7 @@ class _Builder extends Builder {
137146
stack);
138147
}
139148

140-
buildStep.writeAsString(outputId, '$_topHeader$genPartContent');
149+
buildStep.writeAsString(outputId, genPartContent);
141150
}
142151
}
143152

@@ -153,6 +162,10 @@ class PartBuilder extends _Builder {
153162
/// [formatOutput] is called to format the generated code. Defaults to
154163
/// [DartFormatter.format].
155164
///
165+
/// [header] is used to specify the content at the top of each generated file.
166+
/// If `null`, the content of [defaultFileHeader] is used.
167+
/// If [header] is an empty `String` no header is added.
168+
///
156169
/// May set [requireLibraryDirective] to `false` in order to opt-in to
157170
/// supporting a `1.25.0` feature of `part of` being usable without an
158171
/// explicit `library` directive. Developers should restrict their `pubspec`
@@ -164,12 +177,14 @@ class PartBuilder extends _Builder {
164177
{String formatOutput(String code),
165178
String generatedExtension: '.g.dart',
166179
List<String> additionalOutputExtensions: const [],
167-
bool requireLibraryDirective: true})
180+
bool requireLibraryDirective: true,
181+
String header})
168182
: super(generators,
169183
formatOutput: formatOutput,
170184
generatedExtension: generatedExtension,
171185
additionalOutputExtensions: additionalOutputExtensions,
172-
requireLibraryDirective: requireLibraryDirective);
186+
requireLibraryDirective: requireLibraryDirective,
187+
header: header);
173188
}
174189

175190
/// A [Builder] which generates Dart library files.
@@ -181,17 +196,22 @@ class LibraryBuilder extends _Builder {
181196
/// outputs through the [BuildStep] they should be indicated in
182197
/// [additionalOutputExtensions].
183198
///
199+
/// If `null`, the content of [defaultFileHeader] is used.
200+
/// If [header] is an empty `String` no header is added.
201+
///
184202
/// [formatOutput] is called to format the generated code. Defaults to
185203
/// [DartFormatter.format].
186204
LibraryBuilder(Generator generator,
187205
{String formatOutput(String code),
188206
String generatedExtension: '.g.dart',
189-
List<String> additionalOutputExtensions: const []})
207+
List<String> additionalOutputExtensions: const [],
208+
String header})
190209
: super([generator],
191210
formatOutput: formatOutput,
192211
generatedExtension: generatedExtension,
193212
additionalOutputExtensions: additionalOutputExtensions,
194-
isStandalone: true);
213+
isStandalone: true,
214+
header: header);
195215
}
196216

197217
Stream<GeneratedOutput> _generate(LibraryElement library,
@@ -215,7 +235,7 @@ Stream<GeneratedOutput> _generate(LibraryElement library,
215235

216236
final _formatter = new DartFormatter();
217237

218-
const _topHeader = '''// GENERATED CODE - DO NOT MODIFY BY HAND
238+
const defaultFileHeader = '''// GENERATED CODE - DO NOT MODIFY BY HAND
219239
220240
''';
221241

test/builder_test.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ void main() {
4040
});
4141
});
4242

43+
test('Generate standalone output file with custom header', () async {
44+
var srcs = _createPackageStub(pkgName);
45+
var builder =
46+
new LibraryBuilder(const CommentGenerator(), header: _customHeader);
47+
await testBuilder(builder, srcs,
48+
generateFor: new Set.from(['$pkgName|lib/test_lib.dart']),
49+
outputs: {
50+
'$pkgName|lib/test_lib.g.dart':
51+
startsWith(_customHeader + '\n\n// ***')
52+
});
53+
});
54+
55+
test('LibraryBuilder omits header if provided an empty String', () async {
56+
var srcs = _createPackageStub(pkgName);
57+
var builder = new LibraryBuilder(const CommentGenerator(), header: '');
58+
await testBuilder(builder, srcs,
59+
generateFor: new Set.from(['$pkgName|lib/test_lib.dart']),
60+
outputs: {'$pkgName|lib/test_lib.g.dart': startsWith('// ***')});
61+
});
62+
4363
test('Expect no error when multiple generators used on nonstandalone builder',
4464
() async {
4565
expect(
@@ -126,6 +146,27 @@ void main() {
126146
});
127147
});
128148

149+
test('PartBuilder uses a custom header when provided', () async {
150+
await testBuilder(
151+
new PartBuilder([new UnformattedCodeGenerator()],
152+
header: _customHeader),
153+
{'$pkgName|lib/a.dart': 'library a; part "a.part.dart";'},
154+
generateFor: new Set.from(['$pkgName|lib/a.dart']),
155+
outputs: {
156+
'$pkgName|lib/a.g.dart': startsWith(_customHeader + '\npart of'),
157+
});
158+
});
159+
160+
test('PartBuilder includes no header when `header` is empty', () async {
161+
await testBuilder(
162+
new PartBuilder([new UnformattedCodeGenerator()], header: ''),
163+
{'$pkgName|lib/a.dart': 'library a; part "a.part.dart";'},
164+
generateFor: new Set.from(['$pkgName|lib/a.dart']),
165+
outputs: {
166+
'$pkgName|lib/a.g.dart': startsWith('part of'),
167+
});
168+
});
169+
129170
test('can skip formatting with a trivial lambda', () async {
130171
await testBuilder(
131172
new PartBuilder([new UnformattedCodeGenerator()],
@@ -200,6 +241,8 @@ class _ThrowingGenerator extends Generator {
200241
Future<String> generate(_, __) async => throw new UnimplementedError();
201242
}
202243

244+
final _customHeader = '// Copyright 1979';
245+
203246
const pkgName = 'pkg';
204247

205248
const _testLibContent = r'''

0 commit comments

Comments
 (0)