flutterdartfreezedjson-serializablebuild-runner

Is there a build_extensions rule in build.yaml to output all generated Flutter models in a common directory?


I am trying to create a build_extensions rule in build.yaml for builders freezed and json_serializable to output all generated models in the directory lib/generated/model, irrespective of their original location that matches lib/**/*.dart.

What I have tried:

Example:

My current build.yaml (which generates .g.dart and .freezed.dart files in the child generated directory relative to the original model location) is as follows:

targets:
  $default:
    builders:
      source_gen|combining_builder:
        generate_for:
          - lib/**.dart
        options:
          build_extensions:
            # I want this line to "work":
            # '^lib/**/{{}}.dart': 'lib/generated/model/{{}}.g.dart'
            'lib/{{path}}/{{file}}.dart': 'lib/{{path}}/generated/{{file}}.g.dart'
      freezed:
        options:
          build_extensions:
            # I want this line to "work":
            # '^lib/**/{{}}.dart': 'lib/generated/model/{{}}.freezed.dart'
            'lib/{{path}}/{{file}}.dart': 'lib/{{path}}/generated/{{file}}.freezed.dart'
          field_rename: snake
          explicit_to_json: true
      json_serializable:
        options:
          field_rename: snake
          explicit_to_json: true

Solution

  • For anyone else looking for a similar solution, turns out it's not possible to place multiple generated outputs into the same directory.

    Build extensions need to be written in a way that prevents two different files from emitting the same output file (e.g. if you had lib/a/foo.dart and lib/b/foo.dart, there can't be a single foo.g.dart in lib/generated/model). ** is not something build extensions supports, and {{}} should be used to match multiple chars and then used again in the destination directory. Apart from that, build extensions just match suffixes.

    To avoid the problem of different source directories potentially conflicting in the output directory, you'd have to use something like lib/generated/model/{{path}}/{{file}}.g.dart, there's no way to put everything in a single directory, even if you make sure that no generated files will be outputted with the same name in the first place.