Skip to content
bump-version 3.67 KiB
Newer Older
#!/bin/sh
":" ; exec sbcl --script "$0" "$@" ; exit # -*- Lisp -*-
;;; Really runs on any decent Common Lisp implementation

(load (make-pathname :name "prelude" :type "lisp" :defaults *load-pathname*)
  :verbose nil :print nil)
(defvar *adir* (asdf:system-relative-pathname :asdf nil))
(defun afile (x) (subpathname *adir* x))

(defparameter *version-file*
  (afile "version.lisp-expr"))

(defparameter *old-version* nil)
(defparameter *new-version* nil)

(defun next-version (v)
  (let ((pv (parse-version v)))
    (incf (third pv))
    (unparse-version pv)))

(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*))

(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)
                             (external-format *utf-8-external-format*))
  (format t "Transforming file ~A... " (file-namestring file))
  (let* ((old-contents (funcall reader file))
         (new-contents (funcall transformer old-contents)))
        (format t "no changes needed!~%")
        (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.~%")))))
(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)))))
  '(("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)