Merge branch 'master' into tools-analyzer

This commit is contained in:
Michiel Borkent 2024-05-18 17:40:39 +02:00
commit af06ff76d8
131 changed files with 3059 additions and 1775 deletions

View file

@ -2,5 +2,5 @@
:deps {borkdude/gh-release-artifact :deps {borkdude/gh-release-artifact
#_{:local/root "../gh-release-artifact"} #_{:local/root "../gh-release-artifact"}
{:git/url "https://github.com/borkdude/gh-release-artifact" {:git/url "https://github.com/borkdude/gh-release-artifact"
:git/sha "ce060c12a25b552b864dc90f8fb344a2eb91ea9d"}} :git/sha "4a9a74f0e50e897c45df8cc70684360eb30fce80"}}
:tasks {release-artifact babashka.release-artifact/release}} :tasks {release-artifact babashka.release-artifact/release}}

View file

@ -29,7 +29,7 @@ jobs:
- run: - run:
name: Generate config name: Generate config
command: | command: |
/tmp/bbb .circleci/script/short_ci.clj > generated_config.yml /tmp/bbb .circleci/script/gen_ci.clj > generated_config.yml
- continuation/continue: - continuation/continue:
configuration_path: generated_config.yml configuration_path: generated_config.yml

View file

@ -1,6 +1,6 @@
(require '[clojure.string :as str] (require '[babashka.fs :as fs]
'[babashka.process :as proc] '[babashka.process :as proc]
'[babashka.fs :as fs]) '[clojure.string :as str])
(import '[java.time Instant]) (import '[java.time Instant])
(defn read-env (defn read-env
@ -12,7 +12,9 @@
(def image-name "babashka/babashka") (def image-name "babashka/babashka")
(def image-tag (slurp "resources/BABASHKA_VERSION")) (def ghcr-image-name "ghcr.io/babashka/babashka")
(def image-tag (str/trim (slurp "resources/BABASHKA_VERSION")))
(def latest-tag "latest") (def latest-tag "latest")
@ -46,6 +48,11 @@
[username password] [username password]
(exec ["docker" "login" "-u" username "-p" 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 (defn build-push
[image-tag platform docker-file] [image-tag platform docker-file]
(println (format "Building and pushing %s Docker image(s) %s:%s" (println (format "Building and pushing %s Docker image(s) %s:%s"
@ -59,12 +66,25 @@
"-f" docker-file]] "-f" docker-file]]
(exec (concat base-cmd label-args ["."])))) (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
"--push"
"-f" docker-file]]
(exec (concat base-cmd label-args ["."]))))
(defn build-push-images (defn build-push-images
[] []
(doseq [platform (str/split platforms #",")] (doseq [platform (str/split platforms #",")]
(let [tarball-platform (str/replace platform #"\/" "-") (let [tarball-platform (str/replace platform #"\/" "-")
tarball-platform (if (= "linux-arm64" tarball-platform) tarball-platform (if (= "linux-arm64" tarball-platform)
"linux-aarch64" "linux-aarch64-static"
tarball-platform) tarball-platform)
tarball-path (format "/tmp/release/babashka-%s-%s.tar.gz" tarball-path (format "/tmp/release/babashka-%s-%s.tar.gz"
image-tag image-tag
@ -74,16 +94,20 @@
; this overwrites, but this is to work around having built the uberjar/metabom multiple times ; 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}))) (fs/copy (format "/tmp/release/%s-metabom.jar" tarball-platform) "metabom.jar" {:replace-existing true})))
(build-push image-tag platforms "Dockerfile.ci") (build-push image-tag platforms "Dockerfile.ci")
(build-push-ghcr image-tag platforms "Dockerfile.ci")
(when-not snapshot? (when-not snapshot?
(build-push latest-tag platforms "Dockerfile.ci"))) (build-push latest-tag platforms "Dockerfile.ci")
(build-push-ghcr latest-tag platforms "Dockerfile.ci")))
(defn build-push-alpine-images (defn build-push-alpine-images
"Build alpine image for linux-amd64 only (no upstream arm64 support yet)" "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")]) (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 (str image-tag "-alpine") "linux/amd64" "Dockerfile.alpine")
(build-push-ghcr (str image-tag "-alpine") "linux/amd64" "Dockerfile.alpine")
(when-not snapshot? (when-not snapshot?
(build-push "alpine" "linux/amd64" "Dockerfile.alpine"))) (build-push "alpine" "linux/amd64" "Dockerfile.alpine")
(build-push-ghcr "alpine" "linux/amd64" "Dockerfile.alpine")))
(when (= *file* (System/getProperty "babashka.file")) (when (= *file* (System/getProperty "babashka.file"))
(if (and (nil? (read-env "CIRCLE_PULL_REQUEST")) (if (and (nil? (read-env "CIRCLE_PULL_REQUEST"))
@ -93,6 +117,7 @@
(println "This is a snapshot version") (println "This is a snapshot version")
(println "This is a non-snapshot version")) (println "This is a non-snapshot version"))
(docker-login (read-env "DOCKERHUB_USER") (read-env "DOCKERHUB_PASS")) (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-images)
(build-push-alpine-images)) (build-push-alpine-images))
(println "Not publishing docker image(s)."))) (println "Not publishing docker image(s).")))

View file

@ -1,10 +1,12 @@
(ns short-ci (ns gen-ci
(:require (:require
[babashka.tasks :as tasks] [babashka.tasks :as tasks]
[clj-yaml.core :as yaml] [clj-yaml.core :as yaml]
[clojure.string :as str] [clojure.string :as str]
[flatland.ordered.map :refer [ordered-map]])) [flatland.ordered.map :refer [ordered-map]]))
(def graalvm-version "22")
(defn run (defn run
([cmd-name cmd] ([cmd-name cmd]
(run cmd-name cmd nil)) (run cmd-name cmd nil))
@ -80,8 +82,9 @@
:working_directory "~/repo" :working_directory "~/repo"
:environment {:LEIN_ROOT "true" :environment {:LEIN_ROOT "true"
:BABASHKA_PLATFORM "linux" :BABASHKA_PLATFORM "linux"
:GRAALVM_VERSION "22.3.0" :GRAALVM_VERSION graalvm-version
:GRAALVM_HOME graalvm-home} :GRAALVM_HOME graalvm-home
:BABASHKA_TEST_ENV "jvm"}
:resource_class "large" :resource_class "large"
:steps :steps
(gen-steps (gen-steps
@ -119,7 +122,7 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
(defn unix (defn unix
[shorted? static? musl? arch executor-conf resource-class graalvm-home platform] [shorted? static? musl? arch executor-conf resource-class graalvm-home platform]
(let [env {:LEIN_ROOT "true" (let [env {:LEIN_ROOT "true"
:GRAALVM_VERSION "22.3.0" :GRAALVM_VERSION graalvm-version
:GRAALVM_HOME graalvm-home :GRAALVM_HOME graalvm-home
:BABASHKA_PLATFORM (if (= "mac" platform) :BABASHKA_PLATFORM (if (= "mac" platform)
"macos" "macos"
@ -154,6 +157,8 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
:steps (gen-steps shorted? :steps (gen-steps shorted?
(filter some? (filter some?
[:checkout [:checkout
(when (contains? #{"linux" "linux-aarch64"} platform)
(run "Check max glibc version" "script/check_glibc.sh"))
{:attach_workspace {:at "/tmp"}} {:attach_workspace {:at "/tmp"}}
(run "Pull Submodules" "git submodule init\ngit submodule update") (run "Pull Submodules" "git submodule init\ngit submodule update")
{:restore_cache {:restore_cache
@ -167,13 +172,16 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
(str base-install-cmd "\nsudo -E script/setup-musl") (str base-install-cmd "\nsudo -E script/setup-musl")
base-install-cmd))) base-install-cmd)))
(run "Download GraalVM" "script/install-graalvm") (run "Download GraalVM" "script/install-graalvm")
(run "Build binary" "script/uberjar\nscript/compile" "30m") #_(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 "Run tests" "script/test\nscript/run_lib_tests") (run "Run tests" "script/test\nscript/run_lib_tests")
(run "Release" ".circleci/script/release") (run "Release" ".circleci/script/release")
{:persist_to_workspace {:root "/tmp" {:persist_to_workspace {:root "/tmp"
:paths ["release"]}} :paths ["release"]}}
{:save_cache {:save_cache
{:paths ["~/.m2" "~/graalvm-ce-java11-22.3.0"] {:paths ["~/.m2" "~/graalvm"]
:key cache-key}} :key cache-key}}
{:store_artifacts {:path "/tmp/release" {:store_artifacts {:path "/tmp/release"
:destination "release"}} :destination "release"}}
@ -184,9 +192,9 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
[shorted?] [shorted?]
(let [docker-executor-conf {:docker [{:image "circleci/clojure:openjdk-11-lein-2.9.8-bullseye"}]} (let [docker-executor-conf {:docker [{:image "circleci/clojure:openjdk-11-lein-2.9.8-bullseye"}]}
machine-executor-conf {:machine {:image "ubuntu-2004:202111-01"}} machine-executor-conf {:machine {:image "ubuntu-2004:202111-01"}}
mac-executor-conf {:macos {:xcode "14.0.0"}} mac-executor-conf {:macos {:xcode "12.5.1"}}
linux-graalvm-home "/home/circleci/graalvm-ce-java11-22.3.0" linux-graalvm-home (str "/home/circleci/graalvm-" graalvm-version)
mac-graalvm-home "/Users/distiller/graalvm-ce-java11-22.3.0/Contents/Home"] mac-graalvm-home (format "/Users/distiller/graalvm-%s/Contents/Home" graalvm-version)]
(ordered-map (ordered-map
:version 2.1 :version 2.1
:commands :commands
@ -201,17 +209,9 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
:linux (unix shorted? false false "amd64" docker-executor-conf "large" linux-graalvm-home "linux") :linux (unix shorted? false false "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-static :linux-static
(unix shorted? true true "amd64" docker-executor-conf "large" linux-graalvm-home "linux") (unix shorted? true true "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-aarch64 (unix shorted?
false
false
"aarch64"
machine-executor-conf
"arm.large"
linux-graalvm-home
"linux")
:linux-aarch64-static :linux-aarch64-static
(unix shorted? true false "aarch64" machine-executor-conf "arm.large" linux-graalvm-home "linux") (unix shorted? true false "aarch64" machine-executor-conf "arm.large" linux-graalvm-home "linux")
:mac (unix shorted? false false "amd64" mac-executor-conf "large" mac-graalvm-home "mac") :mac (unix shorted? false false "amd64" mac-executor-conf "macos.x86.medium.gen2" mac-graalvm-home "mac")
:deploy (deploy shorted?) :deploy (deploy shorted?)
:docker (docker shorted?)) :docker (docker shorted?))
:workflows (ordered-map :workflows (ordered-map
@ -220,12 +220,11 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
"linux" "linux"
"linux-static" "linux-static"
"mac" "mac"
"linux-aarch64"
"linux-aarch64-static" "linux-aarch64-static"
{:deploy {:filters {:branches {:only "master"}} {:deploy {:filters {:branches {:only "master"}}
:requires ["jvm" "linux"]}} :requires ["jvm" "linux"]}}
{:docker {:filters {:branches {:only "master"}} {:docker {:filters {:branches {:only "master"}}
:requires ["linux" "linux-static" "linux-aarch64"]}}]})))) :requires ["linux" "linux-static" "linux-aarch64-static"]}}]}))))
(def skip-config (def skip-config
{:skip-if-only [#".*.md$" {:skip-if-only [#".*.md$"

View file

@ -5,8 +5,8 @@ task:
skip: "changesIncludeOnly('logo/*', '**.md')" skip: "changesIncludeOnly('logo/*', '**.md')"
env: env:
LEIN_ROOT: "true" LEIN_ROOT: "true"
GRAALVM_VERSION: "22.3.0" GRAALVM_VERSION: "22"
GRAALVM_HOME: ${HOME}/graalvm-ce-java11-22.3.0/Contents/Home GRAALVM_HOME: ${HOME}/graalvm-${GRAALVM_VERSION}/Contents/Home
BABASHKA_PLATFORM: macos # used in release script BABASHKA_PLATFORM: macos # used in release script
BABASHKA_ARCH: aarch64 BABASHKA_ARCH: aarch64
BABASHKA_TEST_ENV: native BABASHKA_TEST_ENV: native
@ -25,7 +25,8 @@ task:
java -version java -version
script/uberjar script/uberjar
script/compile # curl -sLO 'https://github.com/babashka/pgo-profiles/releases/download/2023.10.11/default.iprof'
script/compile # --pgo=default.iprof
# script/test # script/test
# script/run_lib_tests # script/run_lib_tests

View file

@ -43,7 +43,7 @@ jobs:
uses: actions/setup-java@v2 uses: actions/setup-java@v2
with: with:
distribution: 'adopt-hotspot' distribution: 'adopt-hotspot'
java-version: '11' java-version: '19'
- name: Install clojure tools - name: Install clojure tools
uses: DeLaGuardo/setup-clojure@5.0 uses: DeLaGuardo/setup-clojure@5.0
@ -102,7 +102,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
LEIN_ROOT: "true" LEIN_ROOT: "true"
GRAALVM_VERSION: "22.3.0" GRAALVM_VERSION: "22"
BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script
BABASHKA_TEST_ENV: native BABASHKA_TEST_ENV: native
BABASHKA_XMX: "-J-Xmx6500m" BABASHKA_XMX: "-J-Xmx6500m"
@ -126,8 +126,8 @@ jobs:
if: "matrix.static == false" if: "matrix.static == false"
uses: graalvm/setup-graalvm@v1 uses: graalvm/setup-graalvm@v1
with: with:
version: '22.3.0' java-version: '22'
java-version: '11' distribution: 'graalvm'
components: 'native-image' components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
@ -135,8 +135,8 @@ jobs:
if: "matrix.static == true" if: "matrix.static == true"
uses: graalvm/setup-graalvm@v1 uses: graalvm/setup-graalvm@v1
with: with:
version: '22.3.0' version: '22'
java-version: '11' distribution: 'graalvm'
components: 'native-image' components: 'native-image'
native-image-musl: true native-image-musl: true
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}

2
.gitignore vendored
View file

@ -36,3 +36,5 @@ bb.build_artifacts.txt
target target
.nrepl-port .nrepl-port
.DS_Store .DS_Store
.portal
default.iprof

View file

@ -9,6 +9,252 @@ A preview of the next release can be installed from
## Unreleased ## Unreleased
- Fix [#1688](https://github.com/babashka/babashka/issues/1688): use-fixtures should add metadata to `*ns*`
- Fix [#1692](https://github.com/babashka/babashka/issues/1692): Add support for ITransientSet and org.flatland/ordered-set
- Bump org.flatland/ordered to `1.15.12`.
## 1.3.190 (2024-04-17)
- Fix [#1679](https://github.com/babashka/babashka/issues/1679): bump timbre and fix wrapping `timbre/log!`
- Add `java.util.concurrent.CountDownLatch`
- Add `java.lang.ThreadLocal`
- Bump `babashka.process`
- Bump httpkit to `2.8.0-RC1`
- Bump clojure to `1.11.2`
- Bump deps.clj
- Bump `babashka.cli`
- Bump `cheshire` to `5.13.0`
- Bump `http-client` to `0.4.17`
## 1.3.189 (2024-02-22)
- [#1660](https://github.com/babashka/babashka/issues/1660): add `:deps-root` as part of hash to avoid caching issue with `deps.clj`
- [#1632](https://github.com/babashka/babashka/issues/1632): fix `(.readPassword (System/console))` by upgrading GraalVM to `21.0.2`
- [#1661](https://github.com/babashka/babashka/issues/1661): follow symlink when reading adjacent bb.edn
- [#1665](https://github.com/babashka/babashka/issues/1665): `read-string` should use non-indexing reader for compatibilty with Clojure
- Bump edamame to 1.4.24
- Bump http-client to 0.4.16
- Bump babashka.cli to 0.8.57
- Uberjar task: support reader conditional in .cljc file
- Support reader conditional in .cljc file when creating uberjar
- Add more `javax.net.ssl` classes
- [#1675](https://github.com/babashka/babashka/issues/1675): add `hash-unordered-coll`
## 1.3.188 (2024-01-12)
- [#1658](https://github.com/babashka/babashka/issues/1658): fix command line parsing for scripts that parse `--version` or `version` etc
## 1.3.187 (2024-01-09)
- Add `clojure.reflect/reflect`
- Add `java.util.ScheduledFuture`, `java.time.temporal.WeekFields`
- Support `Runnable` to be used without import
- Allow `catch` to be used as var name
- [#1646](https://github.com/babashka/babashka/issues/1646): command-line-args are dropped when file exists with same name
- [#1645](https://github.com/babashka/babashka/issues/1645): Support for `clojure.lang.LongRange`
- [#1652](https://github.com/babashka/babashka/issues/1652): allow `bb.edn` to be empty
- [#1586](https://github.com/babashka/babashka/issues/1586): warn when config file doesn't exist and `--debug` is enabled
- [#1410](https://github.com/babashka/babashka/issues/1410): better error message when exec fn doesn't exist
- Bump `babashka.cli` to `0.8.55` which contains subcommand improvements
- Bump `deps.clj` to `1.11.1.1435`
- Bump `babashka.fs` to `0.5.20`
- Compatibility with `plumbing.core`
- Compatibility with `shadow.css` by improving `tools.reader` compatibility
- [#1647](https://github.com/babashka/babashka/issues/1647): Allow capturing env vars at build time (only relevant for building bb)
## 1.3.186 (2023-11-02)
- [Support self-contained binaries as uberjars!](https://github.com/babashka/babashka/wiki/Self-contained-executable#uberjar)
- Add `java.security.KeyFactory`, `java.security.spec.PKCS8EncodedKeySpec`, `java.net.URISyntaxException`, `javax.crypto.spec.IvParameterSpec`
- Fix babashka.process/exec wrt `babashka.process/*defaults*`
- [#1632](https://github.com/babashka/babashka/issues/1632): Partial fix for `(.readPassword (System/console))`
- Enable producing self-contained binaries using [uberjars](https://github.com/babashka/babashka/wiki/Self-contained-executable#uberjar)
- Bump httpkit to `2.8.0-beta3` (fixes GraalVM issue with virtual threads)
- Bump `deps.clj` and `fs`
- Expose `taoensso.timbre.appenders.core`
- nREPL: implement `ns-list` op
- SCI: optimize `swap!`, `deref` and `reset!` for normal atoms (rather than user-created `IAtom`s)
- Add test for [#1639](https://github.com/babashka/babashka/issues/1639)
- Upgrade to GraalVM 21.0.1
## 1.3.185 (2023-09-28)
- [#1624](https://github.com/babashka/babashka/pull/1624): Use Oracle GraalVM 21 ([@lispyclouds](https://github.com/lispyclouds))
- Use PGO to speed up loops (now 2-3x faster for `(time (loop [val 0 cnt 10000000] (if (pos? cnt) (recur (inc val) (dec cnt)) val)))`!)
- Bump babashka.http-client to v0.4.15
- Bump rewrite-clj to v0.1.1.47
- [#1619](https://github.com/babashka/babashka/issues/1619): Fix reflection issue with `Thread/sleep` in `core.async/timeout`
- Support interop on `java.util.stream.IntStream`
- [#1513](https://github.com/babashka/babashka/issues/1513): Fix interop on `Thread/sleep` with numbers that aren't already longs
- Bump babashka.cli to 0.7.53
- Fix [#babashka.nrepl/66](https://github.com/babashka/babashka.nrepl/issues/66)
- Various nREPL server improvements (classpath op, file lookup information for `cider-find-var`)
- Bump cheshire to 5.12.0
## 1.3.184 (2023-08-22)
- Remove leftover debugging output from deps.clj
## 1.3.183 (2023-08-22)
- [#1592](https://github.com/babashka/babashka/issues/1592): expose `sci.core` in babashka
- [#1596](https://github.com/babashka/babashka/issues/1596): Fix `clojure.java.browse/browse-url` truncates URLs with multiple query parameters on Windows
- [#1599](https://github.com/babashka/babashka/issues/1599): propagate error from `run` when task does not exist
- Bump clj-yaml to `1.0.27`
- [#1604](https://github.com/babashka/babashka/issues/1604): throw `FileNotFoundException` when requiring namespace whose file cannot be found (as JVM Clojure does)
- Bump integrant CI tests
- [#1600](https://github.com/babashka/babashka/issues/1600): use pagesize of 64K on linux aarch64, so it works on Asahi linux
- Expose `selmer.parser/resolve-arg`
- [#1610](https://github.com/babashka/babashka/issues/1610): expose `babashka.http-client.websocket` namespace
- Bump `babashka.http-client` to `0.4.14`
- [#1568](https://github.com/babashka/babashka/issues/1568): warn when task overrides built-in command
## 1.3.182 (2023-07-20)
- [#1579](https://github.com/babashka/babashka/issues/1579): add `clojure.tools.reader/resolve-symbol`
- [#1581](https://github.com/babashka/babashka/issues/1581): `bb print-deps`: sort dependencies ([@teodorlu](https://github.com/teodorlu))
- Upgrade `babashka.http-client` to `0.4.12`, fixes `:insecure` option
- Bump [edamame](https://github.com/borkdude/edamame) to `1.3.23`: fixes infinite loop with reader conditional expression
- Bump [Selmer](https://github.com/yogthos/Selmer) to Bumping to `1.12.59`
- Bump [deps.clj](https://github.com/borkdude/deps.clj) with more fixes which should make downloading/installation of tools jar more robust
- Add `javax.net.ssl.X509ExtendedTrustManager` class
- Bump [babashka.process](https://github.com/babashka/process): accept path or file as `:dir` argument
- Bump [hiccup](https://github.com/weavejester/hiccup) to `2.0.0-RC1`
## 1.3.181 (2023-06-13)
- [#1575](https://github.com/babashka/babashka/issues/1575): fix command line parsing problem with `-e` + `*command-line-args*`
- [#1576](https://github.com/babashka/babashka/issues/1576): make downloading/unzipping of deps.clj tools .zip file more robust
## 1.3.180 (2023-05-28)
- [#1524](https://github.com/babashka/babashka/issues/1524): Remove dynamic builds for linux-aarch64 ([@lispyclouds](https://github.com/lispyclouds))
- [#1577](https://github.com/babashka/babashka/issues/1557): Add support for `babashka.process/exec` after namespace reload of `babashka.process` ([@lread](https://github.com/lread))
- [#1548](https://github.com/babashka/babashka/issues/1548): shell and sh should respect `babashka.process/*defaults*`
- [#1524](https://github.com/babashka/babashka/issues/1524): deprecate (remove) linux-aarch64 dynamic binary build
- Expose `org.graalvm.nativeimage.ProcessProperties/exec`
- Bump `babashka.http-client` to `0.3.11`
- Bump `babashka.fs` to `0.4.19`
- Bump `babashka.process` to `0.5.21`
## 1.3.179 (2023-04-26)
- [#1544](https://github.com/babashka/babashka/issues/1544): `:local/root` in script-adjacent bb.edn should resolve relative to script
- [#1545](https://github.com/babashka/babashka/issues/1545): Adjacent `bb.edn` not respected with explicit `-f` option
- [#1546](https://github.com/babashka/babashka/issues/1546): add `.contains` for vector and lazy-seq
## 1.3.178 (2023-04-21)
- Fix regression with [#1541](https://github.com/babashka/babashka/issues/1541)
## 1.3.177 (2023-04-21)
- [#1541](https://github.com/babashka/babashka/issues/1541): respect `bb.edn`
adjacent to invoked file. This eases writing system-global scripts from
projects without using bbin. See [docs](https://book.babashka.org/#_script_adjacent_bb_edn).
- [#1523](https://github.com/babashka/babashka/pull/1523): Reduce the size of the Docker images ([@raszi](https://github.com/raszi))
- Upgrade deps.clj to v1.11.1.1273
- Upgrade transit-clj to 1.0.333
- Add `java.security.cert.CertificateFactory`
- Bump clj-yaml to 1.0.26
- Bump edamame to 1.3.21
- Add `UnsupportedOperationException`
- Bump babashka CLI to 0.7.51
- Bump babashka http-client to 0.2.9
- Add `--install-exit-handlers` to native-image build to support shutdown hook + SIGTERM
## 1.3.176 (2023-03-18)
- Upgrade http-client to 0.1.8, fixes binary file uploads (which messed up the previous release)
- Downgrade org.flatland/ordered to 1.5.9 due to this [issue](https://github.com/clj-commons/ordered/issues/71)
## 1.3.175 (2023-03-18)
- [#1507](https://github.com/babashka/babashka/issues/1507): Expose methods on java.lang.VirtualThread ([@lispyclouds](https://github.com/lispyclouds))
- [#1510](https://github.com/babashka/babashka/issues/1510): add virtual thread interop on `Thread`
- [#1511](https://github.com/babashka/babashka/issues/1511): support for domain sockets
- [#1521](https://github.com/babashka/babashka/issues/1521): push images to GHCR ([@lispyclouds](https://github.com/lispyclouds))
- Bump edamame to 1.3.20
- Bump deps.clj to 1.11.1.1257
- Bump org.flatland/ordered to 1.15.10
- Support `clojure.lang.MapEntry/create`
- clojure.core.async `go` macro now uses virtual threads
- Bump babashka.cli to 0.6.50
- Bump http-client to 0.1.7
## 1.2.174 (2023-03-01)
- Use GraalVM 22.3.1 on JDK 19.0.2. This adds virtual thread support. See [demo](https://twitter.com/borkdude/status/1572222344684531717).
- Expose more `jaxax.crypto` classes
- Add more `java.time` and related classes with the goal of supporting [juxt.tick](https://github.com/juxt/tick) ([issue](https://github.com/juxt/tick/issues/86))
- Compatibility with [kaocha](https://github.com/lambdaisland/kaocha) test runner
- [#1000](https://github.com/babashka/babashka/issues/1000): add lib tests for xforms ([@bobisageek](https://github.com/bobisageek))
- [#1482](https://github.com/babashka/babashka/issues/1482): make loading of libs thread safe
- [#1487](https://github.com/babashka/babashka/issues/1487): `babashka.tasks/clojure` should be supported without arguments to start a REPL
- [#1496](https://github.com/babashka/babashka/issues/1496): Add `set-agent-send-executor!` and `set-agent-send-off-executor!`
- [#1489](https://github.com/babashka/babashka/issues/1489): Don't overwrite non-empty, non-jar files when writing uberscript/uberjar ([@bobisageek](https://github.com/bobisageek))
- [#1506](https://github.com/babashka/babashka/issues/1506): `:exec-args` in task should override `:exec-args` on fn metadata
- [#1501](https://github.com/babashka/babashka/issues/1501): equals on deftype
- Add support for `.getWatches` on atoms
- Bump `babashka.fs` to `0.3.17`
- Bump `deps.clj` to `1.11.1.1237`
- Bump `babashka.http-client` to `0.1.5`
- Bump `babashka.cli` to `0.6.46`
## 1.1.173 (2023-02-04)
- [#1473](https://github.com/babashka/babashka/issues/1473): support `--config` in other dir + `:local/root` ([@lispyclouds](https://github.com/lispyclouds))
- Compatibility with `clojure.tools.namespace.repl/refresh` and `clojure.java.classpath`
- `(clojure.lang.RT/baseLoader)` now returns classloader with babashka dependencies on classpath
- Support reading tags from `data_readers.clj` and `data_readers.cljc`
- Don't exit REPL when `babashka.deps/add-deps` fails
- Fix [#1474](https://github.com/babashka/babashka/issues/1474): when `.bb` file is in different artifact, `.clj` file is loaded first if it appears first on classpath
- Support for `*loaded-libs*` and `(loaded-libs)`
- Bump rewrite-clj to `1.1.46`
- Bump http-client to `0.0.3`
- Bump fs to `0.2.15`
- Bump process to `0.4.16`
## 1.1.172 (2023-01-23)
- [#1472](https://github.com/babashka/babashka/issues/1472): fix tokenization of `babashka.tasks/clojure`: command was tokenized twice (regression was introduced in `1.0.168`)
- **BREAKING**: Bump `babashka.process`: change default for `:out :append` to `:out :write`. This default is undocumented so the impact should be small.
## 1.1.171 (2023-01-23)
- [#1467](https://github.com/babashka/babashka/issues/1467): **BREAKING**: avoid printing results, unless `--prn` is enabled (aside from `-e`, `-o` and `-O`).
- Include [http-client](https://github.com/babashka/http-client) as built-in library
- SCI: support `add-watch` on vars
- Compatibility with [eftest](https://github.com/weavejester/eftest) test runner (see [demo](https://twitter.com/borkdude/status/1616886788898885632))
- Add classes:
- `java.util.concurrent.Callable`
- `java.util.concurrent.ExecutorService`
- Expose `clojure.main` `main` and `repl-caught`
- Switch `clojure.test/*report-counters*` to ref instead of atom for compatibility with [kaocha](https://github.com/lambdaisland/kaocha)
- Allow `java.io.OutputStream` to be proxied, for [kaocha](https://github.com/lambdaisland/kaocha)
- Support qualified method names in `proxy` and ignore namespace
## 1.0.170 (2023-01-19)
- [#1463](https://github.com/babashka/babashka/issues/1463): Add `java.util.jar.Attributes` class ([@jeroenvandijk](https://github.com/jeroenvandijk))
- [#1456](https://github.com/babashka/babashka/issues/1456): allow `*warn-on-reflection*` and `*unchecked-math*` to be set in socket REPL and nREPL ([@axks](https://github.com/axks))
- SCI: macroexpansion error location improvement
- Add compatibility with [tab](https://github.com/eerohele/tab) and [solenoid](https://github.com/adam-james-v/solenoid)
- Bump babashka.cli and babashka.fs
- New classes:
- `java.util.jar.Attributes`
- `java.util.concurrent.ThreadFactory`
- `java.lang.Thread$UncaughtExceptionHandler`
- `java.lang.Thread$UncaughtExceptionHandler`
- `java.util.concurrent.BlockingQueue`
- `java.util.concurrent.ArrayBlockingQueue`
- `java.util.concurrent.ThreadFactory`
- `java.lang.Thread$UncaughtExceptionHandler`
- `java.util.concurrent.Semaphore`
- Expose more httpkit.server functions: `with-channel`, `on-close`, `close`
## 1.0.169 (2023-01-03)
- Implement `ns`, `lazy-seq` as macro - Implement `ns`, `lazy-seq` as macro
- Support `--dev-build` flag in installation script - Support `--dev-build` flag in installation script
- [#1451](https://github.com/babashka/babashka/issues/1451): Allow passing explicit file and line number to clojure.test ([@matthewdowney](https://github.com/matthewdowney)) - [#1451](https://github.com/babashka/babashka/issues/1451): Allow passing explicit file and line number to clojure.test ([@matthewdowney](https://github.com/matthewdowney))
@ -16,6 +262,11 @@ A preview of the next release can be installed from
- [#1446](https://github.com/babashka/babashka/issues/1446): add `pprint/code-dispatch` - [#1446](https://github.com/babashka/babashka/issues/1446): add `pprint/code-dispatch`
- Update zlib to version `1.2.13` ([@thiagokokada](https://github.com/thiagokokada)) - Update zlib to version `1.2.13` ([@thiagokokada](https://github.com/thiagokokada))
- [#1454](https://github.com/babashka/babashka/issues/1454): Add `babashka.process` to `print-deps` output - [#1454](https://github.com/babashka/babashka/issues/1454): Add `babashka.process` to `print-deps` output
- Update `deps.clj` / clojure tools to `1.11.1.1208`
- Add `reader-conditional` function
- Fix pretty printing (with `clojure.pprint`) of vars
- Upgrade built-in `spec.alpha`
- SCI performance improvements: faster JVM interop
## 1.0.168 (2022-12-07) ## 1.0.168 (2022-12-07)
@ -625,7 +876,7 @@ Babashka.pods:
- Add `babashka.task` `System` property [#837](https://github.com/babashka/babashka/issues/837) - Add `babashka.task` `System` property [#837](https://github.com/babashka/babashka/issues/837)
- Allow thread-first with `shell` like `babashka.process` [#829](https://github.com/babashka/babashka/issues/829) - Allow thread-first with `shell` like `babashka.process` [#829](https://github.com/babashka/babashka/issues/829)
## 0.4.0 ## 0.4.0 (2021-05-08)
Babashka proper: Babashka proper:
@ -635,7 +886,7 @@ Babashka proper:
[jasentaa](https://github.com/rm-hull/jasentaa) parser combinator library [jasentaa](https://github.com/rm-hull/jasentaa) parser combinator library
- Update Selmer to 1.12.40 - Update Selmer to 1.12.40
Sci: SCI:
- Better error msg for protocol not found or class - Better error msg for protocol not found or class
@ -1205,6 +1456,14 @@ Details about releases prior to v0.1.0 can be found
## Breaking changes ## Breaking changes
### v1.1.172
- Bump `babashka.process`: change default for `:out :append` to `:out :write`. This default is undocumented so the impact should be small.
### v1.1.171
- [#1467](https://github.com/babashka/babashka/issues/1467): avoid printing results, unless `--prn` is enabled (aside from `-e`, `-o` and `-O`).
### v0.2.4 ### v0.2.4
- Remove cheshire smile functions [#658](https://github.com/babashka/babashka/issues/658) - Remove cheshire smile functions [#658](https://github.com/babashka/babashka/issues/658)

View file

@ -5,25 +5,25 @@ RUN apt update
RUN apt install --no-install-recommends -yy build-essential zlib1g-dev RUN apt install --no-install-recommends -yy build-essential zlib1g-dev
WORKDIR "/opt" WORKDIR "/opt"
ENV GRAALVM_VERSION="22.3.0" ENV GRAALVM_VERSION="22"
ARG TARGETARCH ARG TARGETARCH
# Do not set those directly, use TARGETARCH instead # Do not set those directly, use TARGETARCH instead
ENV BABASHKA_ARCH= ENV BABASHKA_ARCH=
ENV GRAALVM_ARCH= ENV GRAALVM_ARCH=
RUN if [ "${TARGETARCH}" = "" ] || [ "${TARGETARCH}" = "amd64" ]; then \ RUN if [ "${TARGETARCH}" = "" ] || [ "${TARGETARCH}" = "amd64" ]; then \
export GRAALVM_ARCH=amd64; export BABASHKA_ARCH=x86_64; \ export GRAALVM_ARCH=x64; export BABASHKA_ARCH=x86_64; \
elif [ "${TARGETARCH}" = "arm64" ]; then \ elif [ "${TARGETARCH}" = "arm64" ]; then \
export GRAALVM_ARCH=aarch64; \ export GRAALVM_ARCH=aarch64; \
fi && \ fi && \
echo "Installing GraalVM for ${GRAALVM_ARCH}" && \ echo "Installing GraalVM for ${GRAALVM_ARCH}" && \
curl -sLO https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${GRAALVM_VERSION}/graalvm-ce-java11-linux-${GRAALVM_ARCH}-${GRAALVM_VERSION}.tar.gz && \ curl -sLO https://download.oracle.com/graalvm/21/archive/graalvm-jdk-${GRAALVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz
tar -xzf graalvm-ce-java11-linux-${GRAALVM_ARCH}-${GRAALVM_VERSION}.tar.gz && \ mkdir "graalvm-$GRAALVM_VERSION"
rm graalvm-ce-java11-linux-${GRAALVM_ARCH}-${GRAALVM_VERSION}.tar.gz tar -xzf graalvm-jdk-${GRAALVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz -C graalvm --strip-components 1
ARG BABASHKA_XMX="-J-Xmx4500m" ARG BABASHKA_XMX="-J-Xmx4500m"
ENV GRAALVM_HOME="/opt/graalvm-ce-java11-${GRAALVM_VERSION}" ENV GRAALVM_HOME="/opt/graalvm-$GRAALVM_VERSION"
ENV JAVA_HOME="/opt/graalvm-ce-java11-${GRAALVM_VERSION}/bin" ENV JAVA_HOME="$GRAALVM_HOME/bin"
ENV PATH="$JAVA_HOME:$PATH" ENV PATH="$JAVA_HOME:$PATH"
ENV BABASHKA_XMX=$BABASHKA_XMX ENV BABASHKA_XMX=$BABASHKA_XMX
@ -73,7 +73,9 @@ RUN ./script/compile
FROM ubuntu:latest FROM ubuntu:latest
RUN apt-get update && apt-get install -y curl \ RUN apt-get update && apt-get install -y curl \
&& mkdir -p /usr/local/bin && 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/target/metabom.jar /opt/babashka-metabom.jar
COPY --from=BASE /opt/bb /usr/local/bin/bb COPY --from=BASE /opt/bb /usr/local/bin/bb
CMD ["bb"] CMD ["bb"]

View file

@ -13,8 +13,8 @@ RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswit
# TODO: Run actual native tests when they are ported # TODO: Run actual native tests when they are ported
RUN bb -e "(curl/get \"https://httpstat.us/200\")" # cURL http test 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://httpstat.us/200\"))] (throw error))" # JVM 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 "(.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 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
@ -23,7 +23,7 @@ FROM alpine:3
RUN apk --no-cache add curl ca-certificates tar && \ 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 && \ 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 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 RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
COPY metabom.jar /opt/babashka-metabom.jar COPY metabom.jar /opt/babashka-metabom.jar

View file

@ -2,6 +2,7 @@ FROM ubuntu:latest
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y curl \ && apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /usr/local/bin && mkdir -p /usr/local/bin
ARG TARGETARCH ARG TARGETARCH

111
README.md
View file

@ -58,6 +58,28 @@ $ ls | bb -i '(filter fs/directory? *input*)'
bb took 4ms. bb took 4ms.
``` ```
## Support :heart:
You can support this project via [Github
Sponsors](https://github.com/sponsors/borkdude),
[OpenCollective](https://opencollective.com/babashka),
[Ko-fi](https://ko-fi.com/borkdude) or indirectly via [Clojurists
Together](https://www.clojuriststogether.org/).
<details>
<summary>Top sponsors</summary>
- [Clojurists Together](https://clojuriststogether.org/)
- [Roam Research](https://roamresearch.com/)
- [Nextjournal](https://nextjournal.com/)
- [Toyokumo](https://toyokumo.co.jp/)
- [Cognitect](https://www.cognitect.com/)
- [Kepler16](https://kepler16.com/)
- [Adgoji](https://www.adgoji.com/)
</details>
## Babashka users ## Babashka users
See [companies](doc/companies.md) for a list of companies using babashka. See [companies](doc/companies.md) for a list of companies using babashka.
@ -82,7 +104,7 @@ and is unlikely to change. Changes may happen in other parts of babashka,
although we will try our best to prevent them. Always check the release notes or although we will try our best to prevent them. Always check the release notes or
[CHANGELOG.md](CHANGELOG.md) before upgrading. [CHANGELOG.md](CHANGELOG.md) before upgrading.
### Talk ## Talk
To get an overview of babashka, you can watch this talk ([slides](https://speakerdeck.com/borkdude/babashka-and-the-small-clojure-interpreter-at-clojured-2020)): To get an overview of babashka, you can watch this talk ([slides](https://speakerdeck.com/borkdude/babashka-and-the-small-clojure-interpreter-at-clojured-2020)):
@ -93,6 +115,11 @@ To get an overview of babashka, you can watch this talk ([slides](https://speake
The [babashka book](https://book.babashka.org) contains detailed information The [babashka book](https://book.babashka.org) contains detailed information
about how to get the most out of babashka scripting. about how to get the most out of babashka scripting.
There is also the book [Babashka Babooka](https://www.braveclojure.com/quests/babooka/),
by Daniel Higginbotham, who has also helped a lot of people learn Clojure with
[Clojure for the Brave and
True](https://www.braveclojure.com/clojure-for-the-brave-and-true/).
## Examples ## Examples
Read the output from a shell command as a lazy seq of strings: Read the output from a shell command as a lazy seq of strings:
@ -127,7 +154,7 @@ File `pst.clj`:
``` ```
``` shell ``` shell
$ pst.clj $ bb pst.clj
05:17 05:17
``` ```
@ -148,11 +175,6 @@ Install:
brew install borkdude/brew/babashka brew install borkdude/brew/babashka
<!-- On macOS with an M1 processor: -->
<!-- softwareupdate --install-rosetta -->
<!-- arch -x86_64 brew install borkdude/brew/babashka -->
Upgrade: Upgrade:
brew upgrade babashka brew upgrade babashka
@ -190,13 +212,25 @@ linux binary.
### asdf ### asdf
[asdf](https://github.com/asdf-vm/asdf) is an extendable version manager for linux and macOS. [asdf](https://github.com/asdf-vm/asdf) is an extendable version manager for linux and macOS. Note that asdf will add significant startup time to any babashka script, consider using [mise](#mise) instead.
Babashka can be installed using a plugin as follows: Babashka can be installed using a plugin as follows:
asdf plugin add babashka asdf plugin add babashka https://github.com/pitch-io/asdf-babashka
asdf install babashka latest asdf install babashka latest
### mise
[mise](https://mise.jdx.dev/) is a development environment setup tool for linux and macOS.
Install:
mise use --global babashka@latest
Upgrade:
mise upgrade babashka
### Windows ### Windows
#### Scoop #### Scoop
@ -283,6 +317,12 @@ You may also download a binary from
[Github](https://github.com/babashka/babashka/releases). For linux there is a [Github](https://github.com/babashka/babashka/releases). For linux there is a
static binary available which can be used on Alpine. static binary available which can be used on Alpine.
### CI
- On Github Actions it's recommended to use [setup-clojure](https://github.com/DeLaGuardo/setup-clojure) with `bb: latest`.
- You can use the [installer script](https://github.com/babashka/babashka#installer-script) on any non-Windows CI system. CircleCI requires `sudo`.
- On Appveyor + Windows you can use a bit of [Powershell](https://github.com/clj-kondo/clj-kondo/blob/39b5cb2b0d3d004c005e8975b6fafe0e314eec68/appveyor.yml#L60-L64).
## Docker ## Docker
Check out the image on [Docker hub](https://hub.docker.com/r/babashka/babashka/). Check out the image on [Docker hub](https://hub.docker.com/r/babashka/babashka/).
@ -358,6 +398,10 @@ https://babashka.org[image:https://raw.githubusercontent.com/babashka/babashka/m
</details> </details>
</br> </br>
## Swag
- [t-shirt](https://www.etsy.com/listing/1241766068/babashka-clj-kondo-nbb-shirt)
## [Pods](https://github.com/babashka/babashka.pods) ## [Pods](https://github.com/babashka/babashka.pods)
Pods are programs that can be used as a Clojure library by Pods are programs that can be used as a Clojure library by
@ -406,11 +450,21 @@ handling of SIGINT and SIGPIPE. This can be done by setting
## Articles, podcasts and videos ## Articles, podcasts and videos
- [Babashka: 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) by Michiel Borkent - [Blambda analyses sites](https://jmglov.net/blog/2023-01-04-blambda-analyses-sites.html) by Josh Glover
- [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
- [Babashka Babooka](https://www.braveclojure.com/quests/babooka/): Write Command-Line Clojure by Daniel Higginbotham
- [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
- [Babashka: 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) by Michiel Borkent (Japanese version [here]((https://logico-jp.io/2023/01/07/babashka-how-graalvm-helped-create-a-fast-starting-scripting-environment-for-clojure/)))
- [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 - [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
- [Using Babashka to Get Electricity Prices](https://www.karimarttila.fi/clojure/2022/12/04/using-babashka-to-get-electricity-prices.html) by Kari Marttila - [Using Babashka to Get Electricity Prices](https://www.karimarttila.fi/clojure/2022/12/04/using-babashka-to-get-electricity-prices.html) by Kari Marttila
- [How to Do Things With Babashka](https://presumably.de/how-to-do-things-with-babashka.html) by Paulus Esterhazy (2022-12)
- [Using nREPL as a system interface](https://yogthos.net/posts/2022-11-26-nREPL-system-interaction.html) by Dmitri Sotnikov
- [Manage git hooks with babashka tasks](https://blaster.ai/blog/posts/manage-git-hooks-w-babashka.html) by Mykhaylo Bilyanskyy - [Manage git hooks with babashka tasks](https://blaster.ai/blog/posts/manage-git-hooks-w-babashka.html) by Mykhaylo Bilyanskyy
- [Messing around with babashka](https://ian-muge.medium.com/messing-around-with-babashka-f181a9003faa) by Ian Muge - [Messing around with babashka](https://ian-muge.medium.com/messing-around-with-babashka-f181a9003faa) by Ian Muge
- Introducing [bbin](https://radsmith.com/bbin) by Radford Smith (2022-09)
- [Deleting AWS Glacier vaults with babashka](https://javahippie.net/clojure/2022/07/23/deleting-aws-glacier-vaults-with-babashka.html) by Tim Zöller - [Deleting AWS Glacier vaults with babashka](https://javahippie.net/clojure/2022/07/23/deleting-aws-glacier-vaults-with-babashka.html) by Tim Zöller
- [Recursive document transformations with Pandoc and Clojure](https://play.teod.eu/document-transform-pandoc-clojure/) by Teodor Heggelund - [Recursive document transformations with Pandoc and Clojure](https://play.teod.eu/document-transform-pandoc-clojure/) by Teodor Heggelund
- [Blambda!](https://jmglov.net/blog/2022-07-03-blambda.html) by Josh Glover - [Blambda!](https://jmglov.net/blog/2022-07-03-blambda.html) by Josh Glover
@ -497,47 +551,10 @@ commit](https://github.com/babashka/babashka/commit/02c7c51ad4b2b1ab9aa95c26a744
Thanks to all the people that contributed to babashka: Thanks to all the people that contributed to babashka:
- [Adgoji](https://www.adgoji.com/) for financial support
- [CircleCI](https://circleci.com/) for CI and additional support - [CircleCI](https://circleci.com/) for CI and additional support
- [Nikita Prokopov](https://github.com/tonsky) for the logo - [Nikita Prokopov](https://github.com/tonsky) for the logo
- [Contributors](https://github.com/babashka/babashka/graphs/contributors) and - [Contributors](https://github.com/babashka/babashka/graphs/contributors) and
other users posting issues with bug reports and ideas other users posting issues with bug reports and ideas
- [Github sponsors](https://github.com/sponsors/borkdude)
- [OpenCollective sponsors](https://opencollective.com/babashka)
- [Clojurists Together](https://www.clojuriststogether.org/)
### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](doc/dev.md)].
<a href="https://github.com/babashka/babashka/graphs/contributors"><img src="https://opencollective.com/babashka/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
#### Github Sponsors
- [Dig Gashinsky](https://github.com/digash)
#### OpenCollective
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/babashka/contribute)]
##### Individuals
<a href="https://opencollective.com/babashka"><img src="https://opencollective.com/babashka/individuals.svg?width=890"></a>
##### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/babashka/contribute)]
<a href="https://opencollective.com/babashka/organization/0/website"><img src="https://opencollective.com/babashka/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/1/website"><img src="https://opencollective.com/babashka/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/2/website"><img src="https://opencollective.com/babashka/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/3/website"><img src="https://opencollective.com/babashka/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/4/website"><img src="https://opencollective.com/babashka/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/5/website"><img src="https://opencollective.com/babashka/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/6/website"><img src="https://opencollective.com/babashka/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/7/website"><img src="https://opencollective.com/babashka/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/8/website"><img src="https://opencollective.com/babashka/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/babashka/organization/9/website"><img src="https://opencollective.com/babashka/organization/9/avatar.svg"></a>
## License ## License

View file

@ -2,13 +2,13 @@
version: "v-{build}" version: "v-{build}"
image: Visual Studio 2017 image: Visual Studio 2022
clone_folder: C:\projects\babashka clone_folder: C:\projects\babashka
environment: environment:
GRAALVM_HOME: C:\projects\babashka\graalvm\graalvm-ce-java11-22.3.0 GRAALVM_HOME: C:\projects\babashka\graalvm\graalvm-jdk-22+36.1
JAVA_HOME: C:\projects\babashka\graalvm\graalvm-ce-java11-22.3.0 JAVA_HOME: C:\projects\babashka\graalvm\graalvm-jdk-22+36.1
BABASHKA_XMX: "-J-Xmx5g" BABASHKA_XMX: "-J-Xmx5g"
skip_commits: skip_commits:
@ -23,6 +23,9 @@ cache:
clone_script: clone_script:
- cmd: git config --global core.autocrlf true - cmd: git config --global core.autocrlf true
- cmd: git config --global core.symlinks true
- ps: >- - ps: >-
if(-not $env:APPVEYOR_PULL_REQUEST_NUMBER) { 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 git clone -q --branch=$env:APPVEYOR_REPO_BRANCH https://github.com/$env:APPVEYOR_REPO_NAME.git $env:APPVEYOR_BUILD_FOLDER
@ -36,9 +39,12 @@ clone_script:
} }
- cmd: git submodule update --init --recursive - cmd: git submodule update --init --recursive
- cmd: git reset --hard
build_script: build_script:
# TODO: Extract the zip by removing the top level folder to remove the hardcoded path for GRAALVM_HOME
- cmd: >- - cmd: >-
powershell -Command "if (Test-Path('graalvm')) { return } else { (New-Object Net.WebClient).DownloadFile('https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.0/graalvm-ce-java11-windows-amd64-22.3.0.zip', 'graalvm.zip') }" powershell -Command "if (Test-Path('graalvm')) { return } else { (New-Object Net.WebClient).DownloadFile('https://download.oracle.com/graalvm/22/archive/graalvm-jdk-22_windows-x64_bin.zip', 'graalvm.zip') }"
powershell -Command "if (Test-Path('graalvm')) { return } else { Expand-Archive graalvm.zip graalvm }" powershell -Command "if (Test-Path('graalvm')) { return } else { Expand-Archive graalvm.zip graalvm }"
@ -55,8 +61,6 @@ build_script:
# see https://github.com/quarkusio/quarkus/pull/7663 # see https://github.com/quarkusio/quarkus/pull/7663
- cmd: >- - cmd: >-
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
call script/uberjar.bat call script/uberjar.bat
call script/compile.bat call script/compile.bat
@ -69,11 +73,15 @@ build_script:
bb --config .build/bb.edn --deps-root . release-artifact %zip% bb --config .build/bb.edn --deps-root . release-artifact %zip%
before_test:
- cmd: >-
set BABASHKA_CLASSPATH= set BABASHKA_CLASSPATH=
set BABASHKA_TEST_ENV=native set BABASHKA_TEST_ENV=native
call script/test.bat test_script:
- cmd: >-
call script/test.bat :windows
call script/run_lib_tests.bat call script/run_lib_tests.bat

@ -1 +1 @@
Subproject commit 99e6d3ba7a7252284b43f9de7d91d3433ecfa8f0 Subproject commit e936acd40544eb637b6041c7e89454b21eb7ee34

@ -1 +1 @@
Subproject commit ad763a78f1bc327a493ff0b650aa5408ecbf4819 Subproject commit edd3d613bfb9bf3adabfd0bda5c3f5c6ee85ec20

@ -1 +1 @@
Subproject commit 2d185718ba2871c96e6cb4a4181d1dcf9d8fde86 Subproject commit aa143f015469884d91f812e16b977ecccdcc2c04

View file

@ -17,10 +17,10 @@
"depstar/src" "process/src" "depstar/src" "process/src"
"deps.clj/src" "deps.clj/resources" "deps.clj/src" "deps.clj/resources"
"resources" "sci/resources" "resources" "sci/resources"
"reify/src"], "impl-java/src"],
:deps {org.clojure/clojure {:mvn/version "1.11.1"}, :deps {org.clojure/clojure {:mvn/version "1.11.2"},
org.babashka/sci {:local/root "sci"} org.babashka/sci {:local/root "sci"}
org.babashka/babashka.impl.reify {:mvn/version "0.1.3"} org.babashka/babashka.impl.java {:mvn/version "0.1.8"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"} org.babashka/sci.impl.types {:mvn/version "0.0.2"}
babashka/babashka.curl {:local/root "babashka.curl"} babashka/babashka.curl {:local/root "babashka.curl"}
babashka/fs {:local/root "fs"} babashka/fs {:local/root "fs"}
@ -29,28 +29,30 @@
org.clojure/core.async {:mvn/version "1.6.673"}, org.clojure/core.async {:mvn/version "1.6.673"},
org.clojure/tools.cli {:mvn/version "1.0.214"}, org.clojure/tools.cli {:mvn/version "1.0.214"},
org.clojure/data.csv {:mvn/version "1.0.0"}, org.clojure/data.csv {:mvn/version "1.0.0"},
cheshire/cheshire {:mvn/version "5.11.0"} cheshire/cheshire {:mvn/version "5.13.0"}
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"} org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
clj-commons/clj-yaml {:mvn/version "0.7.169"} clj-commons/clj-yaml {:mvn/version "1.0.27"}
com.cognitect/transit-clj {:mvn/version "1.0.329"} com.cognitect/transit-clj {:mvn/version "1.0.333"}
org.clojure/test.check {:mvn/version "1.1.1"} org.clojure/test.check {:mvn/version "1.1.1"}
nrepl/bencode {:mvn/version "1.1.0"} nrepl/bencode {:mvn/version "1.1.0"}
seancorfield/next.jdbc {:mvn/version "1.1.610"} seancorfield/next.jdbc {:mvn/version "1.1.610"}
org.postgresql/postgresql {:mvn/version "42.2.18"} org.postgresql/postgresql {:mvn/version "42.2.18"}
org.hsqldb/hsqldb {:mvn/version "2.5.1"} org.hsqldb/hsqldb {:mvn/version "2.5.1"}
datascript/datascript {:mvn/version "1.0.1"} datascript/datascript {:mvn/version "1.0.1"}
http-kit/http-kit {:mvn/version "2.6.0-RC1"} http-kit/http-kit {:mvn/version "2.8.0-RC1"}
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"} babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
org.clojure/core.match {:mvn/version "1.0.0"} org.clojure/core.match {:mvn/version "1.0.0"}
hiccup/hiccup {:mvn/version "2.0.0-alpha2"} hiccup/hiccup {:mvn/version "2.0.0-RC1"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.45"} rewrite-clj/rewrite-clj {:mvn/version "1.1.47"}
selmer/selmer {:mvn/version "1.12.50"} selmer/selmer {:mvn/version "1.12.59"}
com.taoensso/timbre {:mvn/version "6.0.1"} com.taoensso/timbre {:mvn/version "6.5.0"}
org.clojure/tools.logging {:mvn/version "1.1.0"} org.clojure/tools.logging {:mvn/version "1.1.0"}
org.clojure/data.priority-map {:mvn/version "1.1.0"} org.clojure/data.priority-map {:mvn/version "1.1.0"}
insn/insn {:mvn/version "0.5.2"} insn/insn {:mvn/version "0.5.2"}
org.clojure/core.rrb-vector {:mvn/version "0.1.2"} org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
org.babashka/cli {:mvn/version "0.6.41"}} org.babashka/cli {:mvn/version "0.8.59"}
org.babashka/http-client {:mvn/version "0.4.18"}
org.flatland/ordered {:mvn/version "1.15.12"}}
:aliases {:babashka/dev :aliases {:babashka/dev
{:main-opts ["-m" "babashka.main"]} {:main-opts ["-m" "babashka.main"]}
:profile :profile
@ -64,7 +66,7 @@
{:extra-paths ["process/src" "process/test" "test-resources/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"} :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" #_#_org.babashka/spec.alpha {:git/url "https://github.com/babashka/spec.alpha"
:sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"} :sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"}
lambdaisland/regal {:mvn/version "0.0.143"} lambdaisland/regal {:mvn/version "0.0.143"}
cprop/cprop {:mvn/version "0.1.16"} cprop/cprop {:mvn/version "0.1.16"}
comb/comb {:mvn/version "0.1.1"} comb/comb {:mvn/version "0.1.1"}
@ -106,7 +108,7 @@
exoscale/coax {:mvn/version "1.0.0-alpha14"} exoscale/coax {:mvn/version "1.0.0-alpha14"}
orchestra/orchestra {:mvn/version "2021.01.01-1"} orchestra/orchestra {:mvn/version "2021.01.01-1"}
expound/expound {:mvn/version "0.8.10"} expound/expound {:mvn/version "0.8.10"}
integrant/integrant {:mvn/version "0.8.0"} integrant/integrant {:git/url "https://github.com/weavejester/integrant", :git/sha "a9fd7c02bd7201f36344b47142badc3c3ef22f88"}
com.stuartsierra/dependency {:mvn/version "1.0.0"} com.stuartsierra/dependency {:mvn/version "1.0.0"}
listora/again {:mvn/version "1.0.0"} listora/again {:mvn/version "1.0.0"}
org.clojure/tools.gitlibs {:mvn/version "2.4.172"} org.clojure/tools.gitlibs {:mvn/version "2.4.172"}
@ -165,7 +167,12 @@
:git/sha "1a29775a3d286f9f6fe3f979c78b6e2bf298d5ba"} :git/sha "1a29775a3d286f9f6fe3f979c78b6e2bf298d5ba"}
com.github.rawleyfowler/sluj {:git/url "https://github.com/rawleyfowler/sluj" com.github.rawleyfowler/sluj {:git/url "https://github.com/rawleyfowler/sluj"
:git/sha "4a92e772b4e07bf127423448d4140748b5782198" :git/sha "4a92e772b4e07bf127423448d4140748b5782198"
:deps/manifest :deps}} :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"}}
:classpath-overrides {org.clojure/clojure nil :classpath-overrides {org.clojure/clojure nil
org.clojure/spec.alpha nil}} org.clojure/spec.alpha nil}}
:clj-nvd :clj-nvd

@ -1 +1 @@
Subproject commit c419b8c82041855d55593c5b561fc7cea8234712 Subproject commit 2bf9d3c9f15298d7dd9de033674a42f830e23d6f

View file

@ -3,24 +3,24 @@
## Prerequisites ## Prerequisites
- Install [lein](https://leiningen.org/) for producing uberjars - Install [lein](https://leiningen.org/) for producing uberjars
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *java11-22.3.0*. - Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *jdk-22*.
- For Windows, installing Visual Studio 2019 with the "Desktop development - For Windows, installing Visual Studio 2019 with the "Desktop development
with C++" workload is recommended. with C++" workload is recommended.
- Set `$GRAALVM_HOME` to the GraalVM distribution directory. On macOS this can look like: - Set `$GRAALVM_HOME` to the GraalVM distribution directory. On macOS this can look like:
``` shell ``` shell
export GRAALVM_HOME=~/Downloads/graalvm-ce-java11-22.3.0/Contents/Home export GRAALVM_HOME=~/Downloads/graalvm-jdk-21.0.0.1/Contents/Home
``` ```
On linux: On linux:
``` shell ``` shell
export GRAALVM_HOME=~/Downloads/graalvm-ce-java11-22.3.0 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): 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-java11-22.3.0 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: If you are not running from the x64 Native Tools Command Prompt, you will need to set additional environment variables using:
``` ```

View file

@ -64,6 +64,7 @@ Sponsoring via [Cognitect](https://www.cognitect.com/).
- [Fluree](https://flur.ee/) - [Fluree](https://flur.ee/)
- [Hi](https://www.hi.group/) - [Hi](https://www.hi.group/)
- [Juxt](https://www.juxt.pro/) - [Juxt](https://www.juxt.pro/)
- [Kleene](https://www.kleene.ai/)
- [Latacora](https://www.latacora.com/) - [Latacora](https://www.latacora.com/)
- [Metosin](https://www.metosin.fi/en/) - [Metosin](https://www.metosin.fi/en/)
- [Nextdoc](https://www.nextdoc.io/) - [Nextdoc](https://www.nextdoc.io/)

View file

@ -37,7 +37,7 @@ reasons:
## Requirements ## Requirements
You need [lein](https://leiningen.org/) for running JVM tests and/or producing uberjars. For building binaries you need GraalVM. Currently we use java11-22.3.0. You need [lein](https://leiningen.org/) for running JVM tests and/or producing uberjars. For building binaries you need GraalVM. Currently we use jdk-21.0.0.1
## Clone repository ## Clone repository

View file

@ -67,6 +67,7 @@ meta-merge/meta-merge,https://github.com/weavejester/meta-merge
metosin/malli,https://github.com/metosin/malli metosin/malli,https://github.com/metosin/malli
minimallist/minimallist,https://github.com/green-coder/minimallist minimallist/minimallist,https://github.com/green-coder/minimallist
mvxcvi/arrangement,https://github.com/greglook/clj-arrangement mvxcvi/arrangement,https://github.com/greglook/clj-arrangement
net.cgrand/xforms,https://github.com/cgrand/xforms
orchestra/orchestra,https://github.com/jeaye/orchestra orchestra/orchestra,https://github.com/jeaye/orchestra
org.babashka/spec.alpha,https://github.com/babashka/spec.alpha 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/clj-http-lite,https://github.com/clj-commons/clj-http-lite
@ -83,7 +84,7 @@ org.clojure/math.combinatorics,https://github.com/clojure/math.combinatorics
org.clojure/math.numeric-tower,https://github.com/clojure/math.numeric-tower org.clojure/math.numeric-tower,https://github.com/clojure/math.numeric-tower
org.clojure/test.check,https://github.com/clojure/test.check org.clojure/test.check,https://github.com/clojure/test.check
org.clojure/tools.gitlibs,https://github.com/clojure/tools.gitlibs org.clojure/tools.gitlibs,https://github.com/clojure/tools.gitlibs
org.clojure/tools.namespace,https://github.com/babashka/tools.namespace org.clojure/tools.namespace,https://github.com/clojure/tools.namespace
postmortem/postmortem,https://github.com/athos/Postmortem postmortem/postmortem,https://github.com/athos/Postmortem
prismatic/schema,https://github.com/plumatic/schema prismatic/schema,https://github.com/plumatic/schema
progrock/progrock,https://github.com/weavejester/progrock progrock/progrock,https://github.com/weavejester/progrock

1 maven-name git-url
67 metosin/malli https://github.com/metosin/malli
68 minimallist/minimallist https://github.com/green-coder/minimallist
69 mvxcvi/arrangement https://github.com/greglook/clj-arrangement
70 net.cgrand/xforms https://github.com/cgrand/xforms
71 orchestra/orchestra https://github.com/jeaye/orchestra
72 org.babashka/spec.alpha https://github.com/babashka/spec.alpha
73 org.clj-commons/clj-http-lite https://github.com/clj-commons/clj-http-lite
84 org.clojure/math.numeric-tower https://github.com/clojure/math.numeric-tower
85 org.clojure/test.check https://github.com/clojure/test.check
86 org.clojure/tools.gitlibs https://github.com/clojure/tools.gitlibs
87 org.clojure/tools.namespace https://github.com/babashka/tools.namespace https://github.com/clojure/tools.namespace
88 postmortem/postmortem https://github.com/athos/Postmortem
89 prismatic/schema https://github.com/plumatic/schema
90 progrock/progrock https://github.com/weavejester/progrock

View file

@ -5,8 +5,234 @@ you have anything to add. Also see
[#babashka](https://twitter.com/hashtag/babashka?src=hashtag_click&f=live) on [#babashka](https://twitter.com/hashtag/babashka?src=hashtag_click&f=live) on
Twitter. Twitter.
## [2022-07](https://twitter.com/search?q=(%23babashka)%20until%3A2022-08-01%20since%3A2022-07-01&src=typed_query&f=live) ## 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 - [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 - [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 - [Quickblog](https://github.com/borkdude/quickblog): Light-weight static blog engine for Clojure and babashka
@ -23,7 +249,7 @@ Twitter.
- [Deleting AWS Glacier vaults with babashka](https://javahippie.net/clojure/2022/07/23/deleting-aws-glacier-vaults-with-babashka.html) by Tim Zöller - [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=(%23babashka)%20until%3A2022-07-01%20since%3A2022-06-01&src=typed_query&f=live) ## [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). - Releases: [0.8.156](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [AWS wiki page](https://github.com/babashka/babashka/wiki/AWS) - [AWS wiki page](https://github.com/babashka/babashka/wiki/AWS)
@ -37,7 +263,7 @@ Twitter.
- [Logseq bb tasks](https://github.com/logseq/bb-tasks): Reusable babashka tasks used by logseq team - [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 - [Breakneck Babashka on K8s](Breakneck Babashka on K8s) by Heow Goodman
## [2022-05](https://twitter.com/search?q=(%23babashka)%20until%3A2022-06-01%20since%3A2022-05-01&src=typed_query&f=live) ## [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). - 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. - [Etaoin](https://github.com/clj-commons/etaoin) moved to clj-commons and now works with babashka as well.
@ -47,7 +273,7 @@ Twitter.
- [Quickdoc](https://github.com/borkdude/quickdoc): (Quick and minimal API doc generation for Clojure - [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 - [Awyeah-api](https://github.com/grzm/awyeah-api) - Cognitect's aws-api for babashka
## [2022-04](https://twitter.com/search?q=(%23babashka)%20until%3A2022-05-01%20since%3A2022-04-01&src=typed_query&f=live) ## [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). - 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 - [Babashka and Clojure](https://youtu.be/ZvOs5Ele6VE) by Rahul Dé at North Virginia Linux Users Group
@ -55,7 +281,7 @@ Twitter.
- Control Chrome via devtools using [clj-chrome-devtools](https://github.com/tatut/clj-chrome-devtools/blob/master/bb.clj) which runs with bb! - 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) - Use pods directly in `bb.edn`: [tweet](https://twitter.com/borkdude/status/1510995356229767172)
## [2022-03](https://twitter.com/search?q=(%23babashka)%20until%3A2022-04-01%20since%3A2022-03-01&src=typed_query&f=live) ## [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). - 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 - [Create a password manager with Clojure using Babashka, sqlite, honeysql and stash](https://youtu.be/jm0RXmyjRJ8) by Daniel Amber
@ -65,7 +291,7 @@ Twitter.
- The [loom](https://github.com/aysylu/loom) library is now compatible [(tweet)](https://twitter.com/borkdude/status/1502237220811550723) - 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 - The [at-at](https://github.com/overtone/at-at) library is now compatible
## [2022-02](https://twitter.com/search?q=(%23babashka)%20until%3A2022-03-01%20since%3A2022-02-01&src=typed_query&f=live) ## [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). - 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) - [Spire is available as a babashka pod](https://twitter.com/epic_castle/status/1496784352256008194)
@ -78,7 +304,7 @@ Twitter.
- [Apptemplate](https://github.com/redstarssystems/apptemplate): Application project template for Clojure featuring bb tasks - [Apptemplate](https://github.com/redstarssystems/apptemplate): Application project template for Clojure featuring bb tasks
## [2022-01](https://twitter.com/search?f=live&q=(%23babashka)%20until%3A2022-02-01%20since%3A2022-01-01&src=typed_query) ## [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). - Releases: [0.7.4](https://github.com/babashka/babashka/blob/master/CHANGELOG.md).
- [Babashka dev builds](https://github.com/babashka/babashka-dev-builds) - [Babashka dev builds](https://github.com/babashka/babashka-dev-builds)

View file

@ -66,6 +66,7 @@ The following libraries and projects are known to work with babashka.
- [Meander](#meander) - [Meander](#meander)
- [Schema](#schema) - [Schema](#schema)
- [Sluj](#sluj) - [Sluj](#sluj)
- [malli-cli](#malli-cli)
- [Pods](#pods) - [Pods](#pods)
- [Projects](#projects-1) - [Projects](#projects-1)
- [babashka-test-action](#babashka-test-action) - [babashka-test-action](#babashka-test-action)
@ -833,6 +834,10 @@ Clojure(Script) library for declarative data description and validation
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. 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 ## Pods
[Babashka pods](https://github.com/babashka/babashka.pods) are programs that can [Babashka pods](https://github.com/babashka/babashka.pods) are programs that can

View file

@ -15,4 +15,8 @@
'send-checked-websocket-handshake! (copy-var server/send-checked-websocket-handshake! sns) 'send-checked-websocket-handshake! (copy-var server/send-checked-websocket-handshake! sns)
'send-websocket-handshake! (copy-var server/send-websocket-handshake! sns) 'send-websocket-handshake! (copy-var server/send-websocket-handshake! sns)
'as-channel (copy-var server/as-channel sns) 'as-channel (copy-var server/as-channel sns)
'send! (copy-var server/send! 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

@ -13,56 +13,78 @@
(defn- fline [and-form] (:line (meta and-form))) (defn- fline [and-form] (:line (meta and-form)))
(defonce callsite-counter
(enc/counter))
(defmacro log! ; Public wrapper around `-log!` (defmacro log! ; Public wrapper around `-log!`
"Core low-level log macro. Useful for tooling, etc. "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}
* `opts` - ks e/o #{:config :?err :?ns-str :?file :?line :?base-data :spying?}
Supports compile-time elision when compile-time const vals
provided for `level` and/or `?ns-str`."
[level msg-type args & [opts]]
(have [:or nil? sequential?] args) ; To allow -> (delay [~@args])
(let [{:keys [?ns-str] :or {?ns-str (str @sci/ns)}} opts]
;; level, ns may/not be compile-time consts:
(when-not (timbre/-elide? level ?ns-str)
(let [{:keys [config ?err ?file ?line ?base-data spying?]
:or {config 'taoensso.timbre/*config*
?err :auto ; => Extract as err-type v0
?file @sci/file
;; NB waiting on CLJ-865:
?line (fline &form)}} opts
?file (when (not= ?file "NO_SOURCE_PATH") ?file) * `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}
;; Identifies this particular macro expansion; note that this'll Supports compile-time elision when compile-time const vals
;; be fixed for any fns wrapping `log!` (notably `tools.logging`, provided for `level` and/or `?ns-str`.
;; `slf4j-timbre`, etc.):
callsite-id
(hash [level msg-type args ; Unevaluated args (arg forms)
?ns-str ?file ?line (rand)])]
`(taoensso.timbre/-log! ~config ~level ~?ns-str ~?file ~?line ~msg-type ~?err Logging wrapper examples:
(delay [~@args]) ~?base-data ~callsite-id ~spying?)))))
(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?)))))
([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] (defn make-ns [ns sci-ns ks]
(reduce (fn [ns-map [var-name var]] (reduce (fn [ns-map [var-name var]]
(let [m (meta var) (let [m (meta var)
no-doc (:no-doc m)
doc (:doc m) doc (:doc m)
arglists (:arglists m)] arglists (:arglists m)]
(if no-doc ns-map (assoc ns-map var-name
(assoc ns-map var-name (sci/new-var (symbol var-name) @var
(sci/new-var (symbol var-name) @var (cond-> {:ns sci-ns
(cond-> {:ns sci-ns :name (:name m)}
:name (:name m)} (:macro m) (assoc :macro true)
(:macro m) (assoc :macro true) doc (assoc :doc doc)
doc (assoc :doc doc) arglists (assoc :arglists arglists))))))
arglists (assoc :arglists arglists)))))))
{} {}
(select-keys (ns-publics ns) ks))) (select-keys (ns-publics ns) ks)))
(def atomic-println @#'appenders/atomic-println)
(defn println-appender (defn println-appender
"Returns a simple `println` appender for Clojure/Script. "Returns a simple `println` appender for Clojure/Script.
Use with ClojureScript requires that `cljs.core/*print-fn*` be set. Use with ClojureScript requires that `cljs.core/*print-fn*` be set.
@ -92,7 +114,7 @@
:*err* @sci/err :*err* @sci/err
stream)] stream)]
(binding [*out* stream] (binding [*out* stream]
(atomic-println (force output_)))))})) (enc/println-atomic (force output_)))))}))
(def default-config (assoc-in timbre/*config* [:appenders :println] (def default-config (assoc-in timbre/*config* [:appenders :println]
(println-appender {:stream :auto}))) (println-appender {:stream :auto})))
@ -127,7 +149,13 @@
'merge-config! (sci/copy-var merge-config! tns) 'merge-config! (sci/copy-var merge-config! tns)
'set-level! (sci/copy-var set-level! tns) 'set-level! (sci/copy-var set-level! tns)
'println-appender (sci/copy-var println-appender tns) 'println-appender (sci/copy-var println-appender tns)
'-log-and-rethrow-errors (sci/copy-var -log-and-rethrow-errors tns))) '-log-and-rethrow-errors (sci/copy-var -log-and-rethrow-errors tns)
'-ensure-vec (sci/copy-var enc/ensure-vec tns)))
(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 ;;;; clojure.tools.logging

View file

@ -4,6 +4,7 @@
[babashka.impl.common :refer [ctx]] [babashka.impl.common :refer [ctx]]
[sci.core :as sci] [sci.core :as sci]
[selmer.filters :as filters] [selmer.filters :as filters]
[selmer.filter-parser :as fp]
[selmer.parser] [selmer.parser]
[selmer.tags :as tags] [selmer.tags :as tags]
[selmer.util :as util] [selmer.util :as util]
@ -83,12 +84,31 @@
(apply merge) (apply merge)
(selmer.parser/render ~s))) (selmer.parser/render ~s)))
(defn resolve-arg
"Resolves an arg as passed to an add-tag! handler using the provided
context-map.
A custom tag handler will receive a seq of args as its first argument.
With this function, you can selectively resolve one or more of those args
so that if they contain literals, the literal value is returned, and if they
contain templates of any sort, which can itself have variables, filters or
tags in it, they will be returned resolved, applied and rendered.
Example:
(resolve-arg {{header-name|upper}} {:header-name \"My Page\"})
=> \"MY PAGE\""
[arg context-map]
(if (fp/literal? arg)
(fp/parse-literal arg)
(render arg context-map)))
(def selmer-parser-namespace (def selmer-parser-namespace
(-> selmer-parser-ns (-> selmer-parser-ns
(assoc 'render-file (sci/copy-var render-file spns) (assoc 'render-file (sci/copy-var render-file spns)
'render (sci/copy-var render spns) 'render (sci/copy-var render spns)
'render-template (sci/copy-var render-template spns) 'render-template (sci/copy-var render-template spns)
'resolve-var-from-kw (sci/copy-var resolve-var-from-kw spns) 'resolve-var-from-kw (sci/copy-var resolve-var-from-kw spns)
'resolve-arg (sci/copy-var resolve-arg spns )
'<< (sci/copy-var << spns)))) '<< (sci/copy-var << spns))))
(def stns (sci/create-ns 'selmer.tags nil)) (def stns (sci/create-ns 'selmer.tags nil))
@ -105,7 +125,9 @@
(def selmer-filters-namespace (def selmer-filters-namespace
{'add-filter! (sci/copy-var filters/add-filter! sfns) {'add-filter! (sci/copy-var filters/add-filter! sfns)
'remove-filter! (sci/copy-var filters/remove-filter! sfns)}) 'remove-filter! (sci/copy-var filters/remove-filter! sfns)
'get-filter (sci/copy-var filters/get-filter sfns)
'filters (sci/copy-var filters/filters sfns)})
(defn turn-off-escaping! [] (defn turn-off-escaping! []
(sci/alter-var-root escape-variables (constantly false))) (sci/alter-var-root escape-variables (constantly false)))

View file

@ -1,9 +1,14 @@
(ns babashka.impl.ordered (ns babashka.impl.ordered
{:no-doc true} {:no-doc true}
(:require [flatland.ordered.map :as omap] (:require [flatland.ordered.map :as omap]
[flatland.ordered.set :as oset]
[sci.core :as sci])) [sci.core :as sci]))
(def omap-ns (sci/create-ns 'flatland.ordered.map nil)) (def omap-ns (sci/create-ns 'flatland.ordered.map nil))
(def oset-ns (sci/create-ns 'flatland.ordered.set nil))
(def ordered-map-ns (def ordered-map-ns
{'ordered-map (sci/copy-var omap/ordered-map omap-ns)}) {'ordered-map (sci/copy-var omap/ordered-map omap-ns)})
(def ordered-set-ns
{'ordered-set (sci/copy-var oset/ordered-set oset-ns)})

2
fs

@ -1 +1 @@
Subproject commit d3226cccd9898eba5adb50dfcc30a7223ff5c8cc Subproject commit 8658cab4981158dfd439b55b5932a276c4b65bf2

View file

@ -2,8 +2,8 @@
(:require [build.reify2 :as reify2] (:require [build.reify2 :as reify2]
[clojure.tools.build.api :as b])) [clojure.tools.build.api :as b]))
(def lib 'org.babashka/babashka.impl.reify) (def lib 'org.babashka/babashka.impl.java)
(def version "0.1.3") (def version "0.1.8")
(def class-dir "target/classes") (def class-dir "target/classes")
(def basis (b/create-basis {:project "deps.edn"})) (def basis (b/create-basis {:project "deps.edn"}))
(def jar-file (format "target/%s-%s.jar" (name lib) version)) (def jar-file (format "target/%s-%s.jar" (name lib) version))
@ -14,7 +14,13 @@
(defn gen-classes [_] (defn gen-classes [_]
(reify2/gen-classes nil)) (reify2/gen-classes nil))
(defn compile-java [_]
(b/javac {:src-dirs ["src-java"]
:class-dir class-dir
:basis basis}))
(defn jar [_] (defn jar [_]
(compile-java nil)
(gen-classes nil) (gen-classes nil)
(b/write-pom {:class-dir class-dir (b/write-pom {:class-dir class-dir
:lib lib :lib lib

View file

@ -0,0 +1,94 @@
// This file is mostly a workaround for https://github.com/oracle/graal/issues/1956
package babashka.impl;
import java.util.WeakHashMap;
import java.io.*;
import java.util.Objects;
import java.net.*;
import java.util.jar.*;
public class URLClassLoader extends java.net.URLClassLoader implements Closeable {
private WeakHashMap<Closeable,Void>
closeables = new WeakHashMap<>();
public URLClassLoader(java.net.URL[] urls) {
super(urls);
}
public URLClassLoader(java.net.URL[] urls, java.net.URLClassLoader parent) {
super(urls, parent);
}
public void _addURL(java.net.URL url) {
super.addURL(url);
}
// calling super.getResource() returned nil in native-image
public java.net.URL getResource(String name) {
return findResource(name);
}
// calling super.getResourceAsStream() returned nil in native-image
public InputStream getResourceAsStream(String name) {
Objects.requireNonNull(name);
URL url = getResource(name);
try {
if (url == null) {
return null;
}
URLConnection urlc = url.openConnection();
InputStream is = urlc.getInputStream();
if (urlc instanceof JarURLConnection) {
JarFile jar = ((JarURLConnection)urlc).getJarFile();
synchronized (closeables) {
if (!closeables.containsKey(jar)) {
closeables.put(jar, null);
}
}
} else {
synchronized (closeables) {
closeables.put(is, null);
}
}
return is;
} catch (IOException e) {
return null;
}
}
public java.util.Enumeration<java.net.URL> getResources(String name) throws java.io.IOException {
return findResources(name);
}
public void close() throws IOException {
super.close();
java.util.List<IOException> errors = new java.util.ArrayList<IOException>();
synchronized (closeables) {
java.util.Set<Closeable> keys = closeables.keySet();
for (Closeable c : keys) {
try {
c.close();
} catch (IOException ex) {
errors.add(ex);
}
}
closeables.clear();
}
if (errors.isEmpty()) {
return;
}
IOException firstEx = errors.remove(0);
for (IOException error: errors) {
firstEx.addSuppressed(error);
}
throw firstEx;
}
}

View file

@ -31,4 +31,7 @@
java.lang.Comparable java.lang.Comparable
javax.net.ssl.X509TrustManager javax.net.ssl.X509TrustManager
clojure.lang.LispReader$Resolver clojure.lang.LispReader$Resolver
sun.misc.SignalHandler]) sun.misc.SignalHandler
java.util.concurrent.ThreadFactory
java.lang.Thread$UncaughtExceptionHandler
java.util.concurrent.Callable])

View file

@ -96,7 +96,11 @@ IFS='.' read -ra VER <<< "${version//-SNAPSHOT/}"
vernum=$(printf "%03d%03d%03d" "${VER[0]}" "${VER[1]}" "${VER[2]}") vernum=$(printf "%03d%03d%03d" "${VER[0]}" "${VER[1]}" "${VER[2]}")
case "$(uname -m)" in case "$(uname -m)" in
aarch64) arch=aarch64;; aarch64) arch=aarch64
if [[ "$platform" == "linux" ]]; then
static_binary="true"
fi
;;
arm64) if [[ 10#$vernum -le 10#000008002 ]]; then arm64) if [[ 10#$vernum -le 10#000008002 ]]; then
arch="amd64" arch="amd64"
else else

2
pods

@ -1 +1 @@
Subproject commit decf791000081ca9e6d2fbea9f20a0aa3fae902e Subproject commit 717cef7af5cb1c1b091bd10e012b2e71b7b8b9bc

@ -1 +1 @@
Subproject commit 90e4cf0b0cc7856f8c39591c3350cdf156d11042 Subproject commit 7b02584145992832c4a50f4f571b009ff093585d

View file

@ -11,35 +11,40 @@
"babashka.core/src" "babashka.core/src"
"babashka.nrepl/src" "depstar/src" "process/src" "babashka.nrepl/src" "depstar/src" "process/src"
"deps.clj/src" "deps.clj/resources" "deps.clj/src" "deps.clj/resources"
"reify/src"] "impl-java/src"]
;; for debugging Reflector.java code: ;; for debugging Reflector.java code:
;; :java-source-paths ["sci/reflector/src-java"] ;; :java-source-paths ["sci/reflector/src-java"]
:java-source-paths ["src-java"] :java-source-paths ["src-java"]
:resource-paths ["resources" "sci/resources"] :resource-paths ["resources" "sci/resources"]
:test-selectors {:default (complement :windows-only) :test-selectors {:default (complement (some-fn :windows-only :flaky))
:windows (complement :skip-windows)} :windows (complement (some-fn :skip-windows :flaky))
:dependencies [[org.clojure/clojure "1.11.1"] :non-flaky (complement :flaky)
[borkdude/edamame "1.0.16"] :flaky :flaky}
:jvm-opts ["--enable-preview"]
:dependencies [[org.clojure/clojure "1.11.2"]
[borkdude/edamame "1.4.24"]
[borkdude/graal.locking "0.0.2"] [borkdude/graal.locking "0.0.2"]
[org.clojure/tools.cli "1.0.214"] [org.clojure/tools.cli "1.0.214"]
[cheshire "5.11.0"] [cheshire "5.13.0"]
[nrepl/bencode "1.1.0"] [nrepl/bencode "1.1.0"]
[borkdude/sci.impl.reflector "0.0.1"] [borkdude/sci.impl.reflector "0.0.1"]
[org.babashka/sci.impl.types "0.0.2"] [org.babashka/sci.impl.types "0.0.2"]
[org.babashka/babashka.impl.reify "0.1.3"] [org.babashka/babashka.impl.java "0.1.8"]
[org.clojure/core.async "1.6.673"] [org.clojure/core.async "1.6.673"]
[org.clojure/test.check "1.1.1"] [org.clojure/test.check "1.1.1"]
[com.github.clj-easy/graal-build-time "0.1.0"] [com.github.clj-easy/graal-build-time "0.1.0"]
[rewrite-clj/rewrite-clj "1.1.45"] [rewrite-clj/rewrite-clj "1.1.47"]
[insn/insn "0.5.2"] [insn/insn "0.5.2"]
[org.babashka/cli "0.6.41"]] [org.babashka/cli "0.8.59"]
[org.babashka/http-client "0.4.18"]]
:plugins [[org.kipz/lein-meta-bom "0.1.1"]] :plugins [[org.kipz/lein-meta-bom "0.1.1"]]
:metabom {:jar-name "metabom.jar"} :metabom {:jar-name "metabom.jar"}
:profiles {:feature/xml {:source-paths ["feature-xml"] :profiles {:feature/xml {:source-paths ["feature-xml"]
:dependencies [[org.clojure/data.xml "0.2.0-alpha8"]]} :dependencies [[org.clojure/data.xml "0.2.0-alpha8"]]}
:feature/yaml {:source-paths ["feature-yaml"] :feature/yaml {:source-paths ["feature-yaml"]
:dependencies [[clj-commons/clj-yaml "0.7.169" :dependencies [[clj-commons/clj-yaml "1.0.27"
#_#_clj-commons/clj-yaml "0.7.110"]]} :exclusions [org.flatland/ordered]#_#_clj-commons/clj-yaml "0.7.110"]
[org.flatland/ordered "1.15.12"]]}
:feature/jdbc {:source-paths ["feature-jdbc"] :feature/jdbc {:source-paths ["feature-jdbc"]
:dependencies [[seancorfield/next.jdbc "1.1.610"]]} :dependencies [[seancorfield/next.jdbc "1.1.610"]]}
:feature/sqlite [:feature/jdbc {:dependencies [[org.xerial/sqlite-jdbc "3.36.0.3"]]}] :feature/sqlite [:feature/jdbc {:dependencies [[org.xerial/sqlite-jdbc "3.36.0.3"]]}]
@ -50,25 +55,25 @@
:feature/csv {:source-paths ["feature-csv"] :feature/csv {:source-paths ["feature-csv"]
:dependencies [[org.clojure/data.csv "1.0.0"]]} :dependencies [[org.clojure/data.csv "1.0.0"]]}
:feature/transit {:source-paths ["feature-transit"] :feature/transit {:source-paths ["feature-transit"]
:dependencies [[com.cognitect/transit-clj "1.0.329"]]} :dependencies [[com.cognitect/transit-clj "1.0.333"]]}
:feature/datascript {:source-paths ["feature-datascript"] :feature/datascript {:source-paths ["feature-datascript"]
:dependencies [[datascript "1.3.10"]]} :dependencies [[datascript "1.3.10"]]}
:feature/httpkit-client {:source-paths ["feature-httpkit-client"] :feature/httpkit-client {:source-paths ["feature-httpkit-client"]
:dependencies [[http-kit "2.6.0-RC1"]]} :dependencies [[http-kit "2.8.0-RC1"]]}
:feature/httpkit-server {:source-paths ["feature-httpkit-server"] :feature/httpkit-server {:source-paths ["feature-httpkit-server"]
:dependencies [[http-kit "2.6.0-RC1"]]} :dependencies [[http-kit "2.8.0-RC1"]]}
:feature/lanterna {:source-paths ["feature-lanterna"] :feature/lanterna {:source-paths ["feature-lanterna"]
:dependencies [[babashka/clojure-lanterna "0.9.8-SNAPSHOT"]]} :dependencies [[babashka/clojure-lanterna "0.9.8-SNAPSHOT"]]}
:feature/core-match {:source-paths ["feature-core-match"] :feature/core-match {:source-paths ["feature-core-match"]
:dependencies [[org.clojure/core.match "1.0.0"]]} :dependencies [[org.clojure/core.match "1.0.0"]]}
:feature/hiccup {:source-paths ["feature-hiccup"] :feature/hiccup {:source-paths ["feature-hiccup"]
:dependencies [[hiccup/hiccup "2.0.0-alpha2"]]} :dependencies [[hiccup/hiccup "2.0.0-RC1"]]}
:feature/test-check {:source-paths ["feature-test-check"]} :feature/test-check {:source-paths ["feature-test-check"]}
:feature/spec-alpha {:source-paths ["feature-spec-alpha"]} :feature/spec-alpha {:source-paths ["feature-spec-alpha"]}
:feature/selmer {:source-paths ["feature-selmer"] :feature/selmer {:source-paths ["feature-selmer"]
:dependencies [[selmer/selmer "1.12.50"]]} :dependencies [[selmer/selmer "1.12.59"]]}
:feature/logging {:source-paths ["feature-logging"] :feature/logging {:source-paths ["feature-logging"]
:dependencies [[com.taoensso/timbre "6.0.1"] :dependencies [[com.taoensso/timbre "6.5.0"]
[org.clojure/tools.logging "1.1.0"]]} [org.clojure/tools.logging "1.1.0"]]}
:feature/priority-map {:source-paths ["feature-priority-map"] :feature/priority-map {:source-paths ["feature-priority-map"]
:dependencies [[org.clojure/data.priority-map "1.1.0"]]} :dependencies [[org.clojure/data.priority-map "1.1.0"]]}
@ -92,7 +97,8 @@
:feature/logging :feature/logging
:feature/priority-map :feature/priority-map
:feature/rrb-vector :feature/rrb-vector
{:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.5.0"] {:dependencies [[borkdude/rewrite-edn "0.4.6"]
[com.clojure-goes-fast/clj-async-profiler "0.5.0"]
[com.opentable.components/otj-pg-embedded "0.13.3"] [com.opentable.components/otj-pg-embedded "0.13.3"]
[nubank/matcher-combinators "3.6.0"]]}] [nubank/matcher-combinators "3.6.0"]]}]
:uberjar {:global-vars {*assert* false} :uberjar {:global-vars {*assert* false}

View file

@ -1 +1 @@
1.0.168 1.3.190

View file

@ -1 +1 @@
1.0.169-SNAPSHOT 1.3.191-SNAPSHOT

View file

@ -17,10 +17,10 @@
"depstar/src" "process/src" "depstar/src" "process/src"
"deps.clj/src" "deps.clj/resources" "deps.clj/src" "deps.clj/resources"
"resources" "sci/resources" "resources" "sci/resources"
"reify/src"], "impl-java/src"],
:deps {org.clojure/clojure {:mvn/version "1.11.1"}, :deps {org.clojure/clojure {:mvn/version "1.11.2"},
org.babashka/sci {:local/root "sci"} org.babashka/sci {:local/root "sci"}
org.babashka/babashka.impl.reify {:mvn/version "0.1.3"} org.babashka/babashka.impl.java {:mvn/version "0.1.8"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"} org.babashka/sci.impl.types {:mvn/version "0.0.2"}
babashka/babashka.curl {:local/root "babashka.curl"} babashka/babashka.curl {:local/root "babashka.curl"}
babashka/fs {:local/root "fs"} babashka/fs {:local/root "fs"}
@ -29,28 +29,30 @@
org.clojure/core.async {:mvn/version "1.6.673"}, org.clojure/core.async {:mvn/version "1.6.673"},
org.clojure/tools.cli {:mvn/version "1.0.214"}, org.clojure/tools.cli {:mvn/version "1.0.214"},
org.clojure/data.csv {:mvn/version "1.0.0"}, org.clojure/data.csv {:mvn/version "1.0.0"},
cheshire/cheshire {:mvn/version "5.11.0"} cheshire/cheshire {:mvn/version "5.13.0"}
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"} org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
clj-commons/clj-yaml {:mvn/version "0.7.169"} clj-commons/clj-yaml {:mvn/version "1.0.27"}
com.cognitect/transit-clj {:mvn/version "1.0.329"} com.cognitect/transit-clj {:mvn/version "1.0.333"}
org.clojure/test.check {:mvn/version "1.1.1"} org.clojure/test.check {:mvn/version "1.1.1"}
nrepl/bencode {:mvn/version "1.1.0"} nrepl/bencode {:mvn/version "1.1.0"}
seancorfield/next.jdbc {:mvn/version "1.1.610"} seancorfield/next.jdbc {:mvn/version "1.1.610"}
org.postgresql/postgresql {:mvn/version "42.2.18"} org.postgresql/postgresql {:mvn/version "42.2.18"}
org.hsqldb/hsqldb {:mvn/version "2.5.1"} org.hsqldb/hsqldb {:mvn/version "2.5.1"}
datascript/datascript {:mvn/version "1.0.1"} datascript/datascript {:mvn/version "1.0.1"}
http-kit/http-kit {:mvn/version "2.6.0-RC1"} http-kit/http-kit {:mvn/version "2.8.0-RC1"}
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"} babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
org.clojure/core.match {:mvn/version "1.0.0"} org.clojure/core.match {:mvn/version "1.0.0"}
hiccup/hiccup {:mvn/version "2.0.0-alpha2"} hiccup/hiccup {:mvn/version "2.0.0-RC1"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.45"} rewrite-clj/rewrite-clj {:mvn/version "1.1.47"}
selmer/selmer {:mvn/version "1.12.50"} selmer/selmer {:mvn/version "1.12.59"}
com.taoensso/timbre {:mvn/version "6.0.1"} com.taoensso/timbre {:mvn/version "6.5.0"}
org.clojure/tools.logging {:mvn/version "1.1.0"} org.clojure/tools.logging {:mvn/version "1.1.0"}
org.clojure/data.priority-map {:mvn/version "1.1.0"} org.clojure/data.priority-map {:mvn/version "1.1.0"}
insn/insn {:mvn/version "0.5.2"} insn/insn {:mvn/version "0.5.2"}
org.clojure/core.rrb-vector {:mvn/version "0.1.2"} org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
org.babashka/cli {:mvn/version "0.6.41"}} org.babashka/cli {:mvn/version "0.8.58"}
org.babashka/http-client {:mvn/version "0.4.16"}
org.flatland/ordered {:mvn/version "1.15.12"}}
:aliases {:babashka/dev :aliases {:babashka/dev
{:main-opts ["-m" "babashka.main"]} {:main-opts ["-m" "babashka.main"]}
:profile :profile
@ -64,7 +66,7 @@
{:extra-paths ["process/src" "process/test" "test-resources/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"} :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" #_#_org.babashka/spec.alpha {:git/url "https://github.com/babashka/spec.alpha"
:sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"} :sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"}
lambdaisland/regal {:mvn/version "0.0.143"} lambdaisland/regal {:mvn/version "0.0.143"}
cprop/cprop {:mvn/version "0.1.16"} cprop/cprop {:mvn/version "0.1.16"}
comb/comb {:mvn/version "0.1.1"} comb/comb {:mvn/version "0.1.1"}
@ -106,7 +108,7 @@
exoscale/coax {:mvn/version "1.0.0-alpha14"} exoscale/coax {:mvn/version "1.0.0-alpha14"}
orchestra/orchestra {:mvn/version "2021.01.01-1"} orchestra/orchestra {:mvn/version "2021.01.01-1"}
expound/expound {:mvn/version "0.8.10"} expound/expound {:mvn/version "0.8.10"}
integrant/integrant {:mvn/version "0.8.0"} integrant/integrant {:git/url "https://github.com/weavejester/integrant", :git/sha "a9fd7c02bd7201f36344b47142badc3c3ef22f88"}
com.stuartsierra/dependency {:mvn/version "1.0.0"} com.stuartsierra/dependency {:mvn/version "1.0.0"}
listora/again {:mvn/version "1.0.0"} listora/again {:mvn/version "1.0.0"}
org.clojure/tools.gitlibs {:mvn/version "2.4.172"} org.clojure/tools.gitlibs {:mvn/version "2.4.172"}
@ -165,7 +167,12 @@
:git/sha "1a29775a3d286f9f6fe3f979c78b6e2bf298d5ba"} :git/sha "1a29775a3d286f9f6fe3f979c78b6e2bf298d5ba"}
com.github.rawleyfowler/sluj {:git/url "https://github.com/rawleyfowler/sluj" com.github.rawleyfowler/sluj {:git/url "https://github.com/rawleyfowler/sluj"
:git/sha "4a92e772b4e07bf127423448d4140748b5782198" :git/sha "4a92e772b4e07bf127423448d4140748b5782198"
:deps/manifest :deps}} :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"}}
:classpath-overrides {org.clojure/clojure nil :classpath-overrides {org.clojure/clojure nil
org.clojure/spec.alpha nil}} org.clojure/spec.alpha nil}}
:clj-nvd :clj-nvd

View file

@ -7,7 +7,7 @@ Args=-H:+ReportExceptionStackTraces \
-H:IncludeResources=src/babashka/.* \ -H:IncludeResources=src/babashka/.* \
-H:IncludeResources=SCI_VERSION \ -H:IncludeResources=SCI_VERSION \
-H:Log=registerResource:3 \ -H:Log=registerResource:3 \
-H:EnableURLProtocols=http,https,jar \ --enable-url-protocols=http,https,jar,unix \
--enable-all-security-services \ --enable-all-security-services \
-H:+JNI \ -H:+JNI \
--no-server \ --no-server \
@ -26,4 +26,31 @@ Args=-H:+ReportExceptionStackTraces \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.SoundbankReader \ -H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.SoundbankReader \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.MidiFileWriter \ -H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.MidiFileWriter \
-H:ServiceLoaderFeatureExcludeServices=java.net.ContentHandlerFactory \ -H:ServiceLoaderFeatureExcludeServices=java.net.ContentHandlerFactory \
-H:ServiceLoaderFeatureExcludeServices=java.nio.charset.spi.CharsetProvider -H:ServiceLoaderFeatureExcludeServices=java.nio.charset.spi.CharsetProvider \
-EBABASHKA_STATIC \
-EBABASHKA_MUSL \
-EBABASHKA_FEATURE_YAML \
-EBABASHKA_FEATURE_XML \
-EBABASHKA_FEATURE_CSV \
-EBABASHKA_FEATURE_TRANSIT \
-EBABASHKA_FEATURE_JAVA_TIME \
-EBABASHKA_FEATURE_JAVA_NET_HTTP \
-EBABASHKA_FEATURE_JAVA_NIO \
-EBABASHKA_FEATURE_HTTPKIT_CLIENT \
-EBABASHKA_FEATURE_HTTPKIT_SERVER \
-EBABASHKA_FEATURE_CORE_MATCH \
-EBABASHKA_FEATURE_HICCUP \
-EBABASHKA_FEATURE_TEST_CHECK \
-EBABASHKA_FEATURE_SELMER \
-EBABASHKA_FEATURE_LOGGING \
-EBABASHKA_FEATURE_PRIORITY_MAP \
-EBABASHKA_FEATURE_JDBC \
-EBABASHKA_FEATURE_SQLITE \
-EBABASHKA_FEATURE_POSTGRESQL \
-EBABASHKA_FEATURE_ORACLEDB \
-EBABASHKA_FEATURE_HSQLDB \
-EBABASHKA_FEATURE_DATASCRIPT \
-EBABASHKA_FEATURE_LANTERNA \
-EBABASHKA_FEATURE_SPEC_ALPHA \
-EBABASHKA_FEATURE_RRB_VECTOR \
-EBABASHKA_REQUIRE_SCAN

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessControlContext;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.WeakHashMap;
import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
@TargetClass(URLClassLoader.class)
@SuppressWarnings({"unused", "static-method"})
final class Target_java_net_URLClassLoader {
@Alias//
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClass = WeakHashMap.class)//
private WeakHashMap<Closeable, Void> closeables;
@Substitute
public InputStream getResourceAsStream(String name) throws IOException {
System.out.println("getResource");
return null;
// return Resources.createInputStream(name);
}
}

View file

@ -322,10 +322,7 @@
"Returns a symbol from a symbol or var" "Returns a symbol from a symbol or var"
[x] [x]
(if (var? x) (if (var? x)
(let [m (meta x) (symbol x)
n (:name m)
ns (:ns m)]
(symbol (str ns) (str n)))
x)) x))
(defn- unfn [expr] (defn- unfn [expr]
@ -339,10 +336,7 @@
(defn- res [form] (defn- res [form]
(cond (cond
(keyword? form) form (keyword? form) form
(symbol? form) (cond (symbol? form) (c/or (-> form resolve ->sym) form)
(= 'fn form) 'clojure.core/fn ;; make tests pass, fn is not a macro in SCI
(= 'not form) 'clojure.core/not ;; make tests pass, not is not a macro in SCI
:else (c/or (-> form resolve ->sym) form))
(sequential? form) (walk/postwalk #(if (symbol? %) (res %) %) (unfn form)) (sequential? form) (walk/postwalk #(if (symbol? %) (res %) %) (unfn form))
:else form)) :else form))

2
sci

@ -1 +1 @@
Subproject commit 92a071269f1a4e3f4fda262b33b47ec827be3d4e Subproject commit bf6a0f1e00313a902c62c59e440266612725b926

View file

@ -9,7 +9,8 @@
(let [tmp-dir (fs/file tmp-dir)] (let [tmp-dir (fs/file tmp-dir)]
(shell {:dir tmp-dir} "git clone https://github.com/babashka/spec.alpha") (shell {:dir tmp-dir} "git clone https://github.com/babashka/spec.alpha")
(let [spec-dir (fs/file tmp-dir "spec.alpha")] (let [spec-dir (fs/file tmp-dir "spec.alpha")]
(shell {:dir spec-dir} "git reset 1d9df099be4fbfd30b9b903642ad376373c16298 --hard") (shell {:dir spec-dir} "git reset 951b49b8c173244e66443b8188e3ff928a0a71e7 --hard")
(fs/copy-tree (fs/file spec-dir "src" "main" "clojure") (fs/file "resources" "src" "babashka"))))) (fs/copy-tree (fs/file spec-dir "src" "main" "clojure") (fs/file "resources" "src" "babashka")
{:replace-existing true}))))

View file

@ -11,7 +11,7 @@
;; GraalVM Community Edition 19.3.2 based on OpenJDK 8u252 ;; GraalVM Community Edition 19.3.2 based on OpenJDK 8u252
;; GraalVM Community Edition 19.3.2 based on OpenJDK 11.0.7 ;; GraalVM Community Edition 19.3.2 based on OpenJDK 11.0.7
;; ;;
;; Currently we use GraalVM java11-20.1.0 ;; Currently we use GraalVM java19-20.1.0
(ns bump-graal-version (ns bump-graal-version
(:require [clojure.string :as str] (:require [clojure.string :as str]
@ -31,8 +31,8 @@
"" ""
"./bump_graal_version.clj -g 19.3.2 (the new version)" "./bump_graal_version.clj -g 19.3.2 (the new version)"
"or" "or"
"./bump_graal_version.clj -g 19.3.2 --java java11" "./bump_graal_version.clj -g 19.3.2 --java java19"
"(for GraalVM java11-19.3.2)" "(for GraalVM java19-19.3.2)"
""] ""]
(str/join \newline)))) (str/join \newline))))
@ -54,8 +54,8 @@
;; OR ;; OR
;; ;;
;; We could have them as environment variables ;; We could have them as environment variables
(def current-graal-version "22.3.0") (def current-graal-version "22.3.1")
(def current-java-version "java11") (def current-java-version "java19")
(def cl-options (def cl-options
[["-g" "--graal VERSION" "graal version"] [["-g" "--graal VERSION" "graal version"]

15
script/check_glibc.sh Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
function ver_lte() {
printf '%s\n%s' "$1" "$2" | sort -C -V
}
max_glibc_version="2.31"
current_glibc_version=$(ldd --version | head -1 | awk '{print $4}' | cut -d "-" -f 1)
function bail() {
echo "glibc greater than max version ${max_glibc_version}: ${current_glibc_version}"
exit 1
}
ver_lte "${current_glibc_version}" "${max_glibc_version}" || bail

View file

@ -26,17 +26,6 @@ fi
export JAVA_HOME=$GRAALVM_HOME export JAVA_HOME=$GRAALVM_HOME
export PATH=$GRAALVM_HOME/bin:$PATH export PATH=$GRAALVM_HOME/bin:$PATH
rm -rf resources/*.class
# SVM_JAR=$(find -L "$GRAALVM_HOME" | grep svm.jar)
# "$GRAALVM_HOME/bin/javac" -cp "$SVM_JAR" resources/CutOffCoreServicesDependencies.java
# "$GRAALVM_HOME/bin/javac" -cp "$SVM_JAR" resources/CutOffSunAwtWwwContentAudioAiff.java
# "$GRAALVM_HOME/bin/javac" -cp "$SVM_JAR" resources/CutOffMisc.java
if [ -z "$BABASHKA_JAR" ]; then
lein with-profiles +reflection,+native-image "do" run
lein "do" clean, uberjar, metabom
BABASHKA_JAR=${BABASHKA_JAR:-"target/babashka-$BABASHKA_VERSION-standalone.jar"}
fi
# because script/test cleans target during ci before the jar can we saved # because script/test cleans target during ci before the jar can we saved
cp target/metabom.jar . cp target/metabom.jar .
@ -54,8 +43,12 @@ args=("-jar" "$BABASHKA_JAR"
"--verbose" "--verbose"
"--no-fallback" "--no-fallback"
"--native-image-info" "--native-image-info"
"--install-exit-handlers"
# --trace-class-initialization=jdk.internal.net.http.common.DebugLogger,jdk.internal.net.http.websocket.WebSocketImpl,jdk.internal.net.http.common.Utils # --trace-class-initialization=jdk.internal.net.http.common.DebugLogger,jdk.internal.net.http.websocket.WebSocketImpl,jdk.internal.net.http.common.Utils
"$BABASHKA_XMX") "$BABASHKA_XMX"
"--enable-preview"
"-march=compatibility" # necessary for compatibility with older machines, e.g. see https://github.com/borkdude/deps.clj/actions/runs/6337277754/job/17212028399
"-O1")
BABASHKA_STATIC=${BABASHKA_STATIC:-} BABASHKA_STATIC=${BABASHKA_STATIC:-}
BABASHKA_MUSL=${BABASHKA_MUSL:-} BABASHKA_MUSL=${BABASHKA_MUSL:-}
@ -113,4 +106,4 @@ then
export BABASHKA_FEATURE_PRIORITY_MAP="${BABASHKA_FEATURE_PRIORITY_MAP:-false}" export BABASHKA_FEATURE_PRIORITY_MAP="${BABASHKA_FEATURE_PRIORITY_MAP:-false}"
fi fi
"$GRAALVM_HOME/bin/native-image" "${args[@]}" "$GRAALVM_HOME/bin/native-image" "${args[@]}" "$@"

View file

@ -29,7 +29,12 @@ call %GRAALVM_HOME%\bin\native-image.cmd ^
"-H:+ReportExceptionStackTraces" ^ "-H:+ReportExceptionStackTraces" ^
"--verbose" ^ "--verbose" ^
"--no-fallback" ^ "--no-fallback" ^
"%BABASHKA_XMX%" "--enable-preview" ^
"--install-exit-handlers" ^
"-march=compatibility" ^
"-O1" ^
"%BABASHKA_XMX%" ^
%*
if %errorlevel% neq 0 exit /b %errorlevel% if %errorlevel% neq 0 exit /b %errorlevel%

View file

@ -4,34 +4,33 @@ set -euo pipefail
INSTALL_DIR="${1:-$HOME}" INSTALL_DIR="${1:-$HOME}"
GRAALVM_VERSION="${GRAALVM_VERSION:-21.2.0}" GRAALVM_VERSION="${GRAALVM_VERSION:-22}"
case "$BABASHKA_PLATFORM" in GRAALVM_PLATFORM=$BABASHKA_PLATFORM
macos)
GRAALVM_PLATFORM="darwin"
;;
linux)
GRAALVM_PLATFORM="linux"
;;
esac
case "${BABASHKA_ARCH:-}" in case "${BABASHKA_ARCH:-}" in
aarch64) aarch64)
GRAALVM_ARCH="aarch64" GRAALVM_ARCH="aarch64"
;; ;;
*) *)
GRAALVM_ARCH="amd64" GRAALVM_ARCH="x64"
;; ;;
esac esac
GRAALVM_FILENAME="graalvm-ce-java11-$GRAALVM_PLATFORM-$GRAALVM_ARCH-$GRAALVM_VERSION.tar.gz" GRAALVM_DIR_NAME="graalvm-$GRAALVM_VERSION"
GRAALVM_FILENAME="graalvm-jdk-${GRAALVM_VERSION}_${GRAALVM_PLATFORM}-${GRAALVM_ARCH}_bin.tar.gz"
DOWNLOAD_URL="https://download.oracle.com/graalvm/22/archive/${GRAALVM_FILENAME}"
pushd "$INSTALL_DIR" >/dev/null pushd "$INSTALL_DIR" >/dev/null
if ! [ -d "graalvm-ce-java11-$GRAALVM_VERSION" ]; then if ! [ -d "$GRAALVM_DIR_NAME" ]; then
echo "Downloading GraalVM $GRAALVM_PLATFORM-$GRAALVM_ARCH-$GRAALVM_VERSION on '$PWD'..." echo "Downloading GraalVM $GRAALVM_PLATFORM-$GRAALVM_ARCH-$GRAALVM_VERSION on '$PWD'..."
curl -O -sL "https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-$GRAALVM_VERSION/$GRAALVM_FILENAME" echo "$DOWNLOAD_URL"
tar xzf "$GRAALVM_FILENAME" curl --fail -LO "$DOWNLOAD_URL"
ls -la
mkdir "$GRAALVM_DIR_NAME"
tar xzvf "$GRAALVM_FILENAME" -C "$GRAALVM_DIR_NAME" --strip-components 1
ls -la "$GRAALVM_DIR_NAME"
fi fi
popd >/dev/null popd >/dev/null

View file

@ -1,5 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail
if [ "$GRAALVM_HOME" != "" ] if [ "$GRAALVM_HOME" != "" ]
then then
export JAVA_HOME=$GRAALVM_HOME export JAVA_HOME=$GRAALVM_HOME
@ -8,7 +10,6 @@ fi
java -version java -version
set -eo pipefail
unset BABASHKA_PRELOADS unset BABASHKA_PRELOADS
unset BABASHKA_CLASSPATH unset BABASHKA_CLASSPATH
unset BABASHKA_PRELOADS_TEST unset BABASHKA_PRELOADS_TEST
@ -16,6 +17,9 @@ unset BABASHKA_PRELOADS_TEST
echo "running tests part 1" echo "running tests part 1"
lein "do" clean, test "$@" lein "do" clean, test "$@"
echo "running flaky tests"
lein "do" clean, test :flaky || true
export BABASHKA_PRELOADS='(defn __bb__foo [] "foo") (defn __bb__bar [] "bar")' export BABASHKA_PRELOADS='(defn __bb__foo [] "foo") (defn __bb__bar [] "bar")'
export BABASHKA_PRELOADS_TEST=true export BABASHKA_PRELOADS_TEST=true
echo "running tests part 2" echo "running tests part 2"
@ -37,3 +41,13 @@ lein test :only babashka.pod-test
export BABASHKA_SOCKET_REPL_TEST=true export BABASHKA_SOCKET_REPL_TEST=true
lein test :only babashka.impl.socket-repl-test lein test :only babashka.impl.socket-repl-test
# test invoking script in subdir with bb.edn in parent dir
unset BABASHKA_PRELOADS
unset BABASHKA_CLASSPATH
pushd test-resources/bb_in_root_script_in_other_dir
if [[ $BABASHKA_TEST_ENV = "native" ]]
then
../../bb dir/script.clj
fi
popd

View file

@ -16,7 +16,11 @@ set BABASHKA_POD_TEST=
set BABASHKA_SOCKET_REPL_TEST= set BABASHKA_SOCKET_REPL_TEST=
echo "running tests part 1" echo "running tests part 1"
call lein do clean, test :windows || exit /B 1 call lein do clean, test %* || exit /B 1
echo "running flaky tests"
REM there's no "or exit" here because we don't want flaky tests to fail the script
call lein do clean, test :flaky
set BABASHKA_PRELOADS=(defn __bb__foo [] "foo") (defn __bb__bar [] "bar") set BABASHKA_PRELOADS=(defn __bb__foo [] "foo") (defn __bb__bar [] "bar")
set BABASHKA_PRELOADS_TEST=true set BABASHKA_PRELOADS_TEST=true

View file

@ -175,8 +175,15 @@ else
BABASHKA_LEIN_PROFILES+=",-feature/rrb-vector" BABASHKA_LEIN_PROFILES+=",-feature/rrb-vector"
fi fi
mkdir -p resources/META-INF/babashka
cp deps.edn resources/META-INF/babashka/deps.edn cp deps.edn resources/META-INF/babashka/deps.edn
rm -rf resources/*.class
# SVM_JAR=$(find -L "$GRAALVM_HOME" | grep svm.jar)
# "$GRAALVM_HOME/bin/javac" -cp "$SVM_JAR" resources/UrlClassLoaderSubstitutions.java
# "$GRAALVM_HOME/bin/javac" -cp "$SVM_JAR" resources/CutOffSunAwtWwwContentAudioAiff.java
# "$GRAALVM_HOME/bin/javac" -cp "$SVM_JAR" resources/CutOffMisc.java
if [ -z "$BABASHKA_JAR" ]; then if [ -z "$BABASHKA_JAR" ]; then
lein with-profiles "$BABASHKA_LEIN_PROFILES,+reflection,-uberjar" do run lein with-profiles "$BABASHKA_LEIN_PROFILES,+reflection,-uberjar" do run
lein with-profiles "$BABASHKA_LEIN_PROFILES" do clean, uberjar, metabom lein with-profiles "$BABASHKA_LEIN_PROFILES" do clean, uberjar, metabom

View file

@ -3,28 +3,46 @@
(:require [babashka.impl.patches.datafy] (:require [babashka.impl.patches.datafy]
[babashka.impl.pprint])) [babashka.impl.pprint]))
;; Enable this for scanning requiring-resolve usage: ;; Enable this for scanning requiring usage:
;; --- (def enable-require-scan
;; (def old-requiring-resolve requiring-resolve) "(do
(def old-require require)
;; (defmacro static-requiring-resolve [sym] (def old-resolve resolve)
;; (prn :sym sym)
;; `(old-requiring-resolve ~sym)) (def our-requiring-resolve (fn [sym]
(let [ns (symbol (namespace sym))]
;; (alter-var-root #'requiring-resolve (constantly @#'static-requiring-resolve)) (old-require ns)
;; (doto #'requiring-resolve (.setMacro)) (old-resolve sym))))
;; ---
(defn static-requiring-resolve [form _ _]
;; ((requiring-resolve 'clojure.pprint/pprint) (range 20)) (prn :req-resolve form :args (rest form))
`(let [res# (our-requiring-resolve ~@(rest form))]
;; Enable this for detecting literal usages of require res#))
;; ---
;; (def old-require require) (alter-var-root #'requiring-resolve (constantly @#'static-requiring-resolve))
(doto #'requiring-resolve (.setMacro))
;; (defmacro static-require [& syms]
;; (when (meta &form) (defn static-require [& [&form _bindings & syms]]
;; (prn :require &form )) (when (meta &form)
;; `(old-require ~@syms)) (prn :require &form (meta &form) *file*))
;; (alter-var-root #'require (constantly @#'static-require)) `(old-require ~@syms))
;; (doto #'require (.setMacro)) (alter-var-root #'require (constantly @#'static-require))
(doto #'require (.setMacro))
(alter-var-root #'clojure.core/serialized-require (constantly (fn [& args]
(prn :serialized-req args)))))
(defn static-resolve [& [&form _bindings & syms]]
(when (meta &form)
(prn :require &form (meta &form) *file*))
`(old-resolve ~@syms))
(alter-var-root #'resolve (constantly @#'static-resolve))
(doto #'resolve (.setMacro))
")
(when (System/getenv "BABASHKA_REQUIRE_SCAN")
(load-string enable-require-scan))
;; --- ;; ---

View file

@ -22,7 +22,7 @@
Examples: Examples:
(-> (clojure '[-M -e (+ 1 2 3)] {:out :string}) deref :out) returns (-> (clojure {:out :string} '-M '-e '(+ 1 2 3)]) deref :out) returns
\"6\n\". \"6\n\".
(-> @(clojure) :exit) starts a clojure REPL, waits for it (-> @(clojure) :exit) starts a clojure REPL, waits for it
@ -38,17 +38,13 @@
*out* @sci/out *out* @sci/out
*err* @sci/err *err* @sci/err
deps/*dir* (:dir opts) deps/*dir* (:dir opts)
deps/*env* (:env opts) deps/*aux-process-fn* (fn [{:keys [cmd out]}]
deps/*extra-env* (:extra-env opts) (pp/shell (assoc opts :out out :cmd cmd)))
deps/*process-fn* (fn deps/*clojure-process-fn* (fn [{:keys [cmd]}]
([cmd] (pp/process* {:cmd cmd (pp/process* {:cmd cmd
:prev prev :prev prev
:opts opts})) :opts opts}))
([cmd _] (pp/process* {:cmd cmd deps/*exit-fn* (fn [{:keys [message]}]
:prev prev (when message
:opts opts}))) (throw (Exception. message))))]
deps/*exit-fn* (fn
([_])
([_exit-code msg]
(throw (Exception. msg))))]
(apply deps/-main cmd)))) (apply deps/-main cmd))))

8
src/babashka/dude.clj Normal file
View file

@ -0,0 +1,8 @@
(ns babashka.dude
(:require [clojure-csv.core :as csv]
[clojure.java.io :as io]
[clojure.string :as string]))
csv/x
io/x
string/x

View file

@ -8,6 +8,18 @@
[sci.core :as sci] [sci.core :as sci]
[sci.impl.types :as t])) [sci.impl.types :as t]))
(set! *warn-on-reflection* true)
(def has-of-virtual?
(some #(= "ofVirtual" (.getName ^java.lang.reflect.Method %))
(.getMethods Thread)))
(def has-domain-sockets?
(resolve 'java.net.UnixDomainSocketAddress))
(def has-graal-process-properties?
(resolve 'org.graalvm.nativeimage.ProcessProperties))
(def base-custom-map (def base-custom-map
`{clojure.lang.LineNumberingPushbackReader {:allPublicConstructors true `{clojure.lang.LineNumberingPushbackReader {:allPublicConstructors true
:allPublicMethods true} :allPublicMethods true}
@ -47,7 +59,10 @@
{:name "sleep"} {:name "sleep"}
{:name "start"} {:name "start"}
{:name "toString"} {:name "toString"}
{:name "yield"}]} {:name "yield"}
~@(when has-of-virtual? [{:name "ofVirtual"}
{:name "startVirtualThread"}
{:name "isVirtual"}])]}
java.net.URL java.net.URL
{:allPublicConstructors true {:allPublicConstructors true
:allPublicFields true :allPublicFields true
@ -76,7 +91,8 @@
java.util.Arrays java.util.Arrays
{:methods [{:name "copyOf"} {:methods [{:name "copyOf"}
{:name "copyOfRange"} {:name "copyOfRange"}
{:name "equals"}]} {:name "equals"}
{:name "fill"}]}
;; this fixes clojure.lang.Reflector for Java 11 ;; this fixes clojure.lang.Reflector for Java 11
java.lang.reflect.AccessibleObject java.lang.reflect.AccessibleObject
{:methods [{:name "canAccess"}]} {:methods [{:name "canAccess"}]}
@ -111,17 +127,21 @@
clojure.lang.RT clojure.lang.RT
{:methods [{:name "aget"} {:methods [{:name "aget"}
{:name "aset"} {:name "aset"}
{:name "aclone"}]} {:name "aclone"}
;; we expose this via the Compiler/LOADER dynamic var
{:name "baseLoader"}]}
clojure.lang.Compiler clojure.lang.Compiler
{:fields [{:name "specials"} {:fields [{:name "specials"}
{:name "CHAR_MAP"}]} {:name "CHAR_MAP"}]}
clojure.lang.PersistentHashMap clojure.lang.PersistentHashMap
{:fields [{:name "EMPTY"}]} {:fields [{:name "EMPTY"}]}
clojure.lang.APersistentVector clojure.lang.APersistentVector
{:methods [{:name "indexOf"}]} {:methods [{:name "indexOf"}
{:name "contains"}]}
clojure.lang.LazySeq clojure.lang.LazySeq
{:allPublicConstructors true, {:allPublicConstructors true,
:methods [{:name "indexOf"}]} :methods [{:name "indexOf"}
{:name "contains"}]}
clojure.lang.ILookup clojure.lang.ILookup
{:methods [{:name "valAt"}]} {:methods [{:name "valAt"}]}
clojure.lang.IPersistentMap clojure.lang.IPersistentMap
@ -140,19 +160,39 @@
{:methods [{:name "hasNext"} {:methods [{:name "hasNext"}
{:name "next"}]} {:name "next"}]}
java.util.TimeZone java.util.TimeZone
{:methods [{:name "getTimeZone"}]}}) {:methods [{:name "getTimeZone"}]}
java.net.URLClassLoader
{:methods [{:name "close"}
{:name "findResource"}
{:name "findResources"}
{:name "getResourceAsStream"}
{:name "getURLs"}]}
java.lang.ClassLoader
{:methods [{:name "getResource"}
{:name "getResources"}
{:name "getResourceAsStream"}
{:name "getParent"}]}
clojure.lang.ARef
{:methods [{:name "getWatches"}]}
clojure.lang.MapEntry
{:allPublicConstructors true
:methods [{:name "create"}]}})
(def custom-map (def custom-map
(cond-> (cond->
(merge base-custom-map (merge base-custom-map
proxy/custom-reflect-map) proxy/custom-reflect-map)
features/hsqldb? (assoc `org.hsqldb.dbinfo.DatabaseInformationFull features/hsqldb? (assoc `org.hsqldb.dbinfo.DatabaseInformationFull
{:methods [{:name "<init>" {:methods [{:name "<init>"
:parameterTypes ["org.hsqldb.Database"]}]} :parameterTypes ["org.hsqldb.Database"]}]}
`java.util.ResourceBundle `java.util.ResourceBundle
{:methods [{:name "getBundle" {:methods [{:name "getBundle"
:parameterTypes ["java.lang.String","java.util.Locale", :parameterTypes ["java.lang.String","java.util.Locale",
"java.lang.ClassLoader"]}]}))) "java.lang.ClassLoader"]}]})
has-graal-process-properties?
(assoc `org.graalvm.nativeimage.ProcessProperties
{:methods [{:name "exec"}]})))
(def java-net-http-classes (def java-net-http-classes
"These classes must be initialized at run time since GraalVM 22.1" "These classes must be initialized at run time since GraalVM 22.1"
@ -182,7 +222,14 @@
java.net.http.WebSocket$Builder java.net.http.WebSocket$Builder
java.net.http.WebSocket$Listener java.net.http.WebSocket$Listener
java.security.cert.X509Certificate java.security.cert.X509Certificate
java.security.cert.CertificateFactory
javax.crypto.Cipher
javax.crypto.Mac javax.crypto.Mac
javax.crypto.SecretKey
javax.crypto.SecretKeyFactory
javax.crypto.spec.GCMParameterSpec
javax.crypto.spec.IvParameterSpec
javax.crypto.spec.PBEKeySpec
javax.crypto.spec.SecretKeySpec javax.crypto.spec.SecretKeySpec
javax.net.ssl.HostnameVerifier ;; clj-http-lite javax.net.ssl.HostnameVerifier ;; clj-http-lite
javax.net.ssl.HttpsURLConnection ;; clj-http-lite javax.net.ssl.HttpsURLConnection ;; clj-http-lite
@ -194,6 +241,9 @@
javax.net.ssl.TrustManager javax.net.ssl.TrustManager
javax.net.ssl.TrustManagerFactory javax.net.ssl.TrustManagerFactory
javax.net.ssl.X509TrustManager javax.net.ssl.X509TrustManager
javax.net.ssl.X509ExtendedTrustManager
javax.net.ssl.SSLSocket
javax.net.ssl.SSLSocketFactory
jdk.internal.net.http.HttpClientBuilderImpl jdk.internal.net.http.HttpClientBuilderImpl
jdk.internal.net.http.HttpClientFacade jdk.internal.net.http.HttpClientFacade
jdk.internal.net.http.HttpRequestBuilderImpl jdk.internal.net.http.HttpRequestBuilderImpl
@ -284,7 +334,9 @@
java.lang.StringBuilder java.lang.StringBuilder
java.lang.System java.lang.System
java.lang.Throwable java.lang.Throwable
;; java.lang.UnsupportedOperationException java.lang.ThreadLocal
java.lang.Thread$UncaughtExceptionHandler
java.lang.UnsupportedOperationException
java.lang.ref.WeakReference java.lang.ref.WeakReference
java.lang.ref.ReferenceQueue java.lang.ref.ReferenceQueue
java.lang.ref.Cleaner java.lang.ref.Cleaner
@ -299,11 +351,15 @@
java.net.HttpURLConnection java.net.HttpURLConnection
java.net.InetAddress java.net.InetAddress
java.net.InetSocketAddress java.net.InetSocketAddress
java.net.StandardProtocolFamily
java.net.ServerSocket java.net.ServerSocket
java.net.Socket java.net.Socket
java.net.SocketException java.net.SocketException
~@(when has-domain-sockets?
'[java.net.UnixDomainSocketAddress])
java.net.UnknownHostException java.net.UnknownHostException
java.net.URI java.net.URI
java.net.URISyntaxException
;; java.net.URL, see custom map ;; java.net.URL, see custom map
java.net.URLConnection java.net.URLConnection
java.net.URLEncoder java.net.URLEncoder
@ -319,6 +375,8 @@
java.nio.file.StandardOpenOption java.nio.file.StandardOpenOption
java.nio.channels.FileChannel java.nio.channels.FileChannel
java.nio.channels.FileChannel$MapMode java.nio.channels.FileChannel$MapMode
java.nio.channels.ServerSocketChannel
java.nio.channels.SocketChannel
java.nio.charset.Charset java.nio.charset.Charset
java.nio.charset.CoderResult java.nio.charset.CoderResult
java.nio.charset.CharsetEncoder java.nio.charset.CharsetEncoder
@ -343,14 +401,17 @@
java.nio.file.attribute.FileTime java.nio.file.attribute.FileTime
java.nio.file.attribute.PosixFilePermission java.nio.file.attribute.PosixFilePermission
java.nio.file.attribute.PosixFilePermissions]) java.nio.file.attribute.PosixFilePermissions])
java.security.spec.PKCS8EncodedKeySpec
java.security.MessageDigest java.security.MessageDigest
java.security.DigestInputStream java.security.DigestInputStream
java.security.Provider java.security.Provider
java.security.KeyFactory
java.security.KeyStore java.security.KeyStore
java.security.SecureRandom java.security.SecureRandom
java.security.Security java.security.Security
java.sql.Date java.sql.Date
java.text.ParseException java.text.ParseException
java.text.ParsePosition
;; adds about 200kb, same functionality provided by java.time: ;; adds about 200kb, same functionality provided by java.time:
java.text.SimpleDateFormat java.text.SimpleDateFormat
~@(when features/java-time? ~@(when features/java-time?
@ -378,6 +439,7 @@
java.time.format.DateTimeFormatterBuilder java.time.format.DateTimeFormatterBuilder
java.time.format.DateTimeParseException java.time.format.DateTimeParseException
java.time.format.DecimalStyle java.time.format.DecimalStyle
java.time.format.FormatStyle
java.time.format.ResolverStyle java.time.format.ResolverStyle
java.time.format.SignStyle java.time.format.SignStyle
java.time.temporal.ChronoField java.time.temporal.ChronoField
@ -386,31 +448,44 @@
java.time.temporal.TemporalAdjusters java.time.temporal.TemporalAdjusters
java.time.temporal.TemporalAmount java.time.temporal.TemporalAmount
java.time.temporal.TemporalField java.time.temporal.TemporalField
java.time.temporal.WeekFields
~(symbol "[Ljava.time.temporal.TemporalField;") ~(symbol "[Ljava.time.temporal.TemporalField;")
java.time.format.TextStyle java.time.format.TextStyle
java.time.temporal.Temporal java.time.temporal.Temporal
java.time.temporal.TemporalAccessor java.time.temporal.TemporalAccessor
java.time.temporal.TemporalAdjuster]) java.time.temporal.TemporalAdjuster
java.time.temporal.TemporalQuery
~(symbol "[Ljava.time.temporal.TemporalQuery;")])
java.util.concurrent.atomic.AtomicInteger java.util.concurrent.atomic.AtomicInteger
java.util.concurrent.atomic.AtomicLong java.util.concurrent.atomic.AtomicLong
java.util.concurrent.atomic.AtomicReference java.util.concurrent.atomic.AtomicReference
java.util.concurrent.Callable
java.util.concurrent.CancellationException java.util.concurrent.CancellationException
java.util.concurrent.CompletionException java.util.concurrent.CompletionException
java.util.concurrent.CountDownLatch
java.util.concurrent.ExecutionException java.util.concurrent.ExecutionException
java.util.concurrent.Executor java.util.concurrent.Executor
java.util.concurrent.ExecutorService
java.util.concurrent.BlockingQueue
java.util.concurrent.ArrayBlockingQueue
java.util.concurrent.LinkedBlockingQueue java.util.concurrent.LinkedBlockingQueue
java.util.concurrent.ScheduledFuture
java.util.concurrent.ScheduledThreadPoolExecutor java.util.concurrent.ScheduledThreadPoolExecutor
java.util.concurrent.Semaphore
java.util.concurrent.ThreadFactory
java.util.concurrent.ThreadPoolExecutor java.util.concurrent.ThreadPoolExecutor
java.util.concurrent.ThreadPoolExecutor$AbortPolicy java.util.concurrent.ThreadPoolExecutor$AbortPolicy
java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy
java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy
java.util.concurrent.ThreadPoolExecutor$DiscardPolicy java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
java.util.concurrent.ExecutorService
java.util.concurrent.ScheduledExecutorService java.util.concurrent.ScheduledExecutorService
java.util.concurrent.Future java.util.concurrent.Future
java.util.concurrent.FutureTask java.util.concurrent.FutureTask
java.util.concurrent.CompletableFuture java.util.concurrent.CompletableFuture
java.util.concurrent.Executors java.util.concurrent.Executors
java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit
java.util.jar.Attributes
java.util.jar.Attributes$Name java.util.jar.Attributes$Name
java.util.jar.JarFile java.util.jar.JarFile
java.util.jar.JarEntry java.util.jar.JarEntry
@ -420,6 +495,7 @@
java.util.jar.Manifest java.util.jar.Manifest
java.util.stream.BaseStream java.util.stream.BaseStream
java.util.stream.Stream java.util.stream.Stream
java.util.stream.IntStream
java.util.Random java.util.Random
java.util.regex.Matcher java.util.regex.Matcher
java.util.regex.Pattern java.util.regex.Pattern
@ -432,6 +508,7 @@
java.util.Base64$Encoder java.util.Base64$Encoder
java.util.Date java.util.Date
java.util.HashMap java.util.HashMap
java.util.HashSet
java.util.IdentityHashMap java.util.IdentityHashMap
java.util.InputMismatchException java.util.InputMismatchException
java.util.List java.util.List
@ -452,6 +529,8 @@
java.util.function.BiFunction java.util.function.BiFunction
java.util.function.Predicate java.util.function.Predicate
java.util.function.Supplier java.util.function.Supplier
java.util.zip.CheckedInputStream
java.util.zip.CRC32
java.util.zip.Inflater java.util.zip.Inflater
java.util.zip.InflaterInputStream java.util.zip.InflaterInputStream
java.util.zip.Deflater java.util.zip.Deflater
@ -485,7 +564,6 @@
~@(when features/yaml? '[org.yaml.snakeyaml.error.YAMLException]) ~@(when features/yaml? '[org.yaml.snakeyaml.error.YAMLException])
~@(when features/hsqldb? '[org.hsqldb.jdbcDriver])] ~@(when features/hsqldb? '[org.hsqldb.jdbcDriver])]
:constructors [clojure.lang.Delay :constructors [clojure.lang.Delay
clojure.lang.MapEntry
clojure.lang.LineNumberingPushbackReader clojure.lang.LineNumberingPushbackReader
java.io.EOFException] java.io.EOFException]
:methods [borkdude.graal.LockFix] ;; support for locking :methods [borkdude.graal.LockFix] ;; support for locking
@ -527,19 +605,23 @@
clojure.lang.IRef clojure.lang.IRef
clojure.lang.ISeq clojure.lang.ISeq
clojure.lang.IPersistentVector clojure.lang.IPersistentVector
clojure.lang.ITransientSet
clojure.lang.ITransientVector clojure.lang.ITransientVector
clojure.lang.Iterate clojure.lang.Iterate
clojure.lang.LispReader$Resolver clojure.lang.LispReader$Resolver
clojure.lang.LongRange
clojure.lang.Named clojure.lang.Named
clojure.lang.Keyword clojure.lang.Keyword
clojure.lang.PersistentArrayMap clojure.lang.PersistentArrayMap
clojure.lang.PersistentHashSet clojure.lang.PersistentHashSet
clojure.lang.PersistentList clojure.lang.PersistentList
clojure.lang.PersistentList$EmptyList
clojure.lang.PersistentQueue clojure.lang.PersistentQueue
clojure.lang.PersistentStructMap clojure.lang.PersistentStructMap
clojure.lang.PersistentTreeMap clojure.lang.PersistentTreeMap
clojure.lang.PersistentTreeSet clojure.lang.PersistentTreeSet
clojure.lang.PersistentVector clojure.lang.PersistentVector
clojure.lang.Range
clojure.lang.Ratio clojure.lang.Ratio
clojure.lang.ReaderConditional clojure.lang.ReaderConditional
clojure.lang.Repeat clojure.lang.Repeat
@ -557,7 +639,6 @@
java.lang.LinkageError java.lang.LinkageError
java.lang.ThreadDeath java.lang.ThreadDeath
java.lang.VirtualMachineError java.lang.VirtualMachineError
java.net.URLClassLoader
java.sql.Timestamp java.sql.Timestamp
java.util.concurrent.TimeoutException java.util.concurrent.TimeoutException
java.util.Collection java.util.Collection
@ -574,7 +655,27 @@
(:instance-checks classes)) (:instance-checks classes))
m (apply hash-map m (apply hash-map
(for [c classes (for [c classes
c [(list 'quote c) c]] c [(list 'quote c) (cond-> `{:class ~c}
(= 'java.lang.Class c)
(assoc :static-methods
{(list 'quote 'forName)
`(fn
([_# ^String class-name#]
(Class/forName class-name#))
([_# ^String class-name# initialize# ^java.lang.ClassLoader clazz-loader#]
(Class/forName class-name#)))})
(= 'java.lang.Thread c)
(assoc :static-methods
{(list 'quote 'sleep)
`(fn
([_# x#]
(if (instance? Number x#)
(let [x# (long x#)]
(Thread/sleep x#))
(let [^java.time.Duration x# x#]
(Thread/sleep x#))))
([_# ^java.lang.Long millis# ^java.lang.Long nanos#]
(Thread/sleep millis# nanos#)))}))]]
c)) c))
m (assoc m :public-class m (assoc m :public-class
(fn [v] (fn [v]
@ -607,6 +708,8 @@
java.nio.file.FileSystem java.nio.file.FileSystem
(instance? java.nio.file.PathMatcher v) (instance? java.nio.file.PathMatcher v)
java.nio.file.PathMatcher java.nio.file.PathMatcher
(instance? java.util.stream.IntStream v)
java.util.stream.IntStream
(instance? java.util.stream.BaseStream v) (instance? java.util.stream.BaseStream v)
java.util.stream.BaseStream java.util.stream.BaseStream
(instance? java.nio.ByteBuffer v) (instance? java.nio.ByteBuffer v)
@ -619,6 +722,10 @@
java.nio.CharBuffer java.nio.CharBuffer
(instance? java.nio.channels.FileChannel v) (instance? java.nio.channels.FileChannel v)
java.nio.channels.FileChannel java.nio.channels.FileChannel
(instance? java.nio.channels.ServerSocketChannel v)
java.nio.channels.ServerSocketChannel
(instance? java.nio.channels.SocketChannel v)
java.nio.channels.SocketChannel
(instance? java.net.CookieStore v) (instance? java.net.CookieStore v)
java.net.CookieStore java.net.CookieStore
;; this makes interop on reified classes work ;; this makes interop on reified classes work
@ -626,18 +733,38 @@
(instance? sci.impl.types.IReified v) (instance? sci.impl.types.IReified v)
(first (t/getInterfaces v)) (first (t/getInterfaces v))
;; fix for #1061 ;; fix for #1061
(instance? java.io.Closeable v) (instance? java.net.URLClassLoader v)
java.io.Closeable java.net.URLClassLoader
(instance? java.lang.ClassLoader v)
java.lang.ClassLoader
(instance? java.nio.file.attribute.BasicFileAttributes v) (instance? java.nio.file.attribute.BasicFileAttributes v)
java.nio.file.attribute.BasicFileAttributes java.nio.file.attribute.BasicFileAttributes
(instance? java.util.concurrent.Future v) (instance? java.util.concurrent.Future v)
java.util.concurrent.Future java.util.concurrent.Future
(instance? java.util.concurrent.ScheduledExecutorService v) (instance? java.util.concurrent.ScheduledExecutorService v)
java.util.concurrent.ScheduledExecutorService java.util.concurrent.ScheduledExecutorService
(instance? java.util.concurrent.ExecutorService v)
java.util.concurrent.ExecutorService
(instance? java.util.Iterator v) (instance? java.util.Iterator v)
java.util.Iterator java.util.Iterator
(instance? javax.crypto.SecretKey v)
javax.crypto.SecretKey
(instance? javax.net.ssl.SSLSocketFactory v)
javax.net.ssl.SSLSocketFactory
(instance? javax.net.ssl.SSLSocket v)
javax.net.ssl.SSLSocket
(instance? java.lang.Thread v)
java.lang.Thread
(instance? java.security.cert.X509Certificate v)
java.security.cert.X509Certificate
(instance? java.io.Console v)
java.io.Console
(instance? java.util.Set v)
java.util.Set
(instance? java.io.Closeable v)
java.io.Closeable
;; keep commas for merge friendliness ;; keep commas for merge friendliness
,,,))) )))
m (assoc m (list 'quote 'clojure.lang.Var) 'sci.lang.Var) m (assoc m (list 'quote 'clojure.lang.Var) 'sci.lang.Var)
m (assoc m (list 'quote 'clojure.lang.Namespace) 'sci.lang.Namespace)] m (assoc m (list 'quote 'clojure.lang.Namespace) 'sci.lang.Namespace)]
m)) m))
@ -648,6 +775,14 @@
allowed to be initialized at build time." allowed to be initialized at build time."
(gen-class-map)) (gen-class-map))
#_(let [class-name (str c)]
(cond-> (Class/forName class-name)
(= "java.lang.Class" class-name)
(->> (hash-map :static-methods {'forName (fn [class-name]
(prn :class-for)
(Class/forName class-name))}
:class))))
(def class-map (def class-map
"A delay to delay initialization of java-net-http classes to run time, since GraalVM 22.1" "A delay to delay initialization of java-net-http classes to run time, since GraalVM 22.1"
(delay (persistent! (reduce (fn [acc c] (delay (persistent! (reduce (fn [acc c]
@ -664,6 +799,7 @@
BigInteger java.math.BigInteger BigInteger java.math.BigInteger
Boolean java.lang.Boolean Boolean java.lang.Boolean
Byte java.lang.Byte Byte java.lang.Byte
Callable java.util.concurrent.Callable
Character java.lang.Character Character java.lang.Character
CharSequence java.lang.CharSequence CharSequence java.lang.CharSequence
Class java.lang.Class Class java.lang.Class
@ -689,9 +825,10 @@
Number java.lang.Number Number java.lang.Number
NumberFormatException java.lang.NumberFormatException NumberFormatException java.lang.NumberFormatException
Object java.lang.Object Object java.lang.Object
Runnable java.lang.Runnable
Runtime java.lang.Runtime Runtime java.lang.Runtime
RuntimeException java.lang.RuntimeException RuntimeException java.lang.RuntimeException
Process java.lang.Process Process java.lang.Process
ProcessBuilder java.lang.ProcessBuilder ProcessBuilder java.lang.ProcessBuilder
Short java.lang.Short Short java.lang.Short
StackTraceElement java.lang.StackTraceElement StackTraceElement java.lang.StackTraceElement
@ -699,11 +836,13 @@
StringBuilder java.lang.StringBuilder StringBuilder java.lang.StringBuilder
System java.lang.System System java.lang.System
Thread java.lang.Thread Thread java.lang.Thread
ThreadLocal java.lang.ThreadLocal
Thread$UncaughtExceptionHandler java.lang.Thread$UncaughtExceptionHandler
Throwable java.lang.Throwable Throwable java.lang.Throwable
VirtualMachineError java.lang.VirtualMachineError VirtualMachineError java.lang.VirtualMachineError
ThreadDeath java.lang.ThreadDeath ThreadDeath java.lang.ThreadDeath
Void java.lang.Void Void java.lang.Void
;; UnsupportedOperationException java.lang.UnsupportedOperationException UnsupportedOperationException java.lang.UnsupportedOperationException
}) })
(defn reflection-file-entries [] (defn reflection-file-entries []
@ -746,13 +885,13 @@
"resources/META-INF/native-image/babashka/babashka/reflect-config.json") "resources/META-INF/native-image/babashka/babashka/reflect-config.json")
(json/generate-string all-entries {:pretty true})))) (json/generate-string all-entries {:pretty true}))))
(defn public-declared-method? [c m] (defn public-declared-method? [^Class c ^java.lang.reflect.Method m]
(and (= c (.getDeclaringClass m)) (and (= c (.getDeclaringClass m))
(not (.getAnnotation m Deprecated)))) (not (.getAnnotation m Deprecated))))
(defn public-declared-method-names [c] (defn public-declared-method-names [^Class c]
(->> (.getMethods c) (->> (.getMethods c)
(keep (fn [m] (keep (fn [^java.lang.reflect.Method m]
(when (public-declared-method? c m) (when (public-declared-method? c m)
{:class c {:class c
:name (.getName m)}))) :name (.getName m)})))
@ -760,8 +899,9 @@
(sort-by :name) (sort-by :name)
(vec))) (vec)))
(defn all-classes [] (defn all-classes
"Returns every java.lang.Class instance Babashka supports." "Returns every java.lang.Class instance Babashka supports."
[]
(->> (reflection-file-entries) (->> (reflection-file-entries)
(map :name) (map :name)
(map #(Class/forName %)))) (map #(Class/forName %))))
@ -779,6 +919,4 @@
(public-declared-method-names java.net.URL) (public-declared-method-names java.net.URL)
(public-declared-method-names java.util.Properties) (public-declared-method-names java.util.Properties)
(all-classes) (all-classes))
)

View file

@ -5,66 +5,51 @@
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.string :as str] [clojure.string :as str]
[sci.core :as sci]) [sci.core :as sci])
(:import [java.util.jar JarFile Manifest] (:import [java.util.jar Manifest]
(java.net URL))) (java.net URL)))
(set! *warn-on-reflection* true) (set! *warn-on-reflection* true)
(defprotocol IResourceResolver (defn getResource [^babashka.impl.URLClassLoader class-loader resource-paths url?]
(getResource [this paths opts]) (some (fn [resource]
(getResources [this paths opts])) (when-let [^java.net.URL res (.findResource class-loader resource)]
(if url?
(deftype DirectoryResolver [path] res
IResourceResolver {:file (if (= "jar" (.getProtocol res))
(getResource [_ resource-paths url?] resource
(some (.getFile res))
(fn [resource-path] :source (slurp res)})))
(let [f (io/file path resource-path)] resource-paths))
(when (.exists f)
(if url?
;; manual conversion, faster than going through .toURI
(java.net.URL. "file" nil (.getAbsolutePath f))
{:file (.getAbsolutePath f)
:source (slurp f)}))))
resource-paths)))
(defn path-from-jar
[^java.io.File jar-file resource-paths url?]
(with-open [jar (JarFile. jar-file)]
(some (fn [path]
(when-let [entry (.getEntry jar path)]
(if url?
;; manual conversion, faster than going through .toURI
(java.net.URL. "jar" nil
(str "file:" (.getAbsolutePath jar-file) "!/" path))
{:file path
:source (slurp (.getInputStream jar entry))})))
resource-paths)))
(deftype JarFileResolver [jar-file]
IResourceResolver
(getResource [_ resource-paths url?]
(path-from-jar jar-file resource-paths url?)))
(defn part->entry [part]
(when-not (str/blank? part)
(if (str/ends-with? part ".jar")
(JarFileResolver. (io/file part))
(DirectoryResolver. (io/file part)))))
(deftype Loader [entries]
IResourceResolver
(getResource [_ resource-paths opts]
(some #(getResource % resource-paths opts) entries))
(getResources [_ resource-paths opts]
(keep #(getResource % resource-paths opts) entries)))
(def path-sep (System/getProperty "path.separator")) (def path-sep (System/getProperty "path.separator"))
(defn loader [^String classpath] (defn ->url ^java.net.URL [^String s]
(let [parts (.split classpath path-sep) (.toURL (java.io.File. s)))
entries (keep part->entry parts)]
(Loader. entries))) (defn new-loader ^babashka.impl.URLClassLoader
([paths]
(babashka.impl.URLClassLoader. (into-array java.net.URL (map ->url paths)))))
(def ^babashka.impl.URLClassLoader the-url-loader (delay (new-loader [])))
(defn add-classpath
"Adds extra-classpath, a string as for example returned by clojure
-Spath, to the current classpath."
[^String extra-classpath]
(let [paths (.split extra-classpath path-sep)
paths (map ->url paths)
loader @the-url-loader]
(run! (fn [path]
(._addURL ^babashka.impl.URLClassLoader loader path)
loader)
paths)
;; (run! prn (.getURLs the-url-loader))
(System/setProperty "java.class.path"
(let [system-cp (System/getProperty "java.class.path")]
(-> (cond-> system-cp
(not (str/blank? system-cp)) (str path-sep))
(str extra-classpath)))))
nil)
(defn resource-paths [namespace] (defn resource-paths [namespace]
(let [ns-str (name namespace) (let [ns-str (name namespace)
@ -86,33 +71,20 @@
(.getValue "Main-Class") (.getValue "Main-Class")
(demunge)))) (demunge))))
(def cp-state (atom nil))
(defn add-classpath
"Adds extra-classpath, a string as for example returned by clojure
-Spath, to the current classpath."
[extra-classpath]
(swap! cp-state
(fn [{:keys [:cp]}]
(let [new-cp
(if-not cp extra-classpath
(str cp path-sep extra-classpath))]
{:loader (loader new-cp)
:cp new-cp})))
nil)
(defn split-classpath (defn split-classpath
"Returns the classpath as a seq of strings, split by the platform "Returns the classpath as a seq of strings, split by the platform
specific path separator." specific path separator."
([^String cp] (vec (.split cp path-sep)))) ([^String cp] (vec (when cp (.split cp path-sep)))))
(defn get-classpath (defn get-classpath
"Returns the current classpath as set by --classpath, BABASHKA_CLASSPATH and add-classpath." "Returns the current classpath as set by --classpath, BABASHKA_CLASSPATH and add-classpath."
[] []
(:cp @cp-state)) (let [cp (System/getProperty "java.class.path")]
(when-not (str/blank? cp)
cp)))
(defn resource (defn resource
(^URL [path] (when-let [st @cp-state] (resource (:loader st) path))) (^URL [path] (resource @the-url-loader path))
(^URL [loader path] (^URL [loader path]
(if (str/starts-with? path "/") nil ;; non-relative paths always return nil (if (str/starts-with? path "/") nil ;; non-relative paths always return nil
(getResource loader [path] true)))) (getResource loader [path] true))))
@ -132,4 +104,3 @@
(def l (loader cp)) (def l (loader cp))
(source-for-namespace l 'babashka.impl.cheshire nil) (source-for-namespace l 'babashka.impl.cheshire nil)
(time (:file (source-for-namespace l 'cheshire.core nil)))) ;; 20ms -> 2.25ms (time (:file (source-for-namespace l 'cheshire.core nil)))) ;; 20ms -> 2.25ms

View file

@ -17,18 +17,22 @@
(let [extra-opts '%s (let [extra-opts '%s
sym `%s sym `%s
the-var (requiring-resolve sym) the-var (requiring-resolve sym)
_ (when-not the-var
(throw (ex-info (str \"Could not resolve sym to a function: \" sym) {:babashka/exit 1})))
the-var-meta (meta the-var) the-var-meta (meta the-var)
ns (:ns (meta the-var)) ns (:ns (meta the-var))
ns-meta (meta ns) ns-meta (meta ns)
ct (babashka.tasks/current-task) ct (babashka.tasks/current-task)
exec-args (babashka.cli/merge-opts (:exec-args (:org.babashka/cli ns-meta))
(:exec-args (:org.babashka/cli the-var-meta))
(:exec-args (:org.babashka/cli ct))
(:exec-args ct)
(:exec-args extra-opts))
cli-opts (babashka.cli/merge-opts (:org.babashka/cli ns-meta) cli-opts (babashka.cli/merge-opts (:org.babashka/cli ns-meta)
(:org.babashka/cli the-var-meta) (:org.babashka/cli the-var-meta)
(:org.babashka/cli ct) (:org.babashka/cli ct)
extra-opts) extra-opts)
task-exec-args (:exec-args ct) cli-opts (assoc cli-opts :exec-args exec-args)
cli-exec-args (:exec-args cli-opts)
exec-args {:exec-args (babashka.cli/merge-opts cli-exec-args task-exec-args)}
cli-opts (babashka.cli/merge-opts exec-args cli-opts)
opts (babashka.cli/parse-opts *command-line-args* cli-opts)] opts (babashka.cli/parse-opts *command-line-args* cli-opts)]
(the-var opts))" (the-var opts))"
(random-uuid) (random-uuid)

View file

@ -15,15 +15,6 @@
(defn locking* [form bindings v f & args] (defn locking* [form bindings v f & args]
(apply @#'locking/locking form bindings v f args)) (apply @#'locking/locking form bindings v f args))
(defn time*
"Evaluates expr and prints the time it took. Returns the value of
expr."
[_ _ expr]
`(let [start# (. System (nanoTime))
ret# ~expr]
(prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs"))
ret#))
(defn core-dynamic-var (defn core-dynamic-var
([sym] (core-dynamic-var sym nil)) ([sym] (core-dynamic-var sym nil))
([sym init-val] (sci/new-dynamic-var sym init-val {:ns clojure-core-ns}))) ([sym init-val] (sci/new-dynamic-var sym init-val {:ns clojure-core-ns})))
@ -34,6 +25,8 @@
(def compile-files (core-dynamic-var '*compile-files* false)) (def compile-files (core-dynamic-var '*compile-files* false))
(def unchecked-math (core-dynamic-var '*unchecked-math* false)) (def unchecked-math (core-dynamic-var '*unchecked-math* false))
(def math-context (core-dynamic-var '*math-context*)) (def math-context (core-dynamic-var '*math-context*))
(def compile-path (core-dynamic-var '*compile-path* *compile-path*))
(def compiler-options (core-dynamic-var '*compiler-options*))
(defn read+string (defn read+string
"Added for compatibility. Must be used with "Added for compatibility. Must be used with
@ -158,7 +151,6 @@
'shutdown-agents (copy-core-var shutdown-agents) 'shutdown-agents (copy-core-var shutdown-agents)
'slurp (copy-core-var slurp) 'slurp (copy-core-var slurp)
'spit (copy-core-var spit) 'spit (copy-core-var spit)
'time (macrofy 'time time*)
'Throwable->map (copy-core-var Throwable->map) 'Throwable->map (copy-core-var Throwable->map)
'tap> (copy-core-var tap>) 'tap> (copy-core-var tap>)
'add-tap (copy-core-var add-tap) 'add-tap (copy-core-var add-tap)
@ -173,6 +165,8 @@
'*compile-files* compile-files '*compile-files* compile-files
'*unchecked-math* unchecked-math '*unchecked-math* unchecked-math
'*math-context* math-context '*math-context* math-context
'*compiler-options* compiler-options
'*compile-path* compile-path
'with-precision (sci/copy-var with-precision clojure-core-ns) 'with-precision (sci/copy-var with-precision clojure-core-ns)
'-with-precision (sci/copy-var -with-precision clojure-core-ns) '-with-precision (sci/copy-var -with-precision clojure-core-ns)
;; STM ;; STM
@ -199,5 +193,7 @@
'print-method (sci/copy-var print-method clojure-core-ns) 'print-method (sci/copy-var print-method clojure-core-ns)
'print-dup (sci/copy-var print-dup clojure-core-ns) 'print-dup (sci/copy-var print-dup clojure-core-ns)
'PrintWriter-on (sci/copy-var PrintWriter-on clojure-core-ns) 'PrintWriter-on (sci/copy-var PrintWriter-on clojure-core-ns)
'*compiler-options* (sci/new-dynamic-var '*compiler-options*)} 'set-agent-send-executor! (sci/copy-var set-agent-send-executor! clojure-core-ns)
'set-agent-send-off-executor! (sci/copy-var set-agent-send-off-executor! clojure-core-ns)
}
) )

View file

@ -6,8 +6,14 @@
[sci.impl.copy-vars :refer [macrofy]] [sci.impl.copy-vars :refer [macrofy]]
[sci.impl.vars :as vars])) [sci.impl.vars :as vars]))
(set! *warn-on-reflection* true)
(def ^java.util.concurrent.Executor executor @#'async/thread-macro-executor) (def ^java.util.concurrent.Executor executor @#'async/thread-macro-executor)
(def ^java.util.concurrent.Executor virtual-executor
(try (eval '(java.util.concurrent.Executors/newVirtualThreadPerTaskExecutor))
(catch Exception _ nil)))
(defn thread-call (defn thread-call
"Executes f in another thread, returning immediately to the calling "Executes f in another thread, returning immediately to the calling
thread. Returns a channel which will receive the result of calling thread. Returns a channel which will receive the result of calling
@ -26,10 +32,32 @@
(async/close! c)))))) (async/close! c))))))
c)) c))
(defn -vthread-call
"Executes f in another virtual thread, returning immediately to the calling
thread. Returns a channel which will receive the result of calling
f when completed, then close."
[f]
(let [c (async/chan 1)]
(let [binds (vars/get-thread-binding-frame)]
(.execute virtual-executor
(fn []
(vars/reset-thread-binding-frame binds)
(try
(let [ret (f)]
(when-not (nil? ret)
(async/>!! c ret)))
(finally
(async/close! c))))))
c))
(defn thread (defn thread
[_ _ & body] [_ _ & body]
`(~'clojure.core.async/thread-call (fn [] ~@body))) `(~'clojure.core.async/thread-call (fn [] ~@body)))
(defn -vthread
[_ _ & body]
`(~'clojure.core.async/-vthread-call (fn [] ~@body)))
(defn alt!! (defn alt!!
"Like alt!, except as if by alts!!, will block until completed, and "Like alt!, except as if by alts!!, will block until completed, and
not intended for use in (go ...) blocks." not intended for use in (go ...) blocks."
@ -38,10 +66,19 @@
(defn go-loop (defn go-loop
[_ _ bindings & body] [_ _ bindings & body]
(list 'clojure.core.async/thread (list* 'loop bindings body))) (list 'clojure.core.async/go (list* 'loop bindings body)))
(def core-async-namespace (sci/create-ns 'clojure.core.async nil)) (def core-async-namespace (sci/create-ns 'clojure.core.async nil))
(defn timeout [ms]
(if virtual-executor
(let [chan (async/chan nil)]
(.execute virtual-executor (fn []
(Thread/sleep (long ms))
(async/close! chan)))
chan)
(async/timeout ms)))
(def async-namespace (def async-namespace
{:obj core-async-namespace {:obj core-async-namespace
'<!! (copy-var async/<!! core-async-namespace) '<!! (copy-var async/<!! core-async-namespace)
@ -92,7 +129,8 @@
'tap (copy-var async/tap core-async-namespace) 'tap (copy-var async/tap core-async-namespace)
'thread (macrofy 'thread thread core-async-namespace) 'thread (macrofy 'thread thread core-async-namespace)
'thread-call (copy-var thread-call core-async-namespace) 'thread-call (copy-var thread-call core-async-namespace)
'timeout (copy-var async/timeout core-async-namespace) '-vthread-call (copy-var -vthread-call core-async-namespace)
'timeout (copy-var timeout core-async-namespace)
'to-chan (copy-var async/to-chan core-async-namespace) 'to-chan (copy-var async/to-chan core-async-namespace)
'to-chan! (copy-var async/to-chan! core-async-namespace) 'to-chan! (copy-var async/to-chan! core-async-namespace)
'to-chan!! (copy-var async/to-chan!! core-async-namespace) 'to-chan!! (copy-var async/to-chan!! core-async-namespace)
@ -107,7 +145,9 @@
'untap (copy-var async/untap core-async-namespace) 'untap (copy-var async/untap core-async-namespace)
'untap-all (copy-var async/untap-all core-async-namespace) 'untap-all (copy-var async/untap-all core-async-namespace)
;; polyfill ;; polyfill
'go (macrofy 'go thread core-async-namespace) 'go (if virtual-executor
(macrofy 'go -vthread core-async-namespace)
(macrofy 'go thread core-async-namespace))
'<! (copy-var async/<!! core-async-namespace {:name '<!}) '<! (copy-var async/<!! core-async-namespace {:name '<!})
'>! (copy-var async/>!! core-async-namespace {:name '>!}) '>! (copy-var async/>!! core-async-namespace {:name '>!})
'alt! (macrofy 'alt! alt!! core-async-namespace) 'alt! (macrofy 'alt! alt!! core-async-namespace)
@ -119,3 +159,4 @@
(def async-protocols-namespace (def async-protocols-namespace
{:obj async-protocols-ns {:obj async-protocols-ns
'ReadPort (copy-var protocols/ReadPort async-protocols-ns)}) 'ReadPort (copy-var protocols/ReadPort async-protocols-ns)})
;; trigger CI

View file

@ -25,7 +25,7 @@
(case os (case os
:mac (sh "open" url) :mac (sh "open" url)
:linux (sh "xdg-open" url) :linux (sh "xdg-open" url)
:windows (sh "cmd" "/C" "start" url))))) :windows (sh "cmd" "/C" "start" (.replace url "&" "^&"))))))
(def browse-namespace (def browse-namespace
{'*open-url-script* open-url-script {'*open-url-script* open-url-script

View file

@ -0,0 +1,7 @@
(ns babashka.impl.clojure.reflect
(:require [clojure.reflect]
[sci.core :as sci]))
(def rns (sci/create-ns 'clojure.reflect))
(def reflect-namespace {'reflect (sci/copy-var clojure.reflect/reflect rns)})

View file

@ -316,8 +316,8 @@
Does nothing if *report-counters* is nil." Does nothing if *report-counters* is nil."
{:added "1.1"} {:added "1.1"}
[name] [name]
(when @report-counters (when-let [rc @report-counters]
(swap! @report-counters update-in [name] (fnil inc 0)))) (dosync (commute rc update-in [name] (fnil inc 0)))))
;;; TEST RESULT REPORTING ;;; TEST RESULT REPORTING
@ -660,14 +660,12 @@
;;; DEFINING FIXTURES ;;; DEFINING FIXTURES
(def ^:private ns->fixtures (atom {}))
(defn- add-ns-meta (defn- add-ns-meta
"Adds elements in coll to the current namespace metadata as the "Adds elements in coll to the current namespace metadata as the
value of key." value of key."
{:added "1.1"} {:added "1.1"}
[key coll] [key coll]
(swap! ns->fixtures assoc-in [(sci-namespaces/sci-ns-name @sci/ns) key] coll)) (alter-meta! @sci/ns assoc key coll))
(defmulti use-fixtures (defmulti use-fixtures
"Wrap test runs in a fixture function to perform setup and "Wrap test runs in a fixture function to perform setup and
@ -677,10 +675,10 @@
(fn [fixture-type & args] fixture-type)) (fn [fixture-type & args] fixture-type))
(defmethod use-fixtures :each [fixture-type & args] (defmethod use-fixtures :each [fixture-type & args]
(add-ns-meta ::each-fixtures args)) (add-ns-meta :clojure.test/each-fixtures args))
(defmethod use-fixtures :once [fixture-type & args] (defmethod use-fixtures :once [fixture-type & args]
(add-ns-meta ::once-fixtures args)) (add-ns-meta :clojure.test/once-fixtures args))
(defn- default-fixture (defn- default-fixture
"The default, empty, fixture function. Just calls its argument." "The default, empty, fixture function. Just calls its argument."
@ -731,10 +729,8 @@
[vars] [vars]
(doseq [[ns vars] (group-by (comp :ns meta) vars) (doseq [[ns vars] (group-by (comp :ns meta) vars)
:when ns] :when ns]
(let [ns-name (sci-namespaces/sci-ns-name ns) (let [once-fixture-fn (join-fixtures (:clojure.test/once-fixtures (meta ns)))
fixtures (get @ns->fixtures ns-name) each-fixture-fn (join-fixtures (:clojure.test/each-fixtures (meta ns)))]
once-fixture-fn (join-fixtures (::once-fixtures fixtures))
each-fixture-fn (join-fixtures (::each-fixtures fixtures))]
(once-fixture-fn (once-fixture-fn
(fn [] (fn []
(doseq [v vars] (doseq [v vars]
@ -758,7 +754,7 @@
*report-counters*." *report-counters*."
{:added "1.1"} {:added "1.1"}
[ctx ns] [ctx ns]
(sci/binding [report-counters (atom @initial-report-counters)] (sci/binding [report-counters (ref @initial-report-counters)]
(let [ns-obj (sci-namespaces/sci-the-ns ctx ns)] (let [ns-obj (sci-namespaces/sci-the-ns ctx ns)]
(do-report {:type :begin-test-ns, :ns ns-obj}) (do-report {:type :begin-test-ns, :ns ns-obj})
;; If the namespace has a test-ns-hook function, call that: ;; If the namespace has a test-ns-hook function, call that:
@ -809,7 +805,7 @@
"Runs the tests for a single Var, with fixtures executed around the test, and summary output after." "Runs the tests for a single Var, with fixtures executed around the test, and summary output after."
{:added "1.11"} {:added "1.11"}
[v] [v]
(sci/binding [report-counters (atom @initial-report-counters)] (sci/binding [report-counters (ref @initial-report-counters)]
(let [ns-obj (-> v meta :ns) (let [ns-obj (-> v meta :ns)
summary (do summary (do
(do-report {:type :begin-test-ns (do-report {:type :begin-test-ns

View file

@ -1,9 +1,11 @@
(ns babashka.impl.clojure.tools.reader (ns babashka.impl.clojure.tools.reader
(:refer-clojure :exclude [read]) (:refer-clojure :exclude [read read-string])
(:require (:require
[clojure.tools.reader.reader-types :as rt]
[edamame.core :as e] [edamame.core :as e]
[sci.core :as sci] [sci.core :as sci]
[clojure.tools.reader.reader-types :as rt])) [sci.ctx-store :as ctx]
[sci.impl.parser :as p]))
(def rns (sci/create-ns 'clojure.tools.reader)) (def rns (sci/create-ns 'clojure.tools.reader))
@ -15,6 +17,15 @@
:location? seq? :location? seq?
:end-location false})) :end-location false}))
(def default-data-reader-fn (sci/new-dynamic-var '*default-data-reader-fn* nil {:ns rns}))
(def alias-map (sci/new-dynamic-var '*alias-map* nil {:ns rns}))
(defn resolve-tag [sym]
;; https://github.com/clojure/tools.reader/blob/ff18b1b872398a99e3e2941a0ed9abc0c2dec151/src/main/clojure/clojure/tools/reader.clj#L858
(or (default-data-readers sym)
(when-let [f @default-data-reader-fn]
(f sym))))
;; Added for compatibility with tools.namespace ;; Added for compatibility with tools.namespace
(defn read (defn read
"Reads the first object from an IPushbackReader or a java.io.PushbackReader. "Reads the first object from an IPushbackReader or a java.io.PushbackReader.
@ -38,7 +49,17 @@
([{eof :eof :as opts :or {eof :eofthrow}} reader] ([{eof :eof :as opts :or {eof :eofthrow}} reader]
(let [opts (assoc default-opts (let [opts (assoc default-opts
:read-cond (:read-cond opts) :read-cond (:read-cond opts)
:features (:features opts)) :features (:features opts)
:readers (fn [sym]
(resolve-tag sym))
:auto-resolve (fn [alias]
(if (= :current alias)
(symbol (str @sci/ns))
(or (when-let [alias-map @alias-map]
(@alias-map alias))
(sci/eval-form (ctx/get-ctx)
(list 'get '(ns-aliases *ns*)
(list 'quote alias)))))))
v (e/parse-next reader opts)] v (e/parse-next reader opts)]
(if (identical? ::e/eof v) (if (identical? ::e/eof v)
(if (identical? :eofthrow eof) (if (identical? :eofthrow eof)
@ -53,4 +74,18 @@
sentinel) sentinel)
v)))) v))))
(def reader-namespace {'read (sci/copy-var read rns)}) (defn read-string
([s] (read-string nil s))
([opts s]
(when (and s (not (identical? s "")))
(read opts (rt/string-push-back-reader s)))))
(defn resolve-symbol [sym]
(p/fully-qualify (ctx/get-ctx) sym))
(def reader-namespace
{'read (sci/copy-var read rns)
'read-string (sci/copy-var read-string rns)
'resolve-symbol (sci/copy-var resolve-symbol rns)
'*default-data-reader-fn* default-data-reader-fn
'*alias-map* alias-map})

View file

@ -15,4 +15,5 @@
'read-char (sci/copy-var rt/read-char rtns) 'read-char (sci/copy-var rt/read-char rtns)
'unread (sci/copy-var rt/unread rtns) 'unread (sci/copy-var rt/unread rtns)
'source-logging-push-back-reader (sci/copy-var rt/source-logging-push-back-reader rtns) 'source-logging-push-back-reader (sci/copy-var rt/source-logging-push-back-reader rtns)
'source-logging-reader? (sci/copy-var rt/source-logging-reader? rtns)}) 'source-logging-reader? (sci/copy-var rt/source-logging-reader? rtns)
'string-push-back-reader (sci/copy-var rt/string-push-back-reader rtns)})

View file

@ -3,6 +3,7 @@
[babashka.fs :as fs] [babashka.fs :as fs]
[babashka.impl.classpath :as cp] [babashka.impl.classpath :as cp]
[babashka.impl.common :refer [bb-edn]] [babashka.impl.common :refer [bb-edn]]
[babashka.process :as process]
[borkdude.deps :as deps] [borkdude.deps :as deps]
[clojure.string :as str] [clojure.string :as str]
[sci.core :as sci])) [sci.core :as sci]))
@ -59,42 +60,61 @@
then used to resolve dependencies in babashka." then used to resolve dependencies in babashka."
([deps-map] (add-deps deps-map nil)) ([deps-map] (add-deps deps-map nil))
([deps-map {:keys [:aliases :env :extra-env :force]}] ([deps-map {:keys [:aliases :env :extra-env :force]}]
(when-let [paths (:paths deps-map)] (let [deps-root (:deps-root @bb-edn)]
(let [paths (if-let [deps-root (:deps-root @bb-edn)] (when-let [paths (:paths deps-map)]
(let [deps-root (fs/absolutize deps-root) (let [paths (if deps-root
paths (mapv #(str (fs/file deps-root %)) paths)] (let [deps-root (fs/absolutize deps-root)
paths) paths (mapv #(str (fs/file deps-root %)) paths)]
paths)] paths)
(cp/add-classpath (str/join cp/path-sep paths)))) paths)]
(let [need-deps? (or (seq (:deps deps-map)) (cp/add-classpath (str/join cp/path-sep paths))))
(and (:aliases deps-map) (let [need-deps? (or (seq (:deps deps-map))
aliases))] (and (:aliases deps-map)
(when need-deps? aliases))]
(let [deps-map (dissoc deps-map (when need-deps?
;; paths are added manually above (let [deps-map (dissoc deps-map
;; extra-paths are added as :paths in tasks ;; paths are added manually above
:paths :tasks :raw :file :deps-root ;; extra-paths are added as :paths in tasks
:min-bb-version)] :paths :tasks :raw :file :deps-root
(binding [*print-namespace-maps* false] :min-bb-version)
(let [deps-map (assoc-in deps-map [:aliases :org.babashka/defaults] ;; associate deps-root to avoid cache conflict between different
{:replace-paths [] ;; babashka sets paths manually ;; bb.edns with relative local/roots by the same name NOTE:
:classpath-overrides (cond-> ;; deps-root is nil when bb.edn isn't used, so clashes may still
'{org.clojure/clojure "" ;; happen with dynamic add-deps, but at least we don't invoke
org.clojure/spec.alpha ""} ;; clojure CLI's java process each time we call a script from a
;; only remove core specs when they are not mentioned in deps map ;; different directory.
(not (str/includes? (str deps-map) "org.clojure/core.specs.alpha")) deps-map (assoc deps-map :deps-root (str deps-root))]
(assoc 'org.clojure/core.specs.alpha ""))}) (binding [*print-namespace-maps* false]
args (list "-Srepro" ;; do not include deps.edn from user config (let [deps-map (assoc-in deps-map [:aliases :org.babashka/defaults]
"-Spath" "-Sdeps" (str deps-map) {:replace-paths [] ;; babashka sets paths manually
"-Sdeps-file" "") ;; we reset deps file so the local deps.edn isn't used :classpath-overrides (cond->
args (if force (cons "-Sforce" args) args) '{org.clojure/clojure ""
args (concat args [(str "-A:" (str/join ":" (cons ":org.babashka/defaults" aliases)))]) org.clojure/spec.alpha ""}
cp (with-out-str (binding [deps/*env* env ;; only remove core specs when they are not mentioned in deps map
deps/*extra-env* extra-env] (not (str/includes? (str deps-map) "org.clojure/core.specs.alpha"))
(apply deps/-main args))) (assoc 'org.clojure/core.specs.alpha ""))})
cp (str/trim cp) args (list "-Srepro" ;; do not include deps.edn from user config
cp (str/replace cp (re-pattern (str cp/path-sep "+$")) "")] "-Spath" "-Sdeps" (str deps-map)
(cp/add-classpath cp)))))))) "-Sdeps-file" "__babashka_no_deps_file__.edn") ;; we reset deps file so the local deps.edn isn't used
args (if force (cons "-Sforce" args) args)
args (concat args [(str "-A:" (str/join ":" (cons ":org.babashka/defaults" aliases)))])
bindings (cond->
{#'deps/*aux-process-fn* (fn [{:keys [cmd out]}]
(process/shell
{:cmd cmd
:out out
:env env
:dir (when deps-root (str deps-root))
:extra-env extra-env}))
#'deps/*exit-fn* (fn [{:keys [message]}]
(when message
(throw (Exception. message))))}
deps-root (assoc #'deps/*dir* (str deps-root)))
cp (with-out-str (with-bindings bindings
(apply deps/-main args)))
cp (str/trim cp)
cp (str/replace cp (re-pattern (str cp/path-sep "+$")) "")]
(cp/add-classpath cp)))))))))
(def deps-namespace (def deps-namespace
{'add-deps (sci/copy-var add-deps dns) {'add-deps (sci/copy-var add-deps dns)

View file

@ -0,0 +1,15 @@
(ns babashka.impl.http-client
(:require
[babashka.http-client]
[babashka.http-client.websocket]
[sci.core :as sci]))
(def hns (sci/create-ns 'babashka.http-client))
(def wns (sci/create-ns 'babashka.http-client.websocket))
(def http-client-namespace
(sci/copy-ns babashka.http-client hns))
(def http-client-websocket-namespace
(sci/copy-ns babashka.http-client.websocket wns))

View file

@ -1,11 +1,18 @@
(ns babashka.impl.nrepl-server (ns babashka.impl.nrepl-server
{:no-doc true} {:no-doc true}
(:require (:require
[babashka.impl.clojure.core] [babashka.impl.classpath :as cp]
[babashka.impl.clojure.core :as core-extras]
[babashka.impl.common :as common] [babashka.impl.common :as common]
[babashka.nrepl.impl.server :refer [process-msg]]
[babashka.nrepl.server :as server] [babashka.nrepl.server :as server]
[sci.core :as sci])) [sci.core :as sci]))
(defmethod process-msg :classpath [rf result m]
(rf result {:response {"status" ["done"]
"classpath" (cp/split-classpath (cp/get-classpath))}
:response-for (:msg m)}))
(defn start-server! (defn start-server!
([] ([]
(start-server! nil)) (start-server! nil))
@ -13,7 +20,11 @@
(let [dev? (= "true" (System/getenv "BABASHKA_DEV")) (let [dev? (= "true" (System/getenv "BABASHKA_DEV"))
opts (merge {:debug dev? opts (merge {:debug dev?
:describe {"versions" {"babashka" common/version}} :describe {"versions" {"babashka" common/version}}
:thread-bind [babashka.impl.clojure.core/warn-on-reflection]} :thread-bind [core-extras/warn-on-reflection
core-extras/unchecked-math
core-extras/data-readers
sci/ns
sci/print-length]}
opts)] opts)]
(server/start-server! (common/ctx) opts)))) (server/start-server! (common/ctx) opts))))

View file

@ -14,11 +14,11 @@
edn/read-string) edn/read-string)
deps (:deps deps) deps (:deps deps)
deps (assoc deps deps (assoc deps
'babashka/fs {:mvn/version "0.2.12"} 'babashka/fs {:mvn/version "0.4.19"}
'babashka/babashka.curl {:mvn/version "0.1.2"} 'babashka/babashka.curl {:mvn/version "0.1.2"}
'babashka/babashka.core {:git/url "https://github.com/babashka/babashka.core" 'babashka/babashka.core {:git/url "https://github.com/babashka/babashka.core"
:git/sha "52a6037bd4b632bffffb04394fb4efd0cdab6b1e"} :git/sha "52a6037bd4b632bffffb04394fb4efd0cdab6b1e"}
'babashka/process {:mvn/version "0.4.13"}) 'babashka/process {:mvn/version "0.5.21"})
deps (dissoc deps deps (dissoc deps
'borkdude/sci 'borkdude/sci
'org.babashka/sci 'org.babashka/sci
@ -30,6 +30,7 @@
'org.hsqldb/hsqldb) 'org.hsqldb/hsqldb)
bb-edn-deps (:deps @common/bb-edn) bb-edn-deps (:deps @common/bb-edn)
deps (merge deps bb-edn-deps) deps (merge deps bb-edn-deps)
deps (into (sorted-map) deps)
paths (:paths @common/bb-edn) paths (:paths @common/bb-edn)
deps {:deps deps} deps {:deps deps}
deps (cond-> deps deps (cond-> deps

View file

@ -20,6 +20,18 @@
(binding [process/*defaults* @defaults] (binding [process/*defaults* @defaults]
(apply process/pb args))) (apply process/pb args)))
(defn sh [& args]
(binding [process/*defaults* @defaults]
(apply process/sh args)))
(defn shell [& args]
(binding [process/*defaults* @defaults]
(apply process/shell args)))
(defn exec [& args]
(binding [process/*defaults* @defaults]
(apply process/exec args)))
(def process-namespace (def process-namespace
{'parse-args (copy-var process/parse-args tns) {'parse-args (copy-var process/parse-args tns)
'process* (copy-var process/process* tns) 'process* (copy-var process/process* tns)
@ -29,11 +41,11 @@
'start (copy-var process/start tns) 'start (copy-var process/start tns)
'pipeline (copy-var process/pipeline tns) 'pipeline (copy-var process/pipeline tns)
'$ (copy-var process/$ tns) '$ (copy-var process/$ tns)
'sh (copy-var process/sh tns) 'sh (copy-var sh tns)
'tokenize (copy-var process/tokenize tns) 'tokenize (copy-var process/tokenize tns)
'*defaults* defaults '*defaults* defaults
'destroy (copy-var process/destroy tns) 'destroy (copy-var process/destroy tns)
'destroy-tree (copy-var process/destroy-tree tns) 'destroy-tree (copy-var process/destroy-tree tns)
'exec (copy-var process/exec tns) 'exec (copy-var exec tns)
'shell (copy-var process/shell tns) 'shell (copy-var shell tns)
'alive? (copy-var process/alive? tns)}) 'alive? (copy-var process/alive? tns)})

View file

@ -100,6 +100,36 @@
(write (write
([b] ((method-or-bust methods 'write) this b)) ([b] ((method-or-bust methods 'write) this b))
([b off len] ((method-or-bust methods 'write) this b off len)))) ([b off len] ((method-or-bust methods 'write) this b off len))))
["java.io.OutputStream" #{}]
(proxy [java.io.OutputStream] []
(close [] (when-let [m (get methods 'close)]
(m this)))
(flush [] (when-let [m (get methods 'flush)]
(m this)))
(write
([b]
((method-or-bust methods 'write) this b))
([b off len]
((method-or-bust methods 'write) this b off len))))
["javax.net.ssl.X509ExtendedTrustManager" #{}]
(proxy [javax.net.ssl.X509ExtendedTrustManager] []
(checkClientTrusted
([x y]
((method-or-bust methods 'checkClientTrusted) this x y))
([x y z]
((method-or-bust methods 'checkClientTrusted) this x y z)))
(checkServerTrusted
([x y]
((method-or-bust methods 'checkServerTrusted) this x y))
([x y z]
((method-or-bust methods 'checkServerTrusted) this x y z)))
(getAcceptedIssuers [] ((method-or-bust methods 'getAcceptedIssuers) this)))
["java.lang.ThreadLocal" #{}]
(proxy [java.lang.ThreadLocal] []
(initialValue []
((method-or-bust methods 'initialValue) this)))
, ;; keep this for merge friendliness , ;; keep this for merge friendliness
))) )))
@ -112,7 +142,9 @@
{:methods [{:name "connectFailed"} {:methods [{:name "connectFailed"}
{:name "select"}]} {:name "select"}]}
(class-sym (class (proxy-fn {:class javax.net.ssl.HostnameVerifier}))) (class-sym (class (proxy-fn {:class javax.net.ssl.HostnameVerifier})))
{:methods [{:name "verify"}]}}) {:methods [{:name "verify"}]}
(class-sym (class (proxy-fn {:class java.lang.ThreadLocal})))
{:methods [{:name "get"}]}})
;;; Scratch ;;; Scratch

View file

@ -1,6 +1,7 @@
(ns babashka.impl.repl (ns babashka.impl.repl
{:no-doc true} {:no-doc true}
(:require (:require
[babashka.impl.clojure.core :as core-extras]
[babashka.impl.clojure.main :as m] [babashka.impl.clojure.main :as m]
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.string :as str] [clojure.string :as str]
@ -50,41 +51,46 @@
([sci-ctx] (repl sci-ctx nil)) ([sci-ctx] (repl sci-ctx nil))
([sci-ctx {:keys [:init :read :eval :need-prompt :prompt :flush :print :caught]}] ([sci-ctx {:keys [:init :read :eval :need-prompt :prompt :flush :print :caught]}]
(let [in @sci/in] (let [in @sci/in]
(m/repl (sci/binding [core-extras/warn-on-reflection @core-extras/warn-on-reflection
:init (or init core-extras/unchecked-math @core-extras/unchecked-math
(fn [] core-extras/data-readers @core-extras/data-readers
(sci/with-bindings {sci/out @sci/err} sci/ns @sci/ns
(sio/println "Babashka" sci/print-length @sci/print-length]
(str "v" (str/trim (slurp (io/resource "BABASHKA_VERSION")))) (m/repl
"REPL.") :init (or init
(sio/println "Use :repl/quit or :repl/exit to quit the REPL.") (fn []
(sio/println "Clojure rocks, Bash reaches.") (sci/with-bindings {sci/out @sci/err}
(sio/println)) (sio/println "Babashka"
(eval-form sci-ctx `(apply require (quote ~m/repl-requires))))) (str "v" (str/trim (slurp (io/resource "BABASHKA_VERSION"))))
:read (or read "REPL.")
(fn [_request-prompt request-exit] (sio/println "Use :repl/quit or :repl/exit to quit the REPL.")
(if (nil? (r/peek-char in)) (sio/println "Clojure rocks, Bash reaches.")
request-exit (sio/println))
(let [v (parser/parse-next sci-ctx in)] (eval-form sci-ctx `(apply require (quote ~m/repl-requires)))))
(skip-if-eol in) :read (or read
(if (or (identical? :repl/quit v) (fn [_request-prompt request-exit]
(identical? :repl/exit v)) (if (nil? (r/peek-char in))
request-exit request-exit
v))))) (let [v (parser/parse-next sci-ctx in)]
:eval (or eval (skip-if-eol in)
(fn [expr] (if (or (identical? :repl/quit v)
(sci/with-bindings {sci/file "<repl>" (identical? :repl/exit v))
sci/*1 *1 request-exit
sci/*2 *2 v)))))
sci/*3 *3 :eval (or eval
sci/*e *e} (fn [expr]
(let [ret (eval-form sci-ctx expr)] (sci/with-bindings {sci/file "<repl>"
ret)))) sci/*1 *1
:need-prompt (or need-prompt (fn [] true)) sci/*2 *2
:prompt (or prompt #(sio/printf "%s=> " (utils/current-ns-name))) sci/*3 *3
:flush (or flush sio/flush) sci/*e *e}
:print (or print sio/prn) (let [ret (eval-form sci-ctx expr)]
:caught (or caught repl-caught))))) ret))))
:need-prompt (or need-prompt (fn [] true))
:prompt (or prompt #(sio/printf "%s=> " (utils/current-ns-name)))
:flush (or flush sio/flush)
:print (or print sio/prn)
:caught (or caught repl-caught))))))
(defn start-repl! (defn start-repl!
([sci-ctx] (start-repl! sci-ctx nil)) ([sci-ctx] (start-repl! sci-ctx nil))

52
src/babashka/impl/sci.clj Normal file
View file

@ -0,0 +1,52 @@
(ns babashka.impl.sci
{:no-doc true}
(:require [sci.core :as sci]
[sci.ctx-store :as store]))
(def sns (sci/create-ns 'sci.core nil))
(defmacro copy-ns
"Returns map of names to SCI vars as a result of copying public
Clojure vars from ns-sym (a symbol). Attaches sci-ns (result of
sci/create-ns) to meta. Copies :name, :macro :doc, :no-doc
and :argslists metadata.
Options:
- :exclude: a seqable of names to exclude from the
namespace. Defaults to none.
- :copy-meta: a seqable of keywords to copy from the original var
meta. Use :all instead of a seqable to copy all. Defaults
to [:doc :arglists :macro].
- :exclude-when-meta: seqable of keywords; vars with meta matching
these keys are excluded. Defaults to [:no-doc :skip-wiki]
The selection of vars is done at compile time which is mostly
important for ClojureScript to not pull in vars into the compiled
JS. Any additional vars can be added after the fact with sci/copy-var
manually."
([ns-sym sci-ns] `(sci.core/copy-ns ~ns-sym ~sci-ns nil))
([ns-sym sci-ns opts]
;; this branch is hit by macroexpanding in JVM Clojure, not in the CLJS compiler
(let [publics-map (sci/eval-form (store/get-ctx) (list 'ns-publics (list 'quote ns-sym)))
publics-map (#'sci/process-publics publics-map opts)
mf (#'sci/meta-fn (:copy-meta opts))
publics-map (#'sci/exclude-when-meta
publics-map
meta
(fn [k]
(list 'quote k))
(fn [var m]
{:name (list 'quote (:name m))
:var var
:meta (list 'quote (mf m))})
(or (:exclude-when-meta opts)
[:no-doc :skip-wiki]))]
`(sci.core/-copy-ns ~publics-map ~sci-ns))))
(def sci-core-namespace
(assoc (sci/copy-ns sci.core sns {:exclude [copy-ns]})
'copy-ns (sci/copy-var copy-ns sns)
'-copy-ns (sci/copy-var sci/-copy-ns sns)))

View file

@ -6,7 +6,6 @@
[babashka.impl.process :as pp] [babashka.impl.process :as pp]
[babashka.process :as p] [babashka.process :as p]
[clojure.core.async :refer [<!!]] [clojure.core.async :refer [<!!]]
[clojure.java.io :as io]
[clojure.string :as str] [clojure.string :as str]
[rewrite-clj.node :as node] [rewrite-clj.node :as node]
[rewrite-clj.parser :as parser] [rewrite-clj.parser :as parser]
@ -30,7 +29,7 @@
(let [log-level @log-level] (let [log-level @log-level]
(when (when
;; do not log when level is :error ;; do not log when level is :error
(identical? :info log-level) (identical? :info log-level)
(binding [*out* *err*] (binding [*out* *err*]
(println (format "[bb %s]" (:name @task)) (str/join " " strs)))))) (println (format "[bb %s]" (:name @task)) (str/join " " strs))))))
@ -67,29 +66,18 @@
(apply log-info args) (apply log-info args)
(handle-non-zero (pp/process* {:opts opts :cmd cmd :prev prev}) opts)))) (handle-non-zero (pp/process* {:opts opts :cmd cmd :prev prev}) opts))))
(defn clojure [cmd & args] (defn clojure [& args]
(let [[opts cmd args] (let [[cmd & args] args
[opts cmd args]
(if (map? cmd) (if (map? cmd)
[cmd (first args) (rest args)] [cmd (first args) (rest args)]
[nil cmd args]) [nil cmd args])
opts (if-let [o (:out opts)] cmd (cond-> args
(if (string? o) cmd (->> (cons cmd)))
(update opts :out io/file)
opts)
opts)
opts (if-let [o (:err opts)]
(if (string? o)
(update opts :err io/file)
opts)
opts)
cmd (if (.exists (io/file cmd))
[cmd]
(p/tokenize cmd))
cmd (into cmd args)
local-log-level (:log-level opts)] local-log-level (:log-level opts)]
(sci/binding [log-level (or local-log-level @log-level)] (sci/binding [log-level (or local-log-level @log-level)]
(apply log-info (cons "clojure" cmd)) (apply log-info (cons "clojure" cmd))
(handle-non-zero (deps/clojure cmd (merge default-opts opts)) opts)))) (handle-non-zero (apply deps/clojure (merge default-opts opts) cmd) opts))))
(defn -wait [res] (defn -wait [res]
(when res (when res
@ -139,7 +127,7 @@
"Used internally for debugging" "Used internally for debugging"
[& strs] [& strs]
(locking o (locking o
(apply prn strs))) (apply prn strs)))
(defn wait-tasks [deps] (defn wait-tasks [deps]
(if deps (if deps
@ -397,7 +385,7 @@
loc (zip/down loc)] loc (zip/down loc)]
(into [] (into []
(comp (comp
(take-nth 2 ) (take-nth 2)
(take-while #(not (zip/end? %))) (take-while #(not (zip/end? %)))
(filter zip/sexpr-able?) (filter zip/sexpr-able?)
(map zip/sexpr) (map zip/sexpr)
@ -437,8 +425,11 @@
([task] (run task nil)) ([task] (run task nil))
([task {:keys [:parallel] ([task {:keys [:parallel]
:or {parallel (:parallel (current-task))}}] :or {parallel (:parallel (current-task))}}]
(let [[[expr]] (assemble-task task parallel)] (let [[[expr] exit-code] (assemble-task task parallel)]
(sci/eval-string* (ctx) expr)))) (if (or (nil? exit-code) (zero? exit-code))
(sci/eval-string* (ctx) expr)
(throw (ex-info nil
{:babashka/exit exit-code}))))))
(defn exec (defn exec
([sym] ([sym]

View file

@ -19,13 +19,14 @@
[babashka.impl.clojure.java.shell :refer [shell-namespace]] [babashka.impl.clojure.java.shell :refer [shell-namespace]]
[babashka.impl.clojure.main :as clojure-main :refer [demunge]] [babashka.impl.clojure.main :as clojure-main :refer [demunge]]
[babashka.impl.clojure.math :refer [math-namespace]] [babashka.impl.clojure.math :refer [math-namespace]]
[babashka.impl.clojure.reflect :refer [reflect-namespace]]
[babashka.impl.clojure.stacktrace :refer [stacktrace-namespace]] [babashka.impl.clojure.stacktrace :refer [stacktrace-namespace]]
[babashka.impl.clojure.tools.reader :refer [reader-namespace]] [babashka.impl.clojure.tools.reader :refer [reader-namespace]]
[babashka.impl.clojure.tools.reader-types :refer [edn-namespace [babashka.impl.clojure.tools.reader-types :refer [edn-namespace
reader-types-namespace]] reader-types-namespace]]
[babashka.impl.clojure.zip :refer [zip-namespace]] [babashka.impl.clojure.zip :refer [zip-namespace]]
[babashka.impl.common :as common] [babashka.impl.common :as common]
[babashka.impl.core :as bbcore] [babashka.impl.core :as bbcore]
[babashka.impl.curl :refer [curl-namespace]] [babashka.impl.curl :refer [curl-namespace]]
[babashka.impl.data :as data] [babashka.impl.data :as data]
[babashka.impl.datafy :refer [datafy-namespace]] [babashka.impl.datafy :refer [datafy-namespace]]
@ -34,6 +35,7 @@
[babashka.impl.error-handler :refer [error-handler]] [babashka.impl.error-handler :refer [error-handler]]
[babashka.impl.features :as features] [babashka.impl.features :as features]
[babashka.impl.fs :refer [fs-namespace]] [babashka.impl.fs :refer [fs-namespace]]
[babashka.impl.http-client :refer [http-client-namespace http-client-websocket-namespace]]
[babashka.impl.nrepl-server :refer [nrepl-server-namespace]] [babashka.impl.nrepl-server :refer [nrepl-server-namespace]]
[babashka.impl.pods :as pods] [babashka.impl.pods :as pods]
[babashka.impl.pprint :refer [pprint-namespace]] [babashka.impl.pprint :refer [pprint-namespace]]
@ -44,6 +46,7 @@
[babashka.impl.reify2 :refer [reify-fn]] [babashka.impl.reify2 :refer [reify-fn]]
[babashka.impl.repl :as repl] [babashka.impl.repl :as repl]
[babashka.impl.rewrite-clj :as rewrite] [babashka.impl.rewrite-clj :as rewrite]
[babashka.impl.sci :refer [sci-core-namespace]]
[babashka.impl.server :refer [clojure-core-server-namespace]] [babashka.impl.server :refer [clojure-core-server-namespace]]
[babashka.impl.socket-repl :as socket-repl] [babashka.impl.socket-repl :as socket-repl]
[babashka.impl.tasks :as tasks :refer [tasks-namespace]] [babashka.impl.tasks :as tasks :refer [tasks-namespace]]
@ -55,6 +58,7 @@
[clojure.edn :as edn] [clojure.edn :as edn]
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.string :as str] [clojure.string :as str]
[edamame.core :as edamame]
[hf.depstar.uberjar :as uberjar] [hf.depstar.uberjar :as uberjar]
[sci.addons :as addons] [sci.addons :as addons]
[sci.core :as sci] [sci.core :as sci]
@ -62,6 +66,7 @@
[sci.impl.copy-vars :as sci-copy-vars] [sci.impl.copy-vars :as sci-copy-vars]
[sci.impl.io :as sio] [sci.impl.io :as sio]
[sci.impl.namespaces :as sci-namespaces] [sci.impl.namespaces :as sci-namespaces]
[sci.impl.parser]
[sci.impl.types :as sci-types] [sci.impl.types :as sci-types]
[sci.impl.unrestrict :refer [*unrestricted*]] [sci.impl.unrestrict :refer [*unrestricted*]]
[sci.impl.vars :as vars]) [sci.impl.vars :as vars])
@ -139,6 +144,7 @@
(println " (println "
Usage: bb [svm-opts] [global-opts] [eval opts] [cmdline args] Usage: bb [svm-opts] [global-opts] [eval opts] [cmdline args]
or: bb [svm-opts] [global-opts] file [cmdline args] or: bb [svm-opts] [global-opts] file [cmdline args]
or: bb [svm-opts] [global-opts] task [cmdline args]
or: bb [svm-opts] [global-opts] subcommand [subcommand opts] [cmdline args] or: bb [svm-opts] [global-opts] subcommand [subcommand opts] [cmdline args]
Substrate VM opts: Substrate VM opts:
@ -151,10 +157,13 @@ Global opts:
-cp, --classpath Classpath to use. Overrides bb.edn classpath. -cp, --classpath Classpath to use. Overrides bb.edn classpath.
--debug Print debug information and internal stacktrace in case of exception. --debug Print debug information and internal stacktrace in case of exception.
--init <file> Load file after any preloads and prior to evaluation/subcommands. --init <file> Load file after any preloads and prior to evaluation/subcommands.
--config <file> Replacing bb.edn with file. Relative paths are resolved relative to file. --config <file> Replace bb.edn with file. Defaults to bb.edn adjacent to invoked file or bb.edn in current dir. Relative paths are resolved relative to bb.edn.
--deps-root <dir> Treat dir as root of relative paths in config. --deps-root <dir> Treat dir as root of relative paths in config.
--prn Print result via clojure.core/prn
-Sforce Force recalculation of the classpath (don't use the cache) -Sforce Force recalculation of the classpath (don't use the cache)
-Sdeps Deps data to use as the last deps file to be merged -Sdeps Deps data to use as the last deps file to be merged
-f, --file <path> Run file
--jar <path> Run uberjar
Help: Help:
@ -166,7 +175,6 @@ Help:
Evaluation: Evaluation:
-e, --eval <expr> Evaluate an expression. -e, --eval <expr> Evaluate an expression.
-f, --file <path> Evaluate a file.
-m, --main <ns|var> Call the -main function from a namespace or call a fully qualified var. -m, --main <ns|var> Call the -main function from a namespace or call a fully qualified var.
-x, --exec <var> Call the fully qualified var. Args are parsed by babashka CLI. -x, --exec <var> Call the fully qualified var. Args are parsed by babashka CLI.
@ -232,8 +240,7 @@ When no eval opts or subcommand is provided, the implicit subcommand is repl.")
(clojure.repl/doc %1$s) (clojure.repl/doc %1$s)
true)" arg))) true)" arg)))
[nil 0] [nil 0]
[nil 1])) [nil 1])))
,)
(defn print-run-help [] (defn print-run-help []
(println (str/trim " (println (str/trim "
@ -320,25 +327,25 @@ Use bb run --help to show this help output.
(def aliases (def aliases
(cond-> (cond->
'{str clojure.string '{str clojure.string
set clojure.set set clojure.set
tools.cli clojure.tools.cli tools.cli clojure.tools.cli
edn clojure.edn edn clojure.edn
wait babashka.wait wait babashka.wait
signal babashka.signal signal babashka.signal
shell clojure.java.shell shell clojure.java.shell
io clojure.java.io io clojure.java.io
json cheshire.core json cheshire.core
curl babashka.curl curl babashka.curl
fs babashka.fs fs babashka.fs
bencode bencode.core bencode bencode.core
deps babashka.deps deps babashka.deps
async clojure.core.async} async clojure.core.async}
features/xml? (assoc 'xml 'clojure.data.xml) features/xml? (assoc 'xml 'clojure.data.xml)
features/yaml? (assoc 'yaml 'clj-yaml.core) features/yaml? (assoc 'yaml 'clj-yaml.core)
features/jdbc? (assoc 'jdbc 'next.jdbc) features/jdbc? (assoc 'jdbc 'next.jdbc)
features/csv? (assoc 'csv 'clojure.data.csv) features/csv? (assoc 'csv 'clojure.data.csv)
features/transit? (assoc 'transit 'cognitect.transit))) features/transit? (assoc 'transit 'cognitect.transit)))
;;(def ^:private server-ns-obj (sci/create-ns 'clojure.core.server nil)) ;;(def ^:private server-ns-obj (sci/create-ns 'clojure.core.server nil))
@ -349,85 +356,85 @@ Use bb run --help to show this help output.
(defn catvec [& xs] (defn catvec [& xs]
(into [] cat xs)) (into [] cat xs))
(def sci-ns (sci/create-ns 'sci.core)) (def main-var (sci/new-var 'main nil {:ns clojure-main-ns}))
(require '[clojure.reflect] '[clojure.core.memoize :as memoize]) (require '[clojure.reflect] '[clojure.core.memoize :as memoize])
(def namespaces (def namespaces
(cond-> (cond->
{'user {'*input* (reify {'user {'*input* (reify
sci-types/Eval sci-types/Eval
(eval [_ _ctx _bindings] (eval [_ _ctx _bindings]
(force @input-var)))} (force @input-var)))}
'clojure.tools.cli tools-cli-namespace 'clojure.core core-extras
'clojure.java.shell shell-namespace 'clojure.tools.cli tools-cli-namespace
'babashka.core bbcore/core-namespace 'clojure.java.shell shell-namespace
'babashka.nrepl.server nrepl-server-namespace 'babashka.core bbcore/core-namespace
'babashka.wait wait-namespace 'babashka.nrepl.server nrepl-server-namespace
'babashka.signal signal-ns 'babashka.wait wait-namespace
'clojure.java.io io-namespace 'babashka.signal signal-ns
'cheshire.core cheshire-core-namespace 'clojure.java.io io-namespace
'clojure.data data/data-namespace 'cheshire.core cheshire-core-namespace
'clojure.instant instant/instant-namespace 'clojure.data data/data-namespace
'clojure.stacktrace stacktrace-namespace 'clojure.instant instant/instant-namespace
'clojure.zip zip-namespace 'clojure.stacktrace stacktrace-namespace
'clojure.main {:obj clojure-main-ns 'clojure.zip zip-namespace
'demunge (sci/copy-var demunge clojure-main-ns) 'clojure.main {:obj clojure-main-ns
'repl-requires (sci/copy-var clojure-main/repl-requires clojure-main-ns) 'demunge (sci/copy-var demunge clojure-main-ns)
'repl (sci/new-var 'repl 'repl-requires (sci/copy-var clojure-main/repl-requires clojure-main-ns)
(fn [& opts] 'repl (sci/new-var 'repl
(let [opts (apply hash-map opts)] (fn [& opts]
(repl/start-repl! (common/ctx) opts))) {:ns clojure-main-ns}) (let [opts (apply hash-map opts)]
'with-bindings (sci/copy-var clojure-main/with-bindings clojure-main-ns)} (repl/start-repl! (common/ctx) opts))) {:ns clojure-main-ns})
'clojure.test t/clojure-test-namespace 'with-bindings (sci/copy-var clojure-main/with-bindings clojure-main-ns)
'clojure.math math-namespace 'repl-caught (sci/copy-var repl/repl-caught clojure-main-ns)
'babashka.classpath classpath-namespace 'main main-var}
'babashka.classes classes-namespace 'clojure.test t/clojure-test-namespace
'clojure.pprint pprint-namespace 'clojure.math math-namespace
'babashka.curl curl-namespace 'babashka.classpath classpath-namespace
'babashka.fs fs-namespace 'babashka.classes classes-namespace
'babashka.pods pods/pods-namespace 'clojure.pprint pprint-namespace
'bencode.core bencode-namespace 'babashka.curl curl-namespace
'clojure.java.browse browse-namespace 'babashka.fs fs-namespace
'clojure.datafy datafy-namespace 'babashka.pods pods/pods-namespace
'clojure.core.protocols protocols-namespace 'bencode.core bencode-namespace
'babashka.process process-namespace 'clojure.java.browse browse-namespace
'clojure.core.server clojure-core-server-namespace 'clojure.datafy datafy-namespace
'babashka.deps deps-namespace 'clojure.core.protocols protocols-namespace
'babashka.tasks tasks-namespace 'babashka.process process-namespace
'clojure.tools.reader.edn edn-namespace 'clojure.core.server clojure-core-server-namespace
'clojure.tools.reader.reader-types reader-types-namespace 'babashka.deps deps-namespace
'clojure.tools.reader reader-namespace 'babashka.tasks tasks-namespace
'clojure.core.async async-namespace 'clojure.tools.reader.edn edn-namespace
'clojure.core.async.impl.protocols async-protocols-namespace 'clojure.tools.reader.reader-types reader-types-namespace
'rewrite-clj.node rewrite/node-namespace 'clojure.tools.reader reader-namespace
'rewrite-clj.paredit rewrite/paredit-namespace 'clojure.core.async async-namespace
'rewrite-clj.parser rewrite/parser-namespace 'clojure.core.async.impl.protocols async-protocols-namespace
'rewrite-clj.zip rewrite/zip-namespace 'clojure.reflect reflect-namespace
'rewrite-clj.zip.subedit rewrite/subedit-namespace 'rewrite-clj.node rewrite/node-namespace
'clojure.core.rrb-vector (if features/rrb-vector? 'rewrite-clj.paredit rewrite/paredit-namespace
@(resolve 'babashka.impl.rrb-vector/rrb-vector-namespace) 'rewrite-clj.parser rewrite/parser-namespace
{'catvec (sci/copy-var catvec 'rewrite-clj.zip rewrite/zip-namespace
(sci/create-ns 'clojure.core.rrb-vector))}) 'rewrite-clj.zip.subedit rewrite/subedit-namespace
'edamame.core edamame-namespace 'clojure.core.rrb-vector (if features/rrb-vector?
'sci.core {'format-stacktrace (sci/copy-var sci/format-stacktrace sci-ns) @(resolve 'babashka.impl.rrb-vector/rrb-vector-namespace)
'stacktrace (sci/copy-var sci/stacktrace sci-ns) {'catvec (sci/copy-var catvec
;; 'eval-string (sci/copy-var sci/eval-string sci-ns) (sci/create-ns 'clojure.core.rrb-vector))})
;; 'eval-string* (sci/copy-var sci/eval-string* sci-ns) 'edamame.core edamame-namespace
;; 'init (sci/copy-var sci/init sci-ns) 'sci.core sci-core-namespace
;; 'fork (sci/copy-var sci/fork sci-ns) 'babashka.cli cli/cli-namespace
} 'babashka.http-client http-client-namespace
'babashka.cli cli/cli-namespace 'babashka.http-client.websocket http-client-websocket-namespace}
} features/xml? (assoc 'clojure.data.xml @(resolve 'babashka.impl.xml/xml-namespace)
features/xml? (assoc 'clojure.data.xml @(resolve 'babashka.impl.xml/xml-namespace) 'clojure.data.xml.event @(resolve 'babashka.impl.xml/xml-event-namespace)
'clojure.data.xml.event @(resolve 'babashka.impl.xml/xml-event-namespace) 'clojure.data.xml.tree @(resolve 'babashka.impl.xml/xml-tree-namespace))
'clojure.data.xml.tree @(resolve 'babashka.impl.xml/xml-tree-namespace))
features/yaml? (assoc 'clj-yaml.core @(resolve 'babashka.impl.yaml/yaml-namespace) features/yaml? (assoc 'clj-yaml.core @(resolve 'babashka.impl.yaml/yaml-namespace)
'flatland.ordered.map @(resolve 'babashka.impl.ordered/ordered-map-ns)) 'flatland.ordered.map @(resolve 'babashka.impl.ordered/ordered-map-ns)
'flatland.ordered.set @(resolve 'babashka.impl.ordered/ordered-set-ns))
features/jdbc? (assoc 'next.jdbc @(resolve 'babashka.impl.jdbc/njdbc-namespace) features/jdbc? (assoc 'next.jdbc @(resolve 'babashka.impl.jdbc/njdbc-namespace)
'next.jdbc.sql @(resolve 'babashka.impl.jdbc/next-sql-namespace) 'next.jdbc.sql @(resolve 'babashka.impl.jdbc/next-sql-namespace)
'next.jdbc.result-set @(resolve 'babashka.impl.jdbc/result-set-namespace)) 'next.jdbc.result-set @(resolve 'babashka.impl.jdbc/result-set-namespace))
features/csv? (assoc 'clojure.data.csv @(resolve 'babashka.impl.csv/csv-namespace)) features/csv? (assoc 'clojure.data.csv @(resolve 'babashka.impl.csv/csv-namespace))
features/transit? (assoc 'cognitect.transit @(resolve 'babashka.impl.transit/transit-namespace)) features/transit? (assoc 'cognitect.transit @(resolve 'babashka.impl.transit/transit-namespace))
features/datascript? (assoc 'datascript.core @(resolve 'babashka.impl.datascript/datascript-namespace) features/datascript? (assoc 'datascript.core @(resolve 'babashka.impl.datascript/datascript-namespace)
'datascript.db @(resolve 'babashka.impl.datascript/datascript-db-namespace)) 'datascript.db @(resolve 'babashka.impl.datascript/datascript-db-namespace))
@ -455,8 +462,8 @@ Use bb run --help to show this help output.
@(resolve 'babashka.impl.clojure.test.check/test-check-namespace) @(resolve 'babashka.impl.clojure.test.check/test-check-namespace)
;; it's better to load this from source by adding the clojure.test.check dependency ;; it's better to load this from source by adding the clojure.test.check dependency
#_#_'clojure.test.check.clojure-test #_#_'clojure.test.check.clojure-test
@(resolve 'babashka.impl.clojure.test.check/test-check-clojure-test-namespace)) @(resolve 'babashka.impl.clojure.test.check/test-check-clojure-test-namespace))
features/spec-alpha? (-> (assoc ;; spec features/spec-alpha? (-> (assoc ;; spec
'clojure.spec.alpha @(resolve 'babashka.impl.spec/spec-namespace) 'clojure.spec.alpha @(resolve 'babashka.impl.spec/spec-namespace)
'clojure.spec.gen.alpha @(resolve 'babashka.impl.spec/gen-namespace) 'clojure.spec.gen.alpha @(resolve 'babashka.impl.spec/gen-namespace)
'clojure.spec.test.alpha @(resolve 'babashka.impl.spec/test-namespace))) 'clojure.spec.test.alpha @(resolve 'babashka.impl.spec/test-namespace)))
@ -471,6 +478,7 @@ Use bb run --help to show this help output.
'selmer.validator 'selmer.validator
@(resolve 'babashka.impl.selmer/selmer-validator-namespace)) @(resolve 'babashka.impl.selmer/selmer-validator-namespace))
features/logging? (assoc 'taoensso.timbre @(resolve 'babashka.impl.logging/timbre-namespace) features/logging? (assoc 'taoensso.timbre @(resolve 'babashka.impl.logging/timbre-namespace)
'taoensso.timbre.appenders.core @(resolve 'babashka.impl.logging/timbre-appenders-namespace)
'clojure.tools.logging 'clojure.tools.logging
@(resolve 'babashka.impl.logging/tools-logging-namespace) @(resolve 'babashka.impl.logging/tools-logging-namespace)
'clojure.tools.logging.impl 'clojure.tools.logging.impl
@ -487,7 +495,8 @@ Use bb run --help to show this help output.
(def edn-readers (cond-> {} (def edn-readers (cond-> {}
features/yaml? features/yaml?
(assoc 'ordered/map @(resolve 'flatland.ordered.map/ordered-map)) (assoc 'ordered/map @(resolve 'flatland.ordered.map/ordered-map)
'ordered/set @(resolve 'flatland.ordered.set/ordered-set))
features/xml? features/xml?
(assoc 'xml/ns @(resolve 'clojure.data.xml.name/uri-symbol) (assoc 'xml/ns @(resolve 'clojure.data.xml.name/uri-symbol)
'xml/element @(resolve 'clojure.data.xml.node/tagged-element)))) 'xml/element @(resolve 'clojure.data.xml.node/tagged-element))))
@ -575,10 +584,10 @@ Use bb run --help to show this help output.
:edn-in true)) :edn-in true))
("-o") (recur (next options) ("-o") (recur (next options)
(assoc opts-map (assoc opts-map
:shell-out true)) :shell-out true :prn true))
("-O") (recur (next options) ("-O") (recur (next options)
(assoc opts-map (assoc opts-map
:edn-out true)) :edn-out true :prn true))
("-io") (recur (next options) ("-io") (recur (next options)
(assoc opts-map (assoc opts-map
:shell-in true :shell-in true
@ -609,16 +618,6 @@ Use bb run --help to show this help output.
(recur (next options) (recur (next options)
(assoc opts-map (assoc opts-map
:uberjar (first options)))) :uberjar (first options))))
("-f" "--file")
(let [options (next options)]
(recur (next options)
(assoc opts-map
:file (first options))))
("--jar" "-jar")
(let [options (next options)]
(recur (next options)
(assoc opts-map
:jar (first options))))
("--repl") ("--repl")
(let [options (next options)] (let [options (next options)]
(recur (next options) (recur (next options)
@ -645,16 +644,17 @@ Use bb run --help to show this help output.
(assoc opts-map (assoc opts-map
:nrepl (or opt "1667")))) :nrepl (or opt "1667"))))
("--eval", "-e") ("--eval", "-e")
(let [options (next options)] (let [options (next options)
opts-map (assoc opts-map :prn true)]
(recur (next options) (recur (next options)
(update opts-map :expressions (fnil conj []) (first options)))) (update opts-map :expressions (fnil conj []) (first options))))
("--main", "-m",) ("--main", "-m")
(let [options (next options)] (let [options (next options)]
(assoc opts-map :main (first options) (assoc opts-map :main (first options)
:command-line-args (if (= "--" (second options)) :command-line-args (if (= "--" (second options))
(nthrest options 2) (nthrest options 2)
(rest options)))) (rest options))))
("--exec", "-x",) ("--exec", "-x")
(let [options (next options)] (let [options (next options)]
(assoc opts-map :exec (first options) (assoc opts-map :exec (first options)
:command-line-args (if (= "--" (second options)) :command-line-args (if (= "--" (second options))
@ -681,6 +681,7 @@ Use bb run --help to show this help output.
(case c (case c
(\( \{ \[ \* \@ \#) (\( \{ \[ \* \@ \#)
(-> opts-map (-> opts-map
(assoc :prn true)
(update :expressions (fnil conj []) (first options)) (update :expressions (fnil conj []) (first options))
(assoc :command-line-args (next options))) (assoc :command-line-args (next options)))
(assoc opts-map (assoc opts-map
@ -716,36 +717,49 @@ Use bb run --help to show this help output.
("--deps-root") ("--deps-root")
(recur (nnext options) (assoc opts-map :deps-root (second options))) (recur (nnext options) (assoc opts-map :deps-root (second options)))
("--prn")
(recur (next options) (assoc opts-map :prn true))
("-f" "--file")
(recur (nnext options) (assoc opts-map :file (second options)))
("-jar" "--jar")
(recur (nnext options) (assoc opts-map :jar (second options)))
[options opts-map]) [options opts-map])
[options opts-map]))) [options opts-map])))
(defn parse-file-opt (defn parse-file-opt
[options opts-map] [options opts-map]
(let [opt (first options) (let [opt (first options)]
opts-key (if (str/ends-with? opt ".jar") (if (and opt (and (fs/exists? opt)
:jar :file)] (not (fs/directory? opt))))
(assoc opts-map [nil (assoc opts-map
opts-key opt (if (str/ends-with? opt ".jar")
:command-line-args (next options)))) :jar :file) opt
:command-line-args (next options))]
[options opts-map])))
(defn parse-opts (defn parse-opts
([options] (parse-opts options nil)) ([options] (parse-opts options nil))
([options opts-map] ([options opts-map]
(let [opt (first options) (let [opt (first options)
tasks (into #{} (map str) (keys (:tasks @common/bb-edn)))] task-map (:tasks @common/bb-edn)
tasks (into #{} (map str) (keys task-map))]
(when-let [commands (seq (filter (fn [task]
(and (command? task)
(not (:override-builtin (get task-map (symbol task))))))
tasks))]
(binding [*out* *err*]
(println "[babashka] WARNING: task(s)" (str/join ", " (map #(format "'%s'" %) commands)) "override built-in command(s). Use :override-builtin true to disable warning.")))
(if-not opt opts-map (if-not opt opts-map
;; FILE > TASK > SUBCOMMAND ;; FILE > TASK > SUBCOMMAND
(cond (cond
(.isFile (io/file opt)) (and (not (or (:file opts-map)
(if (or (:file opts-map) (:jar opts-map)) (:jar opts-map)))
opts-map ; we've already parsed the file opt (.isFile (io/file opt)))
(parse-file-opt options opts-map)) (parse-file-opt options opts-map)
(contains? tasks opt) (contains? tasks opt)
(assoc opts-map (assoc opts-map
:run opt :run opt
:command-line-args (next options)) :command-line-args (next options))
(command? opt) (command? opt)
(recur (cons (str "--" opt) (next options)) opts-map) (recur (cons (str "--" opt) (next options)) opts-map)
@ -775,13 +789,56 @@ Use bb run --help to show this help output.
env-os-name-present? (not= env-os-name sys-os-name) env-os-name-present? (not= env-os-name sys-os-name)
env-os-arch-present? (not= env-os-arch sys-os-arch)))) env-os-arch-present? (not= env-os-arch sys-os-arch))))
(defn file-write-allowed?
"For output file of uberscript/uberjar, allow writing of jar files
and files that are empty/don't exist."
[path]
(or (= "jar" (fs/extension path))
(not (fs/exists? path))))
(def seen-urls (atom nil))
(defn read-data-readers [url]
(edamame/parse-string (slurp url)
{:read-cond :allow
:features #{:bb :clj}
:eof nil}))
(defn readers-fn
"Lazy reading of data reader functions"
[ctx t]
(or (@core/data-readers t)
(default-data-readers t)
(when (simple-symbol? t)
(when-let [the-var (sci/resolve ctx t)]
(some-> the-var meta :sci.impl.record/map-constructor)))
(when-let [f @sci.impl.parser/default-data-reader-fn]
(fn [form]
(f t form)))
(let [;; urls is a vector for equality check
urls (vec (.getURLs ^java.net.URLClassLoader @cp/the-url-loader))
parsed-resources (or (get @seen-urls urls)
(let [^java.net.URLClassLoader cl @cp/the-url-loader
resources (concat (enumeration-seq (.getResources cl "data_readers.clj"))
(enumeration-seq (.getResources cl "data_readers.cljc")))
parsed-resources (apply merge (map read-data-readers resources))
_ (swap! seen-urls assoc urls parsed-resources)]
parsed-resources))]
(when-let [var-sym (get parsed-resources t)]
(when-let [the-var (sci/resolve ctx var-sym)]
(sci/eval-form ctx (list 'clojure.core/var-set core/data-readers (list 'quote (assoc @core/data-readers t the-var))))
the-var)))))
(defn exec [cli-opts] (defn exec [cli-opts]
(binding [*unrestricted* true] (with-bindings {#'*unrestricted* true
clojure.lang.Compiler/LOADER @cp/the-url-loader}
(sci/binding [core/warn-on-reflection @core/warn-on-reflection (sci/binding [core/warn-on-reflection @core/warn-on-reflection
core/unchecked-math @core/unchecked-math core/unchecked-math @core/unchecked-math
core/data-readers @core/data-readers core/data-readers @core/data-readers
sci/ns @sci/ns sci/ns @sci/ns
sci/print-length @sci/print-length] sci/print-length @sci/print-length
;; when adding vars here, also add them to repl.clj and nrepl_server.clj
]
(let [{version-opt :version (let [{version-opt :version
:keys [:shell-in :edn-in :shell-out :edn-out :keys [:shell-in :edn-in :shell-out :edn-out
:help :file :command-line-args :help :file :command-line-args
@ -794,6 +851,7 @@ Use bb run --help to show this help output.
:print-deps :prepare] :print-deps :prepare]
exec-fn :exec} exec-fn :exec}
cli-opts cli-opts
print-result? (:prn cli-opts)
_ (when debug (vreset! common/debug true)) _ (when debug (vreset! common/debug true))
_ (do ;; set properties _ (do ;; set properties
(when main (System/setProperty "babashka.main" main)) (when main (System/setProperty "babashka.main" main))
@ -828,15 +886,14 @@ Use bb run --help to show this help output.
abs-path)) abs-path))
_ (when jar _ (when jar
(cp/add-classpath jar)) (cp/add-classpath jar))
load-fn (fn [{:keys [:namespace :reload]}] load-fn (fn [{:keys [namespace reload ctx]}]
(let [{:keys [loader]} (let [loader @cp/the-url-loader]
@cp/cp-state]
(or (or
(when ;; ignore built-in namespaces when uberscripting, unless with :reload (when ;; ignore built-in namespaces when uberscripting, unless with :reload
(and uberscript (and uberscript
(not reload) (not reload)
(or (contains? namespaces namespace) (or (contains? namespaces namespace)
(contains? sci-namespaces/namespaces namespace))) (contains? sci-namespaces/namespaces namespace)))
"") "")
;; pod namespaces go before namespaces from source, ;; pod namespaces go before namespaces from source,
;; unless reload is used ;; unless reload is used
@ -873,19 +930,18 @@ Use bb run --help to show this help output.
clojure.core.specs.alpha clojure.core.specs.alpha
(binding [*out* *err*] (binding [*out* *err*]
(println "[babashka] WARNING: clojure.core.specs.alpha is removed from the classpath, unless you explicitly add the dependency.")) (println "[babashka] WARNING: clojure.core.specs.alpha is removed from the classpath, unless you explicitly add the dependency."))
nil)))) (when-not (sci/find-ns ctx namespace)
(let [file (str/replace (namespace-munge namespace) "." "/")]
(throw (new java.io.FileNotFoundException (format "Could not locate %s.bb, %s.clj or %s.cljc on classpath." file file file)))))))))
main (if (and jar (not main)) main (if (and jar (not main))
(when-let [res (cp/getResource (when-let [res (cp/getResource
(cp/loader jar) (cp/new-loader [jar])
["META-INF/MANIFEST.MF"] {:url? true})] ["META-INF/MANIFEST.MF"] {:url? true})]
(cp/main-ns res)) (cp/main-ns res))
main) main)
;; TODO: pull more of these values to compile time ;; TODO: pull more of these values to compile time
opts {:aliases aliases opts {:aliases aliases
:namespaces (-> namespaces :namespaces (assoc-in namespaces ['clojure.core 'load-file] (sci-copy-vars/new-var 'load-file load-file*))
(assoc 'clojure.core
(assoc core-extras
'load-file (sci-copy-vars/new-var 'load-file load-file*))))
:env env :env env
:features #{:bb :clj} :features #{:bb :clj}
:classes @classes/class-map :classes @classes/class-map
@ -894,13 +950,14 @@ Use bb run --help to show this help output.
:uberscript uberscript :uberscript uberscript
;; :readers core/data-readers ;; :readers core/data-readers
:reify-fn reify-fn :reify-fn reify-fn
:proxy-fn proxy-fn} :proxy-fn proxy-fn
:readers #(readers-fn (common/ctx) %)}
opts (addons/future opts) opts (addons/future opts)
sci-ctx (sci/init opts) sci-ctx (sci/init opts)
_ (ctx-store/reset-ctx! sci-ctx) _ (ctx-store/reset-ctx! sci-ctx)
_ (when-let [pods (:pods @common/bb-edn)] _ (when-let [pods (:pods @common/bb-edn)]
(when-let [pod-metadata (pods/load-pods-metadata (when-let [pod-metadata (pods/load-pods-metadata
pods {:download-only (download-only?)})] pods {:download-only (download-only?)})]
(vreset! pod-namespaces pod-metadata))) (vreset! pod-namespaces pod-metadata)))
preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim)) preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim))
[expressions exit-code] [expressions exit-code]
@ -929,7 +986,7 @@ Use bb run --help to show this help output.
:debug debug :debug debug
:preloads preloads :preloads preloads
:init init :init init
:loader (:loader @cp/cp-state)})))) :loader @cp/the-url-loader}))))
expression (str/join " " expressions) ;; this might mess with the locations... expression (str/join " " expressions) ;; this might mess with the locations...
exit-code exit-code
;; handle preloads ;; handle preloads
@ -943,7 +1000,7 @@ Use bb run --help to show this help output.
:debug debug :debug debug
:preloads preloads :preloads preloads
:init init :init init
:loader (:loader @cp/cp-state)}))))) :loader @cp/the-url-loader})))))
nil)) nil))
exit-code exit-code
;; handle --init ;; handle --init
@ -956,7 +1013,7 @@ Use bb run --help to show this help output.
:debug debug :debug debug
:preloads preloads :preloads preloads
:init init :init init
:loader (:loader @cp/cp-state)})))) :loader @cp/the-url-loader}))))
nil)) nil))
;; socket REPL is start asynchronously. when no other args are ;; socket REPL is start asynchronously. when no other args are
;; provided, a normal REPL will be started as well, which causes the ;; provided, a normal REPL will be started as well, which causes the
@ -999,8 +1056,7 @@ Use bb run --help to show this help output.
(sci/eval-string* sci-ctx expression))] (sci/eval-string* sci-ctx expression))]
;; return value printing ;; return value printing
(when (and (some? res) (when (and (some? res)
(or (not run) print-result?)
(:prn cli-opts)))
(if-let [pr-f (cond shell-out println (if-let [pr-f (cond shell-out println
edn-out sio/prn)] edn-out sio/prn)]
(if (sequential? res) (if (sequential? res)
@ -1016,7 +1072,7 @@ Use bb run --help to show this help output.
(error-handler e {:expression expression (error-handler e {:expression expression
:debug debug :debug debug
:preloads preloads :preloads preloads
:loader (:loader @cp/cp-state)})))) :loader @cp/the-url-loader}))))
clojure [nil (if-let [proc (bdeps/clojure command-line-args)] clojure [nil (if-let [proc (bdeps/clojure command-line-args)]
(-> @proc :exit) (-> @proc :exit)
0)] 0)]
@ -1024,29 +1080,38 @@ Use bb run --help to show this help output.
1)] 1)]
(flush) (flush)
(when uberscript (when uberscript
(let [uberscript-out uberscript] (if (file-write-allowed? uberscript)
(spit uberscript-out "") ;; reset file (do
(doseq [s (distinct @uberscript-sources)] (spit uberscript "") ;; reset file
(spit uberscript-out s :append true)) (doseq [s (distinct @uberscript-sources)]
(spit uberscript-out preloads :append true) (spit uberscript s :append true))
(spit uberscript-out expression :append true))) (spit uberscript preloads :append true)
(spit uberscript expression :append true))
(throw (Exception. (str "Uberscript target file '" uberscript
"' exists and is not empty. Overwrite prohibited.")))))
(when uberjar (when uberjar
(if-let [cp (cp/get-classpath)] (let [cp (cp/get-classpath)]
(let [uber-params {:dest uberjar (cond
:jar :uber (not (file-write-allowed? uberjar))
:classpath cp (throw (Exception. (str "Uberjar target file '" uberjar
:main-class main "' exists and is not empty. Overwrite prohibited.")))
:verbose debug}] (not cp)
(if-let [bb-edn-pods (:pods @common/bb-edn)] (throw (Exception. "The uberjar task needs a classpath."))
(fs/with-temp-dir [bb-edn-dir {}] :else
(let [bb-edn-resource (fs/file bb-edn-dir "META-INF" "bb.edn")] (let [uber-params {:dest uberjar
(fs/create-dirs (fs/parent bb-edn-resource)) :jar :uber
(->> {:pods bb-edn-pods} pr-str (spit bb-edn-resource)) :classpath cp
(let [cp-with-bb-edn (str bb-edn-dir cp/path-sep cp)] :main-class main
(uberjar/run (assoc uber-params :verbose debug}]
:classpath cp-with-bb-edn))))) (if-let [bb-edn-pods (:pods @common/bb-edn)]
(uberjar/run uber-params))) (fs/with-temp-dir [bb-edn-dir {}]
(throw (Exception. "The uberjar task needs a classpath.")))) (let [bb-edn-resource (fs/file bb-edn-dir "META-INF" "bb.edn")]
(fs/create-dirs (fs/parent bb-edn-resource))
(->> {:pods bb-edn-pods} pr-str (spit bb-edn-resource))
(let [cp-with-bb-edn (str bb-edn-dir cp/path-sep cp)]
(uberjar/run (assoc uber-params
:classpath cp-with-bb-edn)))))
(uberjar/run uber-params))))))
exit-code)))) exit-code))))
(defn satisfies-min-version? [min-version] (defn satisfies-min-version? [min-version]
@ -1058,8 +1123,8 @@ Use bb run --help to show this help output.
(and (= minor-current minor-min) (and (= minor-current minor-min)
(>= patch-current patch-min))))))) (>= patch-current patch-min)))))))
(defn load-bb-edn [string] (defn read-bb-edn [string]
(try (edn/read-string {:default tagged-literal} string) (try (edn/read-string {:default tagged-literal :eof nil} string)
(catch java.lang.RuntimeException e (catch java.lang.RuntimeException e
(if (re-find #"No dispatch macro for: \"" (.getMessage e)) (if (re-find #"No dispatch macro for: \"" (.getMessage e))
(throw (ex-info "Invalid regex literal found in EDN config, use re-pattern instead" {})) (throw (ex-info "Invalid regex literal found in EDN config, use re-pattern instead" {}))
@ -1067,40 +1132,85 @@ Use bb run --help to show this help output.
(println "Error during loading bb.edn:")) (println "Error during loading bb.edn:"))
(throw e)))))) (throw e))))))
(defn binary-invoked-as-jar []
(and (= "executable" (System/getProperty "org.graalvm.nativeimage.kind"))
(let [bin (-> (java.lang.ProcessHandle/current)
.info
.command
.get)
fn (fs/file-name bin)]
(if (= "bb" fn)
false
(if (and (fs/windows?)
(= "bb.exe" fn))
false
(when (try (with-open [_ (java.util.zip.ZipFile. (fs/file bin))])
true
(catch Exception _ false))
bin))))))
(defn resolve-symbolic-link [f]
(if (and f (fs/exists? f))
(str (fs/real-path f))
f))
(defn main [& args] (defn main [& args]
(let [[args global-opts] (parse-global-opts args) (let [bin-jar (binary-invoked-as-jar)
{:keys [:jar] :as file-opt} (when (some-> args first io/file .isFile) args (if bin-jar
(parse-file-opt args global-opts)) (list* "--jar" bin-jar "--" args)
config (:config global-opts) args)
merge-deps (:merge-deps global-opts) [args opts] (parse-global-opts args)
abs-path #(-> % io/file .getAbsolutePath) [args {:keys [config merge-deps debug] :as opts}]
bb-edn-file (cond (if-not (or (:file opts)
config (when (fs/exists? config) (abs-path config)) (:jar opts))
jar (some-> jar cp/loader (cp/resource "META-INF/bb.edn") .toString) (parse-file-opt args opts)
:else (when (fs/exists? "bb.edn") (abs-path "bb.edn"))) [args opts])
bb-edn (when (or bb-edn-file merge-deps) {:keys [jar file]} opts
(when bb-edn-file (System/setProperty "babashka.config" bb-edn-file)) abs-path resolve-symbolic-link
(let [raw-string (when bb-edn-file (slurp bb-edn-file)) config (cond
edn (when bb-edn-file (load-bb-edn raw-string)) config (if (fs/exists? config) (abs-path config)
(when debug
(binding [*out* *err*]
(println "[babashka] WARNING: config file does not exist:" config))
nil))
jar (let [jar (resolve-symbolic-link jar)]
(some-> [jar] cp/new-loader (cp/resource "META-INF/bb.edn") .toString))
:else (if (and file (fs/exists? file))
;; file relative to bb.edn
(let [file (abs-path file) ;; follow symlink
rel-bb-edn (fs/file (fs/parent file) "bb.edn")]
(if (fs/exists? rel-bb-edn)
(abs-path rel-bb-edn)
;; fall back to local bb.edn
(when (fs/exists? "bb.edn")
(abs-path "bb.edn"))))
;; default to local bb.edn
(when (fs/exists? "bb.edn")
(abs-path "bb.edn"))))
bb-edn (when (or config merge-deps)
(when config (System/setProperty "babashka.config" config))
(let [raw-string (when config (slurp config))
edn (when config (read-bb-edn raw-string))
edn (if merge-deps edn (if merge-deps
(deps/merge-deps [edn (load-bb-edn merge-deps)]) (deps/merge-deps [edn (read-bb-edn merge-deps)])
edn) edn)
edn (assoc edn edn (assoc edn
:raw raw-string :raw raw-string
:file bb-edn-file) :file config)
edn (if-let [deps-root (or (:deps-root global-opts) edn (if-let [deps-root (or (:deps-root opts)
(some-> config fs/parent))] (some-> config fs/parent))]
(assoc edn :deps-root deps-root) (assoc edn :deps-root deps-root)
edn)] edn)]
(vreset! common/bb-edn edn))) (vreset! common/bb-edn edn)))
;; _ (.println System/err (str bb-edn)) opts (parse-opts args opts)
min-bb-version (:min-bb-version bb-edn)] min-bb-version (:min-bb-version bb-edn)]
(System/setProperty "java.class.path" "")
(when min-bb-version (when min-bb-version
(when-not (satisfies-min-version? min-bb-version) (when-not (satisfies-min-version? min-bb-version)
(binding [*out* *err*] (binding [*out* *err*]
(println (str "WARNING: this project requires babashka " (println (str "WARNING: this project requires babashka "
min-bb-version " or newer, but you have: " version))))) min-bb-version " or newer, but you have: " version)))))
(exec (parse-opts args (merge global-opts file-opt))))) (exec opts)))
(def musl? (def musl?
"Captured at compile time, to know if we are running inside a "Captured at compile time, to know if we are running inside a
@ -1139,6 +1249,7 @@ Use bb run --help to show this help output.
(let [exit-code (run args)] (let [exit-code (run args)]
(System/exit exit-code)))) (System/exit exit-code))))
(sci/alter-var-root main-var (constantly -main))
;;;; Scratch ;;;; Scratch
(comment) (comment)

View file

@ -0,0 +1,2 @@
{:deps {medley/medley {:mvn/version "1.3.0"}
my-local/dep {:local/root "../local-dep"}}}

View file

@ -0,0 +1,10 @@
#!/usr/bin/env bb
(require '[local-dep])
(assert (= :foo local-dep/local-dep-var))
(ns medley
(:require [medley.core :as medley]))
(prn (medley/index-by :id [{:id 1}]))

View file

@ -2,7 +2,9 @@
{:org.babashka/cli {:coerce {:foo []}}}) {:org.babashka/cli {:coerce {:foo []}}})
(defn exec-test (defn exec-test
{:org.babashka/cli {:coerce {:bar :keyword}}} {:org.babashka/cli
{:exec-args {:foo :foo}
:coerce {:bar :keyword}}}
[m] [m]
(if (:meta m) (if (:meta m)
(prn (meta m)) (prn (meta m))

View file

@ -0,0 +1 @@
{r/reverse reader/reversev}

View file

@ -0,0 +1 @@
{r/distinct reader/distinctv}

View file

@ -0,0 +1,7 @@
(ns reader)
(defn reversev [data]
(vec (reverse data)))
(defn distinctv [data]
(vec (distinct data)))

View file

@ -1,6 +1,6 @@
(ns my.main-main (ns my.main-main
(:require [my.impl :as impl]) (:require [my.impl :as impl])
(:require [my.impl2 :as impl2])) (:require [my.impl2]))
(defn -main [& args] (defn -main [& args]
(impl/impl-fn args)) (prn (impl/impl-fn args)))

View file

@ -0,0 +1,2 @@
{:deps {medley/medley {:mvn/version "1.3.0"}}}

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bb
(ns script
(:require [medley.core :as medley]))
(prn (medley/index-by :id [{:id 1}]))

View file

@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIF0zCCBLugAwIBAgIQByqysLNGGzf4RXfWDxaxzTANBgkqhkiG9w0BAQsFADA8
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g
UlNBIDIwNDggTTAyMB4XDTIzMDIyMTAwMDAwMFoXDTIzMTAxNDIzNTk1OVowFjEU
MBIGA1UEAxMLY2xvanVyZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC6JGRt221bAElnBPzSVOebsjPofEDQdLTfAr52LCQLCo/4x7cHsPTi9x4+
W3Pl7Fq0yrgimBhJHT34z7UeFqHEMnjsGxt7dLY0XJ87iikd8pz+v9xqXW8rrGaT
ykGx/85JFOGHJy+ZCparNYgUYN68IkaLe1QLb5w0GBcQa1U9JwpLqQVajrPDgD9Z
YRBJqgaFzJuRVsXo28rxHHFdNlP6PF2scMSFrAZEaex0bLXDxw/bHChzjypPODuO
ElsqxqI48Gsotqxe+iyP+Tu3B4GCHv2NKEFBYKiE+9UmNqQfXdVFvZFT+V2r4R9B
SMv3hpDNjmDcgpCVxmCI1sUttfQvAgMBAAGjggL1MIIC8TAfBgNVHSMEGDAWgBTA
MVLNWlDDgnx0cc7L6Zz5euuC4jAdBgNVHQ4EFgQUqkWGgRcK24T3gV3nNWwZ1EwQ
MPUwJwYDVR0RBCAwHoILY2xvanVyZS5vcmeCD3d3dy5jbG9qdXJlLm9yZzAOBgNV
HQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDsGA1Ud
HwQ0MDIwMKAuoCyGKmh0dHA6Ly9jcmwucjJtMDIuYW1hem9udHJ1c3QuY29tL3Iy
bTAyLmNybDATBgNVHSAEDDAKMAgGBmeBDAECATB1BggrBgEFBQcBAQRpMGcwLQYI
KwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnIybTAyLmFtYXpvbnRydXN0LmNvbTA2Bggr
BgEFBQcwAoYqaHR0cDovL2NydC5yMm0wMi5hbWF6b250cnVzdC5jb20vcjJtMDIu
Y2VyMAwGA1UdEwEB/wQCMAAwggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB1AOg+
0No+9QY1MudXKLyJa8kD08vREWvs62nhd31tBr1uAAABhnTETgYAAAQDAEYwRAIg
IqyTlcuIQp6edqePX8mbZL42EgXfdTuFcBsoFdK9R5UCIEfKD8zISR0q08R2Zk6J
xnHAwBNsMXbebXu0ez3CjeDDAHcAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PAD
Dnk2pZoAAAGGdMROQQAABAMASDBGAiEAhVldSvw96LP/Qb48ZnHC0LqtsV77t/zd
7BCUNJY5bsACIQCENQ19xq5Yu7fWEB+qQQhjHlHD5yrocxqbdmMvdx9uggB2ALc+
+yTfnE26dfI5xbpY9Gxd/ELPep81xJ4dCYEl7bSZAAABhnTETg4AAAQDAEcwRQIh
APsLYOmzOz3qoDCqBULup/twLLmLLu5pK7R/zP1lyPP4AiBZ7PQzi4K2pD8Rfcv1
6Xm1oQwud8jmp1uQbnTCKHUPLjANBgkqhkiG9w0BAQsFAAOCAQEAdACtcuC2kFe0
sQU1m6nnjXdXpds25Xa+Rfbls2vyTqrmatFhSleOhzbkTOnWv/tNunHikttp3+DR
YOAbhJoUe4RVfuu1cQzL3kdc1q4MEmGgEl6V+jDO8657Ck1ld1ViGnqxKtncbV8b
k7hUOurO2saQhlzgylKyFL02Re+kXgw4x/U1n20MvvzHU6QCpU6KcAUeQfub3orQ
gEjmMxjOsnI38ZY8NX7guwhRiyFex3NOZ3avZxG6p8S5amXj8H6M8RBeQ07FVO3H
wj/WczPsGo6D8RG0nU4MiGCerMiY1oF9navINFTZptWiy/gVhR85XwQrKu+Pt+AM
47JAFeruig==
-----END CERTIFICATE-----

View file

@ -0,0 +1,41 @@
(import java.net.UnixDomainSocketAddress
java.net.StandardProtocolFamily
[java.nio.channels ServerSocketChannel SocketChannel])
(require '[clojure.java.io :as io]
'[babashka.fs])
(def sockaddr (UnixDomainSocketAddress/of
(-> (doto (fs/file (fs/temp-dir) "server.socket")
(.deleteOnExit))
str)))
;; server
(def server
(future
(let [ch (ServerSocketChannel/open StandardProtocolFamily/UNIX)]
(.bind ch sockaddr)
(.accept ch))))
(Thread/sleep 100)
;; client
(let [ch (SocketChannel/open StandardProtocolFamily/UNIX)
ch (loop [retry 0]
(let [v (try (.connect ch sockaddr)
(catch Exception e e))]
(if (instance? Exception v)
(if (< retry 10)
(do (Thread/sleep 100)
(recur (inc retry)))
(throw v))
v)))]
#_(prn :ch ch)
#_(.close ch))
@server
(when-not (System/getProperty "babashka.version")
(shutdown-agents))
:success

View file

@ -3,6 +3,7 @@
[babashka.classpath :as cp :refer [add-classpath]] [babashka.classpath :as cp :refer [add-classpath]]
[babashka.core :refer [windows?]] [babashka.core :refer [windows?]]
[babashka.fs :as fs] [babashka.fs :as fs]
[babashka.process :refer [sh]]
[clojure.edn :as edn] [clojure.edn :as edn]
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.spec.test.alpha :as st] [clojure.spec.test.alpha :as st]
@ -53,18 +54,30 @@
(swap! status (fn [status] (swap! status (fn [status]
(merge-with + status (dissoc m :type)))))))))))) (merge-with + status (dissoc m :type))))))))))))
(defn current-branch []
(or (System/getenv "APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH")
(System/getenv "APPVEYOR_REPO_BRANCH")
(System/getenv "CIRCLE_BRANCH")
(System/getenv "GITHUB_REF_NAME")
(System/getenv "CIRRUS_BRANCH")
(-> (sh "git" "rev-parse" "--abbrev-ref" "HEAD")
:out
str/trim)))
;; Standard test-runner for libtests ;; Standard test-runner for libtests
(let [lib-tests (edn/read-string (slurp (io/resource "bb-tested-libs.edn"))) (let [lib-tests (edn/read-string (slurp (io/resource "bb-tested-libs.edn")))
test-nss (atom [])] test-nss (atom [])]
(doseq [[libname {tns :test-namespaces skip-windows :skip-windows (doseq [[libname {tns :test-namespaces skip-windows :skip-windows
:keys [test-paths :keys [test-paths
git-sha]}] lib-tests] git-sha flaky]}] lib-tests]
(let [git-dir (format ".gitlibs/libs/%s/%s" libname git-sha) (let [git-dir (format ".gitlibs/libs/%s/%s" libname git-sha)
git-dir (fs/file (fs/home) git-dir)] git-dir (fs/file (fs/home) git-dir)]
(doseq [p test-paths] (doseq [p test-paths]
(add-classpath (str (fs/file git-dir p))))) (add-classpath (str (fs/file git-dir p)))))
(when-not (and skip-windows (windows?)) (when-not (and skip-windows (windows?))
(swap! test-nss into tns))) (if (and flaky (#{"main" "master"} (current-branch)))
(println "Skipping" tns "for main branch because it's marked flaky")
(swap! test-nss into tns))))
(apply test-namespaces @test-nss)) (apply test-namespaces @test-nss))
;; Non-standard tests - These are tests with unusual setup around test-namespaces ;; Non-standard tests - These are tests with unusual setup around test-namespaces
@ -80,13 +93,15 @@
(test-doric-cyclic-dep-problem)) (test-doric-cyclic-dep-problem))
;;;; babashka.process ;;;; babashka.process
(when-not (windows?) ;; test built-in babashka.process
;; test built-in babashka.process (test-namespaces 'babashka.process-test)
(test-namespaces 'babashka.process-test)
(when (= "native" (System/getenv "BABASHKA_TEST_ENV"))
;; test babashka.process from source ;; test babashka.process from source
#_{:clj-kondo/ignore [:duplicate-require]}
(require '[babashka.process] :reload) (require '[babashka.process] :reload)
(test-namespaces 'babashka.process-test)) (System/setProperty "babashka.process.test.reload" "true")
(test-namespaces 'babashka.process-test 'babashka.process-exec-test))
;;;; final exit code ;;;; final exit code

View file

@ -46,8 +46,8 @@
com.github.seancorfield/honeysql {:git-sha "6e4e1f6928450788353c181f32474d930d6afe84", :git-url "https://github.com/seancorfield/honeysql", :test-namespaces (honey.sql-test honey.sql.helpers-test honey.sql.postgres-test), :branch "develop"} com.github.seancorfield/honeysql {:git-sha "6e4e1f6928450788353c181f32474d930d6afe84", :git-url "https://github.com/seancorfield/honeysql", :test-namespaces (honey.sql-test honey.sql.helpers-test honey.sql.postgres-test), :branch "develop"}
honeysql/honeysql {:git-sha "1137dd12350afdc30ad4976c3718279581390b36", :git-url "https://github.com/seancorfield/honeysql", :test-namespaces (honeysql.format-test honeysql.core-test), :branch "v1"} honeysql/honeysql {:git-sha "1137dd12350afdc30ad4976c3718279581390b36", :git-url "https://github.com/seancorfield/honeysql", :test-namespaces (honeysql.format-test honeysql.core-test), :branch "v1"}
; skip tests on Windows because of the :compressed thing ; skip tests on Windows because of the :compressed thing
babashka/babashka.curl {:git-url "https://github.com/babashka/babashka.curl", :test-namespaces [babashka.curl-test], :skip-windows true, :manually-added true} babashka/babashka.curl {:git-url "https://github.com/babashka/babashka.curl", :test-namespaces [babashka.curl-test], :skip-windows true, :manually-added true :flaky true}
http-kit/http-kit {:git-url "https://github.com/http-kit/http-kit", :test-namespaces [httpkit.client-test], :manually-added true} http-kit/http-kit {:git-url "https://github.com/http-kit/http-kit", :test-namespaces [httpkit.client-test], :manually-added true :flaky true}
org.clojure/core.match {:git-url "https://github.com/clojure/core.match", :test-namespaces [core-match.core-tests], :manually-added true} org.clojure/core.match {:git-url "https://github.com/clojure/core.match", :test-namespaces [core-match.core-tests], :manually-added true}
hiccup/hiccup {:git-url "http://github.com/weavejester/hiccup", :test-namespaces [hiccup.core-test hiccup2.core-test], :manually-added true} hiccup/hiccup {:git-url "http://github.com/weavejester/hiccup", :test-namespaces [hiccup.core-test hiccup2.core-test], :manually-added true}
org.clojure/test.check {:git-url "https://github.com/clojure/test.check", :test-namespaces [test-check.smoke-test], :manually-added true} org.clojure/test.check {:git-url "https://github.com/clojure/test.check", :test-namespaces [test-check.smoke-test], :manually-added true}
@ -57,15 +57,15 @@
crispin/crispin {:git-url "https://github.com/dunaj-project/crispin", :test-namespaces [crispin.core-test], :manually-added true} crispin/crispin {:git-url "https://github.com/dunaj-project/crispin", :test-namespaces [crispin.core-test], :manually-added true}
clj-commons/multigrep {:git-url "https://github.com/clj-commons/multigrep", :test-namespaces [multigrep.core-test], :manually-added true} clj-commons/multigrep {:git-url "https://github.com/clj-commons/multigrep", :test-namespaces [multigrep.core-test], :manually-added true}
org.clj-commons/digest {:git-url "https://github.com/clj-commons/clj-digest", :test-namespaces [clj-commons.digest-test], :manually-added true} org.clj-commons/digest {:git-url "https://github.com/clj-commons/clj-digest", :test-namespaces [clj-commons.digest-test], :manually-added true}
hato/hato {:git-url "https://github.com/gnarroway/hato", :test-namespaces [hato.client-test], :manually-added true} hato/hato {:git-url "https://github.com/gnarroway/hato", :test-namespaces [hato.client-test], :manually-added true :flaky true}
java-http-clj/java-http-clj {:git-url "http://www.github.com/schmee/java-http-clj", :test-namespaces [java-http-clj.smoke-test], :manually-added true} java-http-clj/java-http-clj {:git-url "http://www.github.com/schmee/java-http-clj", :test-namespaces [java-http-clj.smoke-test], :manually-added true :flaky true}
rewrite-clj/rewrite-clj {:git-url "https://github.com/clj-commons/rewrite-clj", :test-namespaces [rewrite-clj.parser-test rewrite-clj.node-test rewrite-clj.zip-test rewrite-clj.paredit-test rewrite-clj.zip.subedit-test rewrite-clj.node.coercer-test], :manually-added true} rewrite-clj/rewrite-clj {:git-url "https://github.com/clj-commons/rewrite-clj", :test-namespaces [rewrite-clj.parser-test rewrite-clj.node-test rewrite-clj.zip-test rewrite-clj.paredit-test rewrite-clj.zip.subedit-test rewrite-clj.node.coercer-test], :manually-added true}
;; TODO: env tests don't work because envoy lib isn't compatible with bb ;; TODO: env tests don't work because envoy lib isn't compatible with bb
;; TODO: failing tests in the following namespaces: vault.client.mock-test, vault.secrets.kvv1-test vault.secrets.kvv2-test ;; TODO: failing tests in the following namespaces: vault.client.mock-test, vault.secrets.kvv1-test vault.secrets.kvv2-test
amperity/vault-clj {:git-url "https://github.com/amperity/vault-clj", :test-namespaces [vault.lease-test vault.client.http-test], :manually-added true} amperity/vault-clj {:git-url "https://github.com/amperity/vault-clj", :test-namespaces [vault.lease-test vault.client.http-test], :manually-added true}
orchestra/orchestra {:git-url "https://github.com/jeaye/orchestra", :test-namespaces (orchestra.make-fns orchestra.many-fns orchestra.expound-test orchestra.core-test orchestra.reload-test), :test-directories ("test/cljc" "test/clj"), :git-sha "81e5181f7b42e5e2763a2b37db17954f3be0314e"} orchestra/orchestra {:git-url "https://github.com/jeaye/orchestra", :test-namespaces (orchestra.make-fns orchestra.many-fns orchestra.expound-test orchestra.core-test orchestra.reload-test), :test-directories ("test/cljc" "test/clj"), :git-sha "81e5181f7b42e5e2763a2b37db17954f3be0314e"}
;; BB-TEST-PATCH: Deleted tasks.clj ;; BB-TEST-PATCH: Deleted tasks.clj
org.clj-commons/clj-http-lite {:git-url "https://github.com/clj-commons/clj-http-lite", :test-namespaces (clj-http.lite.test-runner clj-http.lite.client-test), :test-directories ("bb"), :git-sha "6b53000df55ac05c4ff8e5047a5323fc08a52e8b"} org.clj-commons/clj-http-lite {:git-url "https://github.com/clj-commons/clj-http-lite", :test-namespaces (clj-http.lite.test-runner clj-http.lite.client-test), :test-directories ("bb"), :git-sha "6b53000df55ac05c4ff8e5047a5323fc08a52e8b" :flaky true}
cprop/cprop {:git-url "https://github.com/tolitius/cprop", :test-namespaces [cprop.smoke-test], :manually-added true} cprop/cprop {:git-url "https://github.com/tolitius/cprop", :test-namespaces [cprop.smoke-test], :manually-added true}
org.clojure/data.zip {:git-url "https://github.com/clojure/data.zip", :test-namespaces [clojure.data.zip-test], :manually-added true} org.clojure/data.zip {:git-url "https://github.com/clojure/data.zip", :test-namespaces [clojure.data.zip-test], :manually-added true}
borkdude/deps {:git-url "https://github.com/borkdude/deps.clj", :test-namespaces [borkdude.deps.smoke-test], :manually-added true} borkdude/deps {:git-url "https://github.com/borkdude/deps.clj", :test-namespaces [borkdude.deps.smoke-test], :manually-added true}
@ -94,7 +94,8 @@
progrock/progrock {:git-url "https://github.com/weavejester/progrock", :test-namespaces (progrock.core-test), :git-sha "9c277a3244c52bfde19c21add327d6e20b94fdf5"} progrock/progrock {:git-url "https://github.com/weavejester/progrock", :test-namespaces (progrock.core-test), :git-sha "9c277a3244c52bfde19c21add327d6e20b94fdf5"}
;; Don't run portal.jvm-test as it depends on headless chrome ;; Don't run portal.jvm-test as it depends on headless chrome
djblue/portal {:git-url "https://github.com/djblue/portal", :test-namespaces (portal.test-runner portal.runtime.cson-test portal.runtime.fs-test portal.e2e portal.bench), :git-sha "64e4624bcf3bee2dd47e3d8e47982c709738eb11"} djblue/portal {:git-url "https://github.com/djblue/portal", :test-namespaces (portal.test-runner portal.runtime.cson-test portal.runtime.fs-test portal.e2e portal.bench), :git-sha "64e4624bcf3bee2dd47e3d8e47982c709738eb11"}
integrant/integrant {:git-url "https://github.com/weavejester/integrant", :test-namespaces (integrant.test.foo integrant.test.quz integrant.test.bar integrant.test.baz integrant.core-test), :git-sha "32a46f5dca8a6b563a6dddf88bec887be3201b08"} integrant/integrant {:git-url "https://github.com/weavejester/integrant", :test-namespaces (integrant.test.foo integrant.test.quz integrant.test.bar integrant.test.baz integrant.core-test), :git-sha "a9fd7c02bd7201f36344b47142badc3c3ef22f88"
:test-paths ["test"]}
com.wsscode/cljc-misc {:git-url "https://github.com/wilkerlucio/cljc-misc", :test-namespaces (com.wsscode.misc.uuid-test com.wsscode.misc.macros-test com.wsscode.misc.math-test com.wsscode.misc.coll-test com.wsscode.misc.refs-test), :git-sha "dc8e31a200f9cacf86af10b63e40fcb448c259f4"} com.wsscode/cljc-misc {:git-url "https://github.com/wilkerlucio/cljc-misc", :test-namespaces (com.wsscode.misc.uuid-test com.wsscode.misc.macros-test com.wsscode.misc.math-test com.wsscode.misc.coll-test com.wsscode.misc.refs-test), :git-sha "dc8e31a200f9cacf86af10b63e40fcb448c259f4"}
edn-query-language/eql {:git-url "https://github.com/edn-query-language/eql", :test-namespaces (edn-query-language.core-test), :git-sha "0d4f9745d98c3d20b81bb4bdce3e8e15db7fd094"} edn-query-language/eql {:git-url "https://github.com/edn-query-language/eql", :test-namespaces (edn-query-language.core-test), :git-sha "0d4f9745d98c3d20b81bb4bdce3e8e15db7fd094"}
meta-merge/meta-merge {:git-url "https://github.com/weavejester/meta-merge", :test-namespaces (meta-merge.core-test), :git-sha "c968c38baccd4219fe0ba592d89af37ea8e426bf"} meta-merge/meta-merge {:git-url "https://github.com/weavejester/meta-merge", :test-namespaces (meta-merge.core-test), :git-sha "c968c38baccd4219fe0ba592d89af37ea8e426bf"}
@ -182,4 +183,12 @@
org.clojure/tools.namespace {:git-sha "daf82a10e70182aea4c0716a48f3922163441b32", org.clojure/tools.namespace {:git-sha "daf82a10e70182aea4c0716a48f3922163441b32",
:git-url "https://github.com/clojure/tools.namespace", :git-url "https://github.com/clojure/tools.namespace",
:test-namespaces [clojure.tools.namespace.test-helpers clojure.tools.namespace.dependency-test clojure.tools.namespace.find-test clojure.tools.namespace.move-test clojure.tools.namespace.parse-test], :test-namespaces [clojure.tools.namespace.test-helpers clojure.tools.namespace.dependency-test clojure.tools.namespace.find-test clojure.tools.namespace.move-test clojure.tools.namespace.parse-test],
:test-paths ["src/test/clojure"]}} :test-paths ["src/test/clojure"]}
net.cgrand/xforms {:git-url "https://github.com/cgrand/xforms",
:git-sha "550dbc150a79c6ecc148d8a7e260e10bc36321c6",
:test-namespaces [net.cgrand.xforms-test],
:test-paths ["test"]}
prismatic/plumbing {:git-url "https://github.com/plumatic/plumbing",
:git-sha "424bc704f2db422de34269c139a5494314b3a43b",
:test-namespaces [plumbing.core-test],
:test-paths ["test"]}}

View file

@ -331,7 +331,7 @@
(deftest ^:integration test-http2 (deftest ^:integration test-http2
(testing "can make an http2 request" (testing "can make an http2 request"
(let [r (get "https://nghttp2.org/httpbin/get" {:as :json})] (let [r (get "https://httpbin.org/get" {:as :json})]
(is (= :http-2 (:version r)))))) (is (= :http-2 (:version r))))))
(deftest custom-middleware (deftest custom-middleware

View file

@ -1,549 +0,0 @@
(ns integrant.core-test
(:require [clojure.spec.alpha :as s]
#?(:clj [clojure.test :refer :all]
:cljs [cljs.test :refer-macros [are deftest is testing]])
[integrant.core :as ig]
[weavejester.dependency :as dep]))
(def log (atom []))
(defmethod ig/prep-key ::p [_ v]
(merge {:a (ig/ref ::a)} v))
(defmethod ig/init-key :default [k v]
(swap! log conj [:init k v])
[v])
(defmethod ig/init-key ::x [k v]
(swap! log conj [:init k v])
:x)
(defmethod ig/init-key ::error-init [_ _]
(throw (ex-info "Testing" {:reason ::test})))
(defmethod ig/init-key ::k [_ v] v)
(defmethod ig/init-key ::n [_ v] (inc v))
(defmethod ig/pre-init-spec ::n [_] nat-int?)
(defmethod ig/init-key ::r [_ v] {:v v})
(defmethod ig/resolve-key ::r [_ {:keys [v]}] v)
(defmethod ig/resume-key ::r [k v _ _] (ig/init-key k v))
(defmethod ig/halt-key! :default [k v]
(swap! log conj [:halt k v]))
(defmethod ig/halt-key! ::error-halt [_ _]
(throw (ex-info "Testing" {:reason ::test})))
(defmethod ig/resume-key :default [k cfg cfg' sys]
(swap! log conj [:resume k cfg cfg' sys])
[cfg])
(defmethod ig/resume-key ::x [k cfg cfg' sys]
(swap! log conj [:resume k cfg cfg' sys])
:rx)
(defmethod ig/suspend-key! :default [k v]
(swap! log conj [:suspend k v]))
(derive ::p ::pp)
(derive ::pp ::ppp)
(derive ::ap ::a)
(derive ::ap ::p)
(deftest ref-test
(is (ig/ref? (ig/ref ::foo)))
(is (ig/ref? (ig/ref [::foo ::bar])))
(is (ig/reflike? (ig/ref ::foo)))
(is (ig/reflike? (ig/ref [::foo ::bar]))))
(deftest refset-test
(is (ig/refset? (ig/refset ::foo)))
(is (ig/refset? (ig/refset [::foo ::bar])))
(is (ig/reflike? (ig/refset ::foo)))
(is (ig/reflike? (ig/refset [::foo ::bar]))))
(deftest composite-keyword-test
(let [k (ig/composite-keyword [::a ::b])]
(is (isa? k ::a))
(is (isa? k ::b))
(is (identical? k (ig/composite-keyword [::a ::b])))
(is (not= k (ig/composite-keyword [::a ::c])))))
(deftest valid-config-key-test
(is (ig/valid-config-key? ::a))
(is (not (ig/valid-config-key? :a))))
(deftest expand-test
(is (= (ig/expand {::a (ig/ref ::b), ::b 1})
{::a 1, ::b 1}))
(is (= (ig/expand {::a (ig/ref ::b), ::b (ig/ref ::c), ::c 2})
{::a 2, ::b 2, ::c 2}))
(is (= (ig/expand {::a (ig/ref ::pp), ::p 1})
{::a 1, ::p 1}))
(is (= (ig/expand {::a (ig/refset ::ppp), ::p 1, ::pp 2})
{::a #{1 2}, ::p 1, ::pp 2}))
(is (= (ig/expand {::a (ig/refset ::ppp)})
{::a #{}})))
#?(:clj
(deftest read-string-test
(is (= (ig/read-string "{:foo/a #ig/ref :foo/b, :foo/b 1}")
{:foo/a (ig/ref :foo/b), :foo/b 1}))
(is (= (ig/read-string "{:foo/a #ig/refset :foo/b, :foo/b 1}")
{:foo/a (ig/refset :foo/b), :foo/b 1}))
(is (= (ig/read-string {:readers {'test/var find-var}}
"{:foo/a #test/var clojure.core/+}")
{:foo/a #'+}))))
;; BB-TEST-PATCH: No *loaded-libs* in bb
#?(:bb :TODO :clj
(defn- remove-lib [lib]
(remove-ns lib)
(dosync (alter @#'clojure.core/*loaded-libs* disj lib))))
(derive :integrant.test-child/foo :integrant.test/foo)
;; BB-TEST-PATCH: No *loaded-libs* in bb
#?(:bb :TODO
:clj
(deftest load-namespaces-test
(testing "all namespaces"
(remove-lib 'integrant.test.foo)
(remove-lib 'integrant.test.bar)
(remove-lib 'integrant.test.baz)
(remove-lib 'integrant.test.quz)
(is (= (set (ig/load-namespaces {:integrant.test/foo 1
:integrant.test.bar/wuz 2
[:integrant.test/baz :integrant.test/x] 3
[:integrant.test/y :integrant.test/quz] 4}))
'#{integrant.test.foo
integrant.test.bar
integrant.test.baz
integrant.test.quz}))
(is (some? (find-ns 'integrant.test.foo)))
(is (some? (find-ns 'integrant.test.bar)))
(is (some? (find-ns 'integrant.test.baz)))
(is (some? (find-ns 'integrant.test.quz)))
(is (= (some-> 'integrant.test.foo/message find-var var-get) "foo"))
(is (= (some-> 'integrant.test.bar/message find-var var-get) "bar"))
(is (= (some-> 'integrant.test.baz/message find-var var-get) "baz"))
(is (= (some-> 'integrant.test.quz/message find-var var-get) "quz")))
(testing "some namespaces"
(remove-lib 'integrant.test.foo)
(remove-lib 'integrant.test.bar)
(remove-lib 'integrant.test.baz)
(remove-lib 'integrant.test.quz)
(is (= (set (ig/load-namespaces
{:integrant.test/foo 1
:integrant.test/bar (ig/ref :integrant.test/foo)
:integrant.test/baz 3}
[:integrant.test/bar]))
'#{integrant.test.foo
integrant.test.bar}))
(is (some? (find-ns 'integrant.test.foo)))
(is (some? (find-ns 'integrant.test.bar)))
(is (nil? (find-ns 'integrant.test.baz))))
(testing "load namespaces of ancestors"
(remove-lib 'integrant.test.foo)
(is (= (set (ig/load-namespaces
{:integrant.test-child/foo 1}))
'#{integrant.test.foo}))
(is (some? (find-ns 'integrant.test.foo))))))
(deftest dependency-graph-test
(let [m {::a (ig/ref ::p), ::b (ig/refset ::ppp) ::p 1, ::pp 2}]
(testing "graph with refsets"
(let [g (ig/dependency-graph m)]
(is (dep/depends? g ::a ::p))
(is (dep/depends? g ::b ::p))
(is (dep/depends? g ::b ::pp))))
(testing "graph without refsets"
(let [g (ig/dependency-graph m {:include-refsets? false})]
(is (dep/depends? g ::a ::p))
(is (not (dep/depends? g ::b ::p)))
(is (not (dep/depends? g ::b ::pp)))))))
(deftest key-comparator-test
(let [graph (ig/dependency-graph {::a (ig/ref ::ppp) ::p 1, ::b 2})]
(is (= (sort (ig/key-comparator graph) [::b ::a ::p])
[::p ::a ::b]))))
(deftest derived-from?-test
(are [a b] (ig/derived-from? a b)
::p ::p
::p ::pp
::p ::ppp
::ap [::a ::p]
::ap [::a ::pp]
[::a ::p] [::a ::pp]
[::a ::b ::p] [::a ::ppp]))
(deftest find-derived-1-test
(testing "missing key"
(is (nil? (ig/find-derived-1 {} ::p))))
(testing "derived key"
(is (= (ig/find-derived-1 {::a "x" ::p "y"} ::pp)
[::p "y"])))
(testing "ambiguous key"
(is (thrown-with-msg?
#?(:clj clojure.lang.ExceptionInfo :cljs cljs.core.ExceptionInfo)
(re-pattern (str "Ambiguous key: " ::pp "\\. "
"Found multiple candidates: " ::p ", " ::pp))
(ig/find-derived-1 {::a "x" ::p "y", ::pp "z"} ::pp))))
(testing "composite key"
(is (= (ig/find-derived-1 {::a "x" [::b ::x] "y"} ::x)
[[::b ::x] "y"]))))
(deftest find-derived-test
(testing "missing key"
(is (nil? (ig/find-derived {} ::p))))
(testing "derived key"
(is (= (ig/find-derived {::a "x" ::p "y" ::pp "z"} ::pp)
[[::p "y"] [::pp "z"]])))
(testing "ambiguous key"
(is (= (ig/find-derived {::a "x" ::p "y" ::pp "z"} ::ppp)
[[::p "y"] [::pp "z"]])))
(testing "composite key"
(is (= (ig/find-derived {::a "x" [::b ::x] "y", [::b ::y] "z"} ::b)
[[[::b ::x] "y"] [[::b ::y] "z"]]))))
(deftest prep-test
(testing "default"
(is (= (ig/prep {::q {:b 2}, ::a 1})
{::q {:b 2}, ::a 1})))
(testing "custom prep-key"
(is (= (ig/prep {::p {:b 2}, ::a 1})
{::p {:a (ig/ref ::a), :b 2}, ::a 1})))
(testing "prep then init"
(is (= (ig/init (ig/prep {::p {:b 2}, ::a 1}))
{::p [{:a [1], :b 2}], ::a [1]}))))
(deftest init-test
(testing "without keys"
(reset! log [])
(let [m (ig/init {::a (ig/ref ::b), ::b 1})]
(is (= m {::a [[1]], ::b [1]}))
(is (= @log [[:init ::b 1]
[:init ::a [1]]]))))
(testing "with keys"
(reset! log [])
(let [m (ig/init {::a (ig/ref ::b), ::b 1, ::c 2} [::a])]
(is (= m {::a [[1]], ::b [1]}))
(is (= @log [[:init ::b 1]
[:init ::a [1]]]))))
(testing "with inherited keys"
(reset! log [])
(let [m (ig/init {::p (ig/ref ::a), ::a 1} [::pp])]
(is (= m {::p [[1]], ::a [1]}))
(is (= @log [[:init ::a 1]
[:init ::p [1]]]))))
(testing "with composite keys"
(reset! log [])
(let [m (ig/init {::a (ig/ref ::b), [::x ::b] 1})]
(is (= m {::a [:x], [::x ::b] :x}))
(is (= @log [[:init [::x ::b] 1]
[:init ::a :x]]))))
(testing "with composite refs"
(reset! log [])
(let [m (ig/init {::a (ig/ref [::b ::c]), [::b ::c ::e] 1, [::b ::d] 2})]
(is (= m {::a [[1]], [::b ::c ::e] [1], [::b ::d] [2]}))
(is (or (= @log [[:init [::b ::c ::e] 1]
[:init ::a [1]]
[:init [::b ::d] 2]])
(= @log [[:init [::b ::d] 2]
[:init [::b ::c ::e] 1]
[:init ::a [1]]])))))
(testing "with failing composite refs"
(reset! log [])
(is (thrown-with-msg?
#?(:clj clojure.lang.ExceptionInfo :cljs cljs.core.ExceptionInfo)
#"^Invalid composite key: \[:integrant.core-test/a :b\]. Every keyword must be namespaced.$"
(ig/init {[::a :b] :anything}))))
(testing "with custom resolve-key"
(let [m (ig/init {::a (ig/ref ::r), ::r 1})]
(is (= m {::a [1], ::r {:v 1}}))))
(testing "with refsets"
(reset! log [])
(let [m (ig/init {::a (ig/refset ::ppp), ::p 1, ::pp 2})]
(is (= m {::a [#{[1] [2]}], ::p [1], ::pp [2]}))
(is (= @log [[:init ::p 1]
[:init ::pp 2]
[:init ::a #{[1] [2]}]]))))
(testing "with refsets and keys"
(reset! log [])
(let [m {::a (ig/refset ::ppp), ::p 1, ::pp 2}]
(is (= (ig/init m [::a]) {::a [#{}]}))
(is (= (ig/init m [::a ::p]) {::a [#{[1]}] ::p [1]}))
(is (= (ig/init m [::a ::pp]) {::a [#{[1] [2]}] ::p [1] ::pp [2]}))))
(testing "large config"
(is (= (ig/init {:a/a1 {} :a/a2 {:_ (ig/ref :a/a1)}
:a/a3 {} :a/a4 {} :a/a5 {}
:a/a6 {} :a/a7 {} :a/a8 {}
:a/a9 {} :a/a10 {}})
{:a/a1 [{}] :a/a2 [{:_ [{}]}]
:a/a3 [{}] :a/a4 [{}] :a/a5 [{}]
:a/a6 [{}] :a/a7 [{}] :a/a8 [{}]
:a/a9 [{}] :a/a10 [{}]})))
(testing "with passing specs"
(let [m (ig/init {::n (ig/ref ::k), ::k 1})]
(is (= m {::n 2, ::k 1}))))
(testing "with failing specs"
(is (thrown-with-msg?
#?(:clj clojure.lang.ExceptionInfo :cljs cljs.core.ExceptionInfo)
(re-pattern (str "Spec failed on key " ::n " when building system"))
(ig/init {::n (ig/ref ::k), ::k 1.1}))))
(testing "with failing composite specs"
(is (thrown-with-msg?
#?(:clj clojure.lang.ExceptionInfo :cljs cljs.core.ExceptionInfo)
(re-pattern (str "Spec failed on key \\[" ::n " " ::nnn "\\] when building system"))
(ig/init {[::n ::nnn] 1.1})))))
(deftest halt-test
(testing "without keys"
(reset! log [])
(let [m (ig/init {::a (ig/ref ::b), ::b 1})]
(ig/halt! m)
(is (= @log [[:init ::b 1]
[:init ::a [1]]
[:halt ::a [[1]]]
[:halt ::b [1]]]))))
(testing "with keys"
(reset! log [])
(let [m (ig/init {::a (ig/ref ::b), ::b (ig/ref ::c), ::c 1})]
(ig/halt! m [::a])
(is (= @log [[:init ::c 1]
[:init ::b [1]]
[:init ::a [[1]]]
[:halt ::a [[[1]]]]]))
(reset! log [])
(ig/halt! m [::c])
(is (= @log [[:halt ::a [[[1]]]]
[:halt ::b [[1]]]
[:halt ::c [1]]]))))
(testing "with partial system"
(reset! log [])
(let [m (ig/init {::a 1, ::b (ig/ref ::a)} [::a])]
(ig/halt! m)
(is (= @log [[:init ::a 1]
[:halt ::a [1]]]))))
(testing "with inherited keys"
(reset! log [])
(let [m (ig/init {::a (ig/ref ::p), ::p 1} [::a])]
(ig/halt! m [::pp])
(is (= @log [[:init ::p 1]
[:init ::a [1]]
[:halt ::a [[1]]]
[:halt ::p [1]]]))))
(testing "with composite keys"
(reset! log [])
(let [m (ig/init {::a (ig/ref ::b), [::x ::b] 1})]
(ig/halt! m)
(is (= @log [[:init [::x ::b] 1]
[:init ::a :x]
[:halt ::a [:x]]
[:halt [::x ::b] :x]])))))
(deftest suspend-resume-test
(testing "same configuration"
(reset! log [])
(let [c {::a (ig/ref ::b), ::b 1}
m (ig/init c)
_ (ig/suspend! m)
m' (ig/resume c m)]
(is (= @log [[:init ::b 1]
[:init ::a [1]]
[:suspend ::a [[1]]]
[:suspend ::b [1]]
[:resume ::b 1 1 [1]]
[:resume ::a [1] [1] [[1]]]]))))
(testing "missing keys"
(reset! log [])
(let [c {::a (ig/ref ::b), ::b 1}
m (ig/init c)
_ (ig/suspend! m)
m' (ig/resume (dissoc c ::a) m)]
(is (= @log [[:init ::b 1]
[:init ::a [1]]
[:suspend ::a [[1]]]
[:suspend ::b [1]]
[:halt ::a [[1]]]
[:resume ::b 1 1 [1]]]))))
(testing "missing refs"
(reset! log [])
(let [c {::a {:b (ig/ref ::b)}, ::b 1}
m (ig/init c)
_ (ig/suspend! m)
m' (ig/resume {::a []} m)]
(is (= @log [[:init ::b 1]
[:init ::a {:b [1]}]
[:suspend ::a [{:b [1]}]]
[:suspend ::b [1]]
[:halt ::b [1]]
[:resume ::a [] {:b [1]} [{:b [1]}]]]))))
(testing "with custom resolve-key"
(let [c {::a (ig/ref ::r), ::r 1}
m (ig/init c)
_ (ig/suspend! m)
m' (ig/resume c m)]
(is (= m m'))))
(testing "composite keys"
(reset! log [])
(let [c {::a (ig/ref ::x), [::b ::x] 1}
m (ig/init c)
_ (ig/suspend! m)
m' (ig/resume c m)]
(is (= @log [[:init [::b ::x] 1]
[:init ::a :x]
[:suspend ::a [:x]]
[:suspend [::b ::x] :x]
[:resume [::b ::x] 1 1 :x]
[:resume ::a :rx :x [:x]]]))))
(testing "resume key with dependencies"
(reset! log [])
(let [c {::a {:b (ig/ref ::b)}, ::b 1}
m (ig/init c [::a])
_ (ig/suspend! m)
m' (ig/resume c m [::a])]
(is (= @log
[[:init ::b 1]
[:init ::a {:b [1]}]
[:suspend ::a [{:b [1]}]]
[:suspend ::b [1]]
[:resume ::b 1 1 [1]]
[:resume ::a {:b [1]} {:b [1]} [{:b [1]}]]])))))
(deftest invalid-configs-test
(testing "ambiguous refs"
(is (thrown-with-msg?
#?(:clj clojure.lang.ExceptionInfo :cljs cljs.core.ExceptionInfo)
(re-pattern (str "Ambiguous key: " ::ppp "\\. "
"Found multiple candidates: "
"(" ::p ", " ::pp "|" ::pp ", " ::p ")"))
(ig/init {::a (ig/ref ::ppp), ::p 1, ::pp 2}))))
(testing "missing refs"
(is (thrown-with-msg?
#?(:clj clojure.lang.ExceptionInfo :cljs cljs.core.ExceptionInfo)
(re-pattern (str "Missing definitions for refs: " ::b))
(ig/init {::a (ig/ref ::b)}))))
(testing "missing refs with explicit keys"
(is (= (ig/init {::a (ig/ref ::ppp), ::p 1, ::pp 2} [::p ::pp])
{::p [1], ::pp [2]})))
(testing "missing refs with explicit keys"
(is (= (ig/init {::a 1, ::b (ig/ref ::c)} [::a])
{::a [1]}))))
(defn build-log [config]
(let [log (atom [])]
[(ig/build config (keys config) (fn [k v] (last (swap! log conj [:build k v]))))
@log]))
(deftest build-test
(is (= [{::a [:build ::a [:build ::b 1]]
::b [:build ::b 1]}
[[:build ::b 1]
[:build ::a [:build ::b 1]]]]
(build-log {::a (ig/ref ::b)
::b 1}))))
(defn test-log [f m]
(let [log (atom [])]
[(f m (keys m) (fn [k v] (last (swap! log conj [:test k v]))))
@log]))
(deftest run-test* ;; BB-TEST-PATCH: renamed due to conflict with clojure.test
(let [config {::a (ig/ref ::b), ::b 1}
[system _] (build-log config)]
(is (= [nil
[[:test ::b [:build ::b 1]]
[:test ::a [:build ::a [:build ::b 1]]]]]
(test-log ig/run! system)))
(is (= [nil
[[:test ::a [:build ::a [:build ::b 1]]]
[:test ::b [:build ::b 1]]]]
(test-log ig/reverse-run! system)))))
(deftest fold-test
(let [config {::a (ig/ref ::ppp), ::b (ig/ref ::pp), ::p 1, ::c 2}
system (ig/init config)]
(is (= (ig/fold system #(conj %1 [%2 %3]) [])
[[::p [1]] [::a [[1]]] [::b [[1]]] [::c [2]]]))))
(deftest wrapped-exception-test
(testing "exception when building"
(let [ex (try (ig/init {::a 1, ::error-init (ig/ref ::a)}) nil
(catch #?(:clj Throwable :cljs :default) t t))]
(is (some? ex))
(is (= (#?(:clj .getMessage :cljs ex-message) ex)
(str "Error on key " ::error-init " when building system")))
(is (= (ex-data ex)
{:reason ::ig/build-threw-exception
:system {::a [1]}
:function ig/init-key
:key ::error-init
:value [1]}))
(let [cause (#?(:clj .getCause :cljs ex-cause) ex)]
(is (some? cause))
(is (= (#?(:clj .getMessage :cljs ex-message) cause) "Testing"))
(is (= (ex-data cause) {:reason ::test})))))
(testing "exception when running"
(let [system (ig/init {::a 1
::error-halt (ig/ref ::a)
::b (ig/ref ::error-halt)
::c (ig/ref ::b)})
ex (try (ig/halt! system)
(catch #?(:clj Throwable :cljs :default) t t))]
(is (some? ex))
(is (= (#?(:clj .getMessage :cljs ex-message) ex)
(str "Error on key " ::error-halt " when running system")))
(is (= (ex-data ex)
{:reason ::ig/run-threw-exception
:system {::a [1], ::error-halt [[1]], ::b [[[1]]], ::c [[[[1]]]]}
:completed-keys '(::c ::b)
:remaining-keys '(::a)
:function ig/halt-key!
:key ::error-halt
:value [[1]]}))
(let [cause (#?(:clj .getCause :cljs ex-cause) ex)]
(is (some? cause))
(is (= (#?(:clj .getMessage :cljs ex-message) cause) "Testing"))
(is (= (ex-data cause) {:reason ::test}))))))

View file

@ -1,3 +0,0 @@
(ns integrant.test.bar)
(def message "bar")

View file

@ -1,3 +0,0 @@
(ns integrant.test.baz)
(def message "baz")

View file

@ -1,3 +0,0 @@
(ns integrant.test.foo)
(def message "foo")

View file

@ -1,3 +0,0 @@
(ns integrant.test.quz)
(def message "quz")

View file

@ -1,5 +0,0 @@
(ns integrant.test-runner
(:require [doo.runner :refer-macros [doo-tests]]
[integrant.core-test]))
(doo-tests 'integrant.core-test)

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