{"id":18521800,"url":"https://github.com/simphotonics/merging_builder","last_synced_at":"2025-10-31T14:05:14.115Z","repository":{"id":56834621,"uuid":"265525364","full_name":"simphotonics/merging_builder","owner":"simphotonics","description":"Dart builder that reads several input files and writes the merged output to one file.  ","archived":false,"fork":false,"pushed_at":"2025-01-21T15:45:58.000Z","size":203,"stargazers_count":8,"open_issues_count":0,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-10T03:39:33.097Z","etag":null,"topics":["build-tool","builder","dart","generator","merging","output","source-code-generator","synthetic"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/merging_builder","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simphotonics.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-20T10:07:45.000Z","updated_at":"2025-01-21T15:53:47.000Z","dependencies_parsed_at":"2024-11-06T17:35:41.886Z","dependency_job_id":"ce3515a0-3d6a-4cd8-b7a7-deae02c1a945","html_url":"https://github.com/simphotonics/merging_builder","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/simphotonics/merging_builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fmerging_builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fmerging_builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fmerging_builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fmerging_builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simphotonics","download_url":"https://codeload.github.com/simphotonics/merging_builder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simphotonics%2Fmerging_builder/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265505587,"owners_count":23778540,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["build-tool","builder","dart","generator","merging","output","source-code-generator","synthetic"],"created_at":"2024-11-06T17:27:40.673Z","updated_at":"2025-10-31T14:05:14.109Z","avatar_url":"https://github.com/simphotonics.png","language":"Dart","readme":"\n# Merging Builder\n\n[![Dart](https://github.com/simphotonics/merging_builder/actions/workflows/dart.yml/badge.svg)](https://github.com/simphotonics/merging_builder/actions/workflows/dart.yml)\n\n## Introduction\n\nSource code generation has become an important software development tool\nwhen building and maintaining a large number of data models,\ndata access object, widgets, etc. The premise of *source code generation* is that we can specify\n(hopefully few) details and flesh out the rest of the classes,\nand methods during the build process.\n\nThe library [`merging_builder`][merging_builder] includes the following (synthetic input) builder classes:\n\n* [`MergingBuilder`][class-merging-builder] reads *several input files* and writes\nmerged output to *one output file* to a custom location.\n\n* [`StandaloneBuilder`][StandaloneBuilder] reads one or several input files and\nwrites standalone files to a custom location. In this context, *standalone*\nmeans the output files may be written to a *custom folder* and\nnot only the *extension* but the *name* of the output file can\nbe configured (as opposed to using part files).\n\n\n## Usage\n\nFollowing the example of [`source_gen`][source_gen], it is common practice to\nseparate *builders* and *generators* from the code using those builders.\n\nIn the [example] project provided, the package defining a new\nbuilder is called `researcher_builder` and the package using this builder is called `researcher`.\nTo set up a build system the following steps are required:\n\n### 1. Builder Package Setup\n\n1. Get dependencies: Include [`merging_builder`][merging_builder], [`build`][build] as *dependencies* in the file `pubspec.yaml`. In the [example] mentioned here, the generator also requires the packages [`analyzer`][analyzer] and [`source_gen`][source_gen].\n\n2. Create a generator: Create a custom generator that extends [`MergingGenerator`][MergingGenerator]. In [example] `generateItemForAnnotatedElement` reads a list of strings while `generateMergedContent` merges the data and generates output that is written to [researchers.dart].\n\n3. Create a builder: Create an instance of [`MergingBuilder`][MergingBuilder]. Following the example of [`source_gen`][source_gen], builders are typically placed in a file called: `builder.dart` located in the `lib` folder of the builder package.\n   * Input sources may be specified using wildcard characters supported by [`Glob`][Glob].\n   * The builder definition includes the default values of the *options* `input_files`, `output_file`, `header`, `footer`, and `sort_assets`. These options can be overwritten by the user of the builder by specifying them explicitly in the file `build.yaml`  located  in the package `researcher` (see step 1 in section [User Package Setup](#1-builder-package-setup)).\n\n4. Add a builder configuration:  The build extensions for\n[`MergingBuilder`][MergingBuilder] must be specified using the notation\navailable for *synthetic input*. For example, `\"$lib$\"` indicates that the\ninput files are located in the folder `lib` or a subfolder thereof.\n    ```Yaml\n    builders:\n      add_names_builder:\n        import: \"package:researcher_builder/builder.dart\"\n        builder_factories: [\"addNamesBuilder\"]\n        build_extensions: {\"lib/$lib$\": [\"lib/output.dart\"]}\n        auto_apply: root_package\n        build_to: source\n      assistant_builder:\n        import: \"package:researcher_builder/builder.dart\"\n        builder_factories: [\"assistantBuilder\"]\n        build_extensions: {\"lib/$lib$\": [\"*.dart\"]}\n        auto_apply: root_package\n        build_to: source\n    ```\n\n### 2. User Package Setup\n\nThe following steps are performed in the package that is using the custom builder:\n\n1. Add dependencies: Add the custom builder package and\n[`build_runner`][build_runner] as a *dev_dependencies* in the file `pubspec.yaml`.\n\n2. Builder configuration: Add the builder to the list of known builders\nand configure the available options (thus overwriting the default values).\nA sample `build.yaml` file is shown below.\n\n    ```Yaml\n     targets:\n       $default:\n         builders:\n           # Configure the builder `pkg_name|builder_name`\n           researcher_builder|add_names_builder:\n             # Only run this builder on the specified input.\n             enabled: true\n             # generate_for:\n             #   - lib/*.dart\n             options:\n               input_files: 'lib/input/*.dart'\n               output_file: 'lib/output/researchers.dart'\n               sort_assets: false\n               header: '// Header specified in build.yaml.'\n               footer: '// Footer specified in build.yaml.'\n           researcher_builder|assistant_builder:\n             enabled: true\n             options:\n               input_files: 'lib/input/*.dart'\n               output_files: 'lib/output/assistant_(*).dart'\n               root: ''\n    ```\n\n3. Initiate the build process by using the command:\n   ```console\n   # dart run build_runner build --delete-conflicting-outputs --verbose\n   ```\n\n# Merging Builder\n\n[`MergingBuilder`][MergingBuilder] reads *several input files* and writes merged output to *one output file*.\nThe builder provides the option to sort the input files in reverse topological order.\nIf the input file `a.dart` includes file `b.dart` then `a.dart` will be listed *after* `b.dart`. This option may be useful when\ngenerating code that needs to list variables or call functions in order of dependence.\nTo enable topological sorting set the constructor parameter `sortAsset: true`. Note: If sorting of input assets is enabled, input files must not include each other directly or indirectly.\n\nA conventional builder typically calls the generator method `generate` from within\nits `build` method to retrieve the generated source-code. [`MergingBuilder`][MergingBuilder]\ncalls the [`MergingGenerator`][MergingGenerator] method `generateStream`.\nIt allows the generator to pass a stream of data-type `T` to the builder,\none stream item for each annotated element processed to the generator method `generateStreamItemForAnnotatedElement`.\n\nThe private builder method `_combineStreams` combines the streams received for each processed input file and calls the generator method `generateMergedContent`.\nAs a result, this method has access to all stream items of type `T` generated f\nor each element annotated with an annotation of type `A` in each input file.\nIt is the task of this method to generate the *merged* source-code output.\n\nThe figure below shows the flow of data between the builder and the generator.\nThe data type is indicated by the starting point of the connectors. Dotted connectors represent a stream of data.\n\n![Directed Graph Image](https://raw.githubusercontent.com/simphotonics/merging_builder/master/images/merging_builder.svg?sanitize=true)\n\n## Standalone Builder\n\n[`StandaloneBuilder`][StandaloneBuilder] reads input files and writes\ncorresponding output files to a custom location.\n\nThe input file path (constructor parameter `inputFiles`) may include\nwild-card notation supported by [`Glob`][Glob].\n\nOutput files are specified by using the custom symbol\n`(*)`. For example, the output path `output\\assistant_(*).dart` is interpreted such that `(*)` is replaced with the input file name (excluding the file extension). For more details, see the file [`example\\researcher_builder\\builder.dart`][builder.dart].\n\nLimitations: For builders extending [`StandaloneBuilder`][StandaloneBuilder] it is recommended to initiate the build command\nfrom the root directory of the package the build is applied to.\n\n## Examples\n\nFor further information on how to use [`MergingBuilder`][MergingBuilder] see [example].\n\n## Features and bugs\n\nPlease file feature requests and bugs at the [issue tracker].\n\n[issue tracker]: https://github.com/simphotonics/merging_builder/issues\n\n[analyzer]: https://pub.dev/packages/analyzer\n\n[build]: https://pub.dev/packages/build\n\n[build_runner]: https://pub.dev/packages/build_runner\n\n[builder.dart]: https://github.com/simphotonics/merging_builder_example/blob/researcher_builder/lib/builder.dart\n\n[Elements]: https://pub.dev/documentation/analyzer/latest/dart_element_element/dart_element_element-library.html\n\n[computeConstantValue()]: https://pub.dev/documentation/analyzer/latest/dart_element_element/VariableElement/computeConstantValue.html\n\n[ConstantReader]: https://pub.dev/documentation/source_gen/latest/source_gen/ConstantReader-class.html\n\n[class-merging-builder]: https://github.com/simphotonics/merging_builder#class-merging-builder\n\n[class-standalone-builder]: https://github.com/simphotonics/merging_builder#class-standalone-builder\n\n[example]: https://github.com/simphotonics/merging_builder_example\n\n[DartObject]: https://pub.dev/documentation/analyzer/latest/dart_constant_value/DartObject-class.html\n\n[Generator]: https://pub.dev/documentation/source_gen/latest/source_gen/Generator-class.html\n\n[GeneratorForAnnotation]: https://pub.dev/documentation/source_gen/latest/source_gen/GeneratorForAnnotation-class.html\n\n[Glob]: https://pub.dev/packages/glob\n\n[MergingBuilder]: https://pub.dev/documentation/merging_builder/latest/merging_builder/MergingBuilder-class.html\n\n[merging_builder]: https://pub.dev/packages/merging_builder\n\n[MergingGenerator]: https://pub.dev/documentation/merging_builder/latest/merging_builder/MergingGenerator-class.html\n\n[researchers.dart]: https://github.com/simphotonics/merging_builder_example/blob/main/researcher/lib/output/researchers.dart\n\n[source_gen]: https://pub.dev/packages/source_gen\n\n[source_gen_test]: https://pub.dev/packages/source_gen_test\n\n[StandaloneBuilder]: https://pub.dev/documentation/merging_builder/latest/merging_builder/StandaloneBuilder-class.html\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimphotonics%2Fmerging_builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimphotonics%2Fmerging_builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimphotonics%2Fmerging_builder/lists"}