121 lines
4.2 KiB
Common Lisp
121 lines
4.2 KiB
Common Lisp
;;;; lspx.lisp
|
|
|
|
(in-package #:lspx)
|
|
|
|
(defparameter *server* nil)
|
|
|
|
(defun main ()
|
|
(multiple-value-bind (opts args) (get-opts)
|
|
(declare (ignore args))
|
|
|
|
;; --log
|
|
(when (getf opts :logging)
|
|
(let ((keyw (car (member (intern (string-upcase (getf opts :logging))
|
|
:keyword)
|
|
+valid-log-levels+))))
|
|
(if keyw
|
|
(log:config keyw)
|
|
(progn
|
|
(format t "bad value for logging level specified.~%proper values are ~{~(~A~)~^, ~}~%"
|
|
(mapcar #'string +valid-log-levels+))
|
|
(uiop:quit 1)))))
|
|
|
|
;; -h/--help
|
|
(when (getf opts :help)
|
|
(opts:describe :usage-of "lspx")
|
|
(uiop:quit 0))
|
|
|
|
;; --version
|
|
(when (getf opts :version)
|
|
(format t "lspx v~A~%" #.(asdf:component-version
|
|
(asdf:find-system :lspx)))
|
|
(uiop:quit 0))
|
|
|
|
(setf
|
|
|
|
;; -v/--verbose OR envvar ENV != production
|
|
*verbose* (or (getf opts :verbose)
|
|
(and (not (str:emptyp (uiop:getenv "ENV")))
|
|
(not (string= (uiop:getenv "ENV")
|
|
"production"))))
|
|
|
|
*html-backtrace* (getf opts :backtrace)
|
|
|
|
;; sets our local pathnames based on arguments provided
|
|
(logical-pathname-translations "WEB")
|
|
|
|
`(
|
|
;; sets our cache directory
|
|
("WEB:CACHE;**;*.*.*"
|
|
,(merge-pathnames ".cache/**/*.*" (namestring (uiop:getcwd))))
|
|
|
|
;; sets our static asset directory
|
|
("WEB:STATIC;**;*.*.*"
|
|
,(str:concat (str:ensure-suffix "/" (getf-dir opts :static-root "static/"))
|
|
"/**/*.*"))
|
|
|
|
;; sets our template root
|
|
("WEB:TEMPLATE;**;*.*.*"
|
|
,(str:concat (str:ensure-suffix "/" (getf-dir opts :template-root "templates/"))
|
|
"/**/*.*"))
|
|
|
|
;; sets our root web path to /provided/path
|
|
("WEB:PAGES;**;*.*.*"
|
|
,(str:concat (str:ensure-suffix "/" (getf-dir opts :web-root (uiop:getcwd)))
|
|
"**/*.*"))))
|
|
|
|
;; -l/--load
|
|
(let ((load-file (getf opts :load-file)))
|
|
(when load-file
|
|
(log:info "loading specified file: ~A" load-file)
|
|
(let ((*package* #.(find-package :lspx.user))
|
|
(*read-eval* t))
|
|
(load (namestring load-file)))))
|
|
|
|
;; deletes the cache if it already exists, ensuring we're in a consistent state
|
|
;; then creates the directories
|
|
(uiop:delete-directory-tree (translate-logical-pathname "web:cache;")
|
|
:validate t :if-does-not-exist :ignore)
|
|
(ensure-directories-exist "web:cache;")
|
|
|
|
(log:debug "Using ~A for pages."
|
|
(translate-logical-pathname "web:pages;"))
|
|
(log:debug "Using ~A for static assets."
|
|
(translate-logical-pathname "web:static;"))
|
|
(log:debug "Using ~A for templates."
|
|
(translate-logical-pathname "web:template;"))
|
|
|
|
(log:debug "loading templates...")
|
|
(let ((*package* #.(find-package :lspx.user)))
|
|
(uiop:collect-sub*directories
|
|
"web:template;" (constantly t) (constantly t)
|
|
#'(lambda (dir)
|
|
(mapcar #'load (uiop:directory-files dir "*.lspt")))))
|
|
|
|
;; creates our server handler, fetching the port if provided
|
|
(setf *server*
|
|
(clack:clackup #'web-handler
|
|
:server #+woo :woo
|
|
#-woo :hunchentoot
|
|
:silent t
|
|
:port (getf opts :port 5000)))
|
|
|
|
;; ensure we print a "Server Started" message regardless of logging
|
|
(log:info "LSPX server started at 127.0.0.1:~A using ~A backend"
|
|
(getf opts :port 5000)
|
|
#+woo :woo
|
|
#-woo :hunchentoot)
|
|
|
|
;; blocks until we C-c
|
|
(handle-user-abort
|
|
(bt:join-thread (find-if (lambda (th)
|
|
(search #+woo "woo"
|
|
#-woo "hunchentoot"
|
|
(bt:thread-name th)))
|
|
(bt:all-threads)))
|
|
(error (e)
|
|
(log:fatal "!!ERROR ~A~%~%BACKTRACE: ~A"
|
|
e (trivial-backtrace:print-backtrace e :output nil))))
|
|
|
|
(clack:stop *server*)))
|