execute method
Executes the generation logic and returns the exit code. Does NOT call exit().
Implementation
Future<int> execute() async {
final failOnWarn = argResults!['fail-on-warn'] as bool;
final dryRun = argResults!['dry-run'] as bool;
final check = argResults!['check'] as bool;
final targets = _parseTargets(argResults!['targets'] as String?);
if (targets == null) return 1;
final startDir = argResults!['directory'] as String?;
final projectDir = findNitroProjectRoot(startDir: startDir);
if (projectDir == null) {
_logError('No Nitro project found in . or its subdirectories (must have nitro dependency in pubspec.yaml).');
return 1;
}
_printGenerateHeader(projectDir);
if (dryRun) {
_printDryRunPlan(projectDir.path, targets);
return 0;
}
if (check) {
return _checkGeneratedFiles(projectDir.path, targets);
}
final totalStart = DateTime.now();
final specFiles = _discoverNativeSpecFiles(projectDir.path);
final incrementalCache = IncrementalGenerationCache(projectDir.path);
final incrementalPlan = incrementalCache.plan(
specs: specFiles,
outputPathsForSpec: (spec) => _generatedOutputsForSpec(projectDir.path, spec, targets),
);
if (!incrementalPlan.hasChanges) {
_printNoChanges();
_logTiming('total', DateTime.now().difference(totalStart));
return 0;
}
// ── pub get ─────────────────────────────────────────────────────────────
final pubGetExit = await _runPubGet(projectDir.path);
if (pubGetExit != null) return pubGetExit;
// ── build_runner ─────────────────────────────────────────────────────────
await _prepareBuildRunner(projectDir.path);
final buildExit = await _runBuildRunner(projectDir.path, targets, incrementalPlan, failOnWarn);
if (buildExit != null) return buildExit;
incrementalCache.write(
specs: specFiles,
outputPathsForSpec: (spec) => _generatedOutputsForSpec(projectDir.path, spec, targets),
);
// ── Post-generation bridge cleanup ───────────────────────────────────────
// Generated Swift bridges live in lib/src/generated/swift/ and are compiled
// via the podspec source_files pattern. Remove any stale copies from Classes/
// to prevent "Invalid redeclaration" Swift compiler errors.
if (targets.isDartOnly) {
_logTiming('total', DateTime.now().difference(totalStart));
_printGenerationComplete();
return 0;
}
_runLinkPhase(projectDir.path);
// ── pod install ──────────────────────────────────────────────────────────
await _runPodInstall(projectDir.path);
// Detect whether any spec uses NativeImpl.cpp to tailor the next-steps hint
final libDir = Directory(p.join(projectDir.path, 'lib'));
final hasCppModules = libDir.existsSync() && libDir.listSync(recursive: true).whereType<File>().where((f) => f.path.endsWith('.native.dart')).any(isCppModule);
_logTiming('total', DateTime.now().difference(totalStart));
_reportSuccess(projectDir.path, hasCppModules);
return 0;
}