babashka/README.md

133 lines
3 KiB
Markdown
Raw Normal View History

2019-08-09 12:51:42 +00:00
# babashka
[![CircleCI](https://circleci.com/gh/borkdude/babashka/tree/master.svg?style=shield)](https://circleci.com/gh/borkdude/babashka/tree/master)
[![Clojars Project](https://img.shields.io/clojars/v/borkdude/babashka.svg)](https://clojars.org/borkdude/babashka)
[![cljdoc badge](https://cljdoc.org/badge/borkdude/babashka)](https://cljdoc.org/d/borkdude/babashka/CURRENT)
2019-08-09 14:05:14 +00:00
A pure, fast and (severely!) limited version of Clojure in Clojure for shell scripting.
2019-08-09 12:51:42 +00:00
Properties:
- pure (no side effects)
2019-08-09 13:48:54 +00:00
- fast startup time
2019-08-09 12:51:42 +00:00
- interprets only one form
- reads from stdin and writes to stdout
2019-08-09 17:48:40 +00:00
## Rationale
Most of your script is in bash, but you want a tiny sprinkle of Clojure.
If most of your shell script evolves into Clojure, you might want to turn to:
- [planck](https://planck-repl.org/)
- [joker](https://github.com/candid82/joker)
- [lumo](https://github.com/anmonteiro/lumo)
2019-08-09 12:51:42 +00:00
## Status
2019-08-09 17:51:45 +00:00
Experimental. Breaking changes are expected to happen at this phase. Not all
Clojure core functions are supported yet, but can be easily
2019-08-09 13:48:54 +00:00
[added](https://github.com/borkdude/babashka/blob/master/src/babashka/interpreter.clj#L10). PRs
welcome.
2019-08-09 12:51:42 +00:00
2019-08-09 14:02:08 +00:00
## Installation
Linux and macOS binaries are provided via brew.
Install:
brew install borkdude/brew/babashka
Upgrade:
brew upgrade babashka
You may also download a binary from [Github](https://github.com/borkdude/babashka/releases).
2019-08-09 13:48:54 +00:00
## Usage
2019-08-09 12:51:42 +00:00
2019-08-09 17:58:11 +00:00
``` shellsession
2019-08-09 18:01:12 +00:00
... | bb [--raw] '<Clojure form>'
2019-08-09 17:58:11 +00:00
```
2019-08-09 18:01:12 +00:00
There is one special variable, `*in*`, which is the input read from stdin. When
the `--raw` flag is provided, `*in*` is a single string or vector of
strings. When it is omitted, the input is read as EDN.
2019-08-09 12:51:42 +00:00
2019-08-09 17:58:11 +00:00
The current version can be printed with:
``` shellsession
bb --version
0.0.2
```
2019-08-09 12:51:42 +00:00
Examples:
``` shellsession
2019-08-09 15:38:26 +00:00
$ ls | bb --raw '*in*'
["LICENSE" "README.md" "bb" "doc" "pom.xml" "project.clj" "reflection.json" "resources" "script" "src" "target" "test"]
2019-08-09 15:40:36 +00:00
$ ls | bb --raw '(count *in*)'
2019-08-09 15:38:26 +00:00
11
2019-08-09 12:51:42 +00:00
$ echo '[1 1 1 1 2]' | bb '(vec (dedupe *in*))'
[1 2]
$ echo '[{:foo 1} {:bar 2}]' | bb '(filter :foo *in*)'
({:foo 1})
```
Functions are written using the reader tag `#f`. Currently up to three
2019-08-09 15:38:26 +00:00
arguments are supported.
``` shellsession
2019-08-09 21:08:49 +00:00
$ echo '3' | bb '(#f(+ %1 %2 %3) 1 2 *in*)'
2019-08-09 15:41:33 +00:00
6
```
Regexes are written using the reader tag `#r`.
2019-08-09 15:38:26 +00:00
``` shellsession
2019-08-09 21:08:49 +00:00
$ ls | bb --raw '(filterv #f(re-find #r "reflection" %) *in*)'
2019-08-09 15:38:26 +00:00
["reflection.json"]
```
2019-08-09 21:08:49 +00:00
Find the line numbers where the word Clojure occurs using a case insensitive regex:
``` shellsession
$ cat /tmp/test.txt
foo
Clojure is nice
bar
when you're nice to clojure
$ cat /tmp/test.txt | bb --raw '(map-indexed #f[%1 %2] *in*))' | \
bb '(keep #f(when (re-find #r"(?i)clojure" (second %)) (first %)) *in*)'
(1 3)
```
2019-08-09 12:51:42 +00:00
## Test
2019-08-09 18:01:12 +00:00
Test on the JVM:
2019-08-09 12:51:42 +00:00
script/test
2019-08-09 18:01:12 +00:00
Although this tool doesn't offer any benefit when running on the JVM, it is
convenient for development.
2019-08-09 12:51:42 +00:00
Test the native version:
BABASHKA_TEST_ENV=native script/test
## Build
You will need leiningen and GraalVM.
script/compile
## License
Copyright © 2019 Michiel Borkent
Distributed under the EPL License, same as Clojure. See LICENSE.