diff --git a/deps.edn b/deps.edn index d296fa11..1a590996 100644 --- a/deps.edn +++ b/deps.edn @@ -89,7 +89,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"}} + java-http-clj/java-http-clj {:mvn/version "0.4.3"} + com.stuartsierra/component {:mvn/version "1.0.0"}} :classpath-overrides {org.clojure/clojure nil org.clojure/spec.alpha nil org.clojure/core.specs.alpha nil}} diff --git a/doc/projects.md b/doc/projects.md index 012d94fa..66967ef8 100644 --- a/doc/projects.md +++ b/doc/projects.md @@ -46,6 +46,7 @@ The following libraries and projects are known to work with babashka. - [ffclj](#ffclj) - [multigrep](#multigrep) - [java-http-clj](#java-http-clj) + - [component](#component) - [Pods](#pods) - [Projects](#projects-1) - [babashka-test-action](#babashka-test-action) @@ -680,6 +681,10 @@ outputs: 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. + ## Pods [Babashka pods](https://github.com/babashka/babashka.pods) are programs that can diff --git a/examples/README.md b/examples/README.md index e02d648a..385d986d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -36,6 +36,7 @@ - [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) Here's a gallery of useful examples. Do you have a useful example? PR welcome! @@ -522,3 +523,14 @@ $ bb examples/xml-example.clj $ bb "(require 'logger) (logger/log \"the logger says hi\")" :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 +``` diff --git a/examples/memo.clj b/examples/memo.clj new file mode 100644 index 00000000..103d4d7e --- /dev/null +++ b/examples/memo.clj @@ -0,0 +1,16 @@ +#!/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))) diff --git a/test-resources/lib_tests/babashka/run_all_libtests.clj b/test-resources/lib_tests/babashka/run_all_libtests.clj index 1d65e503..624f9777 100644 --- a/test-resources/lib_tests/babashka/run_all_libtests.clj +++ b/test-resources/lib_tests/babashka/run_all_libtests.clj @@ -254,6 +254,8 @@ ;; namespaces to see if they at least load correctly (test-namespaces 'java-http-clj.smoke-test) +(test-namespaces 'component.component-test) + ;;;; final exit code (let [{:keys [:test :fail :error] :as m} @status] diff --git a/test-resources/lib_tests/component/component_test.clj b/test-resources/lib_tests/component/component_test.clj new file mode 100644 index 00000000..32b715f8 --- /dev/null +++ b/test-resources/lib_tests/component/component_test.clj @@ -0,0 +1,41 @@ +(ns component.component-test + (:require [clojure.test :refer [deftest is testing]] + [com.stuartsierra.component :as component])) + + +(def syslog (atom [])) + +(defn log [msg] + (swap! syslog conj msg)) + +(defrecord FakeDB [state] + component/Lifecycle + (start [_] + (log "start DB")) + (stop [_] + (log "stop DB"))) + +(defrecord FakeApp [db] + component/Lifecycle + (start [_] + (log "start app")) + (stop [_] + (log "stop app"))) + +(defn base-app [] + (map->FakeApp {})) + +(def sm + (component/system-map + :db (->FakeDB :foo) + :app (component/using (base-app) [:db]))) + +(component/start sm) + +;; do useful stuff here + +(component/stop sm) + +(deftest ordering-test + (testing "components are started and stopped in expected order" + (is (= ["start DB" "start app" "stop app" "stop DB"] @syslog))))