diff --git a/bin/lime.py b/bin/lime.py index 780191f4..01a2f804 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', name): + jarName = name + 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()