Pkg.jl: API to activate first parent dir with Project.toml

Created on 22 Jun 2021  路  4Comments  路  Source: JuliaLang/Pkg.jl

When launching julia with argument --project, then it will _"search through parent directories until a Project.toml or JuliaProject.toml file is found."_ (docs). This is really useful for projects with scripts and notebooks in nested folders. (e.g. <project-root>/notebooks/analysis/hello.jl)

It would be great if this automatic Project search was available as a function in Pkg, to be called at the top of a script/notebook. This would be useful in environments where setting the project flag is impractical (Pluto.jl, Jupyter, VS Code). It also helps to simplify the reproducibility steps: you can just run the script.

Currently, you need to manually count towards the root directory of your project:

import Pkg
Pkg.activate(joinpath(@__DIR__, "..", ".."))

# but I wish I could do:
Pkg.activate(; search_parents=true)

I would be happy to make this PR myself if there is interest?

Most helpful comment

Yes (and actually the source of this function was the starting point for quickactivate). But if we really care about reproducibility, then Base.current_project() would have to be documented (currently it has no docstring) and be formally made part of the public API. If not, it could "potentially" change or be removed at any point between even patch releases (according to SemVer stuff).

Does this sound like something possible for you? If yes, then this issue practically resolves to a documentation PR.

All 4 comments

To give some more context, the proposed functionality is already implemented in DrWatson, as a function quickactivate and a macro @quickactivate. https://juliadynamics.github.io/DrWatson.jl/dev/project/#Activating-a-Project-1

You start a script with the lines:

using DrWatson
@quickactivate "ProjectName" 

and Julia starts scanning the folder that contains your script until it finds a project, and activates that project. The argument "ProjectName" only checks that the activated project matches the given name, and gives an error if not.

The Macro is the most useful version, and our users are extremely happy with it. It allows for reproducible scientific projects, allows finding your "correct" project automatically by running your script (no manual labor!), and it allows for easily switching projects within the same Julia session.

The only problem it has is that it requires DrWatson to be loaded. This means that DrWatson needs to be available on the global environment to use @quickactivate. That's a problem because even if the Project.toml of your scientific project contains DrWatson, this doesn't really guarantee that the global environment of the person you've sent it to will also have it.

This as a result also leads to some difficulties in Pluto.jl notebooks, cf https://github.com/JuliaDynamics/DrWatson.jl/issues/261 . Given that this functionality seems generally useful, we think it is a good idea to have it in Pkg.jl directly.

You can use Pkg.activate(Base.current_project())

Yes (and actually the source of this function was the starting point for quickactivate). But if we really care about reproducibility, then Base.current_project() would have to be documented (currently it has no docstring) and be formally made part of the public API. If not, it could "potentially" change or be removed at any point between even patch releases (according to SemVer stuff).

Does this sound like something possible for you? If yes, then this issue practically resolves to a documentation PR.

This would be useful in environments where setting the project flag is impractical (Pluto.jl, Jupyter, VS Code).

How is it relevant to Jupyter and VS Code? Jupyter (IJulia) already activates the closest parent env:

The default Jupyter kernel that is installed by IJulia starts with the Julia command line flag --project=@.. A Project.toml (or JuliaProject.toml) in the folder of a notebook (or in a parent folder of this notebook) will therefore automatically become the active project for that notebook.

VS Code suggests to choose which of the parent envs to activate when opening a project for the first time, and activates it automatically afterwards.

Was this page helpful?
0 / 5 - 0 ratings