Permalink
Browse files

Initial commit.

  • Loading branch information...
0 parents commit bbd4c29e4ef737d66b0cb7b549a78865aeb7f5a3 @xach committed Sep 15, 2010
Showing with 142 additions and 0 deletions.
  1. +19 −0 LICENSE.txt
  2. +30 −0 README.txt
  3. +8 −0 package.lisp
  4. +6 −0 quickproject.asd
  5. +79 −0 quickproject.lisp
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Zachary Beane
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
@@ -0,0 +1,30 @@
+Quickproject creates the skeleton of a Common Lisp project by
+automatically creating several files:
+
+ * README.txt
+
+ * <project>.asd
+
+ * package.lisp (which defines a package named after the project)
+
+ * <project>.lisp
+
+For example, to create a new project called "screenscraper":
+
+ (quickproject:make-project #p"src/screenscraper/"
+ :depends-on '(cl-ppcre drakma closure-html))
+
+The function interprets the last component of the pathname's directory
+as the project name. You can override this interpretation by passing
+an explicit :name argument. It then creates:
+
+ * src/screenscraper/README.txt
+
+ * src/screenscraper/screenscraper.asd
+
+ * src/screenscraper/package.lisp
+
+ * src/screenscraper/screenscraper.lisp
+
+Quickproject is licensed under the MIT license; see LICENSE.txt for
+details.
@@ -0,0 +1,8 @@
+;;;; package.lisp
+
+(defpackage #:quickproject
+ (:use #:cl)
+ (:export #:make-project))
+
+(in-package #:quickproject)
+
@@ -0,0 +1,6 @@
+;;;; quickproject.asd
+
+(asdf:defsystem #:quickproject
+ :serial t
+ :components ((:file "package")
+ (:file "quickproject")))
@@ -0,0 +1,79 @@
+;;;; quickproject.lisp
+
+(in-package #:quickproject)
+
+(defun uninterned-symbolize (name)
+ "Return an uninterned symbol named after NAME, which is treated as a
+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 " :serial t~%")
+ (when depends-on
+ (format stream " :depends-on (~{~S~^~%~15T~})~%"
+ (mapcar #'uninterned-symbolize depends-on)))
+ (format stream " :components ((:file \"package\")~%")
+ (format stream " (:file ~S)))~%" (string-downcase 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
+#p\"src/awesome-project/\"."
+ (first (last (pathname-directory pathname))))
+
+(defmacro with-new-file ((stream file) &body body)
+ "Like WITH-OPEN-FILE, but specialized for output to a file that must
+not already exist."
+ `(with-open-file (,stream ,file
+ :direction :output
+ :if-exists :error)
+ (let ((*print-case* :downcase))
+ ,@body)))
+
+(defun file-comment-header (stream)
+ (format stream ";;;; ~A~%~%" (file-namestring 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-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 file)
+ (file-comment-header stream)
+ (format stream "(in-package ~S)~%~%" (uninterned-symbolize name))
+ (format stream ";;; ~S goes here. Hacks and glory await!~%~%" name)))
+
+(defun make-project (pathname &key
+ depends-on
+ (name (pathname-project-name pathname)))
+ "Create a project skeleton for NAME in PATHNAME. If DEPENDS-ON is provided,
+it is used as the asdf defsystem depends-on list."
+ (labels ((relative (file)
+ (merge-pathnames file pathname))
+ (nametype (type)
+ (relative (make-pathname :name name :type type))))
+ (ensure-directories-exist pathname)
+ (write-readme-file name (relative "README.txt"))
+ (write-system-file name (nametype "asd") :depends-on depends-on)
+ (write-package-file name (relative "package.lisp"))
+ (write-application-file name (nametype "lisp"))
+ name))

0 comments on commit bbd4c29

Please sign in to comment.