Packages under /.julia/dev/ shared by different versions of Julia?

Hello,

Packages installed for different versions of Julia on my computer should be independent from each other, right?
For example, I can have JuMP 0.18 installed for Julia 1.3.1 while having JuMP 0.21 installed for Julia 1.1.1
Now I have version 0 of a package (called it “A”) cloned from github on Julia 1.3.1, and I tried to clone version 1 of this package A on Julia 1.1.1. But when I did “using A” on Julia 1.1.1, it loaded version 0 (which is only installed for my Julia 1.3.1) instead of version 1.
This package seems to locate under “/.julia/dev/”. I can’t see this directory is separated by different Julia versions. Is this a directory shared by all versions of Julia on my computer? And how can I have different versions of package A for different versions of Julia?

Thank you!

You can have many versions of a package installed and shared between Julia versions, either in the standard way (the code of those versions can be found in .julia/packages, but users normally don’t have to take care of that), or in “development mode” (by default in .julia/dev, but you can choose any folder, so you can have even different development versions at the same time).

The version that will be used when you do using A is defined in the Manifest.toml file of the environment you are using. The default environment for each version of Julia can be found in .julia/environments/.

Look for the entry for your package in the corresponding Manifest.toml. If it has a path entry, you will be using the source code present in that path as development version. If instead it has a git-tree-sha1 entry, it means that you will be using a version added in the standard way.

The commands ]add, ]dev, ]free, etc. always operate on the environment that you have activated at the time of calling them.

3 Likes

Thank you! I see package A in Manifest.toml of Julia 1.1.1 has a path entry. How can I change this so that it will use the version I cloned from github? Should I manually edit this Manifest.toml file? Now I only see version 0 of package A under .julia/dev, which is being used by all Julia versions. My goal is to install version 1 of A, and use it on Julia 1.1.1, while keep using version 0 on Julia 1.3.1. How can I achieve this?

Also, why was package A added to the .julia/dev while the other packages were added to .julia/packages? I don’t think I have been asked where to install the packages.

Thank you!

Which version of a package is used does not depend on the Julia version per se but on the active environment.
When you start Julia 1.1 you are in environment v.1.1. When you issue Pkg.add, you effectively edit the Project.toml of v.1.1. If you switch to a different folder and Pkg.activate(".") you edit that folder’s Project.toml from then on.
Pkg.add looks up the package in the registry, writes it into Project.toml (for the currently active environment) and fetches the version that you specify in the add command (usually the latest) into .julia/packages. That location can have many versions of a package at the same time.
Pkg.dev does the same, but downloads to .julia/dev. There you can edit the code and changes will be known to Julia without downloading anything. The Project.toml entry points to .julia/dev (or wherever you put the package) and Julia does not consider the registry for that package any more.
You never edit Manifest.toml. It is auto generated by resolving dependencies through Pkg.
If you want Julia 1.1 to use the version of A that you downloaded to .julia/dev, you Pkg.develop A in v.1.1 (the environment).
To use a current registered version of A in 1.3.1, you Pkg.add A while in that environment.

3 Likes

Thank you! As you suggested, by using Pkg.add A, I’m now able to use the current version of A.
Previously I downloaded A by Pkg.clone. Is that the reason that it went to .julia/dev instead of .julia/packages? Even if I do Pkg.clone("A") now, .julia/dev still only has the old version of A . Why is the current version not cloned to .julia/dev? Can it not have both the current version and the old version?

I think that Pkg.clone is not meant to be used directly. Use only the commands explained here: https://docs.julialang.org/en/v1/stdlib/Pkg

To clone a package for development use Pkg.develop or ]dev. However, as you say, if the .julia/dev/A already exists, this will track that version, instead of downloading a newer one.

This is because if you are developing the package, you are meant to control the changes of the code on your own. If there is a newer version you want to clone, you should do it via git directly (git pull, etc.), and then you can switch between different versions with git checkout.

2 Likes

Are you actually intending to edit the code in the cloned version of the package? Or are you just trying to have two different versions of A as dependencies for two different versions of Julia?

If the latter, don’t develop A; instead Pkg.add the version that you want to pin for the older Julia version.

Note also that you can always download a new version of A to anywhere you want using any method you want. If you then develop(path/toA) you will use that version of A in that particular environment. develop just means: put an entry into Package.toml that points to a local folder. Whatever code sits there will be used in that environment. That could be your own code or a package that you downloaded (by whatever method) from anywhere else.

3 Likes

Thank you! If my understanding is correct, Pkg.add("A") or Pkg.add(PackageSpec(url="url of A")) will always update the package A to its most recent version for my current environment, while I can have another version 2 of A stored at some path on my computer, and I can always switch back to version 2 by doing Pkg.develop(PackageSpec(path="path to version 2")). These are true for all packages, both unregistered packages and registered packages. Is this correct?

Yes, but you don’t have to develop a package just to get a specific version. You can add a version specification to add instead.

If you don’t plan to edit the code, just use add.

And to ensure that the package does not get updated, you can pin it. The Pkg docs have the syntax for this.

1 Like

Thank you! Does add a specific version work for packages that don’t have a version number? For example, I want to have an older version of a package which can only be installed using url from github, but the one on github only has the code for the most recent version. Doing add url will only give me the most recent version, right? I do have the older version stored under my .julia/dev, that’s why I’m thinking of using develop to go back to that older version. I’m not sure if add will also work in this case?

add A#master to use the master branch (or choose any other branch or commit sha).
https://julialang.github.io/Pkg.jl/v1/managing-packages/

1 Like

What i do is this.

  1. Create a .julia\environments\tomls dir with the Manifest.toml and Project.toml files
  2. For each Julia version make symbolic links to that dir under .julia\environmentsv1.4, v1.5, etc

Now no need the annoying reinstall of all packages for each julia version.

1 Like

I don’t recommend this: say you update some package to a version that requires Julia 1.4 (or any other minor version); then your environment for lower versions will be broken.

That is true, but for many people that situation does not apply and, besides the annoyance when installing more than one Julia version, avoiding duplicating GB of packages is also worthwhile to some.

1 Like