Compare commits

..

2 commits
master ... ansi

Author SHA1 Message Date
Michiel Borkent
d36b1272ec Merge branch 'master' into ansi 2019-12-16 13:57:34 +01:00
Michiel Borkent
bf3548317e ansi 2019-11-27 23:18:07 +01:00
669 changed files with 2402 additions and 70375 deletions

View file

@ -1,6 +0,0 @@
{:paths ["script"]
:deps {borkdude/gh-release-artifact
#_{:local/root "../gh-release-artifact"}
{:git/url "https://github.com/borkdude/gh-release-artifact"
:git/sha "4a9a74f0e50e897c45df8cc70684360eb30fce80"}}
:tasks {release-artifact babashka.release-artifact/release}}

View file

@ -1,3 +0,0 @@
babashka.impl.clojure.stacktrace/root-cause
babashka.impl.classes/generate-reflection-file
babashka.main/-main

View file

@ -1,4 +0,0 @@
babashka.impl.pipe-signal-handler/pipe-signal-received?
babashka.impl.pipe-signal-handler/handle-pipe!
babashka.impl.sigint-handler/handle-sigint!
babashka.impl.classes/generate-reflection-file

View file

@ -3,38 +3,253 @@
# Check https://circleci.com/docs/2.0/language-clojure/ for more details
#
version: 2.1
# this allows you to use CircleCI's dynamic configuration feature
setup: true
# the continuation orb is required in order to use dynamic configuration
orbs:
continuation: circleci/continuation@0.1.2
# our defined job, and its steps
jobs:
setup:
jvm:
docker:
- image: cimg/clojure:1.11.1
# specify the version you desire here
- image: circleci/clojure:lein-2.8.1
working_directory: ~/repo
environment:
LEIN_ROOT: "true"
# GRAALVM_HOME: /home/circleci/graalvm-ce-java8-19.3.0
steps:
- checkout
- run:
name: Bootstrap Babashka
name: "Pull Submodules"
command: |
curl -sLO https://raw.githubusercontent.com/babashka/babashka/master/install
sudo bash install --dir /tmp
git submodule init
git submodule update
- restore_cache:
keys:
- v1-dependencies-{{ checksum "project.clj" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run:
name: Rename bb binary
command: mv /tmp/bb /tmp/bbb
- run:
name: Generate config
name: Install Clojure
command: |
/tmp/bbb .circleci/script/gen_ci.clj > generated_config.yml
- continuation/continue:
configuration_path: generated_config.yml
wget -nc https://download.clojure.org/install/linux-install-1.10.1.447.sh
chmod +x linux-install-1.10.1.447.sh
sudo ./linux-install-1.10.1.447.sh
- run:
name: Install lsof
command: |
sudo apt-get install lsof
# - run:
# name: Download GraalVM
# command: |
# cd ~
# if ! [ -d graalvm-ce-java8-19.3.0 ]; then
# curl -O -sL https://github.com/oracle/graal/releases/download/vm-19.2.0/graalvm-ce-linux-amd64-19.2.0.tar.gz
# tar xzf graalvm-ce-linux-amd64-19.2.0.tar.gz
# fi
# - run:
# name: Install GraalVM SSL libs
# command: |
# .circleci/script/graalvm_ssl
- run:
name: Run JVM tests
command: |
script/test
# - run:
# name: Run as tools.deps dependency
# command: |
# .circleci/script/tools.deps
- run:
name: Run as lein command
command: |
.circleci/script/lein
- save_cache:
paths:
- ~/.m2
key: v1-dependencies-{{ checksum "project.clj" }}
linux:
docker:
- image: circleci/clojure:lein-2.8.1
working_directory: ~/repo
environment:
LEIN_ROOT: "true"
GRAALVM_HOME: /home/circleci/graalvm-ce-java8-19.3.0
BABASHKA_PLATFORM: linux # used in release script
BABASHKA_TEST_ENV: native
steps:
- checkout
- run:
name: "Pull Submodules"
command: |
git submodule init
git submodule update
- restore_cache:
keys:
- linux-{{ checksum "project.clj" }}-{{ checksum ".circleci/config.yml" }}
- run:
name: Install Clojure
command: |
wget https://download.clojure.org/install/linux-install-1.10.1.447.sh
chmod +x linux-install-1.10.1.447.sh
sudo ./linux-install-1.10.1.447.sh
- run:
name: Install lsof
command: |
sudo apt-get install lsof
- run:
name: Install native dev tools
command: |
sudo apt-get update
sudo apt-get -y install gcc g++ zlib1g-dev
- run:
name: Download GraalVM
command: |
cd ~
if ! [ -d graalvm-ce-java8-19.3.0 ]; then
curl -O -sL https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.0/graalvm-ce-java8-linux-amd64-19.3.0.tar.gz
tar xzf graalvm-ce-java8-linux-amd64-19.3.0.tar.gz
fi
# - run:
# name: Install GraalVM SSL libs
# command: |
# .circleci/script/graalvm_ssl
- run:
name: Build binary
command: |
script/compile
no_output_timeout: 30m
- run:
name: Run tests
command: |
script/test
# - run:
# name: Performance report
# command: |
# .circleci/script/performance
- run:
name: Release
command: |
.circleci/script/release
- save_cache:
paths:
- ~/.m2
- ~/graalvm-ce-java8-19.3.0
key: linux-{{ checksum "project.clj" }}-{{ checksum ".circleci/config.yml" }}
- store_artifacts:
path: /tmp/release
destination: release
mac:
macos:
xcode: "9.0"
environment:
GRAALVM_HOME: /Users/distiller/graalvm-ce-java8-19.3.0/Contents/Home
BABASHKA_PLATFORM: macos # used in release script
BABASHKA_TEST_ENV: native
steps:
- checkout
- run:
name: "Pull Submodules"
command: |
git submodule init
git submodule update
- restore_cache:
keys:
- mac-{{ checksum "project.clj" }}-{{ checksum ".circleci/config.yml" }}
- run:
name: Install Clojure
command: |
.circleci/script/install-clojure /usr/local
- run:
name: Install Leiningen
command: |
.circleci/script/install-leiningen
- run:
name: Download GraalVM
command: |
cd ~
ls -la
if ! [ -d graalvm-ce-java8-19.3.0 ]; then
curl -O -sL https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.0/graalvm-ce-java8-darwin-amd64-19.3.0.tar.gz
tar xzf graalvm-ce-java8-darwin-amd64-19.3.0.tar.gz
fi
# - run:
# name: Install GraalVM SSL libs
# command: |
# .circleci/script/graalvm_ssl
- run:
name: Build binary
command: |
script/compile
no_output_timeout: 30m
- run:
name: Run tests
command: |
script/test
# - run:
# name: Performance report
# command: |
# .circleci/script/performance
- run:
name: Release
command: |
.circleci/script/release
- save_cache:
paths:
- ~/.m2
- ~/graalvm-ce-java8-19.3.0
key: mac-{{ checksum "project.clj" }}-{{ checksum ".circleci/config.yml" }}
- store_artifacts:
path: /tmp/release
destination: release
deploy:
docker:
- image: circleci/clojure:lein-2.8.1
working_directory: ~/repo
environment:
LEIN_ROOT: "true"
steps:
- checkout
- run:
name: "Pull Submodules"
command: |
git submodule init
git submodule update
- restore_cache:
keys:
- v1-dependencies-{{ checksum "project.clj" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: .circleci/script/deploy
- save_cache:
paths:
- ~/.m2
key: v1-dependencies-{{ checksum "project.clj" }}
# docker:
# docker:
# - image: circleci/buildpack-deps:stretch
# steps:
# - checkout
# - setup_remote_docker:
# docker_layer_caching: true
# - run:
# name: Build Docker image
# command: .circleci/script/docker
# our single workflow, that triggers the setup job defined above
workflows:
setup:
version: 2
ci:
jobs:
- setup
- jvm
- linux
- mac
- deploy:
filters:
branches:
only: master
requires:
- jvm
- linux
- mac
# - docker:
# filters:
# branches:
# only: master
# requires:
# - jvm
# - linux
# - mac

View file

@ -1,13 +1,10 @@
#!/usr/bin/env bash
set -eo pipefail
image_name="babashka/babashka"
image_tag=$(cat resources/BABASHKA_VERSION)
image_name="borkdude/clj-kondo"
image_tag=$(cat resources/CLJ_KONDO_VERSION)
latest_tag="latest"
if [[ $image_tag =~ SNAPSHOT$ ]]
then
if [[ $image_tag =~ SNAPSHOT$ ]]; then
echo "This is a snapshot version"
snapshot="true"
else
@ -15,31 +12,19 @@ else
snapshot="false"
fi
if [ -z "$GITHUB_HEAD_REF" ] && [ "${GITHUB_REF##*/}" = "master" ]
then
if [ -z "$CIRCLE_PULL_REQUEST" ] && [ "$CIRCLE_BRANCH" = "master" ]; then
echo "Building Docker image $image_name:$image_tag"
echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USER" --password-stdin
mv /tmp/release/bb .
docker build -t "$image_name" -f Dockerfile.ci .
docker build -t "$image_name" .
docker tag "$image_name:$latest_tag" "$image_name:$image_tag"
if [[ $snapshot == "false" ]]; then
mv /tmp/release-static/bb .
docker build -t "$image_name:alpine" -f Dockerfile.alpine .
docker tag "$image_name:alpine" "$image_name:$image_tag-alpine"
fi
# we only update latest when it's not a SNAPSHOT version
if [ "false" = "$snapshot" ]; then
echo "Pushing image $image_name:$latest_tag"
docker push "$image_name:$latest_tag"
echo "Pushing image $image_name:alpine"
docker push "$image_name:alpine"
fi
# we update the version tag, even if it's a SNAPSHOT version
echo "Pushing image $image_name:$image_tag"
docker push "$image_name:$image_tag"
if [[ $snapshot == "false" ]]; then
docker push "$image_name:$image_tag-alpine"
fi
else
echo "Not publishing Docker image"
fi

View file

@ -1,125 +0,0 @@
(require '[babashka.fs :as fs]
'[babashka.process :as proc]
'[clojure.string :as str])
(import '[java.time Instant])
(defn read-env
([k]
(read-env k nil))
([k default]
(or (System/getenv k)
default)))
(def image-name "babashka/babashka")
(def ghcr-image-name "ghcr.io/babashka/babashka")
(def image-tag (str/trim (slurp "resources/BABASHKA_VERSION")))
(def latest-tag "latest")
(def platforms (read-env "PLATFORMS" "linux/amd64"))
(def circle-repository-url (read-env "CIRCLE_REPOSITORY_URL"))
(def label-args
["--label" "'org.opencontainers.image.description=Native, fast starting Clojure interpreter for scripting'"
"--label" "org.opencontainers.image.title=Babashka"
"--label" (str "org.opencontainers.image.created=" (Instant/now))
"--label" (str "org.opencontainers.image.url=" circle-repository-url)
"--label" (str "org.opencontainers.image.documentation=" circle-repository-url)
"--label" (str "org.opencontainers.image.source=" circle-repository-url)
"--label" (str "org.opencontainers.image.revision=" (read-env "CIRCLE_SHA1"))
"--label"
(format "org.opencontainers.image.ref.name=%s:%s"
(read-env "CIRCLE_TAG")
(read-env "CIRCLE_BRANCH"))
"--label" (str "org.opencontainers.image.version=" image-tag)])
(def snapshot? (str/includes? image-tag "SNAPSHOT"))
(defn exec
[cmd]
(-> cmd
(proc/process {:out :inherit :err :inherit})
(proc/check)))
(defn docker-login
[username password]
(exec ["docker" "login" "-u" username "-p" password]))
(defn docker-login-ghcr
[username password]
(exec ["docker" "login" "ghcr.io" "-u" username "-p" password]))
;; TODO: Remove this when Dockerhub goes off
(defn build-push
[image-tag platform docker-file]
(println (format "Building and pushing %s Docker image(s) %s:%s"
platform
image-name
image-tag))
(let [base-cmd ["docker" "buildx" "build"
"-t" (str image-name ":" image-tag)
"--platform" platform
"--progress" "plain"
"--push"
"-f" docker-file]]
(exec (concat base-cmd label-args ["."]))))
(defn build-push-ghcr
[image-tag platform docker-file]
(println (format "Building and pushing %s Docker image(s) %s:%s to GHCR"
platform
ghcr-image-name
image-tag))
(let [base-cmd ["docker" "buildx" "build"
"-t" (str ghcr-image-name ":" image-tag)
"--platform" platform
"--progress" "plain"
"--push"
"-f" docker-file]]
(exec (concat base-cmd label-args ["."]))))
(defn build-push-images
[]
(doseq [platform (str/split platforms #",")]
(let [tarball-platform (str/replace platform #"\/" "-")
tarball-platform (if (= "linux-arm64" tarball-platform)
"linux-aarch64-static"
tarball-platform)
tarball-path (format "/tmp/release/babashka-%s-%s.tar.gz"
image-tag
tarball-platform)]
(fs/create-dirs platform)
(exec ["tar" "zxvf" tarball-path "-C" platform])
; this overwrites, but this is to work around having built the uberjar/metabom multiple times
(fs/copy (format "/tmp/release/%s-metabom.jar" tarball-platform) "metabom.jar" {:replace-existing true})))
(build-push image-tag platforms "Dockerfile.ci")
(build-push-ghcr image-tag platforms "Dockerfile.ci")
(when-not snapshot?
(build-push latest-tag platforms "Dockerfile.ci")
(build-push-ghcr latest-tag platforms "Dockerfile.ci")))
(defn build-push-alpine-images
"Build alpine image for linux-amd64 only (no upstream arm64 support yet)"
[]
(exec ["tar" "zxvf" (str "/tmp/release/babashka-" image-tag "-linux-amd64-static.tar.gz")])
(build-push (str image-tag "-alpine") "linux/amd64" "Dockerfile.alpine")
(build-push-ghcr (str image-tag "-alpine") "linux/amd64" "Dockerfile.alpine")
(when-not snapshot?
(build-push "alpine" "linux/amd64" "Dockerfile.alpine")
(build-push-ghcr "alpine" "linux/amd64" "Dockerfile.alpine")))
(when (= *file* (System/getProperty "babashka.file"))
(if (and (nil? (read-env "CIRCLE_PULL_REQUEST"))
(= "master" (read-env "CIRCLE_BRANCH")))
(do
(if snapshot?
(println "This is a snapshot version")
(println "This is a non-snapshot version"))
(docker-login (read-env "DOCKERHUB_USER") (read-env "DOCKERHUB_PASS"))
(docker-login-ghcr (read-env "CONTAINER_REGISTRY_USER") (read-env "BB_GHCR_TOKEN"))
(build-push-images)
(build-push-alpine-images))
(println "Not publishing docker image(s).")))

View file

@ -1,281 +0,0 @@
(ns gen-ci
(:require
[babashka.tasks :as tasks]
[clj-yaml.core :as yaml]
[clojure.string :as str]
[flatland.ordered.map :refer [ordered-map]]))
(def graalvm-version "24")
(defn run
([cmd-name cmd]
(run cmd-name cmd nil))
([cmd-name cmd no-output-timeout]
(let [base {:run {:name cmd-name
:command cmd}}]
(if no-output-timeout
(assoc-in base [:run :no_output_timeout] no-output-timeout)
base))))
(defn gen-steps
[shorted? steps]
(if shorted?
[(run "Shorted" "echo 'Skipping Run'")]
steps))
(defn gen-job
[shorted? conf]
(if shorted?
(-> conf
(dissoc :machine :macos)
(assoc :resource_class "small" :docker [{:image "ubuntu:latest"}]))
conf))
(defn pull-submodules
[]
(run "Pull Submodules" "git submodule init\ngit submodule update"))
(defn deploy
[shorted?]
(gen-job shorted?
(ordered-map
:resource_class "large"
:docker [{:image "circleci/clojure:lein-2.9.8"}]
:working_directory "~/repo"
:environment {:LEIN_ROOT "true"}
:steps (gen-steps
shorted?
[:checkout
(pull-submodules)
{:restore_cache {:keys ["v1-dependencies-{{ checksum \"project.clj\" }}"
"v1-dependencies-"]}}
{:run ".circleci/script/deploy"}
{:save_cache {:paths ["~/.m2"]
:key "v1-dependencies-{{ checksum \"project.clj\" }}"}}]))))
(defn docker
[shorted?]
(gen-job
shorted?
(ordered-map
:machine {:image "ubuntu-2004:2024.05.1"}
:steps
(gen-steps
shorted?
[:checkout
(pull-submodules)
"setup-docker-buildx"
{:attach_workspace {:at "/tmp"}}
(run "Build uberjar" "script/uberjar")
{:run
{:name "Build Docker image"
:environment {:PLATFORMS "linux/amd64,linux/arm64"}
:command
"java -jar ./target/babashka-$(cat resources/BABASHKA_VERSION)-standalone.jar .circleci/script/docker.clj"}}]))))
(defn jvm
[shorted? graalvm-home]
(gen-job
shorted?
(ordered-map
:docker [{:image "circleci/clojure:openjdk-11-lein-2.9.8-bullseye"}]
:working_directory "~/repo"
:environment {:LEIN_ROOT "true"
:BABASHKA_PLATFORM "linux"
:GRAALVM_VERSION graalvm-version
:GRAALVM_HOME graalvm-home
:BABASHKA_TEST_ENV "jvm"
:BABASHKA_SHA (System/getenv "CIRCLE_SHA1")}
:resource_class "large"
:steps
(gen-steps
shorted?
[:checkout
(pull-submodules)
{:restore_cache {:keys ["v1-dependencies-{{ checksum \"project.clj\" }}-{{ checksum \"deps.edn\" }}"
"v1-dependencies-"]}}
(run "Install Clojure" "sudo script/install-clojure")
(run "Download GraalVM" "script/install-graalvm")
(run
"Run JVM tests"
"export BABASHKA_FEATURE_JDBC=true
export BABASHKA_FEATURE_POSTGRESQL=true
script/test\nscript/run_lib_tests")
(run
"Create uberjar"
"mkdir -p /tmp/release
script/uberjar
VERSION=$(cat resources/BABASHKA_VERSION)
jar=target/babashka-$VERSION-standalone.jar
cp $jar /tmp/release
export PATH=$GRAALVM_HOME/bin:$PATH
export JAVA_HOME=$GRAALVM_HOME
java -jar $jar script/reflection.clj
reflection=\"babashka-$VERSION-reflection.json\"
java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$jar\"
java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$reflection\"")
{:store_artifacts {:path "/tmp/release"
:destination "release"}}
{:save_cache {:paths ["~/.m2"]
:key "v1-dependencies-{{ checksum \"project.clj\" }}-{{ checksum \"deps.edn\" }}"}}]))))
(defn unix
[shorted? static? musl? arch executor-conf resource-class graalvm-home platform]
(let [env {:LEIN_ROOT "true"
:GRAALVM_VERSION graalvm-version
:GRAALVM_HOME graalvm-home
:BABASHKA_PLATFORM (if (= "mac" platform)
"macos"
platform)
:BABASHKA_TEST_ENV "native"
:BABASHKA_XMX "-J-Xmx6500m"
:BABASHKA_SHA (System/getenv "CIRCLE_SHA1")}
env (if (= "aarch64" arch)
(assoc env :BABASHKA_ARCH arch)
env)
env (if static?
(assoc env :BABASHKA_STATIC "true")
env)
env (if musl?
(assoc env :BABASHKA_MUSL "true")
env)
env (if (= "mac" platform)
(assoc env :MACOSX_DEPLOYMENT_TARGET 10.13)
env)
base-install-cmd "sudo apt-get update\nsudo apt-get -y install build-essential zlib1g-dev"
cache-key (format "%s-%s{{ checksum \"project.clj\" }}-{{ checksum \".circleci/config.yml\" }}"
platform
(if (= "aarch64" arch)
"aarch64-"
""))]
(gen-job shorted?
(merge
executor-conf
(ordered-map
:working_directory "~/repo"
:environment env
:resource_class resource-class
:steps (gen-steps shorted?
(filter some?
[:checkout
(when (contains? #{"linux" "linux-aarch64"} platform)
(run "Check max glibc version" "script/check_glibc.sh"))
{:attach_workspace {:at "/tmp"}}
(run "Pull Submodules" "git submodule init\ngit submodule update")
{:restore_cache
{:keys [cache-key]}}
(when (= "mac" platform)
(run "Install Rosetta" "sudo /usr/sbin/softwareupdate --install-rosetta --agree-to-license"))
(run "Install Clojure" "sudo script/install-clojure")
(when (= "mac" platform)
(run "Install Leiningen" "script/install-leiningen"))
(when (not= "mac" platform)
(run "Install native dev tools"
(if (and static? musl? (not= "aarch64" arch))
(str base-install-cmd "\nsudo -E script/setup-musl")
base-install-cmd)))
(run "Download GraalVM" "script/install-graalvm")
#_(run "Download iprof" "curl -sLO 'https://github.com/babashka/pgo-profiles/releases/download/2023.10.11/default.iprof'")
(run "Build binary" (if (= "aarch64" arch)
"script/uberjar\nscript/compile -H:PageSize=64K # --pgo=default.iprof"
"script/uberjar\nscript/compile # --pgo=default.iprof") "30m")
(run "Release" ".circleci/script/release")
{:persist_to_workspace {:root "/tmp"
:paths ["release"]}}
(run "Run tests" "script/test\nscript/run_lib_tests")
(run "Release + publish"
(str/join "\n" ["export BABASHKA_RELEASE=true"
".circleci/script/release"]))
{:save_cache
{:paths ["~/.m2" "~/graalvm"]
:key cache-key}}
{:store_artifacts {:path "/tmp/release"
:destination "release"}}
(run "Publish artifact link to Slack"
"./bb .circleci/script/publish_artifact.clj || true")])))))))
(defn make-config
[shorted?]
(let [docker-executor-conf {:docker [{:image "circleci/clojure:openjdk-11-lein-2.9.8-bullseye"}]}
machine-executor-conf {:machine {:image "ubuntu-2004:2024.05.1"}}
mac-executor-conf {:macos {:xcode "13.4.1"}}
linux-graalvm-home (str "/home/circleci/graalvm-" graalvm-version)
mac-graalvm-home (format "/Users/distiller/graalvm-%s/Contents/Home" graalvm-version)]
(ordered-map
:version 2.1
:commands
{:setup-docker-buildx
{:steps
[{:run
{:name "Create multi-platform capabale buildx builder"
:command
"docker run --privileged --rm tonistiigi/binfmt --install all\ndocker buildx create --name ci-builder --use"}}]}}
:jobs (ordered-map
:jvm (jvm shorted? linux-graalvm-home)
:linux (unix shorted? false false "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-static
(unix shorted? true true "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-aarch64-static
(unix shorted? true false "aarch64" machine-executor-conf "arm.large" linux-graalvm-home "linux")
:mac (unix shorted? false false "amd64" mac-executor-conf "macos.m1.medium.gen1" mac-graalvm-home "mac")
:deploy (deploy shorted?)
:docker (docker shorted?))
:workflows (ordered-map
:version 2
:ci {:jobs ["jvm"
"linux"
"linux-static"
"mac"
"linux-aarch64-static"
{:deploy {:filters {:branches {:only "master"}}
:requires ["jvm" "linux"]}}
{:docker {:filters {:branches {:only "master"}}
:requires ["linux" "linux-static" "linux-aarch64-static"]}}]}))))
(def skip-config
{:skip-if-only [#".*.md$"
#"^logo\/.*$"]})
(defn get-changes
[]
(-> (tasks/shell {:out :string} "git diff --name-only HEAD~1")
(:out)
(str/split-lines)))
(defn irrelevant-change?
[change regexes]
(some? (some #(re-matches % change) regexes)))
(defn relevant?
[change-set regexes]
(some? (some #(not (irrelevant-change? % regexes)) change-set)))
(defn main
[]
(let [{:keys [skip-if-only]} skip-config
changed-files (get-changes)
conf (make-config (not (relevant? changed-files skip-if-only)))]
(println (yaml/generate-string conf
:dumper-options
{:flow-style :block}))))
(when (= *file* (System/getProperty "babashka.file"))
(main))
(comment
(main)
(def regexes
[#".*.md$"
#".*.clj$" ; ignore clojure files
#"^logo\/.*$"])
(:out (tasks/shell {:out :string} "ls"))
(irrelevant-change? "src/file.png" regexes)
(re-matches #".*.clj$" "src/file.clj.dfff")
(re-matches #"^logo\/.*$" "logo/foo/bar.jpg")
(relevant? ["src/file.clj"] regexes))

View file

@ -1,14 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail
CLOJURE_TOOLS_VERSION="1.11.1.1200"
install_dir="${1:-/usr/local}"
install_dir=${1:-/tmp/clojure}
mkdir -p "$install_dir"
cd /tmp
curl -O -sL "https://download.clojure.org/install/clojure-tools-$CLOJURE_TOOLS_VERSION.tar.gz"
tar xzf "clojure-tools-$CLOJURE_TOOLS_VERSION.tar.gz"
curl -O -sL https://download.clojure.org/install/clojure-tools-1.10.1.447.tar.gz
tar xzf clojure-tools-1.10.1.447.tar.gz
cd clojure-tools
clojure_lib_dir="$install_dir/lib/clojure"
mkdir -p "$clojure_lib_dir/libexec"
@ -22,6 +18,6 @@ cp clojure "$install_dir/bin"
cp clj "$install_dir/bin"
cd /tmp
rm -rf "clojure-tools-$CLOJURE_TOOLS_VERSION.tar.gz"
rm -rf "clojure-tools"
rm -rf clojure-tools-1.10.1.447.tar.gz
rm -rf clojure-tools
echo "Installed clojure to $install_dir/bin"

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
curl https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein > lein
sudo mkdir -p /usr/local/bin/
sudo mv lein /usr/local/bin/lein
sudo chmod a+x /usr/local/bin/lein

View file

@ -1,45 +0,0 @@
(require '[babashka.curl :as curl]
'[cheshire.core :refer [generate-string]]
'[clojure.java.io :as io]
'[clojure.string :as str])
(def channel "#babashka-circleci-builds")
#_(def channel "#_test")
(def babashka-version (str/trim (slurp (io/file "resources" "BABASHKA_VERSION"))))
(def slack-hook-url (System/getenv "SLACK_HOOK_URL"))
(defn slack! [text]
(when slack-hook-url
(let [json (generate-string {:username "borkdude"
:channel channel
:text text})]
(curl/post slack-hook-url {:headers {"content-type" "application/json"}
:body json}))))
(def platform
(str (System/getenv "BABASHKA_PLATFORM")
"-"
(or (System/getenv "BABASHKA_ARCH") "amd64")
(when (= "true" (System/getenv "BABASHKA_STATIC"))
"-static")))
(def release-text (format "[%s - %s@%s - %s]: https://%s-201467090-gh.circle-artifacts.com/0/release/babashka-%s-%s.tar.gz"
platform
(System/getenv "CIRCLE_BRANCH")
(System/getenv "CIRCLE_SHA1")
(slurp (io/file "/tmp/bb_size/size"))
(System/getenv "CIRCLE_BUILD_NUM")
babashka-version
platform
))
(slack! release-text)
#_#_(def binary-size-text
(format "[%s - %s@%s] binary size: %s"
platform
(System/getenv "CIRCLE_BRANCH")
(System/getenv "CIRCLE_SHA1")
(slurp (io/file "/tmp/bb_size/size"))))
(slack! binary-size-text)

View file

@ -3,37 +3,16 @@
rm -rf /tmp/release
mkdir -p /tmp/release
cp bb /tmp/release
# cp src-bash/bbk /tmp/release
VERSION=$(cat resources/BABASHKA_VERSION)
## release binary as tar.gz archive
arch=${BABASHKA_ARCH:-amd64}
if [ "$BABASHKA_STATIC" = "true" ]; then
arch="$arch-static"
fi
# because circle won't allow the same file to be saved/restored in the same workspace concurrently
cp metabom.jar "/tmp/release/$BABASHKA_PLATFORM-$arch-metabom.jar"
cd /tmp/release
mkdir -p /tmp/bb_size
./bb '(spit "/tmp/bb_size/size" (.length (io/file "bb")))'
archive="babashka-$VERSION-$BABASHKA_PLATFORM-$arch.tar.gz"
## release binary as zip archive
tar zcvf "$archive" bb # bbk
cd -
if [ "$BABASHKA_RELEASE" = "true" ]; then
./bb --config .build/bb.edn --deps-root . release-artifact "/tmp/release/$archive"
fi
zip "babashka-$VERSION-$BABASHKA_PLATFORM-amd64.zip" bb # bbk
## cleanup
cd /tmp/release
rm bb # bbk

View file

@ -1,42 +0,0 @@
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-base:latest
task:
skip: "changesIncludeOnly('logo/*', '**.md')"
env:
LEIN_ROOT: "true"
GRAALVM_VERSION: "24"
GRAALVM_HOME: ${HOME}/graalvm-${GRAALVM_VERSION}/Contents/Home
BABASHKA_PLATFORM: macos # used in release script
BABASHKA_ARCH: aarch64
BABASHKA_TEST_ENV: native
BABASHKA_XMX: "-J-Xmx6500m"
GITHUB_TOKEN: ENCRYPTED[d6ff8cdc392157f211c754fa0763875434d1bfde0c00a05e48ba9470003a76c14c9213adb80623f81e13f2f0fa8fbd57]
script: |
git submodule init
git submodule update
sudo script/install-clojure
sudo script/install-leiningen
script/install-graalvm
export PATH=$GRAALVM_HOME/bin:$PATH
export JAVA_HOME=$GRAALVM_HOME
sudo /usr/sbin/softwareupdate --install-rosetta --agree-to-license
java -version
export BABASHKA_SHA=$(git rev-parse HEAD)
script/uberjar
# curl -sLO 'https://github.com/babashka/pgo-profiles/releases/download/2023.10.11/default.iprof'
script/compile # --pgo=default.iprof
# script/test
# script/run_lib_tests
VERSION=$(cat resources/BABASHKA_VERSION)
arch=${BABASHKA_ARCH:-amd64}
archive="babashka-$VERSION-$BABASHKA_PLATFORM-$arch.tar.gz"
tar zcvf "$archive" bb
./bb --config .build/bb.edn --deps-root . release-artifact "$archive" || true
binaries_artifacts:
path: "babashka-*.tar.gz"

View file

@ -1 +0,0 @@
{:lint-as {babashka.fs/with-temp-dir clojure.core/let}}

View file

@ -1 +0,0 @@
{:hooks {:macroexpand {sci.core/copy-ns sci.core/copy-ns}}}

View file

@ -1,9 +0,0 @@
(ns sci.core)
(defmacro copy-ns
([ns-sym sci-ns]
`(copy-ns ~ns-sym ~sci-ns nil))
([ns-sym sci-ns opts]
`[(quote ~ns-sym)
~sci-ns
(quote ~opts)]))

View file

@ -1,9 +1,6 @@
{:config-paths ["babashka/sci"]
:lint-as {me.raynes.conch/let-programs clojure.core/let
{:lint-as {me.raynes.conch/let-programs clojure.core/let
babashka.impl.File/gen-wrapper-fn clojure.core/def
babashka.impl.Pattern/gen-wrapper-fn clojure.core/def
babashka.impl.File/gen-wrapper-fn-2 clojure.core/def
babashka.impl.Pattern/gen-wrapper-fn-2 clojure.core/def
babashka.impl.Pattern/gen-constants clojure.core/declare}
:linters {:unsorted-required-namespaces {:level :warning}}
:hooks {:analyze-call {clojure.core/requiring-resolve hooks.mine/req-resolve}}}
babashka.impl.Pattern/gen-constants clojure.core/declare}}

View file

@ -1,5 +0,0 @@
{:lint-as
{rewrite-clj.zip/subedit-> clojure.core/->
rewrite-clj.zip/subedit->> clojure.core/->>
rewrite-clj.zip/edit-> clojure.core/->
rewrite-clj.zip/edit->> clojure.core/->>}}

View file

@ -1,2 +0,0 @@
((clojure-mode
(cider-clojure-cli-aliases . "test")))

View file

@ -1,19 +0,0 @@
.circleci/
.git/
.clj-kondo/
.github/
doc/
examples/
logo/
test-resources/
test/
.gitignore
.carve_ignore
.gitmodules
appveyor.yml
CHANGES.md
Dockerfile
LICENSE
README.md
.cpcache/
target/

5
.github/FUNDING.yml vendored
View file

@ -1,7 +1,8 @@
# These are supported funding model platforms
github: borkdude # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
open_collective: babashka
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: borkdude
open_collective: # Replace with a single Open Collective username
ko_fi: borkdude
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry

View file

@ -7,12 +7,9 @@ assignees: ''
---
[ To keep development of this project going, consider sponsoring. If you are
already a sponsor, thank you! ]
**version**
[ Please specify which version of babashka you're using. You can find this with `babashka --version`. The documentation on the master branch may be ahead of the most released version. ]
[ Please specify which version of babashka you're using. You can find this with `babashka --version`. The documentation on the master branch may be ahead of the most released version. You can check the docs for your version by going to cljdoc. ]
**platform**

View file

@ -7,9 +7,6 @@ assignees: ''
---
[ To keep development of this project going, consider sponsoring. If you are
already a sponsor, thank you! ]
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

View file

@ -1,9 +0,0 @@
Please answer the following questions and leave the below in as part of your PR.
- [ ] I have read the [developer documentation](https://github.com/babashka/babashka/blob/master/doc/dev.md).
- [ ] This PR corresponds to an [issue with a clear problem statement](https://github.com/babashka/babashka/blob/master/doc/dev.md#start-with-an-issue-before-writing-code).
- [ ] This PR contains a [test](https://github.com/babashka/babashka/blob/master/doc/dev.md#tests) to prevent against future regressions
- [ ] I have updated the [CHANGELOG.md](https://github.com/babashka/babashka/blob/master/CHANGELOG.md) file with a description of the addressed issue.

View file

@ -1,8 +0,0 @@
#!/usr/bin/env bash
if [ -z "$GITHUB_HEAD_REF" ] && [ "${GITHUB_REF##*/}" = "master" ]
then
lein deploy clojars
fi
exit 0;

View file

@ -1,99 +0,0 @@
name: build
on:
push:
paths-ignore:
- "**.md"
- "logo/**"
pull_request:
paths-ignore:
- "**.md"
- "logo/**"
# TODO: Add deploy if needed
jobs:
native:
if: "!contains(github.event.head_commit.message, 'skip ci')"
strategy:
matrix:
include:
- os: windows-2022
name: windows
static: false
runs-on: ${{ matrix.os }}
env:
LEIN_ROOT: "true"
GRAALVM_VERSION: "24"
BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script
BABASHKA_TEST_ENV: native
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BABASHKA_SHA: ${{ github.sha }}
steps:
- name: Git checkout
uses: actions/checkout@v2
with:
fetch-depth: 1
submodules: 'true'
- name: Cache deps
uses: actions/cache@v4
id: cache-deps
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('project.clj') }}
restore-keys: ${{ runner.os }}-maven-
- name: Setup GraalVM
if: "matrix.static == false"
uses: graalvm/setup-graalvm@v1.3.3
with:
java-version: '24'
distribution: 'graalvm'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install clojure tools
uses: DeLaGuardo/setup-clojure@13.2
with:
cli: latest
# lein: latest -- skipped because this uses some PS bullshit
- name: Babashka version
id: babashka-version
shell: bash
run: |
BABASHKA_VERSION=$(cat resources/BABASHKA_VERSION)
echo "##[set-output name=version;]${BABASHKA_VERSION}"
- name: Build
shell: cmd
run: |
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat', 'lein.bat')"
call lein self-install
set GRAALVM_HOME=%JAVA_HOME%
call script/uberjar.bat
call script/compile.bat
echo Creating zip archive
set zip=babashka-%BABASHKA_VERSION%-windows-amd64.zip
jar -cMf %zip% bb.exe
bb --config .build/bb.edn --deps-root . release-artifact %zip%
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
path: bb.exe
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-amd64
- name: Test binary and libs
shell: cmd
run: |
set BABASHKA_CLASSPATH=
set BABASHKA_TEST_ENV=native
call script/test.bat :windows
call script/run_lib_tests.bat

View file

@ -1,242 +0,0 @@
name: build
on:
push:
paths-ignore:
- "**.md"
- "logo/**"
branches:
- master
pull_request:
paths-ignore:
- "**.md"
- "logo/**"
branches:
- master
# TODO: Add deploy if needed
jobs:
jvm:
if: ${{ false }} # Disabled
# if: "!contains(github.event.head_commit.message, 'skip ci')"
runs-on: ubuntu-latest
env:
LEIN_ROOT: "true"
BABASHKA_PLATFORM: linux # could be used in jar name
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BABASHKA_SHA: ${{ github.sha }}
steps:
- name: Git checkout
uses: actions/checkout@v2
with:
fetch-depth: 1
submodules: 'true'
- name: Cache deps
uses: actions/cache@v4
id: cache-deps
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('project.clj') }}
restore-keys: ${{ runner.os }}-maven-
- name: Prepare java
uses: actions/setup-java@v2
with:
distribution: 'adopt-hotspot'
java-version: '19'
- name: Install clojure tools
uses: DeLaGuardo/setup-clojure@5.0
with:
cli: 1.10.3.1040
lein: 2.9.8
- name: Run tests
env:
BABASHKA_FEATURE_JDBC: "true"
BABASHKA_FEATURE_POSTGRESQL: "true"
run: |
script/test
script/run_lib_tests
- name: Build uberjar
run: |
mkdir -p /tmp/release
script/uberjar
VERSION=$(cat resources/BABASHKA_VERSION)
jar=target/babashka-$VERSION-standalone.jar
cp $jar /tmp/release
java -jar $jar script/reflection.clj
reflection="babashka-$VERSION-reflection.json"
java -jar "$jar" --config .build/bb.edn --deps-root . release-artifact "$jar"
java -jar "$jar" --config .build/bb.edn --deps-root . release-artifact "$reflection"
- name: Babashka version
id: babashka-version
run: |
BABASHKA_VERSION=$(cat resources/BABASHKA_VERSION)
echo "##[set-output name=version;]${BABASHKA_VERSION}"
- uses: actions/upload-artifact@v4
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-standalone.jar
path: target/babashka-${{ steps.babashka-version.outputs.version }}-standalone.jar
native:
if: "!contains(github.event.head_commit.message, 'skip ci')"
strategy:
matrix:
include:
- os: macos-13
name: macos
static: false
#- os: ubuntu-latest
# name: linux
# static: false
#- os: ubuntu-latest
# name: linux
# static: true
runs-on: ${{ matrix.os }}
env:
LEIN_ROOT: "true"
GRAALVM_VERSION: "24"
BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script
BABASHKA_TEST_ENV: native
BABASHKA_XMX: "-J-Xmx6500m"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BABASHKA_SHA: ${{ github.sha }}
steps:
- name: Git checkout
uses: actions/checkout@v2
with:
fetch-depth: 1
submodules: 'true'
- name: Cache deps
uses: actions/cache@v4
id: cache-deps
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('project.clj') }}
restore-keys: ${{ runner.os }}-maven-
- name: Setup GraalVM
if: "matrix.static == false"
uses: graalvm/setup-graalvm@v1
with:
java-version: '24'
distribution: 'graalvm'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup GraalVM+musl
if: "matrix.static == true"
uses: graalvm/setup-graalvm@v1
with:
version: '24'
distribution: 'graalvm'
components: 'native-image'
native-image-musl: true
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install clojure tools
uses: DeLaGuardo/setup-clojure@5.0
with:
cli: 1.10.3.1040
lein: 2.9.8
- name: Install native dev tools
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get -y install build-essential zlib1g-dev
- name: Babashka version
id: babashka-version
run: |
BABASHKA_VERSION=$(cat resources/BABASHKA_VERSION)
echo "##[set-output name=version;]${BABASHKA_VERSION}"
- name: Build uberjar
run: script/uberjar
- name: Build native image
if: "matrix.static == false"
run: script/compile
- name: Build static native image
if: "matrix.static == true"
env:
BABASHKA_STATIC: "true"
BABASHKA_MUSL: "true"
run: script/compile
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-amd64
- name: Upload static artifact
if: "matrix.static == true"
uses: actions/upload-artifact@v4
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-static-amd64
- name: Test binary and libs
run: |
script/test
script/run_lib_tests
- name: Release
run: .circleci/script/release
docker:
if: ${{ false }} # Disabled
# if: "!contains(github.event.head_commit.message, 'skip ci') && github.event_name == 'push' && github.ref == 'refs/heads/master'"
needs:
- native
runs-on: ubuntu-latest
steps:
- name: Git checkout
uses: actions/checkout@v2
with:
fetch-depth: 1
submodules: 'true'
- name: Babashka version
id: babashka-version
run: |
BABASHKA_VERSION=$(cat resources/BABASHKA_VERSION)
echo "##[set-output name=version;]${BABASHKA_VERSION}"
- name: Make release dir
run: mkdir -p /tmp/release
- name: Download linux binary
uses: actions/download-artifact@v4.1.7
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-linux-amd64.zip
path: /tmp/release
- name: Download static linux binary
uses: actions/download-artifact@v4.1.7
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-linux-static-amd64.zip
path: /tmp/release-static
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
- name: Build uberjar
run: script/uberjar
- name: Docker build
env:
DOCKERHUB_USER: "${{ secrets.DOCKERHUB_USER }}"
DOCKERHUB_PASS: "${{ secrets.DOCKERHUB_PASS }}"
PLATFORMS: linux/amd64,linux/arm64
run: java -jar ./target/babashka-$(cat resources/BABASHKA_VERSION)-standalone.jar .circleci/script/docker.clj

25
.gitignore vendored
View file

@ -14,28 +14,5 @@ pom.xml.asc
.clj-kondo/.cache
!java/src/babashka/impl/LockFix.class
!test-resources/babashka/src_for_classpath_test/foo.jar
!test-resources/pom.xml
.cpcache
*reflect-config.json
/tmp
/reports
*.dylib
*.log
org_babashka*.h
/babashka-0.1.4-SNAPSHOT-windows-amd64.zip
/bb.exe
/bb.exp
/bb.lib
/bb.pdb
/bb.stripped.pdb
/.calva
!test-resources/divide_by_zero.jar
.envrc
.lsp
bb.build_artifacts.txt
target
.nrepl-port
.DS_Store
.portal
default.iprof
scratch.clj
deps.edn

24
.gitmodules vendored
View file

@ -2,27 +2,3 @@
path = sci
url = https://github.com/borkdude/sci
branch = master
[submodule "babashka.curl"]
path = babashka.curl
url = https://github.com/babashka/babashka.curl
[submodule "babashka.nrepl"]
path = babashka.nrepl
url = https://github.com/babashka/babashka.nrepl
[submodule "depstar"]
path = depstar
url = https://github.com/babashka/depstar
[submodule "process"]
path = process
url = https://github.com/babashka/process
[submodule "pods"]
path = pods
url = https://github.com/babashka/pods
[submodule "deps.clj"]
path = deps.clj
url = https://github.com/borkdude/deps.clj
[submodule "fs"]
path = fs
url = https://github.com/babashka/fs
[submodule "babashka.core"]
path = babashka.core
url = https://github.com/babashka/babashka.core.git

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
See [doc/dev.md](doc/dev.md).

View file

@ -1,81 +0,0 @@
FROM clojure:openjdk-11-lein-2.9.6-bullseye AS BASE
ENV DEBIAN_FRONTEND=noninteractive
RUN apt update
RUN apt install --no-install-recommends -yy build-essential zlib1g-dev
WORKDIR "/opt"
ENV GRAALVM_VERSION="24"
ARG TARGETARCH
# Do not set those directly, use TARGETARCH instead
ENV BABASHKA_ARCH=
ENV GRAALVM_ARCH=
RUN if [ "${TARGETARCH}" = "" ] || [ "${TARGETARCH}" = "amd64" ]; then \
export GRAALVM_ARCH=x64; export BABASHKA_ARCH=x86_64; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
export GRAALVM_ARCH=aarch64; \
fi && \
echo "Installing GraalVM for ${GRAALVM_ARCH}" && \
curl -sLO https://download.oracle.com/graalvm/${GRAALVM_VERSION}/archive/graalvm-jdk-${GRAALVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz && \
mkdir "graalvm-$GRAALVM_VERSION" && \
tar -xzf graalvm-jdk-${GRAALVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz -C graalvm-$GRAALVM_VERSION --strip-components 1
ARG BABASHKA_XMX="-J-Xmx4500m"
ENV GRAALVM_HOME="/opt/graalvm-$GRAALVM_VERSION"
ENV JAVA_HOME="$GRAALVM_HOME/bin"
ENV PATH="$JAVA_HOME:$PATH"
ENV BABASHKA_XMX=$BABASHKA_XMX
# Make it possible to use Docker to build bb with a particular set of features
# by setting them at build time via `docker build --build-arg ARG_NAME=true ...`
ARG BABASHKA_LEAN=
ARG BABASHKA_MUSL=
ARG BABASHKA_FEATURE_CSV=
ARG BABASHKA_FEATURE_JAVA_NET_HTTP=
ARG BABASHKA_FEATURE_JAVA_NIO=
ARG BABASHKA_FEATURE_JAVA_TIME=
ARG BABASHKA_FEATURE_TRANSIT=
ARG BABASHKA_FEATURE_XML=
ARG BABASHKA_FEATURE_YAML=
ARG BABASHKA_FEATURE_HTTPKIT_CLIENT=
ARG BABASHKA_FEATURE_HTTPKIT_SERVER=
ARG BABASHKA_FEATURE_JDBC=
ARG BABASHKA_FEATURE_POSTGRESQL=
ARG BABASHKA_FEATURE_HSQLDB=
ARG BABASHKA_FEATURE_ORACLEDB=
ARG BABASHKA_FEATURE_DATASCRIPT=
ARG BABASHKA_FEATURE_LANTERNA=
ARG BABASHKA_STATIC=
ENV BABASHKA_LEAN=$BABASHKA_LEAN
ENV BABASHKA_FEATURE_CSV=$BABASHKA_FEATURE_CSV
ENV BABASHKA_FEATURE_JAVA_NET_HTTP=$BABASHKA_FEATURE_JAVA_NET_HTTP
ENV BABASHKA_FEATURE_JAVA_NIO=$BABASHKA_FEATURE_JAVA_NIO
ENV BABASHKA_FEATURE_JAVA_TIME=$BABASHKA_FEATURE_JAVA_TIME
ENV BABASHKA_FEATURE_TRANSIT=$BABASHKA_FEATURE_TRANSIT
ENV BABASHKA_FEATURE_XML=$BABASHKA_FEATURE_XML
ENV BABASHKA_FEATURE_YAML=$BABASHKA_FEATURE_YAML
ENV BABASHKA_FEATURE_HTTPKIT_CLIENT=$BABASHKA_FEATURE_HTTPKIT_CLIENT
ENV BABASHKA_FEATURE_HTTPKIT_SERVER=$BABASHKA_FEATURE_HTTPKIT_SERVER
ENV BABASHKA_FEATURE_JDBC=$BABASHKA_FEATURE_JDBC
ENV BABASHKA_FEATURE_POSTGRESQL=$BABASHKA_FEATURE_POSTGRESQL
ENV BABASHKA_FEATURE_HSQLDB=$BABASHKA_FEATURE_HSQLDB
ENV BABASHKA_FEATURE_ORACLEDB=$BABASHKA_FEATURE_ORACLEDB
ENV BABASHKA_FEATURE_DATASCRIPT=$BABASHKA_FEATURE_DATASCRIPT
ENV BABASHKA_FEATURE_LANTERNA=$BABASHKA_FEATURE_LANTERNA
ENV BABASHKA_STATIC=$BABASHKA_STATIC
ENV BABASHKA_MUSL=$BABASHKA_MUSL
COPY . .
RUN ./script/uberjar
RUN ./script/setup-musl
RUN ./script/compile
FROM ubuntu:latest
RUN apt-get update && apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /usr/local/bin
COPY --from=BASE /opt/target/metabom.jar /opt/babashka-metabom.jar
COPY --from=BASE /opt/bb /usr/local/bin/bb
CMD ["bb"]

View file

@ -1,35 +0,0 @@
FROM alpine:3 AS tester
COPY bb /bin/bb
RUN chmod +x /bin/bb
# TODO: See https://github.com/sgerrand/alpine-pkg-glibc/issues/185 and remove the `--force-overwrite`s when resolved.
RUN apk --no-cache add curl ca-certificates tar && \
curl -Ls https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk > /tmp/glibc-2.28-r0.apk && \
apk add --allow-untrusted --force-overwrite /tmp/glibc-2.28-r0.apk
RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
# TODO: Run actual native tests when they are ported
RUN curl --version
# RUN bb -e '(prn (java.io.File/createTempFile "babashka.curl" ".headers"))'
# RUN bb -e '(spit (java.io.File/createTempFile "babashka.curl" ".headers") "hello")'
# RUN bb -e "(curl/get \"https://clojure.org\")" # cURL http test
RUN bb -e "(require '[org.httpkit.client :as http]) (when-let [error (:error @(http/get \"https://clojure.org\"))] (throw error))" # JVM http test
RUN bb -e "(.length \"Hello, Babashka\")" # Java interop test
RUN bb -e "(require '[babashka.pods :as pods]) (pods/load-pod 'org.babashka/go-sqlite3 \"0.0.1\") (require '[pod.babashka.go-sqlite3 :as sqlite]) (sqlite/execute! \"/tmp/foo.db\" [\"SELECT 1 + 1\"])" # Pod test
FROM alpine:3
RUN apk --no-cache add curl ca-certificates tar && \
curl -Ls https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk > /tmp/glibc-2.28-r0.apk && \
apk add --allow-untrusted --force-overwrite /tmp/glibc-2.28-r0.apk && rm /tmp/glibc-2.28-r0.apk
RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
COPY metabom.jar /opt/babashka-metabom.jar
COPY --from=tester /bin/bb /bin/bb
CMD ["bb"]

View file

@ -1,16 +0,0 @@
FROM ubuntu:latest
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /usr/local/bin
ARG TARGETARCH
ARG TARGETOS
COPY metabom.jar /opt/babashka-metabom.jar
COPY ${TARGETOS}/${TARGETARCH}/bb /usr/local/bin/bb
RUN chmod +x /usr/local/bin/bb
CMD ["bb"]

897
README.md

File diff suppressed because it is too large Load diff

View file

@ -1,92 +0,0 @@
---
version: "v-{build}"
image: Visual Studio 2022
clone_folder: C:\projects\babashka
environment:
GRAALVM_HOME: C:\projects\babashka\graalvm\graalvm-jdk-24+36.1
JAVA_HOME: C:\projects\babashka\graalvm\graalvm-jdk-24+36.1
BABASHKA_XMX: "-J-Xmx5g"
skip_commits:
files:
- "logo/*"
- "**/*.md"
cache:
- C:\ProgramData\chocolatey\lib -> project.clj, appveyor.yml
- '%USERPROFILE%\.m2 -> project.clj'
- 'graalvm -> appveyor.yml'
clone_script:
- cmd: git config --global core.autocrlf true
- cmd: git config --global core.symlinks true
- ps: >-
if(-not $env:APPVEYOR_PULL_REQUEST_NUMBER) {
git clone -q --branch=$env:APPVEYOR_REPO_BRANCH https://github.com/$env:APPVEYOR_REPO_NAME.git $env:APPVEYOR_BUILD_FOLDER
cd $env:APPVEYOR_BUILD_FOLDER
git checkout -qf $env:APPVEYOR_REPO_COMMIT
} else {
git clone -q https://github.com/$env:APPVEYOR_REPO_NAME.git $env:APPVEYOR_BUILD_FOLDER
cd $env:APPVEYOR_BUILD_FOLDER
git fetch -q origin +refs/pull/$env:APPVEYOR_PULL_REQUEST_NUMBER/merge:
git checkout -qf FETCH_HEAD
}
- cmd: git submodule update --init --recursive
- cmd: git reset --hard
build_script:
# TODO: Extract the zip by removing the top level folder to remove the hardcoded path for GRAALVM_HOME
- cmd: >-
powershell -Command "if (Test-Path('graalvm')) { return } else { (New-Object Net.WebClient).DownloadFile('https://download.oracle.com/graalvm/24/archive/graalvm-jdk-24_windows-x64_bin.zip', 'graalvm.zip') }"
powershell -Command "if (Test-Path('graalvm')) { return } else { Expand-Archive graalvm.zip graalvm }"
- cmd: >-
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat', 'lein.bat')"
call lein self-install
#- cmd: >-
# set BABASHKA_TEST_ENV=jvm
# call script/test.bat
# see https://github.com/quarkusio/quarkus/pull/7663
- cmd: >-
set BABASHKA_SHA=%APPVEYOR_REPO_COMMIT%
call script/uberjar.bat
call script/compile.bat
echo Creating zip archive
set zip=babashka-%BABASHKA_VERSION%-windows-amd64.zip
jar -cMf %zip% bb.exe
bb --config .build/bb.edn --deps-root . release-artifact %zip%
before_test:
- cmd: >-
set BABASHKA_CLASSPATH=
set BABASHKA_TEST_ENV=native
test_script:
- cmd: >-
call script/test.bat :windows
call script/run_lib_tests.bat
artifacts:
- path: babashka-*-windows-amd64.zip
name: babashka

@ -1 +0,0 @@
Subproject commit 52a6037bd4b632bffffb04394fb4efd0cdab6b1e

@ -1 +0,0 @@
Subproject commit e936acd40544eb637b6041c7e89454b21eb7ee34

@ -1 +0,0 @@
Subproject commit edd3d613bfb9bf3adabfd0bda5c3f5c6ee85ec20

@ -1 +0,0 @@
Subproject commit 976cf7b0e54901ada3f7e83f12a4c0aed039adc9

198
deps.edn
View file

@ -1,198 +0,0 @@
{:paths ["src" "feature-xml"
"feature-yaml" "feature-csv" "feature-transit"
"feature-java-time" "feature-java-nio"
"feature-httpkit-client" "feature-httpkit-server"
"feature-lanterna"
"feature-core-match"
"feature-hiccup"
"feature-test-check"
"feature-spec-alpha"
"feature-selmer"
"feature-logging"
"feature-priority-map"
"feature-rrb-vector"
"feature-jdbc"
"pods/src"
"babashka.nrepl/src"
"depstar/src" "process/src"
"deps.clj/src" "deps.clj/resources"
"resources" "sci/resources"
"impl-java/src"],
:deps {org.clojure/clojure {:mvn/version "1.12.0"},
org.babashka/sci {:local/root "sci"}
org.babashka/babashka.impl.java {:mvn/version "0.1.10"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"}
babashka/babashka.curl {:local/root "babashka.curl"}
babashka/fs {:local/root "fs"}
babashka/babashka.core {:local/root "babashka.core"}
org.clojure/core.async {:mvn/version "1.8.741"},
org.clojure/tools.cli {:mvn/version "1.0.214"},
org.clojure/data.csv {:mvn/version "1.0.0"},
cheshire/cheshire {:mvn/version "6.0.0"}
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
clj-commons/clj-yaml {:mvn/version "1.0.29"}
com.cognitect/transit-clj {:mvn/version "1.0.333"}
org.clojure/test.check {:mvn/version "1.1.1"}
nrepl/bencode {:mvn/version "1.2.0"}
seancorfield/next.jdbc {:mvn/version "1.1.610"}
org.postgresql/postgresql {:mvn/version "42.2.18"}
org.hsqldb/hsqldb {:mvn/version "2.5.1"}
datascript/datascript {:mvn/version "1.0.1"}
http-kit/http-kit {:mvn/version "2.8.0-RC1"}
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
org.clojure/core.match {:mvn/version "1.0.0"}
hiccup/hiccup {:mvn/version "2.0.0-RC1"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.49"}
selmer/selmer {:mvn/version "1.12.59"}
com.taoensso/timbre {:mvn/version "6.6.0"}
org.clojure/tools.logging {:mvn/version "1.1.0"}
org.clojure/data.priority-map {:mvn/version "1.1.0"}
insn/insn {:mvn/version "0.5.2"}
org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
org.babashka/cli {:mvn/version "0.8.65"}
org.babashka/http-client {:mvn/version "0.4.22"}
org.flatland/ordered {:mvn/version "1.15.12"}
org.jsoup/jsoup {:mvn/version "1.20.1"}}
:aliases {:babashka/dev
{:main-opts ["-m" "babashka.main"]}
:profile
{:extra-deps
{com.clojure-goes-fast/clj-async-profiler {:mvn/version "0.5.0"}}
:extra-paths ["test"]
:jvm-opts ["-Djdk.attach.allowAttachSelf"
"-Dclojure.compiler.direct-linking=true"]
:main-opts ["-m" "babashka.profile"]}
:lib-tests
{:extra-paths ["process/src" "process/test" "test-resources/lib_tests"]
:extra-deps {org.clj-commons/clj-http-lite {:mvn/version "0.4.392"}
#_#_org.babashka/spec.alpha {:git/url "https://github.com/babashka/spec.alpha"
:sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"}
lambdaisland/regal {:mvn/version "0.0.143"}
cprop/cprop {:mvn/version "0.1.16"}
comb/comb {:mvn/version "0.1.1"}
mvxcvi/arrangement {:mvn/version "2.0.0"}
org.clojure/data.zip {:mvn/version "1.0.0"}
clojure-csv/clojure-csv {:mvn/version "2.0.2"}
org.clojure/math.combinatorics {:mvn/version "0.1.6"}
doric/doric {:mvn/version "0.9.0"}
henryw374/cljc.java-time
{:git/url "https://github.com/henryw374/cljc.java-time.git"
:sha "e3d184b78e933322b3fcaa6ca66cbb8f42a6b35c"}
camel-snake-kebab/camel-snake-kebab {:mvn/version "0.4.2"}
aero/aero {:mvn/version "1.1.6"}
org.clojure/data.generators {:mvn/version "1.0.0"}
honeysql/honeysql {:mvn/version "1.0.461"}
com.github.seancorfield/honeysql {:mvn/version "2.2.840"}
minimallist/minimallist {:mvn/version "0.0.10"}
circleci/bond {:mvn/version "0.6.0"}
version-clj/version-clj {:mvn/version "2.0.2"}
gaka/gaka {:mvn/version "0.3.0"}
failjure/failjure {:mvn/version "2.2.0"}
io.helins/binf {:mvn/version "1.1.0-beta0"}
rm-hull/jasentaa {:mvn/version "0.2.5"}
slingshot/slingshot {:mvn/version "0.12.2"}
io.replikativ/hasch {:mvn/version "0.3.7"}
com.grammarly/omniconf {:mvn/version "0.4.3"}
crispin/crispin {:mvn/version "0.3.8"}
org.clojure/data.json {:mvn/version "2.4.0"}
clj-commons/multigrep {:mvn/version "0.5.0"}
amperity/vault-clj {:mvn/version "1.0.4"}
java-http-clj/java-http-clj {:mvn/version "0.4.3"}
com.stuartsierra/component {:mvn/version "1.0.0"}
org.clojars.askonomm/ruuter {:mvn/version "1.2.2"}
org.clj-commons/digest {:mvn/version "1.4.100"}
hato/hato {:mvn/version "0.8.2"}
better-cond/better-cond {:mvn/version "2.1.1"}
org.clojure/core.specs.alpha {:mvn/version "0.2.62"}
reifyhealth/specmonstah {:git/url "https://github.com/reifyhealth/specmonstah", :sha "a2b357009a3aa99a0c2d2361f3bbcd0b0e36505e"}
exoscale/coax {:mvn/version "1.0.0-alpha14"}
orchestra/orchestra {:mvn/version "2021.01.01-1"}
expound/expound {:mvn/version "0.8.10"}
integrant/integrant {:git/url "https://github.com/weavejester/integrant", :git/sha "a9fd7c02bd7201f36344b47142badc3c3ef22f88"}
com.stuartsierra/dependency {:mvn/version "1.0.0"}
listora/again {:mvn/version "1.0.0"}
org.clojure/tools.gitlibs {:mvn/version "2.4.172"}
environ/environ {:mvn/version "1.2.0"}
table/table {:git/url "https://github.com/cldwalker/table", :sha "f6293c5f3dac1dd6f525a80fc80930f8ccdf16b7"}
markdown-clj/markdown-clj {:mvn/version "1.10.8"}
org.clojure/tools.namespace {:git/sha "daf82a10e70182aea4c0716a48f3922163441b32",
:git/url "https://github.com/clojure/tools.namespace"}
medley/medley {:mvn/version "1.3.0"}
io.github.cognitect-labs/test-runner {:git/url "https://github.com/cognitect-labs/test-runner",
:git/sha "7284cda41fb9edc0f3bc6b6185cfb7138fc8a023"}
borkdude/missing.test.assertions {:git/url "https://github.com/borkdude/missing.test.assertions", :sha "603cb01bee72fb17addacc53c34c85612684ad70"}
dev.nubank/docopt {:mvn/version "0.6.1-fix7"}
testdoc/testdoc {:mvn/version "1.4.1"}
org.clojars.lispyclouds/contajners {:mvn/version "0.0.6"}
borkdude/rewrite-edn {:mvn/version "0.1.0"}
clojure-term-colors/clojure-term-colors {:mvn/version "0.1.0"}
io.aviso/pretty {:mvn/version "1.1.1"}
progrock/progrock {:mvn/version "0.1.2"}
djblue/portal {:mvn/version "0.19.0"}
com.wsscode/cljc-misc {:mvn/version "2021.10.16"}
edn-query-language/eql {:mvn/version "2021.07.18"}
meta-merge/meta-merge {:mvn/version "1.0.0"}
com.exoscale/lingo {:mvn/version "1.0.0-alpha14"}
io.github.swirrl/dogstatsd {:mvn/version "0.1.39"}
org.clojure/algo.monads {:mvn/version "0.1.6"}
io.lambdaforge/datalog-parser {:mvn/version "0.1.9"}
clj-stacktrace/clj-stacktrace {:mvn/version "0.2.8"}
clojure-msgpack/clojure-msgpack {:mvn/version "1.2.1"}
cli-matic/cli-matic {:git/url "https://github.com/l3nz/cli-matic.git", :git/sha "9cd53ba7336363e3d06650dbad413b6f8b06e471"}
aysylu/loom {:mvn/version "1.0.2"}
com.layerware/hugsql-core {:mvn/version "0.5.3"}
com.github.seancorfield/expectations {:mvn/version "2.0.157"}
com.rpl/specter {:mvn/version "1.1.4"}
com.github.askonomm/clarktown {:mvn/version "1.1.2"}
org.clojure/math.numeric-tower {:git/tag "math.numeric-tower-0.0.5", :git/sha "12eb9c5", :git/url "https://github.com/clojure/math.numeric-tower"}
prismatic/schema {:git/url "https://github.com/plumatic/schema"
:git/sha "6846dc7c3a9df5bfd718f68f183c683ce0f621ff"
:git/tag "schema-1.3.0"}
metosin/malli {:git/url "https://github.com/metosin/malli"
:git/sha "588147ef49b2e41c7d12a8aa994b39c1c6fedd99"
:git/tag "0.8.9"}
meander/epsilon {:git/url "https://github.com/noprompt/meander"
:git/sha "55f5ce70e6ef717e95c58260f6bc725d70c0cb6d"}
cc.qbits/auspex {:git/url "https://github.com/mpenet/auspex"
:git/sha "1a9d7427e60e1a434a764aa820d1c53f7e22504a"
:deps/manifest :deps}
exoscale/interceptor {:git/url "https://github.com/exoscale/interceptor"
:git/sha "ca115fe00a0abf3a2f78452ab309c3aa4c00fc4e"
:deps/manifest :deps}
lambdaisland/uri {:git/url "https://github.com/lambdaisland/uri"
:git/sha "ac4f1f9c8e4f45a088db1c6383ce2191c973987c"
:deps/manifest :deps}
clj-commons/fs {:mvn/version "1.6.310"}
postmortem/postmortem {:git/url "https://github.com/athos/Postmortem"
:git/sha "1a29775a3d286f9f6fe3f979c78b6e2bf298d5ba"}
com.github.rawleyfowler/sluj {:git/url "https://github.com/rawleyfowler/sluj"
:git/sha "4a92e772b4e07bf127423448d4140748b5782198"
:deps/manifest :deps}
net.cgrand/xforms {:git/url "https://github.com/cgrand/xforms"
:git/sha "550dbc150a79c6ecc148d8a7e260e10bc36321c6"
:deps/manifest :deps}
prismatic/plumbing {:git/url "https://github.com/plumatic/plumbing",
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}
org.clj-commons/hickory {:git/url "https://github.com/clj-commons/hickory"
:git/sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"}
com.potetm/fusebox {:git/url "https://github.com/potetm/fusebox"
:git/sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"}
net.sekao/odoyle-rules {:git/url "https://github.com/oakes/odoyle-rules"
:git/sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"}}
:classpath-overrides {org.clojure/clojure nil
org.clojure/spec.alpha nil}}
:clj-nvd
{:extra-deps {clj-nvd/clj-nvd {:git/url "https://github.com/miikka/clj-nvd.git"
:sha "f2ec98699e057a379baf170cb49cf7ad76874a70"}}
:main-opts ["-m" "clj-nvd.core"]}
:test
{:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner
{:git/tag "v0.5.0" :git/sha "b3fd0d2"}
nubank/matcher-combinators {:mvn/version "3.6.0"}}
:main-opts ["-m" "cognitect.test-runner"]
:exec-fn cognitect.test-runner.api/test}
:test-pod
{:extra-paths ["test-resources"]
:main-opts ["-m" "babashka.main" "test-resources/pod.clj"]}}}
;; release

@ -1 +0,0 @@
Subproject commit 2bf9d3c9f15298d7dd9de033674a42f830e23d6f

View file

@ -1,176 +0,0 @@
# Building babashka
## Prerequisites
- Install [lein](https://leiningen.org/) for producing uberjars
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *Oracle GraalVM 24*.
- For Windows, installing Visual Studio 2019 with the "Desktop development
with C++" workload is recommended.
- Set `$GRAALVM_HOME` to the GraalVM distribution directory. On macOS this can look like:
``` shell
export GRAALVM_HOME=~/Downloads/graalvm-jdk-21.0.0.1/Contents/Home
```
On linux:
``` shell
export GRAALVM_HOME=~/Downloads/graalvm-jdk-21.0.0.1
```
On Windows, from the [Visual Studio 2019 x64 Native Tools Command Prompt](https://github.com/oracle/graal/issues/2116#issuecomment-590470806) or `cmd.exe` (not Powershell):
```
set GRAALVM_HOME=%USERPROFILE%\Downloads\graalvm-ce-jdk-21.0.0.1
```
If you are not running from the x64 Native Tools Command Prompt, you will need to set additional environment variables using:
```
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
```
## Clone repository
NOTE: the babashka repository contains submodules. You need to use the
`--recursive` flag to clone these submodules along with the main repo.
``` shellsession
$ git clone https://github.com/babashka/babashka --recursive
```
To update later on:
``` shellsession
$ git submodule update --init --recursive
```
## Build
Run the `uberjar` and `compile` script:
``` shell
$ script/uberjar
$ script/compile
```
To configure max heap size you can use:
```
$ export BABASHKA_XMX="-J-Xmx6500m"
```
Note: setting the max heap size to a low value can cause the build to crash or
take long to complete.
### Alternative: Build inside Docker
To build a Linux version of babashka, you can use `docker build`, enabling the
desired features via `--build-arg` like this:
```shell
docker build --build-arg BABASHKA_FEATURE_JDBC=true --target BASE -t bb-builder .
container_id=$(docker create bb-builder)
docker cp $container_id:/opt/bb bb # copy to ./bb on the host file system
docker rm $container_id
```
NOTE: If you get _Error: Image build request failed with exit status 137_ then
check whether Docker is allowed to use enough memory (e.g. in Docker Desktop
preferences). If it is, then increase the memory GraalVM can use, for example
by adding `--build-arg BABASHKA_XMX="-J-Xmx8g"`
(or whatever Docker has available, bigger than the default).
## Windows
Run `script\uberjar.bat` followed by `script\compile.bat`.
## Static
To compile babashka as a static binary for linux, set the `BABASHKA_STATIC`
environment variable to `true`.
## Feature flags
Babashka supports the following feature flags:
| Name | Description | Default |
|--------|----------------------------------------------|----------|
| `BABASHKA_FEATURE_CSV` | Includes the [clojure.data.csv](https://github.com/clojure/data.csv) library | `true` |
| `BABASHKA_FEATURE_JAVA_NET_HTTP` | Includes commonly used classes from the `java.net.http` package | `true` |
| `BABASHKA_FEATURE_JAVA_NIO` | Includes commonly used classes from the `java.nio` package | `true` |
| `BABASHKA_FEATURE_JAVA_TIME` | Includes commonly used classes from the `java.time` package | `true` |
| `BABASHKA_FEATURE_TRANSIT` | Includes the [transit-clj](https://github.com/cognitect/transit-clj) library | `true` |
| `BABASHKA_FEATURE_XML` | Includes the [clojure.data.xml](https://github.com/clojure/data.xml) library | `true` |
| `BABASHKA_FEATURE_YAML` | Includes the [clj-yaml](https://github.com/clj-commons/clj-yaml) library | `true` |
| `BABASHKA_FEATURE_HTTPKIT_CLIENT` | Includes the [http-kit](https://github.com/http-kit/http-kit) client library | `true` |
| `BABASHKA_FEATURE_HTTPKIT_SERVER` | Includes the [http-kit](https://github.com/http-kit/http-kit) server library | `true` |
| `BABASHKA_FEATURE_CORE_MATCH` | Includes the [clojure.core.match](https://github.com/clojure/core.match) library | `true` |
| `BABASHKA_FEATURE_HICCUP` | Includes the [hiccup](https://github.com/weavejester/hiccup) library | `true` |
| `BABASHKA_FEATURE_TEST_CHECK` | Includes the [clojure.test.check](https://github.com/clojure/test.check) library | `true` |
| `BABASHKA_FEATURE_SPEC_ALPHA` | Includes the [clojure.spec.alpha](https://github.com/clojure/spec.alpha) library (WIP) | `false` |
| `BABASHKA_FEATURE_JDBC` | Includes the [next.jdbc](https://github.com/seancorfield/next-jdbc) library | `false` |
| `BABASHKA_FEATURE_SQLITE` | Includes the [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) library | `false` |
| `BABASHKA_FEATURE_POSTGRESQL` | Includes the [PostgresSQL](https://jdbc.postgresql.org/) JDBC driver | `false` |
| `BABASHKA_FEATURE_HSQLDB` | Includes the [HSQLDB](http://www.hsqldb.org/) JDBC driver | `false` |
| `BABASHKA_FEATURE_ORACLEDB` | Includes the [Oracle](https://www.oracle.com/database/technologies/appdev/jdbc.html) JDBC driver | `false` |
| `BABASHKA_FEATURE_DATASCRIPT` | Includes [datascript](https://github.com/tonsky/datascript) | `false` |
| `BABASHKA_FEATURE_LANTERNA` | Includes [clojure-lanterna](https://github.com/babashka/clojure-lanterna) | `false` |
| `BABASHKA_FEATURE_LOGGING` | Includes [clojure.tools.logging](https://github.com/clojure/tools.logging) with [taoensso.timbre](https://github.com/ptaoussanis/timbre) as the default implementation| `true` |
| `BABASHKA_FEATURE_PRIORITY_MAP` | Includes [clojure.data.priority-map](https://github.com/clojure/data.priority-map) | `true` |
Note that httpkit server is currently experimental, the feature flag could be toggled to `false` in a future release.
To disable all of the above features, you can set `BABASHKA_LEAN` to `true`.
Here is an [example
commit](https://github.com/babashka/babashka/commit/13f65f05aeff891678e88965d9fbd146bfa87f4e)
that can be used as a checklist when you want to create a new feature flag.
### HyperSQL
To compile babashka with the `next.jdbc` library and the embedded HyperSQL
database:
``` shell
$ export BABASHKA_FEATURE_JDBC=true
$ export BABASHKA_FEATURE_HSQLDB=true
$ script/uberjar
$ script/compile
```
Note: there is now a [pod](https://github.com/babashka/babashka-sql-pods) for working with HyperSQL.
### PostgresQL
To compile babashka with the `next.jdbc` library and a PostgresQL driver:
``` shell
$ export BABASHKA_FEATURE_JDBC=true
$ export BABASHKA_FEATURE_POSTGRESQL=true
$ script/uberjar
$ script/compile
```
Note: there is now a [pod](https://github.com/babashka/babashka-sql-pods) for working with PostgreSQL.
### Lanterna
To compile babashka with the [babashka/clojure-lanterna](https://github.com/babashka/clojure-lanterna) library:
``` shell
$ export BABASHKA_FEATURE_LANTERNA=true
$ script/uberjar
$ script/compile
```
Example program:
``` clojure
(require '[lanterna.terminal :as terminal])
(def terminal (terminal/get-terminal))
(terminal/start terminal)
(terminal/put-string terminal "Hello TUI Babashka!" 10 5)
(terminal/flush terminal)
(read-line)
```

View file

@ -1,3 +1,2 @@
{:cljdoc.doc/tree
[["Readme" {:file "README.md"}]
["Developing Babashka" {:file "doc/dev.md"}]]}
[["Readme" {:file "README.md"}]]}

View file

@ -1,77 +0,0 @@
# Companies using babashka
Is your company using babashka? Mention it in
[this](https://github.com/babashka/babashka/discussions/1026) discussion to get
yours listed!
If your company is using clj-kondo as well, mention it
[here](https://github.com/clj-kondo/clj-kondo/discussions/1397).
If your company is sponsoring, it will be listed first (in order of sponsorship
size) with a logo and hiring link (if applicable)!
## Sponsoring companies
### [Adgoji](https://www.adgoji.com/)
![adgoji](https://images.squarespace-cdn.com/content/v1/5e5f79dcaeba9e2b64132975/1585646545419-5DOZS4SVO5AU0MFA3ZB3/adgoji_logofull.png?format=300w)
### [Nubank](https://nubank.com.br/)
<img src="https://upload.wikimedia.org/wikipedia/commons/f/f7/Nubank_logo_2021.svg" width="200">
Sponsoring via [Cognitect](https://www.cognitect.com/).
### [Nextjournal](https://nextjournal.com/)
<img src="https://cdn.nextjournal.com/images/nextjournal-logo.svg" width="300">
### [ATA](https://ata-llc.com) - [hiring](https://www.ziprecruiter.com/c/ATA-LLC/Jobs)
<img width="250" alt="Screen Shot 2022-01-07 at 21 21 00" src="https://user-images.githubusercontent.com/284934/148602984-6c333501-505b-4692-ad7a-62383510fb9a.png">
### [Cognician](https://www.cognician.com)
<img src="https://avatars.githubusercontent.com/u/1450774?s=150&v=4">
### [Fluent](https://fluent.to)
<img src="https://uploads-ssl.webflow.com/600fdbbcf0cbfe02f1a48030/600fdf0fffe881c3e8e298f4_Fluent%20logotype-p-500.png" width="300">
### [180seg](https://www.180s.com.br)
<img src="https://avatars.githubusercontent.com/u/75583439?s=200&v=4">
### [Dr. Evidence](https://www.drevidence.com/)
<img src="https://user-images.githubusercontent.com/284934/138914250-f447ca3d-c1c1-4c60-bfaf-9000541d4a0d.png" width="325">
### [EnjoyHQ](https://getenjoyhq.com/)
<img src="https://getenjoyhq.com/wp-content/uploads/2021/07/EnjoyHQ_uz-blue_cropp.svg" width="300">
### [Epic Castle](https://epiccastle.io)
<img src="https://epiccastle.io/images/logo.png" width="100">
## Companies
- [AWS](https://aws.amazon.com/)
- [Barracuda](https://www.barracuda.com/)
- [Datil](https://datil.com/)
- [Deon Digital](https://www.deondigital.com/)
- [Fluent](https://fluent.to/)
- [Fluree](https://flur.ee/)
- [Hi](https://www.hi.group/)
- [Juxt](https://www.juxt.pro/)
- [Kleene](https://www.kleene.ai/)
- [Latacora](https://www.latacora.com/)
- [Metosin](https://www.metosin.fi/en/)
- [Nextdoc](https://www.nextdoc.io/)
- [PractiTest](https://www.practitest.com/)
- [Reify Health](https://www.reifyhealth.com/)
- [Schnaq](https://schnaq.com/)
- [Splash Financial](https://www.splashfinancial.com/)
- [TOYOKUMO, Inc.](https://toyokumo.co.jp/)
- [Xcoo](https://xcoo.com/)
- [Zero one group](https://zero-one-group.com/)

View file

@ -1,275 +0,0 @@
# Developing Babashka
## Workflow
### Start with an issue before writing code
Before writing any code, please create an issue first that describes the problem
you are trying to solve with alternatives that you have considered. A little bit
of prior communication can save a lot of time on coding. Keep the problem as
small as possible. If there are two problems, make two issues. We discuss the
issue and if we reach an agreement on the approach, it's time to move on to a
PR.
### Follow up with a pull request
Post a corresponding PR with the smallest change possible to address the
issue. Then we discuss the PR, make changes as needed and if we reach an
agreement, the PR will be merged.
### Tests
Each bug fix, change or new feature should be tested well to prevent future
regressions.
If possible, tests should use public APIs. If the bug is in private/internal
code, try to trigger it from a public API.
### Force-push
Please do not use `git push --force` on your PR branch for the following
reasons:
- It makes it more difficult for others to contribute to your branch if needed.
- It makes it harder to review incremental commits.
- Links (in e.g. e-mails and notifications) go stale and you're confronted with:
this code isn't here anymore, when clicking on them.
- CircleCI doesn't play well with it: it might try to fetch a commit which
doesn't exist anymore.
- Your PR will be squashed anyway.
## Requirements
You need [lein](https://leiningen.org/) for running JVM tests and/or producing uberjars. For building binaries you need GraalVM. Currently we use Oracle GraalVM 24.
## Clone repository
To work on Babashka itself make sure Git submodules are checked out.
``` shellsession
$ git clone https://github.com/babashka/babashka --recursive
```
To update later on:
``` shellsession
$ git submodule update --recursive
```
## REPL
`lein repl` will get you a standard REPL/nREPL connection. To work on tests use `lein with-profiles +test repl`.
## Adding classes
Add necessary classes to `babashka/impl/classes.clj`. For every addition, write
a unit test, so it's clear why it is added and removing it will break the
tests. Try to reduce the size of the binary by only adding the necessary parts
of a class in `:instance-check`, `:constructors`, `:methods`, `:fields` or
`:custom`.
The `reflection.json` file that is needed for GraalVM compilation is generated
as part of `script/uberjar`.
## Test
Test on the JVM (for development):
script/test
Test the native version:
BABASHKA_TEST_ENV=native script/test
## Tests for Libraries
Babashka runs tests of libraries that are compatible with it through
`script/run_lib_tests`.
You can check out [this
commit](https://github.com/babashka/babashka/commit/8d9ac4c4d18a5588a4a258a61a9db3835b4f4e5c)
for how to add tests for a library that needs no changes to its tests.
The library is cloned as a git dependency, which also includes the tests, that are then added to the test's classpath and ran.
If a library's tests needs changes, we copy the tests using the `add-libtest.clj` script. Examples:
```sh
# To add tests for a new library on clojars
script/add-libtest.clj com.exoscale/lingo -t
# To add tests for a new library that is git based only
script/add-libtest.clj '{borkdude/carve {:git/url "https://github.com/borkdude/carve" :sha "df552797a198b6701fb2d92390fce7c59205ea77"}}' -t
# There are a number of options for specifying how to copy tests
script/add-libtest.clj -h
```
If the library you want to add doesn't work automatically, you can manually do the following:
* Add an entry for the library in `deps.edn` under the `:lib-tests` alias.
* Create a directory for the library in `test-resources/lib_tests/` and copy its tests to there.
* Add a manual lib entry using `add-libtest.clj` e.g. `script/add-libtest.clj http-kit/http-kit -m '{:test-namespaces [httpkit.client-test]}'`.
* Run the tests `script/lib_tests/run_all_libtests NS1 NS2`
Note: If you have to modify any test file or configuration to have it work with
bb, add an inline comment with prefix `BB-TEST-PATCH:` explaining what you did.
## Windows
We have corresponding `.bat` scripts for Windows, examples from a CMD Shell:
```shell
script\test.bat
script\run_lib_tests.bat
set BABASHKA_TEST_ENV=native
script\run_lib_tests.bat
```
### Enable Windows Symbolic Links
You'll need to **enable symbolic links**.
You must do this before you git clone babashka otherwise some tests will fail.
There seems to be many ways to achieve this; I found the following worked from PowerShell:
```shell
Install-Module -Name Carbon -Force
Import-Module Carbon
Grant-CPrivilege -Identity lee -Privilege SeCreateSymbolicLinkPrivilege
```
You'll need to reboot:
```shell
shutdown /r /t 0
```
After reboot, verify the new privilege via:
```shell
whoami /priv
```
Test if you can create a symbolic link via:
```
mklink foofoo barbar
```
> **TIP**: Symbolic links are not supported in some folder-sharing technologies.
For example, if you are running Windows as a VirtualBox guest, sharing babashka
source folders from your host OS will not share the symbolic links as symbolic links.
One solution is to re-clone babashka to a non-shared folder on Windows.
### Git for Windows
Install [Git for Windows](https://gitforwindows.org/).
It includes a version of `cat` that babashka tests currently rely on.
## Build
See [build.md](build.md).
## JDBC
Findings from various experiments with JDBC drivers in babashka:
- Postgres: adds 3MB to the binary. It seems the maintainers have put in effort
to make the driver compatible with Graal. The driver is part of `bb` since
`v0.0.89`.
- Sqlite: I feel like I'm close to a working solution, but it hangs. It adds
20MB to the binary. Since sqlite has a nice CLI we could also just shell out
to it (there's an example in the examples dir). We could also build a
`babashka.sqlite` namespace around the CLI maybe similar to
`babashka.curl`. See [#385](https://github.com/babashka/babashka/issues/385)
for details.
- HSQLDB: easy to get going with Graalvm. Adds 10 MB to the binary. It's under a
feature flag right now on master. See [build.md](build.md) for details. Derby
and H2 are known to not work with GraalVM, so far this is the "best" embedded
option from a Graal perspective. Setting the -Xmx value for Docker to 4500m
got it to crash. 4800m did work, but it took 17 minutes (compared to 10
minutes without this feature).
- MySQL / MariaDB: can't get those to work yet. Work in progress in issue
[#387](https://github.com/babashka/babashka/issues/387).
To progress work on sqlite and mySQL, I need a working Clojure example. If you
want to contribute, consider making a an example Clojure GraalVM CLI that puts
something in a sqlite / mysql DB and reads something from it.
## Design decisions
Some design decisions:
### bb.edn
- We chose the name `bb.edn` (rather than `babashka.edn`) for the configuration
file based on this
[poll](https://twitter.com/borkdude/status/1374720217608302595). The name `bb`
combined with `.edn` is not likely to cause conflicts with other tools.
- We did not choose to put the babashka configuration in `deps.edn` to keep bb config isolated (and more flexible) and also support it in projects that do not use `deps.edn`
### .babashka
- Rather than naming the home config dir `~/.bb` we chose `~/.babashka` to
prevent conflicts with other global tools. We might introduce a project local
`~/.babashka` directory for storing caches or whatnot too.
### Tasks
Some of these design decisions were formed in [these discussions](https://github.com/babashka/babashka/discussions/779).
- Tasks do not allow passing arguments to dependent tasks, other than by rebinding `*command-line-args*` (see discussion).
- Does the list of dependencies need to be dynamic? No, see discussion (same reason as args)
- bb &lt;foo&gt; is resolved as file > task > bb subcommand. Shadowing future subcommand is a problem that a user can solve by renaming a task or file. (same as lein aliases). Also see Conflicts.
- It is a feature that tasks are defined as top-level vars (instead of local let-bound symbols). This plays well with the Gilardi scenario, e.g. here: https://github.com/babashka/babashka.github.io/blob/ad276625f6c41f269d19450f236cb54cab2591e1/bb.edn#L7.
- The parallel option trickles down into run calls. People who use parallel will be confused if its dropped magically, people who dont use parallel wont notice anything either way so it doesnt matter
## Binary size
Keep notes here about how adding libraries and classes to Babashka affects the binary size.
We're registering the size of the macOS binary (as built on CircleCI).
2021/06/13 Upgrading from GraalvM 21.0 to 21.1 added roughly 3mb. Issue [here](https://github.com/oracle/graal/issues/3280#issuecomment-846402115).
2020/10/30 Without httpkit client+server: 68113436. With: 69503316 = 1390kb added.
2020/05/01 Removed `next.jdbc` and postgres JDBC driver: 48304980
2020/04/23 Added `next.jdbc` and postgres JDBC driver:
(- 51019836 48099780) = 2920kb added
2020/04/23 Added BigDecimal
(- 48103868 47857732) = 246kb added
2020/04/18 Added clojure.data.xml
47808572 - 45923028 = 1886kb added.
2020/03/29 Added clj-yaml for parsing and generating yaml.
45196996 - 42626884 = 2570kb added.
2020/03/28 Added java.nio.file.FileSystem(s) to support extracting zip files
42562284 - 42021244 = 541kb added.
2020/03/22 Added java.io.FileReader
42025276 - 42008876 = 16kb added.
2020/03/20 Added transit write, writer, read, reader
42004796 - 41025212 = 980kb added (305kb zipped).
2020/03/19 Added java.lang.NumberFormatException, java.lang.RuntimeException,
java.util.MissingResourceException and java.util.Properties to support
[cprop](https://github.com/tolitius/cprop/).
41025180 - 40729908 = 295kb added.
2020/02/21
Added java.time.temporal.ChronoUnit
40651596 - 40598260 = 53kb added.
2020/02/19, e43727955a2cdabd2bb0189c20dd7f9a18156fc9
Added fipp.edn/pprint
40598268 - 39744804 = 853kb added.
2020/02/09, c8fd1c7931d7842ebaec1fa8faf06d4ab58573bd
Added java.lang.BigInteger and java.security.MessageDigest.
39281972 - 39072764 = 209kb added.
2020/04/02 v0.0.69 38883676
2020/01/24, 43eef7075f9dac038d8d28a5ee4e49b6affd9864: 38.3mb, 11.1mb zipped
Added hierarchies (derive, isa?, etc).
2020/01/23, 485fef7df54d6701936704573468a1ec4c66d221: 37.4mb / 10.9mb zipped
Added: StringBuilder, java.io.{Reader,Writer,PrinterWriter,PushbackReader}
2020/01/08, 303ca9e825d76a4a45bc4240a59139d342c13964: 36.9mb / 10.8mb zipped
Removing cheshire from bb: 36.2mb / 10.5mb zipped.

View file

@ -1,3 +0,0 @@
# Examples
This pages was moved [here](../examples/README.md).

View file

@ -1,5 +0,0 @@
FROM babashka/babashka:0.8.2
COPY example.clj /
ENTRYPOINT bb /example.clj

View file

@ -1,19 +0,0 @@
# Deploying a babashka app to fly.io
[Fly.io](https://fly.io/) is a service that can run full stack apps with minimal
configuration. If you like the ease of Heroku, you might like fly.io and perhaps
even better! This document shows how to get a minimal babashka application up
and running on `fly.io`.
In `example.clj` we start an http-kit web server which spits out some HTML. You
can run this locally by invoking `bb example.clj` from the command line.
To get this site running on `fly.io`, you need to
[install](https://fly.io/docs/getting-started/installing-flyctl/) and [log
in](https://fly.io/docs/getting-started/log-in-to-fly/).
Then run `flyctl launch` to create a new application. After making changes, you
can re-deploy the site with `flyctl deploy`.
That's it! See this
[tweet](https://twitter.com/borkdude/status/1526175120825401344) for a demo.

View file

@ -1,21 +0,0 @@
(ns example
(:require [hiccup2.core :refer [html]]
[org.httpkit.server :refer [run-server]]))
(def port (or (some-> (System/getenv "PORT")
parse-long)
8092))
(run-server
(fn [_]
{:body
(str (html
[:html
[:body
[:h1 "Hello world!"]
[:p (str "This site is running with babashka v"
(System/getProperty "babashka.version"))]]]))})
{:port port})
(println "Site running on port" port)
@(promise)

View file

@ -1,41 +0,0 @@
# fly.toml file generated for shy-sound-2847 on 2022-05-16T14:12:38+02:00
app = "shy-sound-2847"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
PORT = "8092"
[experimental]
allowed_public_ports = []
auto_rollback = true
[[services]]
http_checks = []
internal_port = 8092
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
force_https = true
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"

View file

@ -1,99 +0,0 @@
maven-name,git-url
aero/aero,http://github.com/juxt/aero
amperity/vault-clj,https://github.com/amperity/vault-clj
aysylu/loom,https://github.com/aysylu/loom
babashka/babashka.curl,https://github.com/babashka/babashka.curl
better-cond/better-cond,https://github.com/Engelberg/better-cond
borkdude/deps,https://github.com/borkdude/deps.clj
borkdude/missing.test.assertions,https://github.com/borkdude/missing.test.assertions
borkdude/rewrite-edn,https://github.com/borkdude/rewrite-edn
camel-snake-kebab/camel-snake-kebab,https://github.com/clj-commons/camel-snake-kebab
cc.qbits/auspex,https://github.com/mpenet/auspex
cheshire/cheshire,https://github.com/dakrone/cheshire
circleci/bond,https://github.com/circleci/bond
cli-matic/cli-matic,https://github.com/l3nz/cli-matic.git
clj-commons/clj-yaml,https://github.com/clj-commons/clj-yaml
clj-commons/fs,https://github.com/clj-commons/fs
clj-commons/multigrep,https://github.com/clj-commons/multigrep
clj-stacktrace/clj-stacktrace,https://github.com/mmcgrana/clj-stacktrace
clojure-csv/clojure-csv,https://github.com/davidsantiago/clojure-csv
clojure-msgpack/clojure-msgpack,https://github.com/edma2/clojure-msgpack
clojure-term-colors/clojure-term-colors,https://github.com/trhura/clojure-term-colors
com.exoscale/lingo,https://github.com/exoscale/lingo
com.github.askonomm/clarktown,https://github.com/askonomm/clarktown
com.github.rawleyfowler/sluj,https://github.com/rawleyfowler/sluj
com.github.seancorfield/expectations,https://github.com/clojure-expectations/clojure-test
com.github.seancorfield/honeysql,https://github.com/seancorfield/honeysql
com.grammarly/omniconf,https://github.com/grammarly/omniconf
com.layerware/hugsql-core,
com.rpl/specter,https://github.com/redplanetlabs/specter
com.stuartsierra/component,https://github.com/stuartsierra/component
com.stuartsierra/dependency,https://github.com/stuartsierra/dependency
com.wsscode/cljc-misc,https://github.com/wilkerlucio/cljc-misc
comb/comb,https://github.com/weavejester/comb
cprop/cprop,https://github.com/tolitius/cprop
crispin/crispin,https://github.com/dunaj-project/crispin
dev.nubank/docopt,https://github.com/nubank/docopt.clj
djblue/portal,https://github.com/djblue/portal
doric/doric,https://github.com/joegallo/doric
douglass/clj-psql,https://github.com/DarinDouglass/clj-psql
edn-query-language/eql,https://github.com/edn-query-language/eql
environ/environ,https://github.com/weavejester/environ
exoscale/coax,https://github.com/exoscale/coax
exoscale/interceptor,https://github.com/exoscale/interceptor
expound/expound,https://github.com/bhb/expound
failjure/failjure,https://github.com/adambard/failjure
ffclj/ffclj,https://github.com/luissantos/ffclj
gaka/gaka,https://github.com/cdaddr/gaka
hato/hato,https://github.com/gnarroway/hato
henryw374/cljc.java-time,https://github.com/henryw374/cljc.java-time
hiccup/hiccup,http://github.com/weavejester/hiccup
honeysql/honeysql,https://github.com/seancorfield/honeysql
http-kit/http-kit,https://github.com/http-kit/http-kit
integrant/integrant,https://github.com/weavejester/integrant
io.aviso/pretty,https://github.com/AvisoNovate/pretty
io.github.cognitect-labs/test-runner,https://github.com/cognitect-labs/test-runner
io.github.swirrl/dogstatsd,https://github.com/swirrl/dogstatsd
io.github.technomancy/limit-break,https://github.com/technomancy/limit-break
io.helins/binf,https://github.com/helins/binf.cljc
io.lambdaforge/datalog-parser,https://github.com/lambdaforge/datalog-parser
io.replikativ/hasch,https://github.com/replikativ/hasch
java-http-clj/java-http-clj,http://www.github.com/schmee/java-http-clj
lambdaisland/regal,https://github.com/lambdaisland/regal
listora/again,https://github.com/liwp/again
markdown-clj/markdown-clj,https://github.com/yogthos/markdown-clj
meander/epsilon,https://github.com/noprompt/meander
medley/medley,https://github.com/weavejester/medley
meta-merge/meta-merge,https://github.com/weavejester/meta-merge
metosin/malli,https://github.com/metosin/malli
minimallist/minimallist,https://github.com/green-coder/minimallist
mvxcvi/arrangement,https://github.com/greglook/clj-arrangement
net.cgrand/xforms,https://github.com/cgrand/xforms
orchestra/orchestra,https://github.com/jeaye/orchestra
org.babashka/spec.alpha,https://github.com/babashka/spec.alpha
org.clj-commons/clj-http-lite,https://github.com/clj-commons/clj-http-lite
org.clj-commons/digest,https://github.com/clj-commons/clj-digest
org.clojars.askonomm/ruuter,https://github.com/askonomm/ruuter
org.clojars.lispyclouds/contajners,https://github.com/lispyclouds/contajners
org.clojure/algo.monads,https://github.com/clojure/algo.monads
org.clojure/core.match,https://github.com/clojure/core.match
org.clojure/data.csv,https://github.com/clojure/data.csv
org.clojure/data.generators,https://github.com/clojure/data.generators
org.clojure/data.json,https://github.com/clojure/data.json
org.clojure/data.zip,https://github.com/clojure/data.zip
org.clojure/math.combinatorics,https://github.com/clojure/math.combinatorics
org.clojure/math.numeric-tower,https://github.com/clojure/math.numeric-tower
org.clojure/test.check,https://github.com/clojure/test.check
org.clojure/tools.gitlibs,https://github.com/clojure/tools.gitlibs
org.clojure/tools.namespace,https://github.com/clojure/tools.namespace
postmortem/postmortem,https://github.com/athos/Postmortem
prismatic/schema,https://github.com/plumatic/schema
progrock/progrock,https://github.com/weavejester/progrock
reifyhealth/specmonstah,https://github.com/reifyhealth/specmonstah
rewrite-clj/rewrite-clj,https://github.com/clj-commons/rewrite-clj
rm-hull/jasentaa,https://github.com/rm-hull/jasentaa
selmer/selmer,https://github.com/yogthos/Selmer
slingshot/slingshot,https://github.com/scgilardi/slingshot
table/table,https://github.com/cldwalker/table
testdoc/testdoc,https://github.com/liquidz/testdoc
version-clj/version-clj,https://github.com/xsc/version-clj
1 maven-name git-url
2 aero/aero http://github.com/juxt/aero
3 amperity/vault-clj https://github.com/amperity/vault-clj
4 aysylu/loom https://github.com/aysylu/loom
5 babashka/babashka.curl https://github.com/babashka/babashka.curl
6 better-cond/better-cond https://github.com/Engelberg/better-cond
7 borkdude/deps https://github.com/borkdude/deps.clj
8 borkdude/missing.test.assertions https://github.com/borkdude/missing.test.assertions
9 borkdude/rewrite-edn https://github.com/borkdude/rewrite-edn
10 camel-snake-kebab/camel-snake-kebab https://github.com/clj-commons/camel-snake-kebab
11 cc.qbits/auspex https://github.com/mpenet/auspex
12 cheshire/cheshire https://github.com/dakrone/cheshire
13 circleci/bond https://github.com/circleci/bond
14 cli-matic/cli-matic https://github.com/l3nz/cli-matic.git
15 clj-commons/clj-yaml https://github.com/clj-commons/clj-yaml
16 clj-commons/fs https://github.com/clj-commons/fs
17 clj-commons/multigrep https://github.com/clj-commons/multigrep
18 clj-stacktrace/clj-stacktrace https://github.com/mmcgrana/clj-stacktrace
19 clojure-csv/clojure-csv https://github.com/davidsantiago/clojure-csv
20 clojure-msgpack/clojure-msgpack https://github.com/edma2/clojure-msgpack
21 clojure-term-colors/clojure-term-colors https://github.com/trhura/clojure-term-colors
22 com.exoscale/lingo https://github.com/exoscale/lingo
23 com.github.askonomm/clarktown https://github.com/askonomm/clarktown
24 com.github.rawleyfowler/sluj https://github.com/rawleyfowler/sluj
25 com.github.seancorfield/expectations https://github.com/clojure-expectations/clojure-test
26 com.github.seancorfield/honeysql https://github.com/seancorfield/honeysql
27 com.grammarly/omniconf https://github.com/grammarly/omniconf
28 com.layerware/hugsql-core
29 com.rpl/specter https://github.com/redplanetlabs/specter
30 com.stuartsierra/component https://github.com/stuartsierra/component
31 com.stuartsierra/dependency https://github.com/stuartsierra/dependency
32 com.wsscode/cljc-misc https://github.com/wilkerlucio/cljc-misc
33 comb/comb https://github.com/weavejester/comb
34 cprop/cprop https://github.com/tolitius/cprop
35 crispin/crispin https://github.com/dunaj-project/crispin
36 dev.nubank/docopt https://github.com/nubank/docopt.clj
37 djblue/portal https://github.com/djblue/portal
38 doric/doric https://github.com/joegallo/doric
39 douglass/clj-psql https://github.com/DarinDouglass/clj-psql
40 edn-query-language/eql https://github.com/edn-query-language/eql
41 environ/environ https://github.com/weavejester/environ
42 exoscale/coax https://github.com/exoscale/coax
43 exoscale/interceptor https://github.com/exoscale/interceptor
44 expound/expound https://github.com/bhb/expound
45 failjure/failjure https://github.com/adambard/failjure
46 ffclj/ffclj https://github.com/luissantos/ffclj
47 gaka/gaka https://github.com/cdaddr/gaka
48 hato/hato https://github.com/gnarroway/hato
49 henryw374/cljc.java-time https://github.com/henryw374/cljc.java-time
50 hiccup/hiccup http://github.com/weavejester/hiccup
51 honeysql/honeysql https://github.com/seancorfield/honeysql
52 http-kit/http-kit https://github.com/http-kit/http-kit
53 integrant/integrant https://github.com/weavejester/integrant
54 io.aviso/pretty https://github.com/AvisoNovate/pretty
55 io.github.cognitect-labs/test-runner https://github.com/cognitect-labs/test-runner
56 io.github.swirrl/dogstatsd https://github.com/swirrl/dogstatsd
57 io.github.technomancy/limit-break https://github.com/technomancy/limit-break
58 io.helins/binf https://github.com/helins/binf.cljc
59 io.lambdaforge/datalog-parser https://github.com/lambdaforge/datalog-parser
60 io.replikativ/hasch https://github.com/replikativ/hasch
61 java-http-clj/java-http-clj http://www.github.com/schmee/java-http-clj
62 lambdaisland/regal https://github.com/lambdaisland/regal
63 listora/again https://github.com/liwp/again
64 markdown-clj/markdown-clj https://github.com/yogthos/markdown-clj
65 meander/epsilon https://github.com/noprompt/meander
66 medley/medley https://github.com/weavejester/medley
67 meta-merge/meta-merge https://github.com/weavejester/meta-merge
68 metosin/malli https://github.com/metosin/malli
69 minimallist/minimallist https://github.com/green-coder/minimallist
70 mvxcvi/arrangement https://github.com/greglook/clj-arrangement
71 net.cgrand/xforms https://github.com/cgrand/xforms
72 orchestra/orchestra https://github.com/jeaye/orchestra
73 org.babashka/spec.alpha https://github.com/babashka/spec.alpha
74 org.clj-commons/clj-http-lite https://github.com/clj-commons/clj-http-lite
75 org.clj-commons/digest https://github.com/clj-commons/clj-digest
76 org.clojars.askonomm/ruuter https://github.com/askonomm/ruuter
77 org.clojars.lispyclouds/contajners https://github.com/lispyclouds/contajners
78 org.clojure/algo.monads https://github.com/clojure/algo.monads
79 org.clojure/core.match https://github.com/clojure/core.match
80 org.clojure/data.csv https://github.com/clojure/data.csv
81 org.clojure/data.generators https://github.com/clojure/data.generators
82 org.clojure/data.json https://github.com/clojure/data.json
83 org.clojure/data.zip https://github.com/clojure/data.zip
84 org.clojure/math.combinatorics https://github.com/clojure/math.combinatorics
85 org.clojure/math.numeric-tower https://github.com/clojure/math.numeric-tower
86 org.clojure/test.check https://github.com/clojure/test.check
87 org.clojure/tools.gitlibs https://github.com/clojure/tools.gitlibs
88 org.clojure/tools.namespace https://github.com/clojure/tools.namespace
89 postmortem/postmortem https://github.com/athos/Postmortem
90 prismatic/schema https://github.com/plumatic/schema
91 progrock/progrock https://github.com/weavejester/progrock
92 reifyhealth/specmonstah https://github.com/reifyhealth/specmonstah
93 rewrite-clj/rewrite-clj https://github.com/clj-commons/rewrite-clj
94 rm-hull/jasentaa https://github.com/rm-hull/jasentaa
95 selmer/selmer https://github.com/yogthos/Selmer
96 slingshot/slingshot https://github.com/scgilardi/slingshot
97 table/table https://github.com/cldwalker/table
98 testdoc/testdoc https://github.com/liquidz/testdoc
99 version-clj/version-clj https://github.com/xsc/version-clj

View file

@ -1 +0,0 @@
Moved to [projects.md](projects.md).

View file

@ -1,591 +0,0 @@
# News
This page keeps track of babashka-related new items. Feel free to make a PR if
you have anything to add. Also see
[#babashka](https://twitter.com/hashtag/babashka?src=hashtag_click&f=live) on
Twitter.
## 2023-05 ([Twitter](https://twitter.com/search?q=(%23babashka%20OR%20babashka)%20since%3A2023-05-01%20until%3A2023-06-01&src=typed_query&f=live), [Mastodon](https://mastodon.social/tags/babashka))
### Releases
1.3.178
Mostly a boring maintenance release with lib upgrades!
### Events
- [Babashka-conf](https://babashka.org/conf/) is happening June 10th in
Berlin. Only a few tickets left! See the [schedule](https://babashka.org/conf/schedule.html). Also you can buy a [conf t-shirt](https://www.etsy.com/listing/1475981599/babashka-conf-berlin-2023-t-shirt) now! See Nikita wearing it [here](https://twitter.com/nikitonsky/status/1658066530800742400)!
Thanks to conference sponsors:
<img src="https://pbs.twimg.com/media/Fw5h-0_XwA4DTIj?format=jpg&name=medium" width="200px">
- Babashka is going to the [Strange Loop](https://www.thestrangeloop.com/) conference!
### Projects
- [beep-boop](https://github.com/pesterhazy/beep-boop): Audible and visual feedback for test runs
- [panas.example](https://github.com/keychera/panas.example): All htmx examples ported to babashka!
- [utility-scripts](https://github.com/somecho/utility-scripts): A collection of helper scripts for Clojure, Java, Ledger and Taskwarrior. Written in Clojure
- [bb-scripts](https://github.com/techconative/bb-scripts): Babashka scripts for common utilities
- [Launching bb tasks from emacs](https://mastodon.social/@mykhaylo@fosstodon.org/110456087708592838)
### Articles
- [Clojure in security: Docker](https://www.juxt.pro/blog/clojure-in-docker/): mentions babashka and clj-kondo
- [Changing my mind: Converting a script from bash to Babashka](https://blog.agical.se/en/posts/changing-my-mind--converting-a-script-from-bash-to-babashka/)
- [How to create a really simple ClojureCLR dependency tool](https://blog.agical.se/en/posts/how-to-create-a-really-simple-clojureclr-dependency-tool/) with babashka
- [Making a resume with Node.js babashka (nbb)](https://yogthos.net/posts/2023-05-12-nbb-resume.html)
## 2023-04 ([Twitter](https://twitter.com/search?q=(%23babashka%20OR%20babashka)%20since%3A2023-04-01%20until%3A2023-05-01&src=typed_query&f=live), [Mastodon](https://mastodon.social/tags/babashka))
[Babashka-conf](https://babashka.org/conf/) is happening June 10th in
Berlin. Save the date and/or submit your babashka/clojure-related talk or workshop
in the CfP!
### Releases
1.3.177
Biggest highlight: `bb.edn` is now respected relative of a script, no matter the directory you invoke it from! See [docs](https://book.babashka.org/#_script_adjacent_bb_edn).
### Projects
- [babashka-dl](https://github.com/mjhika/babashka-dl): simple install script for babashka on windows
- [instaparse-bb](https://github.com/babashka/instaparse-bb): Use instaparse from babashka, a new release
### Videos
- [Learning clojure w/ @lispyclouds](https://youtu.be/uBTRLBU-83A): a stream with teej_dv, a neovim core dev
## 2023-03 ([Twitter](https://twitter.com/search?q=(%23babashka%20OR%20babashka)%20since%3A2023-03-01%20until%3A2023-04-01&src=typed_query&f=top), [Mastodon](https://mastodon.social/tags/babashka))
### Releases
1.3.176, 1.3.175, 1.2.174:
Biggest highlight: Switch to GraalVM 19 and enable virtual threads!
### Videos
- [Blambda! The sound of babashka and AWS colliding](https://pitch.com/public/03fa9c7e-2b0e-45fb-8a22-d4a4d4d79d24), by Josh Glover from Pitch!
### Projects
- [babashka.json](https://github.com/babashka/json): JSON abstraction library
- [martian](https://github.com/oliyh/martian) is now babashka compatible!
- [panas.reload](https://github.com/keychera/panas.reload): a hot reload for babashka serving html+css (or htmx)
- [cljs-exif-reader](https://git.sr.ht/~rwv/cljs-exif-reader): Extract information from TIFF and JPEG images (works in babashka, despite the name)
### Jobs
- Write babashka at [Cognician](https://twitter.com/RobStuttaford/status/1641694501793038336)!
## 2023-02 ([Twitter](https://twitter.com/search?q=(%23babashka%20OR%20babashka)%20since%3A2023-02-01%20until%3A2023-03-01&src=typed_query&f=live), [Mastodon](https://mastodon.social/tags/babashka))
## Releases
1.1.173: mostly bugfixes
### Articles
- [A technique for live coding simple web pages](https://github.com/whacked/cow/blob/main/a%20technique%20for%20live%20coding%20simple%20web%20pages.md) with babashka
### Videos
- [Stockholm Clojure Meetup Feb 23: Blambda! The sound of Babashka and Lambda colliding](https://www.youtube.com/watch?v=NfgYon96dsE)
### Projects
- [debux](https://github.com/philoskim/debux) is now babaskha-compatible
- [lines-of-code-bb](https://github.com/matthewdowney/linesofcode-bb): Babashka script to count lines of Clojure code, docs, comments, and more
- [deps-try](https://github.com/eval/deps-try): a babashka-script to try out Clojure libraries in rebel-readline
- [bb-dialog](https://github.com/pixelated-noise/bb-dialog) adds support for `--treeview`
- [A duckduck go CLI with babashka and (bbl)gum](https://mastodon.me.uk/@choffee/109845697304457129)
- [babashka http-client](https://github.com/babashka/http-client) now supports multipart uploads
- [sublime-pretty-edn](https://github.com/oakmac/sublime-pretty-edn): Format, Validate, Minify EDN files in Sublime Text
- [Play console tetris in babashka!](https://twitter.com/borkdude/status/1628473136969576449)
- [kaocha test runner](https://github.com/lambdaisland/kaocha) became babashka compatible!
## 2023-01 ([Twitter](https://twitter.com/search?q=%28%23babashka%20OR%20babashka%29%20until%3A2023-02-01%20since%3A2023-01-01&src=typed_query&f=live), [Mastodon](https://mastodon.social/tags/babashka))
### Releases
New releases in the past month: 1.0.170 - 1.1.173
Release highlights:
- Support for `data_readers.clj(c)`
- Include [http-client](https://github.com/babashka/http-client) as built-in library
- Compatibility with [clojure.tools.namespace.repl/refresh](https://github.com/clojure/tools.namespace)
- Compatibility with [clojure.java.classpath](https://github.com/clojure/java.classpath) (and other libraries which rely on `java.class.path` and `RT/baseLoader`)
- Compatibility with [eftest](https://github.com/weavejester/eftest) test runner (see demo)
- Compatibility with [cljfmt](https://github.com/weavejester/cljfmt)
- Support for `*loaded-libs*` and `(loaded-libs)`
- Support `add-watch` on vars (which adds compatibility with `potemkin.namespaces`)
- BREAKING: make printing of script results explicit with `--prn`
### Events
- [Babashka Workshop](https://clojure.stream/workshops/babashka) at ClojureStream with Rahul De
- [Blambda! The sound of Babashka and Lambda colliding](https://www.meetup.com/sthlm-clj/events/291204199/?utm_medium=referral&utm_campaign=share-btn_savedevents_share_modal&utm_source=twitter): sthlm.clj (Stockholm, Sweden)
### Articles
- [Babooka: write command line Clojure](https://www.braveclojure.com/quests/babooka/) by Daniel Higginbotham
- [Blambda analyses sites](https://jmglov.net/blog/2023-01-04-blambda-analyses-sites.html) by Josh Glover
- [Babashka: How GraalVM Helped Create a Fast-Starting Scripting Environment for Clojure](https://logico-jp.io/2023/01/07/babashka-how-graalvm-helped-create-a-fast-starting-scripting-environment-for-clojure/) in Japanese
- [The wizard of HOP - How we built the web based HOP CLI Settings Editor using Babashka and Scittle](https://www.gethop.dev/post/the-wizard-of-hop-how-we-built-the-web-based-hop-cli-settings-editor-using-babashka-and-scittle) by Bingen Galartza
- [Simple TUIs with Babashka and Gum](https://rattlin.blog/bbgum.html) by Rattlin.blog
- [Babashka And Dialog Part Ii: Announcing The Bb-Dialog Library](https://www.pixelated-noise.com/blog/2023/01/20/bb-dialog-announcement/index.html) by A.C. Danvers
- [Re-Writing a GlobalProtect OpenConnect VPN Connect script in Babashka](https://tech.toryanderson.com/2023/01/14/re-writing-a-globalprotect-openconnect-vpn-connect-script-in-babashka/) by Tory Anderson
### Projects
Projects that were new, had updates or were made compatible with babashka:
- [asdf-babashka](https://github.com/pitch-io/asdf-babashka): babashka plugin for the asdf version manager
- [babashka-htmx-todoapp](https://github.com/prestancedesign/babashka-htmx-todoapp): Quick example of a todo list SPA using Babashka and HTMX
- [bblgum](https://github.com/lispyclouds/bblgum): An extremely tiny and simple wrapper around charmbracelet/gum
- [bb-dialog](https://github.com/pixelated-noise/bb-dialog): A simple wrapper library for working with dialog from Babashka
- [carve](https://github.com/borkdude/carve): Remove unused Clojure vars
- [chr](https://github.com/ThaddeusJiang/chr): native commands history report for the default terminal users
- [clj-kondo-bb](https://github.com/clj-kondo/clj-kondo-bb): Invoke clj-kondo from babashka scripts!
- [cljfmt](https://github.com/weavejester/cljfmt): A tool for formatting Clojure code
- [drepl](https://github.com/claytn/drepl): Node JS dependency-repl. The node repl you already know with easy library installations
- [instaparse-bb](https://github.com/babashka/instaparse-bb): Wrapper library aroud pod-babashka-instaparse
- [lein2deps](https://github.com/borkdude/lein2deps): Lein project.clj to deps.edn converter
- [neil](https://github.com/babashka/neil): A CLI to add common aliases and features to deps.edn-based projects
- [obsidian-babashka](https://github.com/filipesilva/obsidian-babashka): Run Obsidian Clojure(Script) codeblocks in Babashka
- [pod-babashka-buddy](https://github.com/babashka/pod-babashka-buddy): A pod around buddy core (Cryptographic Api for Clojure)
- [quickblog](https://github.com/borkdude/quickblog): Light-weight static blog engine for Clojure and babashka
- [solenoid](https://github.com/adam-james-v/solenoid): A small clojure tool for making little control UIs while using the REPL!
- [tools.bbuild](https://github.com/babashka/tools.bbuild): babashka version of tools.build
- [weather](https://gist.github.com/yogthos/f86e63b856e1413180b2262024ece977): command line util for grabbing current weather for a city using OpenWeather API
## [2022-12](https://twitter.com/search?q=%28%23babashka%20OR%20babashka%29%20until%3A2023-01-01%20since%3A2022-12-01&src=typed_query&f=live)
- Releases: [1.0.168](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [How GraalVM Helped Create a Fast-Starting Scripting Environment for Clojure](https://medium.com/graalvm/babashka-how-graalvm-helped-create-a-fast-starting-scripting-environment-for-clojure-b0fcc38b0746)
- [http-client](https://github.com/babashka/http-client): a new HTTP client library for babashka
- [How to Do Things With Babashka](https://presumably.de/how-to-do-things-with-babashka.html) by Paulus Esterhazy (2022-12)
- [Using Babashka to Get Electricity Prices](https://www.karimarttila.fi/clojure/2022/12/04/using-babashka-to-get-electricity-prices) by Kari Marttila
- [Adding prompts to your babashka scripts with dialog](https://www.pixelated-noise.com/blog/2022/12/09/dialog-and-babashka/index.html) by A.C. Danvers
- [Scraping an HTML dictionary with Babashka and Bootleg](https://blog.exupero.org/scraping-an-html-dictionary-with-babashka-and-bootleg/) by exupero
- [quickblog](https://github.com/borkdude/quickblog) v0.1.0: Light-weight static blog engine for Clojure and babashka
- [bb-excel](https://github.com/kbosompem/bb-excel): Read Excel Files in babashka scripts
- [Get paginated list of issues from gitlab with clojure/babashka](https://gist.github.com/MrGung/29d0547fe45316c3438032fd164d42c6) by Steffen Glückselig
- Install development builds: `bash <(curl https://raw.githubusercontent.com/babashka/babashka/master/install) --dev-build --dir /tmp`
- [JVM interop improvements in bb](https://twitter.com/borkdude/status/1606280110692352001)
- [A little trick to have conditional code for babashka in a .clj file without resorting to .cljc reader conditionals](https://twitter.com/borkdude/status/1599067149187764224)
- [Get Advent of Code input in babashka](https://gist.github.com/jeeger/6e39fea94ce49e33d1fa43f40cc36630) by Jan Seeger
- [Grabbing current weather for a city using OpenWeather API](https://gist.github.com/yogthos/f86e63b856e1413180b2262024ece977) by Dmitri Sotnikov
## [2022-11](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-12-01%20since%3A2022-11-01&src=typed_query&f=live)
- Releases: [1.0.165 - 1.0.167](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- Registration for a [Babashka workshop](https://clojure.stream/workshops/babashka) with Rahul De at ClojureStream is now open!
- [Tutkain, a Sublime plugin for clojure based on socket REPL now with support for babashka](https://github.com/eerohele/Tutkain)
- [Manage git hooks in babashka](https://blaster.ai/blog/posts/manage-git-hooks-w-babashka.html) by Mykhaylo Bilyanskyy
- [Messing around with babashka](Messing around with Babashka) by Ian Muge
- [A babashka one liner to inspect data in portal](https://twitter.com/borkdude/status/1597505695800516609)
- [Using nREPL as a system interface](https://yogthos.net/posts/2022-11-26-nREPL-system-interaction.html) by Dmitri Sotnikov
- [deep-diff2](https://github.com/lambdaisland/deep-diff2) is now babashka-compatible!
- [A script to normalize auto-resolved keywords](https://github.com/babashka/babashka/blob/master/examples/normalize-keywords.clj)
- [Sum up page counts of books from Calibre library with babashka](https://gist.github.com/jeeger/d13159fefaee33c771be979639900ebc) by Jan Seeger
- [Tiny babashka script that returns a random clojure doc](https://gist.github.com/CarnunMP/c592cd3b6e711d56ddd4ca7832b9b251) by Carnun Marcus-Page
## [2022-10](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-11-01%20since%3A2022-10-01&src=typed_query&f=live)
- Releases: [1.0.164](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [bb-pod-racer](https://github.com/justone/bb-pod-racer): Speed up development of Babashka pods by Nate Jones
- [Babashka tasks VSCode plugin](https://marketplace.visualstudio.com/items?itemName=fbeyer.babashka-tasks) by Ferdinand Beyer
- A [PR](https://github.com/nextjournal/clerk/pull/232) to get Clerk working in babashka
- [lein2deps](https://github.com/borkdude/lein2deps): lein to deps.edn converter
- [awyeah-api](https://github.com/grzm/awyeah-api) by Michael Glaesemann v0.8.41 is now available! aws-api for Babashka. Aw yeah!
- [bbssh](https://github.com/epiccastle/bbssh/releases/tag/v0.2.0) by Crispin Wellington, v0.2.0 released
- [safely use rsync --archive --delete to backup a directory](https://gist.github.com/stelcodes/ddc8ff53de2192dca7d3fee1081ddb77) by Stel Abrego
## [2022-09](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-10-01%20since%3A2022-09-01&src=typed_query&f=live)
- Releases: [0.9.162 - 0.10.163](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- Introducing [bbin](https://radsmith.com/bbin): a tool to install babashka scripts on your system by Radford Smith
- [bbssh](https://github.com/epiccastle/bbssh): Babashka pod for SSH support by [Epic Castle](https://github.com/epiccastle)
- [Loom virtual threads are coming to babashka](https://twitter.com/borkdude/status/1572222344684531717)
- [Tiny script to cycle through pulseaudio outputs (aka sinks)](https://gist.github.com/stelcodes/7d9136a5839b645b6cd5bc829a9fe541) by Stel Abrego
- [Tetris in the console via pod-babashka-lantera](https://twitter.com/borkdude/status/1569351199404576770)
- [org-mode gets support for babashka](https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=764642f55b7a9821acbabcfa1e2d354afab99be7)
- [docs for combining babashka process with promesa](https://github.com/babashka/process#promesa)
[exoscale/interceptor](https://github.com/exoscale/interceptor) became babashka-compatible!
- [Tutkain, socket REPL Sublime plugin, gets better support for babashka](https://twitter.com/borkdude/status/1568315151404924933)
- [babashka tweepy](https://github.com/davclark/babashka-tweepy): kicking the tires on using the tweepy library from a babashka task by Dav Clark
- [aoc helper](https://github.com/jjcomer/aoc-helper) by Josh Comer
- [Dogfooding blambda part 5](https://jmglov.net/blog/2022-09-02-dogfooding-blambda-logs.html) by Josh Glover
## [2022-08](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-09-01%20since%3A2022-08-01&src=typed_query&f=live)
- It's babashka's third birthday on August 9th 2022!
- [etaoin](https://github.com/clj-commons/etaoin), Pure Clojure Webdriver protocol implementation, is now babashka-compatible!
- [xforms](https://github.com/cgrand/xforms) is now babashka-compatible!
- [squint](https://github.com/squint-cljs/squint) and [cherry](https://github.com/squint-cljs/cherry) are CLJS-compilers that work with babashka!
## [2022-07](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-08-01%20since%3A2022-07-01&src=typed_query&f=live)
- Releases: [0.8.157 - 0.9.161](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Recursive document transformations with Pandoc and Clojure](https://play.teod.eu/document-transform-pandoc-clojure/) by Teodor Heggelund
- [Babashka toolbox](https://babashka.org/toolbox/): A categorised directory of libraries and tools for Babashka
- [Quickblog](https://github.com/borkdude/quickblog): Light-weight static blog engine for Clojure and babashka
- Win a babashka t-shirt by participating in [this](https://twitter.com/borkdude/status/1547847843381030912) contest!
- [AWS Lambda, now with first class parentheses](https://www.juxt.pro/blog/nbb-lambda) by Ray McDermott (about nbb)
- [bb-github-app](https://github.com/brandonstubbs/bb-github-app): An example Babashka Script authenticating as a Github App and interacting with the Checks API
- [Ruuter](https://github.com/askonomm/ruuter#setting-up-with-babashka) is a routing library which works very well with bb
- [Blambda!](https://jmglov.net/blog/2022-07-03-blambda.html) by Josh Glover
- Files with the `.bb` extension are now correctly highlighted as Clojure code on Github! See [this](https://twitter.com/borkdude/status/1543937735429431298) tweet.
- Encode and decode files as kroki url diagrams, a [gist](https://gist.github.com/henryw374/070845dbd8cfb4672a3c0d06cf8b00e4) by Henry Widd
- Customized bb builds with clj-nix: [tweet](https://twitter.com/jlesquembre/status/1543686641461694470)
- Expose Clojure functions in the CLI with babashka and nix: [tweet](https://twitter.com/jlesquembre/status/1546777332471455745)
- [Meander](https://github.com/noprompt/meander) is now compatible with bb: [tweet](https://twitter.com/borkdude/status/1542881167338250242)
- [Deleting AWS Glacier vaults with babashka](https://javahippie.net/clojure/2022/07/23/deleting-aws-glacier-vaults-with-babashka.html) by Tim Zöller
## [2022-06](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-07-01%20since%3A2022-06-01&src=typed_query&f=live)
- Releases: [0.8.156](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [AWS wiki page](https://github.com/babashka/babashka/wiki/AWS)
- [blambda](https://github.com/jmglov/blambda): Blambda! is a custom runtime for AWS Lambda that lets you write functions using Babashka
- [Babashka CLI](https://blog.michielborkent.nl/babashka-cli.html): turn Clojure functions into CLIs!
- [Http-server](https://github.com/babashka/http-server#babashka): Serve static assets
- [Deps-bundler](https://github.com/MrGung/deps-bundler): Bundle dependencies on
a computer that has access to maven and clojars (PC-A) and bring these over to
a computer with limited access (PC-L).
- [Prismatic/schema](https://github.com/plumatic/schema/blob/master/CHANGELOG.md#130-2022-06-10) and babashka are now compatible
- [Logseq bb tasks](https://github.com/logseq/bb-tasks): Reusable babashka tasks used by logseq team
- [Breakneck Babashka on K8s](Breakneck Babashka on K8s) by Heow Goodman
## [2022-05](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-06-01%20since%3A2022-05-01&src=typed_query&f=live)
- Releases: [0.8.2](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Etaoin](https://github.com/clj-commons/etaoin) moved to clj-commons and now works with babashka as well.
- [Nix docs for babashka](https://github.com/babashka/babashka/blob/master/doc/nix.md)
- [Fly.io docs for babashka](https://github.com/babashka/babashka/tree/master/doc/fly_io)
- [Babashka survey results](https://blog.michielborkent.nl/babashka-survey-q1-2022.html)
- [Quickdoc](https://github.com/borkdude/quickdoc): (Quick and minimal API doc generation for Clojure
- [Awyeah-api](https://github.com/grzm/awyeah-api) - Cognitect's aws-api for babashka
## [2022-04](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-05-01%20since%3A2022-04-01&src=typed_query&f=live)
- Releases: [0.8.0 - 0.8.1](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Babashka and Clojure](https://youtu.be/ZvOs5Ele6VE) by Rahul Dé at North Virginia Linux Users Group
- [Setup-Clojure](https://github.com/DeLaGuardo/setup-clojure/releases/tag/5.0) Github action is now able to install babashka!
- Control Chrome via devtools using [clj-chrome-devtools](https://github.com/tatut/clj-chrome-devtools/blob/master/bb.clj) which runs with bb!
- Use pods directly in `bb.edn`: [tweet](https://twitter.com/borkdude/status/1510995356229767172)
## [2022-03](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-04-01%20since%3A2022-03-01&src=typed_query&f=live)
- Releases: [0.7.7 - 0.7.8](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Create a password manager with Clojure using Babashka, sqlite, honeysql and stash](https://youtu.be/jm0RXmyjRJ8) by Daniel Amber
- [Detecting inconsistent aliases in a clojure codebase](https://www.youtube.com/watch?v=bf8KLKkCH2g) by Oxalorg
- [Clj-konmari](https://github.com/oxalorg/clj-konmari/) by Oxalorg
- [Logseq-query](https://github.com/cldwalker/logseq-query) by Gabriel Horner [(announcement tweet with video)](https://twitter.com/cldwalker/status/1506991213030871041)
- The [loom](https://github.com/aysylu/loom) library is now compatible [(tweet)](https://twitter.com/borkdude/status/1502237220811550723)
- The [at-at](https://github.com/overtone/at-at) library is now compatible
## [2022-02](https://twitter.com/search?q=%28%23babashka%29%20until%3A2022-03-01%20since%3A2022-02-01&src=typed_query&f=live)
- Releases: [0.7.5 - 0.7.6](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Spire is available as a babashka pod](https://twitter.com/epic_castle/status/1496784352256008194)
- Babashka Clojure template on [Repl.it](https://replit.com/@eccentric-j/Babashka-Clojure-Template?v=1#replit.nix) by Eccentric J
- Create a self-contained executable with [caxa](https://github.com/babashka/babashka/wiki/Self-contained-executable)
- Cli-matic is now compatible due to this [PR](https://github.com/l3nz/cli-matic/pull/145)
- [I, too, Wrote Myself a Static Site Generator](https://dawranliou.com/blog/i-too-wrote-myself-a-static-site-generator/) by Daw-Ran Liou
- [Staplegun](https://github.com/escherize/staplegun): Single file clipboard-manager
- [Bbb](https://github.com/nikvdp/bbb): make executable CLI tools from bb scripts
- [Apptemplate](https://github.com/redstarssystems/apptemplate): Application project template for Clojure featuring bb tasks
## [2022-01](https://twitter.com/search?f=live&q=%28%23babashka%29%20until%3A2022-02-01%20since%3A2022-01-01&src=typed_query)
- Releases: [0.7.4](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Babashka dev builds](https://github.com/babashka/babashka-dev-builds)
- [Writing Clojure-living-cookbooks](https://www.loop-code-recur.io/live-clojure-cookbooks/) by Cyprien Pannier
- [HTMX Todo App](https://github.com/prestancedesign/babashka-htmx-todoapp)
- [Better linting for `bb.edn`](https://twitter.com/borkdude/status/1484100071134220291)
- [Unwordle](https://github.com/mknoszlig/unwordle): solver for wordle puzzles
- [Using babashka with PHP](https://blog.michielborkent.nl/using-babashka-with-php.html) by Michiel Borkent
## 2021-12
- Releases: [0.6.8 - 0.7.3](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Scripting with Babashka on Alfred](https://blog.wsscode.com/babashka-and-alfred/) by Wilker Lucio
- [babashka/spec.alpha](https://github.com/babashka/spec.alpha): a fork of spec.alpha that works with babashka.
- Several people are doing [Advent of Code puzzles with babashka](https://twitter.com/search?q=%23babashka%20%20%23AdventOfCode&src=typed_query&f=live)
- Compatibility with a [fork of tools.namespace](https://github.com/babashka/tools.namespace). This allows
running the Cognitect [test-runner](https://github.com/cognitect-labs/test-runner) (Cognitest) from source.
- [bb-components](https://github.com/vedang/bb-scripts#bb-components): A script to find all the components that you should deploy your code to.
- [Babashka workshop at JavaLand](https://github.com/ijug-ev/JavaLand/tree/main/Community-Aktivit%C3%A4ten#bash-war-gestern-shell-scripting-mit-babashka-clojure-ug-d%C3%BCsseldorf-christian-meter-rheinjug-jens-bendisposto)
- Install babashka [dev builds](https://twitter.com/borkdude/status/1475234968146227203)
- [Combine babashka and PHP](https://gist.github.com/borkdude/843548cba14ae9d283191e31bc483959)
- [System wide babashka tasks](https://twitter.com/borkdude/status/1476656022282551300)
- [Run an http file server as a babashka task](https://twitter.com/borkdude/status/1476870516233445377)
## 2021-11
- Releases: [0.6.5 - 0.6.7](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Contajners](https://github.com/lispyclouds/contajners): An idiomatic,
data-driven, REPL friendly clojure client for OCI container engines.
- [deps-modules](https://github.com/exoscale/deps-modules#babashka): a clojure "tool" that attempts to solve one of the "multi module" project problems with tools.deps in a minimalistic way.
- [Moldable Emacs: a Clojure Playground with Babashka](https://ag91.github.io/blog/2021/11/05/moldable-emacs-a-clojure-playground-with-babashka/)
- [aws pod 0.1.0](https://twitter.com/borkdude/status/1459117378441261056)
- [tools.bbuild](https://github.com/babashka/tools.bbuild): a fork of tools.build that runs with babashka and [tools-deps-native](https://github.com/babashka/tools-deps-native)
- [Making markdown-clj babashka compatible](https://blog.michielborkent.nl/markdown-clj-babashka-compatible.html) by Michiel Borkent
- [radiale](https://github.com/xlfe/radiale): radiale: home automation project written using #babashka and Python
- [Writing a Clojure shell script with Babashka](https://www.youtube.com/watch?v=D-_Mz7rz1po), a video by Max Weber
- [makejack](https://github.com/hugoduncan/makejack): A clojure CLI build tool, and build library which can run with babashka.
- [I wrote myself a static site generator](https://freeston.me/posts/2021-11-29-new-site-generator/) (in babashka) by Dominic Freeston.
- [bipe](https://gist.github.com/borkdude/82dcdd36a1e61ef36f19221876e7b1b6): vipe for babashka
## 2021-10
- Releases: [0.6.2-0.6.4](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- Babashka on the [Thoughtworks Technology Radar](https://www.thoughtworks.com/radar/platforms/babashka)
- [ruuter](https://github.com/askonomm/ruuter#setting-up-with-babashka) is a
routing library compatible with babashka.
- A list of [companies](https://github.com/babashka/babashka/blob/master/doc/companies.md) using babashka
- Ilshat Sultanov shares his [babashka tasks](https://twitter.com/just_sultanov/status/1446118161258987534)
- [Slack the music](https://github.com/javahippie/slack-the-music), a babashka script to update your slack status with your current Apple Music track by Tim Zöller.
- [Finding my inner Wes Anderson](https://javahippie.net/clojure/2021/10/18/finding-my-inner-wes-anderson.html) by Tim Zöller.
- [Run a local babashka script in a remote server](https://twitter.com/borkdude/status/1451110414062870528)
- [Replacing my Octopress blog with 200 lines of Babashka](https://blog.michielborkent.nl/migrating-octopress-to-babashka.html) by Michiel Borkent
- The babashka wiki now has a [GNU Emacs](https://github.com/babashka/babashka/wiki/GNU-Emacs) section
- Invoke babashka tasks in a [monorepo](https://github.com/babashka/babashka/discussions/1044#discussioncomment-1544956)
- [Speeding up builds with fs/modified-since](https://blog.michielborkent.nl/speeding-up-builds-fs-modified-since.html) by Michiel Borkent
## 2021-09
- New babashka 0.6.0 released. Highlight: support for `java.net.http` which
enables running [java-http-clj](https://github.com/schmee/java-http-clj) from
source. The raw interop is the first part of a multi-stage plan to move all
http related scripting towards `java.net.http` in favor of the other two
solutions currently available in `bb`: `babashka.curl` and
`org.httpkit.client`.
- [rss-saver](https://github.com/adam-james-v/rss-saver): Simple Clojure (Babashka) script that saves articles from world.hey.com RSS feeds.
- [babashka-docker-action-example](https://github.com/borkdude/babashka-docker-action-example)
- [script](https://gist.github.com/rutenkolk/dbd970d03a0d012b671db38434ccbfa7) to upgrade zig lang to the latest dev release
- [Cursive](https://twitter.com/CursiveIDE/status/1439022267187433472) adds support for babashka in 1.11.0
- How to filter tail output with babashka on [StackOverflow](https://stackoverflow.com/questions/69241046/how-to-filter-output-of-tail-with-babashka/69241911?stw=2#69241911)
- [Awesome Babashka: Parse & produce HTML and SQLite](https://blog.jakubholy.net/2021/awesome-babashka-dash/) by Jakub Holy
- [Neil](https://github.com/babashka/neil): an installable babashka script to add common aliases and features to deps.edn-based projects.
## 2021-08
- New babashka 0.5.1 released. Highlight: new `print-deps` command for printing
a `deps.edn` map and classpath which includes all built-in deps. This can be
used for editor tooling like Cursive and clojure-lsp, but also for migrating a
babashka project to a Graal native-image project.
- Babashka receives long term funding from [Clojurists Together](https://www.clojuriststogether.org/news/long-term-funding-selections/). Thanks!
- Babashka is 2 years old this month: the [first commit](https://github.com/babashka/babashka/commit/6dee50b0face0b890a7f628a63b21d5d706a48ee) was on 9 August 2019!
- [nbb](https://github.com/borkdude/nbb): babashka's Node.js cousin
- [Cursive](https://twitter.com/CursiveIDE/status/1422540023207915520) adds
support for babashka in the latest EAP
- [clojure-lsp](https://twitter.com/ericdallo/status/1422559744712138753) adds support for babashka scripts
- [bb guestbook](https://github.com/SVMBrown/bb-guestbook) by Scot Brown.
- [bb htmx todo app](https://github.com/prestancedesign/babashka-htmx-todoapp) by Michael Sahili.
- [bb aws lambda runtime](https://github.com/tatut/bb-lambda) by Tatu Tarvainen.
## 2021-07
- New babashka 0.5.0 released. Highlights: `clojure.tools.logging` + `taoensso.timbre` added, source compatibility with `clojure.data.json`.
- [Babashka tasks](https://youtu.be/u5ECoR7KT1Y), talk by Michiel Borkent
- [Rewriting a clojure file with rewrite-clj and babashka](https://youtu.be/b7NPKsm8gkc), video by Oxalorg
- [Babashka tasks for PostgreSQL](https://github.com/babashka/babashka/discussions/929) by Stel Abrego
- [String interpolation](https://twitter.com/yogthos/status/1415324124361154561) with Selmer in bb
- [Jirazzz](https://github.com/rwstauner/jirazzz): a babashka JIRA client by Randy Stauner
- [Babashka + scittle guestbook](https://github.com/kloimhardt/babashka-scittle-guestbook) by Kloimhardt
- [Paillier cryptosystem](https://github.com/babashka/babashka/discussions/948) by litteli
- [csv-to-yaml.clj](https://github.com/babashka/babashka/discussions/939) by Cora
## 2021-06
- New babashka 0.4.4 - 0.4.5 released.
- Share your babashka creations on the [Show and tell](https://github.com/babashka/babashka/discussions/categories/show-and-tell) forum on Github.
- [Integrating Babashka into Bazel](https://timjaeger.io/20210627-integrating-babashka-with-bazel.html) by Tim Jäger
- [Babashka + scittle guestbook example](https://github.com/kloimhardt/babashka-scittle-guestbook)
- [Slingshot works with babashka](https://twitter.com/borkdude/status/1402547783295504387)
- [Spire gets a babashka pod](https://twitter.com/epic_castle/status/1402212817533431808)
- [Text to speech AWS example](https://twitter.com/FieryCodDev/status/1401843357555511301) with scittle and babashka.
- [Game of Life](https://gist.github.com/mmzsource/655b9dcfe56eed8a045022837186ed84)
- [ob-babashka](https://gist.github.com/adam-james-v/f4d2b75a70b095d14a351a1eff96b4b0): Emacs org-babel functions for babashka.
- [Normalize auto-resolved keywords](https://github.com/babashka/babashka/tree/master/examples#normalize-keywordsclj)
- [Create PostgreSQL backups](https://twitter.com/stelstuff/status/1400559261025980418) using babashka.
- [Change flutter SDK](https://gist.github.com/ampersanda/aac70cc0644df12199ea32988f3c4d73) using babashka.
## 2021-05
- Babashka 0.3.7 - 0.4.3 released. Highlights:
- New [task runner feature](https://book.babashka.org/#tasks).
- Add [Selmer](https://github.com/yogthos/Selmer) to built-in libraries.
- Add compatibility with [jasentaa](https://github.com/rm-hull/jasentaa).
- New [website](https://babashka.org).
- [Talk](https://youtu.be/Yjeh57eE9rg): Babashka: a native Clojure interpreter for scripting — The 2021 Graal Workshop at CGO
- [Blog](https://savo.rocks/posts/playing-new-music-on-old-car-stereo-with-clojure-and-babashka/): Playing New Music On Old Car Stereo With Clojure And Babashka
- [Homoiconicity and feature flags](https://martinklepsch.org/posts/homoiconicity-and-feature-flags.html) by Martin Klepsch.
- [Manage your macOS setup](https://github.com/cldwalker/osx-setup) using babashka.
- [Localizing a Ghost theme](https://martinklepsch.org/posts/localizing-a-ghost-theme.html) by Martin Klepsch.
- [Babashka SQL pods 0.0.8](https://twitter.com/borkdude/status/1396136828479188997) including a MySQL pod
## 2021-04
- Babashka 0.3.2 - 0.3.6 released. See [CHANGELOG.md](https://github.com/babashka/babashka/blob/master/CHANGELOG.md). Highlights:
- Add [rewrite-clj](https://github.com/clj-commons/rewrite-clj).
- Support for the [binf](https://github.com/helins/binf.cljc) library.
- [Sort requires and imports](https://gist.github.com/laurio/01530ea7700752885df21e92bb926f75) using rewrite-clj
- Babashka [tasks proposal](https://github.com/babashka/babashka/issues/778), available in babashka 0.3.5
- A new useful function in `babashka.fs`: [modified-since](https://babashka.org/fs/babashka.fs.html#var-modified-since)
- Using babashka [for animations](https://twitter.com/RustyVermeer/status/1385269161106972673)
- [rewrite-edn](https://github.com/borkdude/rewrite-edn) is now compatible with babashka
## 2021-03
- Babashka 0.3.0 - 0.3.1 released. See [CHANGELOG.md](https://github.com/babashka/babashka/blob/master/CHANGELOG.md). Highlights: Raspberry Pi support, bb.edn, more flexible main invocation.
- [Babashka shebang](https://github.com/borkdude/deps.clj/blob/master/deps.bat#L1-L7) for Windows .bat files
- [Datalevin](https://twitter.com/huahaiy/status/1371689142585753604) now works as a babashka pod
- [Babashka sql pods](https://github.com/babashka/babashka-sql-pods/blob/master/CHANGELOG.md) update
- [JPoint](https://jpoint.ru/en/2021/talks/3nr1czuok3dvtewtcdjalm/) is going to have a talk on babashka
- A `python -m http.server` [replacement in babashka](https://gist.github.com/holyjak/36c6284c047ffb7573e8a34399de27d8)
- A [PR](https://github.com/ring-clojure/ring-codec/issues/26) to make `ring-codec` compatible with babashka
- The [stuartsierra/component](https://github.com/stuartsierra/component) library [seems to work with babashka](https://github.com/babashka/babashka/issues/742)
- [pathom3](https://pathom3.wsscode.com/docs/tutorials/babashka/) works with babashka!
- [VPN Connect](https://tech.toryanderson.com/2021/03/06/re-writing-an-openconnect-vpn-connect-script-in-babashka/) script
- [Github code search](https://gist.github.com/ertugrulcetin/4f35557962fac3d159d8c931e94873e9) script
## 2021-02
- Babashka 0.2.9 - 0.2.12 released
- [babashka.fs](https://github.com/babashka/fs): utility library for dealing with files (based on java.nio). Bundled with bb 0.2.9.
- New [Youtube channel](https://www.youtube.com/channel/UCRCl_R1ihLJt7IOgICdb9Lw) with babashka related videos
- MS SQL support for the [babashka sql pods](https://github.com/babashka/babashka-sql-pods/)
- [Clojure like its PHP](https://eccentric-j.com/blog/clojure-like-its-php.html): run babashka scripts as CGI scripts
- [Automating Video Edits with Clojure and ffmpeg](https://youtu.be/Tmgy57R9HZM) by Adam James
- [Gaka](https://github.com/cdaddr/gaka), a CSS-generating library that works with babashka.
- [Deploy babashka script to AWS Lambda](https://www.jocas.lt/blog/post/babashka-aws-lambda/) by Dainius Jocas.
- [Elisp](https://gist.github.com/llacom/f391f41cbf4de91739b52bf8bb1a6d54) and cider commands to spawn a babashka repl and connect to it
- [klein](https://gist.github.com/borkdude/c34e8e44eb5b4a6ca735bf8a86ff64fa), a
lein imitation script built on deps.edn
- [failjure](https://github.com/adambard/failjure) works with babashka.
- A [script](https://gist.github.com/borkdude/58f099b2694d206e6eec18daedc5077b) to solve our mono-repo problem with deps.edn at work.
- [Single-script vega-lite plotter](https://gist.github.com/vdikan/6b6063d6e1b00a3cd79bc7b3ce3853d6/)
- [Find vars with the clj-kondo pod](https://gist.github.com/borkdude/841d85d5ad04c517337166b3928697bd). Also see [video](https://youtu.be/TvBmtGS0KJE).
- [Another setup babashka Github action](https://github.com/marketplace/actions/setup-babashka)
- [AWS Lambda + babashka + minimal container image](https://gist.github.com/lukaszkorecki/a1fe27bf08f9b98e9def9da4bcb3264e)
- [football script](https://gist.github.com/mmzsource/a732950aa43d19c5a9b63bbb7f20b7eb)
- [ffclj](https://github.com/luissantos/ffclj): Clojure ffmpeg wrapper
- [clj-lineart](https://github.com/eccentric-j/clj-lineart): Generative line art from a clojure-cgi script
- [bunpack](https://github.com/robertfw/bunpack): remembers how to unpack things, so you don't have to
- A script to download deps for [all `deps.edn` aliases](https://github.com/babashka/babashka/blob/master/examples/download-aliases.clj)
## 2021-01
- Babashka [0.2.8](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v028) released. This includes new libraries: hiccup, core.match and clojure.test.check.
- On 27th of February, Michiel (a.k.a. @borkdude) will do a talk about babashka at the [2021 GraalVM workshop](https://graalworkshop.github.io/2021/).
- First release of the [aws pod](https://github.com/babashka/pod-babashka-aws).
- A [script](https://gist.github.com/borkdude/ba372c8cee311e31020b04063d88e1be) to print API breakage warnings.
- A [script](https://gist.github.com/lgouger/2262e2d2503306f2595e48a7888f4e73) to lazily page through AWS results using the new [aws pod](https://github.com/babashka/pod-babashka-aws).
- [Environ](https://github.com/weavejester/environ) works with babashka.
- [Expound](https://github.com/bhb/expound) now works with [spartan.spec](https://github.com/borkdude/spartan.spec/blob/master/examples/expound.clj)
- A basic [logger](https://gist.github.com/borkdude/c97da85da67c7bcc5671765aef5a89ad) that works in babashka scripts
- A basic [router](https://gist.github.com/borkdude/1627f39d072ea05557a324faf5054cf3) based on core.match
- A minimal [Github GraphQL client](https://gist.github.com/lagenorhynque/c1419487965c0fa3cf34862852825483)
- New developments around babashka on [Raspberry Pi](https://github.com/babashka/babashka/issues/241#issuecomment-763976749)
## 2020-12
- A new babashka talk: [Babashka and sci
internals](https://youtu.be/pgNp4Lk3gf0). Also see
[slides](https://speakerdeck.com/babashka/babashka-and-sci-internals-at-london-clojurians-december-2020)
and [REPL
session](https://gist.github.com/borkdude/66a4d844668e12ae1a8277af10d6cc4b).
- Babashka 0.2.6 released. See [release
notes](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v026).
- Babashka 0.2.5 released. See [release
notes](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v025).
- First release of the [sqlite pod](https://github.com/babashka/pod-babashka-sqlite3)
- First release of the [buddy pod](https://github.com/babashka/pod-babashka-buddy)
- The data from the babashka survey is now available
[here](https://nl.surveymonkey.com/results/SM-8W8V36DZ7/). I have provided a
summary [here](surveys/2020-11.md).
- Blog article: [exporter for passwordstore.org](https://www.ieugen.ro/posts/2020/2020-12-26-export-passwords-with-babashka/) by Eugen Stan
- [weavejester/progrock](https://github.com/weavejester/progrock) is a babashka-compatible library
for printing progress bars.
- A [maze animation](https://gist.github.com/mmzsource/e8c383f69244ebefde058004fee72a8a) babashka script by [mmz](https://gist.github.com/mmzsource)
## 2020-11
- Babashka [survey](https://nl.surveymonkey.com/r/H2HK3RC). Feedback will be used
for future development.
- Babashka 0.2.4 released. See [release
notes](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v024).
- [Gaiwan.co](https://github.com/lambdaisland/gaiwan_co#tech-stack) are building their static HTML with babashka and [bootleg](https://github.com/retrogradeorbit/bootleg#babashka-pod-usage).
- [sha-words](https://github.com/ordnungswidrig/sha-words): A clojure program to
turn a sha hash into list of nouns in a predictable jar.
- [Stash](https://github.com/rorokimdim/stash): a CLI for encrypted text storage
written in Haskell, accessible as pod from babashka and Python!
- NextJournal released a babashka [notebook environment](http://nextjournal.com/try/babashka?cm6=1).
- [Interdep](https://github.com/rejoice-cljc/interdep) manages interdependent
dependencies using Clojure's tools.deps and babashka.
- LA Clojure Meetup [presentation](https://youtu.be/RogyxI-GaGQ) by Nate Jones. Recorded in April 2020.
- [Github action](https://github.com/turtlequeue/setup-babashka) for babashka by Nicolas Ha.
- Oracle DB [feature flag](https://github.com/babashka/babashka/blob/master/doc/build.md#feature-flags) by Jakub Holy added.
- Torrent viewer [gist](https://gist.github.com/zelark/49ffbc0cd701c9299e35421ac2e3d5ab) by Aleksandr Zhuravlёv.
- Clone all repositories from a Gitlab group:
[gist](https://gist.github.com/MrGung/81bee21eb52cb9307f336705d5ab08ad) by
Steffen Glückselig.
- [Matchete](https://github.com/xapix-io/matchete), a pattern matching library,
works with babashka. See
[example](https://github.com/babashka/babashka/issues/631).
## 2020-10
- Babashka 0.2.3 released. See [release
notes](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v023-2020-10-21).
- [Malcolm Sparks](https://twitter.com/malcolmsparks/status/1320274099952848896) posted a
[script](https://gist.github.com/malcolmsparks/61418b6bbcd0962536add1ccb07033b5) that
sorts his photo collection.
- [Image viewer](https://github.com/babashka/babashka/tree/master/examples#image-viewer) example
- SQL Server [pod](https://github.com/xledger/pod_sql_server) by Isak Sky
- [SSH Auth Github](https://github.com/nextjournal/ssh-auth-github) by
NextJournal.
- [pod-tzzh-mail](https://github.com/tzzh/pod-tzzh-mail): a pod to send mail.
- NextJournal [replaces bash with a babashka script](https://twitter.com/kommen/status/1311574776834666496)
## 2020-09
- Babashka
[0.2.1](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v021-2020-09-25)
and 0.2.2 released.
- Code Quality report for Clojure projects in Gitlab using babashka and clj-kondo. See [gist](https://gist.github.com/hansbugge/4be701d771057e8ef6bbbb0912656355). By Hans Bugge.
- [pod-tzzh-aws](https://github.com/tzzh/pod-tzzh-aws): a pod to interact with AWS.
- [spotifyd-notification](https://github.com/dharrigan/spotifyd-notification) by
David Harrigan.
## 2020-08
- Babashka [0.2.0](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v020-2020-08-28) released.
- Maarten Metz
[blogs](https://www.mxmmz.nl/blog/building-a-website-with-babashka.html) about
how he rebuilt his blog using babashka.
## 2020-07
- Blake Miller published [https://gitlab.com/blak3mill3r/emacs-ludicrous-speed](emacs-ludicrous-speed).
- [babashka-clojure](https://github.com/marketplace/actions/babashka-clojure) Github action.
- [testdoc](https://github.com/liquidz/testdoc) works with babashka.
- [babashka-test-action](https://github.com/liquidz/babashka-test-action)
- New release of [tabl](https://github.com/justone/tabl)
which also can be used as a pod from babashka.
## 2020-06
- Babashka [0.1.3](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v013-2020-06-27) and 0.1.2 released.
- New release of [brisk](https://github.com/justone/brisk), a CLI around nippy which can be used as a pod from babashka.
- [passphrase.clj](https://gist.github.com/snorremd/43c49649d2d844ee1e646fee67c141bb) script by Snorre Magnus Davøen

View file

@ -1,87 +0,0 @@
# Using Babashka with Nix
Babashka is [packaged](https://search.nixos.org/packages?type=packages&query=babashka) in nixpkgs and can be easily used from the Nix package manager.
The following assumes a recent installation of nix and uses the unstable [nix cli](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html) and [Flakes](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html).
To enable the unstable cli and flakes add the following to `/etc/nix/nix.conf`:
```
extra-experimental-features flakes nix-command
```
## Imperative install on Nix
To imperatively install nix for the current user, run `nix profile install babashka`.
## Declarative global install on NixOS
To install babashka for all users on a NixOS system, place it in `environment.systemPackages` in your `configuration.nix`:
```nix
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
babashka
];
}
```
Then run `nixos-rebuild switch`, to activate the new configuration.
## Declarative per-user install with home-manager
You can install babashka for a specific user using [home-manager](https://github.com/nix-community/home-manager). Add the following to your `~/.config/nixpkgs/home.nix`:
```nix
{ pkgs, ... }:
{
home.packages = with pkgs; [
babashka
];
}
```
Then run `home-manager switch`, to activate the new configuration.
## Per project install with direnv
To make babashka available on a per-project basis, you can use [direnv](https://direnv.net/).
Create a file `.envrc` in the project directory with the following contents:
```
use flake
```
Create a file `flake.nix` in the project directory with the following contents:
```nix
{
outputs = {nixpkgs, ...}: let
supportedSystems = ["x86_64-linux" "x86_64-darwin"];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
nixpkgsFor = system: import nixpkgs {inherit system;};
in {
devShell = forAllSystems (system: let
pkgs = nixpkgsFor system;
in
pkgs.mkShell {
packages = with pkgs; [
babashka
];
});
};
}
```
After running `direnv allow`, babashka should be available on the `$PATH`, when you are inside the project directory.
## Write Babashka Application
You can write babashka scripts with native dependencies using [WriteBabashkaApplication](https://github.com/sohalt/write-babashka-application).
The WriteBabashkaApplication repository has an [example](https://github.com/Sohalt/write-babashka-application/tree/main/example) `flake.nix` using `cowsay` as an external dependency.
You can download that example, and then build the application using `nix build` or run it using `nix run`.

View file

@ -1,972 +0,0 @@
# Projects
The following libraries and projects are known to work with babashka.
- [Projects](#projects)
- [Libraries](#libraries)
- [tools.namespace](#toolsnamespace)
- [test-runner](#test-runner)
- [spec.alpha](#specalpha)
- [clj-http-lite](#clj-http-lite)
- [spartan.spec](#spartanspec)
- [missing.test.assertions](#missingtestassertions)
- [medley](#medley)
- [limit-break](#limit-break)
- [clojure-csv](#clojure-csv)
- [regal](#regal)
- [cprop](#cprop)
- [comb](#comb)
- [nubank/docopt](#nubankdocopt)
- [arrangement](#arrangement)
- [clojure.math.combinatorics](#clojuremathcombinatorics)
- [testdoc](#testdoc)
- [doric](#doric)
- [clojure.data.zip](#clojuredatazip)
- [clj-psql](#clj-psql)
- [camel-snake-kebab](#camel-snake-kebab)
- [aero](#aero)
- [clojure.data.generators](#clojuredatagenerators)
- [honeysql](#honeysql)
- [bond](#bond)
- [portal](#portal)
- [version-clj](#version-clj)
- [matchete](#matchete)
- [progrock](#progrock)
- [clj-commons/fs](#clj-commonsfs)
- [cljc.java-time](#cljcjava-time)
- [environ](#environ)
- [gaka](#gaka)
- [failjure](#failjure)
- [pretty](#pretty)
- [clojure-term-colors](#clojure-term-colors)
- [binf](#binf)
- [rewrite-edn](#rewrite-edn)
- [expound](#expound)
- [omniconf](#omniconf)
- [slingshot](#slingshot)
- [hasch](#hasch)
- [crispin](#crispin)
- [ffclj](#ffclj)
- [multigrep](#multigrep)
- [java-http-clj](#java-http-clj)
- [component](#component)
- [minimallist](#minimallist)
- [ruuter](#ruuter)
- [clj-commons.digest](#clj-commonsdigest)
- [contajners](#contajners)
- [dependency](#dependency)
- [specmonstah](#specmonstah)
- [markdown-clj](#markdown-clj)
- [algo.monads](#algomonads)
- [datalog-parser](#datalog-parser)
- [at-at](#at-at)
- [aysylu/loom](#aysyluloom)
- [Clarktown](#clarktown)
- [Malli](#malli)
- [Meander](#meander)
- [Schema](#schema)
- [Sluj](#sluj)
- [malli-cli](#malli-cli)
- [Pods](#pods)
- [Projects](#projects-1)
- [babashka-test-action](#babashka-test-action)
- [deps.clj](#depsclj)
- [4bb](#4bb)
- [babashka lambda layer](#babashka-lambda-layer)
- [Release on push Github action](#release-on-push-github-action)
- [justone/bb-scripts](#justonebb-scripts)
- [nativity](#nativity)
- [cldwalker/bb-clis](#cldwalkerbb-clis)
- [krell template](#krell-template)
- [wee-httpd](#wee-httpd)
- [covid19-babashka](#covid19-babashka)
- [bb-spotify](#bb-spotify)
- [lambdaisland/open-source](#lambdaislandopen-source)
- [dharrigan/spotifyd-notification](#dharriganspotifyd-notification)
- [nextjournal/ssh-github-auth](#nextjournalssh-github-auth)
- [turtlequeue/setup-babashka](#turtlequeuesetup-babashka)
- [interdep](#interdep)
- [sha-words](#sha-words)
- [adam-james-v/scripts](#adam-james-vscripts)
- [oidc-client](#oidc-client)
- [jirazzz](#jirazzz)
- [Babashka + scittle guestbook](#babashka--scittle-guestbook)
- [bb htmx todo app](#bb-htmx-todo-app)
- [bb aws lambda runtime](#bb-aws-lambda-runtime)
- [bb-github-app](#bb-github-app)
Also keep an eye on the [news](news.md) page for new projects, gists and other
developments around babashka.
## Libraries
For a full list of libraries, see [libraries.csv](./libraries.csv). To add a
library, see [these instructions](./dev.md#tests-for-libraries).
### [tools.namespace](https://github.com/babashka/tools.namespace)
A fork of `tools.namespace`. This is used by other libraries and enables them to
be supported by babashka.
### [test-runner](https://github.com/cognitect-labs/test-runner)
This library works with the
[tools.namespace](https://github.com/babashka/tools.namespace) fork. See its
readme for an example task for running tests.
### [spec.alpha](https://github.com/babashka/spec.alpha)
A fork of `clojure.spec.alpha` that includes support for generation and
instrumentation! Its readme also contains instructions on how to use
`clojure.core.specs.alpha`.
<!-- ### [tools.bbuild](https://github.com/babashka/tools.bbuild) -->
<!-- A fork of `tools.build`. -->
### [clj-http-lite](https://github.com/clj-commons/clj-http-lite)
Example:
``` shell
$ export BABASHKA_CLASSPATH="$(clojure -Sdeps '{:deps {org.clj-commons/clj-http-lite {:mvn/version "0.4.392"}}}' -Spath)"
$ bb "(require '[clj-http.lite.client :as client]) (:status (client/get \"https://www.clojure.org\"))"
200
```
### [spartan.spec](https://github.com/borkdude/spartan.spec/)
An babashka-compatible implementation of `clojure.spec.alpha`. See
[spec.alpha](#specalpha) for a more complete implementation.
### [missing.test.assertions](https://github.com/borkdude/missing.test.assertions)
This library checks if no assertions have been made in a test:
``` shell
$ export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {borkdude/missing.test.assertions {:git/url "https://github.com/borkdude/missing.test.assertions" :sha "603cb01bee72fb17addacc53c34c85612684ad70"}}}')
$ lein bb "(require '[missing.test.assertions] '[clojure.test :as t]) (t/deftest foo) (t/run-tests)"
Testing user
WARNING: no assertions made in test foo
Ran 1 tests containing 0 assertions.
0 failures, 0 errors.
{:test 1, :pass 0, :fail 0, :error 0, :type :summary}
```
### [medley](https://github.com/weavejester/medley/)
Example:
``` shell
$ export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {medley/medley {:mvn/version "1.3.0"}}}')
$ bb -e "(require '[medley.core :as m]) (m/index-by :id [{:id 1} {:id 2}])"
{1 {:id 1}, 2 {:id 2}}
```
### [limit-break](https://github.com/technomancy/limit-break)
A debug REPL library.
Latest coordinates checked with with bb:
``` clojure
{:git/url "https://github.com/technomancy/limit-break" :sha "050fcfa0ea29fe3340927533a6fa6fffe23bfc2f" :deps/manifest :deps}
```
Example:
``` shell
$ export BABASHKA_CLASSPATH="$(clojure -Sdeps '{:deps {limit-break {:git/url "https://github.com/technomancy/limit-break" :sha "050fcfa0ea29fe3340927533a6fa6fffe23bfc2f" :deps/manifest :deps}}}' -Spath)"
$ bb "(require '[limit.break :as lb]) (let [x 1] (lb/break))"
Babashka v0.0.49 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.
break> x
1
```
### [clojure-csv](https://github.com/davidsantiago/clojure-csv)
A library for reading and writing CSV files. Note that babashka already comes
with `clojure.data.csv`, but in case you need this other library, this is how
you can use it:
``` shell
export BABASHKA_CLASSPATH="$(clojure -Sdeps '{:deps {clojure-csv {:mvn/version "RELEASE"}}}' -Spath)"
./bb -e "
(require '[clojure-csv.core :as csv])
(csv/write-csv (csv/parse-csv \"a,b,c\n1,2,3\"))
"
```
### [regal](https://github.com/lambdaisland/regal)
Example:
``` shell
$ export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {lambdaisland/regal {:mvn/version "0.0.143"}}}')
$ bb -e "(require '[lambdaisland.regal :as regal]) (regal/regex [:* \"ab\"])"
#"(?:\Qab\E)*"
```
### [cprop](https://github.com/tolitius/cprop/)
A clojure configuration library. Latest test version: `"0.1.16"`.
### [comb](https://github.com/weavejester/comb)
Simple templating system for Clojure. Latest tested version: `"0.1.1"`.
``` clojure
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {comb/comb {:mvn/version "0.1.1"}}})
(require '[comb.template :as template])
(template/eval "<% (dotimes [x 3] %>foo<% ) %>") ;;=> "foofoofoo"
```
### [nubank/docopt](https://github.com/nubank/docopt.clj#babashka)
Docopt implementation in Clojure, compatible with babashka.
### [arrangement](https://github.com/greglook/clj-arrangement)
A micro-library which provides a total-ordering comparator for Clojure
values. Tested with version `1.2.0`.
### [clojure.math.combinatorics](https://github.com/clojure/math.combinatorics)
``` clojure
$ bb --classpath "$(clojure -Spath -Sdeps '{:deps {org.clojure/math.combinatorics {:mvn/version "0.1.6"}}}')" \
-e "(use 'clojure.math.combinatorics) (permutations [:a :b])"
((:a :b) (:b :a))
```
### [testdoc](https://github.com/liquidz/testdoc)
Yet another doctest implementation in Clojure.
``` clojure
$ export BABASHKA_CLASSPATH=$(clojure -Sdeps '{:deps {testdoc {:mvn/version "1.2.0"}}}' -Spath)
$ bb '(ns foo (:use clojure.test testdoc.core))
(defn foo "
=> (foo)
:foox"
[] :foo)
(deftest footest
(is (testdoc (var foo))))
(test-var (var footest))'
FAIL in (footest) (:1)
(= (foo) :foox)
expected: :foox
actual: :foo
```
### [doric](https://github.com/joegallo/doric)
Library for printing tables.
``` clojure
$ export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {doric {:mvn/version "0.9.0"}}}')
$ bb "(use 'doric.core) (println (table [:a :b :c] [{:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6}]))"
|---+---+---|
| A | B | C |
|---+---+---|
| 1 | 2 | 3 |
| 4 | 5 | 6 |
|---+---+---|
```
### [clojure.data.zip](https://github.com/clojure/data.zip)
Utilities for clojure.zip, among other things a more fluent way to work
with xml.
Small sample:
``` clojure
$ export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {org.clojure/data.zip {:mvn/version "1.0.0"}}}')
$ cat data_zip_xml.clj
(require '[clojure.data.xml :as xml])
(require '[clojure.zip :as zip])
(require '[clojure.data.zip.xml :refer [text attr attr= xml-> xml1-> text=]])
(def data (str "<root>"
" <character type=\"person\" name=\"alice\" />"
" <character type=\"animal\" name=\"march hare\" />"
"</root>"))
(let [xml (-> data java.io.StringReader. xml/parse zip/xml-zip)]
(prn :alice-is-a (xml1-> xml :character [(attr= :name "alice")] (attr :type)))
(prn :animal-is-called (xml1-> xml :character [(attr= :type "animal")] (attr :name))))
$ bb data_zip_xml.clj
:alice-is-a "person"
:animal-is-called "march hare"
```
(see for exaple [this article](https://blog.korny.info/2014/03/08/xml-for-fun-and-profit.html#datazip-for-zipper-awesomeness)
for more on clojure.data.zip).
### [clj-psql](https://github.com/DarinDouglass/clj-psql)
A small Clojure wrapper for interacting with `psql`.
```clojure
user> (psql/query conn "select name, subject from grades where grade = 100")
=> ({:name "Bobby Tables", :subject "Math"}
{:name "Suzy Butterbean", :subject "Math"})
```
### [camel-snake-kebab](https://github.com/clj-commons/camel-snake-kebab)
A library for word case conversions.
``` clojure
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {camel-snake-kebab/camel-snake-kebab {:mvn/version "0.4.2"}}})
(require '[camel-snake-kebab.core :as csk])
(csk/->camelCase 'flux-capacitor) ;;=> 'fluxCapacitor
```
### [aero](https://github.com/juxt/aero/)
A small library for explicit, intentful configuration.
### [clojure.data.generators](https://github.com/clojure/data.generators)
Random data generators
### [honeysql](https://github.com/seancorfield/honeysql)
Turn Clojure data structures into SQL
### [bond](https://github.com/circleci/bond)
Spying and stubbing library, primarily intended for tests.
### [portal](https://github.com/djblue/portal/)
A clojure tool to navigate through your data. This example will launch a browser to view your `deps.edn`:
``` clojure
$ cat deps.edn | bb -e "(babashka.deps/add-deps '{:deps {djblue/portal {:mvn/version \"0.9.0\"}}})" \
-e "(require 'portal.main)" \
-e '(portal.main/-main "edn")'
```
Also see [examples](https://github.com/babashka/babashka/tree/master/examples#portal).
### [version-clj](https://github.com/xsc/version-clj)
Analysis and comparison of artifact version numbers.
``` clojure
> export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {version-clj/version-clj {:mvn/version "0.1.2"}}}')
> bb --repl
...
user=> (require '[version-clj.core :as ver])
nil
user=> (ver/version->seq "1.0.0-SNAPSHOT")
[(1 0 0) ["snapshot"]]
user=> (ver/version-compare "1.2.3" "1.0.0")
1
user=> (ver/version-compare "1.0.0-SNAPSHOT" "1.0.0")
-1
user=> (ver/version-compare "1.0" "1.0.0")
0
```
### [matchete](https://github.com/xapix-io/matchete.git)
Pattern matching library:
``` clojure
$ rlwrap bb -cp "$(clojure -Spath -Sdeps '{:deps {io.xapix/matchete {:mvn/version "1.2.0"}}}')"
user=> (require '[matchete.core :as mc])
nil
user=> (mc/matches '{?k 1} {:x 1 :y 1})"
({?k :y} {?k :x})
```
### [progrock](https://github.com/weavejester/progrock)
A functional Clojure progress bar for the command line.
Tested version: 0.1.2.
### [clj-commons/fs](https://github.com/clj-commons/fs)
File system utilities for Clojure.
``` clojure
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {clj-commons/fs {:mvn/version "1.5.2"}}})
(require '[me.raynes.fs :as fs])
(fs/link? "/tmp") ;; true
```
### [cljc.java-time](https://github.com/henryw374/cljc.java-time)
``` clojure
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {cljc.java-time/cljc.java-time {:mvn/version "0.1.12"}}})
(require '[cljc.java-time.local-date :as ld])
(def a-date (ld/parse "2019-01-01"))
(ld/plus-days a-date 99)
```
### [environ](https://github.com/weavejester/environ)
Library for managing environment variables in Clojure.
``` clojure
(require '[babashka.deps :as deps])
(babashka.deps/add-deps '{:deps {environ/environ {:mvn/version "1.2.0"}}})
(require '[environ.core :refer [env]])
(prn (:path env))
```
### [gaka](https://github.com/cdaddr/gaka)
``` clojure
(ns script
(:require [babashka.deps :as deps]))
(deps/add-deps '{:deps {gaka/gaka {:mvn/version "0.3.0"}}})
(require '[gaka.core :as gaka])
(def rules [:div#foo
:margin "0px"
[:span.bar
:color "black"
:font-weight "bold"
[:a:hover
:text-decoration "none"]]])
(println (gaka/css rules))
```
Output:
``` css
div#foo {
margin: 0px;}
div#foo span.bar {
color: black;
font-weight: bold;}
div#foo span.bar a:hover {
text-decoration: none;}
```
### [failjure](https://github.com/adambard/failjure)
Working with failed computations in Clojure.
``` clojure
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {failjure/failjure {:mvn/version "2.1.1"}}})
(require '[failjure.core :as f])
(f/fail "foo")
```
### [pretty](https://github.com/AvisoNovate/pretty)
The `io.aviso.ansi` namespace provides ANSI font and background color support.
``` clojure
(require '[babashka.deps :as deps])
(deps/add-deps
'{:deps {io.aviso/pretty {:mvn/version "0.1.36"}}})
(require '[io.aviso.ansi :as ansi])
(println
(str "The following text will be "
ansi/bold-red-font "bold and red "
ansi/reset-font "but this text will not."))
```
### [clojure-term-colors](https://github.com/trhura/clojure-term-colors)
Clojure ASCII color formatting for terminal output.
``` clojure
(require '[babashka.deps :as deps])
(deps/add-deps
'{:deps {clojure-term-colors/clojure-term-colors {:mvn/version "0.1.0"}}})
(require '[clojure.term.colors :as c])
(println
(c/yellow "Yellow")
(c/red "Red")
"No color")
```
### [binf](https://github.com/helins/binf.cljc)
Handling binary formats in all shapes and forms.
### [rewrite-edn](https://github.com/borkdude/rewrite-edn)
Rewrite EDN with preservation of whitespace, based on rewrite-clj.
Example:
``` clojure
#!/usr/bin/env bb
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {borkdude/rewrite-edn {:mvn/version "0.0.2"}}})
(require '[borkdude.rewrite-edn :as r])
(def edn-string (slurp "deps.edn"))
(def nodes (r/parse-string edn-string))
(println (str (r/assoc-in nodes [:deps 'my-other-dep] {:mvn/version "0.1.2"})))
```
### [expound](https://github.com/bhb/expound)
Formats `spartan.spec` error messages in a way that is optimized for humans to read.
Example:
``` clojure
#!/usr/bin/env bb
(ns expound
(:require [babashka.deps :as deps]))
(deps/add-deps
'{:deps {borkdude/spartan.spec {:git/url "https://github.com/borkdude/spartan.spec"
:sha "bf4ace4a857c29cbcbb934f6a4035cfabe173ff1"}
expound/expound {:mvn/version "0.8.9"}}})
;; Loading spartan.spec will create a namespace clojure.spec.alpha for compatibility:
(require 'spartan.spec)
(alias 's 'clojure.spec.alpha)
;; Expound expects some vars to be there, like `fdef`. Spartan prints warnings that these are used, but doesn't implement them yet.
(require '[expound.alpha :as expound])
(s/def ::a (s/cat :i int? :j string?))
(expound/expound ::a [1 2])
```
### [omniconf](https://github.com/grammarly/omniconf)
script.clj:
``` clojure
#!/usr/bin/env bb
(ns script
(:require [babashka.deps :as deps]))
(deps/add-deps
'{:deps {com.grammarly/omniconf {:mvn/version "0.4.3"}}})
(require '[omniconf.core :as cfg])
(cfg/define {:foo {}})
(cfg/populate-from-env)
(cfg/get :foo)
```
``` text
FOO=1 script.clj
Populating Omniconf from env: 1 value(s)
"1"
```
### [slingshot](https://github.com/scgilardi/slingshot)
Enhanced try and throw for Clojure leveraging Clojure's capabilities.
``` clojure
$ export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {slingshot/slingshot {:mvn/version "0.12.2"}}}')
$ bb -e "(require '[slingshot.slingshot :as s]) (s/try+ (s/throw+ {:type ::foo}) (catch [:type ::foo] [] 1))"
1
```
NOTE: slingshot's tests pass with babashka except one: catching a record types
by name. This is due to a difference in how records are implemented in
babashka. This may be fixed later if this turns out to be really useful.
### [hasch](https://github.com/replikativ/hasch)
Cross-platform (JVM and JS atm.) edn data structure hashing for Clojure.
``` clojure
$ export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {io.replikativ/hasch {:mvn/version "0.3.7"}}}')
$ bb -e "(use 'hasch.core) (edn-hash (range 100))"
(168 252 48 247 180 148 51 182 108 76 20 251 155 187 66 8 124 123 103 28 250 151 26 139 10 216 119 168 101 123 130 225 66 168 48 63 53 99 25 117 173 29 198 229 101 196 162 30 23 145 7 166 232 193 57 239 226 238 240 41 254 78 135 122)
```
NOTE: hasch's tests pass with babashka except the test around hashing
records. This is due to a difference in how records are implemented in
babashka. This may be fixed later if this turns out to be really useful.
### [crispin](https://github.com/dunaj-project/crispin)
Populate a configuration map from multiple sources (environment variables,
system variables, config files, etc.)
Example:
script.clj
``` clojure
#!/usr/bin/env bb
(ns script
(:require [babashka.deps :as deps]))
(deps/add-deps
'{:deps {crispin/crispin {:mvn/version "0.3.8"}}})
(require '[crispin.core :as crispin])
(def app-cfg (crispin/cfg))
(app-cfg :foo)
```
``` text
FOO=1 script.clj
"1"
```
### [ffclj](https://github.com/luissantos/ffclj)
A wrapper around executing `ffmpeg` and `ffprobe`. Supports progress reporting via core.async channels.
### [multigrep](https://github.com/clj-commons/multigrep)
Regex-based file grepping and/or text substitution.
Example:
- find the words that are exactly four letters long in some strings:
```clj
(ns multigrep-demo
(:require [babashka.deps :as deps]
[clojure.pprint :refer [pprint]])
(:import (java.io StringReader)))
(deps/add-deps '{:deps {clj-commons/multigrep {:mvn/version "0.5.0"}}})
(require '[multigrep.core :as grep])
; the StringReaders could be anything that clojure.java.io/reader will accept (files, URLs, etc.)
(let [sentence1 (StringReader. "the quick brown fox jumps over the lazy dog")
sentence2 (StringReader. "Lorem ipsum dolor sit amet")]
(pprint (grep/grep #"\b[a-z]{4}\b" [sentence1 sentence2])))
```
outputs:
```
({:file
#object[java.io.StringReader...],
:line "the quick brown fox jumps over the lazy dog",
:line-number 1,
:regex #"\b[a-z]{4}\b",
:re-seq ("over" "lazy")}
{:file
#object[java.io.StringReader...],
:line "Lorem ipsum dolor sit amet",
:line-number 1,
:regex #"\b[a-z]{4}\b",
:re-seq ("amet")})
```
### [java-http-clj](https://github.com/schmee/java-http-clj)
Http client based on `java.net.http`.
### [component](https://github.com/stuartsierra/component)
A tiny Clojure framework for managing the lifecycle and dependencies of software components which have runtime state.
### [minimallist](https://github.com/green-coder/minimallist)
A minimalist data-driven data model library, inspired by Clojure Spec and Malli.
Example partially borrowed from [minimallist's cljdoc](https://cljdoc.org/d/minimallist/minimallist/CURRENT/doc/usage-in-babashka)
```clj
(require '[babashka.deps :refer [add-deps]])
(add-deps '{:deps {minimallist/minimallist {:git/url "https://github.com/green-coder/minimallist"
:sha "b373bb18b8868526243735c760bdc67a88dd1e9a"}}})
(require '[minimallist.core :as m])
(require '[minimallist.helper :as h])
(def contact (h/map [:name (h/fn string?)]
[:phone (h/fn string?)]))
(m/valid? contact {:name "Lucy" :phone "5551212"}) ;=> true
(m/valid? contact {:name "Lucy" :phone 5551212}) ;=> false
(m/describe contact {:name "Lucy" :phone "5551212"}) ;=> {:valid? true, :entries {...}}
(m/describe contact {:name "Lucy" :phone 5551212}) ;=> {:valid? false, :entries {... :phone {:valid? false...}}}
;; Does not work for now.
;(require '[clojure.test.check.generators :as tcg])
;(require '[minimallist.generator :as mg])
;(tcg/sample (mg/gen (h/fn int?)))
```
### [ruuter](https://github.com/askonomm/ruuter)
A zero-dependency router where each route is a map. Works with the httpkit server built into babashka.
### [clj-commons.digest](https://github.com/clj-commons/digest)
A message digest library, providing functions for MD5, SHA-1, SHA-256, etc.
### [contajners](https://github.com/lispyclouds/contajners)
An idiomatic, data-driven, REPL friendly clojure client for OCI container engines.
Example:
``` clojure
#!/usr/bin/env bb
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {org.clojars.lispyclouds/contajners {:mvn/version "0.0.6"}}})
(require '[contajners.core :as c])
(def images-docker (c/client {:engine :docker
:category :images
:version "v1.41"
:conn {:uri "unix:///var/run/docker.sock"}}))
; Pull an image
(c/invoke images-docker {:op :ImageCreate
:params {:fromImage "busybox:musl"}})
; list all images
(c/invoke images-docker {:op :ImageList})
```
### [dependency](https://github.com/stuartsierra/dependency)
Represent dependency graphs as a directed acylic graph.
### [specmonstah](https://github.com/reifyhealth/specmonstah)
Write concise, maintainable test fixtures with clojure.spec.alpha.
### [markdown-clj](https://github.com/yogthos/markdown-clj)
Markdown parser that translates markdown to html.
### [algo.monads](https://github.com/clojure/algo.monads)
Macros for defining monads, and definition of the most common monads.
### [datalog-parser](https://github.com/lambdaforge/datalog-parser)
Datalog parser that is compliant with datomic, datascript and datahike.
### [at-at](https://github.com/overtone/at-at)
Ahead-of-time function scheduler. Compatible with babashka 0.7.7+.
### [aysylu/loom](https://github.com/aysylu/loom)
Graph library for Clojure. Compatible with babashka 0.7.8+.
### [Clarktown](https://github.com/askonomm/clarktown)
An extensible and modular zero-dependency, pure-Clojure Markdown parser.
### [Malli](https://github.com/metosin/malli#babashka)
Data-Driven Schemas for Clojure/Script
### [Meander](https://github.com/noprompt/meander)
Tools for transparent data transformation
### [Schema](https://github.com/plumatic/schema)
Clojure(Script) library for declarative data description and validation
### [Sluj](https://github.com/rawleyfowler/sluj)
Sluj is a very small library for converting strings of UTF-16 text to slugs. A slug is a piece of text that is URL safe.
### [malli-cli](https://github.com/piotr-yuxuan/malli-cli)
Configuration and CLI powertool with `metosin/malli`.
## Pods
[Babashka pods](https://github.com/babashka/babashka.pods) are programs that can
be used as Clojure libraries by babashka. See
[pod-registry](https://github.com/babashka/pod-registry) for an overview of available pods.
Pods not available in the pod registry:
- [pod-janet-peg](https://github.com/sogaiu/pod-janet-peg): a pod for
calling [Janet](https://github.com/janet-lang/janet)'s PEG
functionality.
- [pod-jaydeesimon-jsoup](https://github.com/jaydeesimon/pod-jaydeesimon-jsoup):
a pod for parsing HTML using CSS queries backed by Jsoup.
- [pod.xledger.sql-server](https://github.com/xledger/pod_sql_server): pod for interacting with SQL Server.
## Projects
### [babashka-test-action](https://github.com/marketplace/actions/babashka-test-action)
Github Action to run clojure.test by Babashka.
### [deps.clj](https://github.com/borkdude/deps.clj)
A port of the [clojure](https://github.com/clojure/brew-install/) bash script to
Clojure / babashka.
Also see [deps.clj documentation](../doc/deps.clj.md).
### [4bb](https://github.com/porkostomus/4bb)
4clojure as a babashka script!
### [babashka lambda layer](https://github.com/dainiusjocas/babashka-lambda-layer)
Babashka Lambda runtime packaged as a Lambda layer.
### [Release on push Github action](https://github.com/rymndhng/release-on-push-action)
Github Action to create a git tag + release when pushed to master. Written in
babashka.
### [justone/bb-scripts](https://github.com/justone/bb-scripts)
A collection of scripts developed by [@justone](https://github.com/justone).
### [nativity](https://github.com/MnRA/nativity)
Turn babashka scripts into binaries using GraalVM `native-image`.
### [cldwalker/bb-clis](https://github.com/cldwalker/bb-clis)
A collection of scripts developed by [@cldwalker](https://github.com/cldwalker).
### [krell template](https://github.com/ampersanda/krell-template-runner)
Babashka script for creating React Native (Krell) project
### [wee-httpd](https://github.com/bherrmann7/bb-common/blob/master/wee_httpd.bb)
A wee multi-threaded web server
### [covid19-babashka](https://github.com/agrison/covid19-babashka)
A babashka script to obtain covid-19 related information.
### [bb-spotify](https://github.com/kolharsam/bb-spotify)
Control your spotify player using babashka.
### [lambdaisland/open-source](https://github.com/lambdaisland/open-source)
[Internal
tooling](https://github.com/babashka/babashka/issues/457#issuecomment-636739415)
used by Lambda Island projects. Noteworthy: a [babashka-compatible hiccup
script](https://github.com/lambdaisland/open-source/blob/2cfde3dfb460e72f047bf94e6f5ec7f519c6d7a0/src/lioss/hiccup.clj).
There's also
[subshell](https://github.com/lambdaisland/open-source/blob/master/src/lioss/subshell.clj)
which is like sh/sh, but it inherits stdin/stdout/stderr, so that the user sees
in real time what the subprocess is doing, and can possibly interact with
it. More like how shelling out in a bash script works.
### [dharrigan/spotifyd-notification](https://github.com/dharrigan/spotifyd-notification)
An example of using babashka to show spotifyd notifications via dunst.
### [nextjournal/ssh-github-auth](https://github.com/nextjournal/ssh-github-auth)
A babashka script which uses github auth to fetch SSH public keys. It can be useful to ensure only a certain team of people can access machines with SSH.
### [turtlequeue/setup-babashka](https://github.com/turtlequeue/setup-babashka)
Github Action to install Babashka in your workflows. Useful to run bb scripts in your CI.
### [interdep](https://github.com/rejoice-cljc/interdep)
Manage interdependent dependencies using Clojure's tools.deps and babashka.
### [sha-words](https://github.com/ordnungswidrig/sha-words)
A clojure program to turn a sha hash into list of nouns in a predictable jar.
### [adam-james-v/scripts](https://github.com/adam-james-v/scripts)
A collection of useful scripts. Mainly written with Clojure/babashka
### [oidc-client](https://gist.github.com/holyjak/ad4e1e9b863f8ed57ef0cb6ac6b30494)
Tired of being forced to use the browser every time you need to refresh an OIDC token to authenticate with a backend service? Finally there is a CLI tool for that - the babashka and Docker powered oidc_client.clj.
Upon first invocation it opens up a browser for the OIDC provider login, thereafter it caches the refresh token and uses it as long as it remains valid.
### [jirazzz](https://github.com/rwstauner/jirazzz)
A babashka JIRA client by Randy Stauner
### [Babashka + scittle guestbook](https://github.com/kloimhardt/babashka-scittle-guestbook)
Luminus guestbook example for Babashka + Scittle.
### [bb htmx todo app](https://github.com/prestancedesign/babashka-htmx-todoapp)
Quick example of a todo list SPA using Babashka and htmx.
### [bb aws lambda runtime](https://github.com/tatut/bb-lambda)
AWS Lambda custom runtime for Babashka scripts.
### [bb-github-app](https://github.com/brandonstubbs/bb-github-app)
An example Babashka script that can authenticate as a Github Application,
this example focuses on the checks api.

View file

@ -1,267 +0,0 @@
## Survey November 2020
The raw data from the babashka survey held in November 2020 is now available
[here](https://nl.surveymonkey.com/results/SM-8W8V36DZ7/).
We had about 100 respondents (just below the free tier of SurveyMonkey). Next
time I'll probably switch to Google forms and add an optional contact field,
since I would have liked to go deeper into some of the answers.
Here are the ten questions from the survey followed by the summarized outcome
and my commentary.
Thank you all for taking the time. This provides useful input for the future
development of babashka.
### Q1 What are you using babashka for? Work / hobby
*Outcome:* 75% work, 76% hobby
*My comment:* Most people use it both at work and for their hobby
programming. This is more than I could have hoped for when I started babashka.
### Q2 What features or namespaces in babashka do you use most?
*Outcome:*
```
- clojure.java.shell *******************************
- cheshire.core (json) ****************************
- babashka.curl ************************
- clojure.java.io *********************
- clojure.string ******************
- babashka.process **************
- clojure.edn *******
- clojure.tools.cli *****
- http (in general) ******
- clojure.data.xml ****
- clojure.data.csv ****
- clj-yaml.core ****
- dates / java.time ****
- nREPL server ****
- sql / jdbc ****
- org.httpkit.client ***
- i/o flags ***
- clojure.pprint **
- org.httpkit.server *
- babashka.wait *
- multi-file project *
- docopt *
- ProcessBuilder *
- java.util *
- transit *
- core.async *
- clojure.data *
- aero *
- clojure.zip *
```
*My comment:* Shelling out is a popular thing to do in babashka:
`clojure.java.shell` is the most widely used namespaces. The `babashka.process`
namespace is already used quite a lot despite its recent appearance.
Other popular ways to use babashka:
- http (`babashka.curl` or other)
- JSON (cheshire)
- file interaction (`clojure.java.io`)
- string manipulation (`clojure.string`)
Nothing surprising there for a scripting tool. Closely following is `tools.cli`,
and several other data formats (edn, csv, xml, yaml). The transit format isn't
that widely used from babashka.
Some people are using babashka for interacting with SQL databases. There are two
ways to do this: compile babashka with extra [feature
flags](https://github.com/babashka/babashka/blob/master/doc/build.md#feature-flags)
enabled or use
[babashka-sql-pods](https://github.com/babashka/babashka-sql-pods/).
According to the above outcome, babaska isn't that widely used for small web
applications yet. The `core.async` library had only had one mention although
nobody mentioned it as redundant in question 5.
### Q3 Which babashka pods are you using, if any?
*Outcome:*
```
- sql (mostly postgres) ***************
- file watcher ****
- clj-kondo ***
- kafka **
- tabl **
- tzzh-aws **
- etaoin **
- brisk *
- lanterna *
- tzzh-mail *
- bootleg *
- parcera *
```
*My comment:*
The [sql](https://github.com/babashka/babashka-sql-pods) and
[filewatcher](https://github.com/babashka/pod-babashka-filewatcher) pods are the
most popular, closely followed by the
[clj-kondo](https://github.com/borkdude/clj-kondo/#babashka-pod) pod.
The pod concept isn't widely understood yet. In 2021 I might give a talk, if the
opportunity arises, on babashka pod usage and how to develop them. Pods are an
extra thing to install which may be a barrier for adoption for some. This ties
into the next question.
### Q4 What functionality is currently missing in babashka?
*Outcome:*
```
- easy usage of libs and pods ***********
- java.nio bindings / fs lib ****
- clojure.spec (+ gen) ****
- database / jdbc ***
- raspberry pi support ***
- hiccup **
- compile script to native **
- spire as pod *
- docs and examples *
- packaging *
- ssh *
- nrepl *
- http server *
- easier creation of pods *
- sqlite *
- java-time lib *
- better REPL *
```
*My comment:*
Clearly users want an easier way to include libraries and pods. We are thinking
about that in [this](https://github.com/babashka/babashka/issues/473) issue.
The second most mentioned missing feature was a library around files. This is
work in progress [here](https://github.com/babashka/fs).
### Q5 What features or namespaces in babashka are redundant and could be left out?
Most people did not suggest anything should be removed, maybe also related to
the most given answer to Q9. A few people expressed confusion about multiple
ways of making http requests.
*My comment:* If have attempted to write about HTTP request in babashka
[here](https://book.babashka.org/#_choosing_the_right_client) and
[here](https://github.com/babashka/babashka/wiki/HTTP-client-and-server-considerations).
The summary is that both `babashka.curl` and `org.httpkit.client` have different
optimal use cases. In most small scripting scenarios `babashka.curl` will
do. For making many small requests `org.httpkit.client` is more optimal since it
won't create an OS process. For downloading big files, `babashka.curl` is more
optimal, since there is no way to prevent `org.httpkit.client` from holding the
response into memory all at once.
In the future both of these clients may be superseded by a client based on
`java.net.http` (probably exposed as `babashka.http-client`), but this client
isn't there yet and it may take a while before the Java 11 client space has
crystallized. Meanwhile you will have to do it with either of these
clients. Luckily both clients accept and return Ring-like maps, so upgrading to
the future client should not be hard, unless you are depending on something very
specific. I plan on keeping `babashka.curl` in babashka no matter what, since
it's a very thin layer over `curl` and doesn't complicate the compilation
process of babashka much. There will be a transition period of having both
`org.httpkit.client` and the `java.net.http` client after which
`org.httpkit.client` will be phased out and `babashka.http-client` will be the
recommended HTTP client in babashka.
### Q6 Babashka prints the last value of an expression or script. Should this change?
*Outcome:*
```
- Yes: 7.8%
- No: 69%
- It depends: 23%
```
*My comment:*
The most given answer is: no, keep it this way. Most of the "it depends" answers
said: I don't really care. Some suggested that printing should always be
explicit and maybe should be controlled using a flag.
The reason babashka always prints the list value of a script, unless it is
`nil`, is that in the very beginning, babashka was intended as a Clojure-in-bash
one-liner utility. We only had the `-e` option and not the `-f` option for
executing scripts from disk. When the `-f` option got added, it was handled
exactly the same as `-e`, with the difference that the expression was read from
a file.
Since the majority of people expressed that this should not change, we will keep
it this way. This will also avoid breakage for scripts that depend on
this. Stylistically it might be better to use explicit printing in scripts. If a
script returns `nil`, nothing will get printed for you, which aligns nicely with
how `println` and `prn` behave.
### Q7 When would you use babashka instead of JVM Clojure?
*Outcome:*
The majority of people use babashka as a replacement for `bash`, `python` or
`jq`. The fast startup is the main reason they favor it over the JVM when
writing small and short-running scripts that are cross-platform. In this
scenario babashka is used for CLI utilities, ETL (data processing) scripts,
automation / CI / devops and scripts ran from editors like emacs and vim. Some
people use it in places where they want to avoid or can't have a JVM
installation or in memory constrained environments. Some people answered:
whenever I can.
*My comment:*
Babashka's original goal was to be a Clojure replacement for shell scripting and
based on the answers, it seems to have pulled that off.
### Q8 What operating system do you run babashka on?
*Outcome:*
```
- Linux: 80%
- macOS: 58%
- Windows: 16%
- Other: 2% (raspberry if possible, AWS Lambda)
```
*My comment:*
It's interesting to compare the outcome of this question with the answers to
"what is your primary development OS" in the Clojure 2020 survey
[here](https://clojure.org/news/2020/02/20/state-of-clojure-2020#_deep_dives).
Note that I didn't ask about the development OS but where scripts are run and
multiple answers were allowed.
### Q9 Is the binary size of the bb executable important to you?
*Outcome:*
```
- Yes: 13%
- No: 87%
```
*My comment:*
The people who care about binary size report that it should not grow beyond the
range of 10mb and 512mb. But most people don't care about it.
I do personally care about it from the perspective of not cluttering babashka
unnecessarily during its lifetime. Related, adding more stuff challenges GraalVM
compile time and memory usage during compilation. Hitting the limit on free CI
might mean I will have to charge for building binaries in the future or come up
with some business model to finance the builds.
### Q10 Any other feedback on babashka?
*Outcome:*
Lots of encouraging words. Thank you all!

View file

@ -1,570 +0,0 @@
# Examples
- [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)
- [HTTP server](#http-server)
- [Torrent viewer](#torrent-viewer)
- [cprop.clj](#cpropclj)
- [fzf](#fzf)
- [digitalocean-ping.clj](#digitalocean-pingclj)
- [download-aliases.clj](#download-aliasesclj)
- [Is TTY?](#is-tty)
- [normalize-keywords.clj](#normalize-keywordsclj)
- [Check stdin for data](#check-stdin-for-data)
- [Using org.clojure/data.xml](#using-orgclojuredataxml)
- [Simple logger](#simple-logger)
- [Using GZip streams (memo utility)](#using-gzip-streams-to-make-a-note-utility)
- [Pretty-printing mySQL results](#pretty-printing-mysql-results)
- [Single page application with Babashka + htmx](#single-page-application-with-babashka--htmx)
- [Wikipedia translation](#wikipedia-translation)
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 []
(-> (sh "curl" "https://api.github.com/repos/babashka/babashka/tags")
: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
See [examples/tree.clj](https://github.com/babashka/babashka/blob/master/examples/tree.clj).
``` 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
See [examples/outdated.clj](https://github.com/babashka/babashka/blob/master/examples/outdated.clj).
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
See [examples/pst.clj](https://github.com/babashka/babashka/blob/master/examples/pst.clj)
## Tiny http server
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)
Original by [@souenzzo](https://gist.github.com/souenzzo/a959a4c5b8c0c90df76fe33bb7dfe201)
## Print random docstring
See [examples/random_doc.clj](https://github.com/babashka/babashka/blob/master/examples/random_doc.clj)
``` 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
FROM babashka/babashka
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
[examples/notes.clj](https://github.com/babashka/babashka/blob/master/examples/notes.clj). This
is a variation on the
[http-server](https://github.com/babashka/babashka/#tiny-http-server)
example. If you get prompted with a login, use `admin`/`admin`.
## which
The `which` command re-implemented in Clojure. See
[examples/which.clj](https://github.com/babashka/babashka/blob/master/examples/which.clj).
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
[pom_version_get.clj](pom_version_get.clj). Written by [@wilkerlucio](https://github.com/wilkerlucio).
See [pom_version_get_xml_zip.clj](pom_version_get_xml_zip.clj) for how to do the same using zippers.
Also see [pom_version_set.clj](pom_version_set.clj) to set the pom version.
## 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 |
|----------------------------|--------------------------|------------------------------------|-----------|-----------|
| 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
...
```
## Invoke vim inside a script
See [examples/vim.clj](vim.clj).
## Portal
This script uses [djblue/portal](https://github.com/djblue/portal/) for inspecting EDN, JSON, XML or YAML files.
Example usage:
``` shell
$ examples/portal.clj ~/git/clojure/pom.xml
```
See [portal.clj](portal.clj).
## Image viewer
Opens browser window and lets user navigate through images of all sub-directories.
Example usage:
``` shell
$ examples/image-viewer.clj
```
See [image-viewer.clj](image-viewer.clj).
## HTTP Server
Opens browser window and lets user navigate through filesystem, similar to
`python3 -m http.server`.
Example usage:
``` shell
$ examples/http-server.clj
```
See [http-server.clj](http-server.clj).
## Torrent viewer
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).
## [cprop.clj](cprop.clj)
This script uses [tolitius/cprop](https://github.com/tolitius/cprop) library.
See [cprop.clj](cprop.clj)
Example usage:
```shell
$ ( cd examples && bb cprop.clj )
```
## [fzf](fzf.clj)
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
```
## [digitalocean-ping.clj](digitalocean-ping.clj)
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
```
## [download-aliases.clj](download-aliases.clj)
Download deps for all aliases in a deps.edn project.
## [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
```
## [normalize-keywords.clj](normalize-keywords.clj)
Provide a Clojure file to the script and it will print the Clojure file with
auto-resolved keywords normalized to fully qualified ones without double colons:
`::set/foo` becomes `:clojure.set/foo`.
``` 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]
```
## 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
```
## 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
```
## 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
```
## 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 |
```
## 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).
## 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

View file

@ -1,12 +0,0 @@
datomic.url=datomic:sql://?jdbc:postgresql://localhost:5432/datomic?user=datomic&password=datomic
source.account.rabbit.host=localhost
aws.access-key=super secret key
aws.secret_key=super secret s3cr3t!!!
aws.region=us-east-2
io.http.pool.conn_timeout=42
io.http.pool.max_per_route=42
other_things=1,2,3,4,5,6,7

View file

@ -1,56 +0,0 @@
#!/usr/bin/env bb
(require '[babashka.classpath :refer [add-classpath]])
(require '[clojure.java.shell :refer [sh]])
(require '[clojure.pprint :refer [pprint]])
(def deps '{:deps {cprop {:mvn/version "0.1.17"}}})
(def cp (:out (sh "clojure" "-Spath" "-Sdeps" (str deps))))
(add-classpath cp)
(require '[cprop.core :refer [load-config]])
(require '[cprop.source :refer [from-props-file]])
;; Load sample configuration from the file system
(def conf (load-config :file "cprop.edn"))
;; Print the configuration we just read in
(pprint conf)
;;=>
#_{:datomic {:url "CHANGE ME"}
:aws {:access-key "AND ME"
:secret-key "ME TOO"
:region "FILL ME IN AS WELL"
:visiblity-timeout-sec 30
:max-conn 50
:queue "cprop-dev"}
:io {:http {:pool {:socket-timeout 600000
:conn-timeout :I-SHOULD-BE-A-NUMBER
:conn-req-timeout 600000
:max-total 200
:max-per-route :ME-ALSO}}}
:other-things ["I am a vector and also like to place the substitute game"]}
(let [conf (load-config
:file "cprop.edn"
:merge [(from-props-file "cprop-override.properties")])]
(pprint conf))
;;=>
#_{:datomic
{:url "datomic:sql://?jdbc:postgresql://localhost:5432/datomic?user=datomic&password=datomic"},
:aws
{:access-key "super secret key",
:secret-key "super secret s3cr3t!!!",
:region "us-east-2",
:visiblity-timeout-sec 30,
:max-conn 50,
:queue "cprop-dev"},
:io
{:http
{:pool
{:socket-timeout 600000,
:conn-timeout 42,
:conn-req-timeout 600000,
:max-total 200,
:max-per-route 42}}},
:other-things ["1" "2" "3" "4" "5" "6" "7"]}

View file

@ -1,26 +0,0 @@
#_
{:datomic
{:url "datomic:sql://?jdbc:postgresql://localhost:5432/datomic?user=datomic&password=datomic"}
:source
{:account
{:rabbit
{:host "127.0.0.1"
:port 5672
:vhost "/z-broker"
:username "guest"
:password "guest"}}}
:answer 42}
{:datomic {:url "CHANGE ME"}
:aws {:access-key "AND ME"
:secret-key "ME TOO"
:region "FILL ME IN AS WELL"
:visiblity-timeout-sec 30
:max-conn 50
:queue "cprop-dev"}
:io {:http {:pool {:socket-timeout 600000
:conn-timeout :I-SHOULD-BE-A-NUMBER
:conn-req-timeout 600000
:max-total 200
:max-per-route :ME-ALSO}}}
:other-things ["I am a vector and also like to place the substitute game"]}

View file

@ -1,11 +0,0 @@
(ns db-who
(:require [clojure.java.shell :as shell]
[clojure.string :as str]
[clojure.pprint :as pp]))
(defn tsv->maps [tsv]
(let [lines (str/split-lines tsv)
[headers & rows] (map #(str/split % #"\t") lines)]
(map #(zipmap headers %) rows)))
(-> (shell/sh "mysql" "--column-names" "-e" "select user, program_name from sys.session;")
:out tsv->maps pp/print-table)

View file

@ -1,30 +0,0 @@
#!/usr/bin/env bb
(require '[babashka.curl :as curl]
'[clojure.java.shell :as shell]
'[clojure.string :as str])
(def url "http://speedtest-ams2.digitalocean.com/")
(def get-endpoints
(let [{:keys [body]} (curl/get url)]
(re-seq #"speedtest\-.+.digitalocean.com" body)))
(defn get-average [result]
(-> result
str/split-lines
last
(str/split #"/")
(get 4)))
(def mac? (str/starts-with? (System/getProperty "os.name") "Mac"));; TODO: test on Windows
(def timeout-arg (if mac? "-t3" "-w3"))
(defn ping-result [endpoint]
(let [{:keys [out]} (shell/sh "ping" "-c5" timeout-arg endpoint)
msg (str endpoint " => " (get-average out) "ms")]
(println msg)))
(doseq [endpoint get-endpoints]
(ping-result endpoint))

View file

@ -1,16 +0,0 @@
#!/usr/bin/env bb
(require '[clojure.edn :as edn]
'[clojure.string :as str])
(def edn (edn/read-string (slurp "deps.edn")))
(def aliases (keys (:aliases edn)))
(require '[babashka.deps :as deps])
(def cmd ["-P" (str "-A" (str/join aliases))])
(println "Downloading deps using:" cmd)
(deps/clojure cmd)

View file

@ -1,9 +0,0 @@
(require '[babashka.process :as p])
(defn fzf [s]
(let [proc (p/process ["fzf" "-m"]
{:in s :err :inherit
:out :string})]
(:out @proc)))
(fzf (slurp *in*))

View file

@ -1,88 +0,0 @@
#!/usr/bin/env bb
;; $ examples/hsqldb_unused_vars.clj src
;; | :VARS/NS | :VARS/NAME | :VARS/FILENAME | :VARS/ROW | :VARS/COL |
;; |----------------------------+--------------------------+------------------------------------+-----------+-----------|
;; | 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 |
(ns hsqldb-unused-vars
(:require
[babashka.pods :as pods]
[clojure.pprint :refer [print-table]]))
(pods/load-pod "pod-babashka-hsqldb")
(require '[pod.babashka.hsqldb :as jdbc]
'[pod.babashka.hsqldb.sql :as sql])
(pods/load-pod "clj-kondo")
(require '[pod.borkdude.clj-kondo :as clj-kondo])
(def db "jdbc:hsqldb:mem:testdb;sql.syntax_mys=true")
(defn query [q]
(jdbc/execute! db [q]))
(defn create-db! []
(query "create table vars (
ns text
, name text
, filename text
, row int
, col int )")
(query "create table var_usages (
\"from\" text
, \"to\" text
, name text
, filename text
, row int
, col int )"))
(defn parse-int [^String x]
(when x
(Integer. x)))
(defn insert-vars! [var-definitions]
(sql/insert-multi! db :vars [:ns :name :filename :row :col]
(map (juxt (comp str :ns)
(comp str :name)
:filename
(comp parse-int :row)
(comp parse-int :col))
var-definitions)))
(defn insert-var-usages! [var-usages]
(sql/insert-multi! db :var_usages ["\"from\"" "\"to\"" :name :filename :row :col]
(map (juxt (comp str :from)
(comp str :to)
(comp str :name)
:filename
(comp parse-int :row)
(comp parse-int :col))
var-usages)))
(defn analysis->db [paths]
(let [results (clj-kondo/run! {:lint paths
:config {:output {:analysis true}}})
analysis (:analysis results)
{:keys [:var-definitions :var-usages]} analysis]
(insert-vars! var-definitions)
(insert-var-usages! var-usages)))
(create-db!)
(analysis->db *command-line-args*)
(def unused-vars "
select distinct * from vars v
where (v.ns, v.name) not in
(select vu.\"to\", vu.name from var_usages vu)")
(print-table (query unused-vars))

View file

@ -1,240 +0,0 @@
#!/usr/bin/env bb
;; Source: https://github.com/prestancedesign/babashka-htmx-todoapp
(require '[org.httpkit.server :as srv]
'[clojure.java.browse :as browse]
'[clojure.core.match :refer [match]]
'[clojure.pprint :refer [cl-format]]
'[clojure.string :as str]
'[hiccup.core :as h])
(import '[java.net URLDecoder])
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Config
;;;;;;;;;;;;;;;;;;;;;;;;;;
(def port 3000)
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Mimic DB (in-memory)
;;;;;;;;;;;;;;;;;;;;;;;;;;
(def todos (atom (sorted-map 1 {:id 1 :name "Taste htmx with Babashka" :done true}
2 {:id 2 :name "Buy a unicorn" :done false})))
(def todos-id (atom (count @todos)))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; "DB" queries
;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn add-todo! [name]
(let [id (swap! todos-id inc)]
(swap! todos assoc id {:id id :name name :done false})))
(defn toggle-todo! [id]
(swap! todos update-in [(Integer. id) :done] not))
(defn remove-todo! [id]
(swap! todos dissoc (Integer. id)))
(defn filtered-todo [filter-name todos]
(case filter-name
"active" (remove #(:done (val %)) todos)
"completed" (filter #(:done (val %)) todos)
"all" todos
todos))
(defn get-items-left []
(count (remove #(:done (val %)) @todos)))
(defn todos-completed []
(count (filter #(:done (val %)) @todos)))
(defn remove-all-completed-todo []
(reset! todos (into {} (remove #(:done (val %)) @todos))))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Template and components
;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn todo-item [{:keys [id name done]}]
[:li {:id (str "todo-" id)
:class (when done "completed")}
[:div.view
[:input.toggle {:hx-patch (str "/todos/" id)
:type "checkbox"
:checked done
:hx-target (str "#todo-" id)
:hx-swap "outerHTML"}]
[:label {:hx-get (str "/todos/edit/" id)
:hx-target (str "#todo-" id)
:hx-swap "outerHTML"} name]
[:button.destroy {:hx-delete (str "/todos/" id)
:_ (str "on htmx:afterOnLoad remove #todo-" id)}]]])
(defn todo-list [todos]
(for [todo todos]
(todo-item (val todo))))
(defn todo-edit [id name]
[:form {:hx-post (str "/todos/update/" id)}
[:input.edit {:type "text"
:name "name"
:value name}]])
(defn item-count []
(let [items-left (get-items-left)]
[:span#todo-count.todo-count {:hx-swap-oob "true"}
[:strong items-left] (cl-format nil " item~p " items-left) "left"]))
(defn todo-filters [filter]
[:ul#filters.filters {:hx-swap-oob "true"}
[:li [:a {:hx-get "/?filter=all"
:hx-push-url "true"
:hx-target "#todo-list"
:class (when (= filter "all") "selected")} "All"]]
[:li [:a {:hx-get "/?filter=active"
:hx-push-url "true"
:hx-target "#todo-list"
:class (when (= filter "active") "selected")} "Active"]]
[:li [:a {:hx-get "/?filter=completed"
:hx-push-url "true"
:hx-target "#todo-list"
:class (when (= filter "completed") "selected")} "Completed"]]])
(defn clear-completed-button []
[:button#clear-completed.clear-completed
{:hx-delete "/todos"
:hx-target "#todo-list"
:hx-swap-oob "true"
:hx-push-url "/"
:class (when-not (pos? (todos-completed)) "hidden")}
"Clear completed"])
(defn template [filter]
(str
"<!DOCTYPE html>"
(h/html
[:head
[:meta {:charset "UTF-8"}]
[:title "Htmx + Babashka"]
[:link {:href "https://unpkg.com/todomvc-app-css@2.4.1/index.css" :rel "stylesheet"}]
[:script {:src "https://unpkg.com/htmx.org@1.5.0/dist/htmx.min.js" :defer true}]
[:script {:src "https://unpkg.com/hyperscript.org@0.8.1/dist/_hyperscript.min.js" :defer true}]]
[:body
[:section.todoapp
[:header.header
[:h1 "todos"]
[:form
{:hx-post "/todos"
:hx-target "#todo-list"
:hx-swap "beforeend"
:_ "on htmx:afterOnLoad set #txtTodo.value to ''"}
[:input#txtTodo.new-todo
{:name "todo"
:placeholder "What needs to be done?"
:autofocus ""}]]]
[:section.main
[:input#toggle-all.toggle-all {:type "checkbox"}]
[:label {:for "toggle-all"} "Mark all as complete"]]
[:ul#todo-list.todo-list
(todo-list (filtered-todo filter @todos))]
[:footer.footer
(item-count)
(todo-filters filter)
(clear-completed-button)]]
[:footer.info
[:p "Click to edit a todo"]
[:p "Created by "
[:a {:href "https://twitter.com/PrestanceDesign"} "Michaël Sλlihi"]]
[:p "Part of "
[:a {:href "http://todomvc.com"} "TodoMVC"]]]])))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Helpers
;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn parse-body [body]
(-> body
slurp
(str/split #"=")
second
URLDecoder/decode))
(defn parse-query-string [query-string]
(when query-string
(-> query-string
(str/split #"=")
second)))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Handlers
;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn app-index [{:keys [query-string headers]}]
(let [filter (parse-query-string query-string)
ajax-request? (get headers "hx-request")]
(if (and filter ajax-request?)
(h/html (todo-list (filtered-todo filter @todos))
(todo-filters filter))
(template filter))))
(defn add-item [{body :body}]
(let [name (parse-body body)
todo (add-todo! name)]
(h/html (todo-item (val (last todo)))
(item-count))))
(defn edit-item [id]
(let [{:keys [id name]} (get @todos (Integer. id))]
(h/html (todo-edit id name))))
(defn update-item [{body :body} id]
(let [name (parse-body body)
todo (swap! todos assoc-in [(Integer. id) :name] name)]
(h/html (todo-item (get todo (Integer. id))))))
(defn patch-item [id]
(let [todo (toggle-todo! id)]
(h/html (todo-item (get todo (Integer. id)))
(item-count)
(clear-completed-button))))
(defn delete-item [id]
(remove-todo! id)
(h/html (item-count)))
(defn clear-completed []
(remove-all-completed-todo)
(h/html (todo-list @todos)
(item-count)
(clear-completed-button)))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Routes
;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn routes [{:keys [request-method uri] :as req}]
(let [path (vec (rest (str/split uri #"/")))]
(match [request-method path]
[:get []] {:body (app-index req)}
[:get ["todos" "edit" id]] {:body (edit-item id)}
[:post ["todos"]] {:body (add-item req)}
[:post ["todos" "update" id]] {:body (update-item req id)}
[:patch ["todos" id]] {:body (patch-item id)}
[:delete ["todos" id]] {:body (delete-item id)}
[:delete ["todos"]] {:body (clear-completed)}
:else {:status 404 :body "Error 404: Page not found"})))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Server
;;;;;;;;;;;;;;;;;;;;;;;;;;
(when (= *file* (System/getProperty "babashka.file"))
(let [url (str "http://localhost:" port "/")]
(srv/run-server #'routes {:port port})
(println "serving" url)
(browse/browse-url url)
@(promise)))

View file

@ -1,196 +0,0 @@
#!/usr/bin/env bb
#_" -*- mode: clojure; -*-"
;; Source: https://gist.github.com/holyjak/36c6284c047ffb7573e8a34399de27d8
;; Based on https://github.com/babashka/babashka/blob/master/examples/image-viewer.clj
(ns http-server
(:require [babashka.fs :as fs]
[clojure.java.browse :as browse]
[clojure.string :as str]
[clojure.tools.cli :refer [parse-opts]]
[hiccup2.core :as html]
[org.httpkit.server :as server])
(:import [java.net URLDecoder URLEncoder]))
(def cli-options [["-p" "--port PORT" "Port for HTTP server" :default 8090 :parse-fn #(Integer/parseInt %)]
["-d" "--dir DIR" "Directory to serve files from" :default "."]
["-h" "--help" "Print usage info"]])
(def parsed-args (parse-opts *command-line-args* cli-options))
(def opts (:options parsed-args))
(cond
(:help opts)
(do (println "Start a http server for static files in the given dir. Usage:\n" (:summary parsed-args))
(System/exit 0))
(:errors parsed-args)
(do (println "Invalid arguments:\n" (str/join "\n" (:errors parsed-args)))
(System/exit 1))
:else
:continue)
(def port (:port opts))
(def dir (fs/path (:dir opts)))
(assert (fs/directory? dir) (str "The given dir `" dir "` is not a directory."))
;; A simple mime type utility from https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/mime_type.clj
(def ^{:doc "A map of file extensions to mime-types."}
default-mime-types
{"7z" "application/x-7z-compressed"
"aac" "audio/aac"
"ai" "application/postscript"
"appcache" "text/cache-manifest"
"asc" "text/plain"
"atom" "application/atom+xml"
"avi" "video/x-msvideo"
"bin" "application/octet-stream"
"bmp" "image/bmp"
"bz2" "application/x-bzip"
"class" "application/octet-stream"
"cer" "application/pkix-cert"
"crl" "application/pkix-crl"
"crt" "application/x-x509-ca-cert"
"css" "text/css"
"csv" "text/csv"
"deb" "application/x-deb"
"dart" "application/dart"
"dll" "application/octet-stream"
"dmg" "application/octet-stream"
"dms" "application/octet-stream"
"doc" "application/msword"
"dvi" "application/x-dvi"
"edn" "application/edn"
"eot" "application/vnd.ms-fontobject"
"eps" "application/postscript"
"etx" "text/x-setext"
"exe" "application/octet-stream"
"flv" "video/x-flv"
"flac" "audio/flac"
"gif" "image/gif"
"gz" "application/gzip"
"htm" "text/html"
"html" "text/html"
"ico" "image/x-icon"
"iso" "application/x-iso9660-image"
"jar" "application/java-archive"
"jpe" "image/jpeg"
"jpeg" "image/jpeg"
"jpg" "image/jpeg"
"js" "text/javascript"
"json" "application/json"
"lha" "application/octet-stream"
"lzh" "application/octet-stream"
"mov" "video/quicktime"
"m3u8" "application/x-mpegurl"
"m4v" "video/mp4"
"mjs" "text/javascript"
"mp3" "audio/mpeg"
"mp4" "video/mp4"
"mpd" "application/dash+xml"
"mpe" "video/mpeg"
"mpeg" "video/mpeg"
"mpg" "video/mpeg"
"oga" "audio/ogg"
"ogg" "audio/ogg"
"ogv" "video/ogg"
"pbm" "image/x-portable-bitmap"
"pdf" "application/pdf"
"pgm" "image/x-portable-graymap"
"png" "image/png"
"pnm" "image/x-portable-anymap"
"ppm" "image/x-portable-pixmap"
"ppt" "application/vnd.ms-powerpoint"
"ps" "application/postscript"
"qt" "video/quicktime"
"rar" "application/x-rar-compressed"
"ras" "image/x-cmu-raster"
"rb" "text/plain"
"rd" "text/plain"
"rss" "application/rss+xml"
"rtf" "application/rtf"
"sgm" "text/sgml"
"sgml" "text/sgml"
"svg" "image/svg+xml"
"swf" "application/x-shockwave-flash"
"tar" "application/x-tar"
"tif" "image/tiff"
"tiff" "image/tiff"
"ts" "video/mp2t"
"ttf" "font/ttf"
"txt" "text/plain"
"webm" "video/webm"
"wmv" "video/x-ms-wmv"
"woff" "font/woff"
"woff2" "font/woff2"
"xbm" "image/x-xbitmap"
"xls" "application/vnd.ms-excel"
"xml" "text/xml"
"xpm" "image/x-xpixmap"
"xwd" "image/x-xwindowdump"
"zip" "application/zip"})
;; https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/mime_type.clj
(defn- filename-ext
"Returns the file extension of a filename or filepath."
[filename]
(if-let [ext (second (re-find #"\.([^./\\]+)$" filename))]
(str/lower-case ext)))
;; https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/mime_type.clj
(defn ext-mime-type
"Get the mimetype from the filename extension. Takes an optional map of
extensions to mimetypes that overrides values in the default-mime-types map."
([filename]
(ext-mime-type filename {}))
([filename mime-types]
(let [mime-types (merge default-mime-types mime-types)]
(mime-types (filename-ext filename)))))
(defn index [f]
(let [files (map #(str (.relativize dir %))
(fs/list-dir f))]
{:body (-> [:html
[:head
[:meta {:charset "UTF-8"}]
[:title (str "Index of `" f "`")]]
[:body
[:h1 "Index of " [:code (str f)]]
[:ul
(for [child files]
[:li [:a {:href (URLEncoder/encode (str child))} child
(when (fs/directory? (fs/path dir child)) "/")]])]
[:hr]
[:footer {:style {"text-aling" "center"}} "Served by http-server.clj"]]]
html/html
str)}))
(defn body [path]
{:headers {"Content-Type" (ext-mime-type (fs/file-name path))}
:body (fs/file path)})
(server/run-server
(fn [{:keys [:uri]}]
(let [f (fs/path dir (str/replace-first (URLDecoder/decode uri) #"^/" ""))
index-file (fs/path f "index.html")]
(cond
(and (fs/directory? f) (fs/readable? index-file))
(body index-file)
(fs/directory? f)
(index f)
(fs/readable? f)
(body f)
:else
{:status 404 :body (str "Not found `" f "` in " dir)})))
{:port port})
(println "Starting http server at " port "for" (str dir))
(browse/browse-url (format "http://localhost:%s/" port))
@(promise)

View file

@ -1,63 +0,0 @@
#!/usr/bin/env bb
;; This example creates a file serving web server from scratch.
;; It accepts a single connection from a browser and serves content to the connected browser
;; after the connection times out, this script will serve no more.
;; Also see notes.clj for another web app example.
;; Note that babashka comes with org.httpkit.server now, so you don't need to
;; build an http server from scratch anymore. We leave this script here for educational purposes.
(import (java.net ServerSocket))
(require '[clojure.java.io :as io]
'[clojure.string :as string])
(with-open [server-socket (new ServerSocket 8080)
client-socket (.accept server-socket)]
(loop []
(let [out (io/writer (.getOutputStream client-socket))
in (io/reader (.getInputStream client-socket))
[req-line & _headers] (loop [headers []]
(let [line (.readLine in)]
(if (string/blank? line)
headers
(recur (conj headers line)))))
[_ _ path _] (re-find #"([^\s]+)\s([^\s]+)\s([^\s]+)" req-line)
f (io/file (format "./%s" path))
status (if (.exists f)
200
404)
html (fn html-fn [tag & body]
(let [attrs? (map? (first body))
attrs-str (str (when attrs?
(format " %s" (string/join " " (for [[k v] (first body)]
(format "%s=%s" (name k) (name v)))))))]
(format "<%s%s>%s</%s>"
(name tag)
attrs-str
(string/join (if attrs? (rest body) body))
(name tag))))
body (cond
(not (.exists f)) (str path " not exist")
(.isFile f) (slurp f)
(.isDirectory f) (format "<!DOCTYPE html>\n%s"
(html :html
(html :head
(html :title path))
(html :body
(html :h1 path)
(html :tt
(apply html :pre
(for [i (.list f)]
(html :div
(html
:a
{:href
(str (when (> (count path) 1) path) "/" i)} i)))))))))]
(prn path)
(.write out (format "HTTP/1.1 %s OK\r\nContent-Length: %s\r\n\r\n%s"
status
(count body)
body))
(.flush out))
(recur)))

View file

@ -1,15 +0,0 @@
(ns examples.httpkit-server
(:require [clojure.pprint :refer [pprint]]
[org.httpkit.server :as server]))
(defn handler [req]
(let [reply (str (slurp "examples/httpkit_server.clj")
"---\n\n"
(with-out-str (pprint (dissoc req
:headers
:async-channel))))]
{:body reply}))
(server/run-server handler {:port 8090})
@(promise) ;; wait until SIGINT

View file

@ -1,81 +0,0 @@
#!/usr/bin/env bb
(ns image-viewer
(:require [clojure.java.browse :as browse]
[clojure.java.io :as io]
[clojure.string :as str]
[clojure.tools.cli :refer [parse-opts]]
[org.httpkit.server :as server])
(:import [java.net URLDecoder URLEncoder]))
(def cli-options [["-p" "--port PORT" "Port for HTTP server" :default 8090 :parse-fn #(Integer/parseInt %)]
["-d" "--dir DIR" "Directory to scan for images" :default "."]])
(def opts (:options (parse-opts *command-line-args* cli-options)))
(def port (:port opts))
(def dir (:dir opts))
(def images
(filter #(and (.isFile %)
(let [name (.getName %)
ext (some-> (str/split name #"\.")
last
str/lower-case)]
(contains? #{"jpg" "jpeg" "png" "gif" "svg"} ext)))
(file-seq (io/file dir))))
(def image-count (count images))
(defn page [n]
(let [prev (max 0 (dec n))
next (min (inc n) (dec image-count))
file-path (.getCanonicalPath (nth images n))
encoded-file-path (URLEncoder/encode file-path)]
{:body (format "
<!DOCTYPE html>
<html>
<head>
<meta charset=\"utf-8\"/>
<script>
window.onkeydown=function(e) {
switch (e.key) {
case \"ArrowLeft\":
window.location.href=\"/%s\"; break;
case \"ArrowRight\":
window.location.href=\"/%s\"; break;
}
}
</script>
</head>
<body>
Navigation: use left/right arrow keys
<p>%s</p>
<div>
<img style=\"max-height: 90vh; margin: auto; display: block;\" src=\"assets/%s\"/>
</div>
<div>
</div>
</body>
</html>" prev next file-path encoded-file-path)}))
(server/run-server
(fn [{:keys [:uri]}]
(cond
;; serve the file
(str/starts-with? uri "/assets")
(let [f (io/file (-> (str/replace uri "assets" "")
(URLDecoder/decode)))]
{:body f})
;; serve html
(re-matches #"/[0-9]+" uri)
(let [n (-> (str/replace uri "/" "")
(Integer/parseInt))]
(page n))
;; favicon.ico, etc
:else
{:status 404}))
{:port port})
(browse/browse-url (format "http://localhost:%s/0" port))
@(promise)

View file

@ -1,21 +0,0 @@
#!/usr/bin/env bb
(ns is-tty
(:require [babashka.process :as p]))
(defn- is-tty
[fd key]
(-> ["test" "-t" (str fd)]
(p/process {key :inherit :env {}})
deref
:exit
(= 0)))
(defn in-is-tty? [] (is-tty 0 :in))
(defn out-is-tty? [] (is-tty 1 :out))
(defn err-is-tty? [] (is-tty 2 :err))
(when (= *file* (System/getProperty "babashka.file"))
(println "STDIN is TTY?:" (in-is-tty?))
(println "STDOUT is TTY?:" (out-is-tty?))
(println "STDERR is TTY?:" (err-is-tty?)))

View file

@ -1,11 +0,0 @@
(ns logger)
(defmacro log [& msgs]
(let [m (meta &form)
_ns (ns-name *ns*) ;; can also be used for logging
file *file*]
`(binding [*out* *err*] ;; or bind to (io/writer log-file)
(println (str ~file ":"
~(:line m) ":"
~(:column m))
~@msgs))))

View file

@ -1,19 +0,0 @@
#!/usr/bin/env bb
;; usage: ls_jar.clj borkdude/sci 0.0.13-alpha.24
(require '[clojure.java.io :as io]
'[clojure.string :as str])
(let [file (if (= 1 (count *command-line-args*))
(io/file (first *command-line-args*))
(let [lib (first *command-line-args*)
[_org lib-name] (str/split lib #"/")
version (second *command-line-args*)]
(io/file (System/getProperty "user.home")
(format ".m2/repository/%s/%s/%s-%s.jar"
(str/replace lib "." (System/getProperty "file.separator"))
version
lib-name version))))]
(doseq [e (enumeration-seq
(.entries (java.util.jar.JarFile. file)))]
(println (.getName e))))

View file

@ -1,16 +0,0 @@
#!/usr/bin/env bb
(defn stash [file-name]
(with-open [os (java.util.zip.GZIPOutputStream. (io/output-stream (str "/tmp/" file-name ".zip")))]
(.write os (.getBytes (slurp *in*)))
(.finish os))
'ok)
(defn unstash [file-name]
(print (slurp (java.util.zip.GZIPInputStream. (io/input-stream (str "/tmp/" file-name ".zip"))))))
(let [[action stash-name] *command-line-args*]
(case action
"put" (stash stash-name)
"get" (unstash stash-name)
(println "Invalid op:" action)))

View file

@ -1,44 +0,0 @@
#!/usr/bin/env bb
;; Simple example of accessing mysql's data via the command line, then turnning around and dumping that data as a table.
;; (map2arg-- mdb "-h" :host) => "-hlocalhost"
(defn map2arg-
"Create mysql command line argument from connection map"
[mdb arg key]
(str arg (get mdb key)))
(defn make-mysql-command-
"Create mysql command line using connection map and statement"
[mdb statement]
["mysql" (map2arg- mdb "-h" :host) (map2arg- mdb "-u" :user) (map2arg- mdb "-p" :password) (:dbname mdb) "--column-names" "-e" statement ])
(defn query
"Executes a query agatinst the command line mysql. Return is a vector of maps with populated with each row."
[ mdb statement ]
(let [
mysql-command (make-mysql-command- mdb statement)
table-as-str (:out (apply shell/sh mysql-command))
table-as-lines (str/split-lines table-as-str)
table-headers (str/split (first table-as-lines) #"\t")
table-as-maps (map #(zipmap table-headers (str/split %1 #"\t")) (rest table-as-lines))
]
table-as-maps
))
;; Typical connection specifier
(def mdb {:dbtype "mysql" :dbname "corp" :host "localhost" :user "dba" :password "dba"})
;; extracted rows
(def rows (query mdb "select TABLE_NAME, ENGINE from information_schema.tables limit 3"))
;; display the data!
(clojure.pprint/print-table rows)
;; Tells emacs to jump into clojure mode.
;; Local Variables:
;; mode: clojure
;; End:

View file

@ -1,43 +0,0 @@
(ns normalize-keywords
(:require [babashka.pods :as pods]
[clojure.java.io :as io]
[rewrite-clj.node :as node]
[rewrite-clj.zip :as z]))
(pods/load-pod 'clj-kondo/clj-kondo "2022.11.02")
(require '[pod.borkdude.clj-kondo :as clj-kondo])
(def code (first *command-line-args*))
(defn findings [file-path]
(->> (clj-kondo/run! {:lint [file-path]
:config {:output {:analysis {:keywords true}}}})
:analysis
:keywords
(filter (some-fn :alias :auto-resolved))))
(defn finding->keyword [{:keys [:ns :name]}]
(keyword (str ns) (str name)))
(defn remove-locs [zloc findings]
(loop [zloc zloc
findings (seq findings)]
(if findings
(let [{:keys [:row :col] :as finding} (first findings)
node (z/node zloc)
m (meta node)]
(if (and (= row (:row m))
(= col (:col m)))
(let [k (finding->keyword finding)
zloc (z/replace zloc (node/coerce k))]
(recur zloc (next findings)))
(recur (z/next zloc) findings)))
(str (z/root zloc)))))
(doseq [f (file-seq (io/file code))
:when (re-find #"\.clj[cdsx]?$" (str f))
:let [file-path (str f)]]
(when-let [findings' (findings file-path)]
(prn (format "Rewriting %s" file-path))
(spit f (remove-locs (z/of-file file-path) findings'))))

View file

@ -1,115 +0,0 @@
#!/usr/bin/env bb
(require '[clojure.java.io :as io]
'[clojure.pprint :refer [pprint]]
'[clojure.string :as str]
'[org.httpkit.server :as server])
(def debug? true)
(def user "admin")
(def password "admin")
(def base64 (-> (.getEncoder java.util.Base64)
(.encodeToString (.getBytes (str user ":" password)))))
(def notes-file (io/file (System/getProperty "user.home") ".notes" "notes.txt"))
(def file-lock (Object.))
(defn write-note! [note]
(locking file-lock
(io/make-parents notes-file)
(spit notes-file (str note "\n") :append true)))
;; hiccup-like
(defn html [v]
(cond (vector? v)
(let [tag (first v)
attrs (second v)
attrs (when (map? attrs) attrs)
elts (if attrs (nnext v) (next v))
tag-name (name tag)]
(format "<%s%s>%s</%s>\n" tag-name (html attrs) (html elts) tag-name))
(map? v)
(str/join ""
(map (fn [[k v]]
(format " %s=\"%s\"" (name k) v)) v))
(seq? v)
(str/join " " (map html v))
:else (str v)))
;; the home page
(defn home-response [session-id]
{:status 200
:headers {"Set-Cookie" (str "notes-id=" session-id)}
:body (str
"<!DOCTYPE html>\n"
(html
[:html
[:head
[:title "Notes"]]
[:body
[:h1 "Notes"]
[:pre (when (.exists notes-file)
(slurp notes-file))]
[:form {:action "/" :method "post"}
[:input {:type "text" :name "note"}]
[:input {:type "submit" :value "Submit"}]]]]))})
(def known-sessions
(atom #{}))
(defn new-session! []
(let [uuid (str (java.util.UUID/randomUUID))]
(swap! known-sessions conj uuid)
uuid))
(def authenticated-sessions
(atom #{}))
(defn authenticate! [session-id headers]
(or (contains? @authenticated-sessions session-id)
(when (= (headers "authorization") (str "Basic " base64))
(swap! authenticated-sessions conj session-id)
true)))
(defn parse-session-id [cookie]
(when cookie
(when-let [notes-id (first (filter #(str/starts-with? % "notes-id")
(str/split cookie #"; ")))]
(str/replace notes-id "notes-id=" ""))))
(defn basic-auth-response [session-id]
{:status 401
:headers {"WWW-Authenticate" "Basic realm=\"notes\""
"Set-Cookie" (str "notes-id=" session-id)}})
;; run the server
(defn handler [req]
(when debug?
(println "Request:")
(pprint req))
(let [body (some-> req :body slurp java.net.URLDecoder/decode)
session-id (parse-session-id (get-in req [:headers "cookie"]))
_ (when (and debug? body)
(println "Request body:" body))
response (cond
;; if we didn't see this session before, we want the user to
;; re-authenticate
(not (contains? @known-sessions session-id))
(basic-auth-response (new-session!))
(not (authenticate! session-id (:headers req)))
(basic-auth-response session-id)
:else (do (when-not (str/blank? body)
(let [note (str/replace body "note=" "")]
(write-note! note)))
(home-response session-id)))]
(when debug?
(println "Response:")
(pprint (dissoc response :body))
(println))
response))
(server/run-server handler {:port 8080})
(println "Server started on port 8080.")
@(promise) ;; wait until SIGINT

View file

@ -1,27 +0,0 @@
#!/usr/bin/env bb
(ns pom-version-get
{:author "Wilker Lucio"}
(:require [clojure.data.xml :as xml]
[clojure.string :as str]))
(defn tag-name? [tag tname]
(some-> tag :tag name #{tname}))
(defn tag-content-str [tag]
(->> tag :content (filter string?) (str/join "")))
(defn pom-version
([] (pom-version "pom.xml"))
([path]
(->>
(slurp path)
(xml/parse-str)
(xml-seq)
(filter #(tag-name? % "version"))
first
tag-content-str)))
(if-let [arg (first *command-line-args*)]
(pom-version arg)
(pom-version))

View file

@ -1,15 +0,0 @@
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {org.clojure/data.zip {:mvn/version "RELEASE"}}})
(require '[clojure.data.xml :as xml]
'[clojure.data.zip.xml :as xmlz]
'[clojure.zip :as zip])
(def xml "<pom><version>1.0.0</version></pom>")
(-> xml
xml/parse-str
zip/xml-zip
(xmlz/xml1-> :pom :version zip/down zip/node))
;; => 1.0.0

View file

@ -1,36 +0,0 @@
#!/usr/bin/env bb
;; usage: version.clj pom.xml 1.0.1
;; pom.xml:
;; <project>
;; <version></version>
;; </project>
;; prints to stdout:
;; <project>
;; <version>1.0.1</version>
;; </project>
(ns pom-version-set
{:author "Michiel Borkent"}
(:require [clojure.data.xml :as xml]))
(def pom-xml (first *command-line-args*))
(def version (second *command-line-args*))
(def xml (xml/parse-str (slurp pom-xml)))
(defn update-version [elt]
(if-let [t (:tag elt)]
(if (= "version" (name t))
(assoc elt :content version)
elt)
elt))
(println
(xml/emit-str
(update xml :content
(fn [contents]
(map update-version contents)))))

View file

@ -1,54 +0,0 @@
#!/usr/bin/env bb
(ns portal
(:require [babashka.deps :as deps]
[cheshire.core :as json]
[clj-yaml.core :as yaml]
[clojure.data.xml :as xml]
[clojure.edn :as edn]
[clojure.string :as str]))
(deps/add-deps '{:deps {djblue/portal {:mvn/version "0.9.0"}}})
(require '[portal.api :as p])
(.addShutdownHook (Runtime/getRuntime)
(Thread. (fn [] (p/close))))
(def file (first *command-line-args*))
(when-not file
(binding [*out* *err*]
(println "Usage: portal.clj <file.(edn|json|xml|yaml)>"))
(System/exit 1))
(defn xml->hiccup [xml]
(if-let [t (:tag xml)]
(let [elt [t]
elt (if-let [attrs (:attr xml)]
(conj elt attrs)
elt)]
(into elt (map xml->hiccup (:content xml))))
xml))
(def extension (last (str/split file #"\.")))
(def contents (slurp file))
(def data (case extension
("edn")
(edn/read-string contents)
("json")
(json/parse-string contents)
("yml" "yaml")
(yaml/parse-string contents)
("xml")
(-> (xml/parse-str contents
:skip-whitespace true
:namespace-aware false)
(xml->hiccup))))
(p/open)
(p/tap)
(tap> data)
@(promise)

View file

@ -1,19 +0,0 @@
#!/usr/bin/env bb
(require '[clojure.java.io :as io])
(import '[java.lang ProcessBuilder$Redirect])
(defn grep [input pattern]
(let [proc (-> (ProcessBuilder. ["grep" pattern])
(.redirectOutput ProcessBuilder$Redirect/INHERIT)
(.redirectError ProcessBuilder$Redirect/INHERIT)
(.start))
proc-input (.getOutputStream proc)]
(with-open [w (io/writer proc-input)]
(binding [*out* w]
(print input)
(flush)))
(.waitFor proc)
nil))
(grep "hello\nbye\n" "bye")

View file

@ -1,7 +0,0 @@
#!/usr/bin/env bb
(def now (java.time.ZonedDateTime/now))
(def LA-timezone (java.time.ZoneId/of "America/Los_Angeles"))
(def LA-time (.withZoneSameInstant now LA-timezone))
(def pattern (java.time.format.DateTimeFormatter/ofPattern "HH:mm"))
(println (.format LA-time pattern))

View file

@ -1,11 +0,0 @@
#!/usr/bin/env bb
(require '[clojure.repl])
(defmacro random-doc []
(let [sym (-> (ns-publics 'clojure.core) keys rand-nth)]
(if (:doc (meta (resolve sym)))
`(clojure.repl/doc ~sym)
`(random-doc))))
(random-doc)

View file

@ -1,19 +0,0 @@
#!/usr/bin/env bb
(require '[clojure.java.io :as io])
(require '[bencode.core :refer [read-bencode]])
(require '[clojure.walk :refer [prewalk]])
(require '[clojure.pprint :refer [pprint]])
(import 'java.io.PushbackInputStream)
(defn bytes->strings [coll]
(prewalk #(if (bytes? %) (String. % "UTF-8") %) coll))
(defn read-torrent [src]
(with-open [in (io/input-stream (io/file src))]
(-> in PushbackInputStream. read-bencode bytes->strings)))
(when-let [src (first *command-line-args*)]
(-> (read-torrent src)
(assoc-in ["info" "pieces"] "...") ; binary data
pprint))

View file

@ -1,17 +0,0 @@
#!/usr/bin/env bb
(require '[clojure.java.io :as io])
(defn vim [file]
(->
(ProcessBuilder. ["vim" file])
(.inheritIO)
(.start)
(.waitFor)))
(def readme
(let [f (io/file "README.md")]
(when (not (.exists f))
(vim (.getPath f)))
(slurp f)))
(println readme)

View file

@ -1,32 +0,0 @@
;; USAGE: in whatsapp group chat, export your chat _without_ media, and store somewhere.
;; Then
;; $ cat chatfile.txt | bb -i -f whatsapp_frequencies.clj
(ns whatsapp-frequencies
{:author "Marten Sytema"}
(:require [clojure.java.io :as io]
[clojure.pprint :refer [print-table]]
[clojure.string :refer [trim] :as string]))
(defn parse-line
"Returns the name of the message, or nil if it can't be found"
[l]
(->> (string/replace l #"\p{C}" "")
trim
(re-find #"\[.*\] (.+?):")
second))
(defn chats-by-user
([lines]
(chats-by-user lines parse-line))
([lines keep-fn]
(->> lines
(keep keep-fn)
frequencies
(sort-by second >)
(map (fn [[name amount]]
{:name name
:amount amount}))
(print-table [:name :amount]))))
(chats-by-user (line-seq (io/reader *in*)))

View file

@ -1,17 +0,0 @@
#!/usr/bin/env bb
(require '[clojure.java.io :as io])
(defn which [executable]
(let [path (System/getenv "PATH")
paths (.split path (System/getProperty "path.separator"))]
(loop [paths paths]
(when-first [p paths]
(let [f (io/file p executable)]
(if (and (.isFile f)
(.canExecute f))
(.getCanonicalPath f)
(recur (rest paths))))))))
(when-let [executable (first *command-line-args*)]
(println (which executable)))

View file

@ -1,11 +0,0 @@
#!/usr/bin/env bb
;; by Janne Himanka shared on Clojurians Slack
(require '[babashka.curl :as curl])
(let [url (str "https://en.wikipedia.org/wiki/" (first *command-line-args*))
page (:body (curl/get url))]
(cond
(re-find #"Disambiguation" page)
(doseq [item (map last (re-seq #"<li><a href...wiki/([^\"]+)" page))]
(println item))
:else (last (re-find #"nl.wikipedia.org/.+?title..([^\"]+)" page))))

View file

@ -1,78 +0,0 @@
; let's build up a little data structure to play with
(def pet-store-sexp
[:pet-store
[:family
[:owners
[:name "Terry Smith"]
[:name "Sam Smith"]
[:phone "555-1212"]]
[:animals
[:animal {:type "dog"} "Sparky"]]]
[:family
[:owners
[:name "Pat Jones"]
[:phone "555-2121"]]
[:animals
[:animal {:type "hamster"} "Oliver"]
[:animal {:type "cat"} "Kat"]]]])
; we can build XML from this
(def xml-str (xml/indent-str (xml/sexp-as-element pet-store-sexp)))
(println "Our XML as a string is:")
(println xml-str)
(comment xml-str is
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<pet-store>
<family>
<owners>
<name>Terry Smith</name>...")
; and then we can parse that XML back into a data structure
(def xml-tree (xml/parse-str xml-str))
#_"xml-tree is a nested associative structure:
{:tag :pet-store,
:attrs {},
:content
({:tag :family,
:attrs {},
:content ...})}"
; with a couple of quick helper functions...
(defn get-by-tag
"takes a seq of XML elements (or a 'root-ish' element) and a tag, filters by tag name, and gets the content of each"
[elems tag-name]
; if we get (presumably) a root element, wrap it in a vector so we can still
; filter by its tag
(if (xml/element? elems)
(recur [elems] tag-name)
(->> (filter #(= (:tag %) tag-name) elems)
(mapcat :content))))
(defn get-in-by-tag
"takes a seq of XML elements and a vector of tags, and drills into each
element by the tags, sort of like a mash-up of core/get-in and an XPath
lookup"
[elems tag-vec]
(reduce get-by-tag elems tag-vec))
; we can do things like...
(println "all the owner names:" (get-in-by-tag
xml-tree
[:pet-store :family :owners :name]))
(println "all the animal names:" (get-in-by-tag
xml-tree
[:pet-store :family :animals :animal]))
(println "all the phone numbers:" (get-in-by-tag
xml-tree
[:pet-store :family :owners :phone]))

View file

@ -1,16 +0,0 @@
(ns babashka.impl.match
{:no-doc true}
(:require [clojure.core.match :as match]
clojure.core.match.array ;; side effecting
clojure.core.match.debug ;; side effecting
clojure.core.match.protocols ;; side effecting
clojure.core.match.regex ;; side effecting
[sci.core :as sci :refer [copy-var]]))
(def mns (sci/create-ns 'clojure.core.match nil))
(def core-match-namespace
{'match (copy-var match/match mns)
'backtrack (copy-var match/backtrack mns)
'val-at* (copy-var match/val-at* mns)
'defpred (copy-var match/defpred mns)})

View file

@ -1,10 +0,0 @@
(ns babashka.impl.csv
{:no-doc true}
(:require [clojure.data.csv :as csv]
[sci.core :as sci]))
(def cns (sci/create-ns 'clojure.data.csv nil))
(def csv-namespace
{'read-csv (sci/copy-var csv/read-csv cns)
'write-csv (sci/copy-var csv/write-csv cns)})

View file

@ -1,26 +0,0 @@
(ns babashka.impl.datascript
{:no-doc true}
(:require [datascript.core :as d]
[datascript.db :as db]
[sci.core :as sci :refer [copy-var]]))
(def datascript-ns (sci/create-ns 'datascript.core nil))
(def datascript-db-ns (sci/create-ns 'datascript.db nil))
(def datascript-namespace
{'create-conn (copy-var d/create-conn datascript-ns)
'transact! (copy-var d/transact! datascript-ns)
'q (copy-var d/q datascript-ns)
'empty-db (copy-var d/empty-db datascript-ns)
'db-with (copy-var d/db-with datascript-ns)
'filter (copy-var d/filter datascript-ns)
'init-db (copy-var d/init-db datascript-ns)
'datom (copy-var d/datom datascript-ns)
'pull (copy-var d/pull datascript-ns)
'pull-many (copy-var d/pull-many datascript-ns)})
(def datascript-db-namespace
{'db-from-reader (copy-var db/db-from-reader datascript-db-ns)
'datom-from-reader (copy-var db/datom-from-reader datascript-db-ns)
'datom-added (copy-var db/datom-added datascript-db-ns)
'datom-tx (copy-var db/datom-tx datascript-db-ns)})

View file

@ -1,76 +0,0 @@
(ns babashka.impl.hiccup
{:no-doc true}
(:require [hiccup.compiler :as compiler]
[hiccup.util :as util]
[sci.core :as sci :refer [copy-var]]))
(def hns (sci/create-ns 'hiccup.core nil))
(def hns2 (sci/create-ns 'hiccup2.core nil))
(def uns (sci/create-ns 'hiccup.util nil))
(def cns (sci/create-ns 'hiccup.compiler nil))
(defmacro html-2
"Render Clojure data structures to a compiled representation of HTML. To turn
the representation into a string, use clojure.core/str. Strings inside the
macro are automatically HTML-escaped. To insert a string without it being
escaped, use the [[raw]] function.
A literal option map may be specified as the first argument. It accepts two
keys that control how the HTML is outputted:
`:mode`
: One of `:html`, `:xhtml`, `:xml` or `:sgml` (defaults to `:xhtml`).
Controls how tags are rendered.
`:escape-strings?`
: True if strings should be escaped (defaults to true)."
{:added "2.0"}
[options & content]
;; (prn :escape-strings util/*escape-strings?*)
(if (map? options)
(let [mode (:mode options :xhtml)
escape-strings? (:escape-strings? options true)]
`(binding
[util/*html-mode* ~mode
util/*escape-strings?* ~escape-strings?]
(util/raw-string (compiler/render-html (list ~@content)))))
`(util/raw-string (compiler/render-html (list ~@(cons options content))))))
(defmacro html-1
"Render Clojure data structures to a string of HTML. Strings are **not**
automatically escaped, but must be manually escaped with the [[h]] function.
A literal option map may be specified as the first argument. It accepts the
following keys:
`:mode`
: One of `:html`, `:xhtml`, `:xml` or `:sgml` (defaults to `:xhtml`).
Controls how tags are rendered."
;; {:deprecated "2.0"}
[options & content]
(if (map? options)
`(str (hiccup2.core/html ~(assoc options :escape-strings? false) ~@content))
`(str (hiccup2.core/html {:escape-strings? false} ~options ~@content))))
(def ^{:added "2.0"} raw
"Short alias for [[hiccup.util/raw-string]]."
util/raw-string)
(def hiccup-namespace
{'html (copy-var html-1 hns {:name 'html})})
(def hiccup2-namespace
{'html (copy-var html-2 hns2 {:name 'html})
'raw (copy-var util/raw-string hns2 {:name 'raw})})
(def html-mode (copy-var util/*html-mode* uns))
(def escape-strings? (copy-var util/*escape-strings?* uns))
(def hiccup-util-namespace
{'*html-mode* html-mode
'*escape-strings?* escape-strings?
'raw-string (copy-var util/raw-string uns)
'to-uri (copy-var util/to-uri uns)})
(defn render-html [& contents]
(binding [util/*html-mode* @html-mode
util/*escape-strings?* @escape-strings?]
(apply compiler/render-html contents)))
(def hiccup-compiler-namespace
{'render-html (copy-var render-html cns)})

View file

@ -1,81 +0,0 @@
(ns babashka.impl.httpkit-client
{:no-doc true
:clj-kondo/config '{:lint-as {babashka.impl.httpkit-client/defreq clojure.core/declare}}}
(:refer-clojure :exclude [get])
(:require [clojure.string :as str]
[org.httpkit.client :as client]
[org.httpkit.sni-client :as sni-client]
[sci.core :as sci :refer [copy-var]]))
(def sni-client (delay (client/make-client {:ssl-configurer sni-client/ssl-configurer})))
(def sns (sci/create-ns 'org.httpkit.sni-client nil))
(def cns (sci/create-ns 'org.httpkit.client nil))
(def default-client (sci/new-dynamic-var '*default-client* sni-client {:ns cns}))
(alter-var-root #'client/*default-client* (constantly sni-client))
(defn request
([req]
(binding [client/*default-client* @default-client]
(client/request req)))
([req cb]
(binding [client/*default-client* @default-client]
(client/request req cb))))
(defmacro ^:private defreq [method]
`(defn ~method
~(str "Issues an async HTTP " (str/upper-case method) " request. "
"See `request` for details.")
~'{:arglists '([url & [opts callback]] [url & [callback]])}
~'[url & [s1 s2]]
(if (or (instance? clojure.lang.MultiFn ~'s1) (fn? ~'s1) (keyword? ~'s1))
(request {:url ~'url :method ~(keyword method)} ~'s1)
(request (merge ~'s1 {:url ~'url :method ~(keyword method)}) ~'s2))))
(defreq get)
(defreq delete)
(defreq head)
(defreq post)
(defreq put)
(defreq options)
(defreq patch)
(defreq propfind)
(defreq proppatch)
(defreq lock)
(defreq unlock)
(defreq report)
(defreq acl)
(defreq copy)
(defreq move)
(def httpkit-client-namespace
{'request (sci/new-var 'request request {:doc (:doc (meta #'client/request))
:name 'request
:ns cns})
'get (copy-var get cns)
'options (copy-var options cns)
'put (copy-var put cns)
'lock (copy-var lock cns)
'report (copy-var report cns)
'proppatch (copy-var proppatch cns)
'copy (copy-var copy cns)
'patch (copy-var patch cns)
'make-ssl-engine (copy-var client/make-ssl-engine cns)
'move (copy-var move cns)
'delete (copy-var delete cns)
'make-client (copy-var client/make-client cns)
'head (copy-var head cns)
'propfind (copy-var propfind cns)
'max-body-filter (copy-var client/max-body-filter cns)
'post (copy-var post cns)
'acl (copy-var acl cns)
'unlock (copy-var unlock cns)
'default-client (copy-var client/default-client cns)
'*default-client* default-client
'query-string (copy-var client/query-string cns)
'url-encode (copy-var client/url-encode cns)})
(def sni-client-namespace
{'ssl-configurer (copy-var sni-client/ssl-configurer sns)
'default-client (sci/new-var 'default-client sni-client {:ns sns})})

View file

@ -1,22 +0,0 @@
(ns babashka.impl.httpkit-server
(:require [org.httpkit.server :as server]
[sci.core :as sci :refer [copy-var]]))
(def sns (sci/create-ns 'org.httpkit.server nil))
(def httpkit-server-namespace
{:obj sns
'server-stop! (copy-var server/server-stop! sns)
'server-port (copy-var server/server-port sns)
'server-status (copy-var server/server-status sns)
'run-server (copy-var server/run-server sns)
'sec-websocket-accept (copy-var server/sec-websocket-accept sns)
'websocket-handshake-check (copy-var server/websocket-handshake-check sns)
'send-checked-websocket-handshake! (copy-var server/send-checked-websocket-handshake! sns)
'send-websocket-handshake! (copy-var server/send-websocket-handshake! sns)
'as-channel (copy-var server/as-channel sns)
'send! (copy-var server/send! sns)
'with-channel (copy-var server/with-channel sns)
'on-close (copy-var server/on-close sns)
'close (copy-var server/close sns)}
)

View file

@ -1,48 +0,0 @@
(ns babashka.impl.jdbc
{:no-doc true}
(:require
[next.jdbc :as njdbc]
[next.jdbc.result-set :as rs]
[next.jdbc.sql :as sql]
[sci.core :as sci]))
(def next-ns (sci/create-ns 'next.jdbc nil))
(defn with-transaction
"Given a transactable object, gets a connection and binds it to `sym`,
then executes the `body` in that context, committing any changes if the body
completes successfully, otherwise rolling back any changes made.
The options map supports:
* `:isolation` -- `:none`, `:read-committed`, `:read-uncommitted`,
`:repeatable-read`, `:serializable`,
* `:read-only` -- `true` / `false`,
* `:rollback-only` -- `true` / `false`."
[_ _ [sym transactable opts] & body]
(let [con (vary-meta sym assoc :tag 'java.sql.Connection)]
`(njdbc/transact ~transactable (^{:once true} fn* [~con] ~@body) ~(or opts {}))))
(def njdbc-namespace
{'get-datasource (sci/copy-var njdbc/get-datasource next-ns)
'execute! (sci/copy-var njdbc/execute! next-ns)
'execute-one! (sci/copy-var njdbc/execute-one! next-ns)
'get-connection (sci/copy-var njdbc/get-connection next-ns)
'plan (sci/copy-var njdbc/plan next-ns)
'prepare (sci/copy-var njdbc/prepare next-ns)
'transact (sci/copy-var njdbc/transact next-ns)
'with-transaction (sci/copy-var with-transaction next-ns)})
(def sns (sci/create-ns 'next.jdbc.sql nil))
(def next-sql-namespace
{'insert-multi! (sci/copy-var sql/insert-multi! sns)})
(def rsns (sci/create-ns 'next.jdbc.result-set nil))
(def result-set-namespace
{'as-maps (sci/copy-var rs/as-maps rsns)
'as-unqualified-maps (sci/copy-var rs/as-unqualified-maps rsns)
'as-modified-maps (sci/copy-var rs/as-modified-maps rsns)
'as-unqualified-modified-maps (sci/copy-var rs/as-unqualified-modified-maps rsns)
'as-lower-maps (sci/copy-var rs/as-lower-maps rsns)
'as-unqualified-lower-maps (sci/copy-var rs/as-unqualified-lower-maps rsns)
'as-maps-adapter (sci/copy-var rs/as-maps-adapter rsns)})

View file

@ -1,52 +0,0 @@
(ns babashka.impl.lanterna
{:no-doc true}
(:require
[lanterna.constants]
[lanterna.screen]
[lanterna.terminal]
[sci.core :as sci :refer [copy-var]]))
(def tns (sci/create-ns 'lanterna.terminal nil))
(def sns (sci/create-ns 'lanterna.screen nil))
(def cns (sci/create-ns 'lanterna.constants nil))
(def lanterna-terminal-namespace
{'add-resize-listener (copy-var lanterna.terminal/add-resize-listener tns)
'remove-resize-listener (copy-var lanterna.terminal/remove-resize-listener tns)
'get-terminal (copy-var lanterna.terminal/get-terminal tns)
'start (copy-var lanterna.terminal/start tns)
'stop (copy-var lanterna.terminal/stop tns)
'get-size (copy-var lanterna.terminal/get-size tns)
'move-cursor (copy-var lanterna.terminal/move-cursor tns)
'put-character (copy-var lanterna.terminal/put-character tns)
'put-string (copy-var lanterna.terminal/put-string tns)
'clear (copy-var lanterna.terminal/clear tns)
'flush (copy-var lanterna.terminal/flush tns)
'set-fg-color (copy-var lanterna.terminal/set-fg-color tns)
'set-bg-color (copy-var lanterna.terminal/set-bg-color tns)
'set-style (copy-var lanterna.terminal/set-style tns)
'get-key (copy-var lanterna.terminal/get-key tns)
'get-key-blocking (copy-var lanterna.terminal/get-key-blocking tns)})
(def lanterna-screen-namespace
{'terminal-screen (copy-var lanterna.screen/terminal-screen sns)
'add-resize-listener (copy-var lanterna.screen/add-resize-listener sns)
'remove-resize-listener (copy-var lanterna.screen/remove-resize-listener sns)
'start (copy-var lanterna.screen/start sns)
'stop (copy-var lanterna.screen/stop sns)
'get-size (copy-var lanterna.screen/get-size sns)
'redraw (copy-var lanterna.screen/redraw sns)
'move-cursor (copy-var lanterna.screen/move-cursor sns)
'get-cursor (copy-var lanterna.screen/get-cursor sns)
'put-string (copy-var lanterna.screen/put-string sns)
'put-sheet (copy-var lanterna.screen/put-sheet sns)
'clear (copy-var lanterna.screen/clear sns)
'get-key (copy-var lanterna.screen/get-key sns)
'get-key-blocking (copy-var lanterna.screen/get-key-blocking sns)})
(def lanterna-constants-namespace
{'charsets (copy-var lanterna.constants/charsets cns)
'colors (copy-var lanterna.constants/colors cns)
'styles (copy-var lanterna.constants/styles cns)
'key-codes (copy-var lanterna.constants/key-codes cns)
'sgr (copy-var lanterna.constants/sgr cns)})

View file

@ -1,233 +0,0 @@
(ns babashka.impl.logging
(:require [clojure.tools.logging]
[clojure.tools.logging.impl :as impl]
[clojure.tools.logging.readable]
[sci.core :as sci]
[taoensso.encore :as encore :refer [have]]
[taoensso.timbre :as timbre]))
;;;; timbre
(def tns (sci/create-ns 'taoensso.timbre nil))
(defn- fline [and-form] (:line (meta and-form)))
(defonce callsite-counter
(encore/counter))
(defmacro log! ; Public wrapper around `-log!`
"Core low-level log macro. Useful for tooling/library authors, etc.
* `level` - must eval to a valid logging level
* `msg-type` - must eval to e/o #{:p :f nil}
* `args` - arguments seq (ideally vec) for logging call
* `opts` - ks e/o #{:config ?err ?base-data spying?
:?ns-str :?file :?line :?column}
Supports compile-time elision when compile-time const vals
provided for `level` and/or `?ns-str`.
Logging wrapper examples:
(defn log-wrapper-fn [& args] (timbre/log! :info :p args))
(defmacro log-wrapper-macro [& args] (timbre/keep-callsite `(timbre/log! :info :p ~args)))"
([{:as opts
:keys [loc level msg-type args vargs
config ?err ?base-data spying?]
:or
{config 'taoensso.timbre/*config*
?err :auto}}]
(have [:or nil? sequential? symbol?] args)
(let [callsite-id (callsite-counter)
{:keys [line column]} (merge (meta &form) loc)
{:keys [ns file line column]} {:ns @sci/ns :file @sci/file :line line :column column}
ns (or (get opts :?ns-str) ns)
file (or (get opts :?file) file)
line (or (get opts :?line) line)
column (or (get opts :?column) column)
elide? (and #_(enc/const-forms? level ns) (timbre/-elide? level ns))]
(when-not elide?
(let [vargs-form
(or vargs
(if (symbol? args)
`(taoensso.timbre/-ensure-vec ~args)
`[ ~@args]))]
;; Note pre-resolved expansion
`(taoensso.timbre/-log! ~config ~level ~ns ~file ~line ~column ~msg-type ~?err
(delay ~vargs-form) ~?base-data ~callsite-id ~spying?
~(get opts :instant)
~(get opts :may-log?))))))
([level msg-type args & [opts]]
(let [{:keys [line column]} (merge (meta &form))
{:keys [ns file line column]} {:ns @sci/ns :file @sci/file :line line :column column}
loc {:ns ns :file file :line line :column column}
opts (assoc (conj {:loc loc} opts)
:level level, :msg-type msg-type, :args args)]
`(taoensso.timbre/log! ~opts))))
(defn make-ns [ns sci-ns ks]
(reduce (fn [ns-map [var-name var]]
(let [m (meta var)
doc (:doc m)
arglists (:arglists m)]
(assoc ns-map var-name
(sci/new-var (symbol var-name) @var
(cond-> {:ns sci-ns
:name (:name m)}
(:macro m) (assoc :macro true)
doc (assoc :doc doc)
arglists (assoc :arglists arglists))))))
{}
(select-keys (ns-publics ns) ks)))
(defn println-appender
"Returns a simple `println` appender for Clojure/Script.
Use with ClojureScript requires that `cljs.core/*print-fn*` be set.
:stream (clj only) - e/o #{:auto :*out* :*err* :std-err :std-out <io-stream>}."
;; Unfortunately no easy way to check if *print-fn* is set. Metadata on the
;; default throwing fn would be nice...
[& [{:keys [stream] :or {stream :auto}}]]
(let [stream
(case stream
:std-err timbre/default-err
:std-out timbre/default-out
stream)]
{:enabled? true
:async? false
:min-level nil
:rate-limit nil
:output-fn :inherit
:fn
(fn [data]
(let [{:keys [output_]} data
stream
(case stream
:auto (if (:error-level? data) @sci/err @sci/out)
:*out* @sci/out
:*err* @sci/err
stream)]
(binding [*out* stream]
(encore/println-atomic (force output_)))))}))
(def default-config (assoc-in timbre/*config* [:appenders :println]
(println-appender {:stream :auto})))
(def config (sci/new-dynamic-var '*config* default-config
{:ns tns}))
(defn swap-config! [f & args]
(apply sci/alter-var-root config f args))
(defn set-level! [level] (swap-config! (fn [m] (assoc m :min-level level))))
(defn merge-config! [m] (swap-config! (fn [old] (encore/nested-merge old m))))
(defmacro -log-and-rethrow-errors [?line & body]
`(try (do ~@body)
(catch Throwable e#
(do
#_(error e#) ; CLJ-865
(timbre/log! :error :p [e#] ~{:?line ?line})
(throw e#)))))
(def timbre-namespace
(assoc (make-ns 'taoensso.timbre tns ['trace 'tracef 'debug 'debugf
'info 'infof 'warn 'warnf
'error 'errorf
'-log! 'with-level
'spit-appender '-spy 'spy
'color-str])
'log! (sci/copy-var log! tns)
'*config* config
'swap-config! (sci/copy-var swap-config! tns)
'merge-config! (sci/copy-var merge-config! tns)
'set-level! (sci/copy-var set-level! tns)
'println-appender (sci/copy-var println-appender tns)
'-log-and-rethrow-errors (sci/copy-var -log-and-rethrow-errors tns)
'-ensure-vec (sci/copy-var encore/ensure-vec tns)))
(def enc-ns (sci/create-ns 'taoensso.encore))
(def encore-namespace
{'catching (sci/copy-var encore/catching enc-ns)
'try* (sci/copy-var encore/try* enc-ns)})
(def timbre-appenders-namespace
(let [tan (sci/create-ns 'taoensso.timbre.appenders.core nil)]
{'println-appender (sci/copy-var println-appender tan)
'spit-appender (sci/copy-var #_:clj-kondo/ignore timbre/spit-appender tan)}))
;;;; clojure.tools.logging
(defn- force-var "To support dynamic vars, etc."
[x] (if (instance? clojure.lang.IDeref x) (deref x) x))
(deftype Logger [logger-ns-str timbre-config]
clojure.tools.logging.impl/Logger
(enabled? [_ level]
;; No support for per-call config
(timbre/may-log? level logger-ns-str
(force-var timbre-config)))
(write! [_ level throwable message]
(log! level :p
[message] ; No support for pre-msg raw args
{:config (force-var timbre-config) ; No support for per-call config
:?ns-str logger-ns-str
:?file nil ; No support
:?line nil ; ''
:?err throwable})))
(deftype LoggerFactory [get-logger-fn]
clojure.tools.logging.impl/LoggerFactory
(name [_] "Timbre")
(get-logger [_ logger-ns] (get-logger-fn logger-ns)))
(alter-var-root
#'clojure.tools.logging/*logger-factory*
(fn [_]
(LoggerFactory.
(encore/memoize (fn [logger-ns] (Logger. (str logger-ns) config))))))
(def lns (sci/create-ns 'clojure.tools.logging nil))
(defmacro log
"Evaluates and logs a message only if the specified level is enabled. See log*
for more details."
([level message]
`(clojure.tools.logging/log ~level nil ~message))
([level throwable message]
`(clojure.tools.logging/log ~(deref sci/ns) ~level ~throwable ~message))
([logger-ns level throwable message]
`(clojure.tools.logging/log clojure.tools.logging/*logger-factory* ~logger-ns ~level ~throwable ~message))
([logger-factory logger-ns level throwable message]
`(let [logger# (impl/get-logger ~logger-factory ~logger-ns)]
(if (impl/enabled? logger# ~level)
(clojure.tools.logging/log* logger# ~level ~throwable ~message)))))
(def tools-logging-namespace
(assoc (make-ns 'clojure.tools.logging lns ['debug 'debugf 'info 'infof 'warn 'warnf 'error 'errorf
'logp 'logf '*logger-factory* 'log*
'trace 'tracef])
'log (sci/copy-var log lns)))
(def lins (sci/create-ns 'clojure.tools.logging.impl nil))
(def tools-logging-impl-namespace
(make-ns 'clojure.tools.logging.impl lins ['get-logger 'enabled?]))
(def tlr-ns (sci/create-ns 'clojure.tools.logging.readable nil))
(def tools-logging-readable-namespace
(make-ns 'clojure.tools.logging.readable tlr-ns ['trace 'tracef 'debug 'debugf 'info 'infof
'warn 'warnf 'error 'errorf 'fatal 'fatalf
'logf 'logp 'spyf]))

View file

@ -1,11 +0,0 @@
(ns babashka.impl.priority-map
(:require [clojure.data.priority-map :as pm]
[sci.core :as sci]))
(def pmns (sci/create-ns 'clojure.data.priority-map))
(def priority-map-namespace
{'priority-map (sci/copy-var pm/priority-map pmns)
'priority-map-keyfn (sci/copy-var pm/priority-map-keyfn pmns)
'subseq (sci/copy-var pm/subseq pmns)
'rsubseq (sci/copy-var pm/rsubseq pmns)})

Some files were not shown because too many files have changed in this diff Show more