build method
Generates the outputs for a given BuildStep.
Implementation
@override
Future<void> build(BuildStep buildStep) async {
final inputId = buildStep.inputId;
final content = await buildStep.readAsString(inputId);
AutoInteropConfig config;
try {
config = _configParser.parseYaml(content);
} on ConfigParseException catch (e) {
log.warning('Error parsing auto_interop.yaml: $e');
return;
}
if (config.packages.isEmpty) {
log.info('No packages in auto_interop.yaml');
return;
}
final loader = await _createLoader();
final overrideLoader = OverrideLoader(
projectDir: config.overridesDir ?? 'auto_interop_overrides',
);
// Collect all per-package code and track additional imports needed
final imports = <String>{
"import 'package:auto_interop/auto_interop.dart';"
};
final codeSections = <String>[];
for (final spec in config.packages) {
// Check overrides first (project then global), then fall back to loader
final overrideResult = overrideLoader.load(
spec.package,
source: spec.source.name,
version: spec.version,
);
final schema =
overrideResult?.schema ?? loader.loadForPackage(spec.package);
if (schema == null) {
log.warning('No pre-built type definition for ${spec.package}. '
'Run the CLI to parse and generate definitions first.');
continue;
}
// Run analyzer before generating
final analysisResult = const ApiSurfaceAnalyzer().analyze(schema);
for (final d in analysisResult.diagnostics) {
if (d.isError) {
log.severe('[${spec.package}] $d');
} else {
log.warning('[${spec.package}] $d');
}
}
if (analysisResult.hasErrors) {
log.severe('Skipping ${spec.package} due to analysis errors');
continue;
}
final files = _dartGen.generate(schema);
for (final entry in files.entries) {
// Strip the header and imports from individual files; hoist imports
var code = entry.value;
code = code.replaceFirst(RegExp(r'// GENERATED CODE.*\n'), '');
code = code.replaceFirst(RegExp(r'// Generated by.*\n'), '');
// Extract and hoist all import lines
final importPattern = RegExp(r"import '[^']+';[ ]*\n");
for (final match in importPattern.allMatches(code)) {
imports.add(match.group(0)!.trim());
}
code = code.replaceAll(importPattern, '');
code = code.trim();
codeSections.add('// --- ${spec.package} ---\n$code');
}
}
// Assemble final output with all imports at the top
final buffer = StringBuffer();
buffer.writeln('// GENERATED CODE — DO NOT EDIT');
buffer.writeln('// Generated by auto_interop_generator via build_runner');
buffer.writeln();
// Only emit imports when there is generated code to avoid unused_import
final sortedImports = imports.toList()..sort();
if (codeSections.isNotEmpty) {
for (final imp in sortedImports) {
buffer.writeln(imp);
}
}
buffer.writeln();
for (final section in codeSections) {
buffer.writeln(section);
buffer.writeln();
}
await buildStep.writeAsString(
AssetId(inputId.package, 'lib/generated/auto_interop_bindings.dart'),
buffer.toString(),
);
}