-
Notifications
You must be signed in to change notification settings - Fork 18
/
compiler.py
executable file
·105 lines (87 loc) · 4.89 KB
/
compiler.py
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from __future__ import print_function
from pipeline.compilers import SubProcessCompiler
from django.conf import settings
from django.core.exceptions import SuspiciousFileOperation
from pipeline.exceptions import CompilerError
from warnings import warn
class BrowserifyCompiler(SubProcessCompiler):
output_extension = 'browserified.js'
def match_file(self, path):
if self.verbose:
print('matching file:', path)
return path.endswith('.browserify.js')
# similar to old removed in https://github.com/jazzband/django-pipeline/commit/1f6b48ae74026a12f955f2f15f9f08823d744515
def simple_execute_command(self, cmd, **kwargs):
import subprocess
try:
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
except OSError as e:
raise CompilerError("Compiler failed to execute. (%s)" % e, command=cmd, error_output="Executing the compiler resulted in an %s from the system.\n\nThis is most likely due to the `browserify` executable not being found in your PATH (if it is installed globally), or a misconfigured BROWSERIFY_BINARY setting (if you are using a non-global install)." % repr(e))
stdout, stderr = pipe.communicate()
if self.verbose:
print(stdout)
print(stderr)
if pipe.returncode != 0:
raise CompilerError("Compiler returned non-zero exit status %i" % pipe.returncode, command=cmd, error_output=stderr)
return stdout.decode()
def _get_cmd_parts(self):
pipeline_settings = getattr(settings, 'PIPELINE', {})
tool = pipeline_settings.get('BROWSERIFY_BINARY', "browserify")
old_args = pipeline_settings.get('BROWSERIFY_ARGUMENTS', '')
if old_args:
warn("You are using the string-based BROWSERIFY_ARGUMENTS setting. Please migrate to providing a list of arguments via BROWSERIFY_ARGS instead.", DeprecationWarning)
args = old_args.split()
else:
args = pipeline_settings.get('BROWSERIFY_ARGS', [])
old_env = pipeline_settings.get('BROWSERIFY_VARS', '')
if old_env:
warn("You are using the string-based BROWSERIFY_VARS setting. Please migrate to providing a dict of environment variables via BROWSERIFY_ENV instead.", DeprecationWarning)
env = dict(map(lambda s: s.split('='), old_env.split()))
else:
env = pipeline_settings.get('BROWSERIFY_ENV', None)
if env:
# when there's custom variables, we need to explicitly pass along the original environment
import os
_env = {}
_env.update(os.environ)
_env.update(env)
env = _env
return tool, args, env
def compile_file(self, infile, outfile, outdated=False, force=False):
if not force and not outdated:
return
tool, args, env = self._get_cmd_parts()
cmd = [tool] + args + [infile, '--outfile', outfile]
if self.verbose:
print("compile_file command:", cmd, env)
self.simple_execute_command(cmd, env=env)
def is_outdated(self, infile, outfile):
"""Check if the input file is outdated.
The difficulty with the default implementation is that any file that is
`require`d from the entry-point file will not trigger a recompile if it
is modified. This overloaded version of the method corrects this by generating
a list of all required files that are also a part of the storage manifest
and checking if they've been modified since the last compile.
The command used to generate the list of dependencies is the same as the compile
command but uses the `--list` option instead of `--outfile`.
WARNING: It seems to me that just generating the dependencies may take just
as long as actually compiling, which would mean we would be better off just
forcing a compile every time.
"""
# Preliminary check for simply missing file or modified entry-point file.
if super(BrowserifyCompiler, self).is_outdated(infile, outfile):
return True
# Otherwise we need to see what dependencies there are now, and if they're modified.
tool, args, env = self._get_cmd_parts()
cmd = [tool] + args + ['--list', infile]
if self.verbose:
print("is_outdated command:", cmd, env)
dep_list = self.simple_execute_command(cmd, env=env)
if self.verbose:
print("dep_list is:", dep_list)
for dep_file in dep_list.strip().split('\n'):
if super(BrowserifyCompiler, self).is_outdated(dep_file, outfile):
if self.verbose:
print("Found dep_file \"%s\" updated." % dep_file)
return True
return False