Skip to content

Commit 85121b6

Browse files
committed
Moved djangobwr into the local repository, due to consistent difficulties pulling it from github as an svn:external
- Legacy-Id: 16566
1 parent c22d0b9 commit 85121b6

7 files changed

Lines changed: 245 additions & 0 deletions

File tree

djangobwr/__init__.py

Whitespace-only changes.

djangobwr/finders.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.contrib.staticfiles.finders import AppDirectoriesFinder
2+
3+
class AppDirectoriesFinderBower(AppDirectoriesFinder):
4+
5+
def list(self, ignore_patterns):
6+
"""
7+
List all files in all app storages.
8+
"""
9+
ignore_patterns.append("bower_components")
10+
return super(AppDirectoriesFinderBower, self).list(ignore_patterns)

djangobwr/management/__init__.py

Whitespace-only changes.

djangobwr/management/commands/__init__.py

Whitespace-only changes.
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
import os
2+
import sys
3+
import json
4+
import tempfile
5+
import shutil
6+
import hashlib
7+
import glob
8+
import textwrap
9+
from subprocess import call, check_output, CalledProcessError
10+
from optparse import make_option
11+
12+
import debug # pyflakes:ignore
13+
14+
from django.core.management.base import BaseCommand
15+
from django.core.files.storage import FileSystemStorage
16+
from django.conf import settings
17+
from django.contrib.staticfiles.finders import BaseStorageFinder, AppDirectoriesFinder
18+
19+
class BaseDirectoryFinder(BaseStorageFinder):
20+
storage = FileSystemStorage(location=settings.BASE_DIR)
21+
22+
class Command(BaseCommand):
23+
"""
24+
25+
This command goes through any static/ directories of installed apps,
26+
and the directories listed in settings.STATICFILES_DIRS. If package
27+
description files for bower, npm, or grunt are found in any of these
28+
locations, it will use the appropriate package manager to install the
29+
listed packages in a temporary folder, using these commands:
30+
31+
- package.json: npm install
32+
- Gruntfile.js: grunt default
33+
- bower.json: bower install
34+
35+
It will then extract the distribution files to the location indicated in
36+
settings.COMPONENT_ROOT.
37+
"""
38+
help = textwrap.dedent(__doc__).lstrip()
39+
component_root = getattr(settings, 'COMPONENT_ROOT', os.path.join(settings.STATIC_ROOT, "components"))
40+
41+
def add_arguments(self, parser):
42+
parser.add_argument('--with-version', dest='with_version', default=False, action='store_true',
43+
help='Create component directories with version numbers')
44+
parser.add_argument('--keep-packages', dest='keep_packages', default=False, action='store_true',
45+
help='Keep the downloaded bower packages, instead of removing them after moving '
46+
'distribution files to settings.COMPONENT_ROOT')
47+
48+
bower_info = {}
49+
overrides = {}
50+
51+
def npm_install(self, pkg_json_path):
52+
os.chdir(os.path.dirname(pkg_json_path))
53+
call(['npm', 'install'])
54+
55+
def grunt_default(self, grunt_js_path):
56+
os.chdir(os.path.dirname(grunt_js_path))
57+
call(['grunt'])
58+
59+
def bower_install(self, bower_json_path, dest_dir):
60+
"""Runs bower commnand for the passed bower.json path.
61+
62+
:param bower_json_path: bower.json file to install
63+
:param dest_dir: where the compiled result will arrive
64+
"""
65+
66+
# Verify that we are able to run bower, in order to give a good error message in the
67+
# case that it's not installed. Do this separately from the 'bower install' call, in
68+
# order not to warn about a missing bower in the case of installation-related errors.
69+
try:
70+
bower_version = check_output(['bower', '--version']).strip()
71+
except OSError as e:
72+
print("Trying to run bower failed -- is it installed? The error was: %s" % e)
73+
exit(1)
74+
except CalledProcessError as e:
75+
print("Checking the bower version failed: %s" % e)
76+
exit(2)
77+
78+
print("\nBower %s" % bower_version)
79+
print("Installing from %s\n" % bower_json_path)
80+
81+
# bower args
82+
args = ['bower', 'install', bower_json_path,
83+
'--verbose', '--config.cwd={}'.format(dest_dir), '-p']
84+
85+
# run bower command
86+
call(args)
87+
88+
def get_bower_info(self, bower_json_path):
89+
if not bower_json_path in self.bower_info:
90+
self.bower_info[bower_json_path] = json.load(open(bower_json_path))
91+
92+
def get_bower_main_list(self, bower_json_path, override):
93+
"""
94+
Returns the bower.json main list or empty list.
95+
Applies overrides from the site-wide bower.json.
96+
"""
97+
self.get_bower_info(bower_json_path)
98+
99+
main_list = self.bower_info[bower_json_path].get('main')
100+
component = self.bower_info[bower_json_path].get('name')
101+
102+
if (override in self.bower_info
103+
and "overrides" in self.bower_info[override]
104+
and component in self.bower_info[override].get("overrides")
105+
and "main" in self.bower_info[override].get("overrides").get(component)):
106+
main_list = self.bower_info[override].get("overrides").get(component).get("main")
107+
108+
if isinstance(main_list, list):
109+
return main_list
110+
111+
if main_list:
112+
return [main_list]
113+
114+
return []
115+
116+
def get_bower_version(self, bower_json_path):
117+
"""Returns the bower.json main list or empty list.
118+
"""
119+
self.get_bower_info(bower_json_path)
120+
121+
return self.bower_info[bower_json_path].get("version")
122+
123+
def clean_components_to_static_dir(self, bower_dir, override):
124+
print("\nMoving component files to %s\n" % (self.component_root,))
125+
126+
for directory in os.listdir(bower_dir):
127+
print("Component: %s" % (directory, ))
128+
129+
src_root = os.path.join(bower_dir, directory)
130+
131+
for bower_json in ['bower.json', '.bower.json']:
132+
bower_json_path = os.path.join(src_root, bower_json)
133+
if os.path.exists(bower_json_path):
134+
main_list = self.get_bower_main_list(bower_json_path, override) + ['bower.json']
135+
version = self.get_bower_version(bower_json_path)
136+
137+
dst_root = os.path.join(self.component_root, directory)
138+
if self.with_version:
139+
assert not dst_root.endswith(os.sep)
140+
dst_root += "-"+version
141+
142+
for pattern in filter(None, main_list):
143+
src_pattern = os.path.join(src_root, pattern)
144+
# main_list elements can be fileglob patterns
145+
for src_path in glob.glob(src_pattern):
146+
if not os.path.exists(src_path):
147+
print("Could not find source path: %s" % (src_path, ))
148+
149+
# Build the destination path
150+
src_part = src_path[len(src_root+'/'):]
151+
if src_part.startswith('dist/'):
152+
src_part = src_part[len('dist/'):]
153+
dst_path = os.path.join(dst_root, src_part)
154+
155+
# Normalize the paths, for good looks
156+
src_path = os.path.abspath(src_path)
157+
dst_path = os.path.abspath(dst_path)
158+
159+
# Check if we need to copy the file at all.
160+
if os.path.exists(dst_path):
161+
with open(src_path) as src:
162+
src_hash = hashlib.sha1(src.read()).hexdigest()
163+
with open(dst_path) as dst:
164+
dst_hash = hashlib.sha1(dst.read()).hexdigest()
165+
if src_hash == dst_hash:
166+
#print('{0} = {1}'.format(src_path, dst_path))
167+
continue
168+
169+
# Make sure dest dir exists.
170+
dst_dir = os.path.dirname(dst_path)
171+
if not os.path.exists(dst_dir):
172+
os.makedirs(dst_dir)
173+
174+
print(' {0} > {1}'.format(src_path, dst_path))
175+
shutil.copy(src_path, dst_path)
176+
break
177+
178+
def handle(self, *args, **options):
179+
180+
self.with_version = options.get("with_version")
181+
self.keep_packages = options.get("keep_packages")
182+
183+
temp_dir = getattr(settings, 'BWR_APP_TMP_FOLDER', 'tmp')
184+
temp_dir = os.path.abspath(temp_dir)
185+
186+
# finders
187+
basefinder = BaseDirectoryFinder()
188+
appfinder = AppDirectoriesFinder()
189+
# Assume bower.json files are to be found in each app directory,
190+
# rather than in the app's static/ subdirectory:
191+
appfinder.source_dir = '.'
192+
193+
finders = (basefinder, appfinder, )
194+
195+
if os.path.exists(temp_dir):
196+
if not self.keep_packages:
197+
sys.stderr.write(
198+
"\nWARNING:\n\n"
199+
" The temporary package installation directory exists, but the --keep-packages\n"
200+
" option has not been given. In order to not delete anything which should be\n"
201+
" kept, %s will not be removed.\n\n"
202+
" Please remove it manually, or use the --keep-packages option to avoid this\n"
203+
" message.\n\n" % (temp_dir,))
204+
self.keep_packages = True
205+
else:
206+
os.makedirs(temp_dir)
207+
208+
for finder in finders:
209+
for path in finder.find('package.json', all=True):
210+
self.npm_install(path)
211+
212+
for finder in finders:
213+
for path in finder.find('Gruntfile.json', all=True):
214+
self.grunt_default(path)
215+
216+
for finder in finders:
217+
for path in finder.find('bower.json', all=True):
218+
self.get_bower_info(path)
219+
self.bower_install(path, temp_dir)
220+
221+
bower_dir = os.path.join(temp_dir, 'bower_components')
222+
223+
# nothing to clean
224+
if not os.path.exists(bower_dir):
225+
print('No components seems to have been found by bower, exiting.')
226+
sys.exit(0)
227+
228+
self.clean_components_to_static_dir(bower_dir, path)
229+
230+
if not self.keep_packages:
231+
shutil.rmtree(temp_dir)
232+

djangobwr/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.db import models
2+
3+
# Create your models here.

djangobwr/storage.py

Whitespace-only changes.

0 commit comments

Comments
 (0)