2011-04-19 00:27:33 +00:00
|
|
|
#/usr/bin/env python
|
|
|
|
|
|
|
|
from optparse import OptionParser
|
|
|
|
import httplib, urllib
|
|
|
|
import os, fnmatch, shutil, re
|
2011-04-19 01:35:05 +00:00
|
|
|
from collections import OrderedDict
|
2011-04-19 00:27:33 +00:00
|
|
|
|
|
|
|
usage = """usage: %prog [options] command
|
|
|
|
|
|
|
|
Commands:
|
|
|
|
build build the script
|
|
|
|
debug print the header to include js files
|
|
|
|
clean remove any built files
|
|
|
|
"""
|
|
|
|
parser = OptionParser(usage=usage)
|
2011-04-19 00:44:29 +00:00
|
|
|
parser.add_option('-l', '--level', dest='level', default='SIMPLE_OPTIMIZATIONS',
|
2011-04-19 00:27:33 +00:00
|
|
|
help='Closure compilation level [WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS, \
|
|
|
|
ADVANCED_OPTIMIZATIONS]')
|
|
|
|
|
2011-04-19 01:50:56 +00:00
|
|
|
UTILS = os.path.dirname(os.path.relpath(__file__))
|
|
|
|
PREFIX = os.path.join(UTILS,'..')
|
|
|
|
SRC_ROOT= os.path.join(PREFIX,'src')
|
|
|
|
BUILD_ROOT = os.path.join(PREFIX,'build')
|
|
|
|
INDEX = os.path.join(PREFIX,'index.html')
|
2011-04-19 00:27:33 +00:00
|
|
|
BUILD_NAME = 'DAT.GUI'
|
2011-04-19 01:35:05 +00:00
|
|
|
ALL_JS = ['DAT.GUI.js','DAT.GUI']
|
2011-04-19 00:27:33 +00:00
|
|
|
|
|
|
|
def flatten(l, ltypes=(list, tuple)):
|
|
|
|
ltype = type(l)
|
|
|
|
l = list(l)
|
|
|
|
i = 0
|
|
|
|
while i < len(l):
|
|
|
|
while isinstance(l[i], ltypes):
|
|
|
|
if not l[i]:
|
|
|
|
l.pop(i)
|
|
|
|
i -= 1
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
l[i:i + 1] = l[i]
|
|
|
|
i += 1
|
|
|
|
return ltype(l)
|
|
|
|
|
|
|
|
def expand(path, globby):
|
|
|
|
matches = []
|
|
|
|
path = path.split('.')
|
|
|
|
path.insert(0,SRC_ROOT)
|
2011-04-19 01:35:05 +00:00
|
|
|
filename = "%s.%s"%(path[-2],path[-1])
|
|
|
|
if fnmatch.fnmatch(filename, globby):
|
|
|
|
path[-1] = filename
|
2011-04-19 00:27:33 +00:00
|
|
|
path = os.path.join(*path)
|
2011-04-19 01:35:05 +00:00
|
|
|
if os.path.isdir(path):
|
|
|
|
for root, dirnames, filenames in os.walk(path):
|
|
|
|
for filename in fnmatch.filter(filenames, globby):
|
|
|
|
matches.append(os.path.join(root, filename))
|
|
|
|
else:
|
|
|
|
matches.append(path)
|
2011-04-19 00:27:33 +00:00
|
|
|
return matches
|
|
|
|
|
2011-04-19 01:35:05 +00:00
|
|
|
def unique(seq, idfun=None):
|
|
|
|
"""Ordered uniquify function
|
|
|
|
if in 2.7 use:
|
|
|
|
OrderedDict.fromkeys(seq).keys()
|
|
|
|
"""
|
|
|
|
if idfun is None:
|
|
|
|
def idfun(x): return x
|
|
|
|
seen = {}
|
|
|
|
result = []
|
|
|
|
for item in seq:
|
|
|
|
marker = idfun(item)
|
|
|
|
if marker in seen: continue
|
|
|
|
seen[marker] = 1
|
|
|
|
result.append(item)
|
|
|
|
return result
|
|
|
|
|
2011-04-19 00:27:33 +00:00
|
|
|
def source_list(src, globby='*.js'):
|
|
|
|
def expander(f):
|
|
|
|
return expand(f,globby)
|
2011-04-19 01:35:05 +00:00
|
|
|
return unique(flatten(map(expander, src)))
|
2011-04-19 00:27:33 +00:00
|
|
|
|
|
|
|
def compile(code):
|
|
|
|
params = urllib.urlencode([
|
|
|
|
('js_code', code),
|
|
|
|
('compilation_level', options.level),
|
|
|
|
('output_format', 'text'),
|
|
|
|
('output_info', 'compiled_code'),
|
|
|
|
])
|
|
|
|
headers = { 'Content-type': 'application/x-www-form-urlencoded' }
|
|
|
|
conn = httplib.HTTPConnection('closure-compiler.appspot.com')
|
|
|
|
conn.request('POST', '/compile', params, headers)
|
|
|
|
response = conn.getresponse()
|
|
|
|
data = response.read()
|
|
|
|
conn.close()
|
|
|
|
return data
|
|
|
|
|
|
|
|
def bytes_to_kb(b,digits=1):
|
|
|
|
return round(0.0078125 * b, digits)
|
|
|
|
|
|
|
|
def clean():
|
|
|
|
if os.path.exists(BUILD_ROOT):
|
|
|
|
shutil.rmtree(BUILD_ROOT)
|
|
|
|
print('DONE. Removed %s'%(BUILD_ROOT,))
|
|
|
|
else:
|
|
|
|
print('DONE. Nothing to clean')
|
|
|
|
|
2011-04-19 01:35:05 +00:00
|
|
|
def build(jssrc, csssrc=list([''])):
|
2011-04-19 00:27:33 +00:00
|
|
|
if not os.path.exists(BUILD_ROOT):
|
|
|
|
os.makedirs(BUILD_ROOT)
|
|
|
|
|
2011-04-19 01:35:05 +00:00
|
|
|
if csssrc:
|
|
|
|
cssfiles = source_list(csssrc, '*.css')
|
|
|
|
css = '\n'.join([open(f).read() for f in cssfiles])
|
|
|
|
css = re.sub(r'[ \t\n\r]+',' ',css)
|
2011-04-19 00:27:33 +00:00
|
|
|
|
2011-04-19 01:35:05 +00:00
|
|
|
jsfiles = source_list(jssrc, '*.js')
|
|
|
|
print(jsfiles)
|
2011-04-19 00:27:33 +00:00
|
|
|
code = '\n'.join([open(f).read() for f in jsfiles])
|
2011-04-19 01:35:05 +00:00
|
|
|
if csssrc:
|
|
|
|
code += """DAT.GUI.inlineCSS = '%s';\n"""%(css,)
|
2011-04-19 00:27:33 +00:00
|
|
|
|
|
|
|
outpath = os.path.join(BUILD_ROOT, BUILD_NAME+'.js')
|
|
|
|
with open(outpath,'w') as f:
|
|
|
|
f.write(code)
|
|
|
|
|
|
|
|
compiled = compile(code)
|
|
|
|
outpath = os.path.join(BUILD_ROOT, BUILD_NAME+'.min.js')
|
|
|
|
with open(outpath,'w') as f:
|
|
|
|
f.write(compiled)
|
|
|
|
|
|
|
|
size = bytes_to_kb(os.path.getsize(outpath))
|
|
|
|
with open(INDEX,'r') as f:
|
|
|
|
index = f.read()
|
|
|
|
with open(INDEX,'w') as f:
|
|
|
|
index = re.sub(r'\[[0-9.]+kb\]','[%skb]'%(size,),index)
|
|
|
|
f.write(index)
|
|
|
|
|
|
|
|
print('DONE. Built files in %s.'%(BUILD_ROOT,))
|
|
|
|
|
2011-04-19 01:50:56 +00:00
|
|
|
def debug(jssrc, csssrc=list([''])):
|
|
|
|
head = ""
|
|
|
|
files = source_list(csssrc, '*.css')
|
|
|
|
for f in files:
|
|
|
|
f = f.replace(PREFIX+'/','')
|
|
|
|
head += '<link href="%s" media="screen" rel="stylesheet" type="text/css"/>\n'%(f,)
|
|
|
|
files = source_list(jssrc, '*.js')
|
2011-04-19 00:27:33 +00:00
|
|
|
for f in files:
|
2011-04-19 01:50:56 +00:00
|
|
|
f = f.replace(PREFIX+'/','')
|
|
|
|
head += '<script type="text/javascript" src="%s"></script>\n'%(f,)
|
|
|
|
print(head)
|
2011-04-19 00:27:33 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
global options
|
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
if len(args) != 1:
|
|
|
|
print(parser.usage)
|
|
|
|
exit(0)
|
|
|
|
command = args[0]
|
|
|
|
if command == 'build':
|
2011-04-19 01:35:05 +00:00
|
|
|
build(ALL_JS)
|
2011-04-19 00:27:33 +00:00
|
|
|
elif command == 'clean':
|
|
|
|
clean()
|
|
|
|
elif command == 'debug':
|
2011-04-19 01:50:56 +00:00
|
|
|
debug(ALL_JS)
|
2011-04-19 00:27:33 +00:00
|
|
|
|
|
|
|
|