Only recompile coffescript if the source has actually changed since the last time it was compiled, rather than relying on mtimes.

This commit is contained in:
Kovid Goyal 2014-02-12 12:08:29 +05:30
parent 0cd112e360
commit b821dbd9b8
2 changed files with 16 additions and 12 deletions

Binary file not shown.

View File

@ -6,8 +6,9 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os, cPickle, re, shutil, marshal, zipfile, glob, time, subprocess, sys import os, cPickle, re, shutil, marshal, zipfile, glob, time, subprocess, sys, hashlib, json
from zlib import compress from zlib import compress
from itertools import chain
from setup import Command, basenames, __appname__ from setup import Command, basenames, __appname__
@ -62,18 +63,20 @@ class Coffee(Command): # {{{
'*.coffee')): '*.coffee')):
bn = os.path.basename(f).rpartition('.')[0] bn = os.path.basename(f).rpartition('.')[0]
arcname = src.replace('/', '.') + '.' + bn + '.js' arcname = src.replace('/', '.') + '.' + bn + '.js'
src_files[arcname] = (f, os.stat(f).st_mtime) with open(f, 'rb') as fs:
src_files[arcname] = (f, hashlib.sha1(fs.read()).hexdigest())
existing = {} existing = {}
dest = self.j(self.RESOURCES, 'compiled_coffeescript.zip') dest = self.j(self.RESOURCES, 'compiled_coffeescript.zip')
if os.path.exists(dest): if os.path.exists(dest):
with zipfile.ZipFile(dest, 'r') as zf: with zipfile.ZipFile(dest, 'r') as zf:
existing_hashes = {}
raw = zf.comment
if raw:
existing_hashes = json.loads(raw)
for info in zf.infolist(): for info in zf.infolist():
mtime = time.mktime(info.date_time + (0, 0, -1)) if info.filename in existing_hashes and src_files.get(info.filename, (None, None))[1] == existing_hashes[info.filename]:
arcname = info.filename existing[info.filename] = (zf.read(info), info, existing_hashes[info.filename])
if (arcname in src_files and src_files[arcname][1] <
mtime):
existing[arcname] = (zf.read(info), info)
todo = set(src_files) - set(existing) todo = set(src_files) - set(existing)
updated = {} updated = {}
@ -81,7 +84,7 @@ class Coffee(Command): # {{{
name = arcname.rpartition('.')[0] name = arcname.rpartition('.')[0]
print ('\t%sCompiling %s'%(time.strftime('[%H:%M:%S] ') if print ('\t%sCompiling %s'%(time.strftime('[%H:%M:%S] ') if
timestamp else '', name)) timestamp else '', name))
src = src_files[arcname][0] src, sig = src_files[arcname]
try: try:
js = subprocess.check_output(self.compiler + js = subprocess.check_output(self.compiler +
[src]).decode('utf-8') [src]).decode('utf-8')
@ -100,13 +103,14 @@ class Coffee(Command): # {{{
zi = zipfile.ZipInfo() zi = zipfile.ZipInfo()
zi.filename = arcname zi.filename = arcname
zi.date_time = time.localtime()[:6] zi.date_time = time.localtime()[:6]
updated[arcname] = (js.encode('utf-8'), zi) updated[arcname] = (js.encode('utf-8'), zi, sig)
if updated: if updated:
hashes = {}
with zipfile.ZipFile(dest, 'w', zipfile.ZIP_STORED) as zf: with zipfile.ZipFile(dest, 'w', zipfile.ZIP_STORED) as zf:
for raw, zi in updated.itervalues(): for raw, zi, sig in sorted(chain(updated.itervalues(), existing.itervalues()), key=lambda x: x[1].filename):
zf.writestr(zi, raw)
for raw, zi in existing.itervalues():
zf.writestr(zi, raw) zf.writestr(zi, raw)
hashes[zi.filename] = sig
zf.comment = json.dumps(hashes)
def clean(self): def clean(self):
x = self.j(self.RESOURCES, 'compiled_coffeescript.zip') x = self.j(self.RESOURCES, 'compiled_coffeescript.zip')