43 # usually defaults to e.g. /usr/share/pyjamas |
44 # usually defaults to e.g. /usr/share/pyjamas |
44 _data_dir = os.path.join(pyjs.prefix, "share/pyjamas") |
45 _data_dir = os.path.join(pyjs.prefix, "share/pyjamas") |
45 |
46 |
46 |
47 |
47 # .cache.html files produces look like this |
48 # .cache.html files produces look like this |
48 CACHE_HTML_PAT=re.compile('^[a-z]*.[0-9a-f]{32}\.cache\.html$') |
49 CACHE_HTML_PAT = re.compile('^[a-z]*.[0-9a-f]{32}\.cache\.html$') |
49 |
50 |
50 # ok these are the three "default" library directories, containing |
51 # ok these are the three "default" library directories, containing |
51 # the builtins (str, List, Dict, ord, round, len, range etc.) |
52 # the builtins (str, List, Dict, ord, round, len, range etc.) |
52 # the main pyjamas libraries (pyjamas.ui, pyjamas.Window etc.) |
53 # the main pyjamas libraries (pyjamas.ui, pyjamas.Window etc.) |
53 # and the contributed addons |
54 # and the contributed addons |
134 <script language="javascript" src="pygwt.js"></script> |
137 <script language="javascript" src="pygwt.js"></script> |
135 </body> |
138 </body> |
136 </html> |
139 </html> |
137 """ |
140 """ |
138 |
141 |
139 filename = os.path.split ( source_file )[1] |
142 filename = os.path.split(source_file)[1] |
140 mod_name = os.path.splitext ( filename )[0] |
143 mod_name = os.path.splitext(filename)[0] |
141 file_name = os.path.join ( dest_path, mod_name + '.html' ) |
144 file_name = os.path.join(dest_path, mod_name + '.html') |
142 |
145 |
143 # if html file in output directory exists, leave it alone. |
146 # if html file in output directory exists, leave it alone. |
144 if os.path.exists ( file_name ): |
147 if os.path.exists(file_name): |
145 return 0 |
148 return 0 |
146 |
149 |
147 if os.path.exists ( |
150 if os.path.exists(os.path.join(dest_path, mod_name + '.css')): |
148 os.path.join ( dest_path, mod_name + '.css' ) ) : |
|
149 css = "<link rel='stylesheet' href='" + mod_name + ".css'>" |
151 css = "<link rel='stylesheet' href='" + mod_name + ".css'>" |
150 elif os.path.exists ( |
152 elif os.path.exists(os.path.join(dest_path, 'pyjamas_default.css')): |
151 os.path.join ( dest_path, 'pyjamas_default.css' ) ) : |
|
152 css = "<link rel='stylesheet' href='pyjamas_default.css'>" |
153 css = "<link rel='stylesheet' href='pyjamas_default.css'>" |
153 |
154 |
154 else: |
155 else: |
155 css = '' |
156 css = '' |
156 |
157 |
157 title = 'PyJamas Auto-Generated HTML file ' + mod_name |
158 title = 'PyJamas Auto-Generated HTML file ' + mod_name |
158 |
159 |
159 base_html = base_html % {'modulename': mod_name, 'title': title, 'css': css} |
160 base_html = base_html % {'modulename': mod_name, 'title': title, 'css': css} |
160 |
161 |
161 fh = open (file_name, 'w') |
162 fh = open(file_name, 'w') |
162 fh.write (base_html) |
163 fh.write(base_html) |
163 fh.close () |
164 fh.close() |
164 |
165 |
165 return 1 |
166 return 1 |
166 |
167 |
167 |
168 |
168 def build(app_name, output, js_includes=(), debug=False, dynamic=0, |
169 def build(app_name, output, js_includes=(), debug=False, dynamic=0, |
185 print "Creating output directory" |
186 print "Creating output directory" |
186 os.mkdir(output) |
187 os.mkdir(output) |
187 except StandardError, e: |
188 except StandardError, e: |
188 print >>sys.stderr, "Exception creating output directory %s: %s" % (output, e) |
189 print >>sys.stderr, "Exception creating output directory %s: %s" % (output, e) |
189 |
190 |
190 ## public dir |
191 # public dir |
191 for p in pyjs.path: |
192 for p in pyjs.path: |
192 pub_dir = join(p, 'public') |
193 pub_dir = join(p, 'public') |
193 if isdir(pub_dir): |
194 if isdir(pub_dir): |
194 print "Copying: public directory of library %r" % p |
195 print "Copying: public directory of library %r" % p |
195 copytree_exists(pub_dir, output) |
196 copytree_exists(pub_dir, output) |
196 |
197 |
197 ## AppName.html - can be in current or public directory |
198 # AppName.html - can be in current or public directory |
198 html_input_filename = app_name + ".html" |
199 html_input_filename = app_name + ".html" |
199 html_output_filename = join(output, basename(html_input_filename)) |
200 html_output_filename = join(output, basename(html_input_filename)) |
200 if os.path.isfile(html_input_filename): |
201 if os.path.isfile(html_input_filename): |
201 if not os.path.isfile(html_output_filename) or \ |
202 if not os.path.isfile(html_output_filename) or \ |
202 os.path.getmtime(html_input_filename) > \ |
203 os.path.getmtime(html_input_filename) > \ |
203 os.path.getmtime(html_output_filename): |
204 os.path.getmtime(html_output_filename): |
204 try: |
205 try: |
205 shutil.copy(html_input_filename, html_output_filename) |
206 shutil.copy(html_input_filename, html_output_filename) |
206 except: |
207 except Exception: |
207 print >>sys.stderr, "Warning: Missing module HTML file %s" % html_input_filename |
208 print >>sys.stderr, "Warning: Missing module HTML file %s" % html_input_filename |
208 |
209 |
209 print "Copying: %(html_input_filename)s" % locals() |
210 print "Copying: %(html_input_filename)s" % locals() |
210 |
211 |
211 if check_html_file(html_input_filename, output): |
212 if check_html_file(html_input_filename, output): |
212 print >>sys.stderr, "Warning: Module HTML file %s has been auto-generated" % html_input_filename |
213 print >>sys.stderr, "Warning: Module HTML file %s has been auto-generated" % html_input_filename |
213 |
214 |
214 ## pygwt.js |
215 # pygwt.js |
215 |
216 |
216 print "Copying: pygwt.js" |
217 print "Copying: pygwt.js" |
217 |
218 |
218 pygwt_js_template = read_boilerplate(data_dir, "pygwt.js") |
219 pygwt_js_template = read_boilerplate(data_dir, "pygwt.js") |
219 pygwt_js_output = open(join(output, "pygwt.js"), "w") |
220 pygwt_js_output = open(join(output, "pygwt.js"), "w") |
220 |
221 |
221 print >>pygwt_js_output, pygwt_js_template |
222 print >>pygwt_js_output, pygwt_js_template |
222 |
223 |
223 pygwt_js_output.close() |
224 pygwt_js_output.close() |
224 |
225 |
225 ## Images |
226 # Images |
226 |
227 |
227 print "Copying: Images and History" |
228 print "Copying: Images and History" |
228 copy_boilerplate(data_dir, "corner_dialog_topleft_black.png", output) |
229 copy_boilerplate(data_dir, "corner_dialog_topleft_black.png", output) |
229 copy_boilerplate(data_dir, "corner_dialog_topright_black.png", output) |
230 copy_boilerplate(data_dir, "corner_dialog_topright_black.png", output) |
230 copy_boilerplate(data_dir, "corner_dialog_bottomright_black.png", output) |
231 copy_boilerplate(data_dir, "corner_dialog_bottomright_black.png", output) |
238 copy_boilerplate(data_dir, "tree_closed.gif", output) |
239 copy_boilerplate(data_dir, "tree_closed.gif", output) |
239 copy_boilerplate(data_dir, "tree_open.gif", output) |
240 copy_boilerplate(data_dir, "tree_open.gif", output) |
240 copy_boilerplate(data_dir, "tree_white.gif", output) |
241 copy_boilerplate(data_dir, "tree_white.gif", output) |
241 copy_boilerplate(data_dir, "history.html", output) |
242 copy_boilerplate(data_dir, "history.html", output) |
242 |
243 |
243 |
244 # all.cache.html |
244 ## all.cache.html |
|
245 app_files = generateAppFiles(data_dir, js_includes, app_name, debug, |
245 app_files = generateAppFiles(data_dir, js_includes, app_name, debug, |
246 output, dynamic, cache_buster, optimize) |
246 output, dynamic, cache_buster, optimize) |
247 |
247 |
248 ## AppName.nocache.html |
248 # AppName.nocache.html |
249 |
249 |
250 print "Creating: %(app_name)s.nocache.html" % locals() |
250 print "Creating: %(app_name)s.nocache.html" % locals() |
251 |
251 |
252 home_nocache_html_template = read_boilerplate(data_dir, "home.nocache.html") |
252 home_nocache_html_template = read_boilerplate(data_dir, "home.nocache.html") |
253 home_nocache_html_output = open(join(output, app_name + ".nocache.html"), |
253 home_nocache_html_output = open(join(output, app_name + ".nocache.html"), |
322 |
322 |
323 parser.setPlatform(platform) |
323 parser.setPlatform(platform) |
324 app_translator = pyjs.AppTranslator( |
324 app_translator = pyjs.AppTranslator( |
325 parser=parser, dynamic=dynamic, optimize=optimize) |
325 parser=parser, dynamic=dynamic, optimize=optimize) |
326 early_app_libs[platform], appcode = \ |
326 early_app_libs[platform], appcode = \ |
327 app_translator.translate(None, is_app=False, |
327 app_translator.translate(None, is_app=False, |
328 debug=debug, |
328 debug=debug, |
329 library_modules=['dynamicajax.js', |
329 library_modules=['dynamicajax.js', |
330 '_pyjs.js', 'sys', |
330 '_pyjs.js', 'sys', |
331 'pyjslib']) |
331 'pyjslib']) |
332 pover[platform].update(app_translator.overrides.items()) |
332 pover[platform].update(app_translator.overrides.items()) |
333 for mname, name in app_translator.overrides.items(): |
333 for mname, name in app_translator.overrides.items(): |
334 pd = overrides.setdefault(mname, {}) |
334 pd = overrides.setdefault(mname, {}) |
335 pd[platform] = name |
335 pd[platform] = name |
336 |
336 |
337 print appcode |
337 print appcode |
338 #mod_code[platform][app_name] = appcode |
338 # mod_code[platform][app_name] = appcode |
339 |
339 |
340 # platform.Module.cache.js |
340 # platform.Module.cache.js |
341 |
341 |
342 modules_done = ['pyjslib', 'sys', '_pyjs.js'] |
342 modules_done = ['pyjslib', 'sys', '_pyjs.js'] |
343 #modules_to_do = [app_name] + app_translator.library_modules |
343 # modules_to_do = [app_name] + app_translator.library_modules |
344 modules_to_do = [app_name] + app_translator.library_modules |
344 modules_to_do = [app_name] + app_translator.library_modules |
345 |
345 |
346 dependencies = {} |
346 dependencies = {} |
347 |
347 |
348 deps = map(pyjs.strip_py, modules_to_do) |
348 deps = map(pyjs.strip_py, modules_to_do) |
349 for d in deps: |
349 for d in deps: |
350 sublist = add_subdeps(dependencies, d) |
350 sublist = add_subdeps(dependencies, d) |
351 modules_to_do += sublist |
351 modules_to_do += sublist |
352 deps = uniquify(deps) |
352 deps = uniquify(deps) |
353 #dependencies[app_name] = deps |
353 # dependencies[app_name] = deps |
354 |
354 |
355 modules[platform] = modules_done + modules_to_do |
355 modules[platform] = modules_done + modules_to_do |
356 |
356 |
357 while modules_to_do: |
357 while modules_to_do: |
358 |
358 |
359 #print "modules to do", modules_to_do |
359 # print "modules to do", modules_to_do |
360 |
360 |
361 mn = modules_to_do.pop() |
361 mn = modules_to_do.pop() |
362 mod_name = pyjs.strip_py(mn) |
362 mod_name = pyjs.strip_py(mn) |
363 |
363 |
364 if mod_name in modules_done: |
364 if mod_name in modules_done: |
369 mod_cache_name = "%s.%s.cache.js" % (platform.lower(), mod_name) |
369 mod_cache_name = "%s.%s.cache.js" % (platform.lower(), mod_name) |
370 |
370 |
371 parser.setPlatform(platform) |
371 parser.setPlatform(platform) |
372 mod_translator = pyjs.AppTranslator(parser=parser, optimize=optimize) |
372 mod_translator = pyjs.AppTranslator(parser=parser, optimize=optimize) |
373 mod_libs[platform][mod_name], mod_code[platform][mod_name] = \ |
373 mod_libs[platform][mod_name], mod_code[platform][mod_name] = \ |
374 mod_translator.translate(mod_name, |
374 mod_translator.translate(mod_name, |
375 is_app=False, |
375 is_app=False, |
376 debug=debug) |
376 debug=debug) |
377 pover[platform].update(mod_translator.overrides.items()) |
377 pover[platform].update(mod_translator.overrides.items()) |
378 for mname, name in mod_translator.overrides.items(): |
378 for mname, name in mod_translator.overrides.items(): |
379 pd = overrides.setdefault(mname, {}) |
379 pd = overrides.setdefault(mname, {}) |
380 pd[platform] = name |
380 pd[platform] = name |
381 |
381 |
388 if len(sd) > 1: |
388 if len(sd) > 1: |
389 deps += sd[:-1] |
389 deps += sd[:-1] |
390 while mod_name in deps: |
390 while mod_name in deps: |
391 deps.remove(mod_name) |
391 deps.remove(mod_name) |
392 |
392 |
393 #print |
393 # print |
394 #print |
394 # print |
395 #print "modname preadd:", mod_name, deps |
395 # print "modname preadd:", mod_name, deps |
396 #print |
396 # print |
397 #print |
397 # print |
398 for d in deps: |
398 for d in deps: |
399 sublist = add_subdeps(dependencies, d) |
399 sublist = add_subdeps(dependencies, d) |
400 modules_to_do += sublist |
400 modules_to_do += sublist |
401 modules_to_do += add_subdeps(dependencies, mod_name) |
401 modules_to_do += add_subdeps(dependencies, mod_name) |
402 #print "modname:", mod_name, deps |
402 # print "modname:", mod_name, deps |
403 deps = uniquify(deps) |
403 deps = uniquify(deps) |
404 #print "modname:", mod_name, deps |
404 # print "modname:", mod_name, deps |
405 dependencies[mod_name] = deps |
405 dependencies[mod_name] = deps |
406 |
406 |
407 # work out the dependency ordering of the modules |
407 # work out the dependency ordering of the modules |
408 |
408 |
409 mod_levels[platform] = make_deps(None, dependencies, modules_done) |
409 mod_levels[platform] = make_deps(None, dependencies, modules_done) |
410 |
410 |
411 # now write everything out |
411 # now write everything out |
412 |
412 |
413 for platform in app_platforms: |
413 for platform in app_platforms: |
414 |
414 |
415 early_app_libs_ = early_app_libs[platform] |
415 early_app_libs_ = early_app_libs[platform] |
416 app_libs_ = app_libs[platform] |
416 app_libs_ = app_libs[platform] |
417 app_code_ = app_code[platform] |
417 app_code_ = app_code[platform] |
418 #modules_ = filter_mods(app_name, modules[platform]) |
418 # modules_ = filter_mods(app_name, modules[platform]) |
419 mods = flattenlist(mod_levels[platform]) |
419 mods = flattenlist(mod_levels[platform]) |
420 mods.reverse() |
420 mods.reverse() |
421 modules_ = filter_mods(None, mods) |
421 modules_ = filter_mods(None, mods) |
422 |
422 |
423 for mod_name in modules_: |
423 for mod_name in modules_: |
455 mod_cache_html_output = open(join(output, mod_cache_name), "w") |
455 mod_cache_html_output = open(join(output, mod_cache_name), "w") |
456 else: |
456 else: |
457 mod_cache_html_output = StringIO() |
457 mod_cache_html_output = StringIO() |
458 |
458 |
459 print >>mod_cache_html_output, mod_cache_html_template % dict( |
459 print >>mod_cache_html_output, mod_cache_html_template % dict( |
460 mod_name = mod_name, |
460 mod_name=mod_name, |
461 app_name = app_name, |
461 app_name=app_name, |
462 modnames = modnames, |
462 modnames=modnames, |
463 overrides = overnames, |
463 overrides=overnames, |
464 mod_libs = mod_libs[platform][mod_name], |
464 mod_libs=mod_libs[platform][mod_name], |
465 dynamic = dynamic, |
465 dynamic=dynamic, |
466 mod_code = mod_code_, |
466 mod_code=mod_code_, |
467 ) |
467 ) |
468 |
468 |
469 if dynamic: |
469 if dynamic: |
470 mod_cache_html_output.close() |
470 mod_cache_html_output.close() |
471 else: |
471 else: |
472 mod_cache_html_output.seek(0) |
472 mod_cache_html_output.seek(0) |
473 app_libs_ += mod_cache_html_output.read() |
473 app_libs_ += mod_cache_html_output.read() |
474 |
474 |
475 # write out the dependency ordering of the modules |
475 # write out the dependency ordering of the modules |
476 |
476 |
477 app_modnames = [] |
477 app_modnames = [] |
478 |
478 |
479 for md in mod_levels[platform]: |
479 for md in mod_levels[platform]: |
480 mnames = map(lambda x: "'%s'" % x, md) |
480 mnames = map(lambda x: "'%s'" % x, md) |
481 mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames) |
481 mnames = "new pyjslib.List([\n\t\t\t%s])" % ',\n\t\t\t'.join(mnames) |
487 # convert the overrides |
487 # convert the overrides |
488 |
488 |
489 overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items()) |
489 overnames = map(lambda x: "'%s': '%s'" % x, pover[platform].items()) |
490 overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames) |
490 overnames = "new pyjslib.Dict({\n\t\t%s\n\t})" % ',\n\t\t'.join(overnames) |
491 |
491 |
492 #print "platform names", platform, overnames |
492 # print "platform names", platform, overnames |
493 #print pover |
493 # print pover |
494 |
494 |
495 # now write app.allcache including dependency-ordered list of |
495 # now write app.allcache including dependency-ordered list of |
496 # library modules |
496 # library modules |
497 |
497 |
498 file_contents = all_cache_html_template % dict( |
498 file_contents = all_cache_html_template % dict( |
499 app_name = app_name, |
499 app_name=app_name, |
500 early_app_libs = early_app_libs_, |
500 early_app_libs=early_app_libs_, |
501 app_libs = app_libs_, |
501 app_libs=app_libs_, |
502 app_code = app_code_, |
502 app_code=app_code_, |
503 app_body = app_body, |
503 app_body=app_body, |
504 overrides = overnames, |
504 overrides=overnames, |
505 platform = platform.lower(), |
505 platform=platform.lower(), |
506 dynamic = dynamic, |
506 dynamic=dynamic, |
507 app_modnames = app_modnames, |
507 app_modnames=app_modnames, |
508 app_headers = app_headers |
508 app_headers=app_headers |
509 ) |
509 ) |
510 if cache_buster: |
510 if cache_buster: |
511 digest = md5.new(file_contents).hexdigest() |
511 digest = md5.new(file_contents).hexdigest() |
512 file_name = "%s.%s.%s" % (platform.lower(), app_name, digest) |
512 file_name = "%s.%s.%s" % (platform.lower(), app_name, digest) |
513 else: |
513 else: |
514 file_name = "%s.%s" % (platform.lower(), app_name) |
514 file_name = "%s.%s" % (platform.lower(), app_name) |
515 file_name += ".cache.html" |
515 file_name += ".cache.html" |
516 out_path = join(output, file_name) |
516 out_path = join(output, file_name) |
517 out_file = open(out_path, 'w') |
517 out_file = open(out_path, 'w') |
518 out_file.write(file_contents) |
518 out_file.write(file_contents) |
519 out_file.close() |
519 out_file.close() |
520 app_files.append((platform.lower(), file_name)) |
520 app_files.append((platform.lower(), file_name)) |
521 print "Created app file %s:%s: %s" % ( |
521 print "Created app file %s:%s: %s" % ( |
522 app_name, platform, out_path) |
522 app_name, platform, out_path) |
523 |
523 |
524 return app_files |
524 return app_files |
525 |
525 |
|
526 |
526 def flattenlist(ll): |
527 def flattenlist(ll): |
527 res = [] |
528 res = [] |
528 for l in ll: |
529 for l in ll: |
529 res += l |
530 res += l |
530 return res |
531 return res |
531 |
532 |
532 # creates sub-dependencies e.g. pyjamas.ui.Widget |
533 |
533 # creates pyjamas.ui.Widget, pyjamas.ui and pyjamas. |
|
534 def subdeps(m): |
534 def subdeps(m): |
|
535 """ |
|
536 creates sub-dependencies e.g. pyjamas.ui.Widget |
|
537 creates pyjamas.ui.Widget, pyjamas.ui and pyjamas. |
|
538 """ |
535 d = [] |
539 d = [] |
536 m = m.split(".") |
540 m = m.split(".") |
537 for i in range(0, len(m)): |
541 for i in range(0, len(m)): |
538 d.append('.'.join(m[:i+1])) |
542 d.append('.'.join(m[:i+1])) |
539 return d |
543 return d |
540 |
544 |
541 import time |
|
542 |
545 |
543 def add_subdeps(deps, mod_name): |
546 def add_subdeps(deps, mod_name): |
544 sd = subdeps(mod_name) |
547 sd = subdeps(mod_name) |
545 if len(sd) == 1: |
548 if len(sd) == 1: |
546 return [] |
549 return [] |
547 #print "subdeps", mod_name, sd |
550 # print "subdeps", mod_name, sd |
548 #print "deps", deps |
551 # print "deps", deps |
549 res = [] |
552 res = [] |
550 for i in range(0, len(sd)-1): |
553 for i in range(0, len(sd)-1): |
551 parent = sd[i] |
554 parent = sd[i] |
552 child = sd[i+1] |
555 child = sd[i+1] |
553 l = deps.get(child, []) |
556 k = deps.get(child, []) |
554 l.append(parent) |
557 k.append(parent) |
555 deps[child] = l |
558 deps[child] = k |
556 if parent not in res: |
559 if parent not in res: |
557 res.append(parent) |
560 res.append(parent) |
558 #print deps |
561 # print deps |
559 return res |
562 return res |
560 |
563 |
561 # makes unique and preserves list order |
564 |
562 def uniquify(md): |
565 def uniquify(md): |
|
566 """ |
|
567 makes unique and preserves list order |
|
568 """ |
563 res = [] |
569 res = [] |
564 for m in md: |
570 for m in md: |
565 if m not in res: |
571 if m not in res: |
566 res.append(m) |
572 res.append(m) |
567 return res |
573 return res |
|
574 |
568 |
575 |
569 def filter_mods(app_name, md): |
576 def filter_mods(app_name, md): |
570 while 'sys' in md: |
577 while 'sys' in md: |
571 md.remove('sys') |
578 md.remove('sys') |
572 while 'pyjslib' in md: |
579 while 'pyjslib' in md: |
576 md = filter(lambda x: not x.endswith('.js'), md) |
583 md = filter(lambda x: not x.endswith('.js'), md) |
577 md = map(pyjs.strip_py, md) |
584 md = map(pyjs.strip_py, md) |
578 |
585 |
579 return uniquify(md) |
586 return uniquify(md) |
580 |
587 |
|
588 |
581 def filter_deps(app_name, deps): |
589 def filter_deps(app_name, deps): |
582 |
590 |
583 res = {} |
591 res = {} |
584 for (k, l) in deps.items(): |
592 for (k, l) in deps.items(): |
585 mods = filter_mods(k, l) |
593 mods = filter_mods(k, l) |
586 while k in mods: |
594 while k in mods: |
587 mods.remove(k) |
595 mods.remove(k) |
588 res[k] = mods |
596 res[k] = mods |
589 return res |
597 return res |
590 |
598 |
|
599 |
591 def has_nodeps(mod, deps): |
600 def has_nodeps(mod, deps): |
592 if not deps.has_key(mod) or not deps[mod]: |
601 if mod not in deps or not deps[mod]: |
593 return True |
602 return True |
594 return False |
603 return False |
|
604 |
595 |
605 |
596 def nodeps_list(mod_list, deps): |
606 def nodeps_list(mod_list, deps): |
597 res = [] |
607 res = [] |
598 for mod in mod_list: |
608 for mod in mod_list: |
599 if has_nodeps(mod, deps): |
609 if has_nodeps(mod, deps): |
600 res.append(mod) |
610 res.append(mod) |
601 return res |
611 return res |
602 |
612 |
603 # this function takes a dictionary of dependent modules and |
613 # this function takes a dictionary of dependent modules and |
604 # creates a list of lists. the first list will be modules |
614 # creates a list of lists. the first list will be modules |
605 # that have no dependencies; the second list will be those |
615 # that have no dependencies; the second list will be those |
606 # modules that have the first list as dependencies; the |
616 # modules that have the first list as dependencies; the |
607 # third will be those modules that have the first and second... |
617 # third will be those modules that have the first and second... |
614 deps = filter_deps(app_name, deps) |
624 deps = filter_deps(app_name, deps) |
615 |
625 |
616 if not mod_list: |
626 if not mod_list: |
617 return [] |
627 return [] |
618 |
628 |
619 #print mod_list |
629 # print mod_list |
620 #print deps |
630 # print deps |
621 |
631 |
622 ordered_deps = [] |
632 ordered_deps = [] |
623 last_len = -1 |
633 last_len = -1 |
624 while deps: |
634 while deps: |
625 l_deps = len(deps) |
635 l_deps = len(deps) |
626 #print l_deps |
636 # print l_deps |
627 if l_deps==last_len: |
637 if l_deps == last_len: |
628 for m, dl in deps.items(): |
638 for m, dl in deps.items(): |
629 for d in dl: |
639 for d in dl: |
630 if m in deps.get(d, []): |
640 if m in deps.get(d, []): |
631 raise Exception('Circular Imports found: \n%s %s -> %s %s' |
641 raise Exception('Circular Imports found: \n%s %s -> %s %s' |
632 % (m, dl, d, deps[d])) |
642 % (m, dl, d, deps[d])) |
633 #raise Exception('Could not calculate dependencies: \n%s' % deps) |
643 # raise Exception('Could not calculate dependencies: \n%s' % deps) |
634 break |
644 break |
635 last_len = l_deps |
645 last_len = l_deps |
636 #print "modlist", mod_list |
646 # print "modlist", mod_list |
637 nodeps = nodeps_list(mod_list, deps) |
647 nodeps = nodeps_list(mod_list, deps) |
638 #print "nodeps", nodeps |
648 # print "nodeps", nodeps |
639 mod_list = filter(lambda x: x not in nodeps, mod_list) |
649 mod_list = filter(lambda x: x not in nodeps, mod_list) |
640 newdeps = {} |
650 newdeps = {} |
641 for k in deps.keys(): |
651 for k in deps.keys(): |
642 depslist = deps[k] |
652 depslist = deps[k] |
643 depslist = filter(lambda x: x not in nodeps, depslist) |
653 depslist = filter(lambda x: x not in nodeps, depslist) |
644 if depslist: |
654 if depslist: |
645 newdeps[k] = depslist |
655 newdeps[k] = depslist |
646 #print "newdeps", newdeps |
656 # print "newdeps", newdeps |
647 deps = newdeps |
657 deps = newdeps |
648 ordered_deps.append(nodeps) |
658 ordered_deps.append(nodeps) |
649 #time.sleep(0) |
659 # time.sleep(0) |
650 |
660 |
651 if mod_list: |
661 if mod_list: |
652 ordered_deps.append(mod_list) # last dependencies - usually the app(s) |
662 ordered_deps.append(mod_list) # last dependencies - usually the app(s) |
653 |
663 |
654 ordered_deps.reverse() |
664 ordered_deps.reverse() |
655 |
665 |
656 return ordered_deps |
666 return ordered_deps |
|
667 |
657 |
668 |
658 def main(): |
669 def main(): |
659 global app_platforms |
670 global app_platforms |
660 |
671 |
661 parser = OptionParser(usage = usage, version = version) |
672 parser = OptionParser(usage=usage, version=version) |
662 parser.add_option("-o", "--output", dest="output", |
673 parser.add_option( |
663 help="directory to which the webapp should be written") |
674 "-o", |
664 parser.add_option("-j", "--include-js", dest="js_includes", action="append", |
675 "--output", |
665 help="javascripts to load into the same frame as the rest of the script") |
676 dest="output", |
666 parser.add_option("-I", "--library_dir", dest="library_dirs", |
677 help="directory to which the webapp should be written" |
667 action="append", help="additional paths appended to PYJSPATH") |
678 ) |
668 parser.add_option("-D", "--data_dir", dest="data_dir", |
679 parser.add_option( |
669 help="path for data directory") |
680 "-j", |
670 parser.add_option("-m", "--dynamic-modules", action="store_true", |
681 "--include-js", |
671 dest="dynamic", default=False, |
682 dest="js_includes", |
672 help="Split output into separate dynamically-loaded modules (experimental)") |
683 action="append", |
673 parser.add_option("-P", "--platforms", dest="platforms", |
684 help="javascripts to load into the same frame as the rest of the script" |
674 help="platforms to build for, comma-separated") |
685 ) |
675 parser.add_option("-d", "--debug", action="store_true", dest="debug") |
686 parser.add_option( |
676 parser.add_option("-O", "--optimize", action="store_true", |
687 "-I", |
677 dest="optimize", default=False, |
688 "--library_dir", |
678 help="Optimize generated code (removes all print statements)", |
689 dest="library_dirs", |
679 ) |
690 action="append", |
680 parser.add_option("-c", "--cache_buster", action="store_true", |
691 help="additional paths appended to PYJSPATH" |
681 dest="cache_buster", |
692 ) |
682 help="Enable browser cache-busting (MD5 hash added to output filenames)") |
693 parser.add_option( |
683 |
694 "-D", |
684 parser.set_defaults(output = "output", js_includes=[], library_dirs=[], |
695 "--data_dir", |
|
696 dest="data_dir", |
|
697 help="path for data directory" |
|
698 ) |
|
699 parser.add_option( |
|
700 "-m", |
|
701 "--dynamic-modules", |
|
702 action="store_true", |
|
703 dest="dynamic", |
|
704 default=False, |
|
705 help="Split output into separate dynamically-loaded modules (experimental)" |
|
706 ) |
|
707 parser.add_option( |
|
708 "-P", |
|
709 "--platforms", |
|
710 dest="platforms", |
|
711 help="platforms to build for, comma-separated" |
|
712 ) |
|
713 parser.add_option( |
|
714 "-d", |
|
715 "--debug", |
|
716 action="store_true", |
|
717 dest="debug" |
|
718 ) |
|
719 parser.add_option( |
|
720 "-O", |
|
721 "--optimize", |
|
722 action="store_true", |
|
723 dest="optimize", |
|
724 default=False, |
|
725 help="Optimize generated code (removes all print statements)", |
|
726 ) |
|
727 parser.add_option( |
|
728 "-c", |
|
729 "--cache_buster", |
|
730 action="store_true", |
|
731 dest="cache_buster", |
|
732 help="Enable browser cache-busting (MD5 hash added to output filenames)" |
|
733 ) |
|
734 |
|
735 parser.set_defaults(output="output", js_includes=[], library_dirs=[], |
685 platforms=(','.join(app_platforms)), |
736 platforms=(','.join(app_platforms)), |
686 data_dir=os.path.join(sys.prefix, "share/pyjamas"), |
737 data_dir=os.path.join(sys.prefix, "share/pyjamas"), |
687 dynamic=False, |
738 dynamic=False, |
688 cache_buster=False, |
739 cache_buster=False, |
689 debug=False) |
740 debug=False) |
708 |
759 |
709 for d in options.library_dirs: |
760 for d in options.library_dirs: |
710 pyjs.path.append(abspath(d)) |
761 pyjs.path.append(abspath(d)) |
711 |
762 |
712 if options.platforms: |
763 if options.platforms: |
713 app_platforms = options.platforms.split(',') |
764 app_platforms = options.platforms.split(',') |
714 |
765 |
715 # this is mostly for getting boilerplate stuff |
766 # this is mostly for getting boilerplate stuff |
716 data_dir = os.path.abspath(options.data_dir) |
767 data_dir = os.path.abspath(options.data_dir) |
717 |
768 |
718 build(app_name, options.output, options.js_includes, |
769 build(app_name, options.output, options.js_includes, |
719 options.debug, options.dynamic and 1 or 0, data_dir, |
770 options.debug, options.dynamic and 1 or 0, data_dir, |
720 options.cache_buster, options.optimize) |
771 options.cache_buster, options.optimize) |
721 |
772 |
|
773 |
722 if __name__ == "__main__": |
774 if __name__ == "__main__": |
723 main() |
775 main() |
724 |
|