annotate piecrust/processing/less.py @ 880:342e3ea24b5d

serve: Fix asset processing loop.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 15 Jun 2017 22:55:32 -0700
parents 4850f8c21b6e
children 63be34ce6e65
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 import os
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
2 import os.path
221
f82262f59600 bake: Fix processing record bugs and error logging for external processes.
Ludovic Chabant <ludovic@chabant.com>
parents: 195
diff changeset
3 import sys
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
4 import json
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
5 import hashlib
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
6 import logging
17
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
7 import platform
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8 import subprocess
221
f82262f59600 bake: Fix processing record bugs and error logging for external processes.
Ludovic Chabant <ludovic@chabant.com>
parents: 195
diff changeset
9 from piecrust.processing.base import (
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
10 SimpleFileProcessor, ExternalProcessException, FORCE_BUILD)
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
11
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
12
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
13 logger = logging.getLogger(__name__)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
14
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
15
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
16 class LessProcessor(SimpleFileProcessor):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17 PROCESSOR_NAME = 'less'
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
18
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
19 def __init__(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
20 super(LessProcessor, self).__init__({'less': 'css'})
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
21 self._conf = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
22 self._map_dir = None
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
24 def onPipelineStart(self, ctx):
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
25 self._map_dir = os.path.join(ctx.tmp_dir, 'less')
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
26 if (ctx.is_main_process and
414
c4b3a7fd2f87 bake: Make pipeline processing multi-process.
Ludovic Chabant <ludovic@chabant.com>
parents: 240
diff changeset
27 not os.path.isdir(self._map_dir)):
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
28 os.makedirs(self._map_dir)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
29
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
30 def getDependencies(self, path):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
31 map_path = self._getMapPath(path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
32 try:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
33 with open(map_path, 'r') as f:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
34 dep_map = json.load(f)
498
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
35 except OSError:
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
36 # Map file not found... rebuild.
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
37 logger.debug("No map file found for LESS file '%s' at '%s'. "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
38 "Rebuilding" % (path, map_path))
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
39 return FORCE_BUILD
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
40
498
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
41 # Check the version, since the `sources` list has changed
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
42 # meanings over time.
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
43 if dep_map.get('version') != 3:
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
44 logger.warning("Unknown LESS map version. Force rebuilding.")
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
45 return FORCE_BUILD
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
46
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
47 # Get the sources, but make all paths absolute.
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
48 sources = dep_map.get('sources')
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
49 path_dir = os.path.dirname(path)
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
50
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
51 def _makeAbs(p):
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
52 return os.path.join(path_dir, p)
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
53 deps = list(map(_makeAbs, sources))
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
54 return [map_path] + deps
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
55
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
56 def _doProcess(self, in_path, out_path):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
57 self._ensureInitialized()
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
58
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
59 map_path = self._getMapPath(in_path)
498
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
60 map_url = '/' + os.path.relpath(
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
61 map_path, self.app.root_dir).replace('\\', '/')
498
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
62
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
63 # On Windows, it looks like LESSC is confused with paths when the
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
64 # map file is not to be created in the same directory as the input
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
65 # file (it ends up writing invalid dependencies in the map file, with
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
66 # a mix of relative and absolute paths stuck together).
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
67 # So create it there and move it afterwards... :(
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
68 temp_map_path = os.path.join(
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
69 os.path.dirname(in_path),
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
70 os.path.basename(map_path))
498
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
71
240
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 221
diff changeset
72 args = [self._conf['bin'],
498
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
73 '--source-map=%s' % temp_map_path,
240
c1d4e86a3918 less: Generate a proper, available URL for the LESS CSS map file.
Ludovic Chabant <ludovic@chabant.com>
parents: 221
diff changeset
74 '--source-map-url=%s' % map_url]
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
75 args += self._conf['options']
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
76 args.append(in_path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
77 args.append(out_path)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
78 logger.debug("Processing LESS file: %s" % args)
17
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
79
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
80 # On Windows, we need to run the process in a shell environment
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
81 # otherwise it looks like `PATH` isn't taken into account.
116
1c13f3389fcb Cosmetic fix.
Ludovic Chabant <ludovic@chabant.com>
parents: 17
diff changeset
82 shell = (platform.system() == 'Windows')
17
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
83 try:
221
f82262f59600 bake: Fix processing record bugs and error logging for external processes.
Ludovic Chabant <ludovic@chabant.com>
parents: 195
diff changeset
84 proc = subprocess.Popen(
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
85 args, shell=shell,
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
86 stderr=subprocess.PIPE)
221
f82262f59600 bake: Fix processing record bugs and error logging for external processes.
Ludovic Chabant <ludovic@chabant.com>
parents: 195
diff changeset
87 stdout_data, stderr_data = proc.communicate()
17
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
88 except FileNotFoundError as ex:
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
89 logger.error("Tried running LESS processor with command: %s" %
195
b4724e577a8c cosmetic: Fix some PEP8 issues.
Ludovic Chabant <ludovic@chabant.com>
parents: 119
diff changeset
90 args)
17
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
91 raise Exception("Error running LESS processor. "
de6a296744f7 The LESS compiler must be launched in a shell on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 7
diff changeset
92 "Did you install it?") from ex
221
f82262f59600 bake: Fix processing record bugs and error logging for external processes.
Ludovic Chabant <ludovic@chabant.com>
parents: 195
diff changeset
93 if proc.returncode != 0:
f82262f59600 bake: Fix processing record bugs and error logging for external processes.
Ludovic Chabant <ludovic@chabant.com>
parents: 195
diff changeset
94 raise ExternalProcessException(
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
95 stderr_data.decode(sys.stderr.encoding))
221
f82262f59600 bake: Fix processing record bugs and error logging for external processes.
Ludovic Chabant <ludovic@chabant.com>
parents: 195
diff changeset
96
498
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
97 logger.debug("Moving map file: %s -> %s" % (temp_map_path, map_path))
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
98 if os.path.exists(map_path):
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
99 os.remove(map_path)
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
100 os.rename(temp_map_path, map_path)
35d4c172e5a6 less: Fix issues with the map file on Windows.
Ludovic Chabant <ludovic@chabant.com>
parents: 414
diff changeset
101
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
102 return True
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
103
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
104 def _ensureInitialized(self):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
105 if self._conf is not None:
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
106 return
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
107
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
108 self._conf = self.app.config.get('less') or {}
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
109 self._conf.setdefault('bin', 'lessc')
195
b4724e577a8c cosmetic: Fix some PEP8 issues.
Ludovic Chabant <ludovic@chabant.com>
parents: 119
diff changeset
110 self._conf.setdefault('options', ['--compress'])
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
111 if not isinstance(self._conf['options'], list):
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
112 raise Exception("The `less/options` configuration setting "
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
113 "must be an array of arguments.")
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
114
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
115 def _getMapPath(self, path):
119
0811f92cbdc7 Slightly more robust dependency handling for the LESS processor.
Ludovic Chabant <ludovic@chabant.com>
parents: 116
diff changeset
116 map_name = "%s_%s.map" % (
852
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
117 os.path.basename(path),
4850f8c21b6e core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents: 498
diff changeset
118 hashlib.md5(path.encode('utf8')).hexdigest())
3
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
119 map_path = os.path.join(self._map_dir, map_name)
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
120 return map_path
f485ba500df3 Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
121