From 2d08de6b7202ebf2b3d2462423ef2702ce7d9329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Beffa?= Date: Thu, 12 Jun 2025 21:43:27 +0200 Subject: [PATCH] feat: Add build_runner builder --- README.md | 14 ++++++ build.yaml | 15 +++++- example/index_generator.yaml | 24 +++++----- example/pubspec.yaml | 7 ++- lib/index_generator.dart | 1 + lib/src/builder.dart | 90 ++++++++++++++++++++++++++++++++++++ pubspec.yaml | 8 ++-- 7 files changed, 141 insertions(+), 18 deletions(-) create mode 100644 lib/src/builder.dart diff --git a/README.md b/README.md index b1878b7..ca3596a 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,20 @@ index_generator: -h, --help ``` +## Build runner + +`index_generator` can be run via [build_runner](https://pub.dev/packages/build_runner). To do so, add the following dependancies: + +```yaml +dev_dependencies: + build_runner: ^2.3.3 + index_generator: ^3.5.0 +``` + +To generate use ` pub run build_runner ` + + + ## Features and bugs Please file feature requests and bugs at the [issue tracker](https://github.com/BreX900/index_generator/issues). diff --git a/build.yaml b/build.yaml index 4b6322a..bb1b297 100644 --- a/build.yaml +++ b/build.yaml @@ -1,7 +1,9 @@ targets: $default: + auto_apply_builders: false builders: json_serializable: + enabled: false options: # Options configure how source code is generated for every # `@JsonSerializable`-annotated class in the package. @@ -16,4 +18,15 @@ targets: field_rename: snake generic_argument_factories: false ignore_unannotated: false - include_if_null: true \ No newline at end of file + include_if_null: true + index_generator: + enabled: true + +builders: + index_generator: + import: "package:index_generator/src/builder.dart" + builder_factories: ["indexGeneratorBuilder"] + build_extensions: { '$package$': ['.dart'] } + auto_apply: root_package + build_to: source + required_inputs: ['.gen.dart'] \ No newline at end of file diff --git a/example/index_generator.yaml b/example/index_generator.yaml index 2c97685..b2203f3 100644 --- a/example/index_generator.yaml +++ b/example/index_generator.yaml @@ -1,18 +1,18 @@ index_generator: page_width: 100 exclude: - - '**.g.dart' - - '{_,**/_}*.dart' - indexes: + - "**.g.dart" + - "{_,**/_}*.dart" + libraries: # Default index and library name - - path: lib + - directory_path: lib # Custom index and library name - - path: lib - name: custom_index_name - library: custom_library_name + - directory_path: lib + file_name: custom_index_name + name: custom_library_name # Custom index and library name - - path: lib - name: export_folders + - directory_path: lib + file_name: export_folders include: - src/** exports: @@ -25,11 +25,11 @@ index_generator: - basenameWithoutExtension - canonicalize - withoutExtension - - path: lib - name: docs + - directory_path: lib + file_name: docs disclaimer: false comments: This is a comments. docs: | This is - + a docs. diff --git a/example/pubspec.yaml b/example/pubspec.yaml index a50a0d2..ac400a5 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -9,4 +9,9 @@ scripts: dependencies: args: - path: \ No newline at end of file + path: + +dev_dependencies: + build_runner: ^2.3.3 + index_generator: + path: ../ diff --git a/lib/index_generator.dart b/lib/index_generator.dart index 2f8c74b..55174a5 100644 --- a/lib/index_generator.dart +++ b/lib/index_generator.dart @@ -2,6 +2,7 @@ /// with all the export needed for your library. library index_generator; +export 'src/builder.dart'; export 'src/converters.dart'; export 'src/dart_code/dart_export.dart'; export 'src/index_generator.dart'; diff --git a/lib/src/builder.dart b/lib/src/builder.dart new file mode 100644 index 0000000..5952b1f --- /dev/null +++ b/lib/src/builder.dart @@ -0,0 +1,90 @@ +// ignore_for_file: depend_on_referenced_packages +import 'dart:io'; + +import 'package:build/build.dart'; +import 'package:glob/glob.dart'; +import 'package:path/path.dart' as p; +import 'package:index_generator/src/settings/library_settings.dart'; +import 'package:index_generator/src/settings/package_settings.dart'; +import 'package:index_generator/src/index_generator.dart'; +import 'package:yaml/yaml.dart'; +import 'package:checked_yaml/checked_yaml.dart'; +import 'package:dart_style/dart_style.dart'; +import 'package:args/args.dart'; +import 'package:console/console.dart'; +import 'package:index_generator/src/settings/dart.dart'; + +Builder indexGeneratorBuilder(BuilderOptions options) { + final toolBox = ToolBoxSync(name: 'index_generator'); + final project = ToolBoxSync.loadYaml(toolBox.projectYaml, Pubspec.fromJson); + final settingsFile = toolBox.findYaml(null); + final settings = ToolBoxSync.loadYaml(settingsFile, PackageSettings.fromYaml); + return IndexGeneratorBuilder(project, settings); +} + +class IndexGeneratorBuilder implements Builder { + IndexGeneratorBuilder(Pubspec project, this.package) { + generators = package.libraries.map((library) { + return IndexGenerator.from(project, null, package, library); + }).toList(); + } + late final List generators; + final PackageSettings package; + + static AssetId _createFileOutput(BuildStep buildStep, String filePath) { + return AssetId( + buildStep.inputId.package, + filePath, + ); + } + + @override + Map> get buildExtensions { + return { + r'$package$': generators.map((g) => g.indexFile.path).toList(), + }; + } + + @override + Future build(BuildStep buildStep) async { + final formatter = DartFormatter( + languageVersion: DartFormatter.latestLanguageVersion, + lineEnding: package.lineBreak, + pageWidth: package.pageWidth, + ); + for (var generator in generators) { + final content = formatter.format(generator.generate().join(package.lineBreak)); + final output = _createFileOutput(buildStep, generator.indexFile.path); + buildStep.writeAsString(output, content); + } + } +} + +class ToolBoxSync { + ToolBoxSync({required String name}) : packageYaml = File('$name.yaml'); + final File projectYaml = File('pubspec.yaml'); + final File packageYaml; + + File findYaml(String? path) { + if (path != null) return File(path); + + if (packageYaml.existsSync()) return packageYaml; + + return projectYaml; + } + + static T loadYaml(File file, T Function(Map map) from) { + if (!file.existsSync()) { + throw Exception('Not find ${file.path} file in this project'); + } + try { + return checkedYamlDecode( + file.readAsStringSync(), + (map) => from(map!), + sourceUrl: Uri.file(file.path), + ); + } on ParsedYamlException catch (error) { + throw Exception(error.formattedMessage!); + } + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 213dab9..fa9c405 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,14 +27,14 @@ dependencies: yaml: ^3.1.1 checked_yaml: ^2.0.1 mek_data_class: ^1.0.1 - json_annotation: ^4.8.0 + json_annotation: ^4.8.1 glob: ^2.1.0 dart_style: ^3.0.0 pub_semver: ^2.0.0 dev_dependencies: - lints: ^2.0.0 + lints: ^3.0.0 test: ^1.21.6 @@ -47,8 +47,8 @@ executables: index_generator: exclude: - - '**.g.dart' - - '{_,**/_}*.dart' + - "**.g.dart" + - "{_,**/_}*.dart" indexes: - path: lib disclaimer: false