generateScreenBindings function
Future<void>
generateScreenBindings(
- List<String> args, {
- List<String> defaultTemplates = const ['https://raw.githubusercontent.com/dev-cetera/df_generate_screen/main/templates/v2/_bindings.g.dart.md'],
})
Implementation
Future<void> generateScreenBindings(
List<String> args, {
List<String> defaultTemplates = const [
'https://raw.githubusercontent.com/dev-cetera/df_generate_screen/main/templates/v2/_bindings.g.dart.md',
],
}) async {
Log.enableReleaseAsserts = true;
final parser = CliParser(
title: 'dev-cetera.com',
description:
'A tool for generating screen bindings for classes annotated @GenerateScreenBindings.',
example: 'df_generate_screen_bindings -i .',
additional:
'For contributions, error reports and information, visit: https://github.com/dev-cetera.',
params: [
DefaultFlags.HELP.flag,
DefaultOptionParams.INPUT_PATH.option.copyWith(
defaultsTo: FileSystemUtility.i.currentDir,
),
DefaultMultiOptions.TEMPLATES.multiOption.copyWith(
defaultsTo: defaultTemplates,
),
DefaultOptionParams.DART_SDK.option,
],
);
// ---------------------------------------------------------------------------
final (argResults, argParser) = parser.parse(args);
// ---------------------------------------------------------------------------
final help = argResults.flag(DefaultFlags.HELP.name);
if (help) {
Log.printCyan(parser.getInfo(argParser));
exit(ExitCodes.SUCCESS.code);
}
// ---------------------------------------------------------------------------
late final String inputPath;
late final List<String> templates;
late final String? dartSdk;
try {
inputPath = argResults.option(DefaultOptionParams.INPUT_PATH.name)!;
templates = argResults.multiOption(DefaultMultiOptions.TEMPLATES.name);
dartSdk = argResults.option(DefaultOptionParams.DART_SDK.name);
} catch (_) {
Log.printRed(
'Missing required args! Use --help flag for more information.',
);
exit(ExitCodes.FAILURE.code);
}
// ---------------------------------------------------------------------------
final analysisContextCollection = createDartAnalysisContextCollection(
{inputPath},
dartSdk, //
);
// ---------------------------------------------------------------------------
Log.printWhite('Looking for Dart files..');
final filePathStream0 = PathExplorer(inputPath).exploreFiles();
final filePathStream1 = filePathStream0.where(
(e) => _isAllowedFileName(e.path),
);
List<FilePathExplorerFinding> findings;
try {
findings = await filePathStream1.toList();
} catch (e) {
Log.printRed('Failed to read file tree!');
exit(ExitCodes.FAILURE.code);
}
if (findings.isEmpty) {
Log.printYellow('No files found in $inputPath!');
exit(ExitCodes.SUCCESS.code);
}
// ---------------------------------------------------------------------------
final templateData = <String, String>{};
for (final template in templates) {
Log.printWhite('Reading template at: $template...');
final result =
await MdTemplateUtility.i.readTemplateFromPathOrUrl(template).value;
if (result.isErr()) {
Log.printRed(' Failed to read template!');
exit(ExitCodes.FAILURE.code);
}
templateData[template] = result.unwrap();
}
// ---------------------------------------------------------------------------
Log.printWhite('Generating...');
for (final entry in templateData.entries) {
final fileName = p.basename(entry.key).replaceAll('.md', '');
final template = entry.value;
// Tracks which output paths have already been written this run so we can
// refuse to silently overwrite when two annotated classes in the same
// directory would map to the same generated file — the previous code
// would drop all but the last insight's output without warning.
final writtenOutputPaths = <String>{};
try {
for (final finding in findings) {
final inputFilePath = finding.path;
final insights = await extractInsightsFromFile(
inputFilePath,
analysisContextCollection,
);
for (final insight in insights) {
final output = _interpolator.interpolate(template, insight);
final outputFilePath = p.join(
PathUtility.i.localDirName(inputFilePath),
fileName,
);
if (!writtenOutputPaths.add(outputFilePath)) {
Log.printRed(
'✘ Collision: `${insight.className}` would overwrite '
'$outputFilePath produced earlier in this run. Move '
'`${insight.className}` to its own directory or use a '
'distinct template per class. Skipping this insight.',
);
continue;
}
await FileSystemUtility.i.writeLocalFile(outputFilePath, output);
Log.printWhite('✔ Generated $fileName');
}
}
} catch (e) {
Log.printRed('✘ One or more files failed to generate: $e');
exit(ExitCodes.FAILURE.code);
}
}
// ---------------------------------------------------------------------------
Log.printWhite('Fixing generated files..');
await fixDartFile(inputPath);
Log.printWhite('Formatting generated files..');
await fmtDartFile(inputPath);
// ---------------------------------------------------------------------------
Log.printGreen('Done!');
}