Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

143 linhas
3.3 KiB

  1. from minify import JavascriptMinify
  2. class Bundle:
  3. """
  4. Concatenate, compress and mix (if required) js+css files from build.json
  5. """
  6. def concat(self, filelist, outfile=None, is_js=False):
  7. """
  8. Concat css and js files into a bundle
  9. """
  10. import os
  11. from cStringIO import StringIO
  12. from build import verbose
  13. out_type = outfile and outfile.split('.')[-1] or 'js'
  14. temp = StringIO()
  15. for f in filelist:
  16. if verbose:
  17. print f + ' | ' + str(int(os.path.getsize(f)/1024)) + 'k'
  18. fh = open(f)
  19. # get file type
  20. ftype = f.split('.')[-1]
  21. # special concat (css inside js)
  22. if is_js and ftype =='css':
  23. css = fh.read()
  24. data = "\nwn.assets.handler.css('%s');\n" % css.replace("'", "\\'").replace('\n', '\\\n')
  25. # plain concat
  26. else:
  27. data = fh.read() + '\n'
  28. fh.close()
  29. temp.write(data)
  30. if outfile:
  31. f = open(outfile, 'w')
  32. f.write(temp.getvalue())
  33. f.close()
  34. self.timestamps.update(outfile)
  35. if verbose: print 'Wrote %s' % outfile
  36. return temp
  37. def changed(self, files):
  38. """
  39. Returns true if the files are changed since last build
  40. """
  41. import os
  42. from build import force_rebuild
  43. if force_rebuild:
  44. return True
  45. for f in files:
  46. if f in self.timestamps.dirty:
  47. return True
  48. return False
  49. def minify(self, in_files, outfile, concat=False):
  50. """
  51. Compress in_files into outfile,
  52. give some stats
  53. """
  54. from build import verbose
  55. import os
  56. # concat everything into temp
  57. outtype = outfile.split('.')[-1]
  58. temp = self.concat(in_files, is_js=True)
  59. out = open(outfile, 'w')
  60. org_size = len(temp.getvalue())
  61. temp.seek(0)
  62. # minify
  63. jsm = JavascriptMinify()
  64. jsm.minify(temp, out)
  65. out.close()
  66. self.timestamps.update(outfile)
  67. new_size = os.path.getsize(outfile)
  68. if verbose:
  69. print '=> %s' % outfile
  70. print 'Original: %.2f kB' % (org_size / 1024.0)
  71. print 'Compressed: %.2f kB' % (new_size / 1024.0)
  72. print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100)
  73. def make(self, path):
  74. """
  75. Build (stitch + compress) the file defined in build.json
  76. """
  77. import os, sys, json
  78. from build import no_minify
  79. # open the build.json file and read
  80. # the dict
  81. bfile = open(os.path.join(path, 'build.json'), 'r')
  82. bdata = json.loads(bfile.read())
  83. bfile.close()
  84. for outfile in bdata:
  85. prefix, fname = False, outfile
  86. # check if there is a prefix
  87. if ':' in outfile:
  88. prefix, fname = outfile.split(':')
  89. # build the file list relative to the main folder
  90. fl = [os.path.relpath(os.path.join(path, f), os.curdir) for f in bdata[outfile]]
  91. self.timestamps.bundled += fl
  92. if self.changed(fl):
  93. # js files are minified by default unless explicitly
  94. # mentioned in the prefix.
  95. # some files may not work if minified (known jsmin bug)
  96. if fname.split('.')[-1]=='js' and prefix!='concat' and not no_minify:
  97. self.minify(fl, os.path.relpath(os.path.join(path, fname), os.curdir))
  98. else:
  99. self.concat(fl, os.path.relpath(os.path.join(path, fname), os.curdir))
  100. def bundle(self, timestamps):
  101. """
  102. Build js files from "build.json"
  103. """
  104. import os
  105. self.timestamps = timestamps
  106. # walk the parent folder and build all files as defined in the build.json files
  107. for wt in os.walk('.', followlinks=True):
  108. if 'build.json' in wt[2]:
  109. # found build file
  110. self.make(os.path.abspath(wt[0]))