I am trying to understand better reproducibility and the working of the Package manager.
Let’s say that I develop a Package “A”, that depends on some third party packages (example CUDA.jl). Now I develop a program, in an enviroment. I add both packages “A” (deloped by myself), and CUDA using Pkg.add("…").
My question, is What version of CUDA is being used in my enviroment? Is there a way to force, when adding a package, that this dependency is resolved in some predicted way?
When you add a package, the most up-to-date version that is compatible with other installed packages is installed. So what version of CUDA.jl you get depends on what you have in the [compat] section of A.jl’s Project file (this is true regardless of whether you yourself develop A.jl).
Now, just to make sure if my understanding of reproducibility is clear. No matter what the [compat] section says, If my environment is in a git and someone clones this repo and activate it they will run exactly the versions of all packages as they are specified in the Manifest file. Is this correct?
Yes - that is the purpose of ]instantiate. It takes a Manifest.toml and instantiates it exactly as described. This is the preferred approach to reproducing e.g. versions for a paper or some analysis that you’ve run (and tested with known-good versions!).
You can also use ]pin --all to pin all dependencies to their current versions, disallowing version updates for packages in that environment. This may not be desirable for a library, where you define version bounds for compatible versions - if they’re pinned, they will hold other packages back, as there can only ever be one version of a library installed.