From 70ab1c3b6f30e8e4e4d25f84b2f12ca2ea843940 Mon Sep 17 00:00:00 2001 From: Joseph Moniz Date: Fri, 9 Oct 2020 13:39:18 -0400 Subject: [PATCH] add coursier (jvm) as a language --- azure-pipelines.yml | 8 +++ pre_commit/languages/all.py | 2 + pre_commit/languages/coursier.py | 71 +++++++++++++++++++ testing/gen-languages-all | 2 +- testing/get-coursier.ps1 | 11 +++ testing/get-coursier.sh | 13 ++++ .../.pre-commit-channel/echo-java.json | 8 +++ .../.pre-commit-hooks.yaml | 5 ++ testing/util.py | 4 ++ tests/repository_test.py | 10 +++ 10 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 pre_commit/languages/coursier.py create mode 100755 testing/get-coursier.ps1 create mode 100755 testing/get-coursier.sh create mode 100644 testing/resources/coursier_hooks_repo/.pre-commit-channel/echo-java.json create mode 100644 testing/resources/coursier_hooks_repo/.pre-commit-hooks.yaml diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 41f1e5f9..e7256da1 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -34,6 +34,10 @@ jobs: pre_test: - task: UseRubyVersion@0 - template: step--git-install.yml + - bash: | + testing/get-coursier.sh + echo '##vso[task.prependpath]/tmp/coursier' + displayName: install coursier - bash: | testing/get-swift.sh echo '##vso[task.prependpath]/tmp/swift/usr/bin' @@ -44,6 +48,10 @@ jobs: os: linux pre_test: - task: UseRubyVersion@0 + - bash: | + testing/get-coursier.sh + echo '##vso[task.prependpath]/tmp/coursier' + displayName: install coursier - bash: | testing/get-swift.sh echo '##vso[task.prependpath]/tmp/swift/usr/bin' diff --git a/pre_commit/languages/all.py b/pre_commit/languages/all.py index f32780c1..9c2e59d7 100644 --- a/pre_commit/languages/all.py +++ b/pre_commit/languages/all.py @@ -6,6 +6,7 @@ from typing import Tuple from pre_commit.hook import Hook from pre_commit.languages import conda +from pre_commit.languages import coursier from pre_commit.languages import docker from pre_commit.languages import docker_image from pre_commit.languages import dotnet @@ -41,6 +42,7 @@ class Language(NamedTuple): languages = { # BEGIN GENERATED (testing/gen-languages-all) 'conda': Language(name='conda', ENVIRONMENT_DIR=conda.ENVIRONMENT_DIR, get_default_version=conda.get_default_version, healthy=conda.healthy, install_environment=conda.install_environment, run_hook=conda.run_hook), # noqa: E501 + 'coursier': Language(name='coursier', ENVIRONMENT_DIR=coursier.ENVIRONMENT_DIR, get_default_version=coursier.get_default_version, healthy=coursier.healthy, install_environment=coursier.install_environment, run_hook=coursier.run_hook), # noqa: E501 'docker': Language(name='docker', ENVIRONMENT_DIR=docker.ENVIRONMENT_DIR, get_default_version=docker.get_default_version, healthy=docker.healthy, install_environment=docker.install_environment, run_hook=docker.run_hook), # noqa: E501 'docker_image': Language(name='docker_image', ENVIRONMENT_DIR=docker_image.ENVIRONMENT_DIR, get_default_version=docker_image.get_default_version, healthy=docker_image.healthy, install_environment=docker_image.install_environment, run_hook=docker_image.run_hook), # noqa: E501 'dotnet': Language(name='dotnet', ENVIRONMENT_DIR=dotnet.ENVIRONMENT_DIR, get_default_version=dotnet.get_default_version, healthy=dotnet.healthy, install_environment=dotnet.install_environment, run_hook=dotnet.run_hook), # noqa: E501 diff --git a/pre_commit/languages/coursier.py b/pre_commit/languages/coursier.py new file mode 100644 index 00000000..2841467f --- /dev/null +++ b/pre_commit/languages/coursier.py @@ -0,0 +1,71 @@ +import contextlib +import os +from typing import Generator +from typing import Sequence +from typing import Tuple + +from pre_commit.envcontext import envcontext +from pre_commit.envcontext import PatchesT +from pre_commit.envcontext import Var +from pre_commit.hook import Hook +from pre_commit.languages import helpers +from pre_commit.prefix import Prefix +from pre_commit.util import clean_path_on_failure + +ENVIRONMENT_DIR = 'coursier' + +get_default_version = helpers.basic_get_default_version +healthy = helpers.basic_healthy + + +def install_environment( + prefix: Prefix, + version: str, + additional_dependencies: Sequence[str], +) -> None: # pragma: win32 no cover + helpers.assert_version_default('coursier', version) + helpers.assert_no_additional_deps('coursier', additional_dependencies) + + envdir = prefix.path(helpers.environment_dir(ENVIRONMENT_DIR, version)) + channel = prefix.path('.pre-commit-channel') + with clean_path_on_failure(envdir): + 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, + ( + 'cs', + 'install', + '--default-channels=false', + f'--channel={channel}', + app, + f'--dir={envdir}', + ), + ) + + +def get_env_patch(target_dir: str) -> PatchesT: # pragma: win32 no cover + return ( + ('PATH', (target_dir, os.pathsep, Var('PATH'))), + ) + + +@contextlib.contextmanager +def in_env( + prefix: Prefix, +) -> Generator[None, None, None]: # pragma: win32 no cover + target_dir = prefix.path( + helpers.environment_dir(ENVIRONMENT_DIR, get_default_version()), + ) + with envcontext(get_env_patch(target_dir)): + yield + + +def run_hook( + hook: Hook, + file_args: Sequence[str], + color: bool, +) -> Tuple[int, bytes]: # pragma: win32 no cover + with in_env(hook.prefix): + return helpers.run_xargs(hook, hook.cmd, file_args, color=color) diff --git a/testing/gen-languages-all b/testing/gen-languages-all index 35eac042..d9b01bd0 100755 --- a/testing/gen-languages-all +++ b/testing/gen-languages-all @@ -2,7 +2,7 @@ import sys LANGUAGES = [ - 'conda', 'docker', 'dotnet', 'docker_image', 'fail', 'golang', + 'conda', 'coursier', 'docker', 'dotnet', 'docker_image', 'fail', 'golang', 'node', 'perl', 'pygrep', 'python', 'ruby', 'rust', 'script', 'swift', 'system', ] diff --git a/testing/get-coursier.ps1 b/testing/get-coursier.ps1 new file mode 100755 index 00000000..42e56354 --- /dev/null +++ b/testing/get-coursier.ps1 @@ -0,0 +1,11 @@ +$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" +} diff --git a/testing/get-coursier.sh b/testing/get-coursier.sh new file mode 100755 index 00000000..760c6c12 --- /dev/null +++ b/testing/get-coursier.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# This is a script used in CI to install coursier +set -euxo 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" + +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 diff --git a/testing/resources/coursier_hooks_repo/.pre-commit-channel/echo-java.json b/testing/resources/coursier_hooks_repo/.pre-commit-channel/echo-java.json new file mode 100644 index 00000000..37f401e2 --- /dev/null +++ b/testing/resources/coursier_hooks_repo/.pre-commit-channel/echo-java.json @@ -0,0 +1,8 @@ +{ + "repositories": [ + "central" + ], + "dependencies": [ + "io.get-coursier:echo:latest.stable" + ] +} diff --git a/testing/resources/coursier_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/coursier_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 00000000..d4a143b3 --- /dev/null +++ b/testing/resources/coursier_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: echo-java + name: echo-java + description: echo from java + entry: echo-java + language: coursier diff --git a/testing/util.py b/testing/util.py index f556a8dd..18cd7342 100644 --- a/testing/util.py +++ b/testing/util.py @@ -40,6 +40,10 @@ 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", diff --git a/tests/repository_test.py b/tests/repository_test.py index a6d801ec..3d5093df 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -31,6 +31,7 @@ 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_swift from testing.util import xfailif_windows @@ -195,6 +196,15 @@ def test_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(