From 511de4fe3206c8a46625985f322ccd8f017044c0 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 2 Jun 2014 16:10:59 -0700 Subject: [PATCH] Support hooks with custom node version. --- .pre-commit-config.yaml | 4 +- pre_commit/languages/node.py | 55 +++++++++---------- setup.py | 1 + .../node_0_11_8_hooks_repo/bin/main.js | 4 ++ .../node_0_11_8_hooks_repo/hooks.yaml | 5 ++ .../node_0_11_8_hooks_repo/package.json | 5 ++ tests/conftest.py | 10 ++++ tests/repository_test.py | 8 +++ 8 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 testing/resources/node_0_11_8_hooks_repo/bin/main.js create mode 100644 testing/resources/node_0_11_8_hooks_repo/hooks.yaml create mode 100644 testing/resources/node_0_11_8_hooks_repo/package.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aa11be69..887ebed6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,9 +2,9 @@ sha: ca93f6834f2afc8a8f7de46c0e02076419077c7a hooks: - id: trailing-whitespace - files: \.(py|sh|yaml)$ + files: \.(js|py|sh|yaml)$ - id: end-of-file-fixer - files: \.(py|sh|yaml)$ + files: \.(js|py|sh|yaml)$ - id: check-yaml files: \.(yaml|yml)$ - id: debug-statements diff --git a/pre_commit/languages/node.py b/pre_commit/languages/node.py index 57001ce5..0ddc3fa0 100644 --- a/pre_commit/languages/node.py +++ b/pre_commit/languages/node.py @@ -1,7 +1,6 @@ import contextlib from pre_commit.languages import helpers -from pre_commit.languages import python from pre_commit.prefixed_command_runner import CalledProcessError from pre_commit.util import clean_path_on_failure @@ -9,14 +8,10 @@ from pre_commit.util import clean_path_on_failure ENVIRONMENT_DIR = 'node_env' -class NodeEnv(python.PythonEnv): +class NodeEnv(helpers.Environment): @property def env_prefix(self): - base = super(NodeEnv, self).env_prefix - return ' '.join([ - base, - '. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR)] - ) + return '. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR) @contextlib.contextmanager @@ -27,29 +22,31 @@ def in_env(repo_cmd_runner): def install_environment(repo_cmd_runner, version='default'): assert repo_cmd_runner.exists('package.json') - with clean_path_on_failure(repo_cmd_runner.path(python.ENVIRONMENT_DIR)): - repo_cmd_runner.run( - ['virtualenv', '{{prefix}}{0}'.format(python.ENVIRONMENT_DIR)], - ) + env_dir = repo_cmd_runner.path(ENVIRONMENT_DIR) + with clean_path_on_failure(env_dir): + if version == 'default': + # In the default case we attempt to install system node and if that + # doesn't work we use --prebuilt + try: + with clean_path_on_failure(env_dir): + repo_cmd_runner.run([ + 'nodeenv', '-n', 'system', + '{{prefix}}{0}'.format(ENVIRONMENT_DIR), + ]) + except CalledProcessError: + # TODO: log failure here + repo_cmd_runner.run([ + 'nodeenv', '--prebuilt', + '{{prefix}}{0}'.format(ENVIRONMENT_DIR) + ]) + else: + repo_cmd_runner.run([ + 'nodeenv', '--prebuilt', '-n', version, + '{{prefix}}{0}'.format(ENVIRONMENT_DIR) + ]) - with python.in_env(repo_cmd_runner) as python_env: - python_env.run('pip install nodeenv') - - with clean_path_on_failure(repo_cmd_runner.path(ENVIRONMENT_DIR)): - # Try and use the system level node executable first - try: - with clean_path_on_failure(repo_cmd_runner.path(ENVIRONMENT_DIR)): - python_env.run( - 'nodeenv -n system {{prefix}}{0}'.format(ENVIRONMENT_DIR), - ) - except CalledProcessError: - # TODO: log failure here - python_env.run( - 'nodeenv --jobs 4 {{prefix}}{0}'.format(ENVIRONMENT_DIR), - ) - - with in_env(repo_cmd_runner) as node_env: - node_env.run('cd {prefix} && npm install -g') + with in_env(repo_cmd_runner) as node_env: + node_env.run('cd {prefix} && npm install -g') def run_hook(repo_cmd_runner, hook, file_args): diff --git a/setup.py b/setup.py index 2417b1ae..da10107a 100644 --- a/setup.py +++ b/setup.py @@ -33,6 +33,7 @@ setup( 'asottile.ordereddict', 'asottile.yaml', 'jsonschema', + 'nodeenv>=0.9.4', 'plumbum', 'pyyaml', 'simplejson', diff --git a/testing/resources/node_0_11_8_hooks_repo/bin/main.js b/testing/resources/node_0_11_8_hooks_repo/bin/main.js new file mode 100644 index 00000000..df12cbeb --- /dev/null +++ b/testing/resources/node_0_11_8_hooks_repo/bin/main.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node + +console.log(process.version); +console.log('Hello World'); diff --git a/testing/resources/node_0_11_8_hooks_repo/hooks.yaml b/testing/resources/node_0_11_8_hooks_repo/hooks.yaml new file mode 100644 index 00000000..6fc04785 --- /dev/null +++ b/testing/resources/node_0_11_8_hooks_repo/hooks.yaml @@ -0,0 +1,5 @@ +- id: node-11-8-hook + name: Node 0.11.8 hook + entry: node-11-8-hook + language: node + language_version: 0.11.8 diff --git a/testing/resources/node_0_11_8_hooks_repo/package.json b/testing/resources/node_0_11_8_hooks_repo/package.json new file mode 100644 index 00000000..911a3ed9 --- /dev/null +++ b/testing/resources/node_0_11_8_hooks_repo/package.json @@ -0,0 +1,5 @@ +{ + "name": "node-11-8-hook", + "version": "0.0.1", + "bin": {"node-11-8-hook": "./bin/main.js"} +} diff --git a/tests/conftest.py b/tests/conftest.py index 2c17ea60..0baa468b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -82,6 +82,11 @@ def node_hooks_repo(dummy_git_repo): yield _make_repo(dummy_git_repo, 'node_hooks_repo') +@pytest.yield_fixture +def node_0_11_8_hooks_repo(dummy_git_repo): + yield _make_repo(dummy_git_repo, 'node_0_11_8_hooks_repo') + + @pytest.yield_fixture def ruby_hooks_repo(dummy_git_repo): yield _make_repo(dummy_git_repo, 'ruby_hooks_repo') @@ -128,6 +133,11 @@ def config_for_node_hooks_repo(node_hooks_repo): yield _make_config(node_hooks_repo, 'foo', '\\.js$') +@pytest.yield_fixture +def config_for_node_0_11_8_hooks_repo(node_0_11_8_hooks_repo): + yield _make_config(node_0_11_8_hooks_repo, 'node-11-8-hook', '\\.js$') + + @pytest.yield_fixture def config_for_ruby_hooks_repo(ruby_hooks_repo): yield _make_config(ruby_hooks_repo, 'ruby_hook', '\\.rb$') diff --git a/tests/repository_test.py b/tests/repository_test.py index 408eb8f8..ed3bbb0f 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -32,6 +32,14 @@ def test_run_versioned_hook(config_for_python3_hooks_repo, store): assert ret[1] == "3.3\n['/dev/null']\nHello World\n" +@pytest.mark.integration +def test_run_versioned_node_hook(config_for_node_0_11_8_hooks_repo, store): + repo = Repository.create(config_for_node_0_11_8_hooks_repo, store) + ret = repo.run_hook('node-11-8-hook', ['/dev/null']) + assert ret[0] == 0 + assert ret[1] == 'v0.11.8\nHello World\n' + + @pytest.mark.integration def test_lots_of_files(config_for_python_hooks_repo, store): repo = Repository.create(config_for_python_hooks_repo, store)