Commit 33c9aab8fe385c770934befcf177b2511bc1e538

Thomas de Grivel 2013-08-06T15:29:54

refactor assets and update triangle path

diff --git a/assets.lisp b/assets.lisp
index 140861a..40f8781 100644
--- a/assets.lisp
+++ b/assets.lisp
@@ -45,6 +45,7 @@
 	     (null "")
 	     (symbol (str (string-downcase (symbol-name obj))))
 	     (string obj)
+	     (pathname (format nil "~A" obj))
 	     (t (string obj)))))
 	(t
 	 (apply #'concatenate 'string
@@ -54,14 +55,18 @@
 
 (defvar *debug* nil)
 
-(defvar *assets-dirs*
+(defvar *default-assets-dirs*
   '("lib/*/triangle/assets/*/"
+    "lib/triangle/*/triangle/assets/*/"
     "app/assets/*/"
     "assets/*/"))
 
-(defvar *precompiled-assets*
-  '("all.css"
-    "all.js"
+(defparameter *assets-dirs*
+  *default-assets-dirs*)
+
+(defvar *default-precompiled-assets*
+  '("app.css"
+    "app.js"
     "**/*.jpeg"
     "**/*.jpg"
     "**/*.png"
@@ -70,6 +75,15 @@
     "**/*.ttf"
     "**/*.woff"))
 
+(defparameter *precompiled-assets*
+  *default-precompiled-assets*)
+
+(defvar *asset-url-prefix* "/assets/")
+
+(defvar *asset-path-prefix* "public/assets/")
+
+;;  Config stanzas
+
 (defun assets-dir (pathspec)
   (let* ((namestring (enough-namestring pathspec))
 	 (path (if (char= #\/ (last-elt namestring))
@@ -80,6 +94,8 @@
 (defun precompiled-asset (asset-name)
   (pushnew asset-name *precompiled-assets* :test #'string=))
 
+;;  Read config
+
 (defun assets-dirs ()
   (cache-1 (eq *assets-dirs*)
     (directories (reverse *assets-dirs*))))
@@ -106,19 +122,24 @@
   (declare (type asset asset))
   (let ((name (asset-name asset))
 	(ext (asset-ext asset)))
-    (str "/assets/" name (when ext ".") ext)))
+    (str *asset-url-prefix* name (when ext ".") ext)))
 
 (defun asset-path (asset)
   (declare (type asset asset))
   (let ((name (asset-name asset))
 	(ext (asset-ext asset)))
-    (str "public/assets/" name (when ext ".") ext)))
+    (str *asset-path-prefix* name (when ext ".") ext)))
 
 (defun asset-source-path (asset)
   (declare (type asset asset))
   (with-slots (name source-dir source-ext) asset
     (str source-dir name (when source-ext ".") source-ext)))
 
+(defun asset-debug-path (asset)
+  (declare (type asset asset))
+  (with-slots (name source-dir source-ext) asset
+    (str source-dir name ".debug" (when source-ext ".") source-ext)))
+
 (defmethod print-object ((asset asset) stream)
   (print-unreadable-object (asset stream :type t)
     (ignore-errors (format stream "~S" (asset-path asset)))
diff --git a/find.lisp b/find.lisp
index f39e763..2f4fe2c 100644
--- a/find.lisp
+++ b/find.lisp
@@ -44,12 +44,15 @@
 			(name string)
 			(ext symbol)
 			assets)
-  (let ((absolute-dir (merge-pathnames dir))
+  (let ((absolute-dir (truename dir))
 	(assets assets))
-    (dolist (path (directory (str dir name (when ext ".") ext)
-			     :resolve-symlinks nil))
-      (let ((name (enough-namestring (make-pathname :type nil :defaults path)
-				     absolute-dir)))
+    (dolist (path (directory (str dir name (when ext ".") ext)))
+      (let* ((name.ext (enough-namestring (truename path) absolute-dir))
+	     (name (if ext
+		       (subseq name.ext 0 (- (length name.ext)
+					     (length (string ext))
+					     1))
+		       name.ext)))
 	(unless (find-in-assets type dir name ext assets)
 	  (push (make-instance type
 			       :name name
@@ -115,12 +118,20 @@
        ,@body)))
 
 (defun find-assets-from-spec (spec &optional class assets)
-  (with-asset-spec spec (name ext)
-    (find-assets (or class (extension-asset-class ext))
-		 nil name nil assets)))
+  (let ((new-assets (if class
+			(find-assets class nil spec nil assets)
+			assets)))
+    (if (eq assets new-assets)
+	(with-asset-spec spec (name ext)
+	  (find-assets (or class (extension-asset-class ext))
+		       nil name nil assets))
+	new-assets)))
 
 (defun find-assets-from-specs (specs &optional class assets)
   (reduce (lambda (assets spec)
 	    (find-assets-from-spec spec class assets))
 	  specs
 	  :initial-value assets))
+
+(defun find-asset (spec &optional class)
+  (first (find-assets-from-spec spec class)))
diff --git a/lowh.triangle.assets.precompile.asd b/lowh.triangle.assets.precompile.asd
index 836d2e9..55b06c8 100644
--- a/lowh.triangle.assets.precompile.asd
+++ b/lowh.triangle.assets.precompile.asd
@@ -31,7 +31,8 @@
 	       "cl-uglify-js"
 	       "closer-mop"
 	       "exec-js"
-	       "lowh.triangle.assets")
+	       "lowh.triangle.assets"
+	       "lowh.triangle.files")
   :components
   ((:module "precompile"
 	    :components
diff --git a/package.lisp b/package.lisp
index 71e5916..024ce4a 100644
--- a/package.lisp
+++ b/package.lisp
@@ -19,19 +19,27 @@
 (in-package :cl-user)
 
 (defpackage :lowh.triangle.assets
-  (:nicknames :L.>.assets)
-  (:use :cl :alexandria :lowh.triangle.files)
+  (:nicknames :L>assets)
+  (:use :cl :alexandria :L>files)
   (:export
    ;;  Config
+   #:*debug*
+   #:*asset-url-prefix*
+   #:*asset-path-prefix*
    #:*assets-dirs* #:assets-dir
    #:*precompiled-assets* #:precompiled-asset
+   ;;  Strings
+   #:str
    ;;  Observers
-   #:asset-path
+   #:asset-path #:asset-url
    #:assets-dirs
+   #:find-asset #:find-assets-from-spec #:find-assets-from-specs
+   #:locate-precompiled-assets
    ;;  Precompile
    #:debug-msg
    #:msg
    #:with-msg-indent
+   #:compile-asset
    #:precompile
    #:generator
    #:generate))
diff --git a/precompile/generate.lisp b/precompile/generate.lisp
index 9048cee..50291d8 100644
--- a/precompile/generate.lisp
+++ b/precompile/generate.lisp
@@ -40,4 +40,5 @@
 (defun generate ()
   (msg "Generate")
   (with-msg-indent (1)
+    (mapc #'generate/file (directory "lib/triangle/*/triangle/assets.lisp"))
     (mapc #'generate/file (directory "lib/*/triangle/assets.lisp"))))
diff --git a/precompile/precompile.lisp b/precompile/precompile.lisp
index 2379297..49c64bc 100644
--- a/precompile/precompile.lisp
+++ b/precompile/precompile.lisp
@@ -25,7 +25,7 @@
 (defmethod compile-asset ((asset asset) (output pathname))
   (ensure-directories-exist output)
   (let ((path (asset-source-path asset)))
-    (msg "~A" path)
+    (msg "CP ~A" path)
     (copy-files path output :replace t :update t)
     nil))
 
@@ -38,8 +38,18 @@
 					  output))
 		    assets))
       (with-output-to-file/utf-8 (out output)
-	(dolist (a assets)
-	  (process-asset a out (not (eq asset a))))))))
+	(cond
+	  ((find :assets *debug*)
+	   (dolist (a assets)
+	     (msg "P ~A" (asset-source-path a))
+	     (if (eq asset a)
+		 (process-asset a out)
+		 (progn (include-asset a out)
+			(copy-files (asset-source-path a)
+				    (asset-path a))))))
+	  (t (dolist (a assets)
+	       (msg "P ~A" (asset-source-path a))
+	       (process-asset a out))))))))
 
 ;;  Precompile
 
diff --git a/precompile/preprocess.lisp b/precompile/preprocess.lisp
index a0e8e58..31ff785 100644
--- a/precompile/preprocess.lisp
+++ b/precompile/preprocess.lisp
@@ -1,6 +1,5 @@
 ;;
 ;;  Assets  -  Asset pipeline
-;;  Assets  -  Asset pipeline
 ;;
 ;;  Copyright 2012 Thomas de Grivel <billitch@gmail.com>
 ;;
@@ -28,12 +27,12 @@
 	  :initial-value assets))
 
 (defun preprocess/comment (asset comment assets)
-  (debug-msg "Comment ~S" comment)
+  #+nil(debug-msg "Comment ~S" comment)
   (or (cl-ppcre:register-groups-bind (command arguments)
 	  ("^\\W*=\\s*(\\w+)(\\s+\\S+)*\\s*$" comment)
 	(let ((arg-list (rest (cl-ppcre:split "\\s+" arguments))))
 	  (cond ((string= "require" command)
-		 (preprocess/require asset arg-list assets))
+		 (setf assets (preprocess/require asset arg-list assets)))
 		(t
 		 (warn "Unknown preprocessor command : ~A ~S"
 		       command arg-list)
@@ -48,8 +47,7 @@
     t))
 
 (defun preprocess/stream (asset stream assets &optional stack)
-  (let ((assets assets)
-	(line (read-line stream nil))
+  (let ((line (read-line stream nil))
 	start comment end)
     (or (when line
 	  (cl-ppcre:register-groups-bind (s c e)
@@ -74,10 +72,10 @@
 
 (defun preprocess/asset (asset assets)
   (let ((path (asset-source-path asset)))
-    (msg "~A" path)
+    (msg "PP ~A" path)
     (with-msg-indent (1)
       (with-input-from-file/utf-8 (input path)
 	(preprocess/stream asset input assets)))))
 
-(defun preprocess-asset (asset &optional assets)
-  (preprocess/asset asset assets))
+(defun preprocess-asset (asset)
+  (nreverse (preprocess/asset asset nil)))
diff --git a/precompile/process.lisp b/precompile/process.lisp
index 384159d..fe5ad8b 100644
--- a/precompile/process.lisp
+++ b/precompile/process.lisp
@@ -18,7 +18,9 @@
 
 (in-package :lowh.triangle.assets)
 
-(defgeneric process-asset (asset output included-p))
+(defgeneric process-asset (asset output))
+
+(defgeneric include-asset (asset output))
 
 ;;  CSS
 
@@ -70,26 +72,43 @@ try {
     (exec-js:from-string js :safely nil :out out)))
 
 (defmethod process-asset ((asset css-asset)
-			  (output stream)
-			  included-p)
+			  (output stream))
   (let ((true-assets-dirs (cache-1 (eq *assets-dirs*)
 			    (mapcar #'truename (assets-dirs))))
 	(path (asset-source-path asset)))
     (less path
 	  (list :paths true-assets-dirs	:filename path)
-	  (list :yuicompress t)
+	  (list :yuicompress (not *debug*))
 	  output))
   (values))
 
+(defmethod include-asset ((asset css-asset)
+			  (output stream))
+  (format output "@import url('~A');~%" (asset-url asset)))
+
 ;;  JS
 
 (defmethod process-asset ((asset js-asset)
-			  (output stream)
-			  included-p)
-  (write-string (with-input-from-file/utf-8 (js (asset-source-path asset))
-		  (cl-uglify-js:ast-gen-code (cl-uglify-js:ast-mangle
-					      (cl-uglify-js:ast-squeeze
-					       (parse-js:parse-js js)))
-					     :beautify nil))
-		output)
+			  (output stream))
+  (with-input-from-file/utf-8 (js (asset-source-path asset))
+    (if (find :js *debug*)
+	(progn (copy-stream js output)
+	       (terpri output))
+	(write-string (cl-uglify-js:ast-gen-code (cl-uglify-js:ast-mangle
+						  (cl-uglify-js:ast-squeeze
+						   (parse-js:parse-js js)))
+						 :beautify nil)
+		      output)))
   (values))
+
+(defmethod include-asset ((asset js-asset)
+			  (output stream))
+  (format output "(function () {
+  var head = document.getElementsByTagName('head')[0];
+  var s = document.createElement('script');
+  s.type = 'text/javascript';
+  s.src = ~S;
+  head.appendChild(s);
+})();
+"
+	  (asset-url asset)))