Skip to content

Commit c94cb89

Browse files
jakemac53kevmoo
authored andcommitted
Migrate to the build package instead of custom build scripts
1 parent ea601b9 commit c94cb89

33 files changed

+605
-1158
lines changed

.gitignore

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
.buildlog
2-
pubspec.lock
3-
packages
4-
.pub
1+
.dart_tool
52
.packages
3+
.pub
4+
packages
5+
pubspec.lock

CHANGELOG.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
## 0.5.0
2+
3+
* **Breaking**: Switch to the `build` package for running `Generator`s. This
4+
means that the top level `build` and `generate` functions are no longer
5+
available, and have been replaced by the top level `build`, `watch`, and
6+
`serve` functions from the `build` package, and the `GeneratorBuilder` class.
7+
See `tool/build.dart`, `tool/watch.dart`, and `tool/phases.dart` for usage.
8+
9+
* Note that the `build` package is experimental, and likely to change.
10+
11+
* **Breaking**: The build package provides an abstraction for reading/writing
12+
files via the `BuildStep` class, and that is now also provided to
13+
`Generator#generate` and `GeneratorForAnnotation#generateForAnnotatedElement`
14+
as a second argument.
15+
16+
* There is no longer a need to specify the files related to an individual
17+
generator via `AssociatedFileSet`. Simply use the `BuildStep` instance to read
18+
and write files and the `build` package will track any files you read in and
19+
run incremental rebuilds as necessary.
20+
121
## 0.4.8
222

323
* Added support for `Symbol` and `Type` in annotations.
@@ -18,7 +38,7 @@
1838

1939
## 0.4.6
2040

21-
* `JsonSerializable`: Added `JsonKey` annotation.
41+
* `JsonSerializable`: Added `JsonKey` annotation.
2242

2343
* Improved output of generation errors and stack traces.
2444

build.dart

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
11
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
4-
54
library source_gen.build_file;
65

7-
import 'package:source_gen/generators/json_literal_generator.dart' as literal;
8-
import 'package:source_gen/generators/json_serializable_generator.dart' as json;
9-
import 'package:source_gen/source_gen.dart';
6+
import 'tool/build.dart' as build;
107

11-
main(List<String> args) async {
12-
var msg = await build(args, const [
13-
const json.JsonSerializableGenerator(),
14-
const literal.JsonLiteralGenerator()
15-
], librarySearchPaths: [
16-
'example',
17-
'test/test_files/json_test_example.dart'
18-
]);
19-
print(msg);
8+
main() async {
9+
build.main();
2010
}

example/example.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/builder.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
export 'src/builder.dart';

lib/generators/json_literal_generator.dart

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,28 @@ library source_gen.example.json_literal_generator;
66

77
import 'dart:async';
88
import 'dart:convert';
9-
import 'dart:io';
109

1110
import 'package:analyzer/src/generated/element.dart';
12-
import 'package:analyzer/src/generated/source_io.dart';
11+
import 'package:build/build.dart';
1312
import 'package:path/path.dart' as p;
1413
import 'package:source_gen/source_gen.dart';
1514

1615
import 'json_literal.dart';
1716

1817
class JsonLiteralGenerator extends GeneratorForAnnotation<JsonLiteral> {
19-
@override
20-
final AssociatedFileSet associatedFileSet;
21-
22-
/// If [associatedFileSet] is not set, the default value of
23-
/// [AssociatedFileSet.sameDirectory] is used.
24-
const JsonLiteralGenerator(
25-
{AssociatedFileSet associatedFileSet: AssociatedFileSet.sameDirectory})
26-
: this.associatedFileSet = associatedFileSet;
18+
const JsonLiteralGenerator();
2719

2820
@override
2921
Future<String> generateForAnnotatedElement(
30-
Element element, JsonLiteral annotation) async {
22+
Element element, JsonLiteral annotation, BuildStep buildStep) async {
3123
if (p.isAbsolute(annotation.path)) {
3224
throw 'must be relative path to the source file';
3325
}
3426

35-
var source = element.source as FileBasedSource;
36-
var sourcePath = source.file.getAbsolutePath();
37-
38-
var sourcePathDir = p.dirname(sourcePath);
39-
40-
var filePath = p.join(sourcePathDir, annotation.path);
41-
42-
if (!await FileSystemEntity.isFile(filePath)) {
43-
throw 'Not a file! - $filePath';
44-
}
45-
46-
var file = new File(filePath);
47-
var content = await JSON.decode(await file.readAsString());
27+
var sourcePathDir = p.dirname(buildStep.input.id.path);
28+
var fileId = new AssetId(
29+
buildStep.input.id.package, p.join(sourcePathDir, annotation.path));
30+
var content = JSON.decode(await buildStep.readAsString(fileId));
4831

4932
var thing = JSON.encode(content);
5033

lib/generators/json_serializable_generator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class JsonSerializableGenerator
2121

2222
@override
2323
Future<String> generateForAnnotatedElement(
24-
Element element, JsonSerializable annotation) async {
24+
Element element, JsonSerializable annotation, _) async {
2525
if (element is! ClassElement) {
2626
var friendlyName = friendlyNameForElement(element);
2727
throw new InvalidGenerationSourceError(

lib/source_gen.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
library source_gen;
22

3-
export 'src/build.dart';
4-
export 'src/generate.dart';
3+
export 'src/builder.dart';
54
export 'src/results.dart';
65
export 'src/generator.dart';
76
export 'src/generator_for_annotation.dart';

lib/src/build.dart

Lines changed: 0 additions & 101 deletions
This file was deleted.

lib/src/builder.dart

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
import 'dart:async';
5+
6+
import 'package:analyzer/src/generated/element.dart';
7+
import 'package:build/build.dart';
8+
import 'package:dart_style/src/dart_formatter.dart';
9+
10+
import 'generated_output.dart';
11+
import 'generator.dart';
12+
import 'utils.dart';
13+
14+
class GeneratorBuilder extends Builder {
15+
final List<Generator> generators;
16+
final bool omitGenerateTimestamp;
17+
final String generatedExtension;
18+
19+
GeneratorBuilder(this.generators,
20+
{this.omitGenerateTimestamp: false, this.generatedExtension: '.g.dart'}) {
21+
// TODO: validate that generatedExtension starts with a `.'
22+
// not null, empty, etc
23+
}
24+
25+
@override
26+
Future build(BuildStep buildStep) async {
27+
var id = buildStep.input.id;
28+
var resolver = await buildStep.resolve(id, resolveAllConstants: false);
29+
var lib = resolver.getLibrary(id);
30+
await _generateForLibrary(lib, !omitGenerateTimestamp, buildStep);
31+
resolver.release();
32+
}
33+
34+
@override
35+
List<AssetId> declareOutputs(AssetId input) {
36+
if (input.extension != '.dart') return const [];
37+
return [_generatedFile(input)];
38+
}
39+
40+
AssetId _generatedFile(AssetId input) =>
41+
input.changeExtension(generatedExtension);
42+
43+
Future _generateForLibrary(LibraryElement library, bool includeTimestamp,
44+
BuildStep buildStep) async {
45+
buildStep.logger.fine('Running $generators for ${buildStep.input.id}');
46+
var generatedOutputs =
47+
await _generate(library, generators, buildStep).toList();
48+
49+
// Don't outputs useless files.
50+
if (generatedOutputs.isEmpty) return;
51+
52+
var contentBuffer = new StringBuffer();
53+
54+
contentBuffer.writeln('part of ${library.name};');
55+
contentBuffer.writeln();
56+
57+
for (GeneratedOutput output in generatedOutputs) {
58+
contentBuffer.writeln('');
59+
contentBuffer.writeln(_headerLine);
60+
contentBuffer.writeln('// Generator: ${output.generator}');
61+
contentBuffer
62+
.writeln('// Target: ${friendlyNameForElement(output.sourceMember)}');
63+
contentBuffer.writeln(_headerLine);
64+
contentBuffer.writeln('');
65+
66+
contentBuffer.writeln(output.output);
67+
}
68+
69+
var genPartContent = contentBuffer.toString();
70+
71+
var formatter = new DartFormatter();
72+
try {
73+
genPartContent = formatter.format(genPartContent);
74+
} catch (e, stack) {
75+
buildStep.logger.severe(
76+
"""Error formatting the generated source code.
77+
This may indicate an issue in the generated code or in the formatter.
78+
Please check the generated code and file an issue on source_gen
79+
if approppriate.""",
80+
e,
81+
stack);
82+
}
83+
84+
var outputId = _generatedFile(buildStep.input.id);
85+
var output =
86+
new Asset(outputId, '${_getHeader(includeTimestamp)}$genPartContent');
87+
buildStep.writeAsString(output);
88+
}
89+
90+
String _getHeader(bool includeTimestamp) {
91+
var buffer = new StringBuffer('// GENERATED CODE - DO NOT MODIFY BY HAND');
92+
buffer.writeln();
93+
94+
if (includeTimestamp) {
95+
buffer.writeln("// ${new DateTime.now().toUtc().toIso8601String()}");
96+
}
97+
98+
buffer.writeln();
99+
return buffer.toString();
100+
}
101+
}
102+
103+
Stream<GeneratedOutput> _generate(LibraryElement unit,
104+
List<Generator> generators, BuildStep buildStep) async* {
105+
for (var element in getElementsFromLibraryElement(unit)) {
106+
yield* _processUnitMember(element, generators, buildStep);
107+
}
108+
}
109+
110+
Stream<GeneratedOutput> _processUnitMember(
111+
Element element, List<Generator> generators, BuildStep buildStep) async* {
112+
for (var gen in generators) {
113+
try {
114+
buildStep.logger.finer('Running $gen for $element');
115+
var createdUnit = await gen.generate(element, buildStep);
116+
117+
if (createdUnit != null) {
118+
buildStep.logger.finest(() => 'Generated $createdUnit for $element');
119+
yield new GeneratedOutput(element, gen, createdUnit);
120+
}
121+
} catch (e, stack) {
122+
buildStep.logger.severe('Error running $gen for $element.', e, stack);
123+
yield new GeneratedOutput.fromError(element, gen, e, stack);
124+
}
125+
}
126+
}
127+
128+
final _headerLine = '// '.padRight(77, '*');

0 commit comments

Comments
 (0)