Skip to content

Commit 750f8cb

Browse files
awadell1KristofferC
authored andcommitted
Fix --project=@script when outside script directory (#56351)
(cherry picked from commit d9764d6)
1 parent eaad6fe commit 750f8cb

File tree

8 files changed

+30
-18
lines changed

8 files changed

+30
-18
lines changed

base/initdefs.jl

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -284,22 +284,14 @@ function load_path_expand(env::AbstractString)::Union{String, Nothing}
284284
env == "@temp" && return mktempdir()
285285
env == "@stdlib" && return Sys.STDLIB
286286
if startswith(env, "@script")
287-
if @isdefined(PROGRAM_FILE)
288-
dir = dirname(PROGRAM_FILE)
289-
else
290-
cmds = unsafe_load_commands(JLOptions().commands)
291-
if any(cmd::Pair{Char, String}->cmd_suppresses_program(first(cmd)), cmds)
292-
# Usage error. The user did not pass a script.
293-
return nothing
294-
end
295-
dir = dirname(ARGS[1])
296-
end
297-
if env == "@script" # complete match, not startswith, so search upwards
298-
return current_project(dir)
299-
else
300-
# starts with, so assume relative path is after
301-
return abspath(replace(env, "@script" => dir))
302-
end
287+
program_file = JLOptions().program_file
288+
program_file = program_file != C_NULL ? unsafe_string(program_file) : nothing
289+
isnothing(program_file) && return nothing # User did not pass a script
290+
291+
# Expand trailing relative path
292+
dir = dirname(program_file)
293+
dir = env != "@script" ? (dir * env[length("@script")+1:end]) : dir
294+
return current_project(dir)
303295
end
304296
env = replace(env, '#' => VERSION.major, count=1)
305297
env = replace(env, '#' => VERSION.minor, count=1)

base/options.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ struct JLOptions
1717
nprocs::Int32
1818
machine_file::Ptr{UInt8}
1919
project::Ptr{UInt8}
20+
program_file::Ptr{UInt8}
2021
isinteractive::Int8
2122
color::Int8
2223
historyfile::Int8

src/jloptions.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ JL_DLLEXPORT void jl_init_options(void)
104104
0, // nprocs
105105
NULL, // machine_file
106106
NULL, // project
107+
NULL, // program_file
107108
0, // isinteractive
108109
0, // color
109110
JL_OPTIONS_HISTORYFILE_ON, // history file
@@ -169,11 +170,12 @@ static const char opts[] =
169170
" --help-hidden Print uncommon options not shown by `-h`\n\n"
170171

171172
// startup options
172-
" --project[={<dir>|@temp|@.}] Set <dir> as the active project/environment.\n"
173+
" --project[={<dir>|@temp|@.|@script[<rel>]}] Set <dir> as the active project/environment.\n"
173174
" Or, create a temporary environment with `@temp`\n"
174175
" The default @. option will search through parent\n"
175176
" directories until a Project.toml or JuliaProject.toml\n"
176-
" file is found.\n"
177+
" file is found. @script is similar, but searches up from\n"
178+
" the programfile or a path relative to programfile.\n"
177179
" -J, --sysimage <file> Start up with the given system image file\n"
178180
" -H, --home <dir> Set location of `julia` executable\n"
179181
" --startup-file={yes*|no} Load `JULIA_DEPOT_PATH/config/startup.jl`; \n"
@@ -1012,6 +1014,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
10121014
"This is a bug, please report it.", c);
10131015
}
10141016
}
1017+
jl_options.program_file = optind < argc ? strdup(argv[optind]) : "";
10151018
parsing_args_done:
10161019
if (!jl_options.use_experimental_features) {
10171020
if (jl_options.trim != JL_TRIM_NO)

src/jloptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ typedef struct {
2121
int32_t nprocs;
2222
const char *machine_file;
2323
const char *project;
24+
const char *program_file;
2425
int8_t isinteractive;
2526
int8_t color;
2627
int8_t historyfile;

test/cmdlineargs.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,16 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no`
257257
@test expanded == readchomp(addenv(`$exename -e 'println(Base.active_project())'`, "JULIA_PROJECT" => "@foo", "HOME" => homedir()))
258258
end
259259

260+
# --project=@script handling
261+
let expanded = abspath(joinpath(@__DIR__, "project", "ScriptProject"))
262+
script = joinpath(expanded, "bin", "script.jl")
263+
# Check running julia with --project=@script both within and outside the script directory
264+
@testset "--@script from $name" for (name, dir) in [("project", expanded), ("outside", pwd())]
265+
@test joinpath(expanded, "Project.toml") == readchomp(Cmd(`$exename --project=@script $script`; dir))
266+
@test joinpath(expanded, "SubProject", "Project.toml") == readchomp(Cmd(`$exename --project=@script/../SubProject $script`; dir))
267+
end
268+
end
269+
260270
# handling of `@temp` in --project and JULIA_PROJECT
261271
@test tempdir() == readchomp(`$exename --project=@temp -e 'println(Base.active_project())'`)[1:lastindex(tempdir())]
262272
@test tempdir() == readchomp(addenv(`$exename -e 'println(Base.active_project())'`, "JULIA_PROJECT" => "@temp", "HOME" => homedir()))[1:lastindex(tempdir())]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
name = "ScriptProject"
2+
uuid = "6646321a-c4de-46ad-9761-435e5bb1f223"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
name = "SubProject"
2+
uuid = "50d58d6a-5ae2-46f7-9677-83c51ca667d5"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
println(Base.active_project())

0 commit comments

Comments
 (0)