Commit 13c2004b by Timothée Peignier

add compilers

parent c9240c02
from compress.packager import Packager
__all__ = ['packager']
packager = Packager()
import os
import subprocess import subprocess
from compress.conf import settings
from compress.utils import to_class
class Compiler(object):
def __init__(self, verbose=False):
self.verbose = verbose
def compilers(self):
return [to_class(compiler) for compiler in settings.COMPRESS_COMPILERS]
compilers = property(compilers)
def compile(self, paths):
for index, path in enumerate(paths):
for compiler in self.compilers:
compiler = compiler(self.verbose)
if compiler.match_file(path):
new_path = self.output_path(path, compiler.output_extension)
content = self.read_file(path)
compiled_content = compiler.compile_file(content)
self.save_file(new_path, compiled_content)
paths[index] = new_path
return paths
def output_path(self, path, extension):
path = os.path.splitext(path)
return '.'.join((path[0], extension))
def read_file(self, path):
f = open(path, 'rb')
content = f.read()
f.close()
return content
def save_file(self, path, content):
f = open(path, 'w')
f.write(content)
f.close()
class CompilerBase(object): class CompilerBase(object):
def __init__(self, verbose): def __init__(self, verbose):
self.verbose = verbose self.verbose = verbose
...@@ -10,6 +51,12 @@ class CompilerBase(object): ...@@ -10,6 +51,12 @@ class CompilerBase(object):
def compile_file(self, content): def compile_file(self, content):
raise NotImplementedError raise NotImplementedError
def save_file(self, path, content):
f = open(path, 'w')
f.write(content)
f.close()
return path
class CompilerError(Exception): class CompilerError(Exception):
pass pass
...@@ -31,7 +78,7 @@ class SubProcessCompiler(CompilerBase): ...@@ -31,7 +78,7 @@ class SubProcessCompiler(CompilerBase):
if pipe.wait() != 0: if pipe.wait() != 0:
if not error: if not error:
error = "Unable to apply %s compiler" % self.__class__.__name__ error = "Unable to apply %s compiler" % self.__class__.__name__
raise FilterError(error) raise CompilerError(error)
if self.verbose: if self.verbose:
print error print error
......
...@@ -3,8 +3,10 @@ from compress.compilers import SubProcessCompiler ...@@ -3,8 +3,10 @@ from compress.compilers import SubProcessCompiler
class CoffeeScriptCompiler(SubProcessCompiler): class CoffeeScriptCompiler(SubProcessCompiler):
def match_file(self, filename): output_extension = 'js'
return filename.endswith('.coffee')
def match_file(self, path):
return path.endswith('.coffee')
def compile_file(self, content): def compile_file(self, content):
command = "%s %s" % (settings.COMPRESS_COFFEE_SCRIPT_BINARY, settings.COMPRESS_COFFEE_SCRIPT_ARGUMENTS) command = "%s %s" % (settings.COMPRESS_COFFEE_SCRIPT_BINARY, settings.COMPRESS_COFFEE_SCRIPT_ARGUMENTS)
......
...@@ -6,6 +6,8 @@ from compress.compilers import CompilerBase ...@@ -6,6 +6,8 @@ from compress.compilers import CompilerBase
class LessCompiler(CompilerBase): class LessCompiler(CompilerBase):
output_extension = 'css'
def match_file(self, filename): def match_file(self, filename):
return filename.endswith('.less') return filename.endswith('.less')
......
...@@ -3,6 +3,8 @@ from compress.compilers import SubProcessCompiler ...@@ -3,6 +3,8 @@ from compress.compilers import SubProcessCompiler
class SASSCompiler(SubProcessCompiler): class SASSCompiler(SubProcessCompiler):
output_extension = 'css'
def match_file(self, filename): def match_file(self, filename):
return filename.endswith('.scss') return filename.endswith('.scss')
......
...@@ -22,6 +22,8 @@ COMPRESS_CSS_COMPRESSORS = getattr(settings, 'COMPRESS_CSS_COMPRESSORS', [ ...@@ -22,6 +22,8 @@ COMPRESS_CSS_COMPRESSORS = getattr(settings, 'COMPRESS_CSS_COMPRESSORS', [
COMPRESS_JS_COMPRESSORS = getattr(settings, 'COMPRESS_JS_COMPRESSORS', [ COMPRESS_JS_COMPRESSORS = getattr(settings, 'COMPRESS_JS_COMPRESSORS', [
'compress.compressors.csstidy.YUICompressor' 'compress.compressors.csstidy.YUICompressor'
]) ])
COMPRESS_COMPILERS = getattr(settings, 'COMPRESS_COMPILERS', [])
COMPRESS_CSS = getattr(settings, 'COMPRESS_CSS', {}) COMPRESS_CSS = getattr(settings, 'COMPRESS_CSS', {})
COMPRESS_JS = getattr(settings, 'COMPRESS_JS', {}) COMPRESS_JS = getattr(settings, 'COMPRESS_JS', {})
...@@ -49,3 +51,6 @@ if COMPRESS_CSS_COMPRESSORS is None: ...@@ -49,3 +51,6 @@ if COMPRESS_CSS_COMPRESSORS is None:
if COMPRESS_JS_COMPRESSORS is None: if COMPRESS_JS_COMPRESSORS is None:
COMPRESS_JS_COMPRESSORS = [] COMPRESS_JS_COMPRESSORS = []
if COMPRESS_COMPILERS is None:
COMPRESS_COMPILERS = []
...@@ -15,21 +15,25 @@ class Command(NoArgsCommand): ...@@ -15,21 +15,25 @@ class Command(NoArgsCommand):
args = '' args = ''
def handle_noargs(self, **options): def handle_noargs(self, **options):
from compress import packager from compress.packager import Packager
packager.force = options.get('force', False) packager = Packager(
packager.verbose = int(options.get('verbosity', 1)) >= 2 force=options.get('force', False),
verbose=int(options.get('verbosity', 1)) >= 2
for package_name, package in packager.packages['css'].items(): )
for package_name in packager.packages['css']:
package = packager.package_for('css', package_name)
if packager.verbose or packager.force: if packager.verbose or packager.force:
print print
message = "CSS Group '%s'" % package_name message = "CSS Group '%s'" % package_name
print message print message
print len(message) * '-' print len(message) * '-'
packager.pack_stylesheets(package) packager.pack_stylesheets(package)
for package_name, package in packager.packages['js'].items(): for package_name in packager.packages['js']:
package = packager.package_for('js', package_name)
if packager.verbose or packager.force: if packager.verbose or packager.force:
print print
message = "JS Group '%s'" % package_name message = "JS Group '%s'" % package_name
print message print message
print len(message) * '-' print len(message) * '-'
......
...@@ -3,9 +3,10 @@ import os ...@@ -3,9 +3,10 @@ import os
import urlparse import urlparse
from compress.conf import settings from compress.conf import settings
from compress.compilers import Compiler
from compress.compressors import Compressor from compress.compressors import Compressor
from compress.versioning import Versioning from compress.versioning import Versioning
from compress.signals import css_filtered, js_filtered from compress.signals import css_compressed, js_compressed
class Packager(object): class Packager(object):
...@@ -14,6 +15,7 @@ class Packager(object): ...@@ -14,6 +15,7 @@ class Packager(object):
self.verbose = verbose self.verbose = verbose
self.compressor = Compressor(verbose) self.compressor = Compressor(verbose)
self.versioning = Versioning(verbose) self.versioning = Versioning(verbose)
self.compiler = Compiler(verbose)
self.packages = { self.packages = {
'css': self.create_packages(settings.COMPRESS_CSS), 'css': self.create_packages(settings.COMPRESS_CSS),
'js': self.create_packages(settings.COMPRESS_JS), 'js': self.create_packages(settings.COMPRESS_JS),
...@@ -21,20 +23,25 @@ class Packager(object): ...@@ -21,20 +23,25 @@ class Packager(object):
def package_for(self, kind, package_name): def package_for(self, kind, package_name):
try: try:
return self.packages[kind][package_name] return self.packages[kind][package_name].copy()
except KeyError: except KeyError:
raise PackageNotFound("No corresponding package for %s package name : %s" raise PackageNotFound(
% (kind, package_name) "No corresponding package for %s package name : %s" % (
kind, package_name
)
) )
def individual_url(self, filename): def individual_url(self, filename):
return urlparse.urljoin(settings.COMPRESS_URL, self.compressor.relative_path(filename)[1:]) return urlparse.urljoin(settings.COMPRESS_URL,
self.compressor.relative_path(filename)[1:])
def pack_stylesheets(self, package): def pack_stylesheets(self, package):
css = self.compressor.compress_css(package['paths']) return self.pack(package, self.compressor.compress_css, css_compressed)
return self.pack(package, css, css_filtered)
def pack(self, package, content, signal): def compile(self, paths):
return self.compiler.compile(paths)
def pack(self, package, compress, signal):
if settings.COMPRESS_AUTO or self.force: if settings.COMPRESS_AUTO or self.force:
need_update, version = self.versioning.need_update( need_update, version = self.versioning.need_update(
package['output'], package['paths']) package['output'], package['paths'])
...@@ -45,6 +52,8 @@ class Packager(object): ...@@ -45,6 +52,8 @@ class Packager(object):
if self.verbose or self.force: if self.verbose or self.force:
print "Version: %s" % version print "Version: %s" % version
print "Saving: %s" % self.compressor.relative_path(output_filename) print "Saving: %s" % self.compressor.relative_path(output_filename)
paths = self.compile(package['paths'])
content = compress(paths)
self.save_file(output_filename, content) self.save_file(output_filename, content)
signal.send(sender=self, package=package, version=version) signal.send(sender=self, package=package, version=version)
else: else:
...@@ -53,8 +62,7 @@ class Packager(object): ...@@ -53,8 +62,7 @@ class Packager(object):
return self.versioning.output_filename(package['output'], version) return self.versioning.output_filename(package['output'], version)
def pack_javascripts(self, package): def pack_javascripts(self, package):
js = self.compressor.compress_js(package['paths']) return self.pack(package, self.compressor.compress_js, js_compressed)
return self.pack(package, js, js_filtered)
def save_file(self, filename, content): def save_file(self, filename, content):
dirname = os.path.dirname(filename) dirname = os.path.dirname(filename)
......
from django.dispatch import Signal from django.dispatch import Signal
css_filtered = Signal(providing_args=["package", "version"]) css_compressed = Signal(providing_args=["package", "version"])
js_filtered = Signal(providing_args=["package", "version"]) js_compressed = Signal(providing_args=["package", "version"])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment