I might have done some modifications. I will put here the two scripts I use :
The first one for exporting a zip file containing all the packages useful for a given project
import Pkg.Types: PackageSpec,GitRepo,Context,project_deps_resolve!,registry_resolve!,stdlib_resolve!,ensure_resolved,manifest_info,write_env,update_registries,pkgerror,printpkgstyle
import Pkg.activate
import Pkg.Operations:resolve_versions!,version_data!,install_archive
import Pkg.BinaryProvider
import Pkg:depots1
using UUIDs
import LibGit2
function main(path_to_project,path_to_external)
!isdir(path_to_external) ? mkdir(path_to_external) : nothing
activate(path_to_project)
ctx=Context()
println("Project Path : " * path_to_project)
println("Using : " * ctx.env.manifest_file * "\n"
*" " * ctx.env.project_file)
println("Copying these files to " * path_to_external)
Base.cp(ctx.env.project_file,joinpath(path_to_external,basename(ctx.env.project_file)),force=true)
Base.cp(ctx.env.manifest_file,joinpath(path_to_external,basename(ctx.env.manifest_file)),force=true)
project = ctx.env.project
registry_path = joinpath(depots1(),"registries")
registry_path_extern = joinpath(path_to_external,"registries")
mkpath(registry_path_extern)
Base.cp(registry_path,registry_path_extern,force=true)
pkgs = [ PackageSpec(k,v) for (k,v) in project.deps ]
project_deps_resolve!(ctx.env,pkgs)
registry_resolve!(ctx.env,pkgs)
stdlib_resolve!(ctx,pkgs)
ensure_resolved(ctx.env,pkgs)
for pkg in pkgs
ctx.env.project.deps[pkg.name] = pkg.uuid
end
for (name::String, uuid::UUID) in ctx.env.project.deps
entry = manifest_info(ctx.env, uuid)
entry !== nothing && entry.version !== nothing || continue
version = VersionNumber(entry.version)
for pkg in pkgs
pkg.uuid == uuid && version ∈ pkg.version || continue
pkg.version = version
end
end
resolve_versions!(ctx, pkgs)
hashes, urls = version_data!(ctx, pkgs)
for pkg in pkgs
pkg.uuid in keys(ctx.stdlibs) && continue
pkg.repo = GitRepo(urls[pkg.uuid][1],nothing,nothing)
end
BinaryProvider.probe_platform_engines!()
pkgs_to_install = Tuple{PackageSpec, String}[]
for pkg in pkgs
pkg.uuid in keys(ctx.stdlibs) && continue
path = joinpath(path_to_external,pkg.name,Base.version_slug(pkg.uuid,hashes[pkg.uuid]))
if !isdir(path)
push!(pkgs_to_install, (pkg, path))
end
end
widths = [textwidth(pkg.name) for (pkg, _) in pkgs_to_install]
max_name = length(widths) == 0 ? 0 : maximum(widths)
results = Channel(length(pkgs));
i=1
for (pkg, path) in pkgs_to_install
print(" $i over $(length(pkgs_to_install)) downloaded packages\n
Currently processing $(pkg)\r")
try
success = install_archive(urls[pkg.uuid], hashes[pkg.uuid], path)
if ctx.use_only_tarballs_for_downloads && !success
pkgerror("failed to get tarball from $(urls[pkg.uuid])")
end
put!(results, (pkg, success, path))
catch err
put!(results, (pkg, err, catch_backtrace()))
end
i+=1
end
missed_packages = Tuple{PackageSpec, String}[]
for i in 1:length(pkgs_to_install)
pkg, exc_or_success, bt_or_path = take!(results)
exc_or_success isa Exception && pkgerror("Error when installing package $(pkg.name):\n",
sprint(Base.showerror, exc_or_success, bt_or_path))
success, path = exc_or_success, bt_or_path
if success
vstr = pkg.version != nothing ? "v$(pkg.version)" : "[$h]"
printpkgstyle(ctx, :Installed, string(rpad(pkg.name * " ", max_name + 2, "─"), " ", vstr))
else
push!(missed_packages, (pkg, path))
end
end
for (pkg, path) in missed_packages
uuid = pkg.uuid
if !ctx.preview
install_git(ctx, pkg.uuid, pkg.name, hashes[uuid], urls[uuid], pkg.version::VersionNumber, path)
end
vstr = pkg.version != nothing ? "v$(pkg.version)" : "[$h]"
@info "Installed $(rpad(pkg.name * " ", max_name + 2, "─")) $vstr"
end
end
path_to_project = "your_project_path"
path_to_external = "where_to_export"
main(path_to_project,path_to_external)
## Optional, create a .zip with all the packages
zip_exe = "path_to_zip_exe"
zip_name = abspath(joinpath(path_to_external,"../julia_packages.zip"))
command = `cmd /c $(zip_exe) u -tzip $(zip_name) $(path_to_project) $(path_to_external)`
run(command)
Now that you have your .zip file or the folder with all the packages, you can put this on the offline computer and make the installation with the following script
import Pkg:activate,depots1
import Pkg.Types:Context
import Pkg.Operations:build_versions
function add_local_packagesv11(pkgs_path,project_path)
activate(project_path)
ctx=Context()
uuids_to_build=collect(keys(ctx.env.manifest))
files=Set(readdir(pkgs_path))
pop!(files,"Manifest.toml")
pop!(files,"Project.toml")
registry_path = joinpath(depots1(),"registries")
Base.cp(joinpath(pkgs_path,pop!(files,"registries")),registry_path,force=true)
default_path=joinpath(depots1(),"packages")
for file in files
path = joinpath(pkgs_path,file)
path_project = joinpath(default_path,file)
versions_pkgs = Set(readdir(path))
versions_project = isdir(path_project) ? Set(readdir(path_project)) : Set()
for version in setdiff(versions_pkgs,versions_project)
path_version = joinpath(path_project,version)
path_pkg_version = joinpath(path,version)
mkpath(path_version)
Base.cp(path_pkg_version,path_version,force=true)
end
end
build_versions(ctx,uuids_to_build)
end
pkgs_path = "where_the_exported_packages_are"
project_path = "path_to_project"
pkgs_path= joinpath(pkgs_path,project_path)
add_local_packagesv11(pkgs_path,project_path)
This script only install new packages or newer versions, if you want to override a package you can manually delete it or slightly modify this script with options.
Try with these scripts and let me know if you still have problems. Also, some packages need to be built with libraries, you will need to look in build.jl
files for download links and put libraries under pkg_being_built/deps/usr/downloads
( or sometimes pkg_being_built/deps/usr
) and make sure that during build the build.jl
doesnt delete the library you just manually installed ( you can pass a cat build.jl | grep rm
to check this ).
Hope this help.