From f8d1391e0eb7eb0609a7f7070d369949d0b67dfa Mon Sep 17 00:00:00 2001 From: inaimathi Date: Tue, 10 Oct 2017 19:07:47 -0400 Subject: [PATCH 1/8] Basic changes - README.txt is now README.md - depends-on is now validated to be a list, and is passed to templates - Some filenames are now forced to lower-case for naming compatibility reasons --- quickproject.lisp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/quickproject.lisp b/quickproject.lisp index 8025253..32620af 100644 --- a/quickproject.lisp +++ b/quickproject.lisp @@ -9,6 +9,9 @@ (defvar *template-directory* nil "A directory to use as a source of template files.") +(defvar *depends-on* nil + "Dependencies specified at project creation") + (defvar *author* "Your Name " "Set this variable to your contact information.") @@ -65,7 +68,7 @@ not already exist." (terpri stream)) (defun write-system-file (name file &key depends-on) - (with-new-file (stream file) + (with-new-file (stream (string-downcase file)) (file-comment-header stream) (write-system-form name :depends-on depends-on @@ -85,7 +88,7 @@ not already exist." (format stream " (:use #:cl))~%~%"))) (defun write-application-file (name file) - (with-new-file (stream file) + (with-new-file (stream (string-downcase file)) (file-comment-header stream) (format stream "(in-package ~S)~%~%" (uninterned-symbolize name)) (format stream ";;; ~S goes here. Hacks and glory await!~%~%" name))) @@ -128,7 +131,8 @@ marker is the string \"\(#|\" and the template end marker is the string "Return a plist of :NAME, :LICENSE, and :AUTHOR parameters." (list :name *name* :license *license* - :author *author*)) + :author *author* + :depends-on *depends-on*)) (defvar *template-parameter-functions* (list 'default-template-parameters) "A list of functions that return plists for use when rewriting @@ -142,19 +146,20 @@ marker is the string \"\(#|\" and the template end marker is the string (mapcar 'funcall *template-parameter-functions*))) (defun make-project (pathname &key - depends-on template-parameters ((:template-directory *template-directory*) *template-directory*) + ((:depends-on *depends-on*) *depends-on*) ((:author *author*) *author*) ((:license *license*) *license*) (name (pathname-project-name pathname) name-provided-p) ((:include-copyright *include-copyright*) *include-copyright*)) "Create a project skeleton for NAME in PATHNAME. If DEPENDS-ON is provided, it is used as the asdf defsystem depends-on list." + (check-type depends-on list) (when (pathname-name pathname) (warn "Coercing ~S to directory" - pathname) + pathname) (setf pathname (pathname-as-directory pathname)) (unless name-provided-p (setf name (pathname-project-name pathname)))) @@ -163,7 +168,7 @@ it is used as the asdf defsystem depends-on list." (nametype (type) (relative (make-pathname :name name :type type)))) (ensure-directories-exist pathname) - (write-readme-file name (relative "README.txt")) + (write-readme-file name (relative "README.md")) (write-system-file name (nametype "asd") :depends-on depends-on) (write-package-file name (relative "package.lisp")) (write-application-file name (nametype "lisp")) From 07c4ea26fdf223d205df43e1442210f2c0bdd94f Mon Sep 17 00:00:00 2001 From: inaimathi Date: Tue, 10 Oct 2017 19:21:43 -0400 Subject: [PATCH 2/8] Moderate changes - Provide default template directory complete with README and package file - Output README and package files exclusively from the template directory instead of defining write-*-file functions in quickproject - add .gitignore file - undo some case changes for the moment --- .gitignore | 1 + default-template/README.md | 8 ++++++++ default-template/package.lisp | 2 ++ quickproject.lisp | 32 +++++++++----------------------- 4 files changed, 20 insertions(+), 23 deletions(-) create mode 100644 .gitignore create mode 100644 default-template/README.md create mode 100644 default-template/package.lisp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4e5f6c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ \ No newline at end of file diff --git a/default-template/README.md b/default-template/README.md new file mode 100644 index 0000000..83403f1 --- /dev/null +++ b/default-template/README.md @@ -0,0 +1,8 @@ +# (#| TMPL_VAR name |#) +### _(#| TMPL_VAR author |#)_ + +This is a project to do ... something. + +## License + +(#| TMPL_VAR license |#) diff --git a/default-template/package.lisp b/default-template/package.lisp new file mode 100644 index 0000000..4171bcc --- /dev/null +++ b/default-template/package.lisp @@ -0,0 +1,2 @@ +(defpackage #:(#| TMPL_VAR name |#) + (:use #:cl)) diff --git a/quickproject.lisp b/quickproject.lisp index 32620af..b9a0cf7 100644 --- a/quickproject.lisp +++ b/quickproject.lisp @@ -6,7 +6,7 @@ (setf (documentation '*name* 'variable) "The name of the project currently being created.") -(defvar *template-directory* nil +(defvar *template-directory* (asdf/system:system-relative-pathname :quickproject "default-template") "A directory to use as a source of template files.") (defvar *depends-on* nil @@ -40,7 +40,7 @@ string designator and upcased." (mapcar #'uninterned-symbolize depends-on))) (format stream " :serial t~%") (format stream " :components ((:file \"package\")~%") - (format stream " (:file ~S)))~%" (string-downcase name)))) + (format stream " (:file ~(~S~))))~%" name))) (defun pathname-project-name (pathname) "Return a project name based on PATHNAME by taking the last element @@ -68,27 +68,15 @@ not already exist." (terpri stream)) (defun write-system-file (name file &key depends-on) - (with-new-file (stream (string-downcase file)) + (with-new-file (stream file) (file-comment-header stream) (write-system-form name :depends-on depends-on :stream stream) (terpri stream))) -(defun write-readme-file (name file) - (with-new-file (stream file) - (format stream "This is the stub ~A for the ~S project.~%" - (file-namestring file) - name))) - -(defun write-package-file (name file) - (with-new-file (stream file) - (file-comment-header stream) - (format stream "(defpackage ~S~%" (uninterned-symbolize name)) - (format stream " (:use #:cl))~%~%"))) - (defun write-application-file (name file) - (with-new-file (stream (string-downcase file)) + (with-new-file (stream file) (file-comment-header stream) (format stream "(in-package ~S)~%~%" (uninterned-symbolize name)) (format stream ";;; ~S goes here. Hacks and glory await!~%~%" name))) @@ -156,7 +144,8 @@ marker is the string \"\(#|\" and the template end marker is the string ((:include-copyright *include-copyright*) *include-copyright*)) "Create a project skeleton for NAME in PATHNAME. If DEPENDS-ON is provided, it is used as the asdf defsystem depends-on list." - (check-type depends-on list) + (format t "TEMPLATE-DIRECTORY: ~s" *template-directory*) + (check-type *depends-on* list) (when (pathname-name pathname) (warn "Coercing ~S to directory" pathname) @@ -168,15 +157,12 @@ it is used as the asdf defsystem depends-on list." (nametype (type) (relative (make-pathname :name name :type type)))) (ensure-directories-exist pathname) - (write-readme-file name (relative "README.md")) - (write-system-file name (nametype "asd") :depends-on depends-on) - (write-package-file name (relative "package.lisp")) + (write-system-file name (nametype "asd") :depends-on *depends-on*) (write-application-file name (nametype "lisp")) (let ((*default-pathname-defaults* (truename pathname)) (*name* name)) - (when *template-directory* - (rewrite-templates *template-directory* *default-pathname-defaults* - (template-parameters template-parameters))) + (rewrite-templates *template-directory* *default-pathname-defaults* + (template-parameters template-parameters)) (pushnew *default-pathname-defaults* asdf:*central-registry* :test 'equal) (dolist (hook *after-make-project-hooks*) From 32f3aad904f6de044f478be50fa9043adef1eab5 Mon Sep 17 00:00:00 2001 From: inaimathi Date: Wed, 11 Oct 2017 00:46:55 -0400 Subject: [PATCH 3/8] Move everything into template generators - Add optional copyright notice header/footer to all default template files - Remove file-comment-header function (and add related stuff to each file) - Remove write-system-file and write-application-file - Add hooks to write .asd and initial .lisp file through the default template directory (and change their names as appropriate for output purposes so that we have files named .asd and .lisp) --- default-template/README.md | 4 ++ default-template/application.lisp | 5 +++ default-template/package.lisp | 6 ++- default-template/system.asd | 15 ++++++++ quickproject.lisp | 64 +++++++++++-------------------- 5 files changed, 52 insertions(+), 42 deletions(-) create mode 100644 default-template/application.lisp create mode 100644 default-template/system.asd diff --git a/default-template/README.md b/default-template/README.md index 83403f1..97588dd 100644 --- a/default-template/README.md +++ b/default-template/README.md @@ -6,3 +6,7 @@ This is a project to do ... something. ## License (#| TMPL_VAR license |#) +(#| TMPL_IF copyright |#) + +(#| TMPL_VAR copyright |#) +(#| /TMPL_IF |#) diff --git a/default-template/application.lisp b/default-template/application.lisp new file mode 100644 index 0000000..564d244 --- /dev/null +++ b/default-template/application.lisp @@ -0,0 +1,5 @@ +;;;; (#| TMPL_VAR name |#).lisp(#| TMPL_IF copyright |#) +;; +;;;; (#| TMPL_VAR copyright |#)(#| /TMPL_IF |#) + +(in-package #:(#| TMPL_VAR name |#)) diff --git a/default-template/package.lisp b/default-template/package.lisp index 4171bcc..96618ee 100644 --- a/default-template/package.lisp +++ b/default-template/package.lisp @@ -1,2 +1,6 @@ +;;;; package.lisp(#| TMPL_IF copyright |#) +;; +;;;; (#| TMPL_VAR copyright |#)(#| /TMPL_IF |#) + (defpackage #:(#| TMPL_VAR name |#) - (:use #:cl)) + (:use #:cl)) diff --git a/default-template/system.asd b/default-template/system.asd new file mode 100644 index 0000000..bf49246 --- /dev/null +++ b/default-template/system.asd @@ -0,0 +1,15 @@ +;;;; (#| TMPL_VAR name |#).asd(#| TMPL_IF copyright |#) +;; +;;;; (#| TMPL_VAR copyright |#)(#| /TMPL_IF |#) + +(asdf:defsystem #:(#| TMPL_VAR name |#) + :description "Describe (#| TMPL_VAR name |#) here" + :author (#| TMPL_VAR author |#) + :license (#| TMPL_VAR license |#) + :version "0.0.1" + :serial t(#| TMPL_IF depends-on |#) + :depends-on (;;) + (#| TMPL_LOOP depends-on |#) + (#| TMPL_VAR uninterned |#)(#| /TMPL_LOOP |#))(#| /TMPL_IF |#) + :components ((:file "package") + (:file "(#| TMPL_VAR name |#)"))) diff --git a/quickproject.lisp b/quickproject.lisp index b9a0cf7..b564a8a 100644 --- a/quickproject.lisp +++ b/quickproject.lisp @@ -27,21 +27,6 @@ string designator and upcased." (make-symbol (string-upcase name))) -(defun write-system-form (name &key depends-on (stream *standard-output*)) - "Write an asdf defsystem form for NAME to STREAM." - (let ((*print-case* :downcase)) - (format stream "(asdf:defsystem ~S~%" (uninterned-symbolize name)) - (format stream " :description \"Describe ~A here\"~%" - name) - (format stream " :author ~S~%" *author*) - (format stream " :license ~S~%" *license*) - (when depends-on - (format stream " :depends-on (~{~S~^~%~15T~})~%" - (mapcar #'uninterned-symbolize depends-on))) - (format stream " :serial t~%") - (format stream " :components ((:file \"package\")~%") - (format stream " (:file ~(~S~))))~%" name))) - (defun pathname-project-name (pathname) "Return a project name based on PATHNAME by taking the last element in the pathname-directory list. E.g. returns \"awesome-project\" for @@ -60,27 +45,6 @@ not already exist." (defun current-year () (nth-value 5 (decode-universal-time (get-universal-time)))) -(defun file-comment-header (stream) - (format stream ";;;; ~A~%" (file-namestring stream)) - (when *include-copyright* - (format stream ";;;;~%") - (format stream ";;;; Copyright (c) ~D ~A~%" (current-year) *author*)) - (terpri stream)) - -(defun write-system-file (name file &key depends-on) - (with-new-file (stream file) - (file-comment-header stream) - (write-system-form name - :depends-on depends-on - :stream stream) - (terpri stream))) - -(defun write-application-file (name file) - (with-new-file (stream file) - (file-comment-header stream) - (format stream "(in-package ~S)~%~%" (uninterned-symbolize name)) - (format stream ";;; ~S goes here. Hacks and glory await!~%~%" name))) - (defvar *after-make-project-hooks* nil "A list of functions to call after MAKE-PROJECT is finished making a project. Each function is called with the same arguments passed to @@ -88,6 +52,20 @@ MAKE-PROJECT, except that NAME is canonicalized if necessary. *DEFAULT-PATHNAME-DEFAULTS* bound to the newly created project directory.") +(defun template-pathname->output-name (path) + (flet ((mk-path (name) + (make-pathname + :directory (pathname-directory path) + :name name + :type (pathname-type path)))) + (cond ((and (string= "asd" (pathname-type path)) + (string= "system" (pathname-name path))) + (mk-path *name*)) + ((and (string= "lisp" (pathname-type path)) + (string= "application" (pathname-name path))) + (mk-path *name*)) + (t path)))) + (defun rewrite-templates (template-directory target-directory parameters) "Treat every file in TEMPLATE-DIRECTORY as a template file; fill it out using PARAMETERS into a corresponding file in @@ -103,8 +81,9 @@ marker is the string \"\(#|\" and the template end marker is the string (flet ((rewrite-template (pathname) (let* ((relative-namestring (enough-namestring pathname template-directory)) - (target-pathname (merge-pathnames relative-namestring - target-directory))) + (target-pathname (template-pathname->output-name + (merge-pathnames relative-namestring + target-directory)))) (ensure-directories-exist target-pathname) (with-open-file (stream target-pathname @@ -120,7 +99,12 @@ marker is the string \"\(#|\" and the template end marker is the string (list :name *name* :license *license* :author *author* - :depends-on *depends-on*)) + :depends-on (mapcar + (lambda (sym) + (list :symbol sym :uninterned (format nil "#:~(~a~)" sym))) + *depends-on*) + :copyright (when *include-copyright* + (format nil "Copyright (c) ~D ~A~%" (current-year) *author*)))) (defvar *template-parameter-functions* (list 'default-template-parameters) "A list of functions that return plists for use when rewriting @@ -144,7 +128,6 @@ marker is the string \"\(#|\" and the template end marker is the string ((:include-copyright *include-copyright*) *include-copyright*)) "Create a project skeleton for NAME in PATHNAME. If DEPENDS-ON is provided, it is used as the asdf defsystem depends-on list." - (format t "TEMPLATE-DIRECTORY: ~s" *template-directory*) (check-type *depends-on* list) (when (pathname-name pathname) (warn "Coercing ~S to directory" @@ -157,7 +140,6 @@ it is used as the asdf defsystem depends-on list." (nametype (type) (relative (make-pathname :name name :type type)))) (ensure-directories-exist pathname) - (write-system-file name (nametype "asd") :depends-on *depends-on*) (write-application-file name (nametype "lisp")) (let ((*default-pathname-defaults* (truename pathname)) (*name* name)) From 1fc6316de7d4e46b8ac396aad56ca7e28d103d79 Mon Sep 17 00:00:00 2001 From: inaimathi Date: Wed, 11 Oct 2017 01:01:03 -0400 Subject: [PATCH 4/8] Slightly easier notation for dependencies --- default-template/system.asd | 4 +--- quickproject.lisp | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/default-template/system.asd b/default-template/system.asd index bf49246..6e7227f 100644 --- a/default-template/system.asd +++ b/default-template/system.asd @@ -8,8 +8,6 @@ :license (#| TMPL_VAR license |#) :version "0.0.1" :serial t(#| TMPL_IF depends-on |#) - :depends-on (;;) - (#| TMPL_LOOP depends-on |#) - (#| TMPL_VAR uninterned |#)(#| /TMPL_LOOP |#))(#| /TMPL_IF |#) + :depends-on (#| TMPL_VAR dependencies-string |#)(#| /TMPL_IF |#) :components ((:file "package") (:file "(#| TMPL_VAR name |#)"))) diff --git a/quickproject.lisp b/quickproject.lisp index b564a8a..a8fbe8b 100644 --- a/quickproject.lisp +++ b/quickproject.lisp @@ -103,6 +103,7 @@ marker is the string \"\(#|\" and the template end marker is the string (lambda (sym) (list :symbol sym :uninterned (format nil "#:~(~a~)" sym))) *depends-on*) + :dependencies-string (format nil "(~{#:~(~a~)~^ ~})" *depends-on*) :copyright (when *include-copyright* (format nil "Copyright (c) ~D ~A~%" (current-year) *author*)))) From faac13f187d19ee49543ea39614cc34f13bce48a Mon Sep 17 00:00:00 2001 From: inaimathi Date: Wed, 11 Oct 2017 09:04:34 -0400 Subject: [PATCH 5/8] Fix quoting issue in system.asd template file --- default-template/system.asd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default-template/system.asd b/default-template/system.asd index 6e7227f..d187809 100644 --- a/default-template/system.asd +++ b/default-template/system.asd @@ -4,8 +4,8 @@ (asdf:defsystem #:(#| TMPL_VAR name |#) :description "Describe (#| TMPL_VAR name |#) here" - :author (#| TMPL_VAR author |#) - :license (#| TMPL_VAR license |#) + :author "(#| TMPL_VAR author |#)" + :license "(#| TMPL_VAR license |#)" :version "0.0.1" :serial t(#| TMPL_IF depends-on |#) :depends-on (#| TMPL_VAR dependencies-string |#)(#| /TMPL_IF |#) From 1f81316147793641de2bd5f17eb57cc3ea756be3 Mon Sep 17 00:00:00 2001 From: inaimathi Date: Wed, 11 Oct 2017 09:10:14 -0400 Subject: [PATCH 6/8] Remove vestigial call to write-application-file --- quickproject.lisp | 1 - 1 file changed, 1 deletion(-) diff --git a/quickproject.lisp b/quickproject.lisp index a8fbe8b..b010998 100644 --- a/quickproject.lisp +++ b/quickproject.lisp @@ -141,7 +141,6 @@ it is used as the asdf defsystem depends-on list." (nametype (type) (relative (make-pathname :name name :type type)))) (ensure-directories-exist pathname) - (write-application-file name (nametype "lisp")) (let ((*default-pathname-defaults* (truename pathname)) (*name* name)) (rewrite-templates *template-directory* *default-pathname-defaults* From 93ab5bfd536da4d7a03adaf783f10ddd00f2f63b Mon Sep 17 00:00:00 2001 From: inaimathi Date: Thu, 19 Oct 2017 16:56:23 -0400 Subject: [PATCH 7/8] Indent with spaces instead of tabs --- quickproject.lisp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/quickproject.lisp b/quickproject.lisp index b010998..14c8cb7 100644 --- a/quickproject.lisp +++ b/quickproject.lisp @@ -54,17 +54,17 @@ project directory.") (defun template-pathname->output-name (path) (flet ((mk-path (name) - (make-pathname - :directory (pathname-directory path) - :name name - :type (pathname-type path)))) + (make-pathname + :directory (pathname-directory path) + :name name + :type (pathname-type path)))) (cond ((and (string= "asd" (pathname-type path)) - (string= "system" (pathname-name path))) - (mk-path *name*)) - ((and (string= "lisp" (pathname-type path)) - (string= "application" (pathname-name path))) - (mk-path *name*)) - (t path)))) + (string= "system" (pathname-name path))) + (mk-path *name*)) + ((and (string= "lisp" (pathname-type path)) + (string= "application" (pathname-name path))) + (mk-path *name*)) + (t path)))) (defun rewrite-templates (template-directory target-directory parameters) "Treat every file in TEMPLATE-DIRECTORY as a template file; fill it @@ -82,8 +82,8 @@ marker is the string \"\(#|\" and the template end marker is the string (let* ((relative-namestring (enough-namestring pathname template-directory)) (target-pathname (template-pathname->output-name - (merge-pathnames relative-namestring - target-directory)))) + (merge-pathnames relative-namestring + target-directory)))) (ensure-directories-exist target-pathname) (with-open-file (stream target-pathname @@ -99,13 +99,13 @@ marker is the string \"\(#|\" and the template end marker is the string (list :name *name* :license *license* :author *author* - :depends-on (mapcar - (lambda (sym) - (list :symbol sym :uninterned (format nil "#:~(~a~)" sym))) - *depends-on*) - :dependencies-string (format nil "(~{#:~(~a~)~^ ~})" *depends-on*) - :copyright (when *include-copyright* - (format nil "Copyright (c) ~D ~A~%" (current-year) *author*)))) + :depends-on (mapcar + (lambda (sym) + (list :symbol sym :uninterned (format nil "#:~(~a~)" sym))) + *depends-on*) + :dependencies-string (format nil "(~{#:~(~a~)~^ ~})" *depends-on*) + :copyright (when *include-copyright* + (format nil "Copyright (c) ~D ~A~%" (current-year) *author*)))) (defvar *template-parameter-functions* (list 'default-template-parameters) "A list of functions that return plists for use when rewriting @@ -122,7 +122,7 @@ marker is the string \"\(#|\" and the template end marker is the string template-parameters ((:template-directory *template-directory*) *template-directory*) - ((:depends-on *depends-on*) *depends-on*) + ((:depends-on *depends-on*) *depends-on*) ((:author *author*) *author*) ((:license *license*) *license*) (name (pathname-project-name pathname) name-provided-p) @@ -132,7 +132,7 @@ it is used as the asdf defsystem depends-on list." (check-type *depends-on* list) (when (pathname-name pathname) (warn "Coercing ~S to directory" - pathname) + pathname) (setf pathname (pathname-as-directory pathname)) (unless name-provided-p (setf name (pathname-project-name pathname)))) @@ -144,7 +144,7 @@ it is used as the asdf defsystem depends-on list." (let ((*default-pathname-defaults* (truename pathname)) (*name* name)) (rewrite-templates *template-directory* *default-pathname-defaults* - (template-parameters template-parameters)) + (template-parameters template-parameters)) (pushnew *default-pathname-defaults* asdf:*central-registry* :test 'equal) (dolist (hook *after-make-project-hooks*) From 4f6f1f6cc098fab0c1843b98a3f4b6860995e61b Mon Sep 17 00:00:00 2001 From: inaimathi Date: Thu, 19 Oct 2017 16:59:14 -0400 Subject: [PATCH 8/8] Proper indentation for default template --- default-template/package.lisp | 2 +- default-template/system.asd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/default-template/package.lisp b/default-template/package.lisp index 96618ee..ae60d64 100644 --- a/default-template/package.lisp +++ b/default-template/package.lisp @@ -3,4 +3,4 @@ ;;;; (#| TMPL_VAR copyright |#)(#| /TMPL_IF |#) (defpackage #:(#| TMPL_VAR name |#) - (:use #:cl)) + (:use #:cl)) diff --git a/default-template/system.asd b/default-template/system.asd index d187809..186db66 100644 --- a/default-template/system.asd +++ b/default-template/system.asd @@ -10,4 +10,4 @@ :serial t(#| TMPL_IF depends-on |#) :depends-on (#| TMPL_VAR dependencies-string |#)(#| /TMPL_IF |#) :components ((:file "package") - (:file "(#| TMPL_VAR name |#)"))) + (:file "(#| TMPL_VAR name |#)")))