Recently Written · git

coleslaw

Emacs mode for the "Coleslaw" site generator written in Common Lisp.

git clone https://github.com/equwal/coleslaw

Log | Files | Refs


commit 49288bc1350e905f4dfc9405aca27d02adfc389e
Spenser Truex <web@spensertruex.com>
2020-03-25 17:04:22 -0700

Add git-versioned plugin alternative versioning

More powerful and modern than using symlink versioning. Automatically stages,
commits, and/or uploads the source dir.

 docs/plugin-use.md         | 19 ++++++++++++++++++-
 plugins/git-versioned.lisp | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 src/util.lisp              |  6 ++++++
 3 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/docs/plugin-use.md b/docs/plugin-use.md
index e7cb443..6415db0 100644
--- a/docs/plugin-use.md
+++ b/docs/plugin-use.md
@@ -212,7 +212,24 @@ CL-USER> (chirp:complete-authentication "4173325")
 
 **Example**: `(twitter-summary-card :twitter-handle "@redline6561")
 
-## Versioned Deploys
+## Versioning Deploys
+
+Either [automatic git interaction](#git-versioned) or [double
+versioning](#double-versioning)
+
+### Git Versioned
+
+**Description**: Automatically stages, commits, and/or pushes the server's
+sources. Assumes that a git repository exists in the server's directory. Pushing
+is optional.
+
+**Examples**: 
+`(git-versioned "~/src/dir/" 'stage 'commit 'push)`
+
+
+`(git-versioned "~/src/dir/" 'stage 'commit)`
+
+### Double Versioning
 
 **Description**: Originally, this was Coleslaw's only deploy behavior.
   Instead of deploying directly to `:deploy-dir`, creates `.curr` and
diff --git a/plugins/git-versioned.lisp b/plugins/git-versioned.lisp
new file mode 100644
index 0000000..16cf4d5
--- /dev/null
+++ b/plugins/git-versioned.lisp
@@ -0,0 +1,46 @@
+(defpackage :coleslaw-git-versioned
+  (:use :cl)
+  (:import-from :coleslaw
+                #:*config*
+                #:run-lines)
+  (:import-from :uiop #:ensure-directory-pathname))
+
+(in-package :coleslaw-git-versioned)
+
+(defconstant +nothing-to-commit+ 1
+  "Error code when git-commit has nothing staged to commit.")
+
+;; These have their symbol-functions set in order to close over the src-dir
+;; variable.
+(defun git-versioned ()
+  "Run all git commands as specified in the .coleslawrc.")
+(defun command (args)
+  "Automatically git commit and push the blog to remote."
+  (declare (ignore args)))
+
+(defun enable (src-dir &rest commands)
+  "Define git-versioned functions at runtime."
+  (setf (symbol-function 'git-versioned)
+        (lambda ()
+          (loop for fsym in commands
+                do (funcall (symbol-function (intern (symbol-name fsym)
+                                                     :coleslaw-git-versioned))))))
+  (setf (symbol-function 'command)
+        (lambda (args)
+          (run-lines src-dir
+                     (format nil "git ~A" args)))))
+(defmethod coleslaw:deploy :before (staging)
+  (declare (ignore staging))
+  (git-versioned))
+
+(defun stage () (command "stage -A"))
+(defun commit (&optional (commit-message "Automatic commit."))
+  (handler-case (command (format nil "commit -m '~A'" commit-message))
+    (uiop/run-program:subprocess-error (error)
+      (case (uiop/run-program:subprocess-error-code error)
+        (+nothing-to-commit+ (format t "Nothing to commit. Error ~d"
+                                     +nothing-to-commit+))
+        (otherwise (error error))))))
+
+(defun upload ()
+  (command "push"))
diff --git a/src/util.lisp b/src/util.lisp
index e24e7a6..4e5d6f8 100644
--- a/src/util.lisp
+++ b/src/util.lisp
@@ -100,6 +100,12 @@ If ARGS is provided, use (fmt path args) as the value of PATH."
 use (fmt program args) as the value of PROGRAM."
   (inferior-shell:run (fmt program args) :show t))
 
+(defun run-lines (dir &rest programs)
+  "Runs some programs, in a directory."
+  (mapc (lambda (line)
+          (run-program "cd ~A && ~A" dir line))
+        programs))
+
 (defun take-up-to (n seq)
   "Take elements from SEQ until all elements or N have been taken."
   (subseq seq 0 (min (length seq) n)))