coursier: additional_dependencies support

This commit is contained in:
Anthony Sottile
2023-01-16 18:33:40 -05:00
parent 59ed51a309
commit 70bfd76ced
10 changed files with 132 additions and 66 deletions

View File

@@ -19,6 +19,7 @@ runs:
echo 'C:\Strawberry\perl\site\bin' >> "$GITHUB_PATH"
echo 'C:\Strawberry\c\bin' >> "$GITHUB_PATH"
testing/get-coursier.sh
testing/get-dart.sh
- name: setup (linux)
shell: bash

View File

@@ -1,13 +1,14 @@
from __future__ import annotations
import contextlib
import os
import os.path
from typing import Generator
from typing import Sequence
from pre_commit.envcontext import envcontext
from pre_commit.envcontext import PatchesT
from pre_commit.envcontext import Var
from pre_commit.errors import FatalError
from pre_commit.languages import helpers
from pre_commit.parse_shebang import find_executable
from pre_commit.prefix import Prefix
@@ -23,9 +24,8 @@ def install_environment(
prefix: Prefix,
version: str,
additional_dependencies: Sequence[str],
) -> None: # pragma: win32 no cover
) -> None:
helpers.assert_version_default('coursier', version)
helpers.assert_no_additional_deps('coursier', additional_dependencies)
# Support both possible executable names (either "cs" or "coursier")
executable = find_executable('cs') or find_executable('coursier')
@@ -37,29 +37,40 @@ def install_environment(
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
channel = prefix.path('.pre-commit-channel')
for app_descriptor in os.listdir(channel):
_, app_file = os.path.split(app_descriptor)
app, _ = os.path.splitext(app_file)
helpers.run_setup_cmd(
prefix,
(
executable,
'install',
'--default-channels=false',
f'--channel={channel}',
app,
f'--dir={envdir}',
),
if os.path.isdir(channel):
for app_descriptor in os.listdir(channel):
_, app_file = os.path.split(app_descriptor)
app, _ = os.path.splitext(app_file)
helpers.run_setup_cmd(
prefix,
(
executable,
'install',
'--default-channels=false',
'--channel', channel,
'--dir', envdir,
app,
),
)
elif not additional_dependencies:
raise FatalError(
'expected .pre-commit-channel dir or additional_dependencies',
)
if additional_dependencies:
install_cmd = (
executable, 'install', '--dir', envdir, *additional_dependencies,
)
helpers.run_setup_cmd(prefix, install_cmd)
def get_env_patch(target_dir: str) -> PatchesT: # pragma: win32 no cover
def get_env_patch(target_dir: str) -> PatchesT:
return (
('PATH', (target_dir, os.pathsep, Var('PATH'))),
)
@contextlib.contextmanager # pragma: win32 no cover
@contextlib.contextmanager
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
with envcontext(get_env_patch(envdir)):

View File

@@ -1,11 +0,0 @@
$wc = New-Object System.Net.WebClient
$coursier_url = "https://github.com/coursier/coursier/releases/download/v2.0.5/cs-x86_64-pc-win32.exe"
$coursier_dest = "C:\coursier\cs.exe"
$coursier_hash ="d63d497f7805261e1cd657b8aaa626f6b8f7264cdb68219b2e6be9dd882033a9"
New-Item -Path "C:\" -Name "coursier" -ItemType "directory"
$wc.DownloadFile($coursier_url, $coursier_dest)
if ((Get-FileHash $coursier_dest -Algorithm SHA256).Hash -ne $coursier_hash) {
throw "Invalid coursier file"
}

View File

@@ -1,15 +1,29 @@
#!/usr/bin/env bash
# This is a script used in CI to install coursier
set -euo pipefail
COURSIER_URL="https://github.com/coursier/coursier/releases/download/v2.0.0/cs-x86_64-pc-linux"
COURSIER_HASH="e2e838b75bc71b16bcb77ce951ad65660c89bda7957c79a0628ec7146d35122f"
ARTIFACT="/tmp/coursier/cs"
if [ "$OSTYPE" = msys ]; then
URL='https://github.com/coursier/coursier/releases/download/v2.1.0-RC4/cs-x86_64-pc-win32.zip'
SHA256='0d07386ff0f337e3e6264f7dde29d137dda6eaa2385f29741435e0b93ccdb49d'
TARGET='/tmp/coursier/cs.zip'
unpack() {
unzip "$TARGET" -d /tmp/coursier
mv /tmp/coursier/cs-*.exe /tmp/coursier/cs.exe
cygpath -w /tmp/coursier >> "$GITHUB_PATH"
}
else
URL='https://github.com/coursier/coursier/releases/download/v2.1.0-RC4/cs-x86_64-pc-linux.gz'
SHA256='176e92e08ab292531aa0c4993dbc9f2c99dec79578752f3b9285f54f306db572'
TARGET=/tmp/coursier/cs.gz
unpack() {
gunzip "$TARGET"
chmod +x /tmp/coursier/cs
echo /tmp/coursier >> "$GITHUB_PATH"
}
fi
mkdir -p /tmp/coursier
rm -f "$ARTIFACT"
curl --location --silent --output "$ARTIFACT" "$COURSIER_URL"
echo "$COURSIER_HASH $ARTIFACT" | sha256sum --check
chmod ugo+x /tmp/coursier/cs
echo '/tmp/coursier' >> "$GITHUB_PATH"
curl --location --silent --output "$TARGET" "$URL"
echo "$SHA256 $TARGET" | sha256sum --check
unpack

View File

@@ -0,0 +1,33 @@
from __future__ import annotations
import os
from typing import Sequence
import pre_commit.constants as C
from pre_commit.languages.all import Language
from pre_commit.prefix import Prefix
def run_language(
path: os.PathLike[str],
language: Language,
exe: str,
args: Sequence[str] = (),
file_args: Sequence[str] = (),
version: str = C.DEFAULT,
deps: Sequence[str] = (),
) -> tuple[int, bytes]:
prefix = Prefix(str(path))
language.install_environment(prefix, version, deps)
with language.in_env(prefix, version):
ret, out = language.run_hook(
prefix,
exe,
args,
file_args,
require_serial=True,
color=False,
)
out = out.replace(b'\r\n', b'\n')
return ret, out

View File

@@ -1,8 +0,0 @@
{
"repositories": [
"central"
],
"dependencies": [
"io.get-coursier:echo:latest.stable"
]
}

View File

@@ -1,5 +0,0 @@
- id: echo-java
name: echo-java
description: echo from java
entry: echo-java
language: coursier

View File

@@ -42,10 +42,6 @@ def cmd_output_mocked_pre_commit_home(
return ret, out.replace('\r\n', '\n'), None
skipif_cant_run_coursier = pytest.mark.skipif(
os.name == 'nt' or parse_shebang.find_executable('cs') is None,
reason="coursier isn't installed or can't be found",
)
skipif_cant_run_docker = pytest.mark.skipif(
os.name == 'nt' or not docker_is_running(),
reason="Docker isn't running or can't be accessed",

View File

@@ -0,0 +1,45 @@
from __future__ import annotations
import pytest
from pre_commit.errors import FatalError
from pre_commit.languages import coursier
from testing.language_helpers import run_language
def test_coursier_hook(tmp_path):
echo_java_json = '''\
{
"repositories": ["central"],
"dependencies": ["io.get-coursier:echo:latest.stable"]
}
'''
channel_dir = tmp_path.joinpath('.pre-commit-channel')
channel_dir.mkdir()
channel_dir.joinpath('echo-java.json').write_text(echo_java_json)
ret = run_language(
tmp_path,
coursier,
'echo-java',
args=('Hello', 'World', 'from', 'coursier'),
)
assert ret == (0, b'Hello World from coursier\n')
def test_coursier_hook_additional_dependencies(tmp_path):
ret = run_language(
tmp_path,
coursier,
'scalafmt --version',
deps=('scalafmt:3.6.1',),
)
assert ret == (0, b'scalafmt 3.6.1\n')
def test_error_if_no_deps_or_channel(tmp_path):
with pytest.raises(FatalError) as excinfo:
run_language(tmp_path, coursier, 'dne')
msg, = excinfo.value.args
assert msg == 'expected .pre-commit-channel dir or additional_dependencies'

View File

@@ -32,7 +32,6 @@ from testing.fixtures import make_repo
from testing.fixtures import modify_manifest
from testing.util import cwd
from testing.util import get_resource_path
from testing.util import skipif_cant_run_coursier
from testing.util import skipif_cant_run_docker
from testing.util import skipif_cant_run_lua
from testing.util import skipif_cant_run_swift
@@ -199,15 +198,6 @@ def test_language_versioned_python_hook(tempdir_factory, store):
)
@skipif_cant_run_coursier # pragma: win32 no cover
def test_run_a_coursier_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'coursier_hooks_repo',
'echo-java',
['Hello World from coursier'], b'Hello World from coursier\n',
)
@skipif_cant_run_docker # pragma: win32 no cover
def test_run_a_docker_hook(tempdir_factory, store):
_test_hook_repo(