Restructure Pkg interaction

This commit is contained in:
TEC 2024-02-29 03:33:07 +08:00
parent c28e511a8a
commit 5f896490e9
Signed by: tec
SSH Key Fingerprint: SHA256:eobz41Mnm0/iYWBvWThftS0ElEs1ftBr6jamutnXc/A
4 changed files with 193 additions and 170 deletions

View File

@ -1,139 +1,6 @@
module PkgExt
import Setup: lazypkg
import Markdown: @md_str
const Pkg = lazypkg()
function stack(envs)
if isempty(envs)
printstyled(" The current stack:\n", bold=true)
println.(" " .* LOAD_PATH)
else
for env in envs
if env LOAD_PATH
push!(LOAD_PATH, env)
end
end
end
end
const STACK_SPEC = Pkg.REPLMode.CommandSpec(
name = "stack",
api = stack,
help = md"""
stack envs...
Stack another environment.
""",
description = "Stack another environment",
completions = if VERSION < v"1.11-DEV.0"
Pkg.REPLMode.complete_activate
else
Pkg.REPLMode.get_complete_function(:complete_activate)
end,
should_splat = false,
arg_count = 0 => Inf)
function unstack(envs)
if isempty(envs)
printstyled(" The current stack:\n", bold=true)
println.(" " .* LOAD_PATH)
else
deleteat!(LOAD_PATH, sort(filter(!isnothing, indexin(envs, LOAD_PATH))))
end
end
const UNSTACK_SPEC = Pkg.REPLMode.CommandSpec(
name = "unstack",
api = unstack,
help = md"""
unstack envs...
Unstack a previously stacked environment.
""",
description = "Unstack an environment",
completions = (_, partial, _, _) ->
filter(p -> startswith(p, partial), LOAD_PATH),
should_splat = false,
arg_count = 0 => Inf)
function environments()
envs = String[]
for depot in Base.DEPOT_PATH
envdir = joinpath(depot, "environments")
isdir(envdir) || continue
for env in readdir(envdir)
if !isnothing(match(r"^__", env))
elseif !isnothing(match(r"^v\d+\.\d+$", env))
else
push!(envs, '@' * env)
end
end
end
envs = Base.DEFAULT_LOAD_PATH LOAD_PATH envs
for env in envs
if env in LOAD_PATH
print(" ", env)
else
printstyled(" ", env, color=:light_black)
if env in Base.DEFAULT_LOAD_PATH
printstyled(" (unloaded)", color=:light_red)
end
end
if env == "@"
printstyled(" [current environment]", color=:light_black)
elseif env == "@v#.#"
printstyled(" [global environment]", color=:light_black)
elseif env == "@stdlib"
printstyled(" [standard library]", color=:light_black)
elseif env in LOAD_PATH
printstyled(" (loaded)", color=:green)
end
print('\n')
end
end
const ENVS_SPEC = Pkg.REPLMode.CommandSpec(
name = "environments",
short_name = "envs",
api = environments,
help = md"""
environments|envs
List all known named environments.
""",
description = "List all known named environments",
arg_count = 0 => 0)
const SPECS = Dict(
"stack" => STACK_SPEC,
"unstack" => UNSTACK_SPEC,
"environments" => ENVS_SPEC,
"envs" => ENVS_SPEC)
function __init__()
# add the commands to the repl
activate = Pkg.REPLMode.SPECS["package"]["activate"]
let temp = Pkg.REPLMode.OptionSpec("temp", "t", :temp => true, false)
activate.option_specs["temp"] = temp
activate.option_specs["t"] = temp
end
activate_modified = Pkg.REPLMode.CommandSpec(
activate.canonical_name,
"a", # Modified entry, short name
activate.api,
activate.should_splat,
activate.argument_spec,
activate.option_specs,
activate.completions,
activate.description,
activate.help)
SPECS["activate"] = activate_modified
SPECS["a"] = activate_modified
Pkg.REPLMode.SPECS["package"] = merge(Pkg.REPLMode.SPECS["package"], SPECS)
# update the help with the new commands
copy!(Pkg.REPLMode.help.content, Pkg.REPLMode.gen_help().content)
end
include(joinpath(dirname(@__DIR__), "src", "pkgstack.jl"))
using .PkgStack
end

View File

@ -18,6 +18,8 @@ include("cmdpuns.jl")
include("termsetup.jl")
include("about.jl")
include("pkgutils.jl")
include("autoloads.jl")
using .Autoloads
include("autoload_data.jl")
@ -25,41 +27,6 @@ include("autoload_data.jl")
include("sessions.jl")
using .Sessions
@static if VERSION <= v"1.10"
const Pkg = let pkg_id = Base.PkgId(Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f"), "Pkg")
@something(get(Base.loaded_modules, pkg_id, nothing),
Base.require(pkg_id))
end
lazypkg() = Pkg
include("../ext/PkgExt.jl")
using .PkgExt
else
function lazypkg()
pkg_id = Base.PkgId(Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f"), "Pkg")
@something(get(Base.loaded_modules, pkg_id, nothing),
Base.require(pkg_id))
end
end
function ensureglobalpkg(pkg::String)
if isnothing(Base.find_package(pkg))
Pkg = lazypkg()
oldproj = Base.current_project()
try
Pkg.activate()
@info "Installing $pkg"
Pkg.add(pkg)
finally
if isnothing(oldproj)
Pkg.activate()
else
Pkg.activate(oldproj)
end
end
end
end
function theme_term end # For cairomakie.jl
function __init__()

142
src/pkgstack.jl Normal file
View File

@ -0,0 +1,142 @@
module PkgStack
import Markdown: @md_str
import Setup: lazypkg
const Pkg = lazypkg()
function stack(envs)
if isempty(envs)
printstyled(" The current stack:\n", bold=true)
println.(" " .* LOAD_PATH)
else
for env in envs
if env LOAD_PATH
push!(LOAD_PATH, env)
end
end
end
end
const STACK_SPEC = Pkg.REPLMode.CommandSpec(
name = "stack",
api = stack,
help = md"""
stack envs...
Stack another environment.
""",
description = "Stack another environment",
completions = if VERSION < v"1.11-DEV.0"
Pkg.REPLMode.complete_activate
else
Pkg.REPLMode.get_complete_function(:complete_activate)
end,
should_splat = false,
arg_count = 0 => Inf)
function unstack(envs)
if isempty(envs)
printstyled(" The current stack:\n", bold=true)
println.(" " .* LOAD_PATH)
else
deleteat!(LOAD_PATH, sort(filter(!isnothing, indexin(envs, LOAD_PATH))))
end
end
const UNSTACK_SPEC = Pkg.REPLMode.CommandSpec(
name = "unstack",
api = unstack,
help = md"""
unstack envs...
Unstack a previously stacked environment.
""",
description = "Unstack an environment",
completions = (_, partial, _, _) ->
filter(p -> startswith(p, partial), LOAD_PATH),
should_splat = false,
arg_count = 0 => Inf)
function environments()
envs = String[]
for depot in Base.DEPOT_PATH
@show depot
envdir = joinpath(depot, "environments")
isdir(envdir) || continue
for env in readdir(envdir)
if !isnothing(match(r"^__", env))
@info "Skip(1) $env"
elseif !isnothing(match(r"^v\d+\.\d+$", env))
@info "Skip(2) $env"
else
push!(envs, '@' * env)
end
end
end
envs = Base.DEFAULT_LOAD_PATH LOAD_PATH envs
for env in envs
if env in LOAD_PATH
print(" ", env)
else
printstyled(" ", env, color=:light_black)
if env in Base.DEFAULT_LOAD_PATH
printstyled(" (unloaded)", color=:light_red)
end
end
if env == "@"
printstyled(" [current environment]", color=:light_black)
elseif env == "@v#.#"
printstyled(" [global environment]", color=:light_black)
elseif env == "@stdlib"
printstyled(" [standard library]", color=:light_black)
elseif env in LOAD_PATH
printstyled(" (loaded)", color=:green)
end
print('\n')
end
end
const ENVS_SPEC = Pkg.REPLMode.CommandSpec(
name = "environments",
short_name = "envs",
api = environments,
help = md"""
environments|envs
List all known named environments.
""",
description = "List all known named environments",
arg_count = 0 => 0)
const SPECS = Dict(
"stack" => STACK_SPEC,
"unstack" => UNSTACK_SPEC,
"environments" => ENVS_SPEC,
"envs" => ENVS_SPEC)
function __init__()
# add the commands to the repl
activate = Pkg.REPLMode.SPECS["package"]["activate"]
let temp = Pkg.REPLMode.OptionSpec("temp", "t", :temp => true, false)
activate.option_specs["temp"] = temp
activate.option_specs["t"] = temp
end
activate_modified = Pkg.REPLMode.CommandSpec(
activate.canonical_name,
"a", # Modified entry, short name
activate.api,
activate.should_splat,
activate.argument_spec,
activate.option_specs,
activate.completions,
activate.description,
activate.help)
SPECS["activate"] = activate_modified
SPECS["a"] = activate_modified
Pkg.REPLMode.SPECS["package"] = merge(Pkg.REPLMode.SPECS["package"], SPECS)
# update the help with the new commands
copy!(Pkg.REPLMode.help.content, Pkg.REPLMode.gen_help().content)
end
end

47
src/pkgutils.jl Normal file
View File

@ -0,0 +1,47 @@
@static if VERSION <= v"1.10"
const Pkg = let pkg_id = Base.PkgId(Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f"), "Pkg")
@something(get(Base.loaded_modules, pkg_id, nothing),
Base.require(pkg_id))
end
lazypkg() = Pkg
include("../ext/PkgExt.jl")
using .PkgExt
else
const Pkg = Ref{Module}()
function lazypkg()
if !isassigned(Pkg)
pkg_id = Base.PkgId(Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f"), "Pkg")
Pkg[] = @something(get(Base.loaded_modules, pkg_id, nothing),
Base.require(pkg_id))
end
Pkg[]
end
end
function withproject(f::Function, proj::Union{String, Nothing})
Pkg = lazypkg()
oldproj = Base.current_project()
try
if isnothing(proj)
Pkg.activate()
else
Pkg.activate(proj)
end
f()
finally
if isnothing(oldproj)
Pkg.activate()
else
Pkg.activate(oldproj)
end
end
end
function ensureglobalpkg(pkg::String)
isnothing(Base.find_package(pkg)) || return
withproject(nothing) do
@info "Installing $pkg"
lazypkg().add(pkg)
end
end