Skip to content

Commit 74363e6

Browse files
committed
Print message when installing repositories.
1 parent 36ecf23 commit 74363e6

File tree

9 files changed

+78
-29
lines changed

9 files changed

+78
-29
lines changed

pre_commit/languages/all.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
from pre_commit.languages import script
66
from pre_commit.languages import system
77

8-
# A language implements the following two functions in its module:
8+
# A language implements the following constant and two functions in its module:
9+
#
10+
# # Use None for no environment
11+
# ENVIRONMENT_DIR = 'foo_env'
912
#
1013
# def install_environment(repo_cmd_runner):
1114
# """Installs a repository in the given repository. Note that the current

pre_commit/languages/node.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from pre_commit.util import clean_path_on_failure
77

88

9-
NODE_ENV = 'node_env'
9+
ENVIRONMENT_DIR = 'node_env'
1010

1111

1212
class NodeEnv(python.PythonEnv):
@@ -15,7 +15,7 @@ def env_prefix(self):
1515
base = super(NodeEnv, self).env_prefix
1616
return ' '.join([
1717
base,
18-
'. {{prefix}}{0}/bin/activate &&'.format(NODE_ENV)]
18+
'. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR)]
1919
)
2020

2121

@@ -27,30 +27,26 @@ def in_env(repo_cmd_runner):
2727
def install_environment(repo_cmd_runner):
2828
assert repo_cmd_runner.exists('package.json')
2929

30-
# Return immediately if we already have a virtualenv
31-
if repo_cmd_runner.exists(NODE_ENV):
32-
return
33-
34-
with clean_path_on_failure(repo_cmd_runner.path(python.PY_ENV)):
30+
with clean_path_on_failure(repo_cmd_runner.path(python.ENVIRONMENT_DIR)):
3531
repo_cmd_runner.run(
36-
['virtualenv', '{{prefix}}{0}'.format(python.PY_ENV)],
32+
['virtualenv', '{{prefix}}{0}'.format(python.ENVIRONMENT_DIR)],
3733
)
3834

3935
with python.in_env(repo_cmd_runner) as python_env:
4036
python_env.run('pip install nodeenv')
4137

42-
with clean_path_on_failure(repo_cmd_runner.path(NODE_ENV)):
38+
with clean_path_on_failure(repo_cmd_runner.path(ENVIRONMENT_DIR)):
4339
# Try and use the system level node executable first
4440
try:
4541
python_env.run(
46-
'nodeenv -n system {{prefix}}{0}'.format(NODE_ENV),
42+
'nodeenv -n system {{prefix}}{0}'.format(ENVIRONMENT_DIR),
4743
)
4844
except CalledProcessError:
4945
# TODO: log failure here
5046
# cleanup
51-
# TODO: local.path(NODE_ENV).delete()
47+
# TODO: local.path(ENVIRONMENT_DIR).delete()
5248
python_env.run(
53-
'nodeenv --jobs 4 {{prefix}}{0}'.format(NODE_ENV),
49+
'nodeenv --jobs 4 {{prefix}}{0}'.format(ENVIRONMENT_DIR),
5450
)
5551

5652
with in_env(repo_cmd_runner) as node_env:

pre_commit/languages/python.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
from pre_commit.util import clean_path_on_failure
66

77

8-
PY_ENV = 'py_env'
8+
ENVIRONMENT_DIR = 'py_env'
99

1010

1111
class PythonEnv(helpers.Environment):
1212
@property
1313
def env_prefix(self):
14-
return '. {{prefix}}{0}/bin/activate &&'.format(PY_ENV)
14+
return '. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR)
1515

1616

1717
@contextlib.contextmanager
@@ -21,13 +21,10 @@ def in_env(repo_cmd_runner):
2121

2222
def install_environment(repo_cmd_runner):
2323
assert repo_cmd_runner.exists('setup.py')
24-
# Return immediately if we already have a virtualenv
25-
if repo_cmd_runner.exists(PY_ENV):
26-
return
2724

2825
# Install a virtualenv
29-
with clean_path_on_failure(repo_cmd_runner.path(PY_ENV)):
30-
repo_cmd_runner.run(['virtualenv', '{{prefix}}{0}'.format(PY_ENV)])
26+
with clean_path_on_failure(repo_cmd_runner.path(ENVIRONMENT_DIR)):
27+
repo_cmd_runner.run(['virtualenv', '{{prefix}}{0}'.format(ENVIRONMENT_DIR)])
3128
with in_env(repo_cmd_runner) as env:
3229
env.run('cd {prefix} && pip install .')
3330

pre_commit/languages/ruby.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
from pre_commit.util import clean_path_on_failure
66

77

8-
RVM_ENV = 'rvm_env'
8+
ENVIRONMENT_DIR = 'rvm_env'
99

1010

1111
class RubyEnv(helpers.Environment):
1212
@property
1313
def env_prefix(self):
14-
return '. {{prefix}}{0}/bin/activate &&'.format(RVM_ENV)
14+
return '. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR)
1515

1616

1717
@contextlib.contextmanager
@@ -21,11 +21,11 @@ def in_env(repo_cmd_runner):
2121

2222
def install_environment(repo_cmd_runner):
2323
# Return immediately if we already have a virtualenv
24-
if repo_cmd_runner.exists(RVM_ENV):
24+
if repo_cmd_runner.exists(ENVIRONMENT_DIR):
2525
return
2626

27-
with clean_path_on_failure(repo_cmd_runner.path(RVM_ENV)):
28-
repo_cmd_runner.run(['__rvm-env.sh', '{{prefix}}{0}'.format(RVM_ENV)])
27+
with clean_path_on_failure(repo_cmd_runner.path(ENVIRONMENT_DIR)):
28+
repo_cmd_runner.run(['__rvm-env.sh', '{{prefix}}{0}'.format(ENVIRONMENT_DIR)])
2929
with in_env(repo_cmd_runner) as env:
3030
env.run('cd {prefix} && bundle install')
3131

pre_commit/languages/script.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11

2+
ENVIRONMENT_DIR = None
3+
4+
25
def install_environment(repo_cmd_runner):
36
"""Installation for script type is a noop."""
4-
pass
57

68

79
def run_hook(repo_cmd_runner, hook, file_args):

pre_commit/languages/system.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11

2+
ENVIRONMENT_DIR = None
3+
4+
25
def install_environment(repo_cmd_runner):
36
"""Installation for system type is a noop."""
4-
pass
57

68

79
def run_hook(repo_cmd_runner, hook, file_args):

pre_commit/repository.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
from __future__ import print_function
3+
24
import contextlib
35
from plumbum import local
46

@@ -63,6 +65,10 @@ def create(self):
6365
# Project already exists, no reason to re-create it
6466
return
6567

68+
# Checking out environment for the first time
69+
print('Installing environment for {0}.'.format(self.repo_url))
70+
print('Once installed this environment will be reused.')
71+
print('This may take a few minutes...')
6672
with clean_path_on_failure(unicode(local.path(self.sha))):
6773
local['git']['clone', '--no-checkout', self.repo_url, self.sha]()
6874
with self.in_checkout():
@@ -73,6 +79,7 @@ def require_installed(self, cmd_runner):
7379
return
7480

7581
self.install(cmd_runner)
82+
self.__installed = True
7683

7784
def install(self, cmd_runner):
7885
"""Install the hook repository.
@@ -82,8 +89,15 @@ def install(self, cmd_runner):
8289
"""
8390
self.require_created()
8491
repo_cmd_runner = self.get_cmd_runner(cmd_runner)
85-
for language in self.languages:
86-
languages[language].install_environment(repo_cmd_runner)
92+
for language_name in self.languages:
93+
language = languages[language_name]
94+
if (
95+
language.ENVIRONMENT_DIR is None or
96+
repo_cmd_runner.exists(language.ENVIRONMENT_DIR)
97+
):
98+
# The language is already installed
99+
continue
100+
language.install_environment(repo_cmd_runner)
87101

88102
@contextlib.contextmanager
89103
def in_checkout(self):

tests/languages/all_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
def test_all_languages_support_interface(language):
1010
assert hasattr(languages[language], 'install_environment')
1111
assert hasattr(languages[language], 'run_hook')
12+
assert hasattr(languages[language], 'ENVIRONMENT_DIR')

tests/repository_test.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import __builtin__
2+
import mock
13
import os
24
import pytest
35

@@ -130,3 +132,35 @@ def test_sha(mock_repo_config):
130132
def test_languages(config_for_python_hooks_repo):
131133
repo = Repository(config_for_python_hooks_repo)
132134
assert repo.languages == set(['python'])
135+
136+
137+
@pytest.yield_fixture
138+
def print_mock():
139+
with mock.patch.object(__builtin__, 'print', autospec=True) as print_mock:
140+
yield print_mock
141+
142+
143+
def test_prints_while_creating(config_for_python_hooks_repo, print_mock):
144+
repo = Repository(config_for_python_hooks_repo)
145+
repo.require_created()
146+
print_mock.assert_called_with('This may take a few minutes...')
147+
print_mock.reset_mock()
148+
# Reinstall with same repo should not trigger another install
149+
repo.require_created()
150+
assert print_mock.call_count == 0
151+
# Reinstall on another run should not trigger another install
152+
repo = Repository(config_for_python_hooks_repo)
153+
repo.require_created()
154+
assert print_mock.call_count == 0
155+
156+
157+
def test_reinstall(config_for_python_hooks_repo):
158+
repo = Repository(config_for_python_hooks_repo)
159+
repo.require_installed(PrefixedCommandRunner(C.HOOKS_WORKSPACE))
160+
# Reinstall with same repo should not trigger another install
161+
# TODO: how to assert this?
162+
repo.require_installed(PrefixedCommandRunner(C.HOOKS_WORKSPACE))
163+
# Reinstall on another run should not trigger another install
164+
# TODO: how to assert this?
165+
repo = Repository(config_for_python_hooks_repo)
166+
repo.require_installed(PrefixedCommandRunner(C.HOOKS_WORKSPACE))

0 commit comments

Comments
 (0)