Skip to content

Commit cff8d5c

Browse files
committed
wip: Support portable scripts
1 parent 6aae107 commit cff8d5c

File tree

9 files changed

+444
-38
lines changed

9 files changed

+444
-38
lines changed

docs/src/toml-files.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ UUIDs etc.
1212
[Code Loading](https://docs.julialang.org/en/v1/manual/code-loading/)
1313
in the Julia manual.
1414

15-
1615
## `Project.toml`
1716

1817
The project file describes the project on a high level, for example, the package/project
@@ -542,3 +541,10 @@ uuid = "edca9bc6-334e-11e9-3554-9595dbb4349c"
542541

543542
There is now an array of the two `B` packages, and the `[deps]` section for `A` has been
544543
expanded to be explicit about which `B` package `A` depends on.
544+
## Portable scripts
545+
546+
Julia scripts can embed project and manifest data inline with fenced
547+
comments such as `#!project … #!project end` and `#!manifest … #!manifest end`.
548+
When the active project is set to a `.jl` file, Pkg reads and writes inline project metadata
549+
from that file. All commands that modify the project or manifest
550+
content (e.g. `Pkg.add`, `Pkg.rm`, `Pkg.update`) will update the inline sections accordingly.

ext/REPLExt/REPLExt.jl

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,20 @@ function projname(project_file::String)
6767
nothing
6868
end
6969
if project === nothing || project.name === nothing
70-
name = basename(dirname(project_file))
70+
# For .jl files, use the filename with extension as fallback
71+
# For directories/Project.toml, use the directory name
72+
if endswith(project_file, ".jl")
73+
name = basename(project_file)
74+
else
75+
name = basename(dirname(project_file))
76+
end
7177
else
72-
name = project.name::String
78+
# For portable scripts, include .jl extension to make it clear
79+
if endswith(project_file, ".jl")
80+
name = project.name::String * ".jl"
81+
else
82+
name = project.name::String
83+
end
7384
end
7485
for depot in Base.DEPOT_PATH
7586
envdir = joinpath(depot, "environments")
@@ -94,17 +105,25 @@ function promptf()
94105
else
95106
project_name = projname(project_file)
96107
if project_name !== nothing
97-
root = Types.find_root_base_project(project_file)
98-
rootname = projname(root)
99-
if root !== project_file
100-
path_prefix = "/" * dirname(Types.relative_project_path(root, project_file))
108+
# For portable scripts (.jl files), don't show directory path
109+
if endswith(project_file, ".jl")
110+
if textwidth(project_name) > 30
111+
project_name = first(project_name, 27) * "..."
112+
end
113+
prefix = "($(project_name)) "
101114
else
102-
path_prefix = ""
103-
end
104-
if textwidth(rootname) > 30
105-
rootname = first(rootname, 27) * "..."
115+
root = Types.find_root_base_project(project_file)
116+
rootname = projname(root)
117+
if root !== project_file
118+
path_prefix = "/" * dirname(Types.relative_project_path(root, project_file))
119+
else
120+
path_prefix = ""
121+
end
122+
if textwidth(rootname) > 30
123+
rootname = first(rootname, 27) * "..."
124+
end
125+
prefix = "($(rootname)$(path_prefix)) "
106126
end
107-
prefix = "($(rootname)$(path_prefix)) "
108127
prev_prefix = prefix
109128
prev_project_timestamp = mtime(project_file)
110129
prev_project_file = project_file

src/API.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,10 @@ function activate(; temp = false, shared = false, prev = false, io::IO = stderr_
14051405
end
14061406
Base.ACTIVE_PROJECT[] = nothing
14071407
p = Base.active_project()
1408-
p === nothing || printpkgstyle(io, :Activating, "project at $(pathrepr(dirname(p)))")
1408+
if p !== nothing
1409+
loc = endswith(p, ".jl") ? pathrepr(p) : "$(pathrepr(dirname(p)))"
1410+
printpkgstyle(io, :Activating, "project at $loc")
1411+
end
14091412
add_snapshot_to_undo()
14101413
return nothing
14111414
end
@@ -1465,7 +1468,8 @@ function activate(path::AbstractString; shared::Bool = false, temp::Bool = false
14651468
p = Base.active_project()
14661469
if p !== nothing
14671470
n = ispath(p) ? "" : "new "
1468-
printpkgstyle(io, :Activating, "$(n)project at $(pathrepr(dirname(p)))")
1471+
loc = endswith(p, ".jl") ? pathrepr(p) : "$(pathrepr(dirname(p)))"
1472+
printpkgstyle(io, :Activating, "$(n)project at $loc")
14691473
end
14701474
add_snapshot_to_undo()
14711475
return nothing

src/Operations.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,8 +1537,8 @@ end
15371537
################################
15381538

15391539
function prune_manifest(env::EnvCache)
1540-
# if project uses another manifest, only prune project entry in manifest
1541-
if isempty(env.workspace) && dirname(env.project_file) != dirname(env.manifest_file)
1540+
# if project uses another manifest (and we are not a portable script), only prune project entry in manifest
1541+
if isempty(env.workspace) && dirname(env.project_file) != dirname(env.manifest_file) && !endswith(env.project_file, ".jl")
15421542
proj_entry = env.manifest[env.project.uuid]
15431543
proj_entry.deps = env.project.deps
15441544
else
@@ -3477,8 +3477,8 @@ function git_head_env(env, project_dir)
34773477
git_path = LibGit2.path(repo)
34783478
project_path = relpath(env.project_file, git_path)
34793479
manifest_path = relpath(env.manifest_file, git_path)
3480-
new_env.project = read_project(GitTools.git_file_stream(repo, "HEAD:$project_path", fakeit = true))
3481-
new_env.manifest = read_manifest(GitTools.git_file_stream(repo, "HEAD:$manifest_path", fakeit = true))
3480+
new_env.project = read_project(GitTools.git_file_stream(repo, "HEAD:$project_path", fakeit = true); source_file = project_path)
3481+
new_env.manifest = read_manifest(GitTools.git_file_stream(repo, "HEAD:$manifest_path", fakeit = true); source_file = manifest_path)
34823482
return new_env
34833483
end
34843484
catch err

0 commit comments

Comments
 (0)