Skip to content
Merged
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
7 changes: 1 addition & 6 deletions src/Operations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -810,12 +810,7 @@ function download_source(ctx::Context; readonly=true)
max_name = maximum(widths; init=0)

# Check what registries the current pkg server tracks
# Disable if precompiling to not access internet
server_registry_info = if Base.JLOptions().incremental == 0
Registry.pkg_server_registry_info()
else
nothing
end
server_registry_info = Registry.pkg_server_registry_info()

@sync begin
jobs = Channel{eltype(pkgs_to_install)}(ctx.num_concurrent_downloads)
Expand Down
94 changes: 93 additions & 1 deletion src/Pkg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,98 @@ function _auto_precompile(ctx::Types.Context, pkgs::Vector{PackageSpec}=PackageS
end
end

include("precompile.jl")
using LibGit2: LibGit2
using Tar: Tar
function _run_precompilation_script_setup()
tmp = mktempdir()
cd(tmp)
empty!(DEPOT_PATH)
pushfirst!(DEPOT_PATH, tmp)
touch("Project.toml")
Pkg.activate(".")
Pkg.generate("TestPkg")
uuid = TOML.parsefile(joinpath("TestPkg", "Project.toml"))["uuid"]
mv("TestPkg", "TestPkg.jl")
tree_hash = cd("TestPkg.jl") do
sig = LibGit2.Signature("TEST", "[email protected]", round(time()), 0)
repo = LibGit2.init(".")
LibGit2.add!(repo, "")
commit = LibGit2.commit(repo, "initial commit"; author=sig, committer=sig)
th = LibGit2.peel(LibGit2.GitTree, LibGit2.GitObject(repo, commit)) |> LibGit2.GitHash |> string
close(repo)
th
end
# Prevent cloning the General registry by adding a fake one
mkpath("registries/Registry/T/TestPkg")
write("registries/Registry/Registry.toml", """
name = "Registry"
uuid = "37c07fec-e54c-4851-934c-2e3885e4053e"
repo = "https://github.com/JuliaRegistries/Registry.git"
[packages]
$uuid = { name = "TestPkg", path = "T/TestPkg" }
""")
write("registries/Registry/T/TestPkg/Compat.toml", """
["0"]
julia = "1"
""")
write("registries/Registry/T/TestPkg/Deps.toml", """
["0"]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
""")
write("registries/Registry/T/TestPkg/Versions.toml", """
["0.1.0"]
git-tree-sha1 = "$tree_hash"
""")
write("registries/Registry/T/TestPkg/Package.toml", """
name = "TestPkg"
uuid = "$uuid"
repo = "$(escape_string(tmp))/TestPkg.jl"
""")
Tar.create("registries/Registry", "registries/Registry.tar")
cmd = `$(Pkg.PlatformEngines.exe7z()) a "registries/Registry.tar.gz" -tgzip "registries/Registry.tar"`
run(pipeline(cmd, stdout = stdout_f(), stderr = stderr_f()))
write("registries/Registry.toml", """
git-tree-sha1 = "11b5fad51c4f98cfe0c145ceab0b8fb63fed6f81"
uuid = "37c07fec-e54c-4851-934c-2e3885e4053e"
path = "Registry.tar.gz"
""")
Base.rm("registries/Registry"; recursive=true)
return tmp
end

function _run_precompilation_script_artifact()
# Create simple artifact, bind it, then use it:
foo_hash = Pkg.Artifacts.create_artifact(dir -> touch(joinpath(dir, "foo")))
Artifacts.bind_artifact!("./Artifacts.toml", "foo", foo_hash)
# Also create multiple platform-specific ones because that's a codepath we need precompiled
Artifacts.bind_artifact!("./Artifacts.toml", "foo_plat", foo_hash; platform=Base.BinaryPlatforms.HostPlatform())
# Because @artifact_str doesn't work at REPL-level, we JIT out a file that we can include()
write("load_artifact.jl", """
Pkg.Artifacts.artifact"foo"
Pkg.Artifacts.artifact"foo_plat"
""")
foo_path = include("load_artifact.jl")
end

const CTRL_C = '\x03'
const precompile_script = """
import Pkg
_pwd = pwd()
Pkg.UPDATED_REGISTRY_THIS_SESSION[] = true
tmp = Pkg._run_precompilation_script_setup()
$CTRL_C
Pkg.add("TestPkg")
Pkg.develop(Pkg.PackageSpec(path="TestPkg.jl"))
Pkg.add(Pkg.PackageSpec(path="TestPkg.jl/"))
Pkg.REPLMode.try_prompt_pkg_add(Symbol[:notapackage])
Pkg.update(; update_registry=false)
Pkg.precompile()
] add Te\t\t$CTRL_C
] st
$CTRL_C
Pkg._run_precompilation_script_artifact()
rm(tmp; recursive=true)
cd(_pwd)
"""

end # module
117 changes: 0 additions & 117 deletions src/precompile.jl

This file was deleted.

53 changes: 53 additions & 0 deletions test/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,59 @@ end
include("FakeTerminals.jl")
import .FakeTerminals.FakeTerminal

@testset "Pkg.precompile_script" begin
function fake_repl(@nospecialize(f); options::REPL.Options=REPL.Options(confirm_exit=false))
# Use pipes so we can easily do blocking reads
# In the future if we want we can add a test that the right object
# gets displayed by intercepting the display
input = Pipe()
output = Pipe()
err = Pipe()
Base.link_pipe!(input, reader_supports_async=true, writer_supports_async=true)
Base.link_pipe!(output, reader_supports_async=true, writer_supports_async=true)
Base.link_pipe!(err, reader_supports_async=true, writer_supports_async=true)

repl = REPL.LineEditREPL(FakeTerminal(input.out, output.in, err.in), true)
repl.options = options

f(input.in, output.out, repl)
t = @async begin
close(input.in)
close(output.in)
close(err.in)
end
@test read(err.out, String) == ""
#display(read(output.out, String))
Base.wait(t)
nothing
end
pwd_before = pwd()
fake_repl() do stdin_write, stdout_read, repl
repltask = @async REPL.run_repl(repl)

for line in split(Pkg.precompile_script, "\n"; keepempty=false)
sleep(0.1)
# Consume any extra output
if bytesavailable(stdout_read) > 0
copyback = readavailable(stdout_read)
#@info(copyback)
end

# Write the line
write(stdin_write, line, "\n")

# Read until some kind of prompt
readuntil(stdout_read, "\n")
readuntil(stdout_read, ">")
#@info(line)
end

write(stdin_write, "\x04")
wait(repltask)
end
cd(pwd_before) # something in the precompile_script changes the working directory
end

@testset "Pkg.precompile" begin
# sequential precompile, depth-first
isolate() do; cd_tempdir() do tmp
Expand Down