Commit 1910ad9a by Timothée Peignier

Merge branch 'master' into jinja-ext

Conflicts:
	pipeline/jinja2/ext.py
	tests/tests/__init__.py
	tests/tests/test_jinja2.py
parents d4b24e31 1e1df0c0
......@@ -2,6 +2,6 @@ language: python
python:
- 2.7
install: pip install -q --use-mirrors tox
script: tox -e py26-1.2.X,py27-1.2.X,py26-1.3.X,py27-1.3.X,py26,py27,docs
script: tox -e py26-1.4.X,py27-1.4.X,pypy-1.4.X,py26,py27,py33,docs
notifications:
irc: "irc.freenode.org#django-pipeline"
\ No newline at end of file
......@@ -4,13 +4,17 @@ History
=======
1.1.24
------
* Fix yui/yuglify settings overriding each other. Thanks to Fábio Santos.
1.1.23
------
* Separate yuglify compressor from YUI compressor.
* Improve HTML compression middleware.
1.1.22
------
......
......@@ -33,14 +33,14 @@ To use it for your javascripts add this to your ``PIPELINE_JS_COMPRESSOR`` ::
Additional arguments to use when compressing CSS.
Defaults to ``''``.
Defaults to ``'--terminal'``.
``PIPELINE_YUGLIFY_JS_ARGUMENTS``
---------------------------------
Additional arguments to use when compressing JavaScript.
Defaults to ``''``.
Defaults to ``'--terminal'``.
YUI Compressor compressor
......
......@@ -49,9 +49,9 @@ copyright = u'2011-2012, Timothée Peignier'
# built documents.
#
# The short X.Y version.
version = '1.2'
version = '1.3'
# The full version, including alpha/beta/rc tags.
release = '1.2.23'
release = '1.3.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......
from __future__ import unicode_literals
import os
import subprocess
try:
from staticfiles import finders
except ImportError:
from django.contrib.staticfiles import finders # noqa
from django.contrib.staticfiles import finders
from django.core.files.base import ContentFile
from django.utils.encoding import smart_str
......@@ -83,8 +82,8 @@ class CompilerError(Exception):
class SubProcessCompiler(CompilerBase):
def execute_command(self, command, content=None, cwd=None):
pipe = subprocess.Popen(command, shell=True, cwd=cwd,
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
if content:
pipe.stdin.write(content)
......@@ -102,6 +101,6 @@ class SubProcessCompiler(CompilerBase):
raise CompilerError(error)
if self.verbose:
print error
print(error)
return compressed_content
from __future__ import unicode_literals
from pipeline.conf import settings
from pipeline.compilers import SubProcessCompiler
......
from __future__ import unicode_literals
from os.path import dirname
from pipeline.conf import settings
......
from __future__ import unicode_literals
from os.path import dirname
from pipeline.conf import settings
......
from __future__ import unicode_literals
from os.path import dirname
from pipeline.conf import settings
......
from __future__ import unicode_literals
import base64
import os
import posixpath
......@@ -6,12 +8,7 @@ import subprocess
from itertools import takewhile
from django.utils.encoding import smart_str, force_unicode
try:
from staticfiles import finders
except ImportError:
from django.contrib.staticfiles import finders # noqa
from django.utils.encoding import smart_bytes, force_text
from pipeline.conf import settings
from pipeline.storage import default_storage
......@@ -88,9 +85,9 @@ class Compressor(object):
namespace = settings.PIPELINE_TEMPLATE_NAMESPACE
base_path = self.base_path(paths)
for path in paths:
contents = self.read_file(path)
contents = re.sub(r"\r?\n", "\\\\n", contents)
contents = re.sub(r"'", "\\'", contents)
contents = self.read_text(path)
contents = re.sub("\r?\n", "\\\\n", contents)
contents = re.sub("'", "\\'", contents)
name = self.template_name(path, base_path)
compiled += "%s['%s'] = %s('%s');\n" % (
namespace,
......@@ -131,17 +128,17 @@ class Compressor(object):
if asset_path.startswith("http") or asset_path.startswith("//"):
return "url(%s)" % asset_path
asset_url = self.construct_asset_path(asset_path, path,
output_filename, variant)
output_filename, variant)
return "url(%s)" % asset_url
content = self.read_file(path)
content = self.read_text(path)
# content needs to be unicode to avoid explosions with non-ascii chars
content = re.sub(URL_DETECTOR, reconstruct, force_unicode(content))
content = re.sub(URL_DETECTOR, reconstruct, content)
stylesheets.append(content)
return '\n'.join(stylesheets)
def concatenate(self, paths):
"""Concatenate together a list of files"""
return '\n'.join([self.read_file(path) for path in paths])
return "\n".join([self.read_text(path) for path in paths])
def construct_asset_path(self, asset_path, css_path, output_filename, variant=None):
"""Return a rewritten asset URL for a stylesheet"""
......@@ -178,7 +175,7 @@ class Compressor(object):
"""Return the base64 encoded contents"""
if path in self.__class__.asset_contents:
return self.__class__.asset_contents[path]
data = self.read_file(path)
data = self.read_bytes(path)
self.__class__.asset_contents[path] = base64.b64encode(data)
return self.__class__.asset_contents[path]
......@@ -204,13 +201,17 @@ class Compressor(object):
output_path = posixpath.join(settings.PIPELINE_ROOT, posixpath.dirname(output_filename))
return relpath(absolute_path, output_path)
def read_file(self, path):
def read_bytes(self, path):
"""Read file content in binary mode"""
file = default_storage.open(path, 'rb')
file = default_storage.open(path)
content = file.read()
file.close()
return content
def read_text(self, path):
content = self.read_bytes(path)
return force_text(content)
class CompressorBase(object):
def __init__(self, verbose):
......@@ -231,11 +232,11 @@ class CompressorError(Exception):
class SubProcessCompressor(CompressorBase):
def execute_command(self, command, content):
pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE,
stdin=subprocess.PIPE, stderr=subprocess.PIPE)
stdin=subprocess.PIPE, stderr=subprocess.PIPE)
try:
pipe.stdin.write(smart_str(content))
except IOError, e:
pipe.stdin.write(smart_bytes(content))
except IOError as e:
message = "Unable to pipe content to command: %s" % command
raise CompressorError(message, e)
pipe.stdin.close()
......@@ -252,5 +253,5 @@ class SubProcessCompressor(CompressorBase):
raise CompressorError(error)
if self.verbose:
print error
print(error)
return compressed_content
from __future__ import unicode_literals
from pipeline.conf import settings
from pipeline.compressors import SubProcessCompressor
......
from __future__ import unicode_literals
from pipeline.conf import settings
from pipeline.compressors import SubProcessCompressor
......
from __future__ import unicode_literals
from django.core.files import temp as tempfile
from pipeline.conf import settings
......
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from pipeline.compressors import CompressorBase
......
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from pipeline.compressors import CompressorBase
......
from __future__ import unicode_literals
from pipeline.conf import settings
from pipeline.compressors import SubProcessCompressor
......
from __future__ import unicode_literals
from pipeline.conf import settings
from pipeline.compressors import SubProcessCompressor
......
from __future__ import unicode_literals
from pipeline.conf import settings
from pipeline.compressors import SubProcessCompressor
......
from __future__ import unicode_literals
from django.conf import settings
PIPELINE = getattr(settings, 'PIPELINE', not settings.DEBUG)
......@@ -5,7 +7,7 @@ PIPELINE_ROOT = getattr(settings, 'PIPELINE_ROOT', settings.STATIC_ROOT)
PIPELINE_URL = getattr(settings, 'PIPELINE_URL', settings.STATIC_URL)
PIPELINE_STORAGE = getattr(settings, 'PIPELINE_STORAGE',
'pipeline.storage.PipelineFinderStorage')
'pipeline.storage.PipelineFinderStorage')
PIPELINE_CSS_COMPRESSOR = getattr(settings, 'PIPELINE_CSS_COMPRESSOR',
'pipeline.compressors.yuglify.YuglifyCompressor')
......@@ -25,9 +27,9 @@ PIPELINE_DISABLE_WRAPPER = getattr(settings, 'PIPELINE_DISABLE_WRAPPER', False)
PIPELINE_CSSTIDY_BINARY = getattr(settings, 'PIPELINE_CSSTIDY_BINARY', '/usr/bin/env csstidy')
PIPELINE_CSSTIDY_ARGUMENTS = getattr(settings, 'PIPELINE_CSSTIDY_ARGUMENTS', '--template=highest')
PIPELINE_YUGLIFY_BINARY = getattr(settings, 'PIPELINE_YUI_BINARY', '/usr/bin/env yuglify')
PIPELINE_YUGLIFY_CSS_ARGUMENTS = getattr(settings, 'PIPELINE_YUI_CSS_ARGUMENTS', '--terminal')
PIPELINE_YUGLIFY_JS_ARGUMENTS = getattr(settings, 'PIPELINE_YUI_JS_ARGUMENTS', '--terminal')
PIPELINE_YUGLIFY_BINARY = getattr(settings, 'PIPELINE_YUGLIFY_BINARY', '/usr/bin/env yuglify')
PIPELINE_YUGLIFY_CSS_ARGUMENTS = getattr(settings, 'PIPELINE_YUGLIFY_CSS_ARGUMENTS', '--terminal')
PIPELINE_YUGLIFY_JS_ARGUMENTS = getattr(settings, 'PIPELINE_YUGLIFY_JS_ARGUMENTS', '--terminal')
PIPELINE_YUI_BINARY = getattr(settings, 'PIPELINE_YUI_BINARY', '/usr/bin/env yuicompressor')
PIPELINE_YUI_CSS_ARGUMENTS = getattr(settings, 'PIPELINE_YUI_CSS_ARGUMENTS', '')
......
from __future__ import unicode_literals
import os
import re
import fnmatch
......
try:
from staticfiles.storage import staticfiles_storage
except ImportError:
from django.contrib.staticfiles.storage import staticfiles_storage # noqa
from __future__ import unicode_literals
from jinja2 import nodes
from jinja2.ext import Extension
from django.contrib.staticfiles.storage import staticfiles_storage
from pipeline.conf import settings
from pipeline.packager import Packager, PackageNotFound
from pipeline.utils import guess_type
......
from __future__ import unicode_literals
import os
try:
from staticfiles.finders import get_finders
except ImportError:
from django.contrib.staticfiles.finders import get_finders # noqa
from django.contrib.staticfiles.finders import get_finders
from pipeline.conf import settings
......
from __future__ import unicode_literals
from django.utils.encoding import DjangoUnicodeDecodeError
from django.utils.html import strip_spaces_between_tags as minify_html
......
from __future__ import unicode_literals
from django.core.files.base import ContentFile
from django.utils.encoding import smart_str
......@@ -28,12 +30,12 @@ class Package(object):
@property
def paths(self):
return [path for path in self.sources
if not path.endswith(settings.PIPELINE_TEMPLATE_EXT)]
if not path.endswith(settings.PIPELINE_TEMPLATE_EXT)]
@property
def templates(self):
return [path for path in self.sources
if path.endswith(settings.PIPELINE_TEMPLATE_EXT)]
if path.endswith(settings.PIPELINE_TEMPLATE_EXT)]
@property
def output_filename(self):
......@@ -86,8 +88,8 @@ class Packager(object):
def pack_stylesheets(self, package, **kwargs):
return self.pack(package, self.compressor.compress_css, css_compressed,
output_filename=package.output_filename,
variant=package.variant, **kwargs)
output_filename=package.output_filename,
variant=package.variant, **kwargs)
def compile(self, paths, force=False):
return self.compiler.compile(paths, force=force)
......@@ -95,7 +97,7 @@ class Packager(object):
def pack(self, package, compress, signal, **kwargs):
output_filename = package.output_filename
if self.verbose:
print "Saving: %s" % output_filename
print("Saving: %s" % output_filename)
paths = self.compile(package.paths, force=True)
content = compress(paths, **kwargs)
self.save_file(output_filename, content)
......
from __future__ import unicode_literals
from django.dispatch import Signal
......
from __future__ import unicode_literals
import os
try:
from staticfiles import finders
from staticfiles.storage import CachedFilesMixin, StaticFilesStorage
except ImportError:
from django.contrib.staticfiles import finders # noqa
from django.contrib.staticfiles.storage import CachedFilesMixin, StaticFilesStorage # noqa
from django.contrib.staticfiles import finders
from django.contrib.staticfiles.storage import CachedFilesMixin, StaticFilesStorage
from django.core.exceptions import ImproperlyConfigured
from django.core.files.storage import get_storage_class
......
try:
from staticfiles.storage import staticfiles_storage
except ImportError:
from django.contrib.staticfiles.storage import staticfiles_storage # noqa
from __future__ import unicode_literals
from django.contrib.staticfiles.storage import staticfiles_storage
from django import template
from django.template.loader import render_to_string
......
from __future__ import unicode_literals
import mimetypes
import posixpath
import urllib
......
......@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
setup(
name='django-pipeline',
version='1.2.23',
version='1.3.0',
description='Pipeline is an asset packaging library for Django.',
long_description=open('README.rst').read() + '\n\n' +
open('HISTORY.rst').read(),
......
......@@ -13,7 +13,7 @@ SITE_ID = 1
INSTALLED_APPS = [
'django.contrib.contenttypes',
'django.contrib.sites',
'staticfiles',
'django.contrib.staticfiles',
'django.contrib.auth',
'django.contrib.admin',
'pipeline',
......@@ -32,8 +32,8 @@ STATICFILES_DIRS = (
local_path('assets2/'),
)
STATICFILES_FINDERS = (
'staticfiles.finders.FileSystemFinder',
'staticfiles.finders.AppDirectoriesFinder'
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder'
)
SECRET_KEY = "django-pipeline"
......
# -*- coding: utf-8 flake8: noqa -*-
from compiler import *
from compressor import *
from extension import *
from glob import *
from packager import *
from storage import *
from utils import *
\ No newline at end of file
from .test_compiler import *
from .test_compressor import *
from .test_glob import *
from .test_packager import *
from .test_storage import *
from .test_utils import *
# -*- coding: utf-8 -*-
from jinja2 import Environment, FileSystemLoader
from pipeline.jinja2.ext import PipelineExtension
from django.template.loaders import app_directories
from django.test import TestCase
class PipelineExtensionTest(TestCase):
def setUp(self):
loader = FileSystemLoader(app_directories.app_template_dirs)
self.env = Environment(extensions=[PipelineExtension], loader=loader)
def test_compressed_css(self):
output = self.env.from_string("{% compressed_css 'screen' %}").render()
print output
from __future__ import unicode_literals
from django.test import TestCase
from pipeline.conf import settings
from pipeline.compilers import Compiler, CompilerBase
from paths import _
from tests.utils import _
class DummyCompiler(CompilerBase):
......@@ -20,7 +22,7 @@ class CompilerTest(TestCase):
def setUp(self):
self.compiler = Compiler()
self.old_compilers = settings.PIPELINE_COMPILERS
settings.PIPELINE_COMPILERS = ['tests.tests.compiler.DummyCompiler']
settings.PIPELINE_COMPILERS = ['tests.tests.test_compiler.DummyCompiler']
def test_output_path(self):
output_path = self.compiler.output_path("js/helpers.coffee", "js")
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import base64
from mock import patch
try:
from mock import patch
except ImportError:
from unittest.mock import patch # noqa
from django.test import TestCase
from pipeline.compressors import Compressor, TEMPLATE_FUNC
from pipeline.compressors.yuglify import YuglifyCompressor
from paths import _
from tests.utils import _
class CompressorTest(TestCase):
......@@ -99,7 +104,7 @@ class CompressorTest(TestCase):
output = self.compressor.concatenate_and_rewrite([
_('pipeline/css/urls.css'),
], 'css/screen.css')
self.assertEquals(u"""@font-face {
self.assertEquals("""@font-face {
font-family: 'Pipeline';
src: url(../pipeline/fonts/pipeline.eot);
src: url(../pipeline/fonts/pipeline.eot?#iefix) format('embedded-opentype');
......
from __future__ import unicode_literals
import os
import shutil
......@@ -20,7 +22,7 @@ class GlobTest(TestCase):
base = os.path.join(self.storage.location, base)
if not os.path.exists(base):
os.makedirs(base)
self.storage.save(filename, ContentFile(None))
self.storage.save(filename, ContentFile(""))
def assertSequenceEqual(self, l1, l2):
self.assertEqual(set(l1), set(l2))
......
from __future__ import unicode_literals
from django.test import TestCase
from pipeline.packager import Packager, PackageNotFound
from paths import _
from tests.utils import _
class PackagerTest(TestCase):
......
from __future__ import unicode_literals
from django.test import TestCase
from django.utils.datastructures import SortedDict
from pipeline.conf import settings
from pipeline.storage import PipelineStorage
from paths import _
from tests.utils import _
class StorageTest(TestCase):
......@@ -31,12 +34,8 @@ class StorageTest(TestCase):
'css/first.css': (self.storage, 'css/first.css'),
'images/arrow.png': (self.storage, 'images/arrow.png')
}))
self.assertEqual(processed_files, [
('css/first.css', 'css/first.css', True),
('images/arrow.png', 'images/arrow.png', True),
('testing.css', 'testing.css', True),
('scripts.css', 'scripts.css', True)
])
self.assertTrue(('css/first.css', 'css/first.css', True) in processed_files)
self.assertTrue(('images/arrow.png', 'images/arrow.png', True) in processed_files)
def tearDown(self):
settings.PIPELINE_CSS = {}
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
from pipeline.utils import guess_type
......
import os
import os
def _(path):
# Make sure the path contains only the correct separator
def _(path):
# Make sure the path contains only the correct separator
return path.replace('/', os.sep).replace('\\', os.sep)
[tox]
envlist =
py25-1.2.X, py26-1.2.X, py27-1.2.X,
py25-1.3.X, py26-1.3.X, py27-1.3.X,
py25, py26, py27, pypy, docs
envlist =
py26-1.4.X, py27-1.4.X, pypy-1.4.X,
py26, py27, pypy, py33, docs
[testenv]
downloadcache = {toxworkdir}/_download/
......@@ -12,96 +11,60 @@ setenv =
commands =
{envbindir}/django-admin.py test {posargs:tests}
[testenv:py25-1.2.X]
basepython = python2.5
deps =
Django==1.2.4
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py26-1.2.X]
basepython = python2.6
deps =
Django==1.2.4
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py27-1.2.X]
basepython = python2.7
deps =
Django==1.2.4
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py25-1.3.X]
basepython = python2.5
deps =
Django==1.3.1
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py26-1.3.X]
[testenv:py26-1.4.X]
basepython = python2.6
deps =
Django==1.3.1
Django==1.4.2
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py27-1.3.X]
[testenv:py27-1.4.X]
basepython = python2.7
deps =
Django==1.3.1
Django==1.4.2
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py25]
basepython = python2.5
[testenv:pypy-1.4.X]
basepython = pypy
deps =
Django==1.4
Django==1.4.2
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py26]
basepython = python2.6
deps =
Django==1.4
git+git://github.com/django/django.git@stable/1.5.x#egg=Django
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py27]
basepython = python2.7
deps =
Django==1.4
git+git://github.com/django/django.git@stable/1.5.x#egg=Django
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:pypy]
basepython = pypy
deps =
Django==1.4
git+git://github.com/django/django.git@stable/1.5.x#egg=Django
mock
django-staticfiles==1.2.1
unittest2
jinja2
[testenv:py33]
basepython = python3.3
deps =
jinja2
git+git://github.com/django/django.git@stable/1.5.x#egg=Django
[testenv:docs]
basepython = python2.7
changedir = docs
......
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