Skip to content

Commit

Permalink
Allow --project=@scriptdir for easier co-packaging of scripts and p… (
Browse files Browse the repository at this point in the history
#50864)

…rojects

I have a directory with a number of runnable scripts and a Project.toml
that applies to all of them. I was hoping to have a simple shebang line
for these, but there didn't really seem to be a good way to set the
`--project` without forcing the script to be invoked with a specific cwd
or playing complicated shebang games. With this PR, you can simply
write:

```
#!/usr/bin/env -S julia --project=@scriptdir/..
```

and everything will work out of the box. Perhaps we already have a good
mechanism for this, but if so, I was unable to find it, so in that case,
consider this a documentation issue instead ;).
  • Loading branch information
Keno committed Aug 18, 2023
1 parent 49e6ff8 commit ec07825
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
6 changes: 2 additions & 4 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ function incomplete_tag(ex::Expr)
end
incomplete_tag(exc::Meta.ParseError) = incomplete_tag(exc.detail)

cmd_suppresses_program(cmd) = cmd in ('e', 'E')
function exec_options(opts)
quiet = (opts.quiet != 0)
startup = (opts.startupfile != 2)
Expand All @@ -238,10 +239,7 @@ function exec_options(opts)
repl = !arg_is_program
cmds = unsafe_load_commands(opts.commands)
for (cmd, arg) in cmds
if cmd == 'e'
arg_is_program = false
repl = false
elseif cmd == 'E'
if cmd_suppresses_program(cmd)
arg_is_program = false
repl = false
elseif cmd == 'L'
Expand Down
13 changes: 13 additions & 0 deletions base/initdefs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,19 @@ function load_path_expand(env::AbstractString)::Union{String, Nothing}
env == "@" && return active_project(false)
env == "@." && return current_project()
env == "@stdlib" && return Sys.STDLIB
if startswith(env, "@scriptdir")
if @isdefined(PROGRAM_FILE)
dir = dirname(PROGRAM_FILE)
else
cmds = unsafe_load_commands(opts.commands)
if any((cmd, arg)->cmd_suppresses_program(cmd), cmds)
# Usage error. The user did not pass a script.
return nothing
end
dir = dirname(ARGS[1])
end
return abspath(replace(env, "@scriptdir" => dir))
end
env = replace(env, '#' => VERSION.major, count=1)
env = replace(env, '#' => VERSION.minor, count=1)
env = replace(env, '#' => VERSION.patch, count=1)
Expand Down

0 comments on commit ec07825

Please sign in to comment.