From 4ae07612058035459e0960f93aac33b6fdbf16ac Mon Sep 17 00:00:00 2001 From: Evan Demaris Date: Tue, 22 Nov 2016 13:54:21 -0800 Subject: [PATCH 1/2] Fix closure compiler & closure templates fix #160 A pull request to fix was submitted, but the code broke when the compiler version updated last month. This should fix it and prevent it from breaking again (at least in the near future). --- bin/lime.py | 201 +++++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 98 deletions(-) diff --git a/bin/lime.py b/bin/lime.py index 780191f4..ebb69c43 100755 --- a/bin/lime.py +++ b/bin/lime.py @@ -34,7 +34,7 @@ box2d_dir = os.path.join(basedir,'box2d') extdir = join(basedir,'bin/external') -compiler_path = os.path.join(extdir,'compiler-20130411.jar') +compiler_path = os.path.join(extdir,'compiler.jar') soy_path = os.path.join(extdir,'SoyToJsSrcCompiler.jar') projects_path = join(basedir,'bin/projects') @@ -49,14 +49,14 @@ def removeDupes(seq): for e in seq: keys[e.rstrip()] = 1 return keys.keys() - + def makeProjectPaths(add): lines = open(projects_path,'r').readlines() if len(add): lines.append(add) newlines = filter(lambda x: exists(join(basedir,x.rstrip())) and len(x.rstrip()),lines) newlines = removeDupes(newlines) - + f = open(projects_path,'w') f.write('\n'.join(newlines)) f.close() @@ -64,74 +64,79 @@ def makeProjectPaths(add): def rephook(a,b,c): sys.stdout.write("\r%2d%%" % ((100*a*b)/c) ) sys.stdout.flush() - + def escapeSpace(s): return s.replace(" ","\\ ") - + def quoteSpace(s): return s.replace(" ","' '") def checkDependencies(): - + #Check git retcode = subprocess.Popen(subprocess.list2cmdline(["git","--version"]), stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True).wait() if retcode!=0: logging.error('Lime requires git. Get it from http://git-scm.com/download') - sys.exit(1) - - + sys.exit(1) + + #Closure Library if not (os.path.exists(closure_dir) and os.path.exists(closure_deps_file)): print ('Closure Library not found. Downloading to %s' % closure_dir) print ('Please wait...') - + retcode = subprocess.Popen(subprocess.list2cmdline(["git","clone","https://github.com/google/closure-library.git",closure_dir]),shell=True).wait() - + if(retcode!=0): print ('Failed to clone Closure Library via Git. Discontinuing.') sys.exit(1) - + retcode = subprocess.Popen(subprocess.list2cmdline(["git","checkout","161037749f1efee3142630bba5092709cb09f796"]),shell=True,cwd=closure_dir).wait() - + if(retcode!=0): print ('Failed to clone Closure Library via Git. Discontinuing.') sys.exit(1) - - + + #Box2D if not os.path.exists(box2d_dir): print ('Box2DJS not found. Downloading to %s' % box2d_dir) print ('Please wait...') - + retcode = subprocess.Popen(subprocess.list2cmdline(["git","clone","https://github.com/thinkpixellab/pl.git",box2d_dir]),shell=True).wait() - + if(retcode!=0): logging.error('Error while downloading Box2D. Discontinuing.') sys.exit(1) - + #External tools dir if not os.path.exists(extdir): os.mkdir(extdir) - + #Closure compiler if not os.path.exists(compiler_path): zip_path = os.path.join(extdir,'compiler.zip') print ('Downloading Closure Compiler: ') - urlretrieve("http://closure-compiler.googlecode.com/files/compiler-20130411.zip",zip_path,rephook) + urlretrieve("http://dl.google.com/closure-compiler/compiler-latest.zip",zip_path,rephook) print ('\nUnzipping...') zippedFile = zipfile.ZipFile(zip_path) - zippedFile.extract('compiler.jar',extdir) + jarName = '' + for name in zippedFile.namelist(): + if re.match(r'closure-compiler-.*\.jar', info): + jarName = info + print(jarName) + zippedFile.extract(jarName, extdir) zippedFile.close() print ('Cleanup') os.unlink(zip_path) - os.rename(os.path.join(extdir,'compiler.jar'), compiler_path) - - + os.rename(os.path.join(extdir,jarName), compiler_path) + + #Closure Templates if not os.path.exists(soy_path): zip_path = os.path.join(extdir,'soy.zip') print ('Downloading Closure Templates(Soy):') - urlretrieve("http://closure-templates.googlecode.com/files/closure-templates-for-javascript-latest.zip", + urlretrieve("https://dl.google.com/closure-templates/closure-templates-for-javascript-latest.zip", zip_path,rephook) print ('\nUnzipping...') zippedFile = zipfile.ZipFile(zip_path) @@ -139,50 +144,50 @@ def checkDependencies(): zippedFile.close() print ('Cleanup') os.unlink(zip_path) - + if not os.path.exists(projects_path): open(projects_path,'w').close() - + makeProjectPaths('') - - - + + + def update(): - + reldir = os.path.relpath(curdir,basedir) if reldir!='.': makeProjectPaths(reldir) - + print ('Updating Closure deps file') - + paths = open(projects_path,'r').readlines() paths.append('lime\n') paths.append('box2d/src\n') - + opt = ' '.join(map(lambda x: '--root_with_prefix="'+quoteSpace(os.path.join(basedir,x.rstrip()))+'/ ../../../'+x.rstrip()+'/"',paths)) call = 'python ' + escapeSpace(os.path.join(closure_dir,'closure/bin/build/depswriter.py'))+' --root_with_prefix="'+\ quoteSpace(closure_dir)+'/ ../../" '+opt+' --output_file="'+closure_deps_file+'"' - + print (call) - + subprocess.call(call,shell=True) - + def create(name): - + path = os.path.join(basedir,name) - + if exists(path): logging.error('Directory already exists: %s',path) - sys.exit(1) - + sys.exit(1) + name = os.path.basename(path) - + proj = os.path.relpath(path,basedir) - + shutil.copytree(os.path.join(basedir,'lime/templates/default'),path) - + for root, dirs, files in os.walk(path): for fname in files: newname = fname.replace('__name__',name) @@ -191,43 +196,43 @@ def create(name): for line in fileinput.FileInput(os.path.join(root,newname),inplace=1): line = line.replace('{name}',name) print(line.rstrip()) - + print ('Created %s' % path) - - + + if proj!='.': makeProjectPaths(os.path.relpath(path,basedir)) - + update() def makeSoyJSFile(path,stringbuilder): if path[-4:]=='.soy': call = "java -jar "+soy_path+" --cssHandlingScheme goog --shouldProvideRequireSoyNamespaces --outputPathFormat "+path+".js " - + if not stringbuilder: call+= "--codeStyle concat " - + call += path; - + print (call) subprocess.call(call,shell=True) - + def genSoy(path): - + if not os.path.exists(path): logging.error('No such directory %s',path) exit(1) - + if os.path.isfile(path): - + mtype = mimetypes.guess_type(path)[0] fname = split(path)[1] - + if path[-4:]=='.soy': makeSoyJSFile(path,True) - + elif path[-5:]=='.json': infile= open(path,'r') outfile = open(path+'.js','w') @@ -246,7 +251,7 @@ def genSoy(path): infile.close() outfile.close() makeSoyJSFile(path+'.soy',False) - + else : outfile = open(path+'.soy','w') outfile.write('{namespace lime.ASSETS.'+fname+'}\n\n/**\n * Generated with "bin/lime.py gensoy filepath"\n */\n{template .data}\n') @@ -259,54 +264,54 @@ def genSoy(path): outfile.write('\n{/template}\n') outfile.close() makeSoyJSFile(path+'.soy',False) - - else: + + else: for root,dirs,files in os.walk(path): for fname in files: if fname[-4:]=='.soy': soypath = os.path.join(root,fname) makeSoyJSFile(soypath,False) - + update() - + def build(name,options): - + dir_list = open(projects_path,'r').readlines() dir_list.append('lime') dir_list.append('box2d/src') dir_list.append('closure') - + #dir_list = filter(lambda x: os.path.isdir(os.path.join(basedir,x)) and ['.git','bin','docs'].count(x)==0 ,os.listdir(basedir)) opt = ' '.join(map(lambda x: '--root="'+os.path.join(basedir,x.rstrip())+'/"',dir_list)) - + call = 'python ' + escapeSpace(os.path.join(closure_dir,'closure/bin/build/closurebuilder.py'))+' '+opt+' --namespace="'+name+'" '+\ '-o compiled -c '+compiler_path; - - + + if options.advanced: call+=" -f --compilation_level=ADVANCED_OPTIMIZATIONS" - + if options.debug: call+=" -f --debug -f --formatting=PRETTY_PRINT" - + if options.externs_file: for i, opt in enumerate(options.externs_file): call+=" -f --externs="+opt outname = options.output if options.output[-3:] != '.js': - outname += '.js' - + outname += '.js' + if options.map_file: call+=" -f --formatting=PRETTY_PRINT -f --source_map_format=V3 -f --create_source_map="+outname+'.map' else: call+=" -f --define='goog.DEBUG=false'" - + if options.use_strict: call+=" -f --language_in=ECMASCRIPT5_STRICT" - + if options.define: for i, opt in enumerate(options.define): call+=" -f --define='"+opt+"'" @@ -323,7 +328,7 @@ def build(name,options): # handle error later errhandle = 1 pass - + if options.map_file: map_filename = outname+'.map' map_file = open(map_filename, 'r+') @@ -335,21 +340,21 @@ def build(name,options): map_file = open(map_filename, 'w') json.dump(data, map_file) map_file.close() - + # add path to map file out_file = open(outname, 'a') out_file.write('\n//@ sourceMappingURL=' + os.path.relpath(map_filename, os.path.dirname(outname))) out_file.close() - + if options.output and options.preload: name = os.path.basename(outname)[:-3] target = os.path.dirname(outname) source = os.path.join(basedir,'lime/templates/preloader') for root, dirs, files in os.walk(source): - + for fname in files: - from_ = join(root, fname) + from_ = join(root, fname) to_ = from_.replace(source, target, 1) to_directory = split(to_)[0] to_ = to_.replace('__name__',name) @@ -357,38 +362,38 @@ def build(name,options): os.makedirs(to_directory) if not exists(to_): copyfile(from_, to_) - + for root, dirs, files in os.walk(target): - for fname in files: + for fname in files: if exists(os.path.join(target,fname)): for line in fileinput.FileInput(os.path.join(target,fname),inplace=1): line = line.replace('{name}',name) line = line.replace('{callback}',options.preload) - + if fname == name+'.manifest': line = re.sub(r'# Updated on:.*','# Updated on: '+datetime.now().strftime("%Y-%m-%d %H:%M:%S"),line) print(line.rstrip()) - + if errhandle == 1: exit(1) def main(): """The entrypoint for this script.""" - + usage = """usage: %prog [command] [options] Commands: init Check lime dependecies and setup if needed - update Update Closure dependency file. Need to run every time you + update Update Closure dependency file. Need to run every time you change goog.provide() or goog.require() create [path/name] Setup new project [name] gensoy [path] Convert all *.soy files under path to *.soy.js files build [name] Compile project to single Javascript file""" parser = optparse.OptionParser(usage) - + parser.add_option("-a", "--advanced", dest="advanced", action="store_true", help="Build uses ADVANCED_OPTIMIZATIONS mode (encouraged)") - + parser.add_option("-g", "--debug", dest="debug", action="store_true", help="Closure Compiler: longer names for symbols for debugging of the advanced optimizations.") @@ -397,40 +402,40 @@ def main(): parser.add_option("-o", "--output", dest="output", action="store", type="string", help="Output file for build result") - + parser.add_option("-m", "--map", dest="map_file", action="store_true", help="Build result sourcemap for debugging. Also turns on pretty print.") parser.add_option("-s", "--use-strict", dest="use_strict", action="store_true", help="Use EcmaScript5 strict mode.") - + parser.add_option("-p", "--preload", dest="preload", action="store", type="string", help="Generate preloader code with given callback as start point.") - + parser.add_option("-d", "--define", dest="define", action="append", help="Define custom variable accessible before build.") - + (options, args) = parser.parse_args() if not (len(args) == 2 or (len(args)==1 and ['init','update'].count(args[0])==1 )) : parser.error('incorrect number of arguments') - + checkDependencies() - + if args[0]=='init' or args[0]=='update': update() - + elif args[0]=='create': create(args[1]) - + elif args[0]=='gensoy': genSoy(args[1]) - + elif args[0]=='build': - build(args[1],options) - + build(args[1],options) + else: logging.error('No such command: %s',args[0]) exit(1) - + if __name__ == '__main__': main() From f66730154cbced6992e066977dd3c8d34a2e06d6 Mon Sep 17 00:00:00 2001 From: Evan Demaris Date: Wed, 23 Nov 2016 09:19:15 -0800 Subject: [PATCH 2/2] Typo fix iterator variable `info` was renamed to `name`. --- bin/lime.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/lime.py b/bin/lime.py index ebb69c43..01a2f804 100755 --- a/bin/lime.py +++ b/bin/lime.py @@ -122,8 +122,8 @@ def checkDependencies(): zippedFile = zipfile.ZipFile(zip_path) jarName = '' for name in zippedFile.namelist(): - if re.match(r'closure-compiler-.*\.jar', info): - jarName = info + if re.match(r'closure-compiler-.*\.jar', name): + jarName = name print(jarName) zippedFile.extract(jarName, extdir) zippedFile.close()