flutterdartbuild-runner

How to influence the order of cascaded generators?


I want to use source generators more in my project. Something that I need to often do, is generate code that is then utilised by another generator.

For example.

I have written a generator that produces a dart file from a swagger json schema. That dart file is annotated with @JsonSerializable - so it should then trigger a serializer to be generated.

In this simple case it more of less works - however I think that's mostly down to the luck of the draw.

There are more complex scenarios, such as ones that utilise the MobX generator - these appear extremely flakey and often break when things are not generated in the correct order. Sometimes I need to just "touch" a specific file in a particular way to either break or fix the build runner.

Has this scenario been considered in the design of the source_gen subsystem, and how do I ensure this is working correctly?

Thanks,


Solution

  • I suppose you need to ensure that your generators are executed in the correct order because the orders in which generators run can sometimes affect the outcome.

    You can use the build.yaml file to specify the order in which generators should run.

    targets:
      $default:
        builders:
          your_generator1:
            generate_for:
              - lib/**/*.dart
          your_generator2:
            generate_for:
              - generated/**/*.dart  # Depend on the output of your_generator1
    

    Here is a real-world sample:

    targets:
      $default:
        builders:
          flutter_api|apiParser:
            enabled: true
            generate_for:
              - lib/basic_api/generated/*_receive.json
          flutter_api|api:
            enabled: true
            generate_for:
              - lib/basic_api/generated/*_send.json
              - lib/basic_api/generated/*_receive.json
          flutter_api|apiHelper:
            enabled: true
    
    builders:
      apiParser:
        import: "./api_parser.dart"
        builder_factories: ["apiParser"]
        auto_apply: root_package
        build_extensions: { ".json": ["_result.dart"] }
        is_optional: False
        build_to: source
        runs_before:
          - flutter_api|api
        defaults:
          generate_for:
            include:
              - lib/basic_api/generated/*_receive.json
    
      api:
        import: "./api_builder.dart"
        builder_factories: ["apiBuilder"]
        auto_apply: root_package
        build_extensions: { ".json": [".dart"] }
        is_optional: False
        build_to: source
        runs_before:
          - flutter_api|apiHelper
        defaults:
          generate_for:
            include:
              - lib/basic_api/generated/**
    
      apiHelper:
        import: "./api_helper_builder.dart"
        builder_factories: ["apiHelperBuilder"]
        build_extensions: { ".dart": [".helper.dart"] }
        is_optional: False
        build_to: source
        required_inputs: ["api"]
        runs_before:
          - json_serializable
        defaults:
          generate_for:
            include:
              - lib/basic_api/helper/response_mapper.dart