mirror of
https://gitlab.com/vindarel/ciel.git
synced 2026-01-22 20:41:31 -08:00
add file-notify, add webapp script
[ci skip]
This commit is contained in:
parent
ad63aae024
commit
b65572e3b9
7 changed files with 196 additions and 4 deletions
|
|
@ -87,6 +87,15 @@ Debian system):
|
|||
|
||||
libmagic-dev libc6-dev gcc # from magicffi
|
||||
|
||||
On Linux:
|
||||
|
||||
inotify-tools
|
||||
|
||||
On MacOS:
|
||||
|
||||
fsevent
|
||||
|
||||
|
||||
## With Quicklisp
|
||||
|
||||
You need a Lisp implementation and Quicklisp installed.
|
||||
|
|
|
|||
1
ciel.asd
1
ciel.asd
|
|
@ -44,6 +44,7 @@
|
|||
:cl-json-pointer/synonyms
|
||||
:dissect
|
||||
:fset
|
||||
:file-notify ;; needs inotify (linux) or fsevent (macos)
|
||||
:generic-cl
|
||||
|
||||
;; web
|
||||
|
|
|
|||
|
|
@ -735,6 +735,23 @@ But typing `os:` and TAB in SLIME doesn't help very much with
|
|||
auto-discovery, so we also added a `/os` local nickname, so that we
|
||||
see the available symbols earlier in the autocompletion list.
|
||||
|
||||
We include [file-notify](https://github.com/shinmera/file-notify) to watch changes to files (using `inotify` on Linux and `fsevent` on MacOS). It is available with the `notify:` local nickname.
|
||||
|
||||
~~~lisp
|
||||
(notify:watch "webapp.lisp")
|
||||
(notify:with-events (file change :timeout T)
|
||||
;; Print the available list of events:
|
||||
;; (print (list file change))
|
||||
(when (equal change :close-write)
|
||||
(format! t "~%~%Reloading ~a…~&" file)
|
||||
(handler-case
|
||||
(ciel::load-without-shebang "webapp.lisp")
|
||||
(reader-error ()
|
||||
;; Catch some READ errors, such as parenthesis not closed, etc.
|
||||
(format! t "~%~%read error, waiting for change…~&"))))))
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
## Regular expressions
|
||||
|
||||
|
|
@ -945,12 +962,23 @@ Learn more with:
|
|||
|
||||
We include
|
||||
[Quicksearch](https://github.com/lisp-maintainers/quicksearch), a
|
||||
simple search utility for Common Lisp libraries:
|
||||
simple search utility for Common Lisp libraries that searches on
|
||||
GitHub, Quickdocs and Cliki.
|
||||
|
||||
You can call it with CIEL's binary:
|
||||
|
||||
$ ciel -s quicksearch ciel
|
||||
|
||||
or by calling its wrapper script directly:
|
||||
|
||||
$ quicksearch.lisp ciel # according you have it in your PATH
|
||||
|
||||
or from the Lisp REPL:
|
||||
|
||||
(qs:? "ciel" :u)
|
||||
|
||||
this will search on GitHub, Quickdocs and Cliki for "ciel", and it
|
||||
will print the URL of search results.
|
||||
this will search for the "ciel" keyword and it will print the URL of
|
||||
search results (`:u`).
|
||||
|
||||
```
|
||||
SEARCH-RESULTS: "ciel"
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ $ ciel -e "(-> (http:get \"https://fakestoreapi.com/products/1\") (json:read-jso
|
|||
|
||||
Call built-in scripts with `--script <scriptname>` or `-s`.
|
||||
|
||||
Call `ciel --scripts` to list the available scripts.
|
||||
Call `ciel --scripts` to list the available ones.
|
||||
|
||||
Those are for demo purposes and are subject to evolve. Ideas and contributions welcome.
|
||||
|
||||
|
|
@ -467,3 +467,75 @@ We welcome more capable, expanded scripts!
|
|||
---
|
||||
|
||||
Now, let us iron out the details ;)
|
||||
|
||||
### Simple web app with routes
|
||||
|
||||
See [`scr/scripts/webapp.lisp`](https://github.com/ciel-lang/CIEL/blob/master/src/scripts/webapp.lisp) for inspiration.
|
||||
|
||||
This creates one route on `/` with an optional `name` parameter. Go to `localhost:4567/?name=you` and see.
|
||||
|
||||
```lisp
|
||||
#!/usr/bin/env ciel
|
||||
;;;
|
||||
;;; Run with:
|
||||
;;; $ ./webapp.lisp
|
||||
;;;
|
||||
|
||||
(in-package :ciel-user)
|
||||
|
||||
(routes:defroute route-root "/" (&get name)
|
||||
(format nil "Hello ~a!" (or name (os:getenv "USER") "lisper")))
|
||||
|
||||
(defvar *server* nil)
|
||||
|
||||
(defun start-webapp ()
|
||||
(setf *server* (make-instance 'routes:easy-routes-acceptor :port 4567))
|
||||
(hunchentoot:start *server*))
|
||||
|
||||
(defun stop-webapp ()
|
||||
(hunchentoot:stop *server*))
|
||||
|
||||
#+ciel
|
||||
(progn
|
||||
(start-webapp)
|
||||
(format t "~&App started on localhost:4567…~&")
|
||||
(sleep most-positive-fixnum))
|
||||
```
|
||||
|
||||
At this point you'll certainly want to live-reload your changes.
|
||||
|
||||
### Auto-reload
|
||||
|
||||
In this snippet:
|
||||
[`webapp-notify.lisp`](https://github.com/ciel-lang/CIEL/blob/master/src/scripts/webapp-notify.lisp),
|
||||
we use the [file-notify](https://github.com/shinmera/file-notify)
|
||||
library (shipped in CIEL) to watch write changes to our lisp file, and load
|
||||
it again.
|
||||
|
||||
This allows you to have a dumb "live reload" workflow with a simple editor and a terminal.
|
||||
|
||||
> WARNING: This does NOT take advantage of Common Lisp's image-based-development features at all. Install yourself a Common Lisp IDE to enjoy the interactive debugger, compiling one function at a time, trying things out in the REPL, autocompletion, code navigation…
|
||||
|
||||
> INFO: you need `inotify` on Linux and `fsevent` on MacOS.
|
||||
|
||||
~~~lisp
|
||||
(defun simple-auto-reload ()
|
||||
(notify:watch "webapp.lisp")
|
||||
(notify:with-events (file change :timeout T)
|
||||
;; Print the available list of events:
|
||||
;; (print (list file change))
|
||||
(when (equal change :close-write)
|
||||
(format! t "~%~%Reloading ~a…~&" file)
|
||||
(handler-case
|
||||
(ciel::load-without-shebang "webapp.lisp")
|
||||
(reader-error ()
|
||||
;; Catch some READ errors, such as parenthesis not closed, etc.
|
||||
(format! t "~%~%read error, waiting for change…~&"))))))
|
||||
|
||||
#+ciel
|
||||
(unless *server*
|
||||
(start-webapp)
|
||||
(format t "~&App started on localhost:4567…~&")
|
||||
(simple-auto-reload)
|
||||
(sleep most-positive-fixnum))
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
(:os :uiop/os)
|
||||
;; This other uiop module is always useful:
|
||||
(:filesystem :uiop/filesystem)
|
||||
(:notify :org.shirakumo.file-notify)
|
||||
|
||||
(:alex :alexandria)
|
||||
(:csv :cl-csv)
|
||||
|
|
|
|||
56
src/scripts/webapp-notify.lisp
Executable file
56
src/scripts/webapp-notify.lisp
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env ciel
|
||||
;;;
|
||||
;;; Run with:
|
||||
;;; $ ./webapp-notify.lisp
|
||||
;;;
|
||||
;;; Watch this file for write events and load & compile it again.
|
||||
;;; This redefines our web routes, so we can develop our app in a simple interactive way.
|
||||
;;;
|
||||
;;; If you are doing that, you'll want to setup a proper dev environment to enjoy full Common Lisp image-based development.
|
||||
|
||||
(in-package :ciel-user)
|
||||
|
||||
(routes:defroute route-root "/" (&get name)
|
||||
(format nil "Hello ~a!" (or name (os:getenv "USER") "lisper")))
|
||||
|
||||
(routes:defroute route-hello "/hello" ()
|
||||
(format nil "Hello :)"))
|
||||
|
||||
;; Try adding new routes.
|
||||
;; (gotcha: give them unique names)
|
||||
|
||||
(defvar *server* nil)
|
||||
|
||||
(defun start-webapp ()
|
||||
(unless *server*
|
||||
(setf *server* (make-instance 'routes:easy-routes-acceptor :port 4567))
|
||||
(hunchentoot:start *server*)))
|
||||
|
||||
(defun stop-webapp ()
|
||||
(hunchentoot:stop *server*))
|
||||
|
||||
(defun dumb-auto-reload ()
|
||||
"Watch this file for write events and load & compile it again.
|
||||
This redefines our web routes, so we can develop our app in a simple interactive way.
|
||||
|
||||
If you are doing that, you'll want to setup a proper dev environment to enjoy full Common Lisp image-based development."
|
||||
(format! t "~&Watching webapp.lisp…")
|
||||
(notify:watch "webapp.lisp")
|
||||
(notify:with-events (file change :timeout T)
|
||||
;; list of events:
|
||||
;; (print (list file change))
|
||||
(when (equal change :close-write)
|
||||
(format! t "~%~%Reloading ~a…~&" file)
|
||||
(handler-case
|
||||
(ciel::load-without-shebang "webapp.lisp")
|
||||
(reader-error ()
|
||||
;; READ errors, parenthesis not closed, etc. Wait for the developer.
|
||||
(format! t "~%~%read error, waiting for change…~&"))))))
|
||||
|
||||
|
||||
#+ciel
|
||||
(unless *server*
|
||||
(start-webapp)
|
||||
(format t "~&App started on localhost:4567…~&")
|
||||
(dumb-auto-reload)
|
||||
(sleep most-positive-fixnum))
|
||||
25
src/scripts/webapp.lisp
Executable file
25
src/scripts/webapp.lisp
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env ciel
|
||||
;;;
|
||||
;;; Run with:
|
||||
;;; $ ./webapp.lisp
|
||||
;;;
|
||||
|
||||
(in-package :ciel-user)
|
||||
|
||||
(routes:defroute route-root "/" (&get name)
|
||||
(format nil "Hello ~a!" (or name (os:getenv "USER") "lisper")))
|
||||
|
||||
(defvar *server* nil)
|
||||
|
||||
(defun start-webapp ()
|
||||
(setf *server* (make-instance 'routes:easy-routes-acceptor :port 4567))
|
||||
(hunchentoot:start *server*))
|
||||
|
||||
(defun stop-webapp ()
|
||||
(hunchentoot:stop *server*))
|
||||
|
||||
#+ciel
|
||||
(progn
|
||||
(start-webapp)
|
||||
(format t "~&App started on localhost:4567…~&")
|
||||
(sleep most-positive-fixnum))
|
||||
Loading…
Add table
Add a link
Reference in a new issue