Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[build_runner] execute builder on only a single file #2928

Closed
lunaticcoding opened this issue Dec 4, 2020 · 18 comments
Closed

[build_runner] execute builder on only a single file #2928

lunaticcoding opened this issue Dec 4, 2020 · 18 comments

Comments

@lunaticcoding
Copy link

I don't know if this is already possible but I could not find it in the documentation.

We have quite a large codebase making the builder take a very long time to run. Often we only changed a single file and would like to have a way to have the builder only recreate that single file. Is this already possible and if not is it feasible to implement for you guys or is there already a specific reason why this is not possible.

Thank you in advance and cheers :D


For general questions consider using Stack Overflow instead:
https://stackoverflow.com/questions/tagged/dart

Also consider our Gitter channel for light-weight/quick discussions:
https://gitter.im/dart-lang/build


@jakemac53
Copy link
Contributor

See #2815, and comments about the --build-filter argument.

One thing I just remembered which is not captured there is I believe that build to source generators always do run regardless of that argument. Not for a technical reason but because those files ship with packages on pub and for safety we wanted to ensure they were always up to date. We could revisit that decision, or possibly consider an override flag for that behavior, etc.

As a longer term solution here specifying which files the builder needs to run on is almost certainly going to give you the biggest bang for your buck, see my comment here #2861 (comment).

@lunaticcoding
Copy link
Author

lunaticcoding commented Dec 7, 2020

@jakemac53 Thanks for the response. I didn't know about --build-filter but unfortunately it does not work. I pointed it to a file and it completed with zero actions taken aka it did not generate the file :S

The longest it took for us to run the build runner was almost 16 minutes. :S and that for adding a new field to an enum :S It would be really amazing if we could simply run the build_runner for only a single file :/ Hope that gets added soon :D

@jakemac53
Copy link
Contributor

jakemac53 commented Dec 7, 2020

@lunaticcoding if you are seeing build times that long, then configuring your build to only run on the more specific files that you need it to is definitely worth while. For small/medium sized projects this is less important, but it becomes important for large apps. If you want help with that let me know.

With regards to building single files note that it will still have to build any transitively imported file of the file you want to build, so depending on the structure of your app this may or may not help that much. As a common example, if your package libraries all import a convenience library which exports everything else from the package, then that means it also imports all other generated files in your package and thus they will all be generated when building any of them.

@lunaticcoding
Copy link
Author

lunaticcoding commented Dec 7, 2020

@jakemac53 oh I see. okay, that makes sense (still would be awesome if we could say we don't care about the imports - but I see as to how this is a bigger change). How would we go about limiting the scope? I would really appreciate the help :D

@jakemac53
Copy link
Contributor

jakemac53 commented Dec 7, 2020

You can create a build.yaml file, and configure the generate_for setting for each builder. Ultimately it looks something like this:

targets:
  $default:
    builders:
      # Typically the builder key is just the package name, run `pub run build_runner doctor` to check your config.
      <builder-key>:
        generate_for:
          # Example glob for only the Dart files under `lib/models`
          - lib/models/*.dart

The builder key is the identifier for the builder you are configuring, this is of the format <package-name>:<builder-name>, or just <package-name> if the name is the same as the package. You can run pub run build_runner doctor to confirm you set the key right.

@lunaticcoding
Copy link
Author

@jakemac53 Thank you :D this is already a huge improvement

@jakemac53
Copy link
Contributor

Glad to hear that helped! I am going to close this issue for now, as we do support building specific outputs (which includes all their inputs...). If you have a case where that feature isn't working as intended please do file an issue about that.

@lunaticcoding
Copy link
Author

@jakemac53 one more question :) Is there a way to add a single line at the beginning of every file created by a certain builder?
Like Remi is describing it here?

rrousselGit/freezed#333

@hbock-42
Copy link

hbock-42 commented Apr 26, 2023

Hello, can you point to some examples of using build_runner targeting only 1 file, please?

I tried my best to use the --build-filter to target a single file but had no success in doing so. I am probably missing something.

Here is everything I tried so far, without success:

flutter pub run build_runner build --delete-conflicting-outputs --build-filter=freezed_class/user_2.dart
flutter pub run build_runner build --delete-conflicting-outputs --build-filter='freezed_class/user_2.dart'
flutter pub run build_runner build --delete-conflicting-outputs --build-filter="freezed_class/user_2.dart"
flutter pub run build_runner build --delete-conflicting-outputs --build-filter=lib/freezed_class/user_2.dart
flutter pub run build_runner build --delete-conflicting-outputs --build-filter='lib/freezed_class/user_2.dart'
flutter pub run build_runner build --delete-conflicting-outputs --build-filter="lib/freezed_class/user_2.dart"
flutter pub run build_runner build --delete-conflicting-outputs --build-filter freezed_class/user_2.dart
flutter pub run build_runner build --delete-conflicting-outputs --build-filter 'freezed_class/user_2.dart'
flutter pub run build_runner build --delete-conflicting-outputs --build-filter "freezed_class/user_2.dart"
flutter pub run build_runner build --delete-conflicting-outputs --build-filter lib/freezed_class/user_2.dart
flutter pub run build_runner build --delete-conflicting-outputs --build-filter 'lib/freezed_class/user_2.dart'
flutter pub run build_runner build --delete-conflicting-outputs --build-filter "lib/freezed_class/user_2.dart"

On the other hand, I successfully used the --build-filter option to target specific files type under a folder with:
flutter pub run build_runner build --delete-conflicting-outputs --build-filter="lib/freezed_class/*.dart"

It is good enough but since since it seems possible to target a single file I would love to know how pleae.

@jakemac53
Copy link
Contributor

@hbock-42 any relative path under your package should work, but you need to specify the outputs you are trying to build. So probably flutter pub run build_runner build --delete-conflicting-outputs --build-filter=lib/freezed_class/user_2.freezed.dart in your case?

@hbock-42
Copy link

hbock-42 commented May 2, 2023

Damn thank you, I missed the crucial point that the filter needs to target the output file and not the original file!
I think I am not the only one miss who understands how it works and this might be the reason some people are saying file filtering is not working properly

@luohao123
Copy link

@jakemac53 @hbock-42 Please help..... I am fucking got buld_runnfer just partly gened files, these files in data model all gened, but these file with database dao not gen...

Why??

image

I tried many times, only these dao and database gen not gen....

@ammarqusailah
Copy link

You can use --build-filter="lib/*.dart"
Just replace file name with *

Example:
flutter pub run build_runner build --delete-conflicting-outputs --build-filter="lib/features/locations/domain/*.dart"

@markbulingit
Copy link

markbulingit commented May 26, 2023

May 26, 2023

100% Working

via command

flutter pub run build_runner build --delete-conflicting-outputs --build-filter="lib/app/routes/app_router.dart"
(^depends on your folder structure)

From 1min. 9secs. down to 1.8 secs.
image

@1207roy
Copy link

1207roy commented Aug 19, 2023

Thank you @hbock-42 and @jakemac53
conversation between you was really helpful for me to understand it
Finally, I'm able to run build_runner on a folder and on a single file

@tangbl93
Copy link

this command can execute builder on only a single file

// add * after model name
// replace <CLASS_NAME> with your class name
flutter pub run build_runner build --delete-conflicting-outputs --build-filter="./lib/../<CLASS_NAME>*.dart"

@flawnn
Copy link

flawnn commented Jan 18, 2024

This definitely doesn't work.

I am executing the build runner on a single file called injectible.config.dart (from the package Injectable for Flutter. The command I use is the following:
fvm flutter pub run build_runner build --build-filter="lib/injectable.config.dart"

What happens is, that STILL .freezed files (also use freezed in the package) are being deleted and rebuilt, ALTHOUGH I didn't specify them in the build filter! How can this work? Who is to blame for this behaviour?

@jakemac53
Copy link
Contributor

jakemac53 commented Jan 18, 2024

What happens is, that STILL .freezed files (also use freezed in the package) are being deleted and rebuilt

This is a simple result of the hermetic build guarantees provided by the build system.

  • All files invalidated by any changes must be deleted so they do not reflect a different state of the world than other files
  • All dependencies of any file you ask to be built must also be built (if invalidated)

We do not allow things to exist in an inconsistent state, if it exists on disk it is guaranteed to be up to date (to the extent possible).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants