From 2e8d5a608b7505a64bbbe90e4345a8743462917d Mon Sep 17 00:00:00 2001
From: Dennis Ahrens <dennis.ahrens@hs-hannover.de>
Date: Wed, 8 Nov 2017 17:14:31 +0100
Subject: [PATCH] Support multiple scss include paths

Based on a new settings variable called `SCSS_INCLUDE_PATHS`.
By default hshassets/assets/sass/lib is preconfigured.
---
 hshassets/__init__.py              |  2 ++
 hshassets/app_settings/defaults.py | 11 ++++++++
 hshassets/utils.py                 | 40 ++++++++++++++++++++++++------
 3 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/hshassets/__init__.py b/hshassets/__init__.py
index 6a3d0df5..b7b1ef4f 100644
--- a/hshassets/__init__.py
+++ b/hshassets/__init__.py
@@ -1 +1,3 @@
+import logging
+logger = logging.getLogger('hshassets')
 default_app_config = "hshassets.apps.HshassetsConfig"
diff --git a/hshassets/app_settings/defaults.py b/hshassets/app_settings/defaults.py
index b45d1079..6144f9d6 100644
--- a/hshassets/app_settings/defaults.py
+++ b/hshassets/app_settings/defaults.py
@@ -14,3 +14,14 @@ PIWIK_SITE_ID = None
 #   'f4'      - light blue for faculty 4, "Wirtschaft und Informatik"         - rgb(220, 50,  5)
 #   'f5'      - light blue for faculty 5, "Diakonie, Gesundheit und Soziales" - rgb(210, 60,  150)
 COLOR_SCHEME = 'service'
+
+# need some dependecies already available in another app for your own scss stuff?
+# no problem - by default we already add the hshassets/assets/sass/lib for you
+# but you might define your own, just add your tuple like this:
+# ('app_name', ['path/relative/to/appname/assets', 'another/relative/to/appname/assets']),
+# NOTE: the app must be added to INSTALLED_APPS
+# TODO: if you provide a str instead of tuple this path might be treated absolute or rel to project root!
+# read utils.get_scss_include_paths() for further information
+SCSS_INCLUDE_PATHS = [
+    ('hshassets', ['sass/lib/']),
+]
\ No newline at end of file
diff --git a/hshassets/utils.py b/hshassets/utils.py
index 5941c144..a186301c 100644
--- a/hshassets/utils.py
+++ b/hshassets/utils.py
@@ -1,6 +1,7 @@
 from django.conf import settings
 
-from hshassets.app_settings import COLOR_SCHEME
+from hshassets import logger
+from hshassets.app_settings import COLOR_SCHEME, SCSS_INCLUDE_PATHS
 
 from importlib import import_module
 
@@ -32,6 +33,26 @@ def get_asset_directories():
     return asset_apps
 
 
+def get_scss_include_paths(asset_directories):
+    """ Get additional include_paths for the scss parser - to be able to load e.g. bulma without getting insane """
+    include_paths = []
+    for app_name, rel_paths in SCSS_INCLUDE_PATHS:
+        if app_name in asset_directories.keys():
+            app_meta = asset_directories[app_name]
+            for rel_path in rel_paths:
+                lib_path = os.path.join(app_meta['asset_path'], rel_path)
+                if os.path.exists(lib_path):
+                    include_paths.append(lib_path)
+                else:
+                    logger.warning('You specified an additional scss path which can not be found: {}'.format(lib_path))
+        else:
+            logger.warning(
+                'You specified the app {} in "SCSS_INCLUDE_PATHS" that can not be found. Is it in INSTALLED_APPS?'
+                .format(app_name)
+            )
+    return include_paths
+
+
 def insert_corporate_design_import(filepath):
     content = ''
     tmp_filename = '/sass/_cd_init.tmp.scss'
@@ -51,7 +72,7 @@ def remove_corporate_design_import(filepath):
     os.remove(filepath)
 
 
-def build_scss(app_name, app_directories, verbose=True):
+def build_scss(app_name, app_directories, include_paths, verbose=True):
     if verbose:
         print('Building \033[36msass\033[0m for app "{}" ...'.format(app_name))
 
@@ -75,10 +96,11 @@ def build_scss(app_name, app_directories, verbose=True):
             with open(style_file, 'r') as cdfile:
                 content = cdfile.read() + '\n\n' + content
 
-    sass_path = app_directories['asset_path'] + '/sass'
+    # add this apps sass folder to the include paths
+    include_paths = [os.path.join(app_directories['asset_path'], 'sass')] + include_paths
 
-    expanded_output = sass.compile(string=content, include_paths=[sass_path], output_style='expanded')
-    compressed_output = sass.compile(string=content, include_paths=[sass_path], output_style='compressed')
+    expanded_output = sass.compile(string=content, include_paths=include_paths, output_style='expanded')
+    compressed_output = sass.compile(string=content, include_paths=include_paths, output_style='compressed')
 
     with open(app_directories['static_path'] + '/styles.css', 'w') as outfile:
         outfile.write(expanded_output)
@@ -176,18 +198,20 @@ def discover_app(file_path):
             app_directories = current_app_directories
             break
 
-    return (app_name, app_directories)
+    return app_name, app_directories
 
 
 def do_everything(verbose=False):
-    for app_name, app_directories in get_asset_directories().items():
+    asset_directories = get_asset_directories()
+    include_paths = get_scss_include_paths(asset_directories)
+    for app_name, app_directories in asset_directories.items():
 
         if os.path.isdir(app_directories['static_path']):
             shutil.rmtree(app_directories['static_path'])
 
         os.makedirs(app_directories['static_path'])
 
-        build_scss(app_name, app_directories, verbose=verbose)
+        build_scss(app_name, app_directories, include_paths, verbose=verbose)
         build_javascript(app_name, app_directories, verbose=verbose)
         copy_images(app_name, app_directories, verbose=verbose)
         copy_fonts(app_name, app_directories, verbose=verbose)
-- 
GitLab