### Start a Socket REPL Source: https://book.babashka.org/index Details how to launch a socket REPL in Babashka, specifying the port for connections. It also includes an example of connecting to the socket REPL using `nc` and mentions editor integrations. ```bash $ bb socket-repl 1666 Babashka socket REPL started at localhost:1666 ``` ```bash $ rlwrap nc 127.0.0.1 1666 Babashka v0.0.14 REPL. Use :repl/quit or :repl/exit to quit the REPL. Clojure rocks, Bash reaches. bb=> (+ 1 2 3) 6 bb=> :repl/quit $ ``` ```bash $ bb socket-repl '{:address "0.0.0.0" :accept clojure.core.server/repl :port 1666}' ``` -------------------------------- ### Running the HTTP Client Script Source: https://book.babashka.org/index Illustrates the execution of the `download_html.clj` script with example arguments, showing the expected output and usage message when arguments are missing. ```bash $ ./download_html.clj Usage: $ ./download_html.clj https://www.clojure.org /tmp/clojure.org.html Downloading url: https://www.clojure.org Writing file: /tmp/clojure.org.html ``` -------------------------------- ### Start a pREPL (Procedure REPL) Source: https://book.babashka.org/index Shows how to start a procedure REPL (pREPL) in Babashka, which provides structured return values for evaluated forms. This can be done via the `socket-repl` command or programmatically. ```bash $ bb socket-repl '{:address "0.0.0.0" :accept clojure.core.server/io-prepl :port 1666}' ``` ```clojure $ bb -e '(clojure.core.server/io-prepl)' (+ 1 2 3) {:tag :ret, :val "6", :ns "user", :ms 0, :form "(+ 1 2 3)"} ``` -------------------------------- ### Start babashka nREPL Server Source: https://book.babashka.org/index Starts an nREPL server on a specified port. Can be run directly from the command line or programmatically. Requires babashka.nrepl.server. ```shell $ bb nrepl-server 1667 ``` ```shell $ bb -e "(babashka.nrepl.server/start-server!) (deref (promise))" ``` -------------------------------- ### Start a Standard REPL Source: https://book.babashka.org/index Provides the command to start an interactive Read-Eval-Print Loop (REPL) in Babashka. It also suggests using `rlwrap` for enhanced command-line experience with history support. ```bash $ bb repl ``` ```bash $ rlwrap bb repl ``` -------------------------------- ### Query SQLite Database Source: https://book.babashka.org/index Example of querying an in-memory SQLite database using the `go-sqlite3` pod in Babashka. This requires the pod to be declared in `bb.edn`. ```clojure (ns my-project.db (:require [pod.babashka.go-sqlite3 :as sqlite])) (defn -main [& _args] (prn (sqlite/query ":memory:" ["SELECT 1 + 1 AS sum"]))) ``` -------------------------------- ### Start Clojure REPL within a Task Source: https://book.babashka.org/index Starts a Clojure REPL within a Babashka task using `clojure.main/repl`. ```clojure { :tasks {repl (clojure.main/repl)} } ``` -------------------------------- ### Execute Babashka Script from Command Line Source: https://book.babashka.org/index Demonstrates how to execute a Babashka script directly from the command line, specifying the main function to run. This example executes the `my-project.db` script. ```bash $ bb -m my-project.db [{:sum 2}] ``` -------------------------------- ### Parallel Task Execution in Babashka Source: https://book.babashka.org/index Demonstrates using the 'run' subcommand with the '--parallel' option to execute tasks and their dependencies concurrently. Includes :enter hook for logging task start times. ```clojure { :tasks { :init (def log (Object.)) :enter (locking log (println (str (:name (current-task)) ":") (java.util.Date.))) a (Thread/sleep 5000) b (Thread/sleep 5000) c {:depends [a b]} d {:task (time (run 'c))} } } ``` -------------------------------- ### Babashka core.async: Get first value from multiple processes Source: https://book.babashka.org/index Demonstrates using `clojure.core.async/thread` and `clojure.core.async/alts!!` to concurrently run shell commands and retrieve the output of the first one to complete. ```clojure bb -e \ '(defn async-command [& args] \ (async/thread (apply shell/sh "bash" "-c" args))) (-> (async/alts!! [(async-command "sleep 2 && echo process 1") (async-command "sleep 1 && echo process 2")]) first :out str/trim println)' ``` -------------------------------- ### Configure nREPL Server in bb.edn Source: https://book.babashka.org/index Configures and starts an nREPL server using a bb.edn file. It specifies the host and port, writes the port to a '.nrepl-port' file, and adds a shutdown hook to delete the file. Requires babashka.fs and babashka.nrepl.server. ```clojure { :tasks { nrepl {:requires ([babashka.fs :as fs] [babashka.nrepl.server :as srv]) :task (do (srv/start-server! {:host "localhost" :port 1339}) (spit ".nrepl-port" "1339") (-> (Runtime/getRuntime) (.addShutdownHook (Thread. (fn [] (fs/delete ".nrepl-port"))))) (deref (promise)))}} } ``` -------------------------------- ### Babashka Task Initialization Hook Source: https://book.babashka.org/index Shows the use of the ':init' hook in Babashka tasks for defining helper functions or constants that are executed before any tasks run. This example defines an 'env' function to retrieve environment variables. ```clojure { :tasks { :init (defn env [s] (System/getenv s)) print-env (println (env (first *command-line-args*))) } } ``` -------------------------------- ### Capture Classpath using Babashka Clojure Task Source: https://book.babashka.org/index Captures the classpath by executing `clojure -Spath` and printing the output. This operation does not start a new process but prints to standard output. ```clojure (with-out-str (clojure "-Spath")) ``` -------------------------------- ### Define Task Dependencies in Babashka Source: https://book.babashka.org/index Declares dependencies between tasks using the `:depends` key. Includes an example of creating a target directory and conditionally building a JAR file. ```clojure { :tasks {[:requires ([babashka.fs :as fs]) -target-dir "target" -target {:depends [-target-dir] :task (fs/create-dirs -target-dir)} -jar-file {:depends [-target] :task "target/foo.jar"} jar {:depends [-target -jar-file] :task (when (seq (fs/modified-since -jar-file (fs/glob "src" "**.clj"))) (spit -jar-file "test") (println "made jar!"))} uberjar {:depends [jar] :task (println "creating uberjar!")} } } ``` -------------------------------- ### Run babashka Expression Source: https://book.babashka.org/index Demonstrates how to execute a Clojure expression directly using the babashka executable (`bb`) with the `-e` flag. The `-e` flag is optional if the argument starts with a parenthesis. ```bash bb -e '(+ 1 2 3)' bb '(+ 1 2 3)' ``` -------------------------------- ### Execute Clojure Expression with Babashka Source: https://book.babashka.org/index Starts a Clojure process using deps.clj to evaluate a Clojure expression. The interface mirrors the Clojure CLI. ```clojure { :tasks {eval (clojure "-M -e '(+ 1 2 3)'")} } ``` -------------------------------- ### Babashka Task Execution with Command Line Args Source: https://book.babashka.org/index Shows how to define tasks that access and manipulate command-line arguments using *command-line-args*. It includes an example of rebinding *command-line-args* to pass arguments to other tasks. ```clojure { :tasks { :init (do (defn print-args [] (prn (:name (current-task)) *command-line-args*))) bar (print-args) foo (do (print-args) (binding [*command-line-args* (next *command-line-args*)] (run 'bar))) } } ``` -------------------------------- ### Declare Pods in bb.edn Source: https://book.babashka.org/index Since Babashka version 0.8.0, pods can be declared in the `bb.edn` configuration file. This example shows how to declare the `go-sqlite3` pod. ```clojure { :paths ["bb"] :pods {org.babashka/go-sqlite3 {:version "0.2.3"}} } ``` -------------------------------- ### Filter Input using Babashka Source: https://book.babashka.org/index A command-line example using Babashka to process piped input. It takes the first line of input and checks if it includes the character 'm'. ```bash $ ls | bb -i '(-> *input* first (str/includes? "m"))' true ``` -------------------------------- ### Execute Clojure Function with `-x` Flag Source: https://book.babashka.org/index Shows how to invoke a Clojure function directly from the command line using the `-x` flag, passing arguments as a map. The example uses `clojure.core/prn`. ```clojure bb -x clojure.core/prn --hello there {:hello "there"} ``` -------------------------------- ### HTTP Request via Unix Socket with Babashka Source: https://book.babashka.org/index Example of making an HTTP request to a service (like Docker) using a Unix socket. It uses `clojure.java.shell/sh` to execute `curl` and `cheshire.core` to parse the JSON response. ```clojure (require '[clojure.java.shell :refer [sh]]) (require '[cheshire.core :as json]) (-> (sh "curl" "--silent" "--no-buffer" "--unix-socket" "/var/run/docker.sock" "http://localhost/images/json") :out (json/parse-string true) first :RepoTags) ;;=> ["borkdude/babashka:latest"] ``` -------------------------------- ### Invoking Tasks with `run` Source: https://book.babashka.org/index Shows how to use the `run` function within Babashka tasks to explicitly call other tasks. This example defines a `clean` task to delete a directory and an `uberjar` task, and then creates an `uberjar:clean` task that runs both sequentially using `run`. ```clojure {:tasks {:requires ([babashka.fs :as fs]) clean (do (println "Removing target folder.") (fs/delete-tree "target")) uberjar (do (println "Making uberjar") (clojure "-X:uberjar")) uberjar:clean (do (run 'clean) (run 'uberjar))} } ``` -------------------------------- ### Printing Nil Values in Babashka Source: https://book.babashka.org/index Babashka does not automatically print `nil` return values. To explicitly print `nil`, use `prn`. This example shows the difference between implicit and explicit printing. ```bash $ bb -e '(:a {:a 5})' 5 $ bb -e '(:b {:a 5})' $ ``` -------------------------------- ### Dynamically add JAR to classpath in Babashka Source: https://book.babashka.org/index Demonstrates how to dynamically add a dependency's JAR to the classpath in babashka using the `add-classpath` function. It requires `babashka.classpath` and `clojure.java.shell`. The example fetches the classpath for a specified Maven dependency and then requires a library from that dependency. ```clojure (require '[babashka.classpath :refer [add-classpath]] '[clojure.java.shell :refer [sh]] '[clojure.string :as str]) (def medley-dep '{:deps {medley {:git/url "https://github.com/borkdude/medley" :sha "91adfb5da33f8d23f75f0894da1defe567a625c0"}}}) (def cp (-> (sh "clojure" "-Spath" "-Sdeps" (str medley-dep)) :out str/trim)) (add-classpath cp) (require '[medley.core :as m]) (m/index-by :id [{:id 1} {:id 2}]) ;;=> {1 {:id 1}, 2 {:id 2}} ``` -------------------------------- ### Babashka Command Line Help Source: https://book.babashka.org/index Displays all available command-line options and features of babashka, including VM options, global options, help commands, evaluation options, REPL modes, task execution, Clojure invocation, packaging utilities, input/output flags, and tooling commands. ```bash bb help ``` -------------------------------- ### Build babashka from Source Source: https://book.babashka.org/index Commands to clone the babashka repository, navigate into the directory, and build the uberjar and executable using provided scripts. Requires GraalVM and lein. ```bash git clone https://github.com/borkdude/babashka --recursive cd babashka script/uberjar && script/compile ``` -------------------------------- ### Define Babashka Task with Options Source: https://book.babashka.org/index Demonstrates defining a Babashka task as a map with options, including documentation, namespace requirements, and the task implementation using a filesystem delete function. ```clojure { :tasks { clean {:doc "Removes target folder" :requires ([babashka.fs :as fs]) :task (fs/delete-tree "target")} } } ``` -------------------------------- ### Initialize Task Environment with `:init` Hook Source: https://book.babashka.org/index Uses the `:init` hook to define variables and require namespaces before task execution, demonstrating task dependencies and conditional artifact building. ```clojure { :tasks {[:requires ([babashka.fs :as fs]) :init (do (def target-dir "target") (def jar-file "target/foo.jar")) -target {:task (fs/create-dirs target-dir)} jar {:depends [-target] :task (when (seq (fs/modified-since jar-file (fs/glob "src" "**.clj"))) (spit jar-file "test") (println "made jar!"))} uberjar {:depends [jar] :task (println "creating uberjar!")} } } ``` -------------------------------- ### Parse Command Line Arguments with babashka.cli Source: https://book.babashka.org/index Demonstrates how to parse command-line arguments in Babashka using the `babashka.cli` namespace. It shows how to define specifications for options and parse the arguments accordingly. Dependencies include `babashka.cli`. ```clojure (require '[babashka.cli :as cli]) (def cli-options {:port {:default 80 :coerce :long} :help {:coerce :boolean}}) (prn (cli/parse-opts *command-line-args* {:spec cli-options})) ``` -------------------------------- ### Watch Directory Changes with Babashka Pod Source: https://book.babashka.org/index This script uses the fswatcher pod to watch the current directory for changes, printing any detected modifications. It demonstrates pod loading and usage. ```clojure #!/usr/bin/env bb (require '[babashka.pods :as pods]) (pods/load-pod 'org.babashka/fswatcher "0.0.5") (require '[pod.babashka.fswatcher :as fw]) (fw/watch "." prn {:delay-ms 5000}) (println "Watching current directory for changes... Press Ctrl-C to quit.") @(promise) ``` -------------------------------- ### Connect to nREPL Server using Leiningen Source: https://book.babashka.org/index Demonstrates how to connect to a running babashka nREPL server from a Leiningen REPL client. This allows interaction with the babashka environment. ```shell $ lein repl :connect 1667 ``` -------------------------------- ### Set Preloads with BABASHKA_PRELOADS Environment Variable Source: https://book.babashka.org/index Explains how to define code that is loaded automatically in all Babashka instances using the `BABASHKA_PRELOADS` environment variable. This allows for setting up custom functions or loading external files. ```bash BABASHKA_PRELOADS='(defn foo [x] (+ x 2))' BABASHKA_PRELOADS=$BABASHKA_PRELOADS' (defn bar [x] (* x 2))' export BABASHKA_PRELOADS ``` ```bash export BABASHKA_PRELOADS='(load-file "my_awesome_prelude.clj")' ``` ```clojure $ bb '(-> (foo *input*) bar)' <<< 1 6 ``` -------------------------------- ### Babashka HTTP Client Script Source: https://book.babashka.org/index A babashka script that downloads content from a URL and saves it to a file. It uses the babashka.http-client library and handles command-line arguments for the URL and output file. Includes basic usage instructions and error handling. ```clojure #!/usr/bin/env bb (require '[babashka.http-client :as http]) (defn get-url [url] (println "Downloading url:" url) (http/get url)) (defn write-html [file html] (println "Writing file:" file) (spit file html)) (let [[url file] *command-line-args*] (when (or (empty? url) (empty? file)) (println "Usage: ") (System/exit 1)) (write-html file (:body (get-url url)))) ``` -------------------------------- ### Invoke Configured Task with CLI Arguments Source: https://book.babashka.org/index Demonstrates invoking the `my-function` task configured with CLI arguments, coercion, and aliases, showing how namespace and function options are merged. ```clojure $ bb --prn -x tasks/my-function -n 1 2 {:ns-data 1, :fn-data 1, :num [1 2]} ``` -------------------------------- ### Babashka core.async: High volume message passing (JVM compatibility) Source: https://book.babashka.org/index Illustrates a high-volume message passing scenario using `clojure.core.async/go` and `clojure.core.async/alts!!`. Note that Babashka's `go` maps to `thread` and `alts!!` does not park threads like in JVM Clojure, potentially consuming more resources. ```clojure (require '[clojure.core.async :as async]) (def n 1000) (let [cs (repeatedly n async/chan) begin (System/currentTimeMillis)] (doseq [c cs] (async/go (async/>! c "hi"))) (dotimes [_ n] (let [[v _] (async/alts!! cs)] (assert (= "hi" v)))) (println "Read" n "msgs in" (- (System/currentTimeMillis) begin) "ms")) ``` -------------------------------- ### Create Uberjar with Babashka Source: https://book.babashka.org/index Generates an executable uberjar from a Babashka project. This involves specifying the main namespace and output jar file. ```shell $ cat bb/foo.clj (ns foo) (defn -main [& args] (prn :hello)) $ cat bb.edn {:paths ["bb"] } $ bb uberjar foo.jar -m foo $ bb foo.jar :hello ``` -------------------------------- ### Add 'bb compatible' Badge for AsciiDoc Source: https://book.babashka.org/index This AsciiDoc snippet displays a badge indicating that a project is compatible with babashka. It links to the babashka book for more information. ```asciidoc https://book.babashka.org#badges[image:https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg[bb compatible]] ``` -------------------------------- ### Task Hooks: :enter and :leave Source: https://book.babashka.org/index Explains the :enter and :leave hooks in babashka tasks, which are executed before and after each task, respectively. These hooks can be used for logging or setup/teardown operations and can be overridden or disabled. ```APIDOC ## Task Hooks: :enter and :leave ### Description The `:enter` hook is executed before each task, and the `:leave` hook is executed after each task. They are commonly used for logging task names or performing setup and teardown actions. ### Method N/A (Task Configuration) ### Endpoint N/A (Task Configuration) ### Parameters #### Task Configuration Options - **`:enter`** (function) - Optional - A function to execute before a task. - **`:leave`** (function) - Optional - A function to execute after a task. ### Request Example ```clojure {:tasks {:init (defn env [s] (System/getenv s)) :enter (println "Entering:" (:name (current-task))) print-env (println (env (first *command-line-args*))) } } ``` ### Response #### Success Response No direct response, but hooks influence task execution behavior. #### Response Example ``` $ FOO=1 bb print-env FOO Entering: print-env 1 ``` ``` -------------------------------- ### Babashka: Exit with specific code using ex-info Source: https://book.babashka.org/index Shows how to use `ex-info` with the `:babashka/exit` metadata to terminate the Babashka process with a specific exit code and suppress error reporting. ```shell $ bb -e '(throw (ex-info "Error happened" {:babashka/exit 1}))' ``` ```shell $ echo $? ``` -------------------------------- ### Fish Tab Completion for Babashka Tasks Source: https://book.babashka.org/index Provides Fish shell configuration for tab completion of Babashka tasks. It caches the task list for efficiency and suggests task names. ```shell function __bb_complete_tasks if not test "$__bb_tasks" set -g __bb_tasks (bb tasks |tail -n +3 |cut -f1 -d ' ') end printf "%s\n" $__bb_tasks end complete -c bb -a "(__bb_complete_tasks)" -d 'tasks' ``` -------------------------------- ### Executing the Shebang Workaround Script Source: https://book.babashka.org/index Demonstrates how to run the script utilizing the shebang workaround and shows the output when passing arguments to it. ```bash ./script.clj 1 2 3 ("hello" "1" "2" "3") ``` -------------------------------- ### Babashka Test Runner Source: https://book.babashka.org/index A Babashka script to run tests using `clojure.test`. It adds `src` and `test` directories to the classpath, requires test namespaces, runs the tests, and exits with a non-zero code on failure. ```clojure #!/usr/bin/env bb (require '[clojure.test :as t] '[babashka.classpath :as cp]) (cp/add-classpath "src:test") (require 'your.test-a 'your.test-b) (def test-results (t/run-tests 'your.test-a 'your.test-b)) (let [{:keys [fail error]} test-results] (when (pos? (+ fail error)) (System/exit 1))) ``` -------------------------------- ### Add 'bb compatible' Badge for HTML Source: https://book.babashka.org/index This HTML snippet displays a badge indicating that a project is compatible with babashka. It links to the babashka book for more information. ```html bb compatible ``` -------------------------------- ### Add 'bb compatible' Badge for Markdown Source: https://book.babashka.org/index This Markdown snippet displays a badge indicating that a project is compatible with babashka. It links to the babashka book for more information. ```markdown [![bb compatible](https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg)](https://book.babashka.org#badges) ``` -------------------------------- ### Invoke Clojure from Babashka Source: https://book.babashka.org/index Shows how to invoke a `clojure` JVM process using Babashka's bundled deps.clj. This is useful for running Clojure-specific commands or tools from within Babashka. ```shell $ bb clojure -M -e "*clojure-version*" {:major 1, :minor 10, :incremental 1, :qualifier nil} ``` -------------------------------- ### Integrate Tasks with `babashka.task/exec` Source: https://book.babashka.org/index Explains how to integrate tasks using `babashka.task/exec`, allowing tasks to call other functions and merge CLI arguments. It showcases default `:exec-args` for tasks. ```clojure {:paths [". ``` ```clojure {:paths [". ``` -------------------------------- ### Babashka script execution via Cygwin/Git Bash Source: https://book.babashka.org/index Demonstrates invoking Babashka from a bash shell and highlights a common issue with Cygwin-style paths when using shebangs, along with a solution using a wrapper script. ```shell $ bb -e '(+ 1 2 3)' ``` ```shell #!/usr/bin/env bb (println "Hello, world!") ``` ```shell #!/bin/bash SCRIPT=$1 shift bb.exe $(cygpath -w $SCRIPT) $@ ``` ```shell #!/usr/bin/env bbwrap (println "Hello, world!") ``` -------------------------------- ### Running Script to Print File Path Source: https://book.babashka.org/index Demonstrates executing a simple babashka script that prints the path of the file it is contained within. ```bash $ cat example.clj (prn *file*) $ bb example.clj "/Users/borkdude/example.clj" ``` -------------------------------- ### Add 'bb built-in' Badge for AsciiDoc Source: https://book.babashka.org/index This AsciiDoc snippet displays a badge indicating that a project is built into babashka. It links to the babashka book for more information. ```asciidoc https://book.babashka.org#badges[image:https://raw.githubusercontent.com/babashka/babashka/master/logo/built-in-badge.svg[bb built-in]] ``` -------------------------------- ### Zsh Tab Completion for Babashka Tasks Source: https://book.babashka.org/index Provides Zsh shell configuration to enable tab completion for Babashka tasks. It parses the output of 'bb tasks' to provide task names as completion suggestions. ```shell _bb_tasks() { local matches=(`bb tasks |tail -n +3 |cut -f1 -d ' '`) compadd -a matches _files # autocomplete filenames as well } compdef _bb_tasks bb ``` -------------------------------- ### Invoke clj-kondo as Library with Babashka Source: https://book.babashka.org/index Invokes clj-kondo as a library using the `clojure` function within a specified directory. ```clojure { :tasks {eval (clojure {:dir "subproject"} "-M:clj-kondo")} } ``` -------------------------------- ### Bash Tab Completion for Babashka Tasks Source: https://book.babashka.org/index Provides Bash shell configuration to enable tab completion for Babashka tasks. It uses 'compgen' to filter task names based on user input. ```shell _bb_tasks() { COMPREPLY=( $(compgen -W "$(bb tasks |tail -n +3 |cut -f1 -d ' ')" -- ${COMP_WORDS[COMP_CWORD]}) ); } # autocomplete filenames as well complete -f -F _bb_tasks bb ``` -------------------------------- ### Executing a Babashka Script with -f Source: https://book.babashka.org/index Demonstrates how to run a babashka script file using the '-f' or '--file' flag followed by the script's filename. ```bash bb -f download_html.clj ``` -------------------------------- ### Create Babashka Glob Script Source: https://book.babashka.org/index Defines a Babashka script named 'glob.clj' that utilizes the clj-commons/fs library to find files matching a given glob pattern. It requires the 'me.raynes.fs' namespace. ```clojure (ns glob (:require [me.raynes.fs :as fs])) (run! (comp println str) (fs/glob (first *command-line-args*))) ``` -------------------------------- ### Babashka nREPL Client: Evaluate Clojure expression Source: https://book.babashka.org/index Shows how to interact with an nREPL server by sending a bencoded message to evaluate a Clojure expression and retrieve the result. Requires a running nREPL server. ```clojure (ns nrepl-client (:require [bencode.core :as b])) (defn nrepl-eval [port expr] (let [s (java.net.Socket. "localhost" port) out (.getOutputStream s) in (java.io.PushbackInputStream. (.getInputStream s)) _ (b/write-bencode out {"op" "eval" "code" expr}) bytes (get (b/read-bencode in) "value")] (String. bytes))) (nrepl-eval 52054 "(+ 1 2 3)") ;;=> "6" ``` -------------------------------- ### Executing Shell Commands with `shell` Source: https://book.babashka.org/index Illustrates the usage of the `shell` function in Babashka to execute external commands. It covers basic execution, error handling with `:continue`, output redirection to files (`:out "file.txt"`), capturing output as a string (`:out :string`), running in a different directory (`:dir`), and setting environment variables (`:extra-env`). ```clojure {:tasks {ls (shell "ls foo") } } ``` ```clojure {:tasks {ls (shell {:continue true} "ls foo") } } ``` ```clojure (shell {:out "file.txt"} "echo hello") ``` ```clojure (->> "echo hello" (shell {:out :string}) :out clojure.string/trim) ``` ```clojure (shell {:dir "subproject"} "ls") ``` ```clojure (shell {:extra-env {"FOO" "BAR"}} "printenv FOO") ``` -------------------------------- ### Run babashka Script File Source: https://book.babashka.org/index Shows how to execute a Clojure script file (`.clj`) using the babashka executable (`bb`) with the `-f` flag. The `-f` flag is optional if the argument is a filename. Scripts can also be made executable with a shebang. ```clojure (println (+ 1 2 3)) ``` ```bash bb -f script.clj bb script.clj ``` ```clojure #!/usr/bin/env bb (println (+ 1 2 3)) ``` ```bash ./script.clj ``` -------------------------------- ### Alternative to Synchronous `shell` using `babashka.process` Source: https://book.babashka.org/index Provides an alternative to the synchronous execution of `shell` by directly using `babashka.process/process` and `p/check`. This approach allows for more granular control over process execution and error checking. ```clojure (require '[babashka.process :as p :refer [process]] '[babashka.tasks :as tasks]) (tasks/shell {:dir "subproject"} "npm install") (-> (process {:dir "subproject" :inherit true} "npm install") (p/check)) ``` -------------------------------- ### Using `shell` with `apply` and `*command-line-args*` Source: https://book.babashka.org/index Demonstrates how to use the `apply` function with `shell` and `*command-line-args*` to pass command-line arguments directly to an external program invoked by `shell`. ```clojure (apply shell "npm install" *command-line-args*) ``` -------------------------------- ### Create Uberscript with Babashka Source: https://book.babashka.org/index Generates an 'uberscript' file (e.g., glob-uberscript.clj) by collecting expressions from specified sources. This single file contains all necessary code for execution. ```shell $ bb uberscript glob-uberscript.clj glob.clj ``` -------------------------------- ### Add 'bb built-in' Badge for HTML Source: https://book.babashka.org/index This HTML snippet displays a badge indicating that a project is built into babashka. It links to the babashka book for more information. ```html bb built-in ``` -------------------------------- ### Optimize Uberscript with Carve Source: https://book.babashka.org/index Demonstrates using the 'carve' tool to optimize an uberscript by removing unused code. This significantly reduces the file size and can improve execution time. ```shell $ wc -l glob-uberscript.clj 583 glob-uberscript.clj $ carve --opts '{:paths ["glob-uberscript.clj"] :aggressive true :silent true}' $ wc -l glob-uberscript.clj 105 glob-uberscript.clj ``` -------------------------------- ### Add 'bb built-in' Badge for Markdown Source: https://book.babashka.org/index This Markdown snippet displays a badge indicating that a project is built into babashka. It links to the babashka book for more information. ```markdown [![bb built-in](https://raw.githubusercontent.com/babashka/babashka/master/logo/built-in-badge.svg)](https://book.babashka.org#badges) ``` -------------------------------- ### Set Classpath with --classpath Option Source: https://book.babashka.org/index Illustrates how to control Babashka's classpath using the `--classpath` option, allowing direct specification of directories or JAR files. This method overrides `bb.edn` settings. It's useful for including custom namespaces or libraries. ```bash $ bb --classpath script --main my.namespace 1 2 3 Hello from my namespace! 1 2 3 ``` ```bash $ bb --classpath src:test socket-repl 1666 ``` -------------------------------- ### Invoke Task with Evaluated `exec-args` and CLI Options Source: https://book.babashka.org/index Demonstrates invoking a task that uses `babashka.task/exec` with evaluated `:exec-args` and additional CLI options, showcasing the merging of all arguments. ```clojure $ bb doit --cli-option :yeah -n 1 2 3 :x {:ns-data 1, :fn-data 1, :task-data 1234, :cli-option :yeah, :num [1 2 3] :foo 6} ``` -------------------------------- ### Invoke Main Function with -m Option Source: https://book.babashka.org/index Shows how to execute a specific main function in Babashka using the `-m` or `--main` flag. It allows calling functions like `namespace/-main` or any fully qualified function with command-line arguments. ```bash $ bb -m clojure.core/prn 1 2 3 "1" "2" "3" ``` -------------------------------- ### Configure Task CLI Arguments and Aliases Source: https://book.babashka.org/index Illustrates configuring task-specific CLI arguments, including default values (`:exec-args`), type coercion (`:coerce`), and argument aliasing (`:alias`) using metadata in `tasks.clj`. ```clojure bb.edn: {:paths [". ``` ```clojure (ns tasks {:org.babashka/cli {:exec-args {:ns-data 1}}}) (defn my-function {:org.babashka/cli {:exec-args {:fn-data 1} :coerce {:num [:int]} :alias {:n :num}}} [m] m) ``` -------------------------------- ### Babashka Task Hooks (:enter, :leave) Source: https://book.babashka.org/index Demonstrates the use of :enter and :leave hooks in Babashka tasks. The :enter hook runs before a task, and :leave runs after. They can be used to print task names or manage task execution flow. These hooks can be disabled by setting them to nil locally. ```clojure {:tasks {:init (defn env [s] (System/getenv s)) :enter (println "Entering:" (:name (current-task))) print-env (println (env (first *command-line-args*))) } } ``` -------------------------------- ### Babashka Executable Script Pattern Source: https://book.babashka.org/index This pattern allows a Babashka script to be safely loaded in a REPL while also being executable from the command line. It checks if the current file is the main script being executed. ```clojure #!/usr/bin/env bb ;; Various functions defined here (defn -main [& args] ;; Implementation of main ) (when (= *file* (System/getProperty "babashka.file")) (apply -main *command-line-args*)) ``` -------------------------------- ### Debug babashka nREPL Server Source: https://book.babashka.org/index Enables debugging output for the nREPL server. This can be done by setting the BABASHKA_DEV=true environment variable when running the nREPL server from the binary or from source. ```shell $ BABASHKA_DEV=true bb nrepl-server 1667 ``` ```shell $ git clone https://github.com/borkdude/babashka --recurse-submodules $ cd babashka $ BABASHKA_DEV=true clojure -A:main --nrepl-server 1667 ``` -------------------------------- ### Executing a Babashka Script Directly Source: https://book.babashka.org/index Shows the alternative method of executing a babashka script by passing the script's filename directly to the 'bb' command without using '-f'. ```bash bb download_html.clj ``` -------------------------------- ### Enable Data Readers in Babashka Source: https://book.babashka.org/index Demonstrates enabling custom data readers in Babashka by setting the `*data-readers*` special variable. This allows for custom tag literals. ```clojure $ bb -e "(set! *data-readers* {'t/tag inc}) #t/tag 1" 2 ``` -------------------------------- ### Tasks API Functions: run, shell, clojure, current-task Source: https://book.babashka.org/index Details the core functions available in the `babashka.tasks` namespace: `run` for invoking other tasks, `shell` for executing external commands, `clojure` for running Clojure code, and `current-task` for accessing information about the currently executing task. ```APIDOC ## Tasks API Functions: run, shell, clojure, current-task ### Description The `babashka.tasks` namespace provides essential functions for managing task execution. `run` allows calling other tasks, `shell` executes external processes with various options for output redirection and error handling, `clojure` invokes Clojure code, and `current-task` provides context about the active task. ### Method N/A (Function Calls within Tasks) ### Endpoint N/A (Function Calls within Tasks) ### Parameters #### `run` function: - **task-key** (keyword/symbol) - The key of the task to invoke. - **options** (map) - Optional map for options like `:parallel`. #### `shell` function: - **command** (string) - The command to execute. - **options** (map) - Optional map for options like `:continue`, `:out`, `:dir`, `:extra-env`. #### `clojure` function: - **args** (string/vector) - Arguments to pass to the clojure command. #### `current-task` function: - No parameters. ### Request Example ```clojure ;; Example using run {:tasks {:requires ([babashka.fs :as fs]) clean (do (println "Removing target folder.") (fs/delete-tree "target")) uberjar (do (println "Making uberjar") (clojure "-X:uberjar")) uberjar:clean (do (run 'clean) (run 'uberjar))} } ;; Example using shell with options {:tasks {ls (shell {:out :string} "echo hello") } } ``` ### Response #### Success Response Functions return values based on their operation (e.g., process exit code for `shell`, task result for `run`). #### Response Example ``` $ bb uberjar:clean Removing target folder. Making uberjar $ bb ls hello ``` ``` -------------------------------- ### Wait for Path with Babashka Source: https://book.babashka.org/index The `wait-for-path` function waits for a file path to be available. It allows configuration of timeout, pause between retries, and a default return value. ```clojure (require '[babashka.wait :as wait]) (wait/wait-for-path "/tmp/wait-path-test") ``` ```clojure (require '[babashka.wait :as wait]) (wait/wait-for-path "/tmp/wait-path-test" {:timeout 1000 :pause 1000}) ``` -------------------------------- ### Print Task Result in Babashka Source: https://book.babashka.org/index Illustrates how to use the 'run --prn' option to print the return value of a Babashka task. This is useful for debugging or displaying task outputs. ```clojure { :tasks {sum (+ 1 2 3)} } ``` -------------------------------- ### Add Dependencies with Babashka Source: https://book.babashka.org/index The `add-deps` function resolves and adds dependencies to the babashka classpath. It takes a deps map and optional resolution aliases. ```clojure (require '[babashka.deps :as deps]) (deps/add-deps '{:deps {medley/medley {:mvn/version "1.3.0"}}}) (require '[medley.core :as m]) (m/index-by :id [{:id 1} {:id 2}]) ``` ```clojure (deps/add-deps '{:aliases {:medley {:extra-deps {medley/medley {:mvn/version "1.3.0"}}}}} {:aliases [:medley]}) ``` -------------------------------- ### Stream Input Processing Source: https://book.babashka.org/index Processes input values one by one using the `--stream` option, executing the provided expression for each input value. ```shell $ echo '{:a 1} {:a 2}' | bb --stream '*input*' ``` -------------------------------- ### Babashka Shebang Workaround Source: https://book.babashka.org/index Presents a workaround for using babashka with a shebang line when the standard `#!/usr/bin/env bb` might not be directly supported. It uses a shell script wrapper to execute the babashka interpreter. ```shell #!/bin/sh #_( "exec" "bb" "$0" hello "$@" ) (prn *command-line-args*) ``` -------------------------------- ### Parallel Task Execution in Babashka Source: https://book.babashka.org/index Demonstrates parallel task execution using the `:parallel` option. The `dev` task invokes a private `-dev` task, which in turn depends on other tasks executed simultaneously. ```clojure { :tasks {dev {:doc "Runs app in dev mode. Compiles cljs, less and runs JVM app in parallel." :task (run '-dev {:parallel true})} -dev {:depends [dev:cljs dev:less dev:backend]} dev:cljs {:doc "Runs front-end compilation" :task (clojure "-M:frontend:cljs/dev")} dev:less {:doc "Compiles less" :task (clojure "-M:frontend:less/dev")} dev:backend {:doc "Runs backend in dev mode" :task (clojure (str "-A:backend:backend/dev:" platform-alias) "-X" "dre.standalone/start")} } } ``` -------------------------------- ### Shell Command Argument Tokenization and Bash Syntax Source: https://book.babashka.org/index Explains how the `shell` function tokenizes its first string argument and handles subsequent arguments. It also clarifies that `shell` does not invoke a shell directly and thus does not support bash-specific syntax unless explicitly invoked via `bash -c`. ```clojure (shell "npm install" "-g" "nbb") ``` ```clojure (shell "bash -c" "rm -rf target/*") ``` -------------------------------- ### Execute Task with Evaluated `exec-args` Source: https://book.babashka.org/index Shows how to pass evaluated `:exec-args` to the `babashka.task/exec` function, allowing dynamic data to be included in the function call. ```clojure {:paths [". ```