From bb29630d57440f3ee6bb7e787942f323d502b126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Tue, 28 Jan 2020 23:25:24 +0200 Subject: [PATCH 1/6] First cut at Perl hook support --- pre_commit/languages/all.py | 2 ++ pre_commit/languages/perl.py | 66 ++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 pre_commit/languages/perl.py diff --git a/pre_commit/languages/all.py b/pre_commit/languages/all.py index e6d7b1db..8f4ffa8c 100644 --- a/pre_commit/languages/all.py +++ b/pre_commit/languages/all.py @@ -11,6 +11,7 @@ from pre_commit.languages import docker_image from pre_commit.languages import fail from pre_commit.languages import golang from pre_commit.languages import node +from pre_commit.languages import perl from pre_commit.languages import pygrep from pre_commit.languages import python from pre_commit.languages import python_venv @@ -45,6 +46,7 @@ languages = { 'fail': Language(name='fail', ENVIRONMENT_DIR=fail.ENVIRONMENT_DIR, get_default_version=fail.get_default_version, healthy=fail.healthy, install_environment=fail.install_environment, run_hook=fail.run_hook), # noqa: E501 'golang': Language(name='golang', ENVIRONMENT_DIR=golang.ENVIRONMENT_DIR, get_default_version=golang.get_default_version, healthy=golang.healthy, install_environment=golang.install_environment, run_hook=golang.run_hook), # noqa: E501 'node': Language(name='node', ENVIRONMENT_DIR=node.ENVIRONMENT_DIR, get_default_version=node.get_default_version, healthy=node.healthy, install_environment=node.install_environment, run_hook=node.run_hook), # noqa: E501 + 'perl': Language(name='perl', ENVIRONMENT_DIR=perl.ENVIRONMENT_DIR, get_default_version=perl.get_default_version, healthy=perl.healthy, install_environment=perl.install_environment, run_hook=perl.run_hook), # noqa: E501 'pygrep': Language(name='pygrep', ENVIRONMENT_DIR=pygrep.ENVIRONMENT_DIR, get_default_version=pygrep.get_default_version, healthy=pygrep.healthy, install_environment=pygrep.install_environment, run_hook=pygrep.run_hook), # noqa: E501 'python': Language(name='python', ENVIRONMENT_DIR=python.ENVIRONMENT_DIR, get_default_version=python.get_default_version, healthy=python.healthy, install_environment=python.install_environment, run_hook=python.run_hook), # noqa: E501 'python_venv': Language(name='python_venv', ENVIRONMENT_DIR=python_venv.ENVIRONMENT_DIR, get_default_version=python_venv.get_default_version, healthy=python_venv.healthy, install_environment=python_venv.install_environment, run_hook=python_venv.run_hook), # noqa: E501 diff --git a/pre_commit/languages/perl.py b/pre_commit/languages/perl.py new file mode 100644 index 00000000..52d8aab9 --- /dev/null +++ b/pre_commit/languages/perl.py @@ -0,0 +1,66 @@ +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 = 'perl_env' +get_default_version = helpers.basic_get_default_version +healthy = helpers.basic_healthy + + +def _envdir(prefix: Prefix, version: str) -> str: + directory = helpers.environment_dir(ENVIRONMENT_DIR, version) + return prefix.path(directory) + + +def get_env_patch(venv: str) -> PatchesT: + return ( + ('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))), + ('PERL5LIB', os.path.join(venv, 'lib', 'perl5')), + ('PERL_MB_OPT', f'--install_base {venv}'), + ( + 'PERL_MM_OPT', ( + f'INSTALL_BASE={venv}' + ' INSTALLSITEMAN1DIR=none INSTALLSITEMAN3DIR=none' + ), + ), + ) + + +@contextlib.contextmanager +def in_env( + prefix: Prefix, + language_version: str, +) -> Generator[None, None, None]: + with envcontext(get_env_patch(_envdir(prefix, language_version))): + yield + + +def install_environment( + prefix: Prefix, version: str, additional_dependencies: Sequence[str], +) -> None: + helpers.assert_version_default('perl', version) + + with clean_path_on_failure(_envdir(prefix, version)): + with in_env(prefix, version): + helpers.run_setup_cmd( + prefix, ('cpan', '-T', '.', *additional_dependencies), + ) + + +def run_hook( + hook: 'Hook', + file_args: Sequence[str], + color: bool, +) -> Tuple[int, bytes]: + with in_env(hook.prefix, hook.language_version): + return helpers.run_xargs(hook, hook.cmd, file_args, color=color) From aee7843bec755150a897faf0d62ca981a75f88ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Sat, 1 Feb 2020 15:20:25 +0200 Subject: [PATCH 2/6] Add perl to gen-languages-all --- testing/gen-languages-all | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testing/gen-languages-all b/testing/gen-languages-all index add6752d..6d0b26ff 100755 --- a/testing/gen-languages-all +++ b/testing/gen-languages-all @@ -2,8 +2,9 @@ import sys LANGUAGES = [ - 'conda', 'docker', 'docker_image', 'fail', 'golang', 'node', 'pygrep', - 'python', 'python_venv', 'ruby', 'rust', 'script', 'swift', 'system', + 'conda', 'docker', 'docker_image', 'fail', 'golang', 'node', 'perl', + 'pygrep', 'python', 'python_venv', 'ruby', 'rust', 'script', 'swift', + 'system', ] FIELDS = [ 'ENVIRONMENT_DIR', 'get_default_version', 'healthy', 'install_environment', From 129536498619cc4241ed6424335c9ff93a7222e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Sat, 1 Feb 2020 15:41:14 +0200 Subject: [PATCH 3/6] Add basic perl repo test --- testing/resources/perl_hooks_repo/.gitignore | 7 +++++++ .../resources/perl_hooks_repo/.pre-commit-hooks.yaml | 5 +++++ testing/resources/perl_hooks_repo/MANIFEST | 4 ++++ testing/resources/perl_hooks_repo/Makefile.PL | 10 ++++++++++ .../perl_hooks_repo/bin/pre-commit-perl-hello | 7 +++++++ .../resources/perl_hooks_repo/lib/PreCommitHello.pm | 12 ++++++++++++ tests/repository_test.py | 7 +++++++ 7 files changed, 52 insertions(+) create mode 100644 testing/resources/perl_hooks_repo/.gitignore create mode 100644 testing/resources/perl_hooks_repo/.pre-commit-hooks.yaml create mode 100644 testing/resources/perl_hooks_repo/MANIFEST create mode 100644 testing/resources/perl_hooks_repo/Makefile.PL create mode 100755 testing/resources/perl_hooks_repo/bin/pre-commit-perl-hello create mode 100644 testing/resources/perl_hooks_repo/lib/PreCommitHello.pm diff --git a/testing/resources/perl_hooks_repo/.gitignore b/testing/resources/perl_hooks_repo/.gitignore new file mode 100644 index 00000000..7af99404 --- /dev/null +++ b/testing/resources/perl_hooks_repo/.gitignore @@ -0,0 +1,7 @@ +/MYMETA.json +/MYMETA.yml +/Makefile +/PreCommitHello-*.tar.* +/PreCommitHello-*/ +/blib/ +/pm_to_blib diff --git a/testing/resources/perl_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/perl_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 00000000..11e6f6cd --- /dev/null +++ b/testing/resources/perl_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: perl-hook + name: perl example hook + entry: pre-commit-perl-hello + language: perl + files: '' diff --git a/testing/resources/perl_hooks_repo/MANIFEST b/testing/resources/perl_hooks_repo/MANIFEST new file mode 100644 index 00000000..4a20084c --- /dev/null +++ b/testing/resources/perl_hooks_repo/MANIFEST @@ -0,0 +1,4 @@ +MANIFEST +Makefile.PL +bin/pre-commit-perl-hello +lib/PreCommitHello.pm diff --git a/testing/resources/perl_hooks_repo/Makefile.PL b/testing/resources/perl_hooks_repo/Makefile.PL new file mode 100644 index 00000000..6c70e107 --- /dev/null +++ b/testing/resources/perl_hooks_repo/Makefile.PL @@ -0,0 +1,10 @@ +use strict; +use warnings; + +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => "PreCommitHello", + VERSION_FROM => "lib/PreCommitHello.pm", + EXE_FILES => [qw(bin/pre-commit-perl-hello)], +); diff --git a/testing/resources/perl_hooks_repo/bin/pre-commit-perl-hello b/testing/resources/perl_hooks_repo/bin/pre-commit-perl-hello new file mode 100755 index 00000000..9474009a --- /dev/null +++ b/testing/resources/perl_hooks_repo/bin/pre-commit-perl-hello @@ -0,0 +1,7 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use PreCommitHello; + +PreCommitHello::hello(); diff --git a/testing/resources/perl_hooks_repo/lib/PreCommitHello.pm b/testing/resources/perl_hooks_repo/lib/PreCommitHello.pm new file mode 100644 index 00000000..c76521ce --- /dev/null +++ b/testing/resources/perl_hooks_repo/lib/PreCommitHello.pm @@ -0,0 +1,12 @@ +package PreCommitHello; + +use strict; +use warnings; + +our $VERSION = "0.1.0"; + +sub hello { + print "Hello from perl-commit Perl!\n"; +} + +1; diff --git a/tests/repository_test.py b/tests/repository_test.py index 21f2f41c..6fcf5e5d 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -876,3 +876,10 @@ def test_manifest_hooks(tempdir_factory, store): types=['file'], verbose=False, ) + + +def test_perl_hook(tempdir_factory, store): + _test_hook_repo( + tempdir_factory, store, 'perl_hooks_repo', + 'perl-hook', [], b'Hello from perl-commit Perl!\n', + ) From 04471f7d9795f6d7aee49a9db710bf0c27a21866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Sat, 1 Feb 2020 16:13:01 +0200 Subject: [PATCH 4/6] Add perl additional dependencies test --- pre_commit/resources/empty_template_Makefile.PL | 6 ++++++ pre_commit/store.py | 1 + tests/repository_test.py | 17 +++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 pre_commit/resources/empty_template_Makefile.PL diff --git a/pre_commit/resources/empty_template_Makefile.PL b/pre_commit/resources/empty_template_Makefile.PL new file mode 100644 index 00000000..ac75fe53 --- /dev/null +++ b/pre_commit/resources/empty_template_Makefile.PL @@ -0,0 +1,6 @@ +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => "PreCommitDummy", + VERSION => "0.0.1", +); diff --git a/pre_commit/store.py b/pre_commit/store.py index 4af16193..760b37aa 100644 --- a/pre_commit/store.py +++ b/pre_commit/store.py @@ -184,6 +184,7 @@ class Store: LOCAL_RESOURCES = ( 'Cargo.toml', 'main.go', 'main.rs', '.npmignore', 'package.json', 'pre_commit_dummy_package.gemspec', 'setup.py', 'environment.yml', + 'Makefile.PL', ) def make_local(self, deps: Sequence[str]) -> str: diff --git a/tests/repository_test.py b/tests/repository_test.py index 6fcf5e5d..b745a9aa 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -883,3 +883,20 @@ def test_perl_hook(tempdir_factory, store): tempdir_factory, store, 'perl_hooks_repo', 'perl-hook', [], b'Hello from perl-commit Perl!\n', ) + + +def test_local_perl_additional_dependencies(store): + config = { + 'repo': 'local', + 'hooks': [{ + 'id': 'hello', + 'name': 'hello', + 'entry': 'perltidy --version', + 'language': 'perl', + 'additional_dependencies': ['SHANCOCK/Perl-Tidy-20200110.tar.gz'], + }], + } + hook = _get_hook(config, store, 'hello') + ret, out = _hook_run(hook, (), color=False) + assert ret == 0 + assert _norm_out(out).startswith(b'This is perltidy, v20200110') From 44f5753bd83080b39a42566278d76e5b51918846 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 3 Feb 2020 10:39:08 -0800 Subject: [PATCH 5/6] shlex-quote install path to fix windows --- pre_commit/languages/perl.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pre_commit/languages/perl.py b/pre_commit/languages/perl.py index 52d8aab9..f61815aa 100644 --- a/pre_commit/languages/perl.py +++ b/pre_commit/languages/perl.py @@ -1,5 +1,6 @@ import contextlib import os +import shlex from typing import Generator from typing import Sequence from typing import Tuple @@ -26,11 +27,11 @@ def get_env_patch(venv: str) -> PatchesT: return ( ('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))), ('PERL5LIB', os.path.join(venv, 'lib', 'perl5')), - ('PERL_MB_OPT', f'--install_base {venv}'), + ('PERL_MB_OPT', f'--install_base {shlex.quote(venv)}'), ( 'PERL_MM_OPT', ( - f'INSTALL_BASE={venv}' - ' INSTALLSITEMAN1DIR=none INSTALLSITEMAN3DIR=none' + f'INSTALL_BASE={shlex.quote(venv)} ' + f'INSTALLSITEMAN1DIR=none INSTALLSITEMAN3DIR=none' ), ), ) From 977bbd7643e9df9769a76e6e7b9502cfed05b91c Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 3 Feb 2020 12:42:10 -0800 Subject: [PATCH 6/6] put strawberry perl on the beginning of the PATH for windows --- azure-pipelines.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b9f0b5f3..c51b4a5f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -24,6 +24,11 @@ jobs: pre_test: - powershell: Write-Host "##vso[task.prependpath]$env:CONDA\Scripts" displayName: Add conda to PATH + - powershell: | + Write-Host "##vso[task.prependpath]C:\Strawberry\perl\bin" + Write-Host "##vso[task.prependpath]C:\Strawberry\perl\site\bin" + Write-Host "##vso[task.prependpath]C:\Strawberry\c\bin" + displayName: Add strawberry perl to PATH - template: job--python-tox.yml@asottile parameters: toxenvs: [py37]