It takes several minutes to add a single package

Here’s a potential workflow:

Remove “@v#.#” from Base.LOAD_PATH in startup.jl

Typically always work in the global environment and add packages with ]add --preserve=all package. Update with ]up when I run into a package bug, want a new feature, or have a few minutes where it is okay to let Julia be unresponsive and am okay with a risk of having to deal with broken updates.

When I want to share a minimum working environment, including whenever I do package development, make a new temporary or package environment, run my code, and ]add anything that I need (possibly automate this process with the Pkg API).

Advantages:

  1. I never have to worry about environments unless it is necessary.
  2. Julia shouldn’t spend several minutes precompiling when I don’t expect it to
  3. I typically only have to ]add anything when I start using a package for the first time ever (or change Julia versions?)
  4. When I make a temporary environment it is totally clean so I can share the Project.toml without worrying about accidentally depending on something in my global environment

Disadvantages:

  1. Large global environment (I don’t see why this is a problem)
  2. There is an additional step to create a reproducible environment when I want to share a MWE (note that in the classic workflow I would already have manually created this environment and manually ]added everything to it as I went along)
  3. less explicitly aware of which packages I’m using where for my personal code

What do y’all think? What advantages and disadvantages am I missing? Why isn’t this the default behavior of LOAD_PATH and ]add?

EDIT to clarify recommended default behavior of ]add Xxx in non-trivial cases per @lmiq @dlakelan & @kristoffer.carlsson’s comments:

When possible, ]add Xxx should add the latest version of Xxx without updating anything else
Where this is not possible, but it is possible to install the latest version of Xxx with updates to other packages it should prompt:
"Installing package Xxx requires updating N packages. Expected runtime 15s. Type D for details. Continue? (Y/N)”
and D should yield a menu giving the user options to install…

  1. Xxx v0.21.6 which is 12 days out of date and the latest version compatible with currently installed dependency versions.
  2. latest version of Xxx v0.22.0 and update N packages. Expected runtime 15s
  3. latest version of Xxx v0.22.0 and update all M out-of-date packages. Expected runtime 373s

Where it is impossible to install the latest version of Xxx due to dependency conflict, the user should immediately be given detailed options:

The latest version (v0.22.0) of Xxx is incompatible with Yyy (last used 7 years ago) and Zzz (last used yesterday). You may install…

  1. Xxx v0.21.6 which is 12 days out of date and the latest version compatible with currently installed dependency versions.
  2. Uninstall Xxx & Yyy and install the latest version of Xxx v0.22.0, updating N packages. Expected runtime 15s.
  3. Uninstall Xxx & Yyy and install the latest version of Xxx v0.22.0, updating all M out-of-date packages. Expected runtime 373s.
  4. Xxx v0.21.8 which is 2 days out of date and the latest version compatible with Yyy and Zzz. This requires updating N packages. Expected runtime 15s.
  5. Xxx v0.21.8 and update all M out-of-date packages. Expected runtime 373s.
  6. Install Xxx in a new environment…
  7. Copy the current environment to a new location and replace Yyy and Zzz with Xxx here…

These menus, especially the second, might be best refactored into multiple independent choices (e.g. factor our weather to update everything, or remove that option altogether), though I think presenting every possible choice is nice to give a user a big-picture and results-oriented understanding of their choices, with some indication of why their preferred option (have the latest Xxx, Yyy, and Zzz installed now without a long precompilation time) is not available.

1 Like