diff -Nru django-pipeline-1.6.8/AUTHORS django-pipeline-1.6.13/AUTHORS --- django-pipeline-1.6.8/AUTHORS 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/AUTHORS 2017-05-25 22:41:08.000000000 +0000 @@ -18,11 +18,13 @@ * Andy Kish * Ara Anjargolian * Arnar Yngvason + * Austin Pua * Axel Haustant * Balazs Kossovics * Ben Vinegar * Brad Pitcher * Brant Young + * Brawaga * Brian Montgomery * Bryan Chow * Caio Ariede @@ -59,6 +61,8 @@ * Jannis Leidel * Jared Scott * Jaromir Fojtu + * Jeff Held + * John Whitlock (@jwhitlock) * Jon Dufresne * Josh Braegger * Joshua Kehn @@ -91,6 +95,7 @@ * Sam Thomson * Sander Smits * Sander Steffann + * Sassan Haradji (@sassanh) * Sayed Raianul Kabir * Simon Lydell * Sirex @@ -101,12 +106,15 @@ * Tadas Dailyda * Teo Klestrup Röijezon * Thomas Parslow + * Tiago Espinha * Timothée Peignier * Tom Yam * Tomek Paczkowski * Trey Smith + * Vadym S. Khondar (@vskh) * Venelin Stoykov * Victor Shnayder * Wictor Olseryd + * Wismill * Zachary Kazanski * Zenobius Jiricek diff -Nru django-pipeline-1.6.8/CONTRIBUTING.rst django-pipeline-1.6.13/CONTRIBUTING.rst --- django-pipeline-1.6.8/CONTRIBUTING.rst 1970-01-01 00:00:00.000000000 +0000 +++ django-pipeline-1.6.13/CONTRIBUTING.rst 2017-05-25 22:41:08.000000000 +0000 @@ -0,0 +1,19 @@ +.. image:: https://jazzband.co/static/img/jazzband.svg + :target: https://jazzband.co/ + :alt: Jazzband + +This is a `Jazzband `_ project. By contributing you agree to abide by the `Contributor Code of Conduct `_ and follow the `guidelines `_. + +Contribute +========== + +#. Check for open issues or open a fresh issue to start a discussion around a + feature idea or a bug. There is a **contribute!** tag for issues that should be + ideal for people who are not very familiar with the codebase yet. +#. Fork the repository on Github to start making your changes on a topic branch. +#. Write a test which shows that the bug was fixed or that the feature works as expected. +#. Send a pull request and bug the maintainer until it gets merged and published. + Make sure to add yourself to *AUTHORS*. + +Otherwise, if you simply wants to suggest a feature or report a bug, create an issue : +https://github.com/jazzband/django-pipeline/issues diff -Nru django-pipeline-1.6.8/debian/changelog django-pipeline-1.6.13/debian/changelog --- django-pipeline-1.6.8/debian/changelog 2017-03-10 07:54:37.000000000 +0000 +++ django-pipeline-1.6.13/debian/changelog 2017-07-02 10:28:40.000000000 +0000 @@ -1,3 +1,10 @@ +django-pipeline (1.6.13-1) unstable; urgency=medium + + * New upstream version. + * Fixes FTBFS with Django 1.11. Closes: #865558. + + -- Brian May Sun, 02 Jul 2017 20:28:40 +1000 + django-pipeline (1.6.8-3) unstable; urgency=medium * Work around for random build failures. Closes: #851722. diff -Nru django-pipeline-1.6.8/debian/control django-pipeline-1.6.13/debian/control --- django-pipeline-1.6.8/debian/control 2017-01-13 06:40:55.000000000 +0000 +++ django-pipeline-1.6.13/debian/control 2017-07-02 10:28:21.000000000 +0000 @@ -18,7 +18,7 @@ python3-setuptools, python3-sphinx, python3-jsmin, -Standards-Version: 3.9.8 +Standards-Version: 4.0.0 Vcs-Browser: https://anonscm.debian.org/cgit/python-modules/packages/django-pipeline.git Vcs-Git: https://anonscm.debian.org/git/python-modules/packages/django-pipeline.git Homepage: https://github.com/cyberdelia/django-pipeline diff -Nru django-pipeline-1.6.8/debian/gbp.conf django-pipeline-1.6.13/debian/gbp.conf --- django-pipeline-1.6.8/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ django-pipeline-1.6.13/debian/gbp.conf 2017-07-02 10:05:03.000000000 +0000 @@ -0,0 +1,2 @@ +[DEFAULT] +debian-branch=debian/master diff -Nru django-pipeline-1.6.8/debian/.git-dpm django-pipeline-1.6.13/debian/.git-dpm --- django-pipeline-1.6.8/debian/.git-dpm 2016-08-05 23:57:17.000000000 +0000 +++ django-pipeline-1.6.13/debian/.git-dpm 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -# see git-dpm(1) from git-dpm package -e6c9304cf992e554867f46b51baa277aa9c8031d -e6c9304cf992e554867f46b51baa277aa9c8031d -a6e05d2f0d2ddbb4a6554def26c0571761315ab3 -a6e05d2f0d2ddbb4a6554def26c0571761315ab3 -django-pipeline_1.6.8.orig.tar.gz -2876cf4711198c5454849289db2c12ea40047a81 -52932 -debianTag="debian/%e%v" -patchedTag="patched/%e%v" -upstreamTag="upstream/%e%u" diff -Nru django-pipeline-1.6.8/debian/patches/0001-Remove-slimit-test.patch django-pipeline-1.6.13/debian/patches/0001-Remove-slimit-test.patch --- django-pipeline-1.6.8/debian/patches/0001-Remove-slimit-test.patch 2016-04-06 02:50:15.000000000 +0000 +++ django-pipeline-1.6.13/debian/patches/0001-Remove-slimit-test.patch 2017-07-02 10:05:41.000000000 +0000 @@ -1,4 +1,3 @@ -From e0ea5919780c975e959e0754d186a2c58096515a Mon Sep 17 00:00:00 2001 From: Brian May Date: Thu, 24 Mar 2016 09:03:33 +1100 Subject: Remove slimit test @@ -10,10 +9,10 @@ 1 file changed, 4 deletions(-) diff --git a/tests/tests/test_compressor.py b/tests/tests/test_compressor.py -index 4291b51..bd75504 100644 +index f774373..5446ee9 100644 --- a/tests/tests/test_compressor.py +++ b/tests/tests/test_compressor.py -@@ -225,10 +225,6 @@ class CompressorImplementationTest(TestCase): +@@ -228,10 +228,6 @@ class CompressorImplementationTest(TestCase): self._test_compressor('pipeline.compressors.jsmin.JSMinCompressor', 'js', 'pipeline/compressors/jsmin.js') diff -Nru django-pipeline-1.6.8/debian/patches/0002-Change-default-compressors.patch django-pipeline-1.6.13/debian/patches/0002-Change-default-compressors.patch --- django-pipeline-1.6.8/debian/patches/0002-Change-default-compressors.patch 2016-04-06 02:50:15.000000000 +0000 +++ django-pipeline-1.6.13/debian/patches/0002-Change-default-compressors.patch 2017-07-02 10:05:41.000000000 +0000 @@ -1,4 +1,3 @@ -From e4b97bb92c2b60eace913fc18e0a23fc44d04b9c Mon Sep 17 00:00:00 2001 From: Brian May Date: Thu, 24 Mar 2016 09:14:37 +1100 Subject: Change default compressors @@ -9,7 +8,7 @@ 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipeline/conf.py b/pipeline/conf.py -index b6dd5b7..6d51b65 100644 +index 085a1e2..26f9cb0 100644 --- a/pipeline/conf.py +++ b/pipeline/conf.py @@ -25,8 +25,8 @@ DEFAULTS = { diff -Nru django-pipeline-1.6.8/debian/patches/0003-Define-kwarg_name-in-pipeline_settings-class.patch django-pipeline-1.6.13/debian/patches/0003-Define-kwarg_name-in-pipeline_settings-class.patch --- django-pipeline-1.6.8/debian/patches/0003-Define-kwarg_name-in-pipeline_settings-class.patch 2016-08-05 23:57:17.000000000 +0000 +++ django-pipeline-1.6.13/debian/patches/0003-Define-kwarg_name-in-pipeline_settings-class.patch 2017-07-02 10:06:53.000000000 +0000 @@ -1,19 +1,20 @@ -Subject: Define kwarg_name in pipeline_settings class -Author: Thomas Goirand -Forwarded: no -Bug-Debian: https://bugs.debian.org/828653 +From: Thomas Goirand Date: Fri, 5 Aug 2016 11:30:38 +0000 -Last-Update: 2016-08-05 +Subject: Define kwarg_name in pipeline_settings class + +--- + tests/utils.py | 1 + + 1 file changed, 1 insertion(+) diff --git a/tests/utils.py b/tests/utils.py -index bf1c7ca..c3501dc 100644 +index 15f5573..d8a838e 100644 --- a/tests/utils.py +++ b/tests/utils.py -@@ -16,6 +16,7 @@ def _(path): +@@ -17,6 +17,7 @@ def _(path): class pipeline_settings(override_settings): + kwarg_name = None def __init__(self, **kwargs): - self.options = {'PIPELINE': kwargs} - + if django.VERSION[:2] >= (1, 10): + # Django 1.10's override_settings inherits from TestContextDecorator diff -Nru django-pipeline-1.6.8/django_pipeline.egg-info/PKG-INFO django-pipeline-1.6.13/django_pipeline.egg-info/PKG-INFO --- django-pipeline-1.6.8/django_pipeline.egg-info/PKG-INFO 2016-03-31 03:55:37.000000000 +0000 +++ django-pipeline-1.6.13/django_pipeline.egg-info/PKG-INFO 2017-05-25 22:42:20.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: django-pipeline -Version: 1.6.8 +Version: 1.6.13 Summary: Pipeline is an asset packaging library for Django. Home-page: https://github.com/jazzband/django-pipeline Author: Timothée Peignier @@ -9,13 +9,21 @@ Description: Pipeline ======== - .. image:: https://secure.travis-ci.org/jazzband/django-pipeline.png + .. image:: https://travis-ci.org/jazzband/django-pipeline.svg?branch=master :alt: Build Status :target: http://travis-ci.org/jazzband/django-pipeline + .. image:: https://coveralls.io/repos/github/jazzband/django-pipeline/badge.svg?branch=master + :alt: Code Coverage + :target: https://coveralls.io/github/jazzband/django-pipeline?branch=master + .. image:: https://jazzband.co/static/img/badge.svg - :alt: Jazzband - :target: https://jazzband.co/ + :alt: Jazzband + :target: https://jazzband.co/ + + .. image:: https://badge.fury.io/py/django-pipeline.svg + :alt: PYPI + :target: https://badge.fury.io/py/django-pipeline Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript template support, @@ -34,7 +42,7 @@ ------------- For documentation, usage, and examples, see : - https://django-pipeline.readthedocs.org + https://django-pipeline.readthedocs.io .. :changelog: @@ -42,6 +50,41 @@ History ======= + 1.6.13 + ====== + + * Fix forward-slashed paths on Windows. Thanks to @etiago + * Fix CSS URL detector to match quotes correctly. Thanks to @vskh + * Add a compiler_options dict to compile, to allow passing options to custom + compilers. Thanks to @sassanh + * Verify support for Django 1.11. Thanks to @jwhitlock + + 1.6.12 + ====== + + * Supports Django 1.11 + * Fix a bug with os.rename on windows. Thanks to @wismill + * Fix to view compile error if happens. Thanks to @brawaga + * Add support for Pipeline CSS/JS packages in forms and widgets. Thanks to @chipx86 + + 1.6.11 + ====== + + * Fix performance regression. Thanks to Christian Hammond. + + 1.6.10 + ====== + + * Added Django 1.10 compatiblity issues. Thanks to Austin Pua and Silvan Spross. + * Documentation improvements. Thanks to Chris Streeter. + + 1.6.9 + ===== + + * Various build improvements. + * Improved setup.py classifiers. Thanks to Sobolev Nikita. + * Documentation improvements. Thanks to Adam Chainz. + 1.6.8 ===== @@ -116,12 +159,28 @@ * Drop support for Python 2.6. * **BACKWARD INCOMPATIBLE** : Change configuration settings. +Keywords: django pipeline asset compiling concatenation compression packaging Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment +Classifier: Framework :: Django +Classifier: Framework :: Django :: 1.6 +Classifier: Framework :: Django :: 1.7 +Classifier: Framework :: Django :: 1.8 +Classifier: Framework :: Django :: 1.9 +Classifier: Framework :: Django :: 1.10 +Classifier: Framework :: Django :: 1.11 Classifier: Intended Audience :: Developers -Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Utilities +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content diff -Nru django-pipeline-1.6.8/django_pipeline.egg-info/requires.txt django-pipeline-1.6.13/django_pipeline.egg-info/requires.txt --- django-pipeline-1.6.8/django_pipeline.egg-info/requires.txt 1970-01-01 00:00:00.000000000 +0000 +++ django-pipeline-1.6.13/django_pipeline.egg-info/requires.txt 2017-05-25 22:42:20.000000000 +0000 @@ -0,0 +1 @@ +futures>=2.1.3 diff -Nru django-pipeline-1.6.8/django_pipeline.egg-info/SOURCES.txt django-pipeline-1.6.13/django_pipeline.egg-info/SOURCES.txt --- django-pipeline-1.6.8/django_pipeline.egg-info/SOURCES.txt 2016-03-31 03:55:41.000000000 +0000 +++ django-pipeline-1.6.13/django_pipeline.egg-info/SOURCES.txt 2017-05-25 22:42:20.000000000 +0000 @@ -1,4 +1,5 @@ AUTHORS +CONTRIBUTING.rst HISTORY.rst LICENSE MANIFEST.in @@ -9,6 +10,7 @@ django_pipeline.egg-info/SOURCES.txt django_pipeline.egg-info/dependency_links.txt django_pipeline.egg-info/not-zip-safe +django_pipeline.egg-info/requires.txt django_pipeline.egg-info/top_level.txt docs/Makefile docs/compilers.rst @@ -28,6 +30,7 @@ pipeline/conf.py pipeline/exceptions.py pipeline/finders.py +pipeline/forms.py pipeline/glob.py pipeline/manifest.py pipeline/middleware.py @@ -67,7 +70,6 @@ pipeline/templatetags/pipeline.py tests/__init__.py tests/models.py -tests/package.json tests/settings.py tests/urls.py tests/utils.py @@ -113,7 +115,6 @@ tests/assets/templates/photo/detail.jst tests/assets/templates/photo/list.jst tests/assets/templates/video/detail.jst -tests/scripts/npm_install.py tests/templates/empty.html tests/templates/index.html tests/tests/__init__.py @@ -122,6 +123,7 @@ tests/tests/test_compiler.py tests/tests/test_compressor.py tests/tests/test_conf.py +tests/tests/test_forms.py tests/tests/test_glob.py tests/tests/test_middleware.py tests/tests/test_packager.py diff -Nru django-pipeline-1.6.8/docs/compressors.rst django-pipeline-1.6.13/docs/compressors.rst --- django-pipeline-1.6.8/docs/compressors.rst 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/docs/compressors.rst 2017-05-25 22:41:08.000000000 +0000 @@ -161,7 +161,7 @@ SlimIt compressor ================= -The slimit compressor uses `SlimIt `_ to +The slimit compressor uses `SlimIt `_ to compress javascripts. To use it add this to your ``PIPELINE['JS_COMPRESSOR']`` :: diff -Nru django-pipeline-1.6.8/docs/configuration.rst django-pipeline-1.6.13/docs/configuration.rst --- django-pipeline-1.6.8/docs/configuration.rst 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/docs/configuration.rst 2017-05-25 22:41:08.000000000 +0000 @@ -123,6 +123,15 @@ Defaults to ``True``. +``compiler_options`` +.................... + +**Optional** + +A dictionary passed to compiler's ``compile_file`` method as kwargs. None of default compilers use it currently. It's to be used by custom compilers in case they need some special parameters. + +Defaults to ``{}``. + Other settings -------------- @@ -143,7 +152,7 @@ .. note:: - this only work when PIPELINE_ENABLED is False. + This only applies when ``PIPELINE_ENABLED`` is ``False``. ``SHOW_ERRORS_INLINE`` ...................... @@ -298,4 +307,7 @@ This safety wrapper, make it difficult to pollute the global namespace by accident and improve performance. -You can override this behavior by setting ``DISABLE_WRAPPER`` to ``True``. +You can override this behavior by setting ``DISABLE_WRAPPER`` to ``True``. If you want to use your own wrapper, change +the ``JS_WRAPPER`` setting. For example: :: + + JS_WRAPPER = "(function(){stuff();%s})();" diff -Nru django-pipeline-1.6.8/docs/conf.py django-pipeline-1.6.13/docs/conf.py --- django-pipeline-1.6.8/docs/conf.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/docs/conf.py 2017-05-25 22:41:08.000000000 +0000 @@ -51,7 +51,7 @@ # The short X.Y version. version = '1.6' # The full version, including alpha/beta/rc tags. -release = '1.6.8' +release = '1.6.13' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -Nru django-pipeline-1.6.8/docs/usage.rst django-pipeline-1.6.13/docs/usage.rst --- django-pipeline-1.6.8/docs/usage.rst 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/docs/usage.rst 2017-05-25 22:41:08.000000000 +0000 @@ -40,6 +40,49 @@ {% stylesheet 'stats' %} {% javascript 'scripts' %} + +Form Media +========== + +Django forms and widgets can specify individual CSS or JavaScript files to +include on a page by defining a ``Form.Media`` class with ``css`` and ``js`` +attributes. + +Pipeline builds upon this by allowing packages to be listed in +``css_packages`` and ``js_packages``. This is equivalent to manually including +these packages in a page's template using the template tags. + +To use these, just have your form or widget's ``Media`` class inherit from +``pipeline.forms.PipelineFormMedia`` and define ``css_packages`` and +``js_packages``. You can also continue to reference individual CSS/JavaScript +files using the original ``css``/``js`` attributes, if needed. + +Note that unlike the template tags, you cannot customize the HTML for +referencing these files. The ``pipeline/css.html`` and ``pipeline/js.html`` +files will not be used. Django takes care of generating the HTML for form and +widget media. + + +Example +------- + +.. code-block:: python + + from django import forms + from pipeline.forms import PipelineFormMedia + + + class MyForm(forms.Form): + ... + + class Media(PipelineFormMedia): + css_packages = { + 'all': ('my-styles',) + } + js_packages = ('my-scripts',) + js = ('https://cdn.example.com/some-script.js',) + + Collect static ============== @@ -47,7 +90,7 @@ STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage' -Then when you run ``collectstatic`` command, your CSS and your javascripts will be compressed in the same time :: +Then when you run ``collectstatic`` command, your CSS and your javascripts will be compressed at the same time :: $ python manage.py collectstatic @@ -78,7 +121,7 @@ ============== Pipeline provide a way to add your javascripts and stylesheets files to a -cache-manifest via `Manifesto `_. +cache-manifest via `Manifesto `_. To do so, you just need to add manifesto app to your ``INSTALLED_APPS``. diff -Nru django-pipeline-1.6.8/HISTORY.rst django-pipeline-1.6.13/HISTORY.rst --- django-pipeline-1.6.8/HISTORY.rst 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/HISTORY.rst 2017-05-25 22:41:08.000000000 +0000 @@ -3,6 +3,41 @@ History ======= +1.6.13 +====== + +* Fix forward-slashed paths on Windows. Thanks to @etiago +* Fix CSS URL detector to match quotes correctly. Thanks to @vskh +* Add a compiler_options dict to compile, to allow passing options to custom + compilers. Thanks to @sassanh +* Verify support for Django 1.11. Thanks to @jwhitlock + +1.6.12 +====== + +* Supports Django 1.11 +* Fix a bug with os.rename on windows. Thanks to @wismill +* Fix to view compile error if happens. Thanks to @brawaga +* Add support for Pipeline CSS/JS packages in forms and widgets. Thanks to @chipx86 + +1.6.11 +====== + +* Fix performance regression. Thanks to Christian Hammond. + +1.6.10 +====== + +* Added Django 1.10 compatiblity issues. Thanks to Austin Pua and Silvan Spross. +* Documentation improvements. Thanks to Chris Streeter. + +1.6.9 +===== + +* Various build improvements. +* Improved setup.py classifiers. Thanks to Sobolev Nikita. +* Documentation improvements. Thanks to Adam Chainz. + 1.6.8 ===== diff -Nru django-pipeline-1.6.8/MANIFEST.in django-pipeline-1.6.13/MANIFEST.in --- django-pipeline-1.6.8/MANIFEST.in 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/MANIFEST.in 2017-05-25 22:41:08.000000000 +0000 @@ -1,6 +1,6 @@ recursive-include pipeline/templates *.html *.jinja recursive-include pipeline/jinja2 *.html *.jinja -include AUTHORS LICENSE README.rst HISTORY.rst +include AUTHORS LICENSE README.rst HISTORY.rst CONTRIBUTING.rst recursive-include tests * recursive-exclude tests *.pyc *.pyo recursive-exclude tests/node_modules * @@ -8,3 +8,4 @@ recursive-exclude tests/npm * include docs/Makefile docs/make.bat docs/conf.py recursive-include docs *.rst +exclude package.json requirements.txt tox.ini diff -Nru django-pipeline-1.6.8/pipeline/collector.py django-pipeline-1.6.13/pipeline/collector.py --- django-pipeline-1.6.8/pipeline/collector.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/collector.py 2017-05-25 22:41:08.000000000 +0000 @@ -4,6 +4,7 @@ from collections import OrderedDict +import django from django.contrib.staticfiles import finders from django.contrib.staticfiles.storage import staticfiles_storage from django.utils import six @@ -19,6 +20,11 @@ storage = staticfiles_storage self.storage = storage + def _get_modified_time(self, storage, prefixed_path): + if django.VERSION[:2] >= (1, 10): + return storage.get_modified_time(prefixed_path) + return storage.modified_time(prefixed_path) + def clear(self, path=""): dirs, files = self.storage.listdir(path) for f in files: @@ -65,14 +71,14 @@ if self.storage.exists(prefixed_path): try: # When was the target file modified last time? - target_last_modified = self.storage.modified_time(prefixed_path) + target_last_modified = self._get_modified_time(self.storage, prefixed_path) except (OSError, NotImplementedError, AttributeError): # The storage doesn't support ``modified_time`` or failed pass else: try: # When was the source file modified last time? - source_last_modified = source_storage.modified_time(path) + source_last_modified = self._get_modified_time(source_storage, path) except (OSError, NotImplementedError, AttributeError): pass else: diff -Nru django-pipeline-1.6.8/pipeline/compilers/__init__.py django-pipeline-1.6.13/pipeline/compilers/__init__.py --- django-pipeline-1.6.8/pipeline/compilers/__init__.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/compilers/__init__.py 2017-05-25 22:41:08.000000000 +0000 @@ -1,6 +1,7 @@ from __future__ import unicode_literals import os +import shutil import subprocess from tempfile import NamedTemporaryFile @@ -26,7 +27,7 @@ def compilers(self): return [to_class(compiler) for compiler in settings.COMPILERS] - def compile(self, paths, force=False): + def compile(self, paths, compiler_options={}, force=False): def _compile(input_path): for compiler in self.compilers: compiler = compiler(verbose=self.verbose, storage=self.storage) @@ -38,7 +39,8 @@ outfile = compiler.output_path(infile, compiler.output_extension) outdated = compiler.is_outdated(infile, outfile) compiler.compile_file(infile, outfile, - outdated=outdated, force=force) + outdated=outdated, force=force, + **compiler_options) return compiler.output_path(input_path, compiler.output_extension) else: @@ -112,6 +114,9 @@ else: argument_list.extend(flattening_arg) + # The first element in argument_list is the program that will be executed; if it is '', then + # a PermissionError will be raised. Thus empty arguments are filtered out from argument_list + argument_list = filter(None, argument_list) stdout = None try: # We always catch stdout in a file, but we may not have a use for it. @@ -143,6 +148,6 @@ # Decide what to do with captured stdout. if stdout: if stdout_captured: - os.rename(stdout.name, os.path.join(cwd or os.curdir, stdout_captured)) + shutil.move(stdout.name, os.path.join(cwd or os.curdir, stdout_captured)) else: os.remove(stdout.name) diff -Nru django-pipeline-1.6.8/pipeline/compressors/__init__.py django-pipeline-1.6.13/pipeline/compressors/__init__.py --- django-pipeline-1.6.8/pipeline/compressors/__init__.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/compressors/__init__.py 2017-05-25 22:41:08.000000000 +0000 @@ -16,7 +16,7 @@ from pipeline.exceptions import CompressorError from pipeline.utils import to_class, relpath, set_std_streams_blocking -URL_DETECTOR = r"""url\((['"]){0,1}\s*(.*?)["']{0,1}\)""" +URL_DETECTOR = r"""url\((['"]?)\s*(.*?)\1\)""" URL_REPLACER = r"""url\(__EMBED__(.+?)(\?\d+)?\)""" NON_REWRITABLE_URL = re.compile(r'^(#|http:|https:|data:|//)') @@ -62,7 +62,7 @@ js = js + self.compile_templates(templates) if not settings.DISABLE_WRAPPER: - js = "(function() {\n%s\n}).call(this);" % js + js = settings.JS_WRAPPER % js compressor = self.js_compressor if compressor: diff -Nru django-pipeline-1.6.8/pipeline/conf.py django-pipeline-1.6.13/pipeline/conf.py --- django-pipeline-1.6.8/pipeline/conf.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/conf.py 2017-05-25 22:41:08.000000000 +0000 @@ -38,6 +38,7 @@ 'TEMPLATE_SEPARATOR': "_", 'DISABLE_WRAPPER': False, + 'JS_WRAPPER': "(function() {\n%s\n}).call(this);", 'CSSTIDY_BINARY': '/usr/bin/env csstidy', 'CSSTIDY_ARGUMENTS': '--template=highest', @@ -77,8 +78,6 @@ 'LESS_BINARY': '/usr/bin/env lessc', 'LESS_ARGUMENTS': '', - 'DISABLE_WRAPPER': False, - 'MIMETYPES': ( (b'text/coffeescript', '.coffee'), (b'text/less', '.less'), diff -Nru django-pipeline-1.6.8/pipeline/finders.py django-pipeline-1.6.13/pipeline/finders.py --- django-pipeline-1.6.8/pipeline/finders.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/finders.py 2017-05-25 22:41:08.000000000 +0000 @@ -4,6 +4,7 @@ from django.contrib.staticfiles.finders import BaseFinder, BaseStorageFinder, find, \ AppDirectoriesFinder as DjangoAppDirectoriesFinder, FileSystemFinder as DjangoFileSystemFinder from django.utils._os import safe_join +from os.path import normpath from pipeline.conf import settings @@ -28,7 +29,7 @@ """ matches = [] for elem in chain(settings.STYLESHEETS.values(), settings.JAVASCRIPT.values()): - if elem['output_filename'] == path: + if normpath(elem['output_filename']) == normpath(path): match = safe_join(settings.PIPELINE_ROOT, path) if not all: return match diff -Nru django-pipeline-1.6.8/pipeline/forms.py django-pipeline-1.6.13/pipeline/forms.py --- django-pipeline-1.6.8/pipeline/forms.py 1970-01-01 00:00:00.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/forms.py 2017-05-25 22:41:08.000000000 +0000 @@ -0,0 +1,273 @@ +"""Support for referencing Pipeline packages in forms and widgets.""" + +from __future__ import unicode_literals + +from django.contrib.staticfiles.storage import staticfiles_storage +from django.utils import six +from django.utils.functional import cached_property + +from .collector import default_collector +from .conf import settings +from .packager import Packager + + +class PipelineFormMediaProperty(object): + """A property that converts Pipeline packages to lists of files. + + This is used behind the scenes for any Media classes that subclass + :py:class:`PipelineFormMedia`. When accessed, it converts any Pipeline + packages into lists of media files and returns or forwards on lookups to + that list. + """ + + def __init__(self, get_media_files_func, media_cls, extra_files): + """Initialize the property. + + Args: + get_media_files_func (callable): + The function to call to generate the media files. + + media_cls (type): + The Media class owning the property. + + extra_files (object): + Files listed in the original ``css`` or ``js`` attribute on + the Media class. + """ + self._get_media_files_func = get_media_files_func + self._media_cls = media_cls + self._extra_files = extra_files + + @cached_property + def _media_files(self): + """The media files represented by the property.""" + return self._get_media_files_func(self._media_cls, self._extra_files) + + def __get__(self, *args, **kwargs): + """Return the media files when accessed as an attribute. + + This is called when accessing the attribute directly through the + Media class (for example, ``Media.css``). It returns the media files + directly. + + Args: + *args (tuple, unused): + Unused positional arguments. + + **kwargs (dict, unused): + Unused keyword arguments. + + Returns: + object: + The list or dictionary containing the media files definition. + """ + return self._media_files + + def __getattr__(self, attr_name): + """Return an attribute on the media files definition. + + This is called when accessing an attribute that doesn't otherwise + exist in the property's dictionary. The call is forwarded onto the + media files definition. + + Args: + attr_name (unicode): + The attribute name. + + Returns: + object: + The attribute value. + + Raises: + AttributeError: + An attribute with this name could not be found. + """ + return getattr(self._media_files, attr_name) + + def __iter__(self): + """Iterate through the media files definition. + + This is called when attempting to iterate over this property. It + iterates over the media files definition instead. + + Yields: + object: + Each entry in the media files definition. + """ + return iter(self._media_files) + + +class PipelineFormMediaMetaClass(type): + """Metaclass for the PipelineFormMedia class. + + This is responsible for converting CSS/JavaScript packages defined in + Pipeline into lists of files to include on a page. It handles access to the + :py:attr:`css` and :py:attr:`js` attributes on the class, generating a + list of files to return based on the Pipelined packages and individual + files listed in the :py:attr:`css`/:py:attr:`css_packages` or + :py:attr:`js`/:py:attr:`js_packages` attributes. + """ + + def __new__(cls, name, bases, attrs): + """Construct the class. + + Args: + name (bytes): + The name of the class. + + bases (tuple): + The base classes for the class. + + attrs (dict): + The attributes going into the class. + + Returns: + type: + The new class. + """ + new_class = super(PipelineFormMediaMetaClass, cls).__new__( + cls, name, bases, attrs) + + # If we define any packages, we'll need to use our special + # PipelineFormMediaProperty class. We use this instead of intercepting + # in __getattribute__ because Django does not access them through + # normal properpty access. Instead, grabs the Media class's __dict__ + # and accesses them from there. By using these special properties, we + # can handle direct access (Media.css) and dictionary-based access + # (Media.__dict__['css']). + if 'css_packages' in attrs: + new_class.css = PipelineFormMediaProperty( + cls._get_css_files, new_class, attrs.get('css') or {}) + + if 'js_packages' in attrs: + new_class.js = PipelineFormMediaProperty( + cls._get_js_files, new_class, attrs.get('js') or []) + + return new_class + + def _get_css_files(cls, extra_files): + """Return all CSS files from the Media class. + + Args: + extra_files (dict): + The contents of the Media class's original :py:attr:`css` + attribute, if one was provided. + + Returns: + dict: + The CSS media types and files to return for the :py:attr:`css` + attribute. + """ + packager = Packager() + css_packages = getattr(cls, 'css_packages', {}) + + return dict( + (media_target, + cls._get_media_files(packager=packager, + media_packages=media_packages, + media_type='css', + extra_files=extra_files.get(media_target, + []))) + for media_target, media_packages in six.iteritems(css_packages) + ) + + def _get_js_files(cls, extra_files): + """Return all JavaScript files from the Media class. + + Args: + extra_files (list): + The contents of the Media class's original :py:attr:`js` + attribute, if one was provided. + + Returns: + list: + The JavaScript files to return for the :py:attr:`js` attribute. + """ + return cls._get_media_files( + packager=Packager(), + media_packages=getattr(cls, 'js_packages', {}), + media_type='js', + extra_files=extra_files) + + def _get_media_files(cls, packager, media_packages, media_type, + extra_files): + """Return source or output media files for a list of packages. + + This will go through the media files belonging to the provided list + of packages referenced in a Media class and return the output files + (if Pipeline is enabled) or the source files (if not enabled). + + Args: + packager (pipeline.packager.Packager): + The packager responsible for media compilation for this type + of package. + + media_packages (list of unicode): + The list of media packages referenced in Media to compile or + return. + + extra_files (list of unicode): + The list of extra files to include in the result. This would + be the list stored in the Media class's original :py:attr:`css` + or :py:attr:`js` attributes. + + Returns: + list: + The list of media files for the given packages. + """ + source_files = list(extra_files) + + if (not settings.PIPELINE_ENABLED and + settings.PIPELINE_COLLECTOR_ENABLED): + default_collector.collect() + + for media_package in media_packages: + package = packager.package_for(media_type, media_package) + + if settings.PIPELINE_ENABLED: + source_files.append( + staticfiles_storage.url(package.output_filename)) + else: + source_files += packager.compile(package.paths) + + return source_files + + +@six.add_metaclass(PipelineFormMediaMetaClass) +class PipelineFormMedia(object): + """Base class for form or widget Media classes that use Pipeline packages. + + Forms or widgets that need custom CSS or JavaScript media on a page can + define a standard :py:class:`Media` class that subclasses this class, + listing the CSS or JavaScript packages in :py:attr:`css_packages` and + :py:attr:`js_packages` attributes. These are formatted the same as the + standard :py:attr:`css` and :py:attr:`js` attributes, but reference + Pipeline package names instead of individual source files. + + If Pipeline is enabled, these will expand to the output files for the + packages. Otherwise, these will expand to the list of source files for the + packages. + + Subclasses can also continue to define :py:attr:`css` and :py:attr:`js` + attributes, which will be returned along with the other output/source + files. + + Example: + + from django import forms + from pipeline.forms import PipelineFormMedia + + + class MyForm(forms.Media): + ... + + class Media(PipelineFormMedia): + css_packages = { + 'all': ('my-form-styles-package', + 'other-form-styles-package'), + 'print': ('my-form-print-styles-package',), + } + + js_packages = ('my-form-scripts-package',) + js = ('some-file.js',) + """ diff -Nru django-pipeline-1.6.8/pipeline/middleware.py django-pipeline-1.6.13/pipeline/middleware.py --- django-pipeline-1.6.8/pipeline/middleware.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/middleware.py 2017-05-25 22:41:08.000000000 +0000 @@ -6,9 +6,16 @@ from pipeline.conf import settings +try: + # Support for Django 1.10 new MIDDLEWARE setting + from django.utils.deprecation import MiddlewareMixin +except ImportError: # Django < 1.10 + MiddlewareMixin = object -class MinifyHTMLMiddleware(object): - def __init__(self): + +class MinifyHTMLMiddleware(MiddlewareMixin): + def __init__(self, *args, **kwargs): + super(MinifyHTMLMiddleware, self).__init__(*args, **kwargs) if not settings.PIPELINE_ENABLED: raise MiddlewareNotUsed diff -Nru django-pipeline-1.6.8/pipeline/packager.py django-pipeline-1.6.13/pipeline/packager.py --- django-pipeline-1.6.8/pipeline/packager.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/packager.py 2017-05-25 22:41:08.000000000 +0000 @@ -59,6 +59,10 @@ def manifest(self): return self.config.get('manifest', True) + @property + def compiler_options(self): + return self.config.get('compiler_options', {}) + class Packager(object): def __init__(self, storage=None, verbose=False, css_packages=None, js_packages=None): @@ -95,14 +99,22 @@ output_filename=package.output_filename, variant=package.variant, **kwargs) - def compile(self, paths, force=False): - return self.compiler.compile(paths, force=force) + def compile(self, paths, compiler_options={}, force=False): + return self.compiler.compile( + paths, + compiler_options=compiler_options, + force=force, + ) def pack(self, package, compress, signal, **kwargs): output_filename = package.output_filename if self.verbose: print("Saving: %s" % output_filename) - paths = self.compile(package.paths, force=True) + paths = self.compile( + package.paths, + compiler_options=package.compiler_options, + force=True, + ) content = compress(paths, **kwargs) self.save_file(output_filename, content) signal.send(sender=self, package=package, **kwargs) diff -Nru django-pipeline-1.6.8/pipeline/templatetags/pipeline.py django-pipeline-1.6.13/pipeline/templatetags/pipeline.py --- django-pipeline-1.6.8/pipeline/templatetags/pipeline.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/pipeline/templatetags/pipeline.py 2017-05-25 22:41:08.000000000 +0000 @@ -116,12 +116,12 @@ return method(package, paths, templates=templates) def render_error(self, package_type, package_name, e): - return render_to_string('pipeline/compile_error.html', Context({ + return render_to_string('pipeline/compile_error.html', { 'package_type': package_type, 'package_name': package_name, 'command': subprocess.list2cmdline(e.command), 'errors': e.error_output, - })) + }) class StylesheetNode(PipelineMixin, template.Node): diff -Nru django-pipeline-1.6.8/PKG-INFO django-pipeline-1.6.13/PKG-INFO --- django-pipeline-1.6.8/PKG-INFO 2016-03-31 03:55:41.000000000 +0000 +++ django-pipeline-1.6.13/PKG-INFO 2017-05-25 22:42:21.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: django-pipeline -Version: 1.6.8 +Version: 1.6.13 Summary: Pipeline is an asset packaging library for Django. Home-page: https://github.com/jazzband/django-pipeline Author: Timothée Peignier @@ -9,13 +9,21 @@ Description: Pipeline ======== - .. image:: https://secure.travis-ci.org/jazzband/django-pipeline.png + .. image:: https://travis-ci.org/jazzband/django-pipeline.svg?branch=master :alt: Build Status :target: http://travis-ci.org/jazzband/django-pipeline + .. image:: https://coveralls.io/repos/github/jazzband/django-pipeline/badge.svg?branch=master + :alt: Code Coverage + :target: https://coveralls.io/github/jazzband/django-pipeline?branch=master + .. image:: https://jazzband.co/static/img/badge.svg - :alt: Jazzband - :target: https://jazzband.co/ + :alt: Jazzband + :target: https://jazzband.co/ + + .. image:: https://badge.fury.io/py/django-pipeline.svg + :alt: PYPI + :target: https://badge.fury.io/py/django-pipeline Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript template support, @@ -34,7 +42,7 @@ ------------- For documentation, usage, and examples, see : - https://django-pipeline.readthedocs.org + https://django-pipeline.readthedocs.io .. :changelog: @@ -42,6 +50,41 @@ History ======= + 1.6.13 + ====== + + * Fix forward-slashed paths on Windows. Thanks to @etiago + * Fix CSS URL detector to match quotes correctly. Thanks to @vskh + * Add a compiler_options dict to compile, to allow passing options to custom + compilers. Thanks to @sassanh + * Verify support for Django 1.11. Thanks to @jwhitlock + + 1.6.12 + ====== + + * Supports Django 1.11 + * Fix a bug with os.rename on windows. Thanks to @wismill + * Fix to view compile error if happens. Thanks to @brawaga + * Add support for Pipeline CSS/JS packages in forms and widgets. Thanks to @chipx86 + + 1.6.11 + ====== + + * Fix performance regression. Thanks to Christian Hammond. + + 1.6.10 + ====== + + * Added Django 1.10 compatiblity issues. Thanks to Austin Pua and Silvan Spross. + * Documentation improvements. Thanks to Chris Streeter. + + 1.6.9 + ===== + + * Various build improvements. + * Improved setup.py classifiers. Thanks to Sobolev Nikita. + * Documentation improvements. Thanks to Adam Chainz. + 1.6.8 ===== @@ -116,12 +159,28 @@ * Drop support for Python 2.6. * **BACKWARD INCOMPATIBLE** : Change configuration settings. +Keywords: django pipeline asset compiling concatenation compression packaging Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment +Classifier: Framework :: Django +Classifier: Framework :: Django :: 1.6 +Classifier: Framework :: Django :: 1.7 +Classifier: Framework :: Django :: 1.8 +Classifier: Framework :: Django :: 1.9 +Classifier: Framework :: Django :: 1.10 +Classifier: Framework :: Django :: 1.11 Classifier: Intended Audience :: Developers -Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Utilities +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content diff -Nru django-pipeline-1.6.8/README.rst django-pipeline-1.6.13/README.rst --- django-pipeline-1.6.8/README.rst 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/README.rst 2017-05-25 22:41:08.000000000 +0000 @@ -1,13 +1,21 @@ Pipeline ======== -.. image:: https://secure.travis-ci.org/jazzband/django-pipeline.png +.. image:: https://travis-ci.org/jazzband/django-pipeline.svg?branch=master :alt: Build Status :target: http://travis-ci.org/jazzband/django-pipeline +.. image:: https://coveralls.io/repos/github/jazzband/django-pipeline/badge.svg?branch=master + :alt: Code Coverage + :target: https://coveralls.io/github/jazzband/django-pipeline?branch=master + .. image:: https://jazzband.co/static/img/badge.svg - :alt: Jazzband - :target: https://jazzband.co/ + :alt: Jazzband + :target: https://jazzband.co/ + +.. image:: https://badge.fury.io/py/django-pipeline.svg + :alt: PYPI + :target: https://badge.fury.io/py/django-pipeline Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript template support, @@ -26,4 +34,4 @@ ------------- For documentation, usage, and examples, see : -https://django-pipeline.readthedocs.org +https://django-pipeline.readthedocs.io diff -Nru django-pipeline-1.6.8/setup.cfg django-pipeline-1.6.13/setup.cfg --- django-pipeline-1.6.8/setup.cfg 2016-03-31 03:55:41.000000000 +0000 +++ django-pipeline-1.6.13/setup.cfg 2017-05-25 22:42:21.000000000 +0000 @@ -2,7 +2,7 @@ universal = 1 [egg_info] -tag_date = 0 tag_build = +tag_date = 0 tag_svn_revision = 0 diff -Nru django-pipeline-1.6.8/setup.py django-pipeline-1.6.13/setup.py --- django-pipeline-1.6.8/setup.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/setup.py 2017-05-25 22:41:08.000000000 +0000 @@ -10,7 +10,7 @@ setup( name='django-pipeline', - version='1.6.8', + version='1.6.13', description='Pipeline is an asset packaging library for Django.', long_description=io.open('README.rst', encoding='utf-8').read() + '\n\n' + io.open('HISTORY.rst', encoding='utf-8').read(), @@ -22,14 +22,31 @@ zip_safe=False, install_requires=install_requires, include_package_data=True, + keywords=('django pipeline asset compiling concatenation compression' + ' packaging'), classifiers=[ + 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', + 'Framework :: Django', + 'Framework :: Django :: 1.6', + 'Framework :: Django :: 1.7', + 'Framework :: Django :: 1.8', + 'Framework :: Django :: 1.9', + 'Framework :: Django :: 1.10', + 'Framework :: Django :: 1.11', 'Intended Audience :: Developers', - 'Development Status :: 5 - Production/Stable', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', + 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Utilities', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', ] ) diff -Nru django-pipeline-1.6.8/tests/assets/css/urls.css django-pipeline-1.6.13/tests/assets/css/urls.css --- django-pipeline-1.6.8/tests/assets/css/urls.css 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/assets/css/urls.css 2017-05-25 22:41:08.000000000 +0000 @@ -1,3 +1,6 @@ +.embedded-url-svg { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E% 3C/svg%3E"); +} @font-face { font-family: 'Pipeline'; src: url('../fonts/pipeline.eot'); diff -Nru django-pipeline-1.6.8/tests/package.json django-pipeline-1.6.13/tests/package.json --- django-pipeline-1.6.8/tests/package.json 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/package.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -{ - "name": "django-pipeline-tests", - "private": true, - "version": "1.0.0", - "description": "Pipeline is an asset packaging library for Django.", - "author": "Timothée Peignier ", - "license": "MIT", - "readmeFilename": "../README.rst", - "repository": { - "type": "git", - "url": "git://github.com/jazzband/django-pipeline.git" - }, - "dependencies": { - "babel-cli": "^6.4.5", - "babel-preset-es2015": "^6.3.13", - "coffee-script": "^1.10.0", - "less": "^2.5.3", - "livescript": "^1.4.0", - "node-sass": "^3.4.2", - "stylus": "^0.53.0", - "cssmin": "^0.4.3", - "google-closure-compiler": "^20151216.2.0", - "uglify-js": "^2.6.1", - "yuglify": "^0.1.4", - "yuicompressor": "^2.4.8" - } -} diff -Nru django-pipeline-1.6.8/tests/scripts/npm_install.py django-pipeline-1.6.13/tests/scripts/npm_install.py --- django-pipeline-1.6.8/tests/scripts/npm_install.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/scripts/npm_install.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -#!/usr/bin/env python -""" -A cross-platform compatible `npm install` call, checking whether npm is -in fact installed on the system first (and on windows, checking that the -npm version is at least 3.0 because of a bug in 2.x with MAX_PATH) -""" -import distutils.spawn -import os -from pkg_resources import parse_version -import re -import subprocess -import sys - - -def main(): - tests_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) - if os.name == 'nt': - try: - npm_paths = subprocess.check_output(['where', 'npm.cmd']) - except subprocess.CalledProcessError: - return - else: - npm_bin = re.split(r'\r?\n', npm_paths)[0] - else: - npm_bin = distutils.spawn.find_executable('npm') - if not npm_bin: - return - if os.name == 'nt': - os.environ.setdefault('APPDATA', '.') - npm_version = subprocess.check_output([npm_bin, '--version']).strip() - # Skip on windows if npm version is less than 3 because of - # MAX_PATH issues in version 2 - if parse_version(npm_version) < parse_version('3.0'): - return - pipe = subprocess.Popen([npm_bin, 'install'], - cwd=tests_dir, stdout=sys.stdout, stderr=sys.stderr) - pipe.communicate() - sys.exit(pipe.returncode) - - -if __name__ == '__main__': - main() diff -Nru django-pipeline-1.6.8/tests/settings.py django-pipeline-1.6.13/tests/settings.py --- django-pipeline-1.6.8/tests/settings.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/settings.py 2017-05-25 22:41:08.000000000 +0000 @@ -122,12 +122,12 @@ } } -NODE_MODULES_PATH = local_path('node_modules') +NODE_MODULES_PATH = local_path('../node_modules') NODE_BIN_PATH = os.path.join(NODE_MODULES_PATH, '.bin') NODE_EXE_PATH = distutils.spawn.find_executable('node') JAVA_EXE_PATH = distutils.spawn.find_executable('java') CSSTIDY_EXE_PATH = distutils.spawn.find_executable('csstidy') -HAS_NODE = os.path.exists(NODE_BIN_PATH) and NODE_EXE_PATH +HAS_NODE = bool(NODE_EXE_PATH) HAS_JAVA = bool(JAVA_EXE_PATH) HAS_CSSTIDY = bool(CSSTIDY_EXE_PATH) @@ -164,20 +164,21 @@ if HAS_CSSTIDY: PIPELINE.update({'CSSTIDY_BINARY': CSSTIDY_EXE_PATH}) -TEMPLATE_DIRS = ( - local_path('templates'), -) - TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, - 'DIRS': TEMPLATE_DIRS, + 'DIRS': [local_path('templates')], + 'OPTIONS': { + 'context_processors': [ + 'django.contrib.auth.context_processors.auth', + ] + } }, { 'BACKEND': 'django.template.backends.jinja2.Jinja2', 'APP_DIRS': True, - 'DIRS': TEMPLATE_DIRS, + 'DIRS': [local_path('templates')], 'OPTIONS': { 'extensions': ['pipeline.jinja2.PipelineExtension'] } diff -Nru django-pipeline-1.6.8/tests/tests/test_collector.py django-pipeline-1.6.13/tests/tests/test_collector.py --- django-pipeline-1.6.8/tests/tests/test_collector.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/tests/test_collector.py 2017-05-25 22:41:08.000000000 +0000 @@ -3,12 +3,17 @@ import os from django.contrib.staticfiles import finders +from django.core.files.storage import FileSystemStorage from django.test import TestCase from pipeline.collector import default_collector from pipeline.finders import PipelineFinder +def local_path(path): + return os.path.abspath(os.path.join(os.path.dirname(__file__), '..', path)) + + class CollectorTest(TestCase): def tearDown(self): super(CollectorTest, self).tearDown() @@ -31,6 +36,24 @@ 'pipeline/js/second.js', ])) + def test_delete_file_with_modified(self): + list(default_collector.collect()) + + storage = FileSystemStorage(local_path('assets')) + new_mtime = os.path.getmtime(storage.path('js/first.js')) - 1000 + os.utime(default_collector.storage.path('pipeline/js/first.js'), + (new_mtime, new_mtime)) + + self.assertTrue(default_collector.delete_file( + 'js/first.js', 'pipeline/js/first.js', storage)) + + def test_delete_file_with_unmodified(self): + list(default_collector.collect(files=['pipeline/js/first.js'])) + + self.assertFalse(default_collector.delete_file( + 'js/first.js', 'pipeline/js/first.js', + FileSystemStorage(local_path('assets')))) + def _get_collectable_files(self): for finder in finders.get_finders(): if not isinstance(finder, PipelineFinder): diff -Nru django-pipeline-1.6.8/tests/tests/test_compiler.py django-pipeline-1.6.13/tests/tests/test_compiler.py --- django-pipeline-1.6.8/tests/tests/test_compiler.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/tests/test_compiler.py 2017-05-25 22:41:08.000000000 +0000 @@ -42,6 +42,18 @@ ) return self.execute_command(command) +class CompilerWithEmptyFirstArg(SubProcessCompiler): + output_extension = 'junk' + + def match_file(self, path): + return path.endswith('.coffee') + + def compile_file(self, infile, outfile, outdated=False, force=False): + command = ( + ('', '/usr/bin/env', 'cat'), + infile, + ) + return self.execute_command(command, stdout_captured=outfile) class CopyingCompiler(SubProcessCompiler): output_extension = 'junk' @@ -149,6 +161,20 @@ default_collector.clear() +@pipeline_settings(COMPILERS=['tests.tests.test_compiler.CompilerWithEmptyFirstArg']) +class CompilerWithEmptyFirstArgTest(TestCase): + def setUp(self): + default_collector.collect() + self.compiler = Compiler() + + def test_compile(self): + paths = self.compiler.compile([_('pipeline/js/dummy.coffee')]) + default_collector.collect() + self.assertEqual([_('pipeline/js/dummy.junk')], list(paths)) + + def tearDown(self): + default_collector.clear() + @pipeline_settings(COMPILERS=['tests.tests.test_compiler.InvalidCompiler']) class InvalidCompilerTest(TestCase): def setUp(self): @@ -158,7 +184,6 @@ def test_compile(self): with self.assertRaises(CompilerError) as cm: self.compiler.compile([_('pipeline/js/dummy.coffee')]) - e = cm.exception self.assertEqual( e.command, diff -Nru django-pipeline-1.6.8/tests/tests/test_compressor.py django-pipeline-1.6.13/tests/tests/test_compressor.py --- django-pipeline-1.6.8/tests/tests/test_compressor.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/tests/test_compressor.py 2017-05-25 22:41:08.000000000 +0000 @@ -138,7 +138,10 @@ output = self.compressor.concatenate_and_rewrite([ _('pipeline/css/urls.css'), ], 'css/screen.css') - self.assertEqual("""@font-face { + self.assertEqual(""".embedded-url-svg { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E% 3C/svg%3E"); +} +@font-face { font-family: 'Pipeline'; src: url(../pipeline/fonts/pipeline.eot); src: url(../pipeline/fonts/pipeline.eot?#iefix) format('embedded-opentype'); diff -Nru django-pipeline-1.6.8/tests/tests/test_forms.py django-pipeline-1.6.13/tests/tests/test_forms.py --- django-pipeline-1.6.8/tests/tests/test_forms.py 1970-01-01 00:00:00.000000000 +0000 +++ django-pipeline-1.6.13/tests/tests/test_forms.py 2017-05-25 22:41:08.000000000 +0000 @@ -0,0 +1,200 @@ +from __future__ import unicode_literals + +from django.forms import Media +from django.test import TestCase +from django.utils import six + +from pipeline.forms import PipelineFormMedia +from ..utils import pipeline_settings + + +@pipeline_settings( + PIPELINE_COLLECTOR_ENABLED=False, + STYLESHEETS={ + 'styles1': { + 'source_filenames': ( + 'pipeline/css/first.css', + 'pipeline/css/second.css', + ), + 'output_filename': 'styles1.min.css', + }, + 'styles2': { + 'source_filenames': ( + 'pipeline/css/unicode.css', + ), + 'output_filename': 'styles2.min.css', + }, + 'print': { + 'source_filenames': ( + 'pipeline/css/urls.css', + ), + 'output_filename': 'print.min.css', + }, + }, + JAVASCRIPT={ + 'scripts1': { + 'source_filenames': ( + 'pipeline/js/first.js', + 'pipeline/js/second.js', + ), + 'output_filename': 'scripts1.min.js', + }, + 'scripts2': { + 'source_filenames': ( + 'pipeline/js/application.js', + ), + 'output_filename': 'scripts2.min.js', + }, + }) +class PipelineFormMediaTests(TestCase): + """Unit tests for pipeline.forms.PipelineFormMedia.""" + + @pipeline_settings(PIPELINE_ENABLED=True) + def test_css_packages_with_pipeline_enabled(self): + """Testing PipelineFormMedia.css_packages with PIPELINE_ENABLED=True""" + class MyMedia(PipelineFormMedia): + css_packages = { + 'all': ('styles1', 'styles2'), + 'print': ('print',), + } + + css = { + 'all': ('extra1.css', 'extra2.css') + } + + media = Media(MyMedia) + + self.assertEqual( + MyMedia.css, + { + 'all': [ + 'extra1.css', + 'extra2.css', + '/static/styles1.min.css', + '/static/styles2.min.css', + ], + 'print': ['/static/print.min.css'], + }) + self.assertEqual(MyMedia.css, media._css) + self.assertEqual( + list(media.render_css()), + [ + '' % path + for path in ( + '/static/extra1.css', + '/static/extra2.css', + '/static/styles1.min.css', + '/static/styles2.min.css', + ) + ] + [ + '' + ]) + + @pipeline_settings(PIPELINE_ENABLED=False) + def test_css_packages_with_pipeline_disabled(self): + """Testing PipelineFormMedia.css_packages with PIPELINE_ENABLED=False""" + class MyMedia(PipelineFormMedia): + css_packages = { + 'all': ('styles1', 'styles2'), + 'print': ('print',), + } + + css = { + 'all': ('extra1.css', 'extra2.css') + } + + media = Media(MyMedia) + + self.assertEqual( + MyMedia.css, + { + 'all': [ + 'extra1.css', + 'extra2.css', + 'pipeline/css/first.css', + 'pipeline/css/second.css', + 'pipeline/css/unicode.css', + ], + 'print': ['pipeline/css/urls.css'], + }) + self.assertEqual(MyMedia.css, media._css) + self.assertEqual( + list(media.render_css()), + [ + '' % path + for path in ( + '/static/extra1.css', + '/static/extra2.css', + '/static/pipeline/css/first.css', + '/static/pipeline/css/second.css', + '/static/pipeline/css/unicode.css', + ) + ] + [ + '' + ]) + + @pipeline_settings(PIPELINE_ENABLED=True) + def test_js_packages_with_pipeline_enabled(self): + """Testing PipelineFormMedia.js_packages with PIPELINE_ENABLED=True""" + class MyMedia(PipelineFormMedia): + js_packages = ('scripts1', 'scripts2') + js = ('extra1.js', 'extra2.js') + + media = Media(MyMedia) + + self.assertEqual( + MyMedia.js, + [ + 'extra1.js', + 'extra2.js', + '/static/scripts1.min.js', + '/static/scripts2.min.js', + ]) + self.assertEqual(MyMedia.js, media._js) + self.assertEqual( + media.render_js(), + [ + '' % path + for path in ( + '/static/extra1.js', + '/static/extra2.js', + '/static/scripts1.min.js', + '/static/scripts2.min.js', + ) + ]) + + @pipeline_settings(PIPELINE_ENABLED=False) + def test_js_packages_with_pipeline_disabled(self): + """Testing PipelineFormMedia.js_packages with PIPELINE_ENABLED=False""" + class MyMedia(PipelineFormMedia): + js_packages = ('scripts1', 'scripts2') + js = ('extra1.js', 'extra2.js') + + media = Media(MyMedia) + + self.assertEqual( + MyMedia.js, + [ + 'extra1.js', + 'extra2.js', + 'pipeline/js/first.js', + 'pipeline/js/second.js', + 'pipeline/js/application.js', + ]) + self.assertEqual(MyMedia.js, media._js) + self.assertEqual( + media.render_js(), + [ + '' % path + for path in ( + '/static/extra1.js', + '/static/extra2.js', + '/static/pipeline/js/first.js', + '/static/pipeline/js/second.js', + '/static/pipeline/js/application.js', + ) + ]) diff -Nru django-pipeline-1.6.8/tests/tests/test_storage.py django-pipeline-1.6.13/tests/tests/test_storage.py --- django-pipeline-1.6.8/tests/tests/test_storage.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/tests/test_storage.py 2017-05-25 22:41:08.000000000 +0000 @@ -41,6 +41,9 @@ def open(self, *args): return StringIO() + def listdir(self, *args): + return [] + class DummyCSSCompiler(DummyCompiler): """ Handles css files """ diff -Nru django-pipeline-1.6.8/tests/urls.py django-pipeline-1.6.13/tests/urls.py --- django-pipeline-1.6.8/tests/urls.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/urls.py 2017-05-25 22:41:08.000000000 +0000 @@ -1,11 +1,10 @@ -from django.conf.urls import patterns, include, url +from django.conf.urls import url from django.contrib import admin from django.views.generic import TemplateView -urlpatterns = patterns( - '', +urlpatterns = [ url(r'^$', TemplateView.as_view(template_name="index.html"), name="index"), url(r'^empty/$', TemplateView.as_view(template_name="empty.html"), name="empty"), - (r'^admin/', include(admin.site.urls)), -) + url(r'^admin/', admin.site.urls), +] diff -Nru django-pipeline-1.6.8/tests/utils.py django-pipeline-1.6.13/tests/utils.py --- django-pipeline-1.6.8/tests/utils.py 2016-03-31 03:53:40.000000000 +0000 +++ django-pipeline-1.6.13/tests/utils.py 2017-05-25 22:41:08.000000000 +0000 @@ -1,5 +1,6 @@ import os +import django from django.conf import settings from django.utils import six @@ -17,6 +18,11 @@ class pipeline_settings(override_settings): def __init__(self, **kwargs): + if django.VERSION[:2] >= (1, 10): + # Django 1.10's override_settings inherits from TestContextDecorator + # and its __init__ method calls its superclass' __init__ method too, + # so we must do the same. + super(pipeline_settings, self).__init__() self.options = {'PIPELINE': kwargs}