Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Activate special environments similar to Julia's CLI arg --project #3821

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/src/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ In short, `instantiate` is your friend to make sure an environment is ready to u
```bash
$ julia --project=. myscript.jl
```
For Julia 1.7 or later, `--project=@stdlib` activates stdlib environment.
For Julia 1.11 or later, `--project=@temp` activates temporary environment.


## Temporary environments
Expand All @@ -115,6 +117,13 @@ between several incompatible packages.
[7876af07] + Example v0.5.3
```

```julia-repl
(@v1.11) pkg> activate @temp # requires Julia 1.11 or later
Activating new project at `/tmp/jl_OzBmCP`

(jl_OzBmCP) pkg>
```

## Shared environments

A "shared" environment is simply an environment that exists in `~/.julia/environments`. The default `v1.9` environment is
Expand All @@ -136,6 +145,24 @@ Shared environments can be activated with the `--shared` flag to `activate`:

Shared environments have a `@` before their name in the Pkg REPL prompt.

Shared stdlib environment that exists in `Sys.STDLIB` can be activated as follows:
```julia-repl
(@v1.11) pkg> activate --shared stdlib
Activating project at `@stdlib/v1.11`

(v1.11) pkg>
```

```julia-repl
(@v1.11) pkg> activate @stdlib
Activating project at `@stdlib/v1.11`

(v1.11) pkg>
```

!!! note
For Julia 1.11 or later `temp` is an invalid name for a shared environment as `activate @temp` creates temporary environments.


## Environment Precompilation

Expand Down
34 changes: 20 additions & 14 deletions src/API.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1968,6 +1968,8 @@ function _activate_dep(dep_name::AbstractString)
end
function activate(path::AbstractString; shared::Bool=false, temp::Bool=false, io::IO=stderr_f())
temp && pkgerror("Can not give `path` argument when creating a temporary environment")
shared && path == "temp" && pkgerror("""`temp` is an invalid name for a shared environment.
To create a temporary environment use `Pkg.activate(; temp = true)`""")
if !shared
# `pkg> activate path`/`Pkg.activate(path)` does the following
# 1. if path exists, activate that
Expand All @@ -1982,20 +1984,24 @@ function activate(path::AbstractString; shared::Bool=false, temp::Bool=false, io
end
end
else
# initialize `fullpath` in case of empty `Pkg.depots()`
fullpath = ""
# loop over all depots to check if the shared environment already exists
for depot in Pkg.depots()
fullpath = joinpath(Pkg.envdir(depot), path)
isdir(fullpath) && break
end
# this disallows names such as "Foo/bar", ".", "..", etc
if basename(abspath(fullpath)) != path
pkgerror("not a valid name for a shared environment: $(path)")
end
# unless the shared environment already exists, place it in the first depots
if !isdir(fullpath)
fullpath = joinpath(Pkg.envdir(Pkg.depots1()), path)
if path == "stdlib"
fullpath = Sys.STDLIB
else
# initialize `fullpath` in case of empty `Pkg.depots()`
fullpath = ""
# loop over all depots to check if the shared environment already exists
for depot in Pkg.depots()
fullpath = joinpath(Pkg.envdir(depot), path)
isdir(fullpath) && break
end
# this disallows names such as "Foo/bar", ".", "..", etc
if basename(abspath(fullpath)) != path
pkgerror("not a valid name for a shared environment: $(path)")
end
# unless the shared environment already exists, place it in the first depots
if !isdir(fullpath)
fullpath = joinpath(Pkg.envdir(Pkg.depots1()), path)
end
end
end
if !isnothing(Base.active_project())
Expand Down
9 changes: 9 additions & 0 deletions src/REPLMode/argument_parsers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,15 @@ function parse_activate(args::Vector{QString}, options)
if x == "-"
options[:prev] = true
return []
elseif x == "@temp"
options[:temp] = true
return []
elseif x == "@stdlib"
return [Sys.STDLIB]
elseif x == "@."
return [Base.current_project()]
elseif x == "@"
return [Base.active_project()]
elseif first(x) == '@'
options[:shared] = true
return [x[2:end]]
Expand Down
3 changes: 3 additions & 0 deletions test/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ using ..Utils
cd(mkdir("tests"))
Pkg.activate("Foo") # activate developed Foo from another directory
@test Base.active_project() == joinpath(path, "modules", "Foo", "Project.toml")
@test_throws PkgError Pkg.activate("temp"; shared = true) # Disallow naming a shared env as `temp`.
Pkg.activate("stdlib"; shared = true) # activate `@stdlib/Project.toml`
@test Base.active_project() == joinpath(Sys.STDLIB, "Project.toml")
Pkg.activate() # activate LOAD_PATH project
@test Base.ACTIVE_PROJECT[] === nothing
end end
Expand Down
12 changes: 12 additions & 0 deletions test/repl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ temp_pkg_dir() do project_path
@test_throws Pkg.Types.PkgError pkg"activate --shared ./Foo"
@test_throws Pkg.Types.PkgError pkg"activate --shared Foo/Bar"
@test_throws Pkg.Types.PkgError pkg"activate --shared ../Bar"
@test_throws Pkg.Types.PkgError pkg"activate --shared temp"
# check that those didn't change the environment
@test Base.active_project() == joinpath(path, "Project.toml")
mkdir("Foo")
Expand All @@ -239,6 +240,8 @@ temp_pkg_dir() do project_path
pkg"activate ."
#=@test_logs (:info, r"activating new environment at ")))=# pkg"activate --shared Foo" # activate shared Foo
@test Base.active_project() == joinpath(Pkg.envdir(), "Foo", "Project.toml")
pkg"activate --shared stdlib" # activate shared STDLIB
@test Base.active_project() == joinpath(Sys.STDLIB, "Project.toml")
pkg"activate ."
rm("Foo"; force=true, recursive=true)
pkg"activate Foo" # activate path from developed Foo
Expand All @@ -265,6 +268,15 @@ temp_pkg_dir() do project_path
pop!(Base.DEPOT_PATH)
pkg"activate" # activate LOAD_PATH project
@test Base.ACTIVE_PROJECT[] === nothing
pkg"activate @temp" # activate a temporary environment
@test dirname(Base.ACTIVE_PROJECT[]) == tempdir()
pkg"activate @stdlib" # activate the STDLIB environment
@test Base.ACTIVE_PROJECT[] == Sys.STDLIB
pkg"activate @." # activate current project
@test Base.ACTIVE_PROJECT[] == Base.current_project()
pkg"activate @" # activate active project
@test Base.ACTIVE_PROJECT[] === Base.active_project()

# expansion of ~
if !Sys.iswindows()
pkg"activate ~/Foo_lzTkPF6N"
Expand Down
Loading