Skip to content

Instantly share code, notes, and snippets.

@tgecho
Created October 19, 2012 00:19
Show Gist options
  • Save tgecho/3915553 to your computer and use it in GitHub Desktop.
Save tgecho/3915553 to your computer and use it in GitHub Desktop.
A proof of concept for automatic dependency detection
import re
from os import path, stat
from webassets import Bundle
from webassets.exceptions import BundleError
DEPENDS_REGEXES = map(re.compile, [
# http://stackoverflow.com/questions/4652777/java-regex-to-get-the-urls-from-css
# With addon to handle quotes
r'url[\s]*\([\s\'\"]*(?P<url>[^\)\'\"]*)[\s\'\"]*\)[\s]*',
r'@import[\s]*[\"|\'](?P<url>[^\'\"]*)[\"|\']',
])
PARSE_FILETYPES = ('css', 'scss', 'sass')
def cache_key(resolved_path):
return (resolved_path, str(stat(resolved_path).st_mtime))
def resolve_dependency(item, env):
try:
result = env.resolver.resolve_source(item)
except IOError, e:
raise BundleError(e)
if not isinstance(result, list):
result = [result]
return result
def get_dependencies(subject_path, env):
resolved_sources = resolve_dependency(subject_path, env)
subject_dir = path.dirname(subject_path)
depends = []
for resolved_path in resolved_sources:
cached = env.cache.get(cache_key(resolved_path), python=True) or {}
if cached:
return cached.keys()
with open(resolved_path) as source:
source_data = source.read()
for regex in DEPENDS_REGEXES:
for match in regex.findall(source_data):
normalized = path.normpath(path.join(subject_dir, match))
resolved = resolve_dependency(normalized, env)
depends.extend(resolved)
for dep in resolved:
cached[dep] = stat(dep).st_mtime
env.cache.set(cache_key(resolved_path), cached)
return depends
def recurse_dependencies(sources, global_depends, env):
for source in sources:
if source.rsplit('.', 1)[-1] in PARSE_FILETYPES:
depends = [d for d in get_dependencies(source, env=env) if d not in global_depends]
if depends:
global_depends.extend(depends)
recurse_dependencies(depends, global_depends, env=env)
class AutoDependsBundle(Bundle):
def resolve_depends(self, env):
depends = super(AutoDependsBundle, self).resolve_depends(env)
recurse_dependencies(list(self.contents) + depends, depends, env=env)
return depends
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment