|
| 1 | +from __future__ import unicode_literals |
| 2 | + |
| 3 | +import hashlib |
| 4 | +import os |
| 5 | + |
| 6 | +from pre_commit.languages import helpers |
| 7 | +from pre_commit.util import clean_path_on_failure |
| 8 | +from pre_commit.util import mkdirp |
| 9 | +from pre_commit.xargs import xargs |
| 10 | + |
| 11 | + |
| 12 | +ENVIRONMENT_DIR = 'docker' |
| 13 | + |
| 14 | + |
| 15 | +def md5(s): |
| 16 | + m = hashlib.md5() |
| 17 | + m.update(s) |
| 18 | + return m.hexdigest() |
| 19 | + |
| 20 | + |
| 21 | +def docker_tag(repo_cmd_runner): |
| 22 | + return 'pre-commit-{}'.format( |
| 23 | + md5(os.path.basename(repo_cmd_runner.path())) |
| 24 | + ).lower() |
| 25 | + |
| 26 | + |
| 27 | +def install_environment( |
| 28 | + repo_cmd_runner, |
| 29 | + version='default', |
| 30 | + additional_dependencies=(), |
| 31 | +): |
| 32 | + assert repo_cmd_runner.exists('Dockerfile') |
| 33 | + # I don't know of anybody trying to juggle multiple docker installations |
| 34 | + # so this seems sufficient |
| 35 | + directory = helpers.environment_dir(ENVIRONMENT_DIR, 'default') |
| 36 | + mkdirp(os.path.join(repo_cmd_runner.path(), directory)) |
| 37 | + |
| 38 | + cmd = ( |
| 39 | + 'docker', 'build', '--pull', |
| 40 | + '--tag', docker_tag(repo_cmd_runner), |
| 41 | + '.' |
| 42 | + ) |
| 43 | + |
| 44 | + # Docker doesn't really have relevant disk environment, but pre-commit |
| 45 | + # still needs to cleanup it's state files on failure |
| 46 | + env_dir = repo_cmd_runner.path(directory) |
| 47 | + with clean_path_on_failure(env_dir): |
| 48 | + helpers.run_setup_cmd(repo_cmd_runner, cmd) |
| 49 | + |
| 50 | + |
| 51 | +def run_hook(repo_cmd_runner, hook, file_args): |
| 52 | + cmd = ( |
| 53 | + 'docker', 'run', |
| 54 | + '-t', |
| 55 | + '-v', '{}:/src'.format(os.getcwd()), |
| 56 | + '--workdir', '/src', |
| 57 | + docker_tag(repo_cmd_runner) |
| 58 | + ) |
| 59 | + |
| 60 | + return xargs( |
| 61 | + cmd + (hook['entry'],) + tuple(hook['args']), file_args, |
| 62 | + ) |
0 commit comments