diff --git a/.github/workflows/languages.yaml b/.github/workflows/languages.yaml index fccf29892..e45332ab5 100644 --- a/.github/workflows/languages.yaml +++ b/.github/workflows/languages.yaml @@ -67,7 +67,12 @@ 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' + with: + channel: 'release' + - 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 df91c0697..10367fda6 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, @@ -47,11 +47,17 @@ def run_hook( 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 + # 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 + *( + (('JULIAUP_CHANNEL', version),) + if version not in ('system', 'default') else () + ), ) + return patches @contextlib.contextmanager @@ -68,10 +74,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 +101,14 @@ 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'), + dirs_exist_ok=True, + ) + # Julia code to instantiate the hook environment julia_code = """ @assert length(ARGS) > 0 @@ -127,6 +137,6 @@ def install_environment( end """ cmd_output_b( - 'julia', '-e', julia_code, '--', envdir, *additional_dependencies, - cwd=prefix.prefix_dir, + 'julia', '--startup-file=no', '-e', julia_code, '--', envdir, + *additional_dependencies, cwd=prefix.prefix_dir, ) diff --git a/tests/languages/julia_test.py b/tests/languages/julia_test.py index 4ea3c25b2..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 @@ -95,3 +111,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