From a7f8efa2ae1164d5fdc06bc19c8cfa5f37bf962d Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:57:32 +0200 Subject: [PATCH 1/8] improve julia support --- pre_commit/languages/julia.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pre_commit/languages/julia.py b/pre_commit/languages/julia.py index df91c0697..2f4495f82 100644 --- a/pre_commit/languages/julia.py +++ b/pre_commit/languages/julia.py @@ -37,7 +37,7 @@ def run_hook( cmd = lang_base.hook_cmd(entry, args) script = cmd[0] if is_local else prefix.path(cmd[0]) - cmd = ('julia', script, *cmd[1:]) + cmd = ('julia', '--startup-file=no', script, *cmd[1:]) return lang_base.run_xargs( cmd, file_args, @@ -45,14 +45,14 @@ def run_hook( color=color, ) - def get_env_patch(target_dir: str, version: str) -> PatchesT: - return ( + patches = [ ('JULIA_LOAD_PATH', target_dir), - # May be set, remove it to not interfer with LOAD_PATH ('JULIA_PROJECT', UNSET), - ) - + ] + if version not in ("system", "default"): + patches.append(('JULIAUP_CHANNEL', version)) + return tuple(patches) @contextlib.contextmanager def in_env(prefix: Prefix, version: str) -> Generator[None]: @@ -60,7 +60,6 @@ def in_env(prefix: Prefix, version: str) -> Generator[None]: with envcontext(get_env_patch(envdir, version)): yield - def install_environment( prefix: Prefix, version: str, @@ -68,10 +67,6 @@ def install_environment( ) -> None: envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version) with in_env(prefix, version): - # TODO: Support language_version with juliaup similar to rust via - # rustup - # if version != 'system': - # ... # Copy Project.toml to hook env if it exist os.makedirs(envdir, exist_ok=True) @@ -99,6 +94,11 @@ def install_environment( shutil.copy(manifest_file, envdir) break + # copy `src` files if they exist + src_dir = prefix.path("src") + if os.path.isdir(src_dir): + shutil.copytree(src_dir, os.path.join(envdir, 'src')) + # Julia code to instantiate the hook environment julia_code = """ @assert length(ARGS) > 0 @@ -127,6 +127,6 @@ def install_environment( end """ cmd_output_b( - 'julia', '-e', julia_code, '--', envdir, *additional_dependencies, + 'julia', '--startup-file=no', '-e', julia_code, '--', envdir, *additional_dependencies, cwd=prefix.prefix_dir, ) From 9583b19216c66af72518ae84067d9f0fe55cc4ee Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 14:07:45 +0000 Subject: [PATCH 2/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pre_commit/languages/julia.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pre_commit/languages/julia.py b/pre_commit/languages/julia.py index 2f4495f82..3e74d427a 100644 --- a/pre_commit/languages/julia.py +++ b/pre_commit/languages/julia.py @@ -45,21 +45,24 @@ def run_hook( color=color, ) + def get_env_patch(target_dir: str, version: str) -> PatchesT: patches = [ ('JULIA_LOAD_PATH', target_dir), ('JULIA_PROJECT', UNSET), ] - if version not in ("system", "default"): + if version not in ('system', 'default'): patches.append(('JULIAUP_CHANNEL', version)) return tuple(patches) + @contextlib.contextmanager def in_env(prefix: Prefix, version: str) -> Generator[None]: envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version) with envcontext(get_env_patch(envdir, version)): yield + def install_environment( prefix: Prefix, version: str, @@ -95,7 +98,7 @@ def install_environment( break # copy `src` files if they exist - src_dir = prefix.path("src") + src_dir = prefix.path('src') if os.path.isdir(src_dir): shutil.copytree(src_dir, os.path.join(envdir, 'src')) From 0c54b4772b918b378a939491023478b11057371b Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:20:56 +0200 Subject: [PATCH 3/8] make flake and mypy happier --- pre_commit/languages/julia.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pre_commit/languages/julia.py b/pre_commit/languages/julia.py index 3e74d427a..6d70edd99 100644 --- a/pre_commit/languages/julia.py +++ b/pre_commit/languages/julia.py @@ -5,11 +5,14 @@ import shutil from collections.abc import Generator from collections.abc import Sequence +from typing import Union from pre_commit import lang_base +from pre_commit.envcontext import _Unset from pre_commit.envcontext import envcontext from pre_commit.envcontext import PatchesT from pre_commit.envcontext import UNSET +from pre_commit.envcontext import Var from pre_commit.prefix import Prefix from pre_commit.util import cmd_output_b @@ -46,8 +49,11 @@ def run_hook( ) +PatchEntry = tuple[str, Union[str, _Unset, tuple[Union[str, Var], ...]]] + + def get_env_patch(target_dir: str, version: str) -> PatchesT: - patches = [ + patches: list[PatchEntry] = [ ('JULIA_LOAD_PATH', target_dir), ('JULIA_PROJECT', UNSET), ] @@ -130,6 +136,6 @@ def install_environment( end """ cmd_output_b( - 'julia', '--startup-file=no', '-e', julia_code, '--', envdir, *additional_dependencies, - cwd=prefix.prefix_dir, + 'julia', '--startup-file=no', '-e', julia_code, '--', envdir, + *additional_dependencies, cwd=prefix.prefix_dir, ) From 5501721fa9ecc66ab1cd7b62c89270d265d8c485 Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:37:07 +0200 Subject: [PATCH 4/8] add --- tests/languages/julia_test.py | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/languages/julia_test.py b/tests/languages/julia_test.py index 4ea3c25b2..2c47b1db7 100644 --- a/tests/languages/julia_test.py +++ b/tests/languages/julia_test.py @@ -95,3 +95,41 @@ def test_julia_repo_local(tmp_path): env_dir, julia, 'local.jl --local-arg1 --local-arg2', deps=deps, is_local=True, ) == expected + + +def _make_src_hook(tmp_path, pkg_code, script_code): + # here we have a package with a src dir and a script dir + src_dir = tmp_path.joinpath('src') + src_dir.mkdir() + src_dir.joinpath('ExamplePkg.jl').write_text(pkg_code) + + script_dir = tmp_path.joinpath('scripts') + script_dir.mkdir() + script_dir.joinpath('main.jl').write_text(script_code) + + tmp_path.joinpath('Project.toml').write_text( + 'name = "ExamplePkg"\n' + 'uuid = "df230c44-b485-4b6a-bafb-763c50abe554"\n' + '[deps]\n' + 'Example = "7876af07-990d-54b4-ab0e-23690620f79a"\n', + ) + + +def test_julia_hook_src(tmp_path): + pkg_code = """ + module ExamplePkg + using Example + export main + function main() + println("Hello, world!") + end + end + """ + + script_code = """ + using ExamplePkg + main() + """ + _make_src_hook(tmp_path, pkg_code, script_code) + expected = (0, b'Hello, world!\n') + assert run_language(tmp_path, julia, 'scripts/main.jl') == expected From ae6f19d8702a61fdec8aaf080b55025637537b11 Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Mon, 21 Jul 2025 16:51:14 +0200 Subject: [PATCH 5/8] add test for julia version support --- .github/workflows/languages.yaml | 5 ++++- pre_commit/languages/julia.py | 5 ++++- tests/languages/julia_test.py | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/languages.yaml b/.github/workflows/languages.yaml index fccf29892..6b84acc5e 100644 --- a/.github/workflows/languages.yaml +++ b/.github/workflows/languages.yaml @@ -67,7 +67,10 @@ jobs: if: matrix.language == 'haskell' - uses: r-lib/actions/setup-r@v2 if: matrix.os == 'ubuntu-latest' && matrix.language == 'r' - + - uses: julia-actions/install-juliaup@v2 + if: matrix.language == 'julia' + - run: juliaup add 1.10.10 + if: matrix.language == 'julia' - name: install deps run: python -mpip install -e . -r requirements-dev.txt - name: run tests diff --git a/pre_commit/languages/julia.py b/pre_commit/languages/julia.py index 6d70edd99..0ce31d39a 100644 --- a/pre_commit/languages/julia.py +++ b/pre_commit/languages/julia.py @@ -106,7 +106,10 @@ def install_environment( # copy `src` files if they exist src_dir = prefix.path('src') if os.path.isdir(src_dir): - shutil.copytree(src_dir, os.path.join(envdir, 'src')) + shutil.copytree( + src_dir, os.path.join(envdir, 'src'), + dirs_exist_ok=True, + ) # Julia code to instantiate the hook environment julia_code = """ diff --git a/tests/languages/julia_test.py b/tests/languages/julia_test.py index 2c47b1db7..ef6a5dcca 100644 --- a/tests/languages/julia_test.py +++ b/tests/languages/julia_test.py @@ -28,6 +28,22 @@ def test_julia_hook(tmp_path): assert run_language(tmp_path, julia, 'src/main.jl') == expected +def test_julia_hook_version(tmp_path): + code = """ + using Example + function main() + println("Hello, Julia $(VERSION)!") + end + main() + """ + _make_hook(tmp_path, code) + expected = (0, b'Hello, Julia 1.10.10!\n') + assert run_language( + tmp_path, julia, 'src/main.jl', + version='1.10.10', + ) == expected + + def test_julia_hook_manifest(tmp_path): code = """ using Example From f2837cf5b250dd024d504b21c50106f60f9bbaa2 Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:19:05 +0200 Subject: [PATCH 6/8] add channel --- .github/workflows/languages.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/languages.yaml b/.github/workflows/languages.yaml index 6b84acc5e..e45332ab5 100644 --- a/.github/workflows/languages.yaml +++ b/.github/workflows/languages.yaml @@ -69,6 +69,8 @@ jobs: if: matrix.os == 'ubuntu-latest' && matrix.language == 'r' - uses: julia-actions/install-juliaup@v2 if: matrix.language == 'julia' + with: + channel: 'release' - run: juliaup add 1.10.10 if: matrix.language == 'julia' - name: install deps From 9a04b3967a8f6963cf3146e4b39dcf51b2ce2026 Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:42:47 +0200 Subject: [PATCH 7/8] copy rust's pattern for conditional env --- pre_commit/languages/julia.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/pre_commit/languages/julia.py b/pre_commit/languages/julia.py index 0ce31d39a..5c1437942 100644 --- a/pre_commit/languages/julia.py +++ b/pre_commit/languages/julia.py @@ -5,14 +5,11 @@ import shutil from collections.abc import Generator from collections.abc import Sequence -from typing import Union from pre_commit import lang_base -from pre_commit.envcontext import _Unset from pre_commit.envcontext import envcontext from pre_commit.envcontext import PatchesT from pre_commit.envcontext import UNSET -from pre_commit.envcontext import Var from pre_commit.prefix import Prefix from pre_commit.util import cmd_output_b @@ -49,17 +46,17 @@ def run_hook( ) -PatchEntry = tuple[str, Union[str, _Unset, tuple[Union[str, Var], ...]]] - - def get_env_patch(target_dir: str, version: str) -> PatchesT: - patches: list[PatchEntry] = [ + patches = ( ('JULIA_LOAD_PATH', target_dir), ('JULIA_PROJECT', UNSET), - ] - if version not in ('system', 'default'): - patches.append(('JULIAUP_CHANNEL', version)) - return tuple(patches) + # Only set JULIAUP_CHANNEL if we don't want use the system's default + *( + (('JULIAUP_CHANNEL', version),) + if version not in ('system', 'default') else () + ), + ) + return patches @contextlib.contextmanager From 1ba5581f39477c822d3a57da60a39e179a21de55 Mon Sep 17 00:00:00 2001 From: Eric Hanson <5846501+ericphanson@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:43:22 +0200 Subject: [PATCH 8/8] restore comment --- pre_commit/languages/julia.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pre_commit/languages/julia.py b/pre_commit/languages/julia.py index 5c1437942..10367fda6 100644 --- a/pre_commit/languages/julia.py +++ b/pre_commit/languages/julia.py @@ -49,6 +49,7 @@ def run_hook( def get_env_patch(target_dir: str, version: str) -> PatchesT: patches = ( ('JULIA_LOAD_PATH', target_dir), + # May be set, remove it to not interfere with LOAD_PATH ('JULIA_PROJECT', UNSET), # Only set JULIAUP_CHANNEL if we don't want use the system's default *(