(defparameter *base* "/home/linus/Projects/cl/") (defun read-lines (file) (with-open-file (stream file) (loop for line = (read-line stream NIL) while line when (string/= "" line) collect line))) (defun setup-attributes (path) (with-open-file (stream (merge-pathnames ".gitattributes" path) :direction :output :if-exists :append :if-does-not-exist :create) (terpri stream) (write-line "doc/ linguist-vendored" stream))) (defun determine-year (path) (let* ((content (alexandria:read-file-into-string (first (directory (merge-pathnames "**/*.lisp" path))))) (groups (nth-value 1 (cl-ppcre:scan-to-strings "\\(c\\) (\\d+)" content)))) (if groups (aref groups 0) "2019"))) (defun setup-license-file (path) (with-open-file (stream (merge-pathnames "LICENSE" path) :direction :output :if-exists :supersede :if-does-not-exist :create) (format stream "Copyright (c) ~a Nicolas Hafner This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. " (determine-year path)))) (defun fixup-asd-file (file) (alexandria:write-string-into-file (cl-ppcre:regex-replace-all ":license \"Artistic\"" (alexandria:read-file-into-string file) ":license \"zlib\"") file :if-exists :supersede)) (defun status (format &rest args) (format *query-io* "~& > ~?~%" format args)) (defun prompt (format &rest args) (format *query-io* "~& ? ~?" format args) (read-line *query-io*)) (defun process-repo (base name) (status "Processing ~a" name) (let ((path (pathname-utils:subdirectory *base* name))) (let ((repo (legit:init path :remote (format NIL "~a/~a.git" base name) :if-does-not-exist :clone)) (files (list "LICENSE" ".gitattributes"))) (legit:pull repo) (status "Fixing up files") (setup-attributes path) (setup-license-file path) (dolist (asd (directory (merge-pathnames "**/*.asd" path))) (fixup-asd-file asd) (push asd files)) (status "Changed:~{~% ~a~}" files) (swank:eval-in-emacs `(magit-status ,(uiop:native-namestring path))) (when (prompt "Confirm ~a" path) (legit:add repo files) (legit:commit repo "Update license to zlib. And gitignore docs while we're at it.") (status "Pushing ~a" name) (legit:push repo))))) (defun process-all (base file) (dolist (repo (read-lines file)) (with-simple-restart (abort "Skip ~a" repo) (process-repo base repo))))