From 08b3b1774dc4c1e85282268f75ca4c0971c6a683 Mon Sep 17 00:00:00 2001 From: Dominik George <nik@naturalnet.de> Date: Sat, 7 Dec 2019 23:25:00 +0100 Subject: [PATCH] Port from bower to yarn. --- .coveragerc | 2 +- .covio.yml | 4 - CHANGELOG.rst | 5 + README.rst | 71 +++---- {djangobower => django_yarnpkg}/__init__.py | 0 django_yarnpkg/conf.py | 13 ++ django_yarnpkg/context_processors.py | 28 +++ django_yarnpkg/exceptions.py | 10 + {djangobower => django_yarnpkg}/finders.py | 19 +- .../management/__init__.py | 0 django_yarnpkg/management/base.py | 27 +++ .../management/commands/__init__.py | 0 .../management/commands/yarn.py | 15 +- .../management/commands/yarn_install.py | 10 + {djangobower => django_yarnpkg}/models.py | 0 django_yarnpkg/shortcuts.py | 9 + .../templatetags/__init__.py | 0 .../templatetags/yarn.py | 10 +- .../test_settings.py | 10 +- .../tests/__init__.py | 0 {djangobower => django_yarnpkg}/tests/base.py | 22 +-- .../tests/test_finders.py | 44 ++--- django_yarnpkg/tests/test_yarn.py | 129 +++++++++++++ django_yarnpkg/yarn.py | 58 ++++++ djangobower/bower.py | 80 -------- djangobower/conf.py | 15 -- djangobower/context_processors.py | 31 ---- djangobower/exceptions.py | 19 -- djangobower/management/base.py | 35 ---- .../management/commands/bower_freeze.py | 9 - .../management/commands/bower_install.py | 45 ----- djangobower/shortcuts.py | 28 --- djangobower/tests/test_bower.py | 173 ------------------ docs/Makefile | 8 +- docs/conf.py | 20 +- docs/example.rst | 2 +- docs/index.rst | 14 +- docs/installation.rst | 30 +-- docs/tests.rst | 6 +- docs/usage.rst | 28 ++- example/example/settings.py | 8 +- example/{components => node_modules}/.gitkeep | 0 example/templates/index.html | 2 +- runtests.py | 2 +- setup.cfg | 1 - setup.py | 12 +- 46 files changed, 435 insertions(+), 619 deletions(-) delete mode 100644 .covio.yml rename {djangobower => django_yarnpkg}/__init__.py (100%) create mode 100644 django_yarnpkg/conf.py create mode 100644 django_yarnpkg/context_processors.py create mode 100644 django_yarnpkg/exceptions.py rename {djangobower => django_yarnpkg}/finders.py (52%) rename {djangobower => django_yarnpkg}/management/__init__.py (100%) create mode 100644 django_yarnpkg/management/base.py rename {djangobower => django_yarnpkg}/management/commands/__init__.py (100%) rename djangobower/management/commands/bower.py => django_yarnpkg/management/commands/yarn.py (56%) create mode 100644 django_yarnpkg/management/commands/yarn_install.py rename {djangobower => django_yarnpkg}/models.py (100%) create mode 100644 django_yarnpkg/shortcuts.py rename {djangobower => django_yarnpkg}/templatetags/__init__.py (100%) rename djangobower/templatetags/bower.py => django_yarnpkg/templatetags/yarn.py (80%) rename {djangobower => django_yarnpkg}/test_settings.py (66%) rename {djangobower => django_yarnpkg}/tests/__init__.py (100%) rename {djangobower => django_yarnpkg}/tests/base.py (50%) rename {djangobower => django_yarnpkg}/tests/test_finders.py (62%) create mode 100644 django_yarnpkg/tests/test_yarn.py create mode 100644 django_yarnpkg/yarn.py delete mode 100644 djangobower/bower.py delete mode 100644 djangobower/conf.py delete mode 100644 djangobower/context_processors.py delete mode 100644 djangobower/exceptions.py delete mode 100644 djangobower/management/base.py delete mode 100644 djangobower/management/commands/bower_freeze.py delete mode 100644 djangobower/management/commands/bower_install.py delete mode 100644 djangobower/shortcuts.py delete mode 100644 djangobower/tests/test_bower.py rename example/{components => node_modules}/.gitkeep (100%) delete mode 100644 setup.cfg diff --git a/.coveragerc b/.coveragerc index ca6673d..487f1ad 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,2 +1,2 @@ [run] -include = djangobower* +include = django_yarnpkg* diff --git a/.covio.yml b/.covio.yml deleted file mode 100644 index 2dacb0c..0000000 --- a/.covio.yml +++ /dev/null @@ -1,4 +0,0 @@ -violations: - pep8: pep8 . --exclude='*migrations*,*settings*,*components*,*docs*' - sloccount: sloccount . - py_unittest: cat test_out diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d23a427..72e99a6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +Version 6.0 (2019-12-07) +===================================================== + +* Fork and port to yarnpkg + Version 4.8 (2013-10-02) ===================================================== diff --git a/README.rst b/README.rst index 72f4e5c..887b69b 100644 --- a/README.rst +++ b/README.rst @@ -1,76 +1,65 @@ -Django-bower -============ +Django-yarnpkg +============== -.. image:: https://travis-ci.org/nvbn/django-bower.png - :alt: Build Status - :target: https://travis-ci.org/nvbn/django-bower -.. image:: https://coveralls.io/repos/nvbn/django-bower/badge.png?branch=develop - :alt: Coverage Status - :target: https://coveralls.io/r/nvbn/django-bower -.. image:: https://pypip.in/v/django-bower/badge.png - :target: https://crate.io/packages/django-bower/ -.. image:: https://pypip.in/d/django-bower/badge.png - :target: https://crate.io/packages/django-bower/ +Easy way to use `yarnpkg <http://yarnpkg.com/>`_ with your `Django <https://www.djangoproject.com/>`_ project. -Easy way to use `bower <http://bower.io/>`_ with your `Django <https://www.djangoproject.com/>`_ project. +This is a fork of `django-bower <https://github.com/nvbn/django-bower>` by Vladimir Iakovlev. -Bower is a package manager for the web. It offers a generic, unopinionated solution to the problem of front-end package management, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat. - -Read full documentation on `read-the-docs <https://django-bower.readthedocs.io/en/latest/>`_. +Read full documentation on `read-the-docs <https://django-yarnpkg.readthedocs.io/en/latest/>`_. Installation ------------ -Install django-bower package: +Install django-yarnpkg package: .. code-block:: bash - pip install django-bower + pip install django-yarnpkg Add django-bower to `INSTALLED_APPS` in your settings: .. code-block:: python - 'djangobower', + 'django_yarnpkg', Add staticfinder to `STATICFILES_FINDERS`: .. code-block:: python - 'djangobower.finders.BowerFinder', + 'django_yarnpkg.finders.NodeModulesFinder', Specify path to components root (you need to use an absolute path): .. code-block:: python - BOWER_COMPONENTS_ROOT = '/PROJECT_ROOT/components/' + NODE_MODULES_ROOT = os.path.join(BASE_DIR, 'node_modules') -If you need, you can manually set the path to bower: +If you need, you can manually set the path to yarnpkg: .. code-block:: python - BOWER_PATH = '/usr/bin/bower' + YARN_PATH = '/usr/bin/yarnpkg' -You can see an example settings file in `example project <https://github.com/nvbn/django-bower/blob/master/example/example/settings.py>`_. +You can see an example settings file in `example project <https://github.com/Natureshadow/django-yarnpkg/blob/master/example/example/settings.py>`_. Usage ----- -Specify `BOWER_INSTALLED_APPS` in settings, like: +Specify `YARN_INSTALLED_APPS` in settings, like: .. code-block:: python - BOWER_INSTALLED_APPS = ( - 'jquery#1.9', - 'underscore', + YARN_INSTALLED_APPS = ( + 'bootstrap@^4.4.1', + 'underscore@^1.6.1', ) -Download bower packages with the management command: +Download yarn packages with the management command: .. code-block:: bash - ./manage.py bower install + ./manage.py yarn install Add scripts in the template, like: @@ -79,32 +68,26 @@ Add scripts in the template, like: {% load static %} <script type="text/javascript" src='{% static 'jquery/dist/jquery.js' %}'></script> -In production you need to call `bower install` before `collectstatic`: +In production you need to call `yarnpkg install` before `collectstatic`: .. code-block:: bash - ./manage.py bower install + ./manage.py yarn install ./manage.py collectstatic -If you need to pass arguments to bower, like `--allow-root`, use: - -.. code-block:: bash - - ./manage.py bower install -- --allow-root - -You can use `bower freeze` to receive `BOWER_INSTALLED_APPS` with fixed current versions: +If you need to pass arguments to yarnpkg, like `--flat`, use: .. code-block:: bash - ./manage.py bower freeze + ./manage.py yarn install -- --flat -You can call bower commands like `info` and `update` with: +You can call yarnpkg commands like `info` and `update` with: .. code-block:: bash - ./manage.py bower info backbone - ./manage.py bower update + ./manage.py yarn info backbone + ./manage.py yarn update Python 3 support ---------------- -django-bower supports python 3.3+ +django-yarnpkg supports python 3.3+ diff --git a/djangobower/__init__.py b/django_yarnpkg/__init__.py similarity index 100% rename from djangobower/__init__.py rename to django_yarnpkg/__init__.py diff --git a/django_yarnpkg/conf.py b/django_yarnpkg/conf.py new file mode 100644 index 0000000..c4ea170 --- /dev/null +++ b/django_yarnpkg/conf.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from distutils.spawn import find_executable +import os +import sys +from django.conf import settings + +__all__ = ['NODE_MODULES_ROOT', 'YARN_PATH'] + +NODE_MODULES_ROOT = getattr(settings, 'NODE_MODULES_ROOT', os.path.abspath(os.path.dirname(__name__))) + +default_yarn_path = find_executable('yarn') or find_executable('yarnpkg') + +YARN_PATH = getattr(settings, 'YARN_PATH', default_yarn_path) diff --git a/django_yarnpkg/context_processors.py b/django_yarnpkg/context_processors.py new file mode 100644 index 0000000..2b3fad5 --- /dev/null +++ b/django_yarnpkg/context_processors.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +import os.path +import json +import six +from django.conf import settings +from django.utils.datastructures import OrderedSet + + +def read_files(): + for component in settings.YARN_INSTALLED_APPS: + component = component.split('#')[0] + try: + with open(os.path.join( + settings.NODE_MODULES_ROOT, + 'node_modules', + component, + 'package.json')) as package_json: + files = json.load(bower_json).get('files') + for f in files: + yield '%s/%s' % (component, f) + except FileNotFoundError: + continue + + +def node_modules(request): + return { + 'node_modules': OrderedSet([f for f in read_files()]), + } diff --git a/django_yarnpkg/exceptions.py b/django_yarnpkg/exceptions.py new file mode 100644 index 0000000..fd507a1 --- /dev/null +++ b/django_yarnpkg/exceptions.py @@ -0,0 +1,10 @@ +from django.core.management.base import CommandError + + +class YarnNotInstalled(CommandError): + """Custom command error""" + + def __init__(self): + super(YarnNotInstalled, self).__init__( + "Yarn not installed, read instruction here - http://yarnpkg.com/", + ) diff --git a/djangobower/finders.py b/django_yarnpkg/finders.py similarity index 52% rename from djangobower/finders.py rename to django_yarnpkg/finders.py index 746cb6d..b3f8ff3 100644 --- a/djangobower/finders.py +++ b/django_yarnpkg/finders.py @@ -9,14 +9,14 @@ from . import conf import os -class BowerFinder(FileSystemFinder): - """Find static files installed with bower""" +class NodeModulesFinder(FileSystemFinder): + """Find static files installed with yarnpkg""" def __init__(self, apps=None, *args, **kwargs): self.locations = [] self.storages = OrderedDict() - root = self._get_bower_components_location() + root = self._get_node_modules_location() if root is not None: prefix = '' self.locations.append((prefix, root)) @@ -25,13 +25,10 @@ class BowerFinder(FileSystemFinder): filesystem_storage.prefix = prefix self.storages[root] = filesystem_storage - def _get_bower_components_location(self): + def _get_node_modules_location(self): """ - Return the bower components location, or None if one does not exist. + Return the node modules location, or None if one does not exist. """ - # Bower 0.10 changed the default folder from 'components' to 'bower_components'. - # Try 'bower_components' first, then fall back to trying 'components'. - for name in ['bower_components', 'components']: - path = os.path.join(conf.COMPONENTS_ROOT, name) - if os.path.exists(path): - return path + path = os.path.join(conf.NODE_MODULES_ROOT, 'node_modules') + if os.path.exists(path): + return path diff --git a/djangobower/management/__init__.py b/django_yarnpkg/management/__init__.py similarity index 100% rename from djangobower/management/__init__.py rename to django_yarnpkg/management/__init__.py diff --git a/django_yarnpkg/management/base.py b/django_yarnpkg/management/base.py new file mode 100644 index 0000000..f6b7dd1 --- /dev/null +++ b/django_yarnpkg/management/base.py @@ -0,0 +1,27 @@ +from pprint import pformat +from django.core.management.base import BaseCommand +from django.conf import settings +from ..yarn import yarn_adapter +from ..exceptions import YarnNotInstalled + + +class BaseYarnCommand(BaseCommand): + """Base management command with yarn support""" + + requires_system_checks = False + + # add fake .options_list for Django>=1.10 + if not hasattr(BaseCommand, 'option_list'): + option_list = () + + def handle(self, *args, **options): + self._check_yarn_exists() + yarn_adapter.create_node_modules_root() + + def _check_yarn_exists(self): + """Check yarn exists or raise exception""" + if not yarn_adapter.is_yarn_exists(): + raise YarnNotInstalled() + + def _install(self, args): + yarn_adapter.install(settings.YARN_INSTALLED_APPS, *args) diff --git a/djangobower/management/commands/__init__.py b/django_yarnpkg/management/commands/__init__.py similarity index 100% rename from djangobower/management/commands/__init__.py rename to django_yarnpkg/management/commands/__init__.py diff --git a/djangobower/management/commands/bower.py b/django_yarnpkg/management/commands/yarn.py similarity index 56% rename from djangobower/management/commands/bower.py rename to django_yarnpkg/management/commands/yarn.py index b8779e9..5ea03c0 100644 --- a/djangobower/management/commands/bower.py +++ b/django_yarnpkg/management/commands/yarn.py @@ -1,13 +1,12 @@ -from ...bower import bower_adapter -from ..base import BaseBowerCommand +from ...yarn import yarn_adapter +from ..base import BaseYarnCommand -class Command(BaseBowerCommand): +class Command(BaseYarnCommand): args = 'command' - help = 'Call bower in components root ({0}).'.format( - bower_adapter._components_root) + help = 'Call yarn in node modules root ({0}).'.format( + yarn_adapter._node_modules_root) - # for Django>=1.10 def add_arguments(self, parser): parser.add_argument('command', nargs='*') @@ -16,10 +15,8 @@ class Command(BaseBowerCommand): args = args or tuple(options.pop('command')) if self._is_single_command('install', args): self._install([]) - elif self._is_single_command('freeze', args): - self._freeze() else: - bower_adapter.call_bower(args) + yarn_adapter.call_bower(args) def _is_single_command(self, name, args): return len(args) == 1 and args[0] == name diff --git a/django_yarnpkg/management/commands/yarn_install.py b/django_yarnpkg/management/commands/yarn_install.py new file mode 100644 index 0000000..807eac4 --- /dev/null +++ b/django_yarnpkg/management/commands/yarn_install.py @@ -0,0 +1,10 @@ +from optparse import make_option +from ..base import BaseYarnCommand + + +class Command(BaseYarnCommand): + help = 'Install yarn apps' + + def handle(self, *args, **options): + super(Command, self).handle(*args, **options) + self._install(args) diff --git a/djangobower/models.py b/django_yarnpkg/models.py similarity index 100% rename from djangobower/models.py rename to django_yarnpkg/models.py diff --git a/django_yarnpkg/shortcuts.py b/django_yarnpkg/shortcuts.py new file mode 100644 index 0000000..1effce5 --- /dev/null +++ b/django_yarnpkg/shortcuts.py @@ -0,0 +1,9 @@ +import os, sys + + +def is_executable(path): + """Check file is executable""" + if sys.platform == 'win32': + executable = os.access(path, os.X_OK) or path.lower().endswith(".cmd") + return os.path.isfile(path) and executable + return os.path.isfile(path) and os.access(path, os.X_OK) diff --git a/djangobower/templatetags/__init__.py b/django_yarnpkg/templatetags/__init__.py similarity index 100% rename from djangobower/templatetags/__init__.py rename to django_yarnpkg/templatetags/__init__.py diff --git a/djangobower/templatetags/bower.py b/django_yarnpkg/templatetags/yarn.py similarity index 80% rename from djangobower/templatetags/bower.py rename to django_yarnpkg/templatetags/yarn.py index 6387e88..784717c 100644 --- a/djangobower/templatetags/bower.py +++ b/django_yarnpkg/templatetags/yarn.py @@ -24,13 +24,13 @@ script_template = template.Template( def tags(context, args, type): components = ( - [arg for arg in args if arg in context['bower_components']] - if args else context['bower_components'] + [arg for arg in args if arg in context['node_modules']] + if args else context['node_modules'] ) files = [] for component in components: files.append(component) - context['bower_components'].remove(component) + context['node_modules'].remove(component) return {'files': [ static.static(f) for f in files @@ -39,10 +39,10 @@ def tags(context, args, type): @register.inclusion_tag(style_template, takes_context=True) -def bower_styles(context, *args): +def yarn_styles(context, *args): return tags(context, args, 'css') @register.inclusion_tag(script_template, takes_context=True) -def bower_scripts(context, *args): +def yarn_scripts(context, *args): return tags(context, args, 'js') diff --git a/djangobower/test_settings.py b/django_yarnpkg/test_settings.py similarity index 66% rename from djangobower/test_settings.py rename to django_yarnpkg/test_settings.py index f932db5..ca462cf 100644 --- a/djangobower/test_settings.py +++ b/django_yarnpkg/test_settings.py @@ -8,21 +8,21 @@ TEST_PROJECT_ROOT = os.path.abspath( BASE_DIR = TEST_PROJECT_ROOT -BOWER_COMPONENTS_ROOT = os.path.join(TEST_PROJECT_ROOT, 'bower_components') +NODE_MODULES_ROOT = os.path.join(TEST_PROJECT_ROOT, 'node_modules') -STATIC_ROOT = os.path.join(TEST_PROJECT_ROOT, 'bower_static') +STATIC_ROOT = os.path.join(TEST_PROJECT_ROOT, 'yarnpkg_static') STATIC_URL = '/static/' -BOWER_INSTALLED_APPS = ( +YARN_INSTALLED_APPS = ( 'jquery#1.9', 'underscore', ) -SECRET_KEY = 'iamdjangobower' +SECRET_KEY = 'iamdjangoyarnpkg' INSTALLED_APPS = ( - 'djangobower', + 'django_yarnpkg', ) DATABASES = { diff --git a/djangobower/tests/__init__.py b/django_yarnpkg/tests/__init__.py similarity index 100% rename from djangobower/tests/__init__.py rename to django_yarnpkg/tests/__init__.py diff --git a/djangobower/tests/base.py b/django_yarnpkg/tests/base.py similarity index 50% rename from djangobower/tests/base.py rename to django_yarnpkg/tests/base.py index ca61152..b8e82a6 100644 --- a/djangobower/tests/base.py +++ b/django_yarnpkg/tests/base.py @@ -1,37 +1,37 @@ from django.conf import settings from django.test import TestCase from django.test.utils import override_settings -from ..bower import bower_adapter +from ..yarn import yarn_adapter import os import shutil try: - TEST_COMPONENTS_ROOT = os.path.join( - settings.TEST_PROJECT_ROOT, 'bower_components', + TEST_NODE_MODULES_ROOT = os.path.join( + settings.TEST_PROJECT_ROOT, 'node_modules', ) except AttributeError: - TEST_COMPONENTS_ROOT = '/tmp/bower_components/' + TEST_NODE_MODULES_ROOT = '/tmp/node_modules/' -@override_settings(BOWER_COMPONENTS_ROOT=TEST_COMPONENTS_ROOT) -class BaseBowerCase(TestCase): +@override_settings(NODE_MODULES_ROOT=TEST_NODE_MODULES_ROOT) +class BaseYarnCase(TestCase): """Base bower test case""" def setUp(self): - bower_adapter.create_components_root() + yarn_adapter.create_node_modules_root() def tearDown(self): - self._remove_components_root() + self._remove_node_modules_root() def _remove_components_root(self): """Remove components root if exists""" - if os.path.exists(TEST_COMPONENTS_ROOT): - shutil.rmtree(TEST_COMPONENTS_ROOT) + if os.path.exists(TEST_NODE_MODULES_ROOT): + shutil.rmtree(TEST_NODE_MODULES_ROOT) def assertCountEqual(self, *args, **kwargs): """Add python 2 support""" if hasattr(self, 'assertItemsEqual'): return self.assertItemsEqual(*args, **kwargs) else: - return super(BaseBowerCase, self).assertCountEqual(*args, **kwargs) + return super(BaseYarnCase, self).assertCountEqual(*args, **kwargs) diff --git a/djangobower/tests/test_finders.py b/django_yarnpkg/tests/test_finders.py similarity index 62% rename from djangobower/tests/test_finders.py rename to django_yarnpkg/tests/test_finders.py index 648829b..53378a5 100644 --- a/djangobower/tests/test_finders.py +++ b/django_yarnpkg/tests/test_finders.py @@ -1,10 +1,10 @@ from django.core.files.storage import FileSystemStorage from django.test import TestCase -from ..bower import bower_adapter -from ..finders import BowerFinder +from ..yarn import yarn_adapter +from ..finders import NodeModulesFinder from .. import conf -from .base import BaseBowerCase +from .base import BaseYarnCase import os import os.path import shutil @@ -33,26 +33,26 @@ class _MakeDirsTestCase(TestCase): self.created.append(name) -class SimpleBowerFinderCase(_MakeDirsTestCase): +class SimpleNodeModulesFinderCase(_MakeDirsTestCase): """ - Simple BowerFinder tests, without any packages installed. + Simple YarnFinder tests, without any packages installed. """ def test_list_nonexistent(self): """ - When no Bower folder exists, just gracefully find nothing. + When no Yarn folder exists, just gracefully find nothing. """ - finder = BowerFinder() + finder = NodeModulesFinder() self.assertEqual(finder.locations, []) self.assertEqual(finder.storages, {}) - def test_list_existent(self, leaf_name='bower_components'): + def test_list_existent(self, leaf_name='node_modules'): """ - If 'bower_components' exists, use it to to find files. + If 'node_modules' exists, use it to to find files. """ - root = os.path.join(conf.COMPONENTS_ROOT, leaf_name) + root = os.path.join(conf.NODE_MODULES_ROOT, leaf_name) self.makedirs(root) - finder = BowerFinder() + finder = NodeModulesFinder() self.assertEqual(finder.locations, [('', root)]) @@ -64,32 +64,32 @@ class SimpleBowerFinderCase(_MakeDirsTestCase): def test_list_old_path(self): """ - If only the old 'components' folder exists, use it instead. + If only the old 'node_modules' folder exists, use it instead. """ - self.test_list_existent(leaf_name='components') + self.test_list_existent(leaf_name='node_modules') def test_list_both(self): """ - If both folders exist, only 'bower_components' should be used. + If both folders exist, only 'yarn_node_modules' should be used. """ - self.makedirs(os.path.join(conf.COMPONENTS_ROOT, 'components')) - self.test_list_existent(leaf_name='bower_components') + self.makedirs(os.path.join(conf.NODE_MODULES_ROOT, 'node_modules')) + self.test_list_existent(leaf_name='node_modules') -class BowerFinderCase(BaseBowerCase): - """Test finding installed with bower files""" +class NodeModulesFinderCase(BaseYarnCase): + """Test finding installed with yarn files""" def setUp(self): - super(BowerFinderCase, self).setUp() - bower_adapter.install(['jquery#1.9']) - self.finder = BowerFinder() + super(NodeModulesFinderCase, self).setUp() + yarn_adapter.install(['jquery@1.9']) + self.finder = NodeModulesFinder() def test_find(self): """Test staticfinder find""" test_path = os.path.join('jquery', 'jquery.min.js') path = self.finder.find(test_path) self.assertEqual(path, os.path.join( - conf.COMPONENTS_ROOT, 'bower_components', test_path, + conf.NODE_MODULES_ROOT, 'node_modules', test_path, )) def test_list(self): diff --git a/django_yarnpkg/tests/test_yarn.py b/django_yarnpkg/tests/test_yarn.py new file mode 100644 index 0000000..44d404c --- /dev/null +++ b/django_yarnpkg/tests/test_yarn.py @@ -0,0 +1,129 @@ +from django.core.management import call_command +from django.conf import settings +from django.test import TestCase +from six import StringIO +from mock import MagicMock +from ..yarn import yarn_adapter, YarnAdapter +from .. import conf +from .base import BaseYarnCase, TEST_NODE_MODULES_ROOT +import os +import shutil + + +class YarnAdapterCase(TestCase): + """ + YarnAdapter regression tests. + """ + + def test_create_node_modules_root_subdirs(self): + """ + create_node_modules_root() creates missing intermediate directories. + """ + if os.path.exists(TEST_NODE_MODULES_ROOT): + shutil.rmtree(TEST_NODE_MODULES_ROOT) + + subdir = os.path.join(TEST_NODE_MODULES_ROOT, 'sub', 'dir') + adapter = YarnAdapter(conf.YARN_PATH, subdir) + adapter.create_node_modules_root() + self.assertTrue(os.path.exists(subdir)) + + shutil.rmtree(TEST_NODE_MODULES_ROOT) + + +class YarnInstallCase(BaseYarnCase): + """Test case for yarn_install management command""" + + def setUp(self): + super(YarnInstallCase, self).setUp() + self.apps = settings.YARN_INSTALLED_APPS + self._original_install = yarn_adapter.install + yarn_adapter.install = MagicMock() + + def tearDown(self): + super(YarnInstallCase, self).tearDown() + yarn_adapter.install = self._original_install + + def test_create_node_modules_root(self): + """Test create node_modules root""" + self._remove_node_modules_root() + call_command('yarn_install') + + self.assertTrue(os.path.exists(TEST_NODE_MODULES_ROOT)) + + def test_install(self): + """Test install yarn packages""" + call_command('yarn_install') + yarn_adapter.install.assert_called_once_with(self.apps) + + +class YarnExistsCase(BaseYarnCase): + """ + Test yarn exists checker. + This case need yarn to be installed. + """ + + def setUp(self): + super(YarnExistsCase, self).setUp() + self._original_exists = yarn_adapter.is_yarn_exists + + def tearDown(self): + super(YarnExistsCase, self).tearDown() + yarn_adapter.is_yarn_exists = self._original_exists + + def test_if_exists(self): + """Test if yarn exists""" + self.assertTrue(yarn_adapter.is_yarn_exists()) + + def test_if_not_exists(self): + """Test if yarn not exists""" + adapter = YarnAdapter('/not/exists/path', TEST_NODE_MODULES_ROOT) + self.assertFalse(adapter.is_yarn_exists()) + + def _mock_exists_check(self): + """Make exists check return false""" + yarn_adapter.is_yarn_exists = MagicMock() + yarn_adapter.is_yarn_exists.return_value = False + + +class YarnCommandCase(BaseYarnCase): + """Test case for ./manage.py yarn something command""" + + def setUp(self): + super(YarnCommandCase, self).setUp() + self.apps = settings.YARN_INSTALLED_APPS + self._mock_yarn_adapter() + + def _mock_yarn_adapter(self): + self._original_install = yarn_adapter.install + yarn_adapter.install = MagicMock() + self._orig_call = yarn_adapter.call_yarn + yarn_adapter.call_yarn = MagicMock() + self._orig_freeze = yarn_adapter.freeze + yarn_adapter.freeze = MagicMock() + + def tearDown(self): + super(YarnCommandCase, self).tearDown() + yarn_adapter.install = self._original_install + yarn_adapter.call_yarn = self._orig_call + yarn_adapter.freeze = self._orig_freeze + + def test_install_without_params(self): + """Test that yarn install without param identical + with yarn_install + + """ + call_command('yarn', 'install') + yarn_adapter.install.assert_called_once_with( + self.apps) + + def test_install_with_params(self): + """Test yarn install <something>""" + call_command('yarn', 'install', 'jquery') + yarn_adapter.call_yarn.assert_called_once_with( + ('install', 'jquery')) + + def test_call_to_yarn(self): + """Test simple call to yarn""" + call_command('yarn', 'update') + yarn_adapter.call_yarn.assert_called_once_with( + ('update',)) diff --git a/django_yarnpkg/yarn.py b/django_yarnpkg/yarn.py new file mode 100644 index 0000000..fa25547 --- /dev/null +++ b/django_yarnpkg/yarn.py @@ -0,0 +1,58 @@ +from . import conf, shortcuts, exceptions +from distutils.spawn import find_executable +import os +import subprocess +import sys +import json + + +class YarnAdapter(object): + """Adapter for working with yarnpkg""" + + def __init__(self, yarn_path, node_modules_root): + self._yarn_path = yarn_path + self._node_modules_root = node_modules_root + + def is_yarn_exists(self): + """Check is bower exists""" + if shortcuts.is_executable(self._yarn_path)\ + or find_executable(self._yarn_path): + return True + else: + return False + + def create_node_modules_root(self): + """Create node modules root if need""" + if not os.path.exists(self._node_modules_root): + os.makedirs(self._node_modules_root) + + def call_yarn(self, args): + """Call yarn with a list of args""" + proc = subprocess.Popen( + [self._yarn_path] + list(args), + cwd=self._node_modules_root) + proc.wait() + + def install(self, packages, *options): + """Install packages from yarn""" + self.call_yarn(['add'] + list(options) + list(packages)) + + def _accumulate_dependencies(self, data): + """Accumulate dependencies""" + for name, version in data['dependencies'].items(): + if version: + full_name = '{0}@{1}'.format(name, version) + else: + full_name = name + + self._packages.append(full_name) + self._accumulate_dependencies(params) + + def _parse_package_names(self, output): + """Get package names in yarn""" + data = json.loads(output) + self._packages = [] + self._accumulate_dependencies(data) + return self._packages + +yarn_adapter = YarnAdapter(conf.YARN_PATH, conf.NODE_MODULES_ROOT) diff --git a/djangobower/bower.py b/djangobower/bower.py deleted file mode 100644 index 700554a..0000000 --- a/djangobower/bower.py +++ /dev/null @@ -1,80 +0,0 @@ -from . import conf, shortcuts, exceptions -import os -import subprocess -import sys -import json - - -class BowerAdapter(object): - """Adapter for working with bower""" - - def __init__(self, bower_path, components_root): - self._bower_path = bower_path - self._components_root = components_root - - def is_bower_exists(self): - """Check is bower exists""" - if shortcuts.is_executable(self._bower_path)\ - or shortcuts.which(self._bower_path): - return True - else: - return False - - def create_components_root(self): - """Create components root if need""" - if not os.path.exists(self._components_root): - os.makedirs(self._components_root) - - def call_bower(self, args): - """Call bower with a list of args""" - proc = subprocess.Popen( - [self._bower_path] + list(args), - cwd=self._components_root) - proc.wait() - - def install(self, packages, *options): - """Install packages from bower""" - self.call_bower(['install'] + list(options) + list(packages)) - - def _accumulate_dependencies(self, data): - """Accumulate dependencies""" - for name, params in data['dependencies'].items(): - meta = params.get('pkgMeta', {}) - version = meta.get( - 'version', meta.get('_resolution', {}).get('commit', ''), - ) - - if version: - full_name = '{0}#{1}'.format(name, version) - else: - full_name = name - - self._packages.append(full_name) - self._accumulate_dependencies(params) - - def _parse_package_names(self, output): - """Get package names in bower >= 1.0""" - data = json.loads(output) - self._packages = [] - self._accumulate_dependencies(data) - return self._packages - - def freeze(self): - """Yield packages with versions list""" - proc = subprocess.Popen( - [self._bower_path, 'list', '--json', '--offline', '--no-color'], - cwd=conf.COMPONENTS_ROOT, - stdout=subprocess.PIPE, - ) - outs, errs = proc.communicate() - output = outs.decode(sys.getfilesystemencoding()) - - try: - packages = self._parse_package_names(output) - except ValueError: - raise exceptions.LegacyBowerVersionNotSupported() - - return iter(set(packages)) - - -bower_adapter = BowerAdapter(conf.BOWER_PATH, conf.COMPONENTS_ROOT) diff --git a/djangobower/conf.py b/djangobower/conf.py deleted file mode 100644 index 40a9717..0000000 --- a/djangobower/conf.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -import os -import sys -from django.conf import settings - -__all__ = ['COMPONENTS_ROOT', 'BOWER_PATH'] - -COMPONENTS_ROOT = getattr(settings, 'BOWER_COMPONENTS_ROOT', os.path.abspath(os.path.dirname(__name__))) - -if sys.platform == 'win32': - default_bower_path = os.path.join(os.getenv("APPDATA"), 'npm', 'bower.cmd') -else: - default_bower_path = 'bower' - -BOWER_PATH = getattr(settings, 'BOWER_PATH', default_bower_path) diff --git a/djangobower/context_processors.py b/djangobower/context_processors.py deleted file mode 100644 index 4bd7e47..0000000 --- a/djangobower/context_processors.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -import os.path -import json -import six -from django.conf import settings -from django.utils.datastructures import OrderedSet - - -def read_mains(): - for component in settings.BOWER_INSTALLED_APPS: - component = component.split('#')[0] - try: - with open(os.path.join( - settings.BOWER_COMPONENTS_ROOT, - 'bower_components', - component, - 'bower.json')) as bower_json: - main = json.load(bower_json).get('main') - if isinstance(main, six.string_types): - yield '%s/%s' % (component, main) - elif isinstance(main, list): - for m in main: - yield '%s/%s' % (component, m) - except FileNotFoundError: - continue - - -def bower_components(request): - return { - 'bower_components': OrderedSet([main for main in read_mains()]), - } diff --git a/djangobower/exceptions.py b/djangobower/exceptions.py deleted file mode 100644 index f6d1e60..0000000 --- a/djangobower/exceptions.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.core.management.base import CommandError - - -class BowerNotInstalled(CommandError): - """Custom command error""" - - def __init__(self): - super(BowerNotInstalled, self).__init__( - "Bower not installed, read instruction here - http://bower.io/", - ) - - -class LegacyBowerVersionNotSupported(CommandError): - """Custom command error""" - - def __init__(self): - super(LegacyBowerVersionNotSupported, self).__init__( - "Legacy bower versions not supported, please install bower 1.0+", - ) diff --git a/djangobower/management/base.py b/djangobower/management/base.py deleted file mode 100644 index bac8233..0000000 --- a/djangobower/management/base.py +++ /dev/null @@ -1,35 +0,0 @@ -from pprint import pformat -from django.core.management.base import BaseCommand -from django.conf import settings -from ..bower import bower_adapter -from ..exceptions import BowerNotInstalled - - -class BaseBowerCommand(BaseCommand): - """Base management command with bower support""" - - requires_system_checks = False - - # add fake .options_list for Django>=1.10 - if not hasattr(BaseCommand, 'option_list'): - option_list = () - - def handle(self, *args, **options): - self._check_bower_exists() - bower_adapter.create_components_root() - - def _check_bower_exists(self): - """Check bower exists or raise exception""" - if not bower_adapter.is_bower_exists(): - raise BowerNotInstalled() - - def _install(self, args): - bower_adapter.install(settings.BOWER_INSTALLED_APPS, *args) - - def _freeze(self): - packages = list(bower_adapter.freeze()) - packages.sort() - output = 'BOWER_INSTALLED_APPS = {0}'.format( - pformat(packages), - ) - self.stdout.write(output) diff --git a/djangobower/management/commands/bower_freeze.py b/djangobower/management/commands/bower_freeze.py deleted file mode 100644 index ac89c73..0000000 --- a/djangobower/management/commands/bower_freeze.py +++ /dev/null @@ -1,9 +0,0 @@ -from ..base import BaseBowerCommand - - -class Command(BaseBowerCommand): - help = 'Freeze bower apps' - - def handle(self, *args, **options): - super(Command, self).handle(*args, **options) - self._freeze() diff --git a/djangobower/management/commands/bower_install.py b/djangobower/management/commands/bower_install.py deleted file mode 100644 index 8163298..0000000 --- a/djangobower/management/commands/bower_install.py +++ /dev/null @@ -1,45 +0,0 @@ -from optparse import make_option -from ..base import BaseBowerCommand - - -class Command(BaseBowerCommand): - help = 'Install bower apps' - - # for Django<1.10 - option_list = BaseBowerCommand.option_list + ( - make_option('-F', - action='store_true', - dest='force', - default=False, - help='Force installation of latest package version on conflict'), - make_option('-R', '--allow-root', - action='store_true', - dest='allow-root', - default=False, - help='Allow installing bower packages even when user executing this script is root'), - ) - # for Django>=1.10 - def add_arguments(self, parser): - parser.add_argument('--force', - '-F', - action='store_true', - dest='force', - default=False, - help='Force installation of latest package version on conflict') - parser.add_argument('--allow-root', - '-R', - action='store_true', - dest='allow-root', - default=False, - help='Allow installing bower packages even when user executing this script is root') - - def handle(self, *args, **options): - super(Command, self).handle(*args, **options) - - if options.get('force'): - args = args + ("-F", ) - - if options.get('allow-root'): - args = args + ("--allow-root", ) - - self._install(args) diff --git a/djangobower/shortcuts.py b/djangobower/shortcuts.py deleted file mode 100644 index f1bf112..0000000 --- a/djangobower/shortcuts.py +++ /dev/null @@ -1,28 +0,0 @@ -import os, sys - - -def is_executable(path): - """Check file is executable""" - if sys.platform == 'win32': - executable = os.access(path, os.X_OK) or path.lower().endswith(".cmd") - return os.path.isfile(path) and executable - return os.path.isfile(path) and os.access(path, os.X_OK) - - -def which(program): - """ - Find by path and check exists. - Analog of unix `which` command. - """ - path, name = os.path.split(program) - if path: - if is_executable(program): - return program - else: - for path in os.environ["PATH"].split(os.pathsep): - path = path.strip('"') - exe_file = os.path.join(path, program) - if is_executable(exe_file): - return exe_file - - return None diff --git a/djangobower/tests/test_bower.py b/djangobower/tests/test_bower.py deleted file mode 100644 index 75ee910..0000000 --- a/djangobower/tests/test_bower.py +++ /dev/null @@ -1,173 +0,0 @@ -from django.core.management import call_command -from django.conf import settings -from django.test import TestCase -from six import StringIO -from mock import MagicMock -from ..bower import bower_adapter, BowerAdapter -from .. import conf -from .base import BaseBowerCase, TEST_COMPONENTS_ROOT -import os -import shutil - - -class BowerAdapterCase(TestCase): - """ - BowerAdapter regression tests. - """ - - def test_create_components_root_subdirs(self): - """ - create_components_root() creates missing intermediate directories. - """ - if os.path.exists(TEST_COMPONENTS_ROOT): - shutil.rmtree(TEST_COMPONENTS_ROOT) - - subdir = os.path.join(TEST_COMPONENTS_ROOT, 'sub', 'dir') - adapter = BowerAdapter(conf.BOWER_PATH, subdir) - adapter.create_components_root() - self.assertTrue(os.path.exists(subdir)) - - shutil.rmtree(TEST_COMPONENTS_ROOT) - - -class BowerInstallCase(BaseBowerCase): - """Test case for bower_install management command""" - - def setUp(self): - super(BowerInstallCase, self).setUp() - self.apps = settings.BOWER_INSTALLED_APPS - self._original_install = bower_adapter.install - bower_adapter.install = MagicMock() - - def tearDown(self): - super(BowerInstallCase, self).tearDown() - bower_adapter.install = self._original_install - - def test_create_components_root(self): - """Test create components root""" - self._remove_components_root() - call_command('bower_install') - - self.assertTrue(os.path.exists(TEST_COMPONENTS_ROOT)) - - def test_install(self): - """Test install bower packages""" - call_command('bower_install') - bower_adapter.install.assert_called_once_with(self.apps) - - -class BowerFreezeCase(BaseBowerCase): - """Case for bower freeze""" - - def setUp(self): - super(BowerFreezeCase, self).setUp() - bower_adapter.install(['jquery#1.9']) - bower_adapter.install(['backbone']) - bower_adapter.install(['underscore']) - bower_adapter.install(['typeahead.js']) - bower_adapter.install(['backbone-tastypie']) - - def test_freeze(self): - """Test freeze""" - installed = [ - package.split('#')[0] for package in bower_adapter.freeze() - ] - self.assertCountEqual(installed, [ - 'backbone', 'jquery', - 'typeahead.js', 'underscore', - 'backbone-tastypie', - ]) - - def test_no_newline_in_freeze(self): - """Test no newline in freezee""" - installed = bower_adapter.freeze() - for package in installed: - self.assertNotIn('\n', package) - - def test_management_command(self): - """Test freeze management command""" - stdout = StringIO() - call_command('bower_freeze', stdout=stdout) - stdout.seek(0) - output = stdout.read() - - self.assertIn('BOWER_INSTALLED_APPS', output) - self.assertIn('backbone', output) - - -class BowerExistsCase(BaseBowerCase): - """ - Test bower exists checker. - This case need bower to be installed. - """ - - def setUp(self): - super(BowerExistsCase, self).setUp() - self._original_exists = bower_adapter.is_bower_exists - - def tearDown(self): - super(BowerExistsCase, self).tearDown() - bower_adapter.is_bower_exists = self._original_exists - - def test_if_exists(self): - """Test if bower exists""" - self.assertTrue(bower_adapter.is_bower_exists()) - - def test_if_not_exists(self): - """Test if bower not exists""" - adapter = BowerAdapter('/not/exists/path', TEST_COMPONENTS_ROOT) - self.assertFalse(adapter.is_bower_exists()) - - def _mock_exists_check(self): - """Make exists check return false""" - bower_adapter.is_bower_exists = MagicMock() - bower_adapter.is_bower_exists.return_value = False - - -class BowerCommandCase(BaseBowerCase): - """Test case for ./manage.py bower something command""" - - def setUp(self): - super(BowerCommandCase, self).setUp() - self.apps = settings.BOWER_INSTALLED_APPS - self._mock_bower_adapter() - - def _mock_bower_adapter(self): - self._original_install = bower_adapter.install - bower_adapter.install = MagicMock() - self._orig_call = bower_adapter.call_bower - bower_adapter.call_bower = MagicMock() - self._orig_freeze = bower_adapter.freeze - bower_adapter.freeze = MagicMock() - - def tearDown(self): - super(BowerCommandCase, self).tearDown() - bower_adapter.install = self._original_install - bower_adapter.call_bower = self._orig_call - bower_adapter.freeze = self._orig_freeze - - def test_install_without_params(self): - """Test that bower install without param identical - with bower_install - - """ - call_command('bower', 'install') - bower_adapter.install.assert_called_once_with( - self.apps) - - def test_install_with_params(self): - """Test bower install <something>""" - call_command('bower', 'install', 'jquery') - bower_adapter.call_bower.assert_called_once_with( - ('install', 'jquery')) - - def test_freeze(self): - """Test bower freeze command""" - call_command('bower', 'freeze') - bower_adapter.freeze.assert_called_once_with() - - def test_call_to_bower(self): - """Test simple call to bower""" - call_command('bower', 'update') - bower_adapter.call_bower.assert_called_once_with( - ('update',)) diff --git a/docs/Makefile b/docs/Makefile index 41b25a5..fe36a6d 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -77,17 +77,17 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-bower.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-yarnpkg.qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-bower.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-yarnpkg.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/django-bower" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-bower" + @echo "# mkdir -p $$HOME/.local/share/devhelp/django-yarnpkg" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-yarnpkg" @echo "# devhelp" epub: diff --git a/docs/conf.py b/docs/conf.py index 915d8fe..f20dc83 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# django-bower documentation build configuration file, created by +# django-yarnpkg documentation build configuration file, created by # sphinx-quickstart on Tue Jul 16 16:38:23 2013. # # This file is execfile()d with the current directory set to its containing dir. @@ -40,17 +40,17 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'django-bower' -copyright = u'2013, Vladimir Iakovlev' +project = u'django-yarnpkg' +copyright = u'2013, Vladimir Iakovlev; 2019, Dominik George' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.7' +version = '6.0' # The full version, including alpha/beta/rc tags. -release = '4.8' +release = '6.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -164,7 +164,7 @@ html_static_path = ['_static'] #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'django-bowerdoc' +htmlhelp_basename = 'django-yarnpkgdoc' # -- Options for LaTeX output -------------------------------------------------- @@ -183,7 +183,7 @@ latex_elements = { # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'django-bower.tex', u'django-bower Documentation', + ('index', 'django-yarnpkg.tex', u'django-yarnpkg Documentation', u'Vladimir Iakovlev', 'manual'), ] @@ -213,7 +213,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'django-bower', u'django-bower Documentation', + ('index', 'django-yarnpkg', u'django-yarnpkg Documentation', [u'Vladimir Iakovlev'], 1) ] @@ -227,8 +227,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'django-bower', u'django-bower Documentation', - u'Vladimir Iakovlev', 'django-bower', 'One line description of project.', + ('index', 'django-yarnpkg', u'django-yarnpkg Documentation', + u'Vladimir Iakovlev', 'django-yarnpkg', 'One line description of project.', 'Miscellaneous'), ] diff --git a/docs/example.rst b/docs/example.rst index 07a728f..32cc451 100644 --- a/docs/example.rst +++ b/docs/example.rst @@ -9,7 +9,7 @@ Prepare project with: .. code-block:: bash ./manage.py syncdb - ./manage.py bower_install + ./manage.py yarn install And run project with: diff --git a/docs/index.rst b/docs/index.rst index 69af97a..1a5256c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,18 +1,16 @@ -.. django-bower documentation master file, created by +.. django-yarnpkg documentation master file, created by sphinx-quickstart on Tue Jul 16 16:38:23 2013. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to django-bower's documentation! +Welcome to django-yarnpkg's documentation! ======================================== -Easy way to use `bower <http://bower.io/>`_ with your `django <https://www.djangoproject.com/>`_ project. +Easy way to use `Yarn <http://yarnpkg.com/>`_ with your `django <https://www.djangoproject.com/>`_ project. -Bower is a package manager for the web. It offers a generic, unopinionated solution to the problem of front-end package management, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat. +Yarn is a package manager for the web. It offers a generic, unopinionated solution to the problem of front-end package management, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat. -Bower runs over Git, and is package-agnostic. A packaged component can be made up of any type of asset, and use any type of transport (e.g., AMD, CommonJS, etc.). - -`View all packages available through Bower's registry. <http://sindresorhus.com/bower-components/>`_ +Yarn runs over Git, and is package-agnostic. A packaged module can be made up of any type of asset, and use any type of transport (e.g., AMD, CommonJS, etc.). Contents: @@ -24,7 +22,7 @@ Contents: tests example -`Visit django-bower github page. <https://github.com/nvbn/django-bower>`_ +`Visit django-yarnpkg github page. <https://github.com/Natureshadow/django-yarnpkg>`_ diff --git a/docs/installation.rst b/docs/installation.rst index e081739..637fcd6 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -2,43 +2,43 @@ Installation ************ -Install `bower <http://bower.io/>`_ from npm: +Install `Yarn <http://yarnpkg.com/>`_ from npm: .. code-block:: bash - npm install -g bower + npm install -g yarn -And django-bower package: +And django-yarnpkg package: .. code-block:: bash - pip install django-bower + pip install django-yarnpkg Add django-bower to `INSTALLED_APPS` in your settings: .. code-block:: python - 'djangobower', + 'django_yarnpkg', Add staticfinder to `STATICFILES_FINDERS`: .. code-block:: python - 'djangobower.finders.BowerFinder', + 'django_yarnpkg.finders.NodeModulesFinder', -Specify path to components root (you need to use absolute path): +Specify path to node modules root (you need to use absolute path): .. code-block:: python - BOWER_COMPONENTS_ROOT = '/PROJECT_ROOT/components/' + NODE_MODULES_ROOT = '/PROJECT_ROOT/node_modules/' -If you need, you can manually set path to bower +If you need, you can manually set path to yarn .. code-block:: python - BOWER_PATH = '/usr/bin/bower' + YARN_PATH = '/usr/bin/yarnpkg' -Example settings file with django-bower: +Example settings file with django-yarnpkg: .. code-block:: python :linenos: @@ -68,12 +68,12 @@ Example settings file with django-bower: STATIC_URL = '/static/' - BOWER_COMPONENTS_ROOT = os.path.join(PROJECT_ROOT, 'components') + NODE_MODULES_ROOT = os.path.join(PROJECT_ROOT, 'node_modules') STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', - 'djangobower.finders.BowerFinder', + 'django_yarnpkg.finders.NodeModulesFinder', ) SECRET_KEY = 'g^i##va1ewa5d-rw-mevzvx2^udt63@!xu$-&di^19t)5rbm!5' @@ -101,10 +101,10 @@ Example settings file with django-bower: INSTALLED_APPS = ( 'django.contrib.staticfiles', - 'djangobower', + 'django_yarnpkg', ) - BOWER_INSTALLED_APPS = ( + YARN_INSTALLED_APPS = ( 'jquery', 'underscore', ) diff --git a/docs/tests.rst b/docs/tests.rst index 0b05515..277353e 100644 --- a/docs/tests.rst +++ b/docs/tests.rst @@ -2,7 +2,7 @@ Running tests ************* -For running tests you need to install `django-bower` in development mode with: +For running tests you need to install `django-yarnpkg` in development mode with: .. code-block:: bash @@ -18,8 +18,6 @@ Now you can run tests with: .. code-block:: bash - django-admin.py test --settings=djangobower.test_settings djangobower + django-admin.py test --settings=django_yarnpkg.test_settings django_yarnpkg You can change test project root with `TEST_PROJECT_ROOT` environment variable. By default it is `/tmp`. - -You can show current tests status in `travis ci <https://travis-ci.org/nvbn/django-bower/>`_. diff --git a/docs/usage.rst b/docs/usage.rst index 80fe48c..e7d33ba 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -2,20 +2,20 @@ Usage ***** -Specifie `BOWER_INSTALLED_APPS` in settings, like: +Specify `YARN_INSTALLED_APPS` in settings, like: .. code-block:: python - BOWER_INSTALLED_APPS = ( + YARN_INSTALLED_APPS = ( 'jquery#1.9', 'underscore', ) -Download bower packages with management command: +Download yarn packages with management command: .. code-block:: bash - ./manage.py bower install + ./manage.py yarn install Add scripts in template, like: @@ -24,28 +24,22 @@ Add scripts in template, like: {% load static %} <script type="text/javascript" src='{% static 'jquery/jquery.js' %}'></script> -In production you need to call `bower install` before `collectstatic`: +In production you need to call `yarn install` before `collectstatic`: .. code-block:: bash - ./manage.py bower install + ./manage.py yarn install ./manage.py collectstatic -If you need to pass arguments to bower, like `--allow-root`, use: +If you need to pass arguments to yarn, like `--flat`, use: .. code-block:: bash - ./manage.py bower install -- --allow-root + ./manage.py yarn install -- --flat -You can use `bower freeze` to receive `BOWER_INSTALLED_APPS` with fixed current versions: +You can call yarn commands like `info` and `update` with: .. code-block:: bash - ./manage.py bower freeze - -You can call bower commands like `info` and `update` with: - -.. code-block:: bash - - ./manage.py bower info backbone - ./manage.py bower update + ./manage.py yarn info backbone + ./manage.py yarn update diff --git a/example/example/settings.py b/example/example/settings.py index 34b370c..f057a96 100644 --- a/example/example/settings.py +++ b/example/example/settings.py @@ -23,12 +23,12 @@ STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static') STATIC_URL = '/static/' -BOWER_COMPONENTS_ROOT = os.path.join(PROJECT_ROOT, 'components') +NODE_MODULES_ROOT = os.path.join(PROJECT_ROOT, 'node_modules') STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', - 'djangobower.finders.BowerFinder', + 'django_yarnpkg.finders.NodeModulesFinder', ) SECRET_KEY = 'g^i##va1ewa5d-rw-mevzvx2^udt63@!xu$-&di^19t)5rbm!5' @@ -56,10 +56,10 @@ TEMPLATE_DIRS = ( INSTALLED_APPS = ( 'django.contrib.staticfiles', - 'djangobower', + 'django_yarnpkg', ) -BOWER_INSTALLED_APPS = ( +YARN_INSTALLED_APPS = ( 'jquery', 'underscore', ) diff --git a/example/components/.gitkeep b/example/node_modules/.gitkeep similarity index 100% rename from example/components/.gitkeep rename to example/node_modules/.gitkeep diff --git a/example/templates/index.html b/example/templates/index.html index 017d434..f6adfed 100644 --- a/example/templates/index.html +++ b/example/templates/index.html @@ -2,7 +2,7 @@ {% load static %} <html> <head> - <title>django-bower demo</title> + <title>django-yarnpkg demo</title> <script type="text/javascript" src='{% static 'jquery/dist/jquery.js' %}'></script> <script type="text/javascript" src='{% static 'underscore/underscore.js' %}'></script> <script type="text/javascript"> diff --git a/runtests.py b/runtests.py index 274d508..115c8a2 100644 --- a/runtests.py +++ b/runtests.py @@ -4,7 +4,7 @@ import sys if __name__ == "__main__": os.environ.setdefault( - "DJANGO_SETTINGS_MODULE", 'djangobower.test_settings', + "DJANGO_SETTINGS_MODULE", 'django_yarnpkg.test_settings', ) from django.core.management import execute_from_command_line diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index fa9fe18..0000000 --- a/setup.cfg +++ /dev/null @@ -1 +0,0 @@ -[egg_info] diff --git a/setup.py b/setup.py index d12142f..bd6eeb3 100644 --- a/setup.py +++ b/setup.py @@ -1,11 +1,11 @@ from setuptools import setup, find_packages -version = '5.2.0' +version = '6.0.0' setup( - name='django-bower', + name='django-yarnpkg', version=version, - description="Integrate django with bower", + description="Integrate django with yarnpkg", long_description=open('README.rst').read(), classifiers=[ 'Framework :: Django', @@ -14,9 +14,9 @@ setup( 'Programming Language :: Python :: 3', ], keywords='', - author='Vladimir Iakovlev', - author_email='nvbn.rm@gmail.com', - url='https://github.com/nvbn/django-bower', + author='Dominik George', + author_email='nik@naturalnet.de', + url='https://github.com/Natureshadow/django-yarnpkg', license='BSD', packages=find_packages(exclude=['example']), include_package_data=True, -- GitLab