2020-10-17 09:31:17 +00:00
# Examples
2021-03-09 09:58:27 +00:00
- [Examples ](#examples )
- [Delete a list of files returned by a Unix command ](#delete-a-list-of-files-returned-by-a-unix-command )
- [Calculate aggregate size of directory ](#calculate-aggregate-size-of-directory )
- [Shuffle the lines of a file ](#shuffle-the-lines-of-a-file )
- [Fetch latest Github release tag ](#fetch-latest-github-release-tag )
- [Generate deps.edn entry for a gitlib ](#generate-depsedn-entry-for-a-gitlib )
- [View download statistics from Clojars ](#view-download-statistics-from-clojars )
- [Portable tree command ](#portable-tree-command )
- [List outdated maven dependencies ](#list-outdated-maven-dependencies )
- [Convert project.clj to deps.edn ](#convert-projectclj-to-depsedn )
- [Print current time in California ](#print-current-time-in-california )
- [Tiny http server ](#tiny-http-server )
- [Print random docstring ](#print-random-docstring )
- [Cryptographic hash ](#cryptographic-hash )
- [Package script as Docker image ](#package-script-as-docker-image )
- [Extract single file from zip ](#extract-single-file-from-zip )
- [Note taking app ](#note-taking-app )
- [which ](#which )
- [pom.xml version ](#pomxml-version )
- [Whatsapp frequencies ](#whatsapp-frequencies )
- [Find unused vars ](#find-unused-vars )
- [List contents of jar file ](#list-contents-of-jar-file )
- [Invoke vim inside a script ](#invoke-vim-inside-a-script )
- [Portal ](#portal )
- [Image viewer ](#image-viewer )
2021-06-24 11:22:34 +00:00
- [HTTP server ](#http-server )
2021-03-09 09:58:27 +00:00
- [Torrent viewer ](#torrent-viewer )
- [cprop.clj ](#cpropclj )
- [fzf ](#fzf )
- [digitalocean-ping.clj ](#digitalocean-pingclj )
- [download-aliases.clj ](#download-aliasesclj )
2021-04-29 14:39:13 +00:00
- [Is TTY? ](#is-tty )
2021-07-03 21:53:58 +00:00
- [normalize-keywords.clj ](#normalize-keywordsclj )
- [Check stdin for data ](#check-stdin-for-data )
- [Using org.clojure/data.xml ](#using-orgclojuredataxml )
2021-07-08 18:18:01 +00:00
- [Simple logger ](#simple-logger )
2021-09-26 21:47:39 +00:00
- [Using GZip streams (memo utility) ](#using-gzip-streams-to-make-a-note-utility )
2021-10-04 10:01:31 +00:00
- [Pretty-printing mySQL results ](#pretty-printing-mysql-results )
2022-10-10 15:04:15 +00:00
- [Single page application with Babashka + htmx ](#single-page-application-with-babashka--htmx )
- [Wikipedia translation ](#wikipedia-translation )
2021-10-04 10:01:31 +00:00
2021-03-09 09:58:27 +00:00
2020-10-17 09:31:17 +00:00
Here's a gallery of useful examples. Do you have a useful example? PR welcome!
## Delete a list of files returned by a Unix command
```
find . | grep conflict | bb -i '(doseq [f *input* ] (.delete (io/file f)))'
```
## Calculate aggregate size of directory
``` clojure
#!/usr/bin/env bb
(as-> (io/file (or (first *command-line-args* ) ".")) $
(file-seq $)
(map #(.length %) $)
(reduce + $)
(/ $ (* 1024 1024))
(println (str (int $) "M")))
```
``` shellsession
$ dir-size
130M
$ dir-size ~/Dropbox/bin
233M
```
## Shuffle the lines of a file
``` shellsession
$ cat /tmp/test.txt
1 Hello
2 Clojure
3 Babashka
4 Goodbye
$ < /tmp/test.txt bb -io '(shuffle *input* )'
3 Babashka
2 Clojure
4 Goodbye
1 Hello
```
## Fetch latest Github release tag
``` shell
(require '[clojure.java.shell :refer [sh]]
'[cheshire.core :as json])
(defn babashka-latest-version []
2021-01-01 10:26:31 +00:00
(-> (sh "curl" "https://api.github.com/repos/babashka/babashka/tags")
2020-10-17 09:31:17 +00:00
:out
(json/parse-string true)
first
:name))
(babashka-latest-version) ;;=> "v0.0.73"
```
## Generate deps.edn entry for a gitlib
``` clojure
#!/usr/bin/env bb
(require '[clojure.java.shell :refer [sh]]
'[clojure.string :as str])
(let [[username project branch] *command-line-args*
branch (or branch "master")
url (str "https://github.com/" username "/" project)
sha (-> (sh "git" "ls-remote" url branch)
:out
(str/split #"\s")
first)]
{:git/url url
:sha sha})
```
``` shell
$ gitlib.clj nate fs
{:git/url "https://github.com/nate/fs", :sha "75b9fcd399ac37cb4f9752a4c7a6755f3fbbc000"}
$ clj -Sdeps "{:deps {fs $(gitlib.clj nate fs)}}" \
-e "(require '[nate.fs :as fs]) (fs/creation-time \".\")"
#object[java.nio.file.attribute.FileTime 0x5c748168 "2019-07-05T14:06:26Z"]
```
## View download statistics from Clojars
Contributed by [@plexus ](https://github.com/plexus ).
``` shellsession
$ curl https://clojars.org/stats/all.edn |
bb -o '(for [[[group art] counts] *input* ] (str (reduce + (vals counts)) " " group "/" art))' |
sort -rn |
less
14113842 clojure-complete/clojure-complete
9065525 clj-time/clj-time
8504122 cheshire/cheshire
...
```
## Portable tree command
2021-01-01 10:26:31 +00:00
See [examples/tree.clj ](https://github.com/babashka/babashka/blob/master/examples/tree.clj ).
2020-10-17 09:31:17 +00:00
``` shellsession
$ clojure -Sdeps '{:deps {org.clojure/tools.cli {:mvn/version "0.4.2"}}}' examples/tree.clj src
src
└── babashka
├── impl
│ ├── tools
│ │ └── cli.clj
...
$ examples/tree.clj src
src
└── babashka
├── impl
│ ├── tools
│ │ └── cli.clj
...
```
## List outdated maven dependencies
2021-01-01 10:26:31 +00:00
See [examples/outdated.clj ](https://github.com/babashka/babashka/blob/master/examples/outdated.clj ).
2020-10-17 09:31:17 +00:00
Inspired by an idea from [@seancorfield ](https://github.com/seancorfield ).
``` shellsession
$ cat /tmp/deps.edn
{:deps {cheshire {:mvn/version "5.8.1"}
clj-http {:mvn/version "3.4.0"}}}
$ examples/outdated.clj /tmp/deps.edn
clj-http/clj-http can be upgraded from 3.4.0 to 3.10.0
cheshire/cheshire can be upgraded from 5.8.1 to 5.9.0
```
## Convert project.clj to deps.edn
Contributed by [@plexus ](https://github.com/plexus ).
``` shellsession
$ cat project.clj |
sed -e 's/#=//g' -e 's/~@//g' -e 's/~//g' |
bb '(let [{:keys [dependencies source-paths resource-paths]} (apply hash-map (drop 3 *input* ))]
{:paths (into source-paths resource-paths)
:deps (into {} (for [[d v] dependencies] [d {:mvn/version v}]))}) ' |
jet --pretty > deps.edn
```
A script with the same goal can be found [here ](https://gist.github.com/swlkr/3f346c66410e5c60c59530c4413a248e#gistcomment-3232605 ).
## Print current time in California
2021-01-01 10:26:31 +00:00
See [examples/pst.clj ](https://github.com/babashka/babashka/blob/master/examples/pst.clj )
2020-10-17 09:31:17 +00:00
## Tiny http server
2021-03-09 09:58:27 +00:00
This implements an http server from scratch. Note that babashka comes with `org.httpkit.server` now, so you don't need to build an http server from scratch anymore.
See [examples/http_server_from_scratch.clj ](https://github.com/babashka/babashka/blob/master/examples/http_server_from_scratch.clj )
2020-10-17 09:31:17 +00:00
Original by [@souenzzo ](https://gist.github.com/souenzzo/a959a4c5b8c0c90df76fe33bb7dfe201 )
## Print random docstring
2021-01-01 10:26:31 +00:00
See [examples/random_doc.clj ](https://github.com/babashka/babashka/blob/master/examples/random_doc.clj )
2020-10-17 09:31:17 +00:00
``` shell
$ examples/random_doc.clj
-------------------------
clojure.core/ffirst
([x])
Same as (first (first x))
```
## Cryptographic hash
`sha1.clj` :
``` clojure
#!/usr/bin/env bb
(defn sha1
[s]
(let [hashed (.digest (java.security.MessageDigest/getInstance "SHA-1")
(.getBytes s))
sw (java.io.StringWriter.)]
(binding [*out* sw]
(doseq [byte hashed]
(print (format "%02X" byte))))
(str sw)))
(sha1 (first *command-line-args* ))
```
``` shell
$ sha1.clj babashka
"0AB318BE3A646EEB1E592781CBFE4AE59701EDDF"
```
## Package script as Docker image
`Dockerfile` :
``` dockerfile
2021-01-01 10:26:31 +00:00
FROM babashka/babashka
2020-10-17 09:31:17 +00:00
RUN echo $'\
(println "Your command line args:" *command-line-args* )\
'\
>> script.clj
ENTRYPOINT ["bb", "script.clj"]
```
``` shell
$ docker build . -t script
...
$ docker run --rm script 1 2 3
Your command line args: (1 2 3)
```
## Extract single file from zip
``` clojure
;; Given the following:
;; $ echo 'contents' > file
;; $ zip zipfile.zip file
;; $ rm file
;; we extract the single file from the zip archive using java.nio:
(import '[java.nio.file Files FileSystems CopyOption])
(let [zip-file (io/file "zipfile.zip")
file (io/file "file")
fs (FileSystems/newFileSystem (.toPath zip-file) nil)
file-in-zip (.getPath fs "file" (into-array String []))]
(Files/copy file-in-zip (.toPath file)
(into-array CopyOption [])))
```
## Note taking app
See
2021-01-01 10:26:31 +00:00
[examples/notes.clj ](https://github.com/babashka/babashka/blob/master/examples/notes.clj ). This
2020-10-17 09:31:17 +00:00
is a variation on the
2021-01-01 10:26:31 +00:00
[http-server ](https://github.com/babashka/babashka/#tiny-http-server )
2020-10-17 09:31:17 +00:00
example. If you get prompted with a login, use `admin` /`admin`.
## which
The `which` command re-implemented in Clojure. See
2021-01-01 10:26:31 +00:00
[examples/which.clj ](https://github.com/babashka/babashka/blob/master/examples/which.clj ).
2020-10-17 09:31:17 +00:00
Prints the canonical file name.
``` shell
$ examples/which.clj rg
/usr/local/Cellar/ripgrep/11.0.1/bin/rg
```
## pom.xml version
A script to retrieve the version from a `pom.xml` file. See
2020-10-17 09:39:13 +00:00
[pom_version_get.clj ](pom_version_get.clj ). Written by [@wilkerlucio ](https://github.com/wilkerlucio ).
2021-05-27 07:31:35 +00:00
See [pom_version_get_xml_zip.clj ](pom_version_get_xml_zip.clj ) for how to do the same using zippers.
2020-10-17 09:39:13 +00:00
Also see [pom_version_set.clj ](pom_version_set.clj ) to set the pom version.
2020-10-17 09:31:17 +00:00
## Whatsapp frequencies
Show frequencies of messages by user in Whatsapp group chats.
See [examples/whatsapp_frequencies.clj ](whatsapp_frequencies.clj )
## Find unused vars
[This ](hsqldb_unused_vars.clj ) script invokes clj-kondo, stores
returned data in an in memory HSQLDB database and prints the result of a query
which finds unused vars. It uses
[pod-babashka-hsqldb ](https://github.com/borkdude/pod-babashka-hsqldb ).
``` shell
$ bb examples/hsqldb_unused_vars.clj src
| :VARS/NS | :VARS/NAME | :VARS/FILENAME | :VARS/ROW | :VARS/COL |
2020-11-16 11:16:39 +00:00
|----------------------------|--------------------------|------------------------------------|-----------|-----------|
2020-10-17 09:31:17 +00:00
| babashka.impl.bencode.core | read-netstring | src/babashka/impl/bencode/core.clj | 162 | 1 |
| babashka.impl.bencode.core | write-netstring | src/babashka/impl/bencode/core.clj | 201 | 1 |
| babashka.impl.classes | generate-reflection-file | src/babashka/impl/classes.clj | 230 | 1 |
| babashka.impl.classpath | ->DirectoryResolver | src/babashka/impl/classpath.clj | 12 | 1 |
| babashka.impl.classpath | ->JarFileResolver | src/babashka/impl/classpath.clj | 37 | 1 |
| babashka.impl.classpath | ->Loader | src/babashka/impl/classpath.clj | 47 | 1 |
| babashka.impl.clojure.test | file-position | src/babashka/impl/clojure/test.clj | 286 | 1 |
| babashka.impl.nrepl-server | stop-server! | src/babashka/impl/nrepl_server.clj | 179 | 1 |
| babashka.main | -main | src/babashka/main.clj | 485 | 1 |
```
## List contents of jar file
For the code see [examples/ls_jar.clj ](ls_jar.clj ).
``` shell
$ ls_jar.clj borkdude/sci 0.0.13-alpha.24
META-INF/MANIFEST.MF
META-INF/maven/borkdude/sci/pom.xml
META-INF/leiningen/borkdude/sci/project.clj
...
```
2021-01-25 13:03:33 +00:00
## Invoke vim inside a script
2020-10-17 09:31:17 +00:00
2020-10-26 15:41:05 +00:00
See [examples/vim.clj ](vim.clj ).
2020-10-17 09:31:17 +00:00
2021-01-25 13:03:33 +00:00
## Portal
2020-10-17 09:31:17 +00:00
2020-10-17 10:06:33 +00:00
This script uses [djblue/portal ](https://github.com/djblue/portal/ ) for inspecting EDN, JSON, XML or YAML files.
2020-10-17 09:31:17 +00:00
2020-10-24 22:39:51 +00:00
Example usage:
2020-10-17 10:06:33 +00:00
``` shell
2020-10-17 10:09:05 +00:00
$ examples/portal.clj ~/git/clojure/pom.xml
2020-10-17 10:06:33 +00:00
```
See [portal.clj ](portal.clj ).
2020-10-24 22:39:51 +00:00
2021-01-25 13:03:33 +00:00
## Image viewer
2020-10-24 22:39:51 +00:00
Opens browser window and lets user navigate through images of all sub-directories.
Example usage:
``` shell
2021-03-09 09:58:27 +00:00
$ examples/image-viewer.clj
```
See [image-viewer.clj ](image-viewer.clj ).
2021-06-24 11:22:34 +00:00
## HTTP Server
2021-03-09 09:58:27 +00:00
2021-06-24 11:22:34 +00:00
Opens browser window and lets user navigate through filesystem, similar to
`python3 -m http.server` .
2021-03-09 09:58:27 +00:00
Example usage:
``` shell
2021-06-24 11:22:34 +00:00
$ examples/http-server.clj
2020-10-24 22:39:51 +00:00
```
2022-10-10 15:04:15 +00:00
See [http-server.clj ](http-server.clj ).
2020-11-13 10:38:18 +00:00
2021-01-25 13:03:33 +00:00
## Torrent viewer
2020-11-13 10:38:18 +00:00
Shows the content of a torrent file. Note that pieces' content is hidden.
Example usage:
``` shell
$ examples/torrent-viewer.clj file.torrent
```
See [torrent-viewer.clj ](torrent-viewer.clj ).
2020-11-16 11:16:39 +00:00
2021-01-25 13:03:33 +00:00
## [cprop.clj](cprop.clj)
2020-11-16 11:16:39 +00:00
2020-11-17 16:54:02 +00:00
This script uses [tolitius/cprop ](https://github.com/tolitius/cprop ) library.
2020-11-16 11:16:39 +00:00
See [cprop.clj ](cprop.clj )
Example usage:
```shell
2020-11-17 10:12:26 +00:00
$ ( cd examples & & bb cprop.clj )
```
2021-01-25 13:03:33 +00:00
## [fzf](fzf.clj)
2020-11-17 10:12:26 +00:00
Invoke [fzf ](https://github.com/junegunn/fzf ), a command line fuzzy finder, from babashka.
See [fzf.clj ](fzf.clj )
Example usage:
``` shell
$ cat src/babashka/main.clj | bb examples/fzf.clj
2020-11-16 11:16:39 +00:00
```
2020-11-17 16:54:02 +00:00
2021-01-25 13:03:33 +00:00
## [digitalocean-ping.clj](digitalocean-ping.clj)
2020-12-08 14:54:10 +00:00
The script allows to define which DigitalOcean cloud datacenter (region) has best network performance (ping latency).
See [digitalocean-ping.clj ](digitalocean-ping.clj )
Example usage:
``` shell
$ bb digitalocean-ping.clj
```
2021-02-25 09:22:39 +00:00
## [download-aliases.clj](download-aliases.clj)
Download deps for all aliases in a deps.edn project.
2021-04-29 14:39:13 +00:00
## [Is TTY?](is_tty.clj)
An equivalent of Python's `os.isatty()` in Babashka, to check if the
`stdin` /`stdout`/`stderr` is connected to a TTY or not (useful to check if the
script output is being redirect to `/dev/null` , for example).
Only works in Unix systems.
``` shell
$ bb is-tty.clj
STDIN is TTY?: true
STDOUT is TTY?: true
STDERR is TTY?: true
$ bb is-tty.clj < /dev/null
STDIN is TTY?: false
STDOUT is TTY?: true
STDERR is TTY?: true
$ bb is-tty.clj 1>& 2 >/dev/null
STDIN is TTY?: true
STDOUT is TTY?: false
STDERR is TTY?: true
$ bb is-tty.clj 2>/dev/null
STDIN is TTY?: true
STDOUT is TTY?: true
STDERR is TTY?: false
```
2021-06-19 14:32:58 +00:00
## [normalize-keywords.clj](normalize-keywords.clj)
Provide a Clojure file to the script and it will print the Clojure file with
2021-06-19 14:39:55 +00:00
auto-resolved keywords normalized to fully qualified ones without double colons:
`::set/foo` becomes `:clojure.set/foo` .
2021-06-19 14:32:58 +00:00
``` clojure
$ cat /tmp/test.clj
(ns test (:require [clojure.set :as set]))
[::set/foo ::bar]
$ bb examples/normalize-keywords.clj /tmp/test.clj
(ns test (:require [clojure.set :as set]))
[:clojure.set/foo :test/bar]
```
2021-07-03 21:53:58 +00:00
## Check stdin for data
```shell
# when piping something in, we get a positive number
$ echo 'abc' | bb '(pos? (.available System/in))'
true
# even if we echo an empty string, we still get the newline
$ echo '' | bb '(pos? (.available System/in))'
true
# with nothing passed in, we finally return false
$ bb '(pos? (.available System/in))'
false
```
## Using org.clojure/data.xml
[xml-example.clj ](xml-example.clj ) explores some of the capabilities provided
by the `org.clojure/data.xml` library (required as `xml` by default in Babashka).
While running the script will show some output, reading the file shows the library
in use.
```shell
$ bb examples/xml-example.clj
... some vaguely interesting XML manipulation output
```
2021-07-08 18:18:01 +00:00
## Simple logger
[logger.clj ](logger.clj ) is a simple logger that works in bb.
``` clojure
$ bb "(require 'logger) (logger/log \"the logger says hi\")"
< expr > :1:19 the logger says hi
```
2021-09-26 21:47:39 +00:00
## Using GZip streams to make a note utility
[memo.clj ](memo.clj ) creates zip files in /tmp for stashing notes (possibly the most inefficient KV store ever)
```shell
$ echo "8675309" | memo.clj put jenny
ok
$ memo.clj get jenny
8675309
```
2021-10-04 10:01:31 +00:00
## Pretty-printing mySQL results
[db_who.clj ](db_who.clj ) will query mysql for all the connected sessions and pretty-print the user and what program they're using.
```
$ bb db_who.clj
| user | program_name |
|------------------+----------------|
| root@localhost | mysql |
| fred@192.168.1.2 | workbench |
| jane@192.168.1.3 | Toad for mySQL |
```
2022-01-21 15:29:59 +00:00
## Single page application with Babashka + htmx
Example of a todo list SPA using Babashka and htmx
See [htmx_todoapp.clj ](htmx_todoapp.clj )
Contributed by [@prestancedesign ](https://github.com/prestancedesign ).
2022-10-10 15:04:15 +00:00
## Wikipedia translation
[wiki-translate.clj ](wiki-translate.clj ) uses Wikipedia to translate words from English to Dutch (other languages are available).
``` shell
$ bb wiki-translate.clj window
"Venster (muur) – Dutch"
```
Shared by Janne Himanka on Clojurians Slack