Path of this package?

To add some details.

When running import Foo there are two steps happening.

Step one:

Determine what “Foo” means in this context. This is determined by finding the unique UUID for “Foo”. If you are in “top level” (for example in the REPL) this is determined by looking in Project.toml for an entry Foo = "aefe..." where the right hand side is the UUID. If we are in a package (Bar) and execute the import the UUID is determined by looking at Manifest.toml, finding the [[Bar]] entry with the correct UUID and look up the UUID for Foo there.

Step two:

Ok, so now we know what “Foo” means (i.e we have determined the concrete Foo package out of all possible packages that are named Foo). Now we need to know what concrete path of Foo to load (there can be multiple versions of Foo installed at the same time). This is done by looking in Manifest.toml entry for the uuid we just found (the one for Foo) and if there is a path entry there, that will be the path to Foo, if there is a git-tree-sha entry (as is the case for versioned packages) a “slug” will be computed according to a hashing strategy (based on UUID and git-tree-sha). Every package directory in DEPOT_PATH is now searched for a path with that slug and if it is found that will be loaded.

Concrete example:

I have installed Example and want to know what will be the loaded path when loading it in the REPL. The Project.toml file contains the entry

Example = "7876af07-990d-54b4-ab0e-23690620f79a"

so the UUID will be "7876af07-990d-54b4-ab0e-23690620f79a".

The Manifest.toml contains

[[Example]]
deps = ["Test"]
git-tree-sha1 = "8eb7b4d4ca487caade9ba3e85932e28ce6d6e1f8"
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
version = "0.5.1"

So there is a git-tree_sha1 entry so we compute the slug as

julia> sha = Base.SHA1("8eb7b4d4ca487caade9ba3e85932e28ce6d6e1f8")
SHA1("8eb7b4d4ca487caade9ba3e85932e28ce6d6e1f8")

julia> uuid = Base.UUID("7876af07-990d-54b4-ab0e-23690620f79a")
UUID("7876af07-990d-54b4-ab0e-23690620f79a")

julia> Base.version_slug(uuid, sha)
"kH44X"

We will now search every package folder inside DEPOT_PATH for "Example/kH44X":

julia> isdir(joinpath(DEPOT_PATH[1], "packages", "Example", "kH44X"))
true

So that will be the path that we load. A short form of doing this whole process for top level scope is

julia> Base.find_package("Example")
"/Users/kristoffer/.julia/packages/Example/kH44X/src/Example.jl"

If I now do dev Example

(v1.1) pkg> dev Example
  Updating git-repo `https://github.com/JuliaLang/Example.jl.git`
 Resolving package versions...
  Updating `~/.julia/environments/v1.1/Project.toml`
  [7876af07] ↑ Example v0.5.1 ⇒ v0.5.1+ [`~/.julia/dev/Example`]
  Updating `~/.julia/environments/v1.1/Manifest.toml`
  [7876af07] ↑ Example v0.5.1 ⇒ v0.5.1+ [`~/.julia/dev/Example`]

then the Manifest looks like

[[Example]]
deps = ["Test"]
path = "/Users/kristoffer/.julia/dev/Example"
uuid = "7876af07-990d-54b4-ab0e-23690620f79a"
version = "0.5.1+"

so we will just directly use /Users/kristoffer/.julia/dev/Example as the path:

julia> Base.find_package("Example")
"/Users/kristoffer/.julia/dev/Example/src/Example.jl"

Note that a dependency can depend on a completely different package to Example but that happens to also be called “Example” with a different UUID. So the answer to Pkg.dir("Example") is dependent on who you ask.

5 Likes