Mercurial > piecrust2
comparison piecrust/processing/browserify.py @ 1049:c2bfa1869f0d
bake: Optimize Browserify dependency handling.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 26 Jan 2018 18:01:15 -0800 |
parents | 717ac3c4ee77 |
children | a3dec0fbd9ce |
comparison
equal
deleted
inserted
replaced
1048:63be34ce6e65 | 1049:c2bfa1869f0d |
---|---|
1 import os | 1 import os |
2 import os.path | 2 import os.path |
3 import hashlib | |
3 import logging | 4 import logging |
4 import platform | 5 import platform |
5 import subprocess | 6 import subprocess |
6 from piecrust.processing.base import Processor, PRIORITY_FIRST, FORCE_BUILD | 7 from piecrust.processing.base import Processor, PRIORITY_FIRST, FORCE_BUILD |
7 | 8 |
13 PROCESSOR_NAME = 'browserify' | 14 PROCESSOR_NAME = 'browserify' |
14 | 15 |
15 def __init__(self): | 16 def __init__(self): |
16 super(BrowserifyProcessor, self).__init__() | 17 super(BrowserifyProcessor, self).__init__() |
17 self.priority = PRIORITY_FIRST | 18 self.priority = PRIORITY_FIRST |
18 self.is_delegating_dependency_check = False | 19 self._tmp_dir = None |
19 self._conf = None | 20 self._conf = None |
20 | 21 |
21 def initialize(self, app): | 22 def initialize(self, app): |
22 super(BrowserifyProcessor, self).initialize(app) | 23 super(BrowserifyProcessor, self).initialize(app) |
23 | 24 |
28 if self._conf is True: | 29 if self._conf is True: |
29 self._conf = {} | 30 self._conf = {} |
30 | 31 |
31 self._conf.setdefault('bin', 'browserify') | 32 self._conf.setdefault('bin', 'browserify') |
32 | 33 |
34 def onPipelineStart(self, ctx): | |
35 self._tmp_dir = ctx.tmp_dir | |
36 | |
33 def matches(self, path): | 37 def matches(self, path): |
34 return self._conf is not None and os.path.splitext(path)[1] == '.js' | 38 return self._conf is not None and os.path.splitext(path)[1] == '.js' |
35 | 39 |
36 def getDependencies(self, path): | 40 def getDependencies(self, path): |
37 return FORCE_BUILD | 41 deps_path = self._getDepListPath(path) |
42 try: | |
43 with open(deps_path, 'r', encoding='utf8') as f: | |
44 deps_list = f.read() | |
45 except OSError: | |
46 logger.debug("No dependency list found for Browserify target '%s' " | |
47 "at '%s'. Rebuilding" % (path, deps_path)) | |
48 return FORCE_BUILD | |
49 | |
50 deps_list = [d.strip() for d in deps_list.split('\n')] | |
51 return filter(lambda d: d, deps_list) | |
38 | 52 |
39 def getOutputFilenames(self, filename): | 53 def getOutputFilenames(self, filename): |
40 return [filename] | 54 return [filename] |
41 | 55 |
42 def process(self, path, out_dir): | 56 def process(self, path, out_dir): |
57 # Update the dependency list file. | |
58 # Sadly there doesn't seem to be a way to get the list at the same | |
59 # time as compiling the bundle so we need to run the process twice :( | |
60 deps_list = self._runBrowserify([path, '--list']) | |
61 deps_list = deps_list.decode('utf8') | |
62 deps_path = self._getDepListPath(path) | |
63 with open(deps_path, 'w', encoding='utf8') as f: | |
64 f.write(deps_list) | |
65 | |
66 # Actually compile the JS bundle. | |
43 out_path = os.path.join(out_dir, os.path.basename(path)) | 67 out_path = os.path.join(out_dir, os.path.basename(path)) |
68 self._runBrowserify([path, '-o', out_path]) | |
44 | 69 |
45 args = [self._conf['bin'], path, '-o', out_path] | 70 return True |
71 | |
72 def _runBrowserify(self, args): | |
73 args = [self._conf['bin']] + args | |
46 cwd = self.app.root_dir | 74 cwd = self.app.root_dir |
47 logger.debug("Running Browserify: %s" % ' '.join(args)) | 75 logger.debug("Running Browserify: %s" % ' '.join(args)) |
48 try: | 76 try: |
49 retcode = subprocess.call(args, cwd=cwd) | 77 return subprocess.check_output( |
78 args, | |
79 cwd=cwd, | |
80 stderr=subprocess.STDOUT) | |
50 except FileNotFoundError as ex: | 81 except FileNotFoundError as ex: |
51 logger.error("Tried running Browserify processor " | 82 logger.error("Tried running Browserify with command: %s" % args) |
52 "with command: %s" % args) | |
53 raise Exception("Error running Browserify. " | 83 raise Exception("Error running Browserify. " |
54 "Did you install it?") from ex | 84 "Did you install it?") from ex |
55 if retcode != 0: | 85 except subprocess.CalledProcessError as ex: |
56 raise Exception("Error occured in Browserify compiler. " | 86 logger.error("Error occured while running Browserify:") |
87 logger.info(ex.stdout) | |
88 logger.error(ex.stderr) | |
89 raise Exception("Error occured while running Browserify. " | |
57 "Please check log messages above for " | 90 "Please check log messages above for " |
58 "more information.") | 91 "more information.") |
59 return True | 92 |
93 def _getDepListPath(self, path): | |
94 deps_name = "%s_%s.deps" % ( | |
95 os.path.basename(path), | |
96 hashlib.md5(path.encode('utf8')).hexdigest()) | |
97 deps_path = os.path.join(self._tmp_dir, deps_name) | |
98 return deps_path | |
99 |