Skip to content
Open
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: 7 additions & 0 deletions pre_commit/languages/julia.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ def get_env_patch(target_dir: str, version: str) -> PatchesT:
('JULIA_LOAD_PATH', target_dir),
# May be set, remove it to not interfer with LOAD_PATH
('JULIA_PROJECT', UNSET),
# Keep the package depot inside the hook environment so installed
# packages and precompile caches persist with the env instead of
# leaking into a shared depot. The trailing separator leaves an empty
# entry, which julia expands to its default depots. This keeps the
# bundled stdlib resources (and their precompile caches) available so
# hooks don't recompile from scratch on first run.
('JULIA_DEPOT_PATH', os.path.join(target_dir, 'depot') + os.pathsep),
)


Expand Down
3 changes: 2 additions & 1 deletion pre_commit/xargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def cpu_count() -> int:
# On systems that support it, this will return a more accurate count of
# usable CPUs for the current process, which will take into account
# cgroup limits
return len(os.sched_getaffinity(0))
sched_getaffinity = getattr(os, 'sched_getaffinity')
return len(sched_getaffinity(0))
except AttributeError:
pass

Expand Down
55 changes: 46 additions & 9 deletions tests/languages/julia_test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from __future__ import annotations

import os
from unittest import mock

from pre_commit import constants as C
from pre_commit import lang_base
from pre_commit.envcontext import envcontext
from pre_commit.languages import julia
from pre_commit.prefix import Prefix
from testing.language_helpers import run_language
from testing.util import cwd

Expand Down Expand Up @@ -31,15 +34,49 @@ def test_julia_hook(tmp_path):
assert run_language(tmp_path, julia, 'src/main.jl') == expected


def test_julia_hook_installs_into_env_local_depot(tmp_path):
code = """
using Example
println("Hello, world!")
"""
_make_hook(tmp_path, code)

prefix = Prefix(str(tmp_path))
envdir = lang_base.environment_dir(
prefix, julia.ENVIRONMENT_DIR, C.DEFAULT,
)

# the depot julia points hooks at: first entry of its JULIA_DEPOT_PATH
patch = dict(julia.get_env_patch(envdir, C.DEFAULT))
julia_depot_path = patch['JULIA_DEPOT_PATH']
assert isinstance(julia_depot_path, str)
env_depot = julia_depot_path.split(os.pathsep)[0]
# it must live inside the per-hook env, not in a shared location
assert env_depot.startswith(envdir + os.sep)

# An ambient depot that the hook must ignore: get_env_patch overrides
# JULIA_DEPOT_PATH with the env-local depot so packages are installed there
# (and so persist with the hook env) rather than in a shared depot.
decoy_depot = os.path.join(str(tmp_path), 'decoy-depot')
with envcontext((('JULIA_DEPOT_PATH', decoy_depot + os.pathsep),)):
julia.install_environment(prefix, C.DEFAULT, ())

assert os.path.isdir(os.path.join(env_depot, 'packages', 'Example'))
decoy_example = os.path.join(decoy_depot, 'packages', 'Example')
assert not os.path.exists(decoy_example)


def test_julia_hook_with_startup(tmp_path):
depot_path = tmp_path.joinpath('depot')
depot_path.joinpath('config').mkdir(parents=True)
startup = depot_path.joinpath('config', 'startup.jl')
startup.write_text('error("Startup file used!")\n')

depo_path_var = f'{depot_path}{os.pathsep}'
with mock.patch.dict(os.environ, {'JULIA_DEPOT_PATH': depo_path_var}):
test_julia_hook(tmp_path)
# a startup.jl in the active (env-local) depot must not be evaluated
envdir = lang_base.environment_dir(
Prefix(str(tmp_path)), julia.ENVIRONMENT_DIR, C.DEFAULT,
)
config_dir = os.path.join(envdir, 'depot', 'config')
os.makedirs(config_dir)
with open(os.path.join(config_dir, 'startup.jl'), 'w') as f:
f.write('error("Startup file used!")\n')

test_julia_hook(tmp_path)


def test_julia_hook_manifest(tmp_path):
Expand Down
Loading