Faber is a CLI task runner designed to leverage the power and flexibility of Gauche Scheme. Unlike other build systems that rely on custom formats, Faber uses Gauche Scheme, allowing you to write build scripts using familiar Scheme syntax.
“Homo faber suae quisque fortunae” - Every man is the maker of his own fate.
Tasks are stored in a file called faberfile in your project root. Here's a simple example:
(define-task build ()
(run '(cc main.c foo.c bar.c -o main)))
(define-task test ()
(run-task build) ; execute task "build" first
(run "./test"))
(define-task default ()
(run-task build)) ; default task when no task specified> faber build # Run the build task
> faber test # Run the test task
> faber # Run the default taskThere are two equivalent ways to define a task:
(define-task task-name ()
(display "This is a task!"))
;; OR
(deftask task-name ()
(display "This is a task!"))(define-task touch (path)
(touch-file path))
(define-task test-arg (arg)
(format #t "Hello ~A" arg))
(define-task test-key-arg (:key arg1 arg2)
(format #t "Hello ~A" arg1))(define-task test-pipe ()
;; Equivalent to: ls -l | wc -l
(run-pipe '((ls -l)
(wc -l))))(define-task test-parallel ()
;; returns in ~5 seconds
(run-parallel '((sleep 3) (sleep 5) (sleep 2)))
;; returns in ~10 seconds
(run-parallel '((sleep 3) (sleep 5) (sleep 2))
:num-threads 1))(define-task sloc ()
(let1 cnt (run->string '(wc -l "*.c"))
(show #t cnt " lines of code" nl)))For additional examples, see the test faberfile in the repository.
> faber build
> faber sloc
> faber test-arg world
> faber test-key-arg :arg1 world
> faber touch test.txtThis modules are imported already and can be used in faberfile:
You can import module in faberfile like this:
(use rfc.http)
(define-task api-call ()
(receive (code headers body)
(http-get "example.org" "/api/test"
:secure #t)
(display body)))sh- Execute command via shell (sys-system)run- Execute command directly (do-process)run->string- Capture command output as string (process-output->string)run->lines- Capture command output as list of strings (process-output->string-list)run-pipe- Execute commands pipeline (do-pipeline)run-parallel- Execute list of commands in parallelrun->file- Capture command output to filedeftask- alias fordefine-taskrun*- Execute command directly without quoting list (e.g.,(run* ls -l))run->string*- Capture output without quoting listrun->lines*- Capture lines without quoting list
- Zsh: faber.plugin.zsh - Task autocompletion
- Gauche Scheme installed
- Maak - The infinitely extensible command runner, control plane and project automator à la Make (Guile Scheme - Lisp)