Skip to content

Fix #117: Support bootstrap on read-only installations (e.g., Nix store)#193

Open
KaoruBB wants to merge 2 commits intogcv:masterfrom
KaoruBB:fix/read-only-pkg-env-bootstrap
Open

Fix #117: Support bootstrap on read-only installations (e.g., Nix store)#193
KaoruBB wants to merge 2 commits intogcv:masterfrom
KaoruBB:fix/read-only-pkg-env-bootstrap

Conversation

@KaoruBB
Copy link
Copy Markdown

@KaoruBB KaoruBB commented Mar 7, 2026

This PR fixes #117 by adding a writable environment fallback for the bootstrap process. It uses a hashed environment cache in DEPOT_PATH if the installation directory is read-only.

Fixes #117

KaoruBB added 2 commits March 7, 2026 17:04
Refactor macro to handle unwritable envs and Activation fallback
Ensure dir and action are properly escaped to avoid hygiene issues in macro expansion.
Copilot AI review requested due to automatic review settings March 7, 2026 08:48
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates JuliaSnail’s bootstrap/environment handling to work when the installation directory is read-only (e.g., Nix store) by creating a writable cached environment under DEPOT_PATH and activating it during bootstrap.

Changes:

  • Added pkg_env_for_bootstrap(dir) to redirect bootstrapping to a writable cached environment when dir is not writable.
  • Updated @with_pkg_env to activate the selected environment, retry the action after instantiating/precompiling when bootstrap is required, and restore the previously active project afterward.
  • Added bootstrap_required(err) to broaden bootstrap detection to include certain LoadError cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +23 to +24
env_name = "julia-snail-" * string(hash(abspath(dir)), base=16)
cache = joinpath(first(Base.DEPOT_PATH), "environments", env_name)
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

env_name is derived from hash(abspath(dir)), but hash is intentionally not stable across Julia sessions (seeded), so the cache directory name may change between runs. That defeats the purpose of a persistent bootstrap cache and can create a new environment on every startup. Consider using a deterministic digest of abspath(dir) (e.g., SHA-1/SHA-256 via the SHA stdlib) or another stable encoding instead.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +24
function pkg_env_for_bootstrap(dir)
if iswritable(dir)
return dir
end
env_name = "julia-snail-" * string(hash(abspath(dir)), base=16)
cache = joinpath(first(Base.DEPOT_PATH), "environments", env_name)
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache location uses first(Base.DEPOT_PATH). If the first depot is not writable (or DEPOT_PATH is empty/misconfigured), mkpath(cache) / cp(...) will fail, which undermines the read-only-installation support this PR adds. Consider selecting the first writable depot in Base.DEPOT_PATH (or falling back to tempdir() with a clear error if none are writable).

Suggested change
function pkg_env_for_bootstrap(dir)
if iswritable(dir)
return dir
end
env_name = "julia-snail-" * string(hash(abspath(dir)), base=16)
cache = joinpath(first(Base.DEPOT_PATH), "environments", env_name)
function first_writable_depot_or_tempdir()
# Try to find a writable depot in Base.DEPOT_PATH
for depot in Base.DEPOT_PATH
if iswritable(depot)
return depot
end
end
# Fall back to a writable temporary directory
tmp = tempdir()
if iswritable(tmp)
return tmp
end
error("JuliaSnail: no writable depot in Base.DEPOT_PATH and tempdir() is not writable; cannot create cache environment.")
end
function pkg_env_for_bootstrap(dir)
if iswritable(dir)
return dir
end
env_name = "julia-snail-" * string(hash(abspath(dir)), base=16)
cache_root = first_writable_depot_or_tempdir()
cache = joinpath(cache_root, "environments", env_name)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support installation in read-only locations (e.g. through nixpkgs)

2 participants