You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bundle.py 3.4 KiB

14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
14 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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.vc.repo.add(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, verbose
  43. if force_rebuild:
  44. return True
  45. for f in files:
  46. if f in self.dirty:
  47. if verbose:
  48. print '*** %s changed' % f
  49. return True
  50. return False
  51. def minify(self, in_files, outfile, concat=False):
  52. """
  53. Compress in_files into outfile,
  54. give some stats
  55. """
  56. from build import verbose
  57. import os
  58. # concat everything into temp
  59. outtype = outfile.split('.')[-1]
  60. temp = self.concat(in_files, is_js=True)
  61. out = open(outfile, 'w')
  62. org_size = len(temp.getvalue())
  63. temp.seek(0)
  64. # minify
  65. jsm = JavascriptMinify()
  66. jsm.minify(temp, out)
  67. out.close()
  68. self.vc.repo.add(outfile)
  69. new_size = os.path.getsize(outfile)
  70. if verbose:
  71. print '=> %s' % outfile
  72. print 'Original: %.2f kB' % (org_size / 1024.0)
  73. print 'Compressed: %.2f kB' % (new_size / 1024.0)
  74. print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100)
  75. def make(self, bpath):
  76. """
  77. Build (stitch + compress) the file defined in build.json
  78. """
  79. import os, sys, json
  80. from build import no_minify
  81. # open the build.json file and read
  82. # the dict
  83. bfile = open(bpath, 'r')
  84. bdata = json.loads(bfile.read())
  85. bfile.close()
  86. path = os.path.dirname(bpath)
  87. for outfile in bdata:
  88. prefix, fname = False, outfile
  89. # check if there is a prefix
  90. if ':' in outfile:
  91. prefix, fname = outfile.split(':')
  92. # build the file list relative to the main folder
  93. fl = [os.path.relpath(os.path.join(path, f), os.curdir) for f in bdata[outfile]]
  94. if self.changed(fl):
  95. # js files are minified by default unless explicitly
  96. # mentioned in the prefix.
  97. # some files may not work if minified (known jsmin bug)
  98. if fname.split('.')[-1]=='js' and prefix!='concat' and not no_minify:
  99. self.minify(fl, os.path.relpath(os.path.join(path, fname), os.curdir))
  100. else:
  101. self.concat(fl, os.path.relpath(os.path.join(path, fname), os.curdir))
  102. def bundle(self, vc):
  103. """
  104. Build js files from "build.json" found in version control
  105. """
  106. import os
  107. self.dirty = vc.repo.uncommitted()
  108. self.vc = vc
  109. # walk the parent folder and build all files as defined in the build.json files
  110. for b in vc.repo.sql("select fname from bundles"):
  111. self.make(os.path.abspath(os.path.join(vc.root_path, b[0])))