How to add all dependencies of a package to global environment?

Suppose I have a package A which depends on B and C. If I run add A, then B and C are activate only in A’s environment. This means that if I do using B or using C from the global environment, it will fail. Is there an easy way to add all the dependencies of a given package like A to the global environment, in addition to its own environment, so that using them then works? Thanks.

You can do this:

pkg> add B C

Why do you want this?

Thanks for the suggestion. So, the reason is that I’m making a MyBinder Docker container for an analysis that I’m hoping to pass onto colleagues. There’s a long list of packages useful for this analysis used throughout the notebooks therein, with all these packages listed as dependencies of A. I want to add all these packages to the global environment inside the container, so they’re always easily available to my colleagues.

Some solutions I’ve thought of: 1) I considered yours (but then I have to duplicate the package list in A’s Project.toml as well as in the add command 2) copy A’s Project.toml to the global environment (but then this environment gets renamed to A, which I’m unsure might cause other problems 3) Create a separate Project.toml which I use as the global environment inside the container (which I guess I disfavor again since the duplication issue)

I guess another option is to auto-activate A inside the container. I suppose there’s not a command line option, I should do this in startup.jl ?

I actually liked the old behavior, where you could add A, and then could also just use any of its dependencies.

My use case is mostly that I add Queryverse.jl, which is a meta-package that pulls in everything that belongs to the Queryverse (so quite a lot). But many times I would then prefer to do using B rather than using A, because loading Queryverse takes a while with the current precompile/package load issues. That of course doesn’t work, and then I have to add all the individual packages manually, which is annoying.

2 Likes

Perhaps something like https://github.com/QuantEcon/InstantiateFromURL.jl is more appropriate for this use case.

Uh, that seems way too involved for my use case :slight_smile:

I suppose the reason this can’t be the case anymore is because of the ability of Pkg3 to let packages depend on different versions of the same dependency? I wonder if there’s a way to get the best of both worlds, although I admit I can’t really think of a good way…

You can always do using A.B

2 Likes

Ha! Hadn’t realized you can do that. That could potentially be good enough for me (maybe not so much for @davidanthoff, since it seems it still has to load A)

This is not true. The main reason is that you should not rely on package A to make B available to you. The fact that A depends on B is an implementation detail of A that you should not rely on. For example, if A suddenly drops its B dependency this would break your code! Instead, install the packages you depend on, its rather simple actually.

8 Likes

I think that makes sense in packages, but at the REPL I don’t buy this argument.

1 Like

I am not sure that whether code is evaluated interactively is the relevant distinction here — what should matter is the active project and the environment. Are you proposing that these behave differently?

1 Like

There might also be many dependencies with the same name in the Manifest, using Foo would then be ambiguous.

1 Like

I just know that it is painful in the REPL. I don’t think it would be the end of the world if something like this behaved slightly different in an interactive context.

So throw some sort of ambiguity error if that happens, and make it work in the other cases? We already have a similar situation, that if two packages export the same name and one loads both of them with using, then there is an error thrown about the name ambiguity, but everything works if it doesn’t happen.

As a one off:
Just copy and paste the parts of A’s Project.toml that you want into the Project.toml of the enviroment you care about. ( ~/.julia/environments/v1.0/Project.toml),
then run ]resolve.

If you just download A to wherever, e.g. ~/demo/A
then start julia with julia --project=~/demo/A

then this will do this.

Since it is a docker container for a binder it isn’t like you need to worry about the user messing things up

1 Like

I realize that my request is basically the same as https://discourse.julialang.org/t/add-all-packages-from-1-0-3-to-1-1, which is probably an even more common case. In their case, they want to add all dependencies from the global environment of 1.0 to that of 1.1. In my case its adding all dependencies from a package environment to a global one, but its basically the same thing. Both can accomplished by copying Project.toml entries by hand, but doing so is probably limited to fairly advanced Julia users. Would it not be possible to have a package command that makes this easy for everyone?

Something like add-from: add a given package's dependencies to project ? Then add-from 1.0 solves the issue in the link above and add-from A or add-from /path/to/A (if A is not already added) solves mine here?

Outside of global environment the answer will be this?