Merging upstream version 4.1.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
43620d628e
commit
8e2d7f3f0f
14 changed files with 374 additions and 21 deletions
2
.github/workflows/languages.yaml
vendored
2
.github/workflows/languages.yaml
vendored
|
@ -65,6 +65,8 @@ jobs:
|
||||||
if: matrix.os == 'windows-latest' && matrix.language == 'perl'
|
if: matrix.os == 'windows-latest' && matrix.language == 'perl'
|
||||||
- uses: haskell/actions/setup@v2
|
- uses: haskell/actions/setup@v2
|
||||||
if: matrix.language == 'haskell'
|
if: matrix.language == 'haskell'
|
||||||
|
- uses: r-lib/actions/setup-r@v2
|
||||||
|
if: matrix.os == 'ubuntu-latest' && matrix.language == 'r'
|
||||||
|
|
||||||
- name: install deps
|
- name: install deps
|
||||||
run: python -mpip install -e . -r requirements-dev.txt
|
run: python -mpip install -e . -r requirements-dev.txt
|
||||||
|
|
|
@ -10,11 +10,11 @@ repos:
|
||||||
- id: name-tests-test
|
- id: name-tests-test
|
||||||
- id: requirements-txt-fixer
|
- id: requirements-txt-fixer
|
||||||
- repo: https://github.com/asottile/setup-cfg-fmt
|
- repo: https://github.com/asottile/setup-cfg-fmt
|
||||||
rev: v2.5.0
|
rev: v2.7.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: setup-cfg-fmt
|
- id: setup-cfg-fmt
|
||||||
- repo: https://github.com/asottile/reorder-python-imports
|
- repo: https://github.com/asottile/reorder-python-imports
|
||||||
rev: v3.13.0
|
rev: v3.14.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: reorder-python-imports
|
- id: reorder-python-imports
|
||||||
exclude: ^(pre_commit/resources/|testing/resources/python3_hooks_repo/)
|
exclude: ^(pre_commit/resources/|testing/resources/python3_hooks_repo/)
|
||||||
|
@ -24,7 +24,7 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: add-trailing-comma
|
- id: add-trailing-comma
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v3.17.0
|
rev: v3.19.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py39-plus]
|
args: [--py39-plus]
|
||||||
|
@ -37,7 +37,7 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: v1.11.2
|
rev: v1.14.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
additional_dependencies: [types-pyyaml]
|
additional_dependencies: [types-pyyaml]
|
||||||
|
|
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -1,3 +1,21 @@
|
||||||
|
4.1.0 - 2025-01-20
|
||||||
|
==================
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- Add `language: julia`.
|
||||||
|
- #3348 PR by @fredrikekre.
|
||||||
|
- #2689 issue @jmuchovej.
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Disable automatic toolchain switching for `language: golang`.
|
||||||
|
- #3304 PR by @AleksaC.
|
||||||
|
- #3300 issue by @AleksaC.
|
||||||
|
- #3149 issue by @nijel.
|
||||||
|
- Fix `language: r` installation when initiated by RStudio.
|
||||||
|
- #3389 PR by @lorenzwalthert.
|
||||||
|
- #3385 issue by @lorenzwalthert.
|
||||||
|
|
||||||
|
|
||||||
4.0.1 - 2024-10-08
|
4.0.1 - 2024-10-08
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ from pre_commit.languages import dotnet
|
||||||
from pre_commit.languages import fail
|
from pre_commit.languages import fail
|
||||||
from pre_commit.languages import golang
|
from pre_commit.languages import golang
|
||||||
from pre_commit.languages import haskell
|
from pre_commit.languages import haskell
|
||||||
|
from pre_commit.languages import julia
|
||||||
from pre_commit.languages import lua
|
from pre_commit.languages import lua
|
||||||
from pre_commit.languages import node
|
from pre_commit.languages import node
|
||||||
from pre_commit.languages import perl
|
from pre_commit.languages import perl
|
||||||
|
@ -33,6 +34,7 @@ languages: dict[str, Language] = {
|
||||||
'fail': fail,
|
'fail': fail,
|
||||||
'golang': golang,
|
'golang': golang,
|
||||||
'haskell': haskell,
|
'haskell': haskell,
|
||||||
|
'julia': julia,
|
||||||
'lua': lua,
|
'lua': lua,
|
||||||
'node': node,
|
'node': node,
|
||||||
'perl': perl,
|
'perl': perl,
|
||||||
|
|
|
@ -75,6 +75,7 @@ def get_env_patch(venv: str, version: str) -> PatchesT:
|
||||||
|
|
||||||
return (
|
return (
|
||||||
('GOROOT', os.path.join(venv, '.go')),
|
('GOROOT', os.path.join(venv, '.go')),
|
||||||
|
('GOTOOLCHAIN', 'local'),
|
||||||
(
|
(
|
||||||
'PATH', (
|
'PATH', (
|
||||||
os.path.join(venv, 'bin'), os.pathsep,
|
os.path.join(venv, 'bin'), os.pathsep,
|
||||||
|
@ -145,6 +146,7 @@ def install_environment(
|
||||||
env = no_git_env(dict(os.environ, GOPATH=gopath))
|
env = no_git_env(dict(os.environ, GOPATH=gopath))
|
||||||
env.pop('GOBIN', None)
|
env.pop('GOBIN', None)
|
||||||
if version != 'system':
|
if version != 'system':
|
||||||
|
env['GOTOOLCHAIN'] = 'local'
|
||||||
env['GOROOT'] = os.path.join(env_dir, '.go')
|
env['GOROOT'] = os.path.join(env_dir, '.go')
|
||||||
env['PATH'] = os.pathsep.join((
|
env['PATH'] = os.pathsep.join((
|
||||||
os.path.join(env_dir, '.go', 'bin'), os.environ['PATH'],
|
os.path.join(env_dir, '.go', 'bin'), os.environ['PATH'],
|
||||||
|
|
132
pre_commit/languages/julia.py
Normal file
132
pre_commit/languages/julia.py
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from collections.abc import Generator
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
|
from pre_commit.envcontext import envcontext
|
||||||
|
from pre_commit.envcontext import PatchesT
|
||||||
|
from pre_commit.envcontext import UNSET
|
||||||
|
from pre_commit.prefix import Prefix
|
||||||
|
from pre_commit.util import cmd_output_b
|
||||||
|
|
||||||
|
ENVIRONMENT_DIR = 'juliaenv'
|
||||||
|
health_check = lang_base.basic_health_check
|
||||||
|
get_default_version = lang_base.basic_get_default_version
|
||||||
|
|
||||||
|
|
||||||
|
def run_hook(
|
||||||
|
prefix: Prefix,
|
||||||
|
entry: str,
|
||||||
|
args: Sequence[str],
|
||||||
|
file_args: Sequence[str],
|
||||||
|
*,
|
||||||
|
is_local: bool,
|
||||||
|
require_serial: bool,
|
||||||
|
color: bool,
|
||||||
|
) -> tuple[int, bytes]:
|
||||||
|
# `entry` is a (hook-repo relative) file followed by (optional) args, e.g.
|
||||||
|
# `bin/id.jl` or `bin/hook.jl --arg1 --arg2` so we
|
||||||
|
# 1) shell parse it and join with args with hook_cmd
|
||||||
|
# 2) prepend the hooks prefix path to the first argument (the file), unless
|
||||||
|
# it is a local script
|
||||||
|
# 3) prepend `julia` as the interpreter
|
||||||
|
|
||||||
|
cmd = lang_base.hook_cmd(entry, args)
|
||||||
|
script = cmd[0] if is_local else prefix.path(cmd[0])
|
||||||
|
cmd = ('julia', script, *cmd[1:])
|
||||||
|
return lang_base.run_xargs(
|
||||||
|
cmd,
|
||||||
|
file_args,
|
||||||
|
require_serial=require_serial,
|
||||||
|
color=color,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_env_patch(target_dir: str, version: str) -> PatchesT:
|
||||||
|
return (
|
||||||
|
('JULIA_LOAD_PATH', target_dir),
|
||||||
|
# May be set, remove it to not interfer with LOAD_PATH
|
||||||
|
('JULIA_PROJECT', UNSET),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@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,
|
||||||
|
additional_dependencies: Sequence[str],
|
||||||
|
) -> 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)
|
||||||
|
project_names = ('JuliaProject.toml', 'Project.toml')
|
||||||
|
project_found = False
|
||||||
|
for project_name in project_names:
|
||||||
|
project_file = prefix.path(project_name)
|
||||||
|
if not os.path.isfile(project_file):
|
||||||
|
continue
|
||||||
|
shutil.copy(project_file, envdir)
|
||||||
|
project_found = True
|
||||||
|
break
|
||||||
|
|
||||||
|
# If no project file was found we create an empty one so that the
|
||||||
|
# package manager doesn't error
|
||||||
|
if not project_found:
|
||||||
|
open(os.path.join(envdir, 'Project.toml'), 'a').close()
|
||||||
|
|
||||||
|
# Copy Manifest.toml to hook env if it exists
|
||||||
|
manifest_names = ('JuliaManifest.toml', 'Manifest.toml')
|
||||||
|
for manifest_name in manifest_names:
|
||||||
|
manifest_file = prefix.path(manifest_name)
|
||||||
|
if not os.path.isfile(manifest_file):
|
||||||
|
continue
|
||||||
|
shutil.copy(manifest_file, envdir)
|
||||||
|
break
|
||||||
|
|
||||||
|
# Julia code to instantiate the hook environment
|
||||||
|
julia_code = """
|
||||||
|
@assert length(ARGS) > 0
|
||||||
|
hook_env = ARGS[1]
|
||||||
|
deps = join(ARGS[2:end], " ")
|
||||||
|
|
||||||
|
# We prepend @stdlib here so that we can load the package manager even
|
||||||
|
# though `get_env_patch` limits `JULIA_LOAD_PATH` to just the hook env.
|
||||||
|
pushfirst!(LOAD_PATH, "@stdlib")
|
||||||
|
using Pkg
|
||||||
|
popfirst!(LOAD_PATH)
|
||||||
|
|
||||||
|
# Instantiate the environment shipped with the hook repo. If we have
|
||||||
|
# additional dependencies we disable precompilation in this step to
|
||||||
|
# avoid double work.
|
||||||
|
precompile = isempty(deps) ? "1" : "0"
|
||||||
|
withenv("JULIA_PKG_PRECOMPILE_AUTO" => precompile) do
|
||||||
|
Pkg.instantiate()
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add additional dependencies (with precompilation)
|
||||||
|
if !isempty(deps)
|
||||||
|
withenv("JULIA_PKG_PRECOMPILE_AUTO" => "1") do
|
||||||
|
Pkg.REPLMode.pkgstr("add " * deps)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
cmd_output_b(
|
||||||
|
'julia', '-e', julia_code, '--', envdir, *additional_dependencies,
|
||||||
|
cwd=prefix.prefix_dir,
|
||||||
|
)
|
|
@ -15,27 +15,50 @@ from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import UNSET
|
from pre_commit.envcontext import UNSET
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
from pre_commit.util import cmd_output_b
|
|
||||||
from pre_commit.util import win_exe
|
from pre_commit.util import win_exe
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'renv'
|
ENVIRONMENT_DIR = 'renv'
|
||||||
RSCRIPT_OPTS = ('--no-save', '--no-restore', '--no-site-file', '--no-environ')
|
|
||||||
get_default_version = lang_base.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
|
|
||||||
|
_RENV_ACTIVATED_OPTS = (
|
||||||
|
'--no-save', '--no-restore', '--no-site-file', '--no-environ',
|
||||||
|
)
|
||||||
|
|
||||||
def _execute_vanilla_r_code_as_script(
|
|
||||||
|
def _execute_r(
|
||||||
code: str, *,
|
code: str, *,
|
||||||
prefix: Prefix, version: str, args: Sequence[str] = (), cwd: str,
|
prefix: Prefix, version: str, args: Sequence[str] = (), cwd: str,
|
||||||
|
cli_opts: Sequence[str],
|
||||||
) -> str:
|
) -> str:
|
||||||
with in_env(prefix, version), _r_code_in_tempfile(code) as f:
|
with in_env(prefix, version), _r_code_in_tempfile(code) as f:
|
||||||
_, out, _ = cmd_output(
|
_, out, _ = cmd_output(
|
||||||
_rscript_exec(), *RSCRIPT_OPTS, f, *args, cwd=cwd,
|
_rscript_exec(), *cli_opts, f, *args, cwd=cwd,
|
||||||
)
|
)
|
||||||
return out.rstrip('\n')
|
return out.rstrip('\n')
|
||||||
|
|
||||||
|
|
||||||
|
def _execute_r_in_renv(
|
||||||
|
code: str, *,
|
||||||
|
prefix: Prefix, version: str, args: Sequence[str] = (), cwd: str,
|
||||||
|
) -> str:
|
||||||
|
return _execute_r(
|
||||||
|
code=code, prefix=prefix, version=version, args=args, cwd=cwd,
|
||||||
|
cli_opts=_RENV_ACTIVATED_OPTS,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _execute_vanilla_r(
|
||||||
|
code: str, *,
|
||||||
|
prefix: Prefix, version: str, args: Sequence[str] = (), cwd: str,
|
||||||
|
) -> str:
|
||||||
|
return _execute_r(
|
||||||
|
code=code, prefix=prefix, version=version, args=args, cwd=cwd,
|
||||||
|
cli_opts=('--vanilla',),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _read_installed_version(envdir: str, prefix: Prefix, version: str) -> str:
|
def _read_installed_version(envdir: str, prefix: Prefix, version: str) -> str:
|
||||||
return _execute_vanilla_r_code_as_script(
|
return _execute_r_in_renv(
|
||||||
'cat(renv::settings$r.version())',
|
'cat(renv::settings$r.version())',
|
||||||
prefix=prefix, version=version,
|
prefix=prefix, version=version,
|
||||||
cwd=envdir,
|
cwd=envdir,
|
||||||
|
@ -43,7 +66,7 @@ def _read_installed_version(envdir: str, prefix: Prefix, version: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def _read_executable_version(envdir: str, prefix: Prefix, version: str) -> str:
|
def _read_executable_version(envdir: str, prefix: Prefix, version: str) -> str:
|
||||||
return _execute_vanilla_r_code_as_script(
|
return _execute_r_in_renv(
|
||||||
'cat(as.character(getRversion()))',
|
'cat(as.character(getRversion()))',
|
||||||
prefix=prefix, version=version,
|
prefix=prefix, version=version,
|
||||||
cwd=envdir,
|
cwd=envdir,
|
||||||
|
@ -53,7 +76,7 @@ def _read_executable_version(envdir: str, prefix: Prefix, version: str) -> str:
|
||||||
def _write_current_r_version(
|
def _write_current_r_version(
|
||||||
envdir: str, prefix: Prefix, version: str,
|
envdir: str, prefix: Prefix, version: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
_execute_vanilla_r_code_as_script(
|
_execute_r_in_renv(
|
||||||
'renv::settings$r.version(as.character(getRversion()))',
|
'renv::settings$r.version(as.character(getRversion()))',
|
||||||
prefix=prefix, version=version,
|
prefix=prefix, version=version,
|
||||||
cwd=envdir,
|
cwd=envdir,
|
||||||
|
@ -161,7 +184,7 @@ def _cmd_from_hook(
|
||||||
_entry_validate(cmd)
|
_entry_validate(cmd)
|
||||||
|
|
||||||
cmd_part = _prefix_if_file_entry(cmd, prefix, is_local=is_local)
|
cmd_part = _prefix_if_file_entry(cmd, prefix, is_local=is_local)
|
||||||
return (cmd[0], *RSCRIPT_OPTS, *cmd_part, *args)
|
return (cmd[0], *_RENV_ACTIVATED_OPTS, *cmd_part, *args)
|
||||||
|
|
||||||
|
|
||||||
def install_environment(
|
def install_environment(
|
||||||
|
@ -204,14 +227,15 @@ def install_environment(
|
||||||
renv::install(prefix_dir)
|
renv::install(prefix_dir)
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
_execute_vanilla_r(
|
||||||
with _r_code_in_tempfile(r_code_inst_environment) as f:
|
r_code_inst_environment,
|
||||||
cmd_output_b(_rscript_exec(), '--vanilla', f, cwd=env_dir)
|
prefix=prefix, version=version, cwd=env_dir,
|
||||||
|
)
|
||||||
|
|
||||||
_write_current_r_version(envdir=env_dir, prefix=prefix, version=version)
|
_write_current_r_version(envdir=env_dir, prefix=prefix, version=version)
|
||||||
if additional_dependencies:
|
if additional_dependencies:
|
||||||
r_code_inst_add = 'renv::install(commandArgs(trailingOnly = TRUE))'
|
r_code_inst_add = 'renv::install(commandArgs(trailingOnly = TRUE))'
|
||||||
_execute_vanilla_r_code_as_script(
|
_execute_r_in_renv(
|
||||||
code=r_code_inst_add, prefix=prefix, version=version,
|
code=r_code_inst_add, prefix=prefix, version=version,
|
||||||
args=additional_dependencies,
|
args=additional_dependencies,
|
||||||
cwd=env_dir,
|
cwd=env_dir,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[metadata]
|
[metadata]
|
||||||
name = pre_commit
|
name = pre_commit
|
||||||
version = 4.0.1
|
version = 4.1.0
|
||||||
description = A framework for managing and maintaining multi-language pre-commit hooks.
|
description = A framework for managing and maintaining multi-language pre-commit hooks.
|
||||||
long_description = file: README.md
|
long_description = file: README.md
|
||||||
long_description_content_type = text/markdown
|
long_description_content_type = text/markdown
|
||||||
|
|
|
@ -57,8 +57,7 @@ def make_archive(name: str, repo: str, ref: str, destdir: str) -> str:
|
||||||
arcs.sort()
|
arcs.sort()
|
||||||
|
|
||||||
with gzip.GzipFile(output_path, 'wb', mtime=0) as gzipf:
|
with gzip.GzipFile(output_path, 'wb', mtime=0) as gzipf:
|
||||||
# https://github.com/python/typeshed/issues/5491
|
with tarfile.open(fileobj=gzipf, mode='w') as tf:
|
||||||
with tarfile.open(fileobj=gzipf, mode='w') as tf: # type: ignore
|
|
||||||
for arcname, abspath in arcs:
|
for arcname, abspath in arcs:
|
||||||
tf.add(
|
tf.add(
|
||||||
abspath,
|
abspath,
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from pre_commit.languages import docker_image
|
from pre_commit.languages import docker_image
|
||||||
|
from pre_commit.util import cmd_output_b
|
||||||
from testing.language_helpers import run_language
|
from testing.language_helpers import run_language
|
||||||
from testing.util import xfailif_windows
|
from testing.util import xfailif_windows
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True, scope='module')
|
||||||
|
def _ensure_image_available():
|
||||||
|
cmd_output_b('docker', 'run', '--rm', 'ubuntu:22.04', 'echo')
|
||||||
|
|
||||||
|
|
||||||
@xfailif_windows # pragma: win32 no cover
|
@xfailif_windows # pragma: win32 no cover
|
||||||
def test_docker_image_hook_via_entrypoint(tmp_path):
|
def test_docker_image_hook_via_entrypoint(tmp_path):
|
||||||
ret = run_language(
|
ret = run_language(
|
||||||
|
|
|
@ -27,7 +27,7 @@ def _csproj(tool_name):
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>net8</TargetFramework>
|
||||||
<PackAsTool>true</PackAsTool>
|
<PackAsTool>true</PackAsTool>
|
||||||
<ToolCommandName>{tool_name}</ToolCommandName>
|
<ToolCommandName>{tool_name}</ToolCommandName>
|
||||||
<PackageOutputPath>./nupkg</PackageOutputPath>
|
<PackageOutputPath>./nupkg</PackageOutputPath>
|
||||||
|
|
|
@ -11,11 +11,13 @@ from pre_commit.commands.install_uninstall import install
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.languages import golang
|
from pre_commit.languages import golang
|
||||||
from pre_commit.store import _make_local_repo
|
from pre_commit.store import _make_local_repo
|
||||||
|
from pre_commit.util import CalledProcessError
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
from testing.fixtures import add_config_to_repo
|
from testing.fixtures import add_config_to_repo
|
||||||
from testing.fixtures import make_config_from_repo
|
from testing.fixtures import make_config_from_repo
|
||||||
from testing.language_helpers import run_language
|
from testing.language_helpers import run_language
|
||||||
from testing.util import cmd_output_mocked_pre_commit_home
|
from testing.util import cmd_output_mocked_pre_commit_home
|
||||||
|
from testing.util import cwd
|
||||||
from testing.util import git_commit
|
from testing.util import git_commit
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,3 +167,70 @@ def test_during_commit_all(tmp_path, tempdir_factory, store, in_git_dir):
|
||||||
fn=cmd_output_mocked_pre_commit_home,
|
fn=cmd_output_mocked_pre_commit_home,
|
||||||
tempdir_factory=tempdir_factory,
|
tempdir_factory=tempdir_factory,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_automatic_toolchain_switching(tmp_path):
|
||||||
|
go_mod = '''\
|
||||||
|
module toolchain-version-test
|
||||||
|
|
||||||
|
go 1.23.1
|
||||||
|
'''
|
||||||
|
main_go = '''\
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
'''
|
||||||
|
tmp_path.joinpath('go.mod').write_text(go_mod)
|
||||||
|
mod_dir = tmp_path.joinpath('toolchain-version-test')
|
||||||
|
mod_dir.mkdir()
|
||||||
|
main_file = mod_dir.joinpath('main.go')
|
||||||
|
main_file.write_text(main_go)
|
||||||
|
|
||||||
|
with pytest.raises(CalledProcessError) as excinfo:
|
||||||
|
run_language(
|
||||||
|
path=tmp_path,
|
||||||
|
language=golang,
|
||||||
|
version='1.22.0',
|
||||||
|
exe='golang-version-test',
|
||||||
|
)
|
||||||
|
|
||||||
|
assert 'go.mod requires go >= 1.23.1' in excinfo.value.stderr.decode()
|
||||||
|
|
||||||
|
|
||||||
|
def test_automatic_toolchain_switching_go_fmt(tmp_path, monkeypatch):
|
||||||
|
go_mod_hook = '''\
|
||||||
|
module toolchain-version-test
|
||||||
|
|
||||||
|
go 1.22.0
|
||||||
|
'''
|
||||||
|
go_mod = '''\
|
||||||
|
module toolchain-version-test
|
||||||
|
|
||||||
|
go 1.23.1
|
||||||
|
'''
|
||||||
|
main_go = '''\
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
'''
|
||||||
|
hook_dir = tmp_path.joinpath('hook')
|
||||||
|
hook_dir.mkdir()
|
||||||
|
hook_dir.joinpath('go.mod').write_text(go_mod_hook)
|
||||||
|
|
||||||
|
test_dir = tmp_path.joinpath('test')
|
||||||
|
test_dir.mkdir()
|
||||||
|
test_dir.joinpath('go.mod').write_text(go_mod)
|
||||||
|
main_file = test_dir.joinpath('main.go')
|
||||||
|
main_file.write_text(main_go)
|
||||||
|
|
||||||
|
with cwd(test_dir):
|
||||||
|
ret, out = run_language(
|
||||||
|
path=hook_dir,
|
||||||
|
language=golang,
|
||||||
|
version='1.22.0',
|
||||||
|
exe='go fmt',
|
||||||
|
file_args=(str(main_file),),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert ret == 1
|
||||||
|
assert 'go.mod requires go >= 1.23.1' in out.decode()
|
||||||
|
|
97
tests/languages/julia_test.py
Normal file
97
tests/languages/julia_test.py
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pre_commit.languages import julia
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
from testing.util import cwd
|
||||||
|
|
||||||
|
|
||||||
|
def _make_hook(tmp_path, julia_code):
|
||||||
|
src_dir = tmp_path.joinpath('src')
|
||||||
|
src_dir.mkdir()
|
||||||
|
src_dir.joinpath('main.jl').write_text(julia_code)
|
||||||
|
tmp_path.joinpath('Project.toml').write_text(
|
||||||
|
'[deps]\n'
|
||||||
|
'Example = "7876af07-990d-54b4-ab0e-23690620f79a"\n',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_julia_hook(tmp_path):
|
||||||
|
code = """
|
||||||
|
using Example
|
||||||
|
function main()
|
||||||
|
println("Hello, world!")
|
||||||
|
end
|
||||||
|
main()
|
||||||
|
"""
|
||||||
|
_make_hook(tmp_path, code)
|
||||||
|
expected = (0, b'Hello, world!\n')
|
||||||
|
assert run_language(tmp_path, julia, 'src/main.jl') == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_julia_hook_manifest(tmp_path):
|
||||||
|
code = """
|
||||||
|
using Example
|
||||||
|
println(pkgversion(Example))
|
||||||
|
"""
|
||||||
|
_make_hook(tmp_path, code)
|
||||||
|
|
||||||
|
tmp_path.joinpath('Manifest.toml').write_text(
|
||||||
|
'manifest_format = "2.0"\n\n'
|
||||||
|
'[[deps.Example]]\n'
|
||||||
|
'git-tree-sha1 = "11820aa9c229fd3833d4bd69e5e75ef4e7273bf1"\n'
|
||||||
|
'uuid = "7876af07-990d-54b4-ab0e-23690620f79a"\n'
|
||||||
|
'version = "0.5.4"\n',
|
||||||
|
)
|
||||||
|
expected = (0, b'0.5.4\n')
|
||||||
|
assert run_language(tmp_path, julia, 'src/main.jl') == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_julia_hook_args(tmp_path):
|
||||||
|
code = """
|
||||||
|
function main(argv)
|
||||||
|
foreach(println, argv)
|
||||||
|
end
|
||||||
|
main(ARGS)
|
||||||
|
"""
|
||||||
|
_make_hook(tmp_path, code)
|
||||||
|
expected = (0, b'--arg1\n--arg2\n')
|
||||||
|
assert run_language(
|
||||||
|
tmp_path, julia, 'src/main.jl --arg1 --arg2',
|
||||||
|
) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_julia_hook_additional_deps(tmp_path):
|
||||||
|
code = """
|
||||||
|
using TOML
|
||||||
|
function main()
|
||||||
|
project_file = Base.active_project()
|
||||||
|
dict = TOML.parsefile(project_file)
|
||||||
|
for (k, v) in dict["deps"]
|
||||||
|
println(k, " = ", v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
main()
|
||||||
|
"""
|
||||||
|
_make_hook(tmp_path, code)
|
||||||
|
deps = ('TOML=fa267f1f-6049-4f14-aa54-33bafae1ed76',)
|
||||||
|
ret, out = run_language(tmp_path, julia, 'src/main.jl', deps=deps)
|
||||||
|
assert ret == 0
|
||||||
|
assert b'Example = 7876af07-990d-54b4-ab0e-23690620f79a' in out
|
||||||
|
assert b'TOML = fa267f1f-6049-4f14-aa54-33bafae1ed76' in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_julia_repo_local(tmp_path):
|
||||||
|
env_dir = tmp_path.joinpath('envdir')
|
||||||
|
env_dir.mkdir()
|
||||||
|
local_dir = tmp_path.joinpath('local')
|
||||||
|
local_dir.mkdir()
|
||||||
|
local_dir.joinpath('local.jl').write_text(
|
||||||
|
'using TOML; foreach(println, ARGS)',
|
||||||
|
)
|
||||||
|
with cwd(local_dir):
|
||||||
|
deps = ('TOML=fa267f1f-6049-4f14-aa54-33bafae1ed76',)
|
||||||
|
expected = (0, b'--local-arg1\n--local-arg2\n')
|
||||||
|
assert run_language(
|
||||||
|
env_dir, julia, 'local.jl --local-arg1 --local-arg2',
|
||||||
|
deps=deps, is_local=True,
|
||||||
|
) == expected
|
|
@ -286,7 +286,7 @@ def test_health_check_without_version(prefix, installed_environment, version):
|
||||||
prefix, env_dir = installed_environment
|
prefix, env_dir = installed_environment
|
||||||
|
|
||||||
# simulate old pre-commit install by unsetting the installed version
|
# simulate old pre-commit install by unsetting the installed version
|
||||||
r._execute_vanilla_r_code_as_script(
|
r._execute_r_in_renv(
|
||||||
f'renv::settings$r.version({version})',
|
f'renv::settings$r.version({version})',
|
||||||
prefix=prefix, version=C.DEFAULT, cwd=env_dir,
|
prefix=prefix, version=C.DEFAULT, cwd=env_dir,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue