Newer
Older
Francois-Rene Rideau
committed
":" ; exec sbcl --script "$0" "$@" ; exit # -*- Lisp -*-
;;; Really runs on any decent Common Lisp implementation
Francois-Rene Rideau
committed
(load (make-pathname :name "prelude" :type "lisp" :defaults *load-pathname*)
:verbose nil :print nil)
Francois-Rene Rideau
committed
(in-package :fare-utils)
Francois-Rene Rideau
committed
Francois-Rene Rideau
committed
(defvar *adir* (asdf:system-relative-pathname :asdf nil))
Francois-Rene Rideau
committed
Francois-Rene Rideau
committed
(defun afile (x) (subpathname *adir* x))
Francois-Rene Rideau
committed
(defparameter *version-file*
(afile "version.lisp-expr"))
Francois-Rene Rideau
committed
(defparameter *old-version* nil)
(defparameter *new-version* nil)
Francois-Rene Rideau
committed
(defun next-version (v)
(let ((pv (parse-version v)))
(incf (third pv))
(unparse-version pv)))
Francois-Rene Rideau
committed
(defun version-from-file ()
(safe-read-first-file-form *version-file*))
(defun versions-from-argv (argv)
(ecase (length argv)
((2) (values (second argv) (first argv)))
((1) (values (version-from-file) (first argv)))
((0) (let ((old (version-from-file)))
(values old (next-version old))))))
(multiple-value-setq (*old-version* *new-version*)
(versions-from-argv *command-line-arguments*))
Francois-Rene Rideau
committed
(format t "Bumping ASDF version from ~A to ~A~%" *old-version* *new-version*)
(deftype byte-vector () '(array (unsigned-byte 8) (*)))
(defun maybe-replace-file (file transformer
&key (reader 'read-file-string)
Francois-Rene Rideau
committed
(writer nil) (comparator 'equalp)
Francois-Rene Rideau
committed
(external-format *utf-8-external-format*))
(format t "Transforming file ~A... " (file-namestring file))
Francois-Rene Rideau
committed
(let* ((old-contents (funcall reader file))
(new-contents (funcall transformer old-contents)))
Francois-Rene Rideau
committed
(if (funcall comparator old-contents new-contents)
(format t "no changes needed!~%")
Francois-Rene Rideau
committed
(let ((written-contents
(if writer
(with-output (s ())
(funcall writer s new-contents))
new-contents)))
(check-type written-contents (or string (byte-vector)))
(clobber-file-with-vector file written-contents :external-format external-format)
(format t "done.~%")))))
Francois-Rene Rideau
committed
Francois-Rene Rideau
committed
(defun version-transformer (new-version file prefix suffix)
(let* ((qprefix (cl-ppcre:quote-meta-chars prefix))
(versionrx "([0-9]+(\\.[0-9]+)+)")
(qsuffix (cl-ppcre:quote-meta-chars suffix))
(regex (strcat "(" qprefix ")(" versionrx ")(" qsuffix ")"))
(replacement
(constantly (strcat prefix new-version suffix))))
(lambda (text)
(multiple-value-bind (new-text foundp)
(cl-ppcre:regex-replace regex text replacement)
(unless (or foundp t)
(warn "Missing version in ~A" (file-namestring file)))
(values new-text foundp)))))
Francois-Rene Rideau
committed
(defparameter *versioned-files*
Francois-Rene Rideau
committed
'(("version.lisp-expr" "\"" "\"")
("asdf.asd" " :version \"" "\" ;; to be automatically updated by bin/bump-revision")
("header.lisp" "This is ASDF " ": Another System Definition Facility.")
("upgrade.lisp" " (asdf-version \"" "\")")))
(defun transform-file (new-version file prefix suffix)
(maybe-replace-file (afile file) (version-transformer new-version file prefix suffix)))
(defun transform-files ()
(loop :for f :in *versioned-files* :do (apply 'transform-file *new-version* f)))
(defun test-transform-file (new-version file prefix suffix)
(let ((lines (read-file-lines (afile file))))
(dolist (l lines (progn (warn "Couldn't find a match in ~A" file) nil))
(multiple-value-bind (new-text foundp)
(funcall (version-transformer new-version file prefix suffix) l)
(when foundp
(format t "Found a match:~% ==> ~A~%Replacing with~% ==> ~A~%~%"
l new-text)
(return t))))))
(defun z () (apply 'test-transform-file *new-version* (first *versioned-files*)))
(transform-files)