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
pubspec: Add bin_dependencies or global_dependencies #22054
Comments
When we were first designing the package system, we intentionally decided to limit the number of different ways a dependency could be declared to encourage both conceptual clarity and straightforward implementation. I think that principle applies here: there isn't enough benefit from not having some dependencies downloaded under some circumstances to justify the complexity cost. Added NotPlanned label. |
This comment was originally written by @seaneagan Example of why this would be useful: |
This comment was originally written by @seaneagan Version lock is probably the bigger concern here, not downloading extra dependencies. This bit me again, causing me to have to put my executable and library in separate packages: http://github.com/seaneagan/den And it just came up again here: |
cc @munificent. |
This comment was originally written by @seaneagan I think this would get much easier to implement once we have the package spec: https://github.com/lrhn/dep-pkgspec Then all the deps can still be downloaded into the same place, but |
I'm going to re-open this because I'm increasingly hearing this is a problem and I don't want people to solve it by splitting their packages into pure lib / command line halves. Totally agree that package-spec will help here. Added Triaged label. |
Yes please! This is something we're tangling significantly with in analyzer-land. |
A package's executables are part of its public API; it's valid for one package to depend on another because it wants to run that dependency's executable. If that executable's dependencies are distinct from its normal dependencies, that use-case breaks. This is analogous to a package exposing two classes, one of which has a dependency that the other does not. If a downstream package only uses one class, sure, it would be nice for it not to use the other class's dependency, but that's not how our dependency system works, and for good reason: if every package has to spell out exactly which dependencies are used by which pieces of its API, and which pieces of the APIs of its dependencies it uses, the whole system becomes untenably complex. And just like the multiple-classes case, if the dependencies or versioning story of two pieces of an API are different enough that they're causing problems, I don't think there's anything wrong with splitting them apart. We're planning on doing this with unittest, for example: there will be one "frontend" package for defining tests and a separate "backend" package for manipulating the infrastructure behind the definition, separated out so they can be versioned separately. |
This comment was originally written by @seaneagan
A package shouldn't depend on a package solely for its executable, that's what
I think "breaks" is too strong. As mentioned in the original post, yes, it's harder for
I don't think anyone has or would suggest such a complex partitioning of dependencies. A better analogy is with dev_dependencies. Those are useful because for example packages want to co-locate their tests, build scripts, etc. with their public API, using the standard pub package layout conventions (/lib, /test, /tool), but they don't want dependers to inherit e.g. unittest, grinder, etc. dependencies. Similarly, packages want to co-locate one cohesive public API including an executable and a dart API, using the standard pub package layout conventions (/lib, /bin) without having dependers inherit e.g. args, prompt, and ansicolor.
That sounds like a good solution, but to a problem that's specific to the unittest package. Exposing executables however is a problem shared by a large percentage of packages. It's already partly solved by the /bin convention, |
Not true. It's helpful to depend on packages that you only use executables from because it ensures everyone hacking on your package can easily run the right version of those executables. You can just tell people:
However, I'm not opposed to something like bin_dependencies, though it can be a tricky to implement correctly. |
This is incorrect. "pub global activate" is for end-users to install executables onto their systems for their direct use. If one package needs to use another's executable, it absolutely should depend on that package; making its users run "pub global activate" is an annoyingly manual installation step that interferes with the user's system state and doesn't respect version constraints. I want to emphasize again that we consider a package's executables to be part of its API, and this model is not likely to change. Even if we do decide to add some notion of bin dependencies, it will be in a way that preserves works with this model, rather than against it.
How would this help? The bin-inclusive package graph would be identical to package graphs today, and if it experiences version lock, installation would still fail. |
This comment was originally written by @zoechi I'm fighting a lot with package dependencies lately and every single dependency adds more headaches. Here its with examples https://bitbucket.org/andersmholmgren/shelf_auth/issue/6/please-make-it-compatible-with-shelf-060 (see end of the discussion) |
This is exactly what dev_dependencies do, except that bin shouldn't be in that list. But for things in test, example, and tool, by all means do use dev_dependencies for those. |
This comment was originally written by @seaneagan
I agree that that's a nice to have, but if folks are experiencing version lock they won't even get past the install, and thus won't be able to run the executables at all. This is not a problem with Instead of trying to jam in the dependencies of all the binaries of all your transitive dependencies into a single dependency graph, similar to
We add a step between 2. and 3., which is to run a new command: pub activate some_dep This is just like: pub global activate some_dep <some version or path or git repo> except that you never need to specify <some version or path or git repo> since that is already done for you by the pubspec. It only uses the dependencies of If there is desire to easily activate all the binaries of one's immediate dependencies that could just be a The lock files of the Then when
I personally like 2. a lot. And What do you all think? |
fyi, proposal doc: https://docs.google.com/document/d/1lvbzyivCejhTuHLG4WI3YVThbQqJhPUrwajwTC-sXWU/edit looks great to me |
This comment was originally written by @seaneagan Another example: |
This comment was originally written by @seaneagan Another package:args conflict in issue #23349. |
This issue has been moved to dart-lang/pub#1231. |
This issue was originally filed by @seaneagan
Many packages expose command-line apps as well as dart APIs to that same functionality. Often the command-line apps require additional dependencies such as
args
,unscripted
,ansicolor
,prompt
, etc. Similar to how dev_dependencies allow you to specify dependencies only needed by package developers, bin_dependencies could allow specifying dependencies only needed by folks running command-line apps from the package.For
pub global activate
/pub global run
it would be easy, because those use a self-contained dependency graph.But for
pub run
, it would require separating the dependencies into two separate graphs, e.g.packages
/pubspec.lock
andbin_packages
/pubspec_bin.lock
.The text was updated successfully, but these errors were encountered: