Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staticfiles compiler mixin #438

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ or just made Pipeline more awesome.
* Jared Scott <[email protected]>
* Jaromir Fojtu <[email protected]>
* Jon Dufresne <[email protected]>
* Jonas Lundberg <[email protected]>
* Josh Braegger <[email protected]>
* Joshua Kehn <[email protected]>
* Julien Hartmann <[email protected]>
Expand Down
23 changes: 23 additions & 0 deletions docs/compilers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,29 @@ To use it add this to your ``PIPELINE_COMPILERS`` ::
Defaults to ``''``.


.. _StaticFilesCompilerMixin:

Static files compiler mixin
===========================

When using compilers together with a remote storage, like S3,
you need to extend the compiler of choice to use staticfiles instead of the remote storage.

To do so, you just have to create your own compiler class that inherits from
``pipeline.compilers.StaticFilesCompilerMixin`` and your desired compiler.

Example
-------

A custom less compiler extended with staticfiles usage ::

from pipeline.compilers import StaticFilesCompilerMixin
from pipeline.compilers.less import LessCompiler

class LocalLessCompiler(StaticFilesCompilerMixin, LessCompiler):
pass


Write your own compiler class
=============================

Expand Down
4 changes: 4 additions & 0 deletions docs/storages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ unless you don't have access to the local filesystem in which case you should us
class S3PipelineCachedStorage(PipelineMixin, CachedFilesMixin, S3BotoStorage):
pass

.. note::
When using custom storage in combination with compilers you may also need to use ``StaticFilesCompilerMixin``
(see StaticFilesCompilerMixin_ for more details).


Using Pipeline with Bower
=========================
Expand Down
38 changes: 34 additions & 4 deletions pipeline/compilers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import unicode_literals

import os
from datetime import datetime

try:
from shlex import quote
Expand Down Expand Up @@ -34,14 +35,13 @@ def _compile(input_path):
compiler = compiler(verbose=self.verbose, storage=self.storage)
if compiler.match_file(input_path):
output_path = self.output_path(input_path, compiler.output_extension)
try:
infile = self.storage.path(input_path)
except NotImplementedError:
infile = finders.find(input_path)
infile = compiler.path(input_path)
outfile = self.output_path(infile, compiler.output_extension)
outdated = compiler.is_outdated(input_path, output_path)
compiler.compile_file(quote(infile), quote(outfile),
outdated=outdated, force=force)
if hasattr(compiler, 'post_process'):
compiler.post_process(outfile, name=output_path)
return output_path
else:
return input_path
Expand Down Expand Up @@ -71,6 +71,12 @@ def match_file(self, filename):
def compile_file(self, infile, outfile, outdated=False, force=False):
raise NotImplementedError

def path(self, name):
try:
return self.storage.path(name)
except NotImplementedError:
return finders.find(name)

def save_file(self, path, content):
return self.storage.save(path, ContentFile(smart_str(content)))

Expand Down Expand Up @@ -103,3 +109,27 @@ def execute_command(self, command, content=None, cwd=None):
if pipe.returncode != 0:
raise CompilerError("Command '{0}' returned non-zero exit status {1}".format(command, pipe.returncode))
return stdout


class StaticFilesCompilerMixin(object):
def path(self, name):
return finders.find(name)

def read_file(self, path):
file = open(path, 'rb')
content = file.read()
file.close()
return content

def modified_time(self, name):
return datetime.fromtimestamp(os.path.getmtime(self.path(name)))

def is_outdated(self, infile, outfile):
try:
return self.modified_time(infile) > self.storage.modified_time(outfile)
except (OSError, NotImplementedError):
return True

def post_process(self, outfile, name):
content = self.read_file(outfile)
self.save_file(name, content)