I was recently surprised that a package I published failed to install via pub global activate.
My issue was that I had some shared code in libraries within the bin/ folder that are not binaries themselves. When I ran pub global activate I saw that precompilation failed on those libraries. I was surprised by this because the libraries were not listed in the executables section in the pubspect.yaml file and because, during development, activating via path (pub global activate -s path ...) gives no warning of the issue.
My workaround is to move the shared code under bin/src/. However, I wonder:
To reproduce this, try:
pub global activate dart2js_info 0.6.0
and you'll see errors like:
Failed to precompile dart2js_info:deferred_library_check:
Dart_LoadScriptFromKernel: The binary program does not contain 'main'.
Reading:
https://www.dartlang.org/tools/pub/cmd/pub-global#configuring-package-executables
I'm starting to think that we might have two things we can do here:
A) We should maybe not be pre-compiling scripts from bin/ if they are not listed as executable in the pubspec.yaml. You can still trigger them with pub global run.
B) in pana reduce package score if there are libraries in bin/. Maybe we can do it in a pub package validation step prior to publishing. I'm not sure if any of the other validations does code analysis, or if there is a problem/concern with doing so..
Fwiw I would actually love it if pub stopped precompiling scripts completely on pub get/upgrade - it is really slow and could instead be done lazily always.
That would also make it so pub get/upgrade don't fail just because of a bad executable (you would get the error later when you try to actually run the offending script), and also it would allow it to re-snapshot them if you delete your local pub cache (in .dart_tool of your package). Today if you do that you lose all snapshots until you run pub get/upgrade again so all binaries are slow after that point.
The downside of course is the first run of these executables is slow, but I think that is probably ok, or at least a reasonable tradeoff. Packages should be able to release executables without increasing pub get/upgrade times for all users who have a transitive dep on their package by multiple seconds which is the case today.
@sigurdm was also suggesting we made pre-compilation of scripts lazy.
I would actually love it if pub stopped precompiling scripts completely on pub get/upgrade
This issue is specifically pub global activate. In the pub get case the user hasn't necessarily indicated an intent to run the binaries - but in the activate case they have. I think for activate precompilation makes sense.
but in the activate case they have. I think for activate precompilation makes sense.
Yet, some packages contain many targets that you never run.. as a package may define multiple executable scripts.
I agree that, lazy pre-compilation is mostly a problem for pub get. But doing it lazily for pub global activate might be nice too.
Most helpful comment
Fwiw I would actually love it if pub stopped precompiling scripts completely on pub get/upgrade - it is really slow and could instead be done lazily always.
That would also make it so pub get/upgrade don't fail just because of a bad executable (you would get the error later when you try to actually run the offending script), and also it would allow it to re-snapshot them if you delete your local pub cache (in .dart_tool of your package). Today if you do that you lose all snapshots until you run pub get/upgrade again so all binaries are slow after that point.
The downside of course is the first run of these executables is slow, but I think that is probably ok, or at least a reasonable tradeoff. Packages should be able to release executables without increasing pub get/upgrade times for all users who have a transitive dep on their package by multiple seconds which is the case today.