Created
March 29, 2012 14:39
-
-
Save Neronus/2238044 to your computer and use it in GitHub Desktop.
pre-commit hook in lisp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!lisp --script | |
(defpackage cve.pre-commit | |
(:use :cl :named-readtables :clesh :alexandria)) | |
(in-package cve.pre-commit) | |
(in-readtable clesh:syntax) | |
(defvar *interactive* nil | |
"Indicates if we should drop into a debugger if an error (T) | |
occurs or if we should just exit the program with a non-zero value (NIL).") | |
(defvar *set-up-p* nil | |
"Did we already prepare the git repository?") | |
(defun set-up () | |
"Prepare repository to be in the state it would have after the commit. | |
Call TEAR-DOWN to reset. | |
Signals an error if set-up is called twice without tear-down." | |
(when *set-up-p* | |
(error "set-up called twice without tear-down")) | |
(or-exit [ git stash --keep-index ]) | |
(setf *set-up-p* t)) | |
(defun tear-down () | |
"Reset repository to the state it had before calling SET-UP. | |
Only to be called after a call to SET-UP." | |
(when (not *set-up-p*) | |
(error "tear-down without set-up called")) | |
(or-exit [ git stash pop ]) | |
(setf *set-up-p* nil)) | |
(defun exit (code) | |
"Exit program with exit-code CODE. Makes sure that git repository | |
is in the state it was in before the program started." | |
(when *set-up-p* | |
(tear-down)) | |
(sb-ext:quit :unix-status code)) | |
(defmacro or-exit (script) | |
"Run SCRIPT (which is expected to be a clesh:script command; | |
can also come from [ ... ] syntax). | |
If the return value is ZERO, just return all the values of SCRIPT. | |
Otherwise and if *INTERACTIVE* is NIL, call EXIT. | |
Otherwise signal an error." | |
(with-gensyms (stdout stderr code string) | |
`(multiple-value-bind (,stdout ,stderr ,code) ,script | |
(if (not (zerop ,code)) | |
(let | |
((,string (concatenate 'string ,@(cdr script)))) | |
(if *interactive* | |
(error "~A returned non-zero value" ,string) | |
(progn | |
(write-string ,stdout) | |
(format t "~A returned non-zero value~%" | |
,string) | |
(exit ,code)))) | |
(values ,stdout ,stderr ,code))))) | |
(defun check-make (directory) | |
"Enter DIRECTORY and call make. Exit with Exit-code of make, | |
if its exit code was not zero. Returns the values of its | |
internal script otherwise." | |
(or-exit | |
[ cd ?directory | |
make 2>&1 | |
exit $\?])) | |
(defparameter *make-files* | |
'("$HOME/Work/git/Papers/Repair/")) | |
(defun main () | |
(set-up) | |
(dolist (make *make-files*) | |
(format t "Checking make for ~A~%" make) | |
(check-make make)) | |
(exit 0)) | |
(unless *interactive* (main)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment