1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
#!/usr/bin/env python3
from __future__ import annotations
import os.path
import shutil
import stat
import sys
import tempfile
import zipfile
from pre_commit.file_lock import lock
CACHE_DIR = os.path.expanduser('~/.cache/pre-commit-zipapp')
def _make_executable(filename: str) -> None:
os.chmod(filename, os.stat(filename).st_mode | stat.S_IXUSR)
def _ensure_cache(zipf: zipfile.ZipFile, cache_key: str) -> str:
os.makedirs(CACHE_DIR, exist_ok=True)
cache_dest = os.path.join(CACHE_DIR, cache_key)
lock_filename = os.path.join(CACHE_DIR, f'{cache_key}.lock')
if os.path.exists(cache_dest):
return cache_dest
with lock(lock_filename, blocked_cb=lambda: None):
# another process may have completed this work
if os.path.exists(cache_dest):
return cache_dest
tmpdir = tempfile.mkdtemp(prefix=os.path.join(CACHE_DIR, ''))
try:
zipf.extractall(tmpdir)
# zip doesn't maintain permissions
_make_executable(os.path.join(tmpdir, 'python'))
_make_executable(os.path.join(tmpdir, 'python.exe'))
os.rename(tmpdir, cache_dest)
except BaseException:
shutil.rmtree(tmpdir)
raise
return cache_dest
def main() -> int:
with zipfile.ZipFile(os.path.dirname(__file__)) as zipf:
with zipf.open('CACHE_KEY') as f:
cache_key = f.read().decode().strip()
cache_dest = _ensure_cache(zipf, cache_key)
if sys.platform != 'win32':
exe = os.path.join(cache_dest, 'python')
else:
exe = os.path.join(cache_dest, 'python.exe')
cmd = (exe, '-mpre_commit', *sys.argv[1:])
if sys.platform == 'win32': # https://bugs.python.org/issue19124
import subprocess
return subprocess.call(cmd)
else:
os.execvp(cmd[0], cmd)
if __name__ == '__main__':
raise SystemExit(main())
|