Compare commits

..

1 commit

Author SHA1 Message Date
Michiel Borkent
bf815554ab wip 2023-02-15 10:45:03 +01:00
135 changed files with 2231 additions and 5018 deletions

View file

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

View file

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

View file

@ -1,11 +1,9 @@
(ns gen-ci
(:require
[babashka.tasks :as tasks]
[clj-yaml.core :as yaml]
[clojure.string :as str]
[flatland.ordered.map :refer [ordered-map]]))
(def graalvm-version "24")
[babashka.tasks :as tasks]
[clj-yaml.core :as yaml]
[clojure.string :as str]
[flatland.ordered.map :refer [ordered-map]]))
(defn run
([cmd-name cmd]
@ -39,71 +37,70 @@
[shorted?]
(gen-job shorted?
(ordered-map
:resource_class "large"
:docker [{:image "circleci/clojure:lein-2.9.8"}]
:working_directory "~/repo"
:environment {:LEIN_ROOT "true"}
:steps (gen-steps
shorted?
[:checkout
(pull-submodules)
{:restore_cache {:keys ["v1-dependencies-{{ checksum \"project.clj\" }}"
"v1-dependencies-"]}}
{:run ".circleci/script/deploy"}
{:save_cache {:paths ["~/.m2"]
:key "v1-dependencies-{{ checksum \"project.clj\" }}"}}]))))
:resource_class "large"
:docker [{:image "circleci/clojure:lein-2.9.8"}]
:working_directory "~/repo"
:environment {:LEIN_ROOT "true"}
:steps (gen-steps
shorted?
[:checkout
(pull-submodules)
{:restore_cache {:keys ["v1-dependencies-{{ checksum \"project.clj\" }}"
"v1-dependencies-"]}}
{:run ".circleci/script/deploy"}
{:save_cache {:paths ["~/.m2"]
:key "v1-dependencies-{{ checksum \"project.clj\" }}"}}]))))
(defn docker
[shorted?]
(gen-job
shorted?
(ordered-map
:machine {:image "ubuntu-2004:2024.05.1"}
:steps
(gen-steps
shorted?
[:checkout
(pull-submodules)
"setup-docker-buildx"
{:attach_workspace {:at "/tmp"}}
(run "Build uberjar" "script/uberjar")
{:run
{:name "Build Docker image"
:environment {:PLATFORMS "linux/amd64,linux/arm64"}
:command
"java -jar ./target/babashka-$(cat resources/BABASHKA_VERSION)-standalone.jar .circleci/script/docker.clj"}}]))))
shorted?
(ordered-map
:machine {:image "ubuntu-2004:202111-01"}
:steps
(gen-steps
shorted?
[:checkout
(pull-submodules)
"setup-docker-buildx"
{:attach_workspace {:at "/tmp"}}
(run "Build uberjar" "script/uberjar")
{:run
{:name "Build Docker image"
:environment {:PLATFORMS "linux/amd64,linux/arm64"}
:command
"java -jar ./target/babashka-$(cat resources/BABASHKA_VERSION)-standalone.jar .circleci/script/docker.clj"}}]))))
(defn jvm
[shorted? graalvm-home]
(gen-job
shorted?
(ordered-map
:docker [{:image "circleci/clojure:openjdk-11-lein-2.9.8-bullseye"}]
:working_directory "~/repo"
:environment {:LEIN_ROOT "true"
:BABASHKA_PLATFORM "linux"
:GRAALVM_VERSION graalvm-version
:GRAALVM_HOME graalvm-home
:BABASHKA_TEST_ENV "jvm"
:BABASHKA_SHA (System/getenv "CIRCLE_SHA1")}
:resource_class "large"
:steps
(gen-steps
shorted?
[:checkout
(pull-submodules)
{:restore_cache {:keys ["v1-dependencies-{{ checksum \"project.clj\" }}-{{ checksum \"deps.edn\" }}"
"v1-dependencies-"]}}
(run "Install Clojure" "sudo script/install-clojure")
(run "Download GraalVM" "script/install-graalvm")
(run
"Run JVM tests"
"export BABASHKA_FEATURE_JDBC=true
shorted?
(ordered-map
:docker [{:image "circleci/clojure:openjdk-11-lein-2.9.8-bullseye"}]
:working_directory "~/repo"
:environment {:LEIN_ROOT "true"
:BABASHKA_PLATFORM "linux"
:GRAALVM_VERSION "22.3.0"
:GRAALVM_HOME graalvm-home}
:resource_class "large"
:steps
(gen-steps
shorted?
[:checkout
(pull-submodules)
{:restore_cache {:keys ["v1-dependencies-{{ checksum \"project.clj\" }}-{{ checksum \"deps.edn\" }}"
"v1-dependencies-"]}}
(run "Install Clojure" "sudo script/install-clojure")
(run "Download GraalVM" "script/install-graalvm")
(run
"Run JVM tests"
"export BABASHKA_FEATURE_JDBC=true
export BABASHKA_FEATURE_POSTGRESQL=true
script/test\nscript/run_lib_tests")
(run
"Create uberjar"
"mkdir -p /tmp/release
(run "Run as lein command" ".circleci/script/lein")
(run
"Create uberjar"
"mkdir -p /tmp/release
script/uberjar
VERSION=$(cat resources/BABASHKA_VERSION)
jar=target/babashka-$VERSION-standalone.jar
@ -114,22 +111,21 @@ java -jar $jar script/reflection.clj
reflection=\"babashka-$VERSION-reflection.json\"
java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$jar\"
java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$reflection\"")
{:store_artifacts {:path "/tmp/release"
:destination "release"}}
{:save_cache {:paths ["~/.m2"]
:key "v1-dependencies-{{ checksum \"project.clj\" }}-{{ checksum \"deps.edn\" }}"}}]))))
{:store_artifacts {:path "/tmp/release"
:destination "release"}}
{:save_cache {:paths ["~/.m2"]
:key "v1-dependencies-{{ checksum \"project.clj\" }}-{{ checksum \"deps.edn\" }}"}}]))))
(defn unix
[shorted? static? musl? arch executor-conf resource-class graalvm-home platform]
(let [env {:LEIN_ROOT "true"
:GRAALVM_VERSION graalvm-version
:GRAALVM_VERSION "22.3.0"
:GRAALVM_HOME graalvm-home
:BABASHKA_PLATFORM (if (= "mac" platform)
"macos"
platform)
:BABASHKA_TEST_ENV "native"
:BABASHKA_XMX "-J-Xmx6500m"
:BABASHKA_SHA (System/getenv "CIRCLE_SHA1")}
:BABASHKA_XMX "-J-Xmx6500m"}
env (if (= "aarch64" arch)
(assoc env :BABASHKA_ARCH arch)
env)
@ -150,87 +146,88 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
""))]
(gen-job shorted?
(merge
executor-conf
(ordered-map
:working_directory "~/repo"
:environment env
:resource_class resource-class
:steps (gen-steps shorted?
(filter some?
[:checkout
(when (contains? #{"linux" "linux-aarch64"} platform)
(run "Check max glibc version" "script/check_glibc.sh"))
{:attach_workspace {:at "/tmp"}}
(run "Pull Submodules" "git submodule init\ngit submodule update")
{:restore_cache
{:keys [cache-key]}}
(when (= "mac" platform)
(run "Install Rosetta" "sudo /usr/sbin/softwareupdate --install-rosetta --agree-to-license"))
(run "Install Clojure" "sudo script/install-clojure")
(when (= "mac" platform)
(run "Install Leiningen" "script/install-leiningen"))
(when (not= "mac" platform)
(run "Install native dev tools"
(if (and static? musl? (not= "aarch64" arch))
(str base-install-cmd "\nsudo -E script/setup-musl")
base-install-cmd)))
(run "Download GraalVM" "script/install-graalvm")
#_(run "Download iprof" "curl -sLO 'https://github.com/babashka/pgo-profiles/releases/download/2023.10.11/default.iprof'")
(run "Build binary" (if (= "aarch64" arch)
"script/uberjar\nscript/compile -H:PageSize=64K # --pgo=default.iprof"
"script/uberjar\nscript/compile # --pgo=default.iprof") "30m")
(run "Release" ".circleci/script/release")
{:persist_to_workspace {:root "/tmp"
:paths ["release"]}}
(run "Run tests" "script/test\nscript/run_lib_tests")
(run "Release + publish"
(str/join "\n" ["export BABASHKA_RELEASE=true"
".circleci/script/release"]))
{:save_cache
{:paths ["~/.m2" "~/graalvm"]
:key cache-key}}
{:store_artifacts {:path "/tmp/release"
:destination "release"}}
(run "Publish artifact link to Slack"
"./bb .circleci/script/publish_artifact.clj || true")])))))))
executor-conf
(ordered-map
:working_directory "~/repo"
:environment env
:resource_class resource-class
:steps (gen-steps shorted?
(filter some?
[:checkout
(when (contains? #{"linux" "linux-aarch64"} platform)
(run "Check max glibc version" "script/check_glibc.sh"))
{:attach_workspace {:at "/tmp"}}
(run "Pull Submodules" "git submodule init\ngit submodule update")
{:restore_cache
{:keys [cache-key]}}
(run "Install Clojure" "sudo script/install-clojure")
(when (= "mac" platform)
(run "Install Leiningen" "script/install-leiningen"))
(when (not= "mac" platform)
(run "Install native dev tools"
(if (and static? musl? (not= "aarch64" arch))
(str base-install-cmd "\nsudo -E script/setup-musl")
base-install-cmd)))
(run "Download GraalVM" "script/install-graalvm")
(run "Build binary" "script/uberjar\nscript/compile" "30m")
(run "Run tests" "script/test\nscript/run_lib_tests")
(run "Release" ".circleci/script/release")
{:persist_to_workspace {:root "/tmp"
:paths ["release"]}}
{:save_cache
{:paths ["~/.m2" "~/graalvm-ce-java11-22.3.0"]
:key cache-key}}
{:store_artifacts {:path "/tmp/release"
:destination "release"}}
(run "Publish artifact link to Slack"
"./bb .circleci/script/publish_artifact.clj || true")])))))))
(defn make-config
[shorted?]
(let [docker-executor-conf {:docker [{:image "circleci/clojure:openjdk-11-lein-2.9.8-bullseye"}]}
machine-executor-conf {:machine {:image "ubuntu-2004:2024.05.1"}}
mac-executor-conf {:macos {:xcode "13.4.1"}}
linux-graalvm-home (str "/home/circleci/graalvm-" graalvm-version)
mac-graalvm-home (format "/Users/distiller/graalvm-%s/Contents/Home" graalvm-version)]
machine-executor-conf {:machine {:image "ubuntu-2004:202111-01"}}
mac-executor-conf {:macos {:xcode "14.0.0"}}
linux-graalvm-home "/home/circleci/graalvm-ce-java11-22.3.0"
mac-graalvm-home "/Users/distiller/graalvm-ce-java11-22.3.0/Contents/Home"]
(ordered-map
:version 2.1
:commands
{:setup-docker-buildx
{:steps
[{:run
{:name "Create multi-platform capabale buildx builder"
:command
"docker run --privileged --rm tonistiigi/binfmt --install all\ndocker buildx create --name ci-builder --use"}}]}}
:jobs (ordered-map
:jvm (jvm shorted? linux-graalvm-home)
:linux (unix shorted? false false "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-static
(unix shorted? true true "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-aarch64-static
(unix shorted? true false "aarch64" machine-executor-conf "arm.large" linux-graalvm-home "linux")
:mac (unix shorted? false false "amd64" mac-executor-conf "macos.m1.medium.gen1" mac-graalvm-home "mac")
:deploy (deploy shorted?)
:docker (docker shorted?))
:workflows (ordered-map
:version 2
:ci {:jobs ["jvm"
"linux"
"linux-static"
"mac"
"linux-aarch64-static"
{:deploy {:filters {:branches {:only "master"}}
:requires ["jvm" "linux"]}}
{:docker {:filters {:branches {:only "master"}}
:requires ["linux" "linux-static" "linux-aarch64-static"]}}]}))))
:version 2.1
:commands
{:setup-docker-buildx
{:steps
[{:run
{:name "Create multi-platform capabale buildx builder"
:command
"docker run --privileged --rm tonistiigi/binfmt --install all\ndocker buildx create --name ci-builder --use"}}]}}
:jobs (ordered-map
:jvm (jvm shorted? linux-graalvm-home)
:linux (unix shorted? false false "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-static
(unix shorted? true true "amd64" docker-executor-conf "large" linux-graalvm-home "linux")
:linux-aarch64 (unix shorted?
false
false
"aarch64"
machine-executor-conf
"arm.large"
linux-graalvm-home
"linux")
:linux-aarch64-static
(unix shorted? true false "aarch64" machine-executor-conf "arm.large" linux-graalvm-home "linux")
:mac (unix shorted? false false "amd64" mac-executor-conf "large" mac-graalvm-home "mac")
:deploy (deploy shorted?)
:docker (docker shorted?))
:workflows (ordered-map
:version 2
:ci {:jobs ["jvm"
"linux"
"linux-static"
"mac"
"linux-aarch64"
"linux-aarch64-static"
{:deploy {:filters {:branches {:only "master"}}
:requires ["jvm" "linux"]}}
{:docker {:filters {:branches {:only "master"}}
:requires ["linux" "linux-static" "linux-aarch64"]}}]}))))
(def skip-config
{:skip-if-only [#".*.md$"

View file

@ -29,9 +29,7 @@ tar zcvf "$archive" bb # bbk
cd -
if [ "$BABASHKA_RELEASE" = "true" ]; then
./bb --config .build/bb.edn --deps-root . release-artifact "/tmp/release/$archive"
fi
./bb --config .build/bb.edn --deps-root . release-artifact "/tmp/release/$archive"
## cleanup

View file

@ -5,8 +5,8 @@ task:
skip: "changesIncludeOnly('logo/*', '**.md')"
env:
LEIN_ROOT: "true"
GRAALVM_VERSION: "24"
GRAALVM_HOME: ${HOME}/graalvm-${GRAALVM_VERSION}/Contents/Home
GRAALVM_VERSION: "22.3.0"
GRAALVM_HOME: ${HOME}/graalvm-ce-java11-22.3.0/Contents/Home
BABASHKA_PLATFORM: macos # used in release script
BABASHKA_ARCH: aarch64
BABASHKA_TEST_ENV: native
@ -24,11 +24,8 @@ task:
sudo /usr/sbin/softwareupdate --install-rosetta --agree-to-license
java -version
export BABASHKA_SHA=$(git rev-parse HEAD)
script/uberjar
# curl -sLO 'https://github.com/babashka/pgo-profiles/releases/download/2023.10.11/default.iprof'
script/compile # --pgo=default.iprof
script/compile
# script/test
# script/run_lib_tests

View file

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

View file

@ -24,7 +24,6 @@ jobs:
LEIN_ROOT: "true"
BABASHKA_PLATFORM: linux # could be used in jar name
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BABASHKA_SHA: ${{ github.sha }}
steps:
- name: Git checkout
uses: actions/checkout@v2
@ -33,7 +32,7 @@ jobs:
submodules: 'true'
- name: Cache deps
uses: actions/cache@v4
uses: actions/cache@v2
id: cache-deps
with:
path: ~/.m2/repository
@ -44,7 +43,7 @@ jobs:
uses: actions/setup-java@v2
with:
distribution: 'adopt-hotspot'
java-version: '19'
java-version: '11'
- name: Install clojure tools
uses: DeLaGuardo/setup-clojure@5.0
@ -60,6 +59,9 @@ jobs:
script/test
script/run_lib_tests
- name: Run as lein command
run: echo '{:a 1}' | lein bb '(:a *in*)'
- name: Build uberjar
run: |
mkdir -p /tmp/release
@ -78,7 +80,7 @@ jobs:
BABASHKA_VERSION=$(cat resources/BABASHKA_VERSION)
echo "##[set-output name=version;]${BABASHKA_VERSION}"
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v1
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-standalone.jar
path: target/babashka-${{ steps.babashka-version.outputs.version }}-standalone.jar
@ -88,7 +90,7 @@ jobs:
strategy:
matrix:
include:
- os: macos-13
- os: macos-12
name: macos
static: false
#- os: ubuntu-latest
@ -100,12 +102,11 @@ jobs:
runs-on: ${{ matrix.os }}
env:
LEIN_ROOT: "true"
GRAALVM_VERSION: "24"
GRAALVM_VERSION: "22.3.0"
BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script
BABASHKA_TEST_ENV: native
BABASHKA_XMX: "-J-Xmx6500m"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BABASHKA_SHA: ${{ github.sha }}
steps:
- name: Git checkout
uses: actions/checkout@v2
@ -114,7 +115,7 @@ jobs:
submodules: 'true'
- name: Cache deps
uses: actions/cache@v4
uses: actions/cache@v2
id: cache-deps
with:
path: ~/.m2/repository
@ -125,8 +126,8 @@ jobs:
if: "matrix.static == false"
uses: graalvm/setup-graalvm@v1
with:
java-version: '24'
distribution: 'graalvm'
version: '22.3.0'
java-version: '11'
components: 'native-image'
github-token: ${{ secrets.GITHUB_TOKEN }}
@ -134,8 +135,8 @@ jobs:
if: "matrix.static == true"
uses: graalvm/setup-graalvm@v1
with:
version: '24'
distribution: 'graalvm'
version: '22.3.0'
java-version: '11'
components: 'native-image'
native-image-musl: true
github-token: ${{ secrets.GITHUB_TOKEN }}
@ -172,19 +173,6 @@ jobs:
BABASHKA_MUSL: "true"
run: script/compile
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-amd64
- name: Upload static artifact
if: "matrix.static == true"
uses: actions/upload-artifact@v4
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-static-amd64
- name: Test binary and libs
run: |
script/test
@ -193,6 +181,19 @@ jobs:
- name: Release
run: .circleci/script/release
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-amd64
- name: Upload static artifact
if: "matrix.static == true"
uses: actions/upload-artifact@v2
with:
path: bb
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-static-amd64
docker:
if: ${{ false }} # Disabled
# if: "!contains(github.event.head_commit.message, 'skip ci') && github.event_name == 'push' && github.ref == 'refs/heads/master'"
@ -216,13 +217,13 @@ jobs:
run: mkdir -p /tmp/release
- name: Download linux binary
uses: actions/download-artifact@v4.1.7
uses: actions/download-artifact@v2
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-linux-amd64.zip
path: /tmp/release
- name: Download static linux binary
uses: actions/download-artifact@v4.1.7
uses: actions/download-artifact@v2
with:
name: babashka-${{ steps.babashka-version.outputs.version }}-linux-static-amd64.zip
path: /tmp/release-static

3
.gitignore vendored
View file

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

View file

@ -8,351 +8,10 @@ A preview of the next release can be installed from
[Babashka](https://github.com/babashka/babashka): Native, fast starting Clojure interpreter for scripting
## Unreleased
- [#1818](https://github.com/babashka/babashka/issues/1818): wrong argument order in `clojure.java.io/resource` implementation
- Add `java.text.BreakIterator`
- Bump `fs` to `0.5.25`
- Bump `jsoup` to `1.20.1`
- Bump `edamame` to `1.4.30`
- [#1815](https://github.com/babashka/babashka/issues/1815): Make install-script wget-compatible ([@eval](https://github.com/eval))
## 1.12.200 (2025-04-26)
- Improve Java reflection based on provided type hints (read blog post [here](https://blog.michielborkent.nl/babashka-java-reflection-type-hints.html))
- Add compatibility with the [fusebox](https://github.com/potetm/fusebox) library
- Fix virtual `ThreadBuilder` interop
- Add `java.util.concurrent.ThreadLocalRandom`
- Add `java.util.concurrent.locks.ReentrantLock`
- Add classes:
- `java.time.chrono.ChronoLocalDate`
- `java.time.temporal.TemporalUnit`
- `java.time.chrono.ChronoLocalDateTime`
- `java.time.chrono.ChronoZonedDateTime`
- `java.time.chrono.Chronology`
## 1.12.199 (2025-04-18)
- [#1806](https://github.com/babashka/babashka/issues/1806): Add `cheshire.factory` namespace ([@lread](https://github.com/lread))
## 1.12.198 (2025-04-17)
- Bump GraalVM to `24`
- Bump SCI to `0.9.45`
- Bump edamame to `1.4.28`
- [#1801](https://github.com/babashka/babashka/issues/1801): Add `java.util.regex.PatternSyntaxException`
- Bump core.async to `1.8.735`
- Bump cheshire to `6.0.0`
- Bump babashka.cli to `0.8.65`
## 1.12.197 (2025-02-28)
- [#1785](https://github.com/babashka/babashka/issues/1785): Allow subclasses of `Throwable` to have instance methods invoked ([@bobisageek](https://github.com/bobisageek))
- [#1791](https://github.com/babashka/babashka/issues/1791): interop problem on Jsoup form element
- [#1793](https://github.com/babashka/babashka/issues/1793): Bump `rewrite-clj` to `1.1.49` (fixes parsing of `foo//` among other things)
- Bump `deps.clj`
- Bump `fs`
## 1.12.196 (2024-12-24)
- [#1771](https://github.com/babashka/babashka/issues/1771): `*e*` in REPL should contain exception thrown by user, not a wrapped one
- [#1777](https://github.com/babashka/babashka/issues/1777) Add `java.nio.file.attribute.UserDefinedFileAttributeView`
- [#1776](https://github.com/babashka/babashka/issues/1776) `Add java.nio.file.attribute.PosixFileAttributes`
- [#1761](https://github.com/babashka/babashka/issues/1761) Support calling `clojure.lang.RT/iter`
- [#1760](https://github.com/babashka/babashka/issues/1760) For compatibility with [Fireworks v0.10.3](https://github.com/paintparty/fireworks), added the following to `:instance-checks` entry in `babashka.impl.classes/classes`([@paintparty](https://github.com/paintparty))
- `clojure.lang.PersistentArrayMap$TransientArrayMap`
- `clojure.lang.PersistentHashMap$TransientHashMap`
- `clojure.lang.PersistentVector$TransientVector`
- `java.lang.NoSuchFieldException`
- `java.util.AbstractMap`
- `java.util.AbstractSet`
- `java.util.AbstractList`
- [#1760](https://github.com/babashka/babashka/issues/1760) For compatibility with [Fireworks v0.10.3](https://github.com/paintparty/fireworks), added `volatile?` entry to `babashka.impl.clojure.core/core-extras`([@paintparty](https://github.com/paintparty))
- Bump `babashka.cli` to `0.8.61`
- Bump `clj-yaml` to `1.0.29`
- [#1768](https://github.com/babashka/babashka/issues/1768): Add `taoensso.timbre` `color-str` function
- Add classes:
- `javax.crypto.KeyAgreement`
- `java.security.KeyPairGenerator`
- `java.security.KeyPair`
- `java.security.spec.ECGenParameterSpec`
- `java.security.spec.PKCS8EncodedKeySpec`
- `java.security.spec.X509EncodedKeySpec`
- `java.security.Signature`
- Add `java.util.concurrent.CompletionStage`
- Bump `core.async` to `1.7.701`
- Bump `org.babashka/cli` to `0.8.162`
## 1.12.195 (2024-11-12)
- Include [jsoup](https://jsoup.org/) for HTML parsing. This makes bb compatible with the [hickory](https://github.com/clj-commons/hickory) library (and possibly other libraries?).
- [#1752](https://github.com/babashka/babashka/issues/1752): include `java.lang.SecurityException` for `java.net.http.HttpClient` support ([@grzm](https://github.com/grzm))
- [#1748](https://github.com/babashka/babashka/issues/1748): add `clojure.core/ensure`
- Upgrade `taoensso/timbre`to `v6.6.0`
- Upgrade `babashka.http-client` to `v0.4.22`
- Add `:git/sha` from build to `bb describe` output ([@lispyclouds](https://github.com/lispyclouds))
- Fix NPE with determining if executing from self-contained executable
## 1.12.194 (2024-10-12)
- Upgrade to GraalVM 23
- [#1743](https://github.com/babashka/babashka/issues/1743): fix new fully qualified instance method in call position with GraalVM 23
## 1.12.193 (2024-10-11)
- Clojure 1.12 interop: method thunks, FI coercion, array notation (see below)
- Upgrade SCI reflector based on clojure 1.12 and remove specific workaround for
`Thread/sleep` interop
- Add `tools.reader.edn/read`
- Fix [#1741](https://github.com/babashka/babashka/issues/1741): `(taoensso.timbre/spy)` now relies on macros from `taoensso.encore` previously not available in bb
Examples of the new Clojure interop:
``` clojure
;; Qualified methods in call position:
(String/.length "123") ;;=> 3
(String/new "123") ;;=> "123"
;; Qualified methods in value position, as functions:
(map Integer/parseInt ["1" "22" "333"]) ;;=> (1 22 333)
(map String/.length ["1" "22" "333"]) ;;=> (1 2 3)
(map String/new ["1" "22" "333"]) ;;=> ("1" "22" "333")
;; Typed multi-dimensional array class notation:
long/1 ;;=> 1-dimensional long array class
String/2 ;;=> 2-dimensional String array class
;; Pass Clojure IFn to Java where `java.util.function.Predicate`, etc. is expected:
(into [] (doto (java.util.ArrayList. [1 2 3]) (.removeIf even?))) ;;=> [1 3]
(.computeIfAbsent (java.util.HashMap.) "abc" #(str % %)) ;;=> "abcabc"
```
## 1.4.192 (2024-09-12)
- Upgrade Clojure to `1.12.0`
- [#1722](https://github.com/babashka/babashka/issues/1722): add new clojure 1.12 vars
- [#1720](https://github.com/babashka/babashka/issues/1720): include new clojure 1.12's `clojure.java.process`
- [#1719](https://github.com/babashka/babashka/issues/1719): add new clojure 1.12 `clojure.repl.deps` namespace. Only calls with explicit versions are supported.
- [#1598](https://github.com/babashka/babashka/issues/1598): use Rosetta on CircleCI to build x64 images
- [#1716](https://github.com/babashka/babashka/issues/1716): expose `babashka.http-client.interceptors` namespace
- [#1707](https://github.com/babashka/babashka/issues/1707): support `aset` on primitive array
- [#1676](https://github.com/babashka/babashka/issues/1676): restore compatibility with newest [at-at](https://github.com/overtone/at-at/) version (1.3.58)
- Bump SCI
- Bump `fs`
- Bump `process`
- Bump `deps.clj`
- Bump `http-client`
- Bump `clj-yaml`
- Bump `edamame`
- Bump `rewrite-clj`
- Add `java.io.LineNumberReader`
## 1.3.191 (2024-06-19)
- 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`.
- Partially Fix [#1695](https://github.com/babashka/babashka/issues/1695): `--repl` arg handling should consume only one arg (itself) ([@bobisageek](https://github.com/bobisageek))
- Partially Fix [#1695](https://github.com/babashka/babashka/issues/1695): make `*command-line-args*` value available in the REPL ([@bobisageek](https://github.com/bobisageek))
- Fix [#1686](https://github.com/babashka/babashka/issues/1686): do not fetch dependencies/invoke java for `version`, `help`, and `describe` options ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): add `clojure.lang.DynamicClassLoader` constructors ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): add `clojure.core/*source-path*` (points to the same sci var as `*file*`) ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): add `clojure.main/with-read-known` ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): add `clojure.core.server/repl-read` ([@bobisageek](https://github.com/bobisageek))
- [#1696](https://github.com/babashka/babashka/issues/1696): make the `cognitect-labs/transcriptor` library work ([@bobisageek](https://github.com/bobisageek))
- [#1700](https://github.com/babashka/babashka/issues/1700): catch exceptions from resolving symbolic links during `bb.edn` lookup ([@bobisageek](https://github.com/bobisageek))
- Support `java.nio.channels.ByteChannel` + several other related interop
- Bump `nrepl/bencode` to `1.2.0`
- Bump `babashka/fs`
- Bump `org.babashka/http-client` to `0.4.18`
## 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
- Add more java.time and related classes with the goal of supporting juxt.tick https://github.com/juxt/tick/issues/86
- [#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)
@ -1029,7 +688,7 @@ Babashka.pods:
- 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)
## 0.4.0 (2021-05-08)
## 0.4.0
Babashka proper:
@ -1039,7 +698,7 @@ Babashka proper:
[jasentaa](https://github.com/rm-hull/jasentaa) parser combinator library
- Update Selmer to 1.12.40
SCI:
Sci:
- Better error msg for protocol not found or class

View file

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

View file

@ -13,11 +13,8 @@ RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswit
# TODO: Run actual native tests when they are ported
RUN curl --version
# RUN bb -e '(prn (java.io.File/createTempFile "babashka.curl" ".headers"))'
# RUN bb -e '(spit (java.io.File/createTempFile "babashka.curl" ".headers") "hello")'
# RUN bb -e "(curl/get \"https://clojure.org\")" # cURL http test
RUN bb -e "(require '[org.httpkit.client :as http]) (when-let [error (:error @(http/get \"https://clojure.org\"))] (throw error))" # JVM http test
RUN bb -e "(curl/get \"https://httpstat.us/200\")" # 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 "(.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
@ -26,7 +23,7 @@ FROM alpine:3
RUN apk --no-cache add curl ca-certificates tar && \
curl -Ls https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk > /tmp/glibc-2.28-r0.apk && \
apk add --allow-untrusted --force-overwrite /tmp/glibc-2.28-r0.apk && rm /tmp/glibc-2.28-r0.apk
apk add --allow-untrusted --force-overwrite /tmp/glibc-2.28-r0.apk
RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
COPY metabom.jar /opt/babashka-metabom.jar

View file

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

197
README.md
View file

@ -4,7 +4,7 @@
[![project chat](https://img.shields.io/badge/slack-join_chat-brightgreen.svg)](https://app.slack.com/client/T03RZGPFR/CLX41ASCS)
[![Financial Contributors on Open Collective](https://opencollective.com/babashka/all/badge.svg?label=financial+contributors)](https://opencollective.com/babashka) [![Clojars Project](https://img.shields.io/clojars/v/babashka/babashka.svg)](https://clojars.org/babashka/babashka)
[![twitter](https://img.shields.io/badge/twitter-%23babashka-blue)](https://twitter.com/search?q=%23babashka&src=typed_query&f=live)
[![docs](https://img.shields.io/badge/website-docs-blue)](https://book.babashka.org) [![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20Babashka%20Guru-006BFF)](https://gurubase.io/g/babashka)
[![docs](https://img.shields.io/badge/website-docs-blue)](https://book.babashka.org)
<blockquote class="twitter-tweet" data-lang="en">
<p lang="en" dir="ltr">Life's too short to remember how to write Bash code. I feel liberated.</p>
@ -40,10 +40,10 @@ As one user described it:
## Quickstart
For installation options check [Installation](https://github.com/babashka/babashka#installation).
For quick installation using `bash`, use:
For quick installation use:
``` shell
bash < <(curl -s https://raw.githubusercontent.com/babashka/babashka/master/install)
$ bash < <(curl -s https://raw.githubusercontent.com/babashka/babashka/master/install)
```
or grab a binary from [Github
@ -53,36 +53,11 @@ anywhere on the path.
Then you're ready to go:
``` shellsession
time bb -e '(->> (fs/list-dir ".") (filter fs/directory?) (map fs/normalize) (map str) (take 3))'
$ ls | bb -i '(filter fs/directory? *input*)'
("doc" "resources" "sci" "script" "src" "target" "test")
bb took 4ms.
```
``` clojure
(".build" "feature-lanterna" ".repl")
bb -e 0,01s user 0,01s system 70% cpu 0,017 total
```
## 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
See [companies](doc/companies.md) for a list of companies using babashka.
@ -107,7 +82,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
[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)):
@ -118,10 +93,50 @@ To get an overview of babashka, you can watch this talk ([slides](https://speake
The [babashka book](https://book.babashka.org) contains detailed information
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/).
If you're a fan of [Clojure for the Brave and
True](https://www.braveclojure.com/clojure-for-the-brave-and-true/), you might
enjoy [Babashka Babooka](https://www.braveclojure.com/quests/babooka/), a book
by the same author, Daniel Higginbotham!
## Examples
Read the output from a shell command as a lazy seq of strings:
``` shell
$ ls | bb -i '(take 2 *input*)'
("CHANGES.md" "Dockerfile")
```
Read EDN from stdin and write the result to stdout:
``` shell
$ bb '(vec (dedupe *input*))' <<< '[1 1 1 1 2]'
[1 2]
```
Read more about `*input*` and in- and output flags
[here](https://book.babashka.org/#_input_and_output_flags).
Execute a script. E.g. print the current time in California using the
`java.time` API:
File `pst.clj`:
``` clojure
#!/usr/bin/env bb
(def now (java.time.ZonedDateTime/now))
(def LA-timezone (java.time.ZoneId/of "America/Los_Angeles"))
(def LA-time (.withZoneSameInstant now LA-timezone))
(def pattern (java.time.format.DateTimeFormatter/ofPattern "HH:mm"))
(println (.format LA-time pattern))
```
``` shell
$ pst.clj
05:17
```
More examples can be found [here](examples/README.md).
## Try online
@ -175,25 +190,13 @@ linux binary.
### asdf
[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.
[asdf](https://github.com/asdf-vm/asdf) is an extendable version manager for linux and macOS.
Babashka can be installed using a plugin as follows:
asdf plugin add babashka https://github.com/pitch-io/asdf-babashka
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
#### Scoop
@ -232,8 +235,6 @@ Install via the installer script for linux and macOS:
``` shell
$ curl -sLO https://raw.githubusercontent.com/babashka/babashka/master/install
# or
$ wget -qO install https://raw.githubusercontent.com/babashka/babashka/master/install
$ chmod +x install
$ ./install
```
@ -305,20 +306,63 @@ Go [here](https://book.babashka.org/#built-in-namespaces) to see the full list o
A list of projects (scripts, libraries, pods and tools) known to work with babashka.
## Badges
<!-- note to editor: it seems a blank line must appear before code blocks within <details> -->
[![bb compatible](/logo/badge.svg)](https://babashka.org)
The babashka compatible badge indicates that a [library can be used as babashka dependency](doc/projects.md).
[![bb compatible](/logo/badge.svg)](https://book.babashka.org#badges)
The babashka compatible badge indicates that a library can be used as babashka dependency.
If this is the case for your library, we encourage you to proudly display this badge.
[![bb built-in](/logo/built-in-badge.svg)](https://book.babashka.org#badges)
The babashka built-in badge means that a library has been built directly into babashka and requires no extra dependencies to use it.
<details><summary>Markdown</summary>
```markdown
[![bb compatible](https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg)](https://babashka.org)
```
</details>
<details><summary>AsciiDoc</summary>
```asciidoc
https://babashka.org[image:https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg[bb compatible]]
```
</details>
<details><summary>HTML</summary>
```html
<a href="https://babashka.org" rel="nofollow"><img src="https://github.com/babashka/babashka/raw/master/logo/badge.svg" alt="bb compatible" style="max-width: 100%;"></a>
```
</details>
<br/>
[![bb built-in](/logo/built-in-badge.svg)](https://babashka.org)
The babashka built-in badge means that a [library has been built directly into babashka](https://book.babashka.org/#built-in-namespaces) and requires no extra dependencies to use it.
If this rare honor belongs to your library, you should display this badge.
See [the babashka book for details](https://book.babashka.org#badges).
<details><summary>Markdown</summary>
## Swag
```markdown
[![bb built-in](https://raw.githubusercontent.com/babashka/babashka/master/logo/built-in-badge.svg)](https://babashka.org)
```
</details>
- [t-shirt](https://www.etsy.com/listing/1241766068/babashka-clj-kondo-nbb-shirt)
<details><summary>AsciiDoc</summary>
```asciidoc
https://babashka.org[image:https://raw.githubusercontent.com/babashka/babashka/master/logo/built-in-badge.svg[bb built-in]]
```
</details>
<details><summary>HTML</summary>
```html
<a href="https://babashka.org" rel="nofollow"><img src="https://github.com/babashka/babashka/raw/master/logo/built-in-badge.svg" alt="bb built-in" style="max-width: 100%;"></a>
```
</details>
</br>
## [Pods](https://github.com/babashka/babashka.pods)
@ -469,10 +513,47 @@ commit](https://github.com/babashka/babashka/commit/02c7c51ad4b2b1ab9aa95c26a744
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
- [Nikita Prokopov](https://github.com/tonsky) for the logo
- [Contributors](https://github.com/babashka/babashka/graphs/contributors) and
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

View file

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

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

@ -1 +1 @@
Subproject commit 976cf7b0e54901ada3f7e83f12a4c0aed039adc9
Subproject commit 6f6db788b19e9693faffa5f1e9c0b0c4d7436cc7

View file

@ -18,41 +18,40 @@
"deps.clj/src" "deps.clj/resources"
"resources" "sci/resources"
"impl-java/src"],
:deps {org.clojure/clojure {:mvn/version "1.12.0"},
:deps {org.clojure/clojure {:mvn/version "1.11.1"},
org.babashka/sci {:local/root "sci"}
org.babashka/babashka.impl.java {:mvn/version "0.1.10"}
org.babashka/babashka.impl.java {:mvn/version "0.1.8"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"}
babashka/babashka.curl {:local/root "babashka.curl"}
babashka/fs {:local/root "fs"}
babashka/babashka.core {:local/root "babashka.core"}
org.clojure/core.async {:mvn/version "1.8.741"},
borkdude/graal.locking {:mvn/version "0.0.2"},
org.clojure/core.async {:mvn/version "1.6.673"},
org.clojure/tools.cli {:mvn/version "1.0.214"},
org.clojure/data.csv {:mvn/version "1.0.0"},
cheshire/cheshire {:mvn/version "6.0.0"}
cheshire/cheshire {:mvn/version "5.11.0"}
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
clj-commons/clj-yaml {:mvn/version "1.0.29"}
com.cognitect/transit-clj {:mvn/version "1.0.333"}
clj-commons/clj-yaml {:mvn/version "0.7.169"}
com.cognitect/transit-clj {:mvn/version "1.0.329"}
org.clojure/test.check {:mvn/version "1.1.1"}
nrepl/bencode {:mvn/version "1.2.0"}
nrepl/bencode {:mvn/version "1.1.0"}
seancorfield/next.jdbc {:mvn/version "1.1.610"}
org.postgresql/postgresql {:mvn/version "42.2.18"}
org.hsqldb/hsqldb {:mvn/version "2.5.1"}
datascript/datascript {:mvn/version "1.0.1"}
http-kit/http-kit {:mvn/version "2.8.0-RC1"}
http-kit/http-kit {:mvn/version "2.6.0-RC1"}
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
org.clojure/core.match {:mvn/version "1.0.0"}
hiccup/hiccup {:mvn/version "2.0.0-RC1"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.49"}
selmer/selmer {:mvn/version "1.12.59"}
com.taoensso/timbre {:mvn/version "6.6.0"}
hiccup/hiccup {:mvn/version "2.0.0-alpha2"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.46"}
selmer/selmer {:mvn/version "1.12.50"}
com.taoensso/timbre {:mvn/version "6.0.1"}
org.clojure/tools.logging {:mvn/version "1.1.0"}
org.clojure/data.priority-map {:mvn/version "1.1.0"}
insn/insn {:mvn/version "0.5.2"}
org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
org.babashka/cli {:mvn/version "0.8.65"}
org.babashka/http-client {:mvn/version "0.4.22"}
org.flatland/ordered {:mvn/version "1.15.12"}
org.jsoup/jsoup {:mvn/version "1.20.1"}}
org.babashka/cli {:mvn/version "0.6.45"}
org.babashka/http-client {:mvn/version "0.1.4"}}
:aliases {:babashka/dev
{:main-opts ["-m" "babashka.main"]}
:profile
@ -66,7 +65,7 @@
{:extra-paths ["process/src" "process/test" "test-resources/lib_tests"]
:extra-deps {org.clj-commons/clj-http-lite {:mvn/version "0.4.392"}
#_#_org.babashka/spec.alpha {:git/url "https://github.com/babashka/spec.alpha"
:sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"}
:sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"}
lambdaisland/regal {:mvn/version "0.0.143"}
cprop/cprop {:mvn/version "0.1.16"}
comb/comb {:mvn/version "0.1.1"}
@ -108,7 +107,7 @@
exoscale/coax {:mvn/version "1.0.0-alpha14"}
orchestra/orchestra {:mvn/version "2021.01.01-1"}
expound/expound {:mvn/version "0.8.10"}
integrant/integrant {:git/url "https://github.com/weavejester/integrant", :git/sha "a9fd7c02bd7201f36344b47142badc3c3ef22f88"}
integrant/integrant {:mvn/version "0.8.0"}
com.stuartsierra/dependency {:mvn/version "1.0.0"}
listora/again {:mvn/version "1.0.0"}
org.clojure/tools.gitlibs {:mvn/version "2.4.172"}
@ -170,15 +169,7 @@
:deps/manifest :deps}
net.cgrand/xforms {:git/url "https://github.com/cgrand/xforms"
:git/sha "550dbc150a79c6ecc148d8a7e260e10bc36321c6"
:deps/manifest :deps}
prismatic/plumbing {:git/url "https://github.com/plumatic/plumbing",
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}
org.clj-commons/hickory {:git/url "https://github.com/clj-commons/hickory"
:git/sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"}
com.potetm/fusebox {:git/url "https://github.com/potetm/fusebox"
:git/sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"}
net.sekao/odoyle-rules {:git/url "https://github.com/oakes/odoyle-rules"
:git/sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"}}
:deps/manifest :deps}}
:classpath-overrides {org.clojure/clojure nil
org.clojure/spec.alpha nil}}
:clj-nvd

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

View file

@ -3,24 +3,24 @@
## Prerequisites
- Install [lein](https://leiningen.org/) for producing uberjars
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *Oracle GraalVM 24*.
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *java11-22.3.0*.
- For Windows, installing Visual Studio 2019 with the "Desktop development
with C++" workload is recommended.
- Set `$GRAALVM_HOME` to the GraalVM distribution directory. On macOS this can look like:
``` shell
export GRAALVM_HOME=~/Downloads/graalvm-jdk-21.0.0.1/Contents/Home
export GRAALVM_HOME=~/Downloads/graalvm-ce-java11-22.3.0/Contents/Home
```
On linux:
``` shell
export GRAALVM_HOME=~/Downloads/graalvm-jdk-21.0.0.1
export GRAALVM_HOME=~/Downloads/graalvm-ce-java11-22.3.0
```
On Windows, from the [Visual Studio 2019 x64 Native Tools Command Prompt](https://github.com/oracle/graal/issues/2116#issuecomment-590470806) or `cmd.exe` (not Powershell):
```
set GRAALVM_HOME=%USERPROFILE%\Downloads\graalvm-ce-jdk-21.0.0.1
set GRAALVM_HOME=%USERPROFILE%\Downloads\graalvm-ce-java11-22.3.0
```
If you are not running from the x64 Native Tools Command Prompt, you will need to set additional environment variables using:
```

View file

@ -22,9 +22,6 @@ agreement, the PR will be merged.
Each bug fix, change or new feature should be tested well to prevent future
regressions.
If possible, tests should use public APIs. If the bug is in private/internal
code, try to trigger it from a public API.
### Force-push
Please do not use `git push --force` on your PR branch for the following
@ -40,7 +37,7 @@ reasons:
## Requirements
You need [lein](https://leiningen.org/) for running JVM tests and/or producing uberjars. For building binaries you need GraalVM. Currently we use Oracle GraalVM 24.
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.
## Clone repository
@ -114,47 +111,6 @@ If the library you want to add doesn't work automatically, you can manually do t
Note: If you have to modify any test file or configuration to have it work with
bb, add an inline comment with prefix `BB-TEST-PATCH:` explaining what you did.
## Windows
We have corresponding `.bat` scripts for Windows, examples from a CMD Shell:
```shell
script\test.bat
script\run_lib_tests.bat
set BABASHKA_TEST_ENV=native
script\run_lib_tests.bat
```
### Enable Windows Symbolic Links
You'll need to **enable symbolic links**.
You must do this before you git clone babashka otherwise some tests will fail.
There seems to be many ways to achieve this; I found the following worked from PowerShell:
```shell
Install-Module -Name Carbon -Force
Import-Module Carbon
Grant-CPrivilege -Identity lee -Privilege SeCreateSymbolicLinkPrivilege
```
You'll need to reboot:
```shell
shutdown /r /t 0
```
After reboot, verify the new privilege via:
```shell
whoami /priv
```
Test if you can create a symbolic link via:
```
mklink foofoo barbar
```
> **TIP**: Symbolic links are not supported in some folder-sharing technologies.
For example, if you are running Windows as a VirtualBox guest, sharing babashka
source folders from your host OS will not share the symbolic links as symbolic links.
One solution is to re-clone babashka to a non-shared folder on Windows.
### Git for Windows
Install [Git for Windows](https://gitforwindows.org/).
It includes a version of `cat` that babashka tests currently rely on.
## Build
See [build.md](build.md).

View file

@ -9,7 +9,6 @@ borkdude/missing.test.assertions,https://github.com/borkdude/missing.test.assert
borkdude/rewrite-edn,https://github.com/borkdude/rewrite-edn
camel-snake-kebab/camel-snake-kebab,https://github.com/clj-commons/camel-snake-kebab
cc.qbits/auspex,https://github.com/mpenet/auspex
cheshire/cheshire,https://github.com/dakrone/cheshire
circleci/bond,https://github.com/circleci/bond
cli-matic/cli-matic,https://github.com/l3nz/cli-matic.git
clj-commons/clj-yaml,https://github.com/clj-commons/clj-yaml

1 maven-name git-url
9 borkdude/rewrite-edn https://github.com/borkdude/rewrite-edn
10 camel-snake-kebab/camel-snake-kebab https://github.com/clj-commons/camel-snake-kebab
11 cc.qbits/auspex https://github.com/mpenet/auspex
cheshire/cheshire https://github.com/dakrone/cheshire
12 circleci/bond https://github.com/circleci/bond
13 cli-matic/cli-matic https://github.com/l3nz/cli-matic.git
14 clj-commons/clj-yaml https://github.com/clj-commons/clj-yaml

View file

@ -5,110 +5,6 @@ you have anything to add. Also see
[#babashka](https://twitter.com/hashtag/babashka?src=hashtag_click&f=live) on
Twitter.
## 2023-05 ([Twitter](https://twitter.com/search?q=(%23babashka%20OR%20babashka)%20since%3A2023-05-01%20until%3A2023-06-01&src=typed_query&f=live), [Mastodon](https://mastodon.social/tags/babashka))
### Releases
1.3.178
Mostly a boring maintenance release with lib upgrades!
### Events
- [Babashka-conf](https://babashka.org/conf/) is happening June 10th in
Berlin. Only a few tickets left! See the [schedule](https://babashka.org/conf/schedule.html). Also you can buy a [conf t-shirt](https://www.etsy.com/listing/1475981599/babashka-conf-berlin-2023-t-shirt) now! See Nikita wearing it [here](https://twitter.com/nikitonsky/status/1658066530800742400)!
Thanks to conference sponsors:
<img src="https://pbs.twimg.com/media/Fw5h-0_XwA4DTIj?format=jpg&name=medium" width="200px">
- Babashka is going to the [Strange Loop](https://www.thestrangeloop.com/) conference!
### Projects
- [beep-boop](https://github.com/pesterhazy/beep-boop): Audible and visual feedback for test runs
- [panas.example](https://github.com/keychera/panas.example): All htmx examples ported to babashka!
- [utility-scripts](https://github.com/somecho/utility-scripts): A collection of helper scripts for Clojure, Java, Ledger and Taskwarrior. Written in Clojure
- [bb-scripts](https://github.com/techconative/bb-scripts): Babashka scripts for common utilities
- [Launching bb tasks from emacs](https://mastodon.social/@mykhaylo@fosstodon.org/110456087708592838)
### Articles
- [Clojure in security: Docker](https://www.juxt.pro/blog/clojure-in-docker/): mentions babashka and clj-kondo
- [Changing my mind: Converting a script from bash to Babashka](https://blog.agical.se/en/posts/changing-my-mind--converting-a-script-from-bash-to-babashka/)
- [How to create a really simple ClojureCLR dependency tool](https://blog.agical.se/en/posts/how-to-create-a-really-simple-clojureclr-dependency-tool/) with babashka
- [Making a resume with Node.js babashka (nbb)](https://yogthos.net/posts/2023-05-12-nbb-resume.html)
## 2023-04 ([Twitter](https://twitter.com/search?q=(%23babashka%20OR%20babashka)%20since%3A2023-04-01%20until%3A2023-05-01&src=typed_query&f=live), [Mastodon](https://mastodon.social/tags/babashka))
[Babashka-conf](https://babashka.org/conf/) is happening June 10th in
Berlin. Save the date and/or submit your babashka/clojure-related talk or workshop
in the CfP!
### Releases
1.3.177
Biggest highlight: `bb.edn` is now respected relative of a script, no matter the directory you invoke it from! See [docs](https://book.babashka.org/#_script_adjacent_bb_edn).
### Projects
- [babashka-dl](https://github.com/mjhika/babashka-dl): simple install script for babashka on windows
- [instaparse-bb](https://github.com/babashka/instaparse-bb): Use instaparse from babashka, a new release
### Videos
- [Learning clojure w/ @lispyclouds](https://youtu.be/uBTRLBU-83A): a stream with teej_dv, a neovim core dev
## 2023-03 ([Twitter](https://twitter.com/search?q=(%23babashka%20OR%20babashka)%20since%3A2023-03-01%20until%3A2023-04-01&src=typed_query&f=top), [Mastodon](https://mastodon.social/tags/babashka))
### Releases
1.3.176, 1.3.175, 1.2.174:
Biggest highlight: Switch to GraalVM 19 and enable virtual threads!
### Videos
- [Blambda! The sound of babashka and AWS colliding](https://pitch.com/public/03fa9c7e-2b0e-45fb-8a22-d4a4d4d79d24), by Josh Glover from Pitch!
### Projects
- [babashka.json](https://github.com/babashka/json): JSON abstraction library
- [martian](https://github.com/oliyh/martian) is now babashka compatible!
- [panas.reload](https://github.com/keychera/panas.reload): a hot reload for babashka serving html+css (or htmx)
- [cljs-exif-reader](https://git.sr.ht/~rwv/cljs-exif-reader): Extract information from TIFF and JPEG images (works in babashka, despite the name)
### Jobs
- Write babashka at [Cognician](https://twitter.com/RobStuttaford/status/1641694501793038336)!
## 2023-02 ([Twitter](https://twitter.com/search?q=(%23babashka%20OR%20babashka)%20since%3A2023-02-01%20until%3A2023-03-01&src=typed_query&f=live), [Mastodon](https://mastodon.social/tags/babashka))
## Releases
1.1.173: mostly bugfixes
### Articles
- [A technique for live coding simple web pages](https://github.com/whacked/cow/blob/main/a%20technique%20for%20live%20coding%20simple%20web%20pages.md) with babashka
### Videos
- [Stockholm Clojure Meetup Feb 23: Blambda! The sound of Babashka and Lambda colliding](https://www.youtube.com/watch?v=NfgYon96dsE)
### Projects
- [debux](https://github.com/philoskim/debux) is now babaskha-compatible
- [lines-of-code-bb](https://github.com/matthewdowney/linesofcode-bb): Babashka script to count lines of Clojure code, docs, comments, and more
- [deps-try](https://github.com/eval/deps-try): a babashka-script to try out Clojure libraries in rebel-readline
- [bb-dialog](https://github.com/pixelated-noise/bb-dialog) adds support for `--treeview`
- [A duckduck go CLI with babashka and (bbl)gum](https://mastodon.me.uk/@choffee/109845697304457129)
- [babashka http-client](https://github.com/babashka/http-client) now supports multipart uploads
- [sublime-pretty-edn](https://github.com/oakmac/sublime-pretty-edn): Format, Validate, Minify EDN files in Sublime Text
- [Play console tetris in babashka!](https://twitter.com/borkdude/status/1628473136969576449)
- [kaocha test runner](https://github.com/lambdaisland/kaocha) became babashka compatible!
## 2023-01 ([Twitter](https://twitter.com/search?q=%28%23babashka%20OR%20babashka%29%20until%3A2023-02-01%20since%3A2023-01-01&src=typed_query&f=live), [Mastodon](https://mastodon.social/tags/babashka))
### Releases

View file

@ -66,7 +66,6 @@ The following libraries and projects are known to work with babashka.
- [Meander](#meander)
- [Schema](#schema)
- [Sluj](#sluj)
- [malli-cli](#malli-cli)
- [Pods](#pods)
- [Projects](#projects-1)
- [babashka-test-action](#babashka-test-action)
@ -834,10 +833,6 @@ 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.
### [malli-cli](https://github.com/piotr-yuxuan/malli-cli)
Configuration and CLI powertool with `metosin/malli`.
## Pods
[Babashka pods](https://github.com/babashka/babashka.pods) are programs that can

View file

@ -3,8 +3,9 @@
[clojure.tools.logging.impl :as impl]
[clojure.tools.logging.readable]
[sci.core :as sci]
[taoensso.encore :as encore :refer [have]]
[taoensso.timbre :as timbre]))
[taoensso.encore :as enc :refer [have]]
[taoensso.timbre :as timbre]
[taoensso.timbre.appenders.core :as appenders]))
;;;; timbre
@ -12,80 +13,56 @@
(defn- fline [and-form] (:line (meta and-form)))
(defonce callsite-counter
(encore/counter))
(defmacro log! ; Public wrapper around `-log!`
"Core low-level log macro. Useful for tooling/library authors, etc.
"Core low-level log macro. Useful for tooling, 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
* `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}
?file (when (not= ?file "NO_SOURCE_PATH") ?file)
Supports compile-time elision when compile-time const vals
provided for `level` and/or `?ns-str`.
;; Identifies this particular macro expansion; note that this'll
;; be fixed for any fns wrapping `log!` (notably `tools.logging`,
;; `slf4j-timbre`, etc.):
callsite-id
(hash [level msg-type args ; Unevaluated args (arg forms)
?ns-str ?file ?line (rand)])]
Logging wrapper examples:
(defn log-wrapper-fn [& args] (timbre/log! :info :p args))
(defmacro log-wrapper-macro [& args] (timbre/keep-callsite `(timbre/log! :info :p ~args)))"
([{:as opts
:keys [loc level msg-type args vargs
config ?err ?base-data spying?]
:or
{config 'taoensso.timbre/*config*
?err :auto}}]
(have [:or nil? sequential? symbol?] args)
(let [callsite-id (callsite-counter)
{:keys [line column]} (merge (meta &form) loc)
{:keys [ns file line column]} {:ns @sci/ns :file @sci/file :line line :column column}
ns (or (get opts :?ns-str) ns)
file (or (get opts :?file) file)
line (or (get opts :?line) line)
column (or (get opts :?column) column)
elide? (and #_(enc/const-forms? level ns) (timbre/-elide? level ns))]
(when-not elide?
(let [vargs-form
(or vargs
(if (symbol? args)
`(taoensso.timbre/-ensure-vec ~args)
`[ ~@args]))]
;; Note pre-resolved expansion
`(taoensso.timbre/-log! ~config ~level ~ns ~file ~line ~column ~msg-type ~?err
(delay ~vargs-form) ~?base-data ~callsite-id ~spying?
~(get opts :instant)
~(get opts :may-log?))))))
([level msg-type args & [opts]]
(let [{:keys [line column]} (merge (meta &form))
{:keys [ns file line column]} {:ns @sci/ns :file @sci/file :line line :column column}
loc {:ns ns :file file :line line :column column}
opts (assoc (conj {:loc loc} opts)
:level level, :msg-type msg-type, :args args)]
`(taoensso.timbre/log! ~opts))))
`(taoensso.timbre/-log! ~config ~level ~?ns-str ~?file ~?line ~msg-type ~?err
(delay [~@args]) ~?base-data ~callsite-id ~spying?)))))
(defn make-ns [ns sci-ns ks]
(reduce (fn [ns-map [var-name var]]
(let [m (meta var)
no-doc (:no-doc m)
doc (:doc m)
arglists (:arglists m)]
(assoc ns-map var-name
(sci/new-var (symbol var-name) @var
(cond-> {:ns sci-ns
:name (:name m)}
(:macro m) (assoc :macro true)
doc (assoc :doc doc)
arglists (assoc :arglists arglists))))))
(if no-doc ns-map
(assoc ns-map var-name
(sci/new-var (symbol var-name) @var
(cond-> {:ns sci-ns
:name (:name m)}
(:macro m) (assoc :macro true)
doc (assoc :doc doc)
arglists (assoc :arglists arglists)))))))
{}
(select-keys (ns-publics ns) ks)))
(def atomic-println @#'appenders/atomic-println)
(defn println-appender
"Returns a simple `println` appender for Clojure/Script.
Use with ClojureScript requires that `cljs.core/*print-fn*` be set.
@ -115,7 +92,7 @@
:*err* @sci/err
stream)]
(binding [*out* stream]
(encore/println-atomic (force output_)))))}))
(atomic-println (force output_)))))}))
(def default-config (assoc-in timbre/*config* [:appenders :println]
(println-appender {:stream :auto})))
@ -128,7 +105,7 @@
(defn set-level! [level] (swap-config! (fn [m] (assoc m :min-level level))))
(defn merge-config! [m] (swap-config! (fn [old] (encore/nested-merge old m))))
(defn merge-config! [m] (swap-config! (fn [old] (enc/nested-merge old m))))
(defmacro -log-and-rethrow-errors [?line & body]
`(try (do ~@body)
@ -143,27 +120,14 @@
'info 'infof 'warn 'warnf
'error 'errorf
'-log! 'with-level
'spit-appender '-spy 'spy
'color-str])
'spit-appender '-spy 'spy])
'log! (sci/copy-var log! tns)
'*config* config
'swap-config! (sci/copy-var swap-config! tns)
'merge-config! (sci/copy-var merge-config! tns)
'set-level! (sci/copy-var set-level! tns)
'println-appender (sci/copy-var println-appender tns)
'-log-and-rethrow-errors (sci/copy-var -log-and-rethrow-errors tns)
'-ensure-vec (sci/copy-var encore/ensure-vec tns)))
(def enc-ns (sci/create-ns 'taoensso.encore))
(def encore-namespace
{'catching (sci/copy-var encore/catching enc-ns)
'try* (sci/copy-var encore/try* enc-ns)})
(def timbre-appenders-namespace
(let [tan (sci/create-ns 'taoensso.timbre.appenders.core nil)]
{'println-appender (sci/copy-var println-appender tan)
'spit-appender (sci/copy-var #_:clj-kondo/ignore timbre/spit-appender tan)}))
'-log-and-rethrow-errors (sci/copy-var -log-and-rethrow-errors tns)))
;;;; clojure.tools.logging
@ -196,7 +160,7 @@
#'clojure.tools.logging/*logger-factory*
(fn [_]
(LoggerFactory.
(encore/memoize (fn [logger-ns] (Logger. (str logger-ns) config))))))
(enc/memoize (fn [logger-ns] (Logger. (str logger-ns) config))))))
(def lns (sci/create-ns 'clojure.tools.logging nil))

View file

@ -4,7 +4,6 @@
[babashka.impl.common :refer [ctx]]
[sci.core :as sci]
[selmer.filters :as filters]
[selmer.filter-parser :as fp]
[selmer.parser]
[selmer.tags :as tags]
[selmer.util :as util]
@ -84,31 +83,12 @@
(apply merge)
(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
(-> selmer-parser-ns
(assoc 'render-file (sci/copy-var render-file spns)
'render (sci/copy-var render spns)
'render-template (sci/copy-var render-template 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))))
(def stns (sci/create-ns 'selmer.tags nil))
@ -125,9 +105,7 @@
(def selmer-filters-namespace
{'add-filter! (sci/copy-var filters/add-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)})
'remove-filter! (sci/copy-var filters/remove-filter! sfns)})
(defn turn-off-escaping! []
(sci/alter-var-root escape-variables (constantly false)))

View file

@ -1,14 +1,9 @@
(ns babashka.impl.ordered
{:no-doc true}
(:require [flatland.ordered.map :as omap]
[flatland.ordered.set :as oset]
[sci.core :as sci]))
(def omap-ns (sci/create-ns 'flatland.ordered.map nil))
(def oset-ns (sci/create-ns 'flatland.ordered.set nil))
(def ordered-map-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 fdd5780bc4df4931332b56082c6c3a5c3c85066d
Subproject commit ede4830d95edf6e2e7756924969d28b5619b3b8d

View file

@ -3,7 +3,7 @@
[clojure.tools.build.api :as b]))
(def lib 'org.babashka/babashka.impl.java)
(def version "0.1.10")
(def version "0.1.8")
(def class-dir "target/classes")
(def basis (b/create-basis {:project "deps.edn"}))
(def jar-file (format "target/%s-%s.jar" (name lib) version))
@ -17,8 +17,7 @@
(defn compile-java [_]
(b/javac {:src-dirs ["src-java"]
:class-dir class-dir
:basis basis
:javac-opts ["--release" "8"]}))
:basis basis}))
(defn jar [_]
(compile-java nil)
@ -27,12 +26,7 @@
:lib lib
:version version
:basis basis
:src-dirs ["src"]
:pom-data
[[:licenses
[:license
[:name "MIT License"]
[:url "https://opensource.org/license/mit/"]]]]})
:src-dirs ["src"]})
(b/copy-dir {:src-dirs ["src"]
:target-dir class-dir})
(b/jar {:class-dir class-dir

View file

@ -2,7 +2,7 @@
:aliases
{:build ;; added by neil
{:paths ["." "build" "src"]
:deps {io.github.clojure/tools.build {:git/tag "v0.9.6" :git/sha "8e78bcc"}
:deps {io.github.clojure/tools.build {:git/tag "v0.8.1" :git/sha "7d40500"}
slipset/deps-deploy {:mvn/version "0.2.0"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"}
;; insn/insn {:mvn/version "0.5.3"}

View file

@ -1,7 +1,6 @@
(ns babashka.impl.reify2.interfaces)
(def interfaces [java.nio.file.FileVisitor
java.nio.file.DirectoryStream$Filter
java.io.FileFilter
java.io.FilenameFilter
clojure.lang.Associative

42
install
View file

@ -29,32 +29,6 @@ print_help() {
exit 1
}
has() {
command -v "$1" >/dev/null 2>&1
}
fetch() {
local url=$1
local outfile=${2:-}
if has wget; then
if [[ -n $outfile ]]; then
wget -qO "$outfile" "$url"
else
wget -qO - "$url"
fi
elif has curl; then
if [[ -n $outfile ]]; then
curl -fsSL "$url" -o "$outfile"
else
curl -fsSL "$url"
fi
else
>&2 echo "Either 'wget' or 'curl' needs to be on PATH!"
exit 1
fi
}
while [[ $# -gt 0 ]]
do
key="$1"
@ -106,9 +80,9 @@ fi
if [[ "$version" == "" ]]; then
if [[ "$dev_build" == "true" ]]; then
version="$(fetch https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_VERSION)"
version="$(curl -sL https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_VERSION)"
else
version="$(fetch https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_RELEASED_VERSION)"
version="$(curl -sL https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_RELEASED_VERSION)"
fi
fi
@ -122,11 +96,7 @@ IFS='.' read -ra VER <<< "${version//-SNAPSHOT/}"
vernum=$(printf "%03d%03d%03d" "${VER[0]}" "${VER[1]}" "${VER[2]}")
case "$(uname -m)" in
aarch64) arch=aarch64
if [[ "$platform" == "linux" ]]; then
static_binary="true"
fi
;;
aarch64) arch=aarch64;;
arm64) if [[ 10#$vernum -le 10#000008002 ]]; then
arch="amd64"
else
@ -170,9 +140,9 @@ download_url="https://github.com/babashka/$repo/releases/download/v$version/$fil
# macOS only have shasum available by default
# Some Linux distros (RHEL-like) only have sha256sum available by default (others have both)
if has sha256sum; then
if command -v sha256sum >/dev/null; then
sha256sum_cmd="sha256sum"
elif has shasum; then
elif command -v shasum >/dev/null; then
sha256sum_cmd="shasum -a 256"
else
>&2 echo "Either 'sha256sum' or 'shasum' needs to be on PATH for '--checksum' flag!"
@ -185,7 +155,7 @@ mkdir -p "$download_dir" && (
cd "$download_dir"
echo -e "Downloading $download_url to $download_dir"
fetch "$download_url" "$filename"
curl -o "$filename" -sL "$download_url"
if [[ -n "$checksum" ]]; then
if ! echo "$checksum *$filename" | $sha256sum_cmd --check --status; then
>&2 echo "Failed checksum on $filename"

2
pods

@ -1 +1 @@
Subproject commit 717cef7af5cb1c1b091bd10e012b2e71b7b8b9bc
Subproject commit 75c2216649bf5caf3ae41e7b8fc202e45b090ea9

@ -1 +1 @@
Subproject commit 2058c79fb63f80ca71917432eddea73e0c58717c
Subproject commit 011c3dcbd370bbf0a54e3a9c4fb5777a62a29441

View file

@ -20,32 +20,29 @@
:windows (complement (some-fn :skip-windows :flaky))
:non-flaky (complement :flaky)
:flaky :flaky}
:jvm-opts ["--enable-preview"]
:dependencies [[org.clojure/clojure "1.12.0"]
[borkdude/edamame "1.4.30"]
:dependencies [[org.clojure/clojure "1.11.1"]
[borkdude/edamame "1.1.17"]
[borkdude/graal.locking "0.0.2"]
[org.clojure/tools.cli "1.0.214"]
[cheshire "6.0.0"]
[nrepl/bencode "1.2.0"]
[borkdude/sci.impl.reflector "0.0.4"]
[cheshire "5.11.0"]
[nrepl/bencode "1.1.0"]
[borkdude/sci.impl.reflector "0.0.1"]
[org.babashka/sci.impl.types "0.0.2"]
[org.babashka/babashka.impl.java "0.1.10"]
[org.clojure/core.async "1.8.741"]
[org.babashka/babashka.impl.java "0.1.8"]
[org.clojure/core.async "1.6.673"]
[org.clojure/test.check "1.1.1"]
[com.github.clj-easy/graal-build-time "0.1.0"]
[rewrite-clj/rewrite-clj "1.1.49"]
[rewrite-clj/rewrite-clj "1.1.46"]
[insn/insn "0.5.2"]
[org.babashka/cli "0.8.65"]
[org.babashka/http-client "0.4.22"]
[org.jsoup/jsoup "1.20.1"]
[borkdude/graal.locking "0.0.2"]]
[org.babashka/cli "0.6.45"]
[org.babashka/http-client "0.1.4"]]
:plugins [[org.kipz/lein-meta-bom "0.1.1"]]
:metabom {:jar-name "metabom.jar"}
:profiles {:feature/xml {:source-paths ["feature-xml"]
:dependencies [[org.clojure/data.xml "0.2.0-alpha8"]]}
:feature/yaml {:source-paths ["feature-yaml"]
:dependencies [[clj-commons/clj-yaml "1.0.29"
:exclusions [org.flatland/ordered]#_#_clj-commons/clj-yaml "0.7.110"]
[org.flatland/ordered "1.15.12"]]}
:dependencies [[clj-commons/clj-yaml "0.7.169"
#_#_clj-commons/clj-yaml "0.7.110"]]}
:feature/jdbc {:source-paths ["feature-jdbc"]
:dependencies [[seancorfield/next.jdbc "1.1.610"]]}
:feature/sqlite [:feature/jdbc {:dependencies [[org.xerial/sqlite-jdbc "3.36.0.3"]]}]
@ -56,25 +53,25 @@
:feature/csv {:source-paths ["feature-csv"]
:dependencies [[org.clojure/data.csv "1.0.0"]]}
:feature/transit {:source-paths ["feature-transit"]
:dependencies [[com.cognitect/transit-clj "1.0.333"]]}
:dependencies [[com.cognitect/transit-clj "1.0.329"]]}
:feature/datascript {:source-paths ["feature-datascript"]
:dependencies [[datascript "1.3.10"]]}
:feature/httpkit-client {:source-paths ["feature-httpkit-client"]
:dependencies [[http-kit "2.8.0-RC1"]]}
:dependencies [[http-kit "2.6.0-RC1"]]}
:feature/httpkit-server {:source-paths ["feature-httpkit-server"]
:dependencies [[http-kit "2.8.0-RC1"]]}
:dependencies [[http-kit "2.6.0-RC1"]]}
:feature/lanterna {:source-paths ["feature-lanterna"]
:dependencies [[babashka/clojure-lanterna "0.9.8-SNAPSHOT"]]}
:feature/core-match {:source-paths ["feature-core-match"]
:dependencies [[org.clojure/core.match "1.0.0"]]}
:feature/hiccup {:source-paths ["feature-hiccup"]
:dependencies [[hiccup/hiccup "2.0.0-RC1"]]}
:dependencies [[hiccup/hiccup "2.0.0-alpha2"]]}
:feature/test-check {:source-paths ["feature-test-check"]}
:feature/spec-alpha {:source-paths ["feature-spec-alpha"]}
:feature/selmer {:source-paths ["feature-selmer"]
:dependencies [[selmer/selmer "1.12.59"]]}
:dependencies [[selmer/selmer "1.12.50"]]}
:feature/logging {:source-paths ["feature-logging"]
:dependencies [[com.taoensso/timbre "6.6.0"]
:dependencies [[com.taoensso/timbre "6.0.4"]
[org.clojure/tools.logging "1.1.0"]]}
:feature/priority-map {:source-paths ["feature-priority-map"]
:dependencies [[org.clojure/data.priority-map "1.1.0"]]}
@ -98,8 +95,7 @@
:feature/logging
:feature/priority-map
:feature/rrb-vector
{:dependencies [[borkdude/rewrite-edn "0.4.6"]
[com.clojure-goes-fast/clj-async-profiler "0.5.0"]
{:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.5.0"]
[com.opentable.components/otj-pg-embedded "0.13.3"]
[nubank/matcher-combinators "3.6.0"]]}]
:uberjar {:global-vars {*assert* false}

View file

@ -1 +1 @@
1.12.200
1.1.173

View file

@ -1 +1 @@
1.12.201-SNAPSHOT
1.1.174-SNAPSHOT

View file

@ -18,41 +18,40 @@
"deps.clj/src" "deps.clj/resources"
"resources" "sci/resources"
"impl-java/src"],
:deps {org.clojure/clojure {:mvn/version "1.12.0"},
:deps {org.clojure/clojure {:mvn/version "1.11.1"},
org.babashka/sci {:local/root "sci"}
org.babashka/babashka.impl.java {:mvn/version "0.1.10"}
org.babashka/babashka.impl.java {:mvn/version "0.1.8"}
org.babashka/sci.impl.types {:mvn/version "0.0.2"}
babashka/babashka.curl {:local/root "babashka.curl"}
babashka/fs {:local/root "fs"}
babashka/babashka.core {:local/root "babashka.core"}
org.clojure/core.async {:mvn/version "1.8.741"},
borkdude/graal.locking {:mvn/version "0.0.2"},
org.clojure/core.async {:mvn/version "1.6.673"},
org.clojure/tools.cli {:mvn/version "1.0.214"},
org.clojure/data.csv {:mvn/version "1.0.0"},
cheshire/cheshire {:mvn/version "6.0.0"}
cheshire/cheshire {:mvn/version "5.11.0"}
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
clj-commons/clj-yaml {:mvn/version "1.0.29"}
com.cognitect/transit-clj {:mvn/version "1.0.333"}
clj-commons/clj-yaml {:mvn/version "0.7.169"}
com.cognitect/transit-clj {:mvn/version "1.0.329"}
org.clojure/test.check {:mvn/version "1.1.1"}
nrepl/bencode {:mvn/version "1.2.0"}
nrepl/bencode {:mvn/version "1.1.0"}
seancorfield/next.jdbc {:mvn/version "1.1.610"}
org.postgresql/postgresql {:mvn/version "42.2.18"}
org.hsqldb/hsqldb {:mvn/version "2.5.1"}
datascript/datascript {:mvn/version "1.0.1"}
http-kit/http-kit {:mvn/version "2.8.0-RC1"}
http-kit/http-kit {:mvn/version "2.6.0-RC1"}
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
org.clojure/core.match {:mvn/version "1.0.0"}
hiccup/hiccup {:mvn/version "2.0.0-RC1"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.49"}
selmer/selmer {:mvn/version "1.12.59"}
com.taoensso/timbre {:mvn/version "6.6.0"}
hiccup/hiccup {:mvn/version "2.0.0-alpha2"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.46"}
selmer/selmer {:mvn/version "1.12.50"}
com.taoensso/timbre {:mvn/version "6.0.1"}
org.clojure/tools.logging {:mvn/version "1.1.0"}
org.clojure/data.priority-map {:mvn/version "1.1.0"}
insn/insn {:mvn/version "0.5.2"}
org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
org.babashka/cli {:mvn/version "0.8.65"}
org.babashka/http-client {:mvn/version "0.4.22"}
org.flatland/ordered {:mvn/version "1.15.12"}
org.jsoup/jsoup {:mvn/version "1.20.1"}}
org.babashka/cli {:mvn/version "0.6.45"}
org.babashka/http-client {:mvn/version "0.0.3"}}
:aliases {:babashka/dev
{:main-opts ["-m" "babashka.main"]}
:profile
@ -66,7 +65,7 @@
{:extra-paths ["process/src" "process/test" "test-resources/lib_tests"]
:extra-deps {org.clj-commons/clj-http-lite {:mvn/version "0.4.392"}
#_#_org.babashka/spec.alpha {:git/url "https://github.com/babashka/spec.alpha"
:sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"}
:sha "0dec1f88cbde74a0470b454396f09a03adb4ae39"}
lambdaisland/regal {:mvn/version "0.0.143"}
cprop/cprop {:mvn/version "0.1.16"}
comb/comb {:mvn/version "0.1.1"}
@ -108,7 +107,7 @@
exoscale/coax {:mvn/version "1.0.0-alpha14"}
orchestra/orchestra {:mvn/version "2021.01.01-1"}
expound/expound {:mvn/version "0.8.10"}
integrant/integrant {:git/url "https://github.com/weavejester/integrant", :git/sha "a9fd7c02bd7201f36344b47142badc3c3ef22f88"}
integrant/integrant {:mvn/version "0.8.0"}
com.stuartsierra/dependency {:mvn/version "1.0.0"}
listora/again {:mvn/version "1.0.0"}
org.clojure/tools.gitlibs {:mvn/version "2.4.172"}
@ -170,15 +169,7 @@
:deps/manifest :deps}
net.cgrand/xforms {:git/url "https://github.com/cgrand/xforms"
:git/sha "550dbc150a79c6ecc148d8a7e260e10bc36321c6"
:deps/manifest :deps}
prismatic/plumbing {:git/url "https://github.com/plumatic/plumbing",
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}
org.clj-commons/hickory {:git/url "https://github.com/clj-commons/hickory"
:git/sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"}
com.potetm/fusebox {:git/url "https://github.com/potetm/fusebox"
:git/sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"}
net.sekao/odoyle-rules {:git/url "https://github.com/oakes/odoyle-rules"
:git/sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"}}
:deps/manifest :deps}}
:classpath-overrides {org.clojure/clojure nil
org.clojure/spec.alpha nil}}
:clj-nvd

View file

@ -7,7 +7,7 @@ Args=-H:+ReportExceptionStackTraces \
-H:IncludeResources=src/babashka/.* \
-H:IncludeResources=SCI_VERSION \
-H:Log=registerResource:3 \
--enable-url-protocols=http,https,jar,unix \
-H:EnableURLProtocols=http,https,jar \
--enable-all-security-services \
-H:+JNI \
--no-server \
@ -26,32 +26,4 @@ Args=-H:+ReportExceptionStackTraces \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.SoundbankReader \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.MidiFileWriter \
-H:ServiceLoaderFeatureExcludeServices=java.net.ContentHandlerFactory \
-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 \
-EBABASHKA_SHA
-H:ServiceLoaderFeatureExcludeServices=java.nio.charset.spi.CharsetProvider

View file

@ -1,31 +0,0 @@
[{
"interfaces": [
"java.util.function.Predicate"
]
},
{
"interfaces": [
"java.util.function.Function"
]
},
{
"interfaces": [
"java.io.FileFilter"
]
},
{
"interfaces": [
"java.nio.file.DirectoryStream$Filter"
]
},
{
"interfaces": [
"java.util.function.Supplier"
]
},
{
"interfaces": [
"java.util.function.UnaryOperator"
]
}
]

View file

@ -1,31 +0,0 @@
(ns clojure.repl.deps
(:require [babashka.deps :as deps]))
(defn add-libs
"Given lib-coords, a map of lib to coord, will resolve all transitive deps for the libs
together and add them to the repl classpath, unlike separate calls to add-lib."
{:added "1.12"}
[lib-coords]
(deps/add-deps {:deps lib-coords})
nil)
(defn add-lib
"Given a lib that is not yet on the repl classpath, make it available by
downloading the library if necessary and adding it to the classloader.
Libs already on the classpath are not updated. Requires a valid parent
DynamicClassLoader.
lib - symbol identifying a library, for Maven: groupId/artifactId
coord - optional map of location information specific to the procurer,
or latest if not supplied
Returns coll of libs loaded, including transitive (or nil if none).
For info on libs, coords, and versions, see:
https://clojure.org/reference/deps_and_cli"
{:added "1.12"}
([lib coord]
(add-libs {lib coord}))
([lib]
(throw (ex-info "add-lib without explicit version isn't supported in babashka (yet)" {:lib lib}))))

2
sci

@ -1 +1 @@
Subproject commit e85433a0214114fdceb4ca896e1b9c27b1bdf713
Subproject commit 6ed13f7f19fdae8438323f1d3dd5bf1c0c581396

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 11.0.7
;;
;; Currently we use GraalVM java19-20.1.0
;; Currently we use GraalVM java11-20.1.0
(ns bump-graal-version
(:require [clojure.string :as str]
@ -31,8 +31,8 @@
""
"./bump_graal_version.clj -g 19.3.2 (the new version)"
"or"
"./bump_graal_version.clj -g 19.3.2 --java java19"
"(for GraalVM java19-19.3.2)"
"./bump_graal_version.clj -g 19.3.2 --java java11"
"(for GraalVM java11-19.3.2)"
""]
(str/join \newline))))
@ -45,8 +45,8 @@
"appveyor.yml"
"project.clj"
"script/bump_graal_version.clj"
".cirrus.yml"
"script/install-graalvm"])
".circleci/script/short_ci.clj"
".cirrus.yml"])
;; We might have to keep changing these from
;; time to time whenever the version is bumped
@ -54,7 +54,8 @@
;; OR
;;
;; We could have them as environment variables
(def current-graal-version "24")
(def current-graal-version "22.3.0")
(def current-java-version "java11")
(def cl-options
[["-g" "--graal VERSION" "graal version"]
@ -90,12 +91,19 @@
[args]
(when (empty? args)
(display-help))
(let [new-graal-version (:graal args)]
(let [new-graal-version (:graal args)
new-java-version (:java args)]
(when (not (nil? new-graal-version))
(if (is-valid-bump? new-graal-version nil)
(do
(println "Performing Graal bump...")
(bump-current current-graal-version new-graal-version))
(show-error new-graal-version)))))
(show-error new-graal-version)))
(when (not (nil? new-java-version))
(if (is-valid-bump? new-java-version nil)
(do
(println "Performing Java bump...")
(bump-current current-java-version new-java-version))
(show-error new-java-version)))))
(exec-script cl-args)

View file

@ -39,29 +39,24 @@ args=("-jar" "$BABASHKA_JAR"
# "-H:DashboardDump=reports/dump"
# "-H:+DashboardPretty"
# "-H:+DashboardJson"
# "-H:ReportAnalysisForbiddenType=java.awt.Toolkit:Instantiated"
"-H:ReportAnalysisForbiddenType=java.awt.Toolkit:InHeap,Allocated"
"--verbose"
"--no-fallback"
"--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
"$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_XMX")
BABASHKA_STATIC=${BABASHKA_STATIC:-}
BABASHKA_MUSL=${BABASHKA_MUSL:-}
if [ "$BABASHKA_STATIC" = "true" ]; then
args+=("--static")
if [ "$BABASHKA_MUSL" = "true" ]; then
args+=("--static")
args+=("--libc=musl"
# see https://github.com/oracle/graal/issues/3398
"-H:CCompilerOption=-Wl,-z,stack-size=2097152")
else
# see https://github.com/oracle/graal/issues/3737
args+=("-H:+UnlockExperimentalVMOptions")
args+=("-H:+StaticExecutableWithDynamicLibC")
fi
fi
@ -107,14 +102,4 @@ then
export BABASHKA_FEATURE_PRIORITY_MAP="${BABASHKA_FEATURE_PRIORITY_MAP:-false}"
fi
if [[ -z "${BABASHKA_SHA:-}" ]]
then
sha=$(git rev-parse HEAD)
if [[ $? -eq 0 ]]; then
export BABASHKA_SHA=$sha
fi
fi
"$GRAALVM_HOME/bin/native-image" "${args[@]}" "$@"
./"$BABASHKA_BINARY" describe
"$GRAALVM_HOME/bin/native-image" "${args[@]}"

View file

@ -23,27 +23,14 @@ Rem -H:EnableURLProtocols=jar,http,https is also not supported.
call %GRAALVM_HOME%\bin\gu.cmd install native-image
if "%BABASHKA_SHA%"=="" (
for /f %%i in ('git rev-parse HEAD') do set sha=%%i
if not errorlevel 1 (
set BABASHKA_SHA=%sha%
)
)
call %GRAALVM_HOME%\bin\native-image.cmd ^
"-jar" "target/babashka-%BABASHKA_VERSION%-standalone.jar" ^
"-H:Name=bb" ^
"-H:+ReportExceptionStackTraces" ^
"--verbose" ^
"--no-fallback" ^
"--enable-preview" ^
"--install-exit-handlers" ^
"-march=compatibility" ^
"-O1" ^
"%BABASHKA_XMX%" ^
%*
"%BABASHKA_XMX%"
if %errorlevel% neq 0 exit /b %errorlevel%
call bb "(+ 1 2 3)"
call bb describe

View file

@ -4,33 +4,34 @@ set -euo pipefail
INSTALL_DIR="${1:-$HOME}"
GRAALVM_VERSION="${GRAALVM_VERSION:-24}"
GRAALVM_VERSION="${GRAALVM_VERSION:-21.2.0}"
GRAALVM_PLATFORM=$BABASHKA_PLATFORM
case "${BABASHKA_ARCH:-}" in
aarch64)
GRAALVM_ARCH="aarch64"
;;
*)
GRAALVM_ARCH="x64"
;;
case "$BABASHKA_PLATFORM" in
macos)
GRAALVM_PLATFORM="darwin"
;;
linux)
GRAALVM_PLATFORM="linux"
;;
esac
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/${GRAALVM_VERSION}/archive/${GRAALVM_FILENAME}"
case "${BABASHKA_ARCH:-}" in
aarch64)
GRAALVM_ARCH="aarch64"
;;
*)
GRAALVM_ARCH="amd64"
;;
esac
GRAALVM_FILENAME="graalvm-ce-java11-$GRAALVM_PLATFORM-$GRAALVM_ARCH-$GRAALVM_VERSION.tar.gz"
pushd "$INSTALL_DIR" >/dev/null
if ! [ -d "$GRAALVM_DIR_NAME" ]; then
echo "Downloading GraalVM $GRAALVM_PLATFORM-$GRAALVM_ARCH-$GRAALVM_VERSION on '$PWD'..."
echo "$DOWNLOAD_URL"
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"
if ! [ -d "graalvm-ce-java11-$GRAALVM_VERSION" ]; then
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"
tar xzf "$GRAALVM_FILENAME"
fi
popd >/dev/null

View file

@ -2,18 +2,12 @@
set -eo pipefail
: "${BABASHKA_TEST_ENV:=jvm}"
export BABASHKA_TEST_ENV
if [ "$BABASHKA_TEST_ENV" = "native" ]; then
BB_CMD="./bb"
else
BB_CMD="lein bb"
fi
export PATH
PATH=$(pwd)/process/target/test/on-path:$PATH
export BABASHKA_CLASSPATH
BABASHKA_CLASSPATH=$(clojure -Spath -A:lib-tests)

View file

@ -1,11 +1,7 @@
if not defined BABASHKA_TEST_ENV set BABASHKA_TEST_ENV=jvm
if "%BABASHKA_TEST_ENV%" EQU "native" (set BB_CMD=.\bb) else (set BB_CMD=lein bb)
set EDN=lib_tests.edn
set PATH=%CD%\process\target\test\on-path;%PATH%
.\bb -f script/lib_tests/bb_edn_from_deps.clj %EDN%
%BB_CMD% --config %EDN% --deps-root . -f test-resources/lib_tests/babashka/run_all_libtests.clj %*

View file

@ -1,7 +1,5 @@
#!/usr/bin/env bash
set -eo pipefail
if [ "$GRAALVM_HOME" != "" ]
then
export JAVA_HOME=$GRAALVM_HOME
@ -10,6 +8,7 @@ fi
java -version
set -eo pipefail
unset BABASHKA_PRELOADS
unset BABASHKA_CLASSPATH
unset BABASHKA_PRELOADS_TEST
@ -41,13 +40,3 @@ lein test :only babashka.pod-test
export BABASHKA_SOCKET_REPL_TEST=true
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

@ -175,9 +175,6 @@ else
BABASHKA_LEIN_PROFILES+=",-feature/rrb-vector"
fi
#lein with-profiles "$BABASHKA_LEIN_PROFILES,+reflection,-uberjar" deps :tree
#exit 0
mkdir -p resources/META-INF/babashka
cp deps.edn resources/META-INF/babashka/deps.edn

View file

@ -1,8 +1,7 @@
(ns aaaa-this-has-to-be-first.because-patches
;; we need pprint loaded first, it patches pprint to not bloat the GraalVM binary
(:require [babashka.impl.patches.datafy]
[babashka.impl.pprint]
))
[babashka.impl.pprint]))
;; Enable this for scanning requiring usage:
(def enable-require-scan

View file

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

View file

@ -1,8 +0,0 @@
(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

@ -1,120 +1,25 @@
(ns babashka.impl.cheshire
{:no-doc true}
(:require [cheshire.core :as json]
[cheshire.factory :as fact]
[sci.core :as sci :refer [copy-var]]))
(def tns (sci/create-ns 'cheshire.core nil))
(def fns (sci/create-ns 'cheshire.factory nil))
(def json-factory (sci/new-dynamic-var '*json-factory* nil {:ns fns}))
;; wrap cheshire fns to support `*json-factory*` dynamic var
(defn generate-string
([obj]
(binding [fact/*json-factory* @json-factory]
(json/generate-string obj)))
([obj opt-map]
(binding [fact/*json-factory* @json-factory]
(json/generate-string obj opt-map))))
(defn generate-stream
([obj writer]
(binding [fact/*json-factory* @json-factory]
(json/generate-stream obj writer)))
([obj writer opt-map]
(binding [fact/*json-factory* @json-factory]
(json/generate-stream obj writer opt-map))))
(defn parse-string
([string]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string string))))
([string key-fn]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string string key-fn))))
([^String string key-fn array-coerce-fn]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string string key-fn array-coerce-fn)))))
(defn parse-string-strict
([string]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string-strict string))))
([string key-fn]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string-strict string key-fn))))
([^String string key-fn array-coerce-fn]
(when string
(binding [fact/*json-factory* @json-factory]
(json/parse-string-strict string key-fn array-coerce-fn)))))
(defn parse-stream
([rdr]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream rdr))))
([rdr key-fn]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream rdr key-fn))))
([rdr key-fn array-coerce-fn]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream rdr key-fn array-coerce-fn)))))
(defn parse-stream-strict
([rdr]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream-strict rdr))))
([rdr key-fn]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream-strict rdr key-fn))))
([rdr key-fn array-coerce-fn]
(when rdr
(binding [fact/*json-factory* @json-factory]
(json/parse-stream-strict rdr key-fn array-coerce-fn)))))
(defn parsed-seq
([reader]
(binding [fact/*json-factory* @json-factory]
(json/parsed-seq reader)))
([reader key-fn]
(binding [fact/*json-factory* @json-factory]
(json/parsed-seq reader key-fn)))
([reader key-fn array-coerce-fn]
(binding [fact/*json-factory* @json-factory]
(json/parsed-seq reader key-fn array-coerce-fn))))
(def cheshire-core-namespace
{'encode (copy-var generate-string tns)
'generate-string (copy-var generate-string tns)
'encode-stream (copy-var generate-stream tns)
'generate-stream (copy-var generate-stream tns)
{'encode (copy-var json/encode tns)
'generate-string (copy-var json/generate-string tns)
'encode-stream (copy-var json/encode-stream tns)
'generate-stream (copy-var json/generate-stream tns)
;;'encode-smile (copy-var json/encode-smile tns)
;;'generate-smile (copy-var json/generate-smile tns)
'decode (copy-var parse-string tns)
'parse-string (copy-var parse-string tns)
'parse-string-strict (copy-var parse-string-strict tns)
'decode (copy-var json/decode tns)
'parse-string (copy-var json/parse-string tns)
'parse-string-strict (copy-var json/parse-string-strict tns)
;;'parse-smile (copy-var json/parse-smile tns)
'parse-stream (copy-var parse-stream tns)
'parse-stream-strict (copy-var parse-stream-strict tns)
'parsed-seq (copy-var parsed-seq tns)
'parse-stream (copy-var json/parse-stream tns)
'parse-stream-strict (copy-var json/parse-stream-strict tns)
'parsed-seq (copy-var json/parsed-seq tns)
;;'parsed-smile-seq (copy-var json/parsed-smile-seq tns)
;;'decode-smile (copy-var json/decode-smile tns)
'default-pretty-print-options (copy-var json/default-pretty-print-options tns)
'create-pretty-printer (copy-var json/create-pretty-printer tns)})
(def cheshire-factory-namespace
{'*json-factory* json-factory
'default-factory-options (copy-var fact/default-factory-options fns)
'json-factory (copy-var fact/json-factory fns)
'make-json-factory (copy-var fact/make-json-factory fns)})

View file

@ -8,18 +8,6 @@
[sci.core :as sci]
[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
`{clojure.lang.LineNumberingPushbackReader {:allPublicConstructors true
:allPublicMethods true}
@ -59,10 +47,7 @@
{:name "sleep"}
{:name "start"}
{:name "toString"}
{:name "yield"}
~@(when has-of-virtual? [{:name "ofVirtual"}
{:name "startVirtualThread"}
{:name "isVirtual"}])]}
{:name "yield"}]}
java.net.URL
{:allPublicConstructors true
:allPublicFields true
@ -91,8 +76,7 @@
java.util.Arrays
{:methods [{:name "copyOf"}
{:name "copyOfRange"}
{:name "equals"}
{:name "fill"}]}
{:name "equals"}]}
;; this fixes clojure.lang.Reflector for Java 11
java.lang.reflect.AccessibleObject
{:methods [{:name "canAccess"}]}
@ -128,7 +112,6 @@
{:methods [{:name "aget"}
{:name "aset"}
{:name "aclone"}
{:name "iter"}
;; we expose this via the Compiler/LOADER dynamic var
{:name "baseLoader"}]}
clojure.lang.Compiler
@ -137,12 +120,10 @@
clojure.lang.PersistentHashMap
{:fields [{:name "EMPTY"}]}
clojure.lang.APersistentVector
{:methods [{:name "indexOf"}
{:name "contains"}]}
{:methods [{:name "indexOf"}]}
clojure.lang.LazySeq
{:allPublicConstructors true,
:methods [{:name "indexOf"}
{:name "contains"}]}
:methods [{:name "indexOf"}]}
clojure.lang.ILookup
{:methods [{:name "valAt"}]}
clojure.lang.IPersistentMap
@ -172,28 +153,19 @@
{:methods [{:name "getResource"}
{:name "getResources"}
{:name "getResourceAsStream"}
{:name "getParent"}]}
clojure.lang.ARef
{:methods [{:name "getWatches"}]}
clojure.lang.MapEntry
{:allPublicConstructors true
:methods [{:name "create"}]}})
{:name "getParent"}]}})
(def custom-map
(cond->
(merge base-custom-map
proxy/custom-reflect-map)
(merge base-custom-map
proxy/custom-reflect-map)
features/hsqldb? (assoc `org.hsqldb.dbinfo.DatabaseInformationFull
{:methods [{:name "<init>"
:parameterTypes ["org.hsqldb.Database"]}]}
`java.util.ResourceBundle
{:methods [{:name "getBundle"
:parameterTypes ["java.lang.String","java.util.Locale",
"java.lang.ClassLoader"]}]})
has-graal-process-properties?
(assoc `org.graalvm.nativeimage.ProcessProperties
{:methods [{:name "exec"}]})))
"java.lang.ClassLoader"]}]})))
(def java-net-http-classes
"These classes must be initialized at run time since GraalVM 22.1"
@ -223,16 +195,7 @@
java.net.http.WebSocket$Builder
java.net.http.WebSocket$Listener
java.security.cert.X509Certificate
java.security.cert.CertificateFactory
java.security.Signature
javax.crypto.Cipher
javax.crypto.KeyAgreement
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.net.ssl.HostnameVerifier ;; clj-http-lite
javax.net.ssl.HttpsURLConnection ;; clj-http-lite
@ -244,9 +207,6 @@
javax.net.ssl.TrustManager
javax.net.ssl.TrustManagerFactory
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.HttpClientFacade
jdk.internal.net.http.HttpRequestBuilderImpl
@ -255,10 +215,6 @@
jdk.internal.net.http.websocket.BuilderImpl
jdk.internal.net.http.websocket.WebSocketImpl])
(def thread-builder
(try (Class/forName "java.lang.Thread$Builder")
(catch Exception _ nil)))
(def classes
`{:all [clojure.lang.ArityException
clojure.lang.BigInt
@ -283,7 +239,6 @@
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter
java.io.LineNumberReader
java.io.RandomAccessFile
java.io.InputStream
java.io.IOException
@ -335,18 +290,14 @@
java.lang.ProcessBuilder$Redirect
java.lang.Runtime
java.lang.RuntimeException
java.lang.SecurityException
java.lang.Short
java.lang.StackTraceElement
java.lang.String
java.lang.StringBuilder
java.lang.System
java.lang.Throwable
java.lang.ThreadLocal
java.lang.Thread$UncaughtExceptionHandler
~@(when thread-builder
'[java.lang.Thread$Builder])
java.lang.UnsupportedOperationException
;; java.lang.UnsupportedOperationException
java.lang.ref.WeakReference
java.lang.ref.ReferenceQueue
java.lang.ref.Cleaner
@ -361,15 +312,11 @@
java.net.HttpURLConnection
java.net.InetAddress
java.net.InetSocketAddress
java.net.StandardProtocolFamily
java.net.ServerSocket
java.net.Socket
java.net.SocketException
~@(when has-domain-sockets?
'[java.net.UnixDomainSocketAddress])
java.net.UnknownHostException
java.net.URI
java.net.URISyntaxException
;; java.net.URL, see custom map
java.net.URLConnection
java.net.URLEncoder
@ -383,14 +330,8 @@
java.nio.MappedByteBuffer
java.nio.file.OpenOption
java.nio.file.StandardOpenOption
java.nio.channels.ByteChannel
java.nio.channels.Channels
java.nio.channels.FileChannel
java.nio.channels.FileChannel$MapMode
java.nio.channels.ReadableByteChannel
java.nio.channels.WritableByteChannel
java.nio.channels.ServerSocketChannel
java.nio.channels.SocketChannel
java.nio.charset.Charset
java.nio.charset.CoderResult
java.nio.charset.CharsetEncoder
@ -404,7 +345,6 @@
java.nio.file.FileVisitOption
java.nio.file.FileVisitResult
java.nio.file.Files
java.nio.file.DirectoryStream$Filter
java.nio.file.LinkOption
java.nio.file.NoSuchFileException
java.nio.file.Path
@ -414,28 +354,19 @@
java.nio.file.attribute.BasicFileAttributes
java.nio.file.attribute.FileAttribute
java.nio.file.attribute.FileTime
java.nio.file.attribute.PosixFileAttributes
java.nio.file.attribute.PosixFilePermission
java.nio.file.attribute.PosixFilePermissions
java.nio.file.attribute.UserDefinedFileAttributeView])
java.security.DigestInputStream
java.security.KeyFactory
java.security.KeyPairGenerator
java.security.KeyPair
java.security.KeyStore
java.nio.file.attribute.PosixFilePermissions])
java.security.MessageDigest
java.security.DigestInputStream
java.security.Provider
java.security.KeyStore
java.security.SecureRandom
java.security.Security
java.security.spec.ECGenParameterSpec
java.security.spec.PKCS8EncodedKeySpec
java.security.spec.X509EncodedKeySpec
java.sql.Date
java.text.ParseException
java.text.ParsePosition
;; adds about 200kb, same functionality provided by java.time:
java.text.SimpleDateFormat
java.text.BreakIterator
~@(when features/java-time?
`[java.time.format.DateTimeFormatter
java.time.Clock
@ -470,33 +401,25 @@
java.time.temporal.TemporalAdjusters
java.time.temporal.TemporalAmount
java.time.temporal.TemporalField
java.time.temporal.WeekFields
~(symbol "[Ljava.time.temporal.TemporalField;")
java.time.format.TextStyle
java.time.temporal.Temporal
java.time.temporal.TemporalAccessor
java.time.temporal.TemporalAdjuster
java.time.temporal.TemporalQuery
~(symbol "[Ljava.time.temporal.TemporalQuery;")
java.time.chrono.ChronoLocalDate
java.time.temporal.TemporalUnit
java.time.chrono.ChronoLocalDateTime
java.time.chrono.ChronoZonedDateTime
java.time.chrono.Chronology])
~(symbol "[Ljava.time.temporal.TemporalQuery;")])
java.util.concurrent.atomic.AtomicInteger
java.util.concurrent.atomic.AtomicLong
java.util.concurrent.atomic.AtomicReference
java.util.concurrent.Callable
java.util.concurrent.CancellationException
java.util.concurrent.CompletionException
java.util.concurrent.CountDownLatch
java.util.concurrent.ExecutionException
java.util.concurrent.Executor
java.util.concurrent.ExecutorService
java.util.concurrent.BlockingQueue
java.util.concurrent.ArrayBlockingQueue
java.util.concurrent.LinkedBlockingQueue
java.util.concurrent.ScheduledFuture
java.util.concurrent.ScheduledThreadPoolExecutor
java.util.concurrent.Semaphore
java.util.concurrent.ThreadFactory
@ -505,17 +428,12 @@
java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy
java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy
java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
java.util.concurrent.ExecutorService
java.util.concurrent.ScheduledExecutorService
java.util.concurrent.Future
java.util.concurrent.FutureTask
java.util.concurrent.CompletableFuture
java.util.concurrent.Executors
java.util.concurrent.TimeUnit
java.util.concurrent.CompletionStage
java.util.concurrent.locks.ReentrantLock
java.util.concurrent.ThreadLocalRandom
java.util.concurrent.ConcurrentHashMap
java.util.jar.Attributes
java.util.jar.Attributes$Name
java.util.jar.JarFile
@ -526,11 +444,9 @@
java.util.jar.Manifest
java.util.stream.BaseStream
java.util.stream.Stream
java.util.stream.IntStream
java.util.Random
java.util.regex.Matcher
java.util.regex.Pattern
java.util.regex.PatternSyntaxException
java.util.ArrayDeque
java.util.ArrayList
java.util.Collections
@ -540,7 +456,6 @@
java.util.Base64$Encoder
java.util.Date
java.util.HashMap
java.util.HashSet
java.util.IdentityHashMap
java.util.InputMismatchException
java.util.List
@ -561,8 +476,6 @@
java.util.function.BiFunction
java.util.function.Predicate
java.util.function.Supplier
java.util.zip.CheckedInputStream
java.util.zip.CRC32
java.util.zip.Inflater
java.util.zip.InflaterInputStream
java.util.zip.Deflater
@ -592,22 +505,9 @@
~(symbol "[Ljava.util.regex.Pattern;")
~(symbol "[Lclojure.core$range;")])
~@(when features/yaml? '[org.yaml.snakeyaml.error.YAMLException])
~@(when features/hsqldb? '[org.hsqldb.jdbcDriver])
org.jsoup.Jsoup
org.jsoup.nodes.Attribute
org.jsoup.nodes.Attributes
org.jsoup.nodes.Comment
org.jsoup.nodes.DataNode
org.jsoup.nodes.Document
org.jsoup.nodes.DocumentType
org.jsoup.nodes.Element
org.jsoup.nodes.Node
org.jsoup.nodes.TextNode
org.jsoup.nodes.XmlDeclaration
org.jsoup.parser.Tag
org.jsoup.parser.Parser]
~@(when features/hsqldb? '[org.hsqldb.jdbcDriver])]
:constructors [clojure.lang.Delay
clojure.lang.DynamicClassLoader
clojure.lang.MapEntry
clojure.lang.LineNumberingPushbackReader
java.io.EOFException]
:methods [borkdude.graal.LockFix] ;; support for locking
@ -647,26 +547,19 @@
clojure.lang.IRef
clojure.lang.ISeq
clojure.lang.IPersistentVector
clojure.lang.ITransientSet
clojure.lang.ITransientVector
clojure.lang.Iterate
clojure.lang.LispReader$Resolver
clojure.lang.LongRange
clojure.lang.Named
clojure.lang.Keyword
clojure.lang.PersistentArrayMap
clojure.lang.PersistentArrayMap$TransientArrayMap
clojure.lang.PersistentHashMap$TransientHashMap
clojure.lang.PersistentHashSet
clojure.lang.PersistentHashSet$TransientHashSet
clojure.lang.PersistentList
clojure.lang.PersistentList$EmptyList
clojure.lang.PersistentQueue
clojure.lang.PersistentStructMap
clojure.lang.PersistentTreeMap
clojure.lang.PersistentTreeSet
clojure.lang.PersistentVector
clojure.lang.PersistentVector$TransientVector
clojure.lang.Range
clojure.lang.Ratio
clojure.lang.ReaderConditional
@ -685,14 +578,12 @@
java.lang.LinkageError
java.lang.ThreadDeath
java.lang.VirtualMachineError
java.lang.NoSuchFieldException
java.sql.Timestamp
java.util.concurrent.TimeoutException
java.util.Collection
java.util.Map$Entry
java.util.AbstractMap
java.util.AbstractSet
java.util.AbstractList
sci.impl.records.SciRecord
sci.impl.deftype.SciType
~@(when features/xml? ['clojure.data.xml.node.Element])]
:custom ~custom-map})
@ -705,132 +596,74 @@
(:instance-checks classes))
m (apply hash-map
(for [c classes
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#)))}))]]
c [(list 'quote c) c]]
c))
m (assoc m :public-class
(fn [v]
;; (prn :v v)
;; NOTE: a series of instance check, so far, is still cheaper
;; than piggybacking on defmulti or defprotocol
(let [res (cond (instance? java.lang.Process v)
java.lang.Process
(instance? java.lang.ProcessHandle v)
java.lang.ProcessHandle
(instance? java.lang.ProcessHandle$Info v)
java.lang.ProcessHandle$Info
;; added for calling .put on .environment from ProcessBuilder
(instance? java.util.Map v)
java.util.Map
;; added for issue #239 regarding clj-http-lite
;; can potentially be removed due to fix for #1061
(instance? java.io.ByteArrayOutputStream v)
java.io.ByteArrayOutputStream
(instance? java.security.MessageDigest v)
java.security.MessageDigest
;; streams
(instance? java.io.InputStream v)
java.io.InputStream
(instance? java.io.OutputStream v)
java.io.OutputStream
;; java nio
(instance? java.nio.file.Path v)
java.nio.file.Path
(instance? java.nio.file.FileSystem v)
java.nio.file.FileSystem
(instance? java.nio.file.PathMatcher v)
java.nio.file.PathMatcher
(instance? java.util.stream.Stream v)
java.util.stream.Stream
(instance? java.util.stream.IntStream v)
java.util.stream.IntStream
(instance? java.util.stream.BaseStream v)
java.util.stream.BaseStream
(instance? java.nio.ByteBuffer v)
java.nio.ByteBuffer
(instance? java.nio.charset.Charset v)
java.nio.charset.Charset
(instance? java.nio.charset.CharsetEncoder v)
java.nio.charset.CharsetEncoder
(instance? java.nio.CharBuffer v)
java.nio.CharBuffer
(instance? java.nio.channels.FileChannel v)
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)
java.net.CookieStore
;; this makes interop on reified classes work
;; see java_net_http_test/interop-test
(instance? sci.impl.types.IReified v)
(first (t/getInterfaces v))
;; fix for #1061
(instance? java.net.URLClassLoader v)
java.net.URLClassLoader
(instance? java.lang.ClassLoader v)
java.lang.ClassLoader
(instance? java.nio.file.attribute.PosixFileAttributes v)
java.nio.file.attribute.PosixFileAttributes
(instance? java.nio.file.attribute.BasicFileAttributes v)
java.nio.file.attribute.BasicFileAttributes
(instance? java.nio.file.attribute.UserDefinedFileAttributeView v)
java.nio.file.attribute.UserDefinedFileAttributeView
(instance? java.util.concurrent.Future v)
java.util.concurrent.Future
(instance? java.util.concurrent.ScheduledExecutorService v)
java.util.concurrent.ScheduledExecutorService
(instance? java.util.concurrent.ExecutorService v)
java.util.concurrent.ExecutorService
(instance? java.util.Iterator v)
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.util.concurrent.ThreadFactory v)
java.util.concurrent.ThreadFactory
(instance? java.security.cert.X509Certificate v)
java.security.cert.X509Certificate
(instance? java.io.Console v)
java.io.Console
(instance? java.security.KeyPairGenerator v)
java.security.KeyPairGenerator
(instance? java.security.Signature v)
java.security.Signature
(instance? java.security.Key v)
java.security.Key
(instance? java.util.Set v)
java.util.Set
(instance? java.io.Closeable v)
java.io.Closeable
(instance? java.util.Collection v)
java.util.Collection
(instance? java.lang.Throwable v)
java.lang.Throwable
(instance? org.jsoup.nodes.Element v)
org.jsoup.nodes.Element
(and thread-builder
(instance? thread-builder v))
thread-builder
(instance? java.text.BreakIterator v)
java.text.BreakIterator
;; keep commas for merge friendliness
,)]
;; (prn :res res)
res)))
(cond (instance? java.lang.Process v)
java.lang.Process
(instance? java.lang.ProcessHandle v)
java.lang.ProcessHandle
(instance? java.lang.ProcessHandle$Info v)
java.lang.ProcessHandle$Info
;; added for calling .put on .environment from ProcessBuilder
(instance? java.util.Map v)
java.util.Map
;; added for issue #239 regarding clj-http-lite
;; can potentially be removed due to fix for #1061
(instance? java.io.ByteArrayOutputStream v)
java.io.ByteArrayOutputStream
(instance? java.security.MessageDigest v)
java.security.MessageDigest
;; streams
(instance? java.io.InputStream v)
java.io.InputStream
(instance? java.io.OutputStream v)
java.io.OutputStream
;; java nio
(instance? java.nio.file.Path v)
java.nio.file.Path
(instance? java.nio.file.FileSystem v)
java.nio.file.FileSystem
(instance? java.nio.file.PathMatcher v)
java.nio.file.PathMatcher
(instance? java.util.stream.BaseStream v)
java.util.stream.BaseStream
(instance? java.nio.ByteBuffer v)
java.nio.ByteBuffer
(instance? java.nio.charset.Charset v)
java.nio.charset.Charset
(instance? java.nio.charset.CharsetEncoder v)
java.nio.charset.CharsetEncoder
(instance? java.nio.CharBuffer v)
java.nio.CharBuffer
(instance? java.nio.channels.FileChannel v)
java.nio.channels.FileChannel
(instance? java.net.CookieStore v)
java.net.CookieStore
;; this makes interop on reified classes work
;; see java_net_http_test/interop-test
(instance? sci.impl.types.IReified v)
(first (t/getInterfaces v))
;; fix for #1061
(instance? java.net.URLClassLoader v)
java.net.URLClassLoader
(instance? java.lang.ClassLoader v)
java.lang.ClassLoader
(instance? java.io.Closeable v)
java.io.Closeable
(instance? java.nio.file.attribute.BasicFileAttributes v)
java.nio.file.attribute.BasicFileAttributes
(instance? java.util.concurrent.Future v)
java.util.concurrent.Future
(instance? java.util.concurrent.ScheduledExecutorService v)
java.util.concurrent.ScheduledExecutorService
(instance? java.util.Iterator v)
java.util.Iterator
;; keep commas for merge friendliness
,,,)))
m (assoc m (list 'quote 'clojure.lang.Var) 'sci.lang.Var)
m (assoc m (list 'quote 'clojure.lang.Namespace) 'sci.lang.Namespace)]
m))
@ -841,14 +674,6 @@
allowed to be initialized at build time."
(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
"A delay to delay initialization of java-net-http classes to run time, since GraalVM 22.1"
(delay (persistent! (reduce (fn [acc c]
@ -882,8 +707,6 @@
Integer java.lang.Integer
InterruptedException java.lang.InterruptedException
Iterable java.lang.Iterable
;; NOTE: in hindsight File never belonged to the default imports of Clojure,
;; but it's been here to long to remove probably
File java.io.File
Float java.lang.Float
Long java.lang.Long
@ -893,26 +716,22 @@
Number java.lang.Number
NumberFormatException java.lang.NumberFormatException
Object java.lang.Object
Runnable java.lang.Runnable
Runtime java.lang.Runtime
RuntimeException java.lang.RuntimeException
Process java.lang.Process
Process java.lang.Process
ProcessBuilder java.lang.ProcessBuilder
SecurityException java.lang.SecurityException
Short java.lang.Short
StackTraceElement java.lang.StackTraceElement
String java.lang.String
StringBuilder java.lang.StringBuilder
System java.lang.System
Thread java.lang.Thread
ThreadLocal java.lang.ThreadLocal
Thread$UncaughtExceptionHandler java.lang.Thread$UncaughtExceptionHandler
Throwable java.lang.Throwable
VirtualMachineError java.lang.VirtualMachineError
ThreadDeath java.lang.ThreadDeath
UnsupportedOperationException java.lang.UnsupportedOperationException})
;; (eval (vec (keys imports)))
;; UnsupportedOperationException java.lang.UnsupportedOperationException
})
(defn reflection-file-entries []
(let [entries (vec (for [c (sort (concat (:all classes)
@ -954,13 +773,13 @@
"resources/META-INF/native-image/babashka/babashka/reflect-config.json")
(json/generate-string all-entries {:pretty true}))))
(defn public-declared-method? [^Class c ^java.lang.reflect.Method m]
(defn public-declared-method? [c m]
(and (= c (.getDeclaringClass m))
(not (.getAnnotation m Deprecated))))
(defn public-declared-method-names [^Class c]
(defn public-declared-method-names [c]
(->> (.getMethods c)
(keep (fn [^java.lang.reflect.Method m]
(keep (fn [m]
(when (public-declared-method? c m)
{:class c
:name (.getName m)})))
@ -988,4 +807,6 @@
(public-declared-method-names java.net.URL)
(public-declared-method-names java.util.Properties)
(all-classes))
(all-classes)
)

View file

@ -74,7 +74,7 @@
(defn split-classpath
"Returns the classpath as a seq of strings, split by the platform
specific path separator."
([^String cp] (vec (when cp (.split cp path-sep)))))
([^String cp] (vec (.split cp path-sep))))
(defn get-classpath
"Returns the current classpath as set by --classpath, BABASHKA_CLASSPATH and add-classpath."
@ -84,8 +84,8 @@
cp)))
(defn resource
(^URL [path] (resource path @the-url-loader))
(^URL [path loader]
(^URL [path] (resource @the-url-loader path))
(^URL [loader path]
(if (str/starts-with? path "/") nil ;; non-relative paths always return nil
(getResource loader [path] true))))

View file

@ -17,22 +17,18 @@
(let [extra-opts '%s
sym `%s
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)
ns (:ns (meta the-var))
ns-meta (meta ns)
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)
(:org.babashka/cli the-var-meta)
(:org.babashka/cli ct)
extra-opts)
cli-opts (assoc cli-opts :exec-args exec-args)
task-exec-args (:exec-args ct)
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)]
(the-var opts))"
(random-uuid)

View file

@ -3,6 +3,7 @@
(:refer-clojure :exclude [future read+string clojure-version with-precision
send-via send send-off sync into-array])
(:require [babashka.impl.common :as common]
[borkdude.graal.locking :as locking]
[clojure.core :as c]
[clojure.string :as str]
[sci.core :as sci]
@ -11,6 +12,18 @@
[sci.impl.utils :refer [clojure-core-ns]]
[sci.impl.vars :as vars]))
(defn 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
([sym] (core-dynamic-var sym nil))
([sym init-val] (sci/new-dynamic-var sym init-val {:ns clojure-core-ns})))
@ -23,7 +36,6 @@
(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*))
(def repl (core-dynamic-var '*repl* true)) ;; set to true, basically just a dummy for now
(defn read+string
"Added for compatibility. Must be used with
@ -52,7 +64,7 @@
The rounding mode is one of CEILING, FLOOR, HALF_UP, HALF_DOWN,
HALF_EVEN, UP, DOWN and UNNECESSARY; it defaults to HALF_UP."
[precision & exprs]
(let [[body rm] (if (= :rounding (first exprs))
(let [[body rm] (if (= (first exprs) :rounding)
[(next (next exprs))
`((. java.math.RoundingMode ~(second exprs)))]
[exprs nil])]
@ -118,7 +130,7 @@
:static true}
([aseq]
(try (clojure.lang.RT/seqToTypedArray (seq aseq))
(catch Throwable _
(catch IllegalArgumentException _
(clojure.lang.RT/seqToTypedArray Object (seq aseq)))))
([type aseq]
(clojure.lang.RT/seqToTypedArray type (seq aseq))))
@ -144,9 +156,11 @@
'file-seq (copy-core-var file-seq)
'promise (copy-core-var promise)
'deliver (copy-core-var deliver)
'locking (macrofy 'locking locking*)
'shutdown-agents (copy-core-var shutdown-agents)
'slurp (copy-core-var slurp)
'spit (copy-core-var spit)
'time (macrofy 'time time*)
'Throwable->map (copy-core-var Throwable->map)
'tap> (copy-core-var tap>)
'add-tap (copy-core-var add-tap)
@ -163,7 +177,6 @@
'*math-context* math-context
'*compiler-options* compiler-options
'*compile-path* compile-path
'*source-path* sci/file
'with-precision (sci/copy-var with-precision clojure-core-ns)
'-with-precision (sci/copy-var -with-precision clojure-core-ns)
;; STM
@ -174,8 +187,6 @@
'sync (sci/copy-var sync clojure-core-ns)
'ref (sci/copy-var ref clojure-core-ns)
'ref-set (sci/copy-var ref-set clojure-core-ns)
'ensure (sci/copy-var ensure clojure-core-ns)
;; end STM
'update-vals (sci/copy-var update-vals clojure-core-ns)
'update-keys (sci/copy-var update-keys clojure-core-ns)
'parse-boolean (sci/copy-var parse-boolean clojure-core-ns)
@ -191,17 +202,5 @@
'into-array (sci/copy-var into-array clojure-core-ns)
'print-method (sci/copy-var print-method clojure-core-ns)
'print-dup (sci/copy-var print-dup clojure-core-ns)
'PrintWriter-on (sci/copy-var PrintWriter-on clojure-core-ns)
'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)
;; 1.12
'splitv-at (sci/copy-var splitv-at clojure-core-ns)
'stream-transduce! (sci/copy-var stream-transduce! clojure-core-ns)
'partitionv (sci/copy-var partitionv clojure-core-ns)
'stream-into! (sci/copy-var stream-into! clojure-core-ns)
'stream-reduce! (sci/copy-var stream-reduce! clojure-core-ns)
'stream-seq! (sci/copy-var stream-seq! clojure-core-ns)
'partitionv-all (sci/copy-var partitionv-all clojure-core-ns)
'*repl* repl
}
'PrintWriter-on (sci/copy-var PrintWriter-on clojure-core-ns)}
)

View file

@ -2,94 +2,33 @@
{:no-doc true}
(:require [clojure.core.async :as async]
[clojure.core.async.impl.protocols :as protocols]
[clojure.core.async.impl.dispatch :as dispatch]
[sci.core :as sci :refer [copy-var]]
[sci.impl.copy-vars :refer [macrofy]]
[sci.impl.vars :as vars])
(:import [java.util.concurrent Executors ExecutorService ThreadFactory]))
[sci.impl.vars :as vars]))
(set! *warn-on-reflection* true)
#_(def ^java.util.concurrent.Executor executor @#'async/thread-macro-executor)
(def executor-for
"Given a workload tag, returns an ExecutorService instance and memoizes the result. By
default, core.async will defer to a user factory (if provided via sys prop) or construct
a specialized ExecutorService instance for each tag :io, :compute, and :mixed. When
given the tag :core-async-dispatch it will default to the executor service for :io."
(memoize
(fn ^ExecutorService [workload]
(let [sysprop-factory nil #_(when-let [esf (System/getProperty "clojure.core.async.executor-factory")]
(requiring-resolve (symbol esf)))
sp-exec (and sysprop-factory (sysprop-factory workload))]
(or sp-exec
(if (= workload :core-async-dispatch)
(executor-for :io)
(@#'dispatch/create-default-executor workload)))))))
(alter-var-root #'dispatch/executor-for (constantly executor-for))
#_#_(defn exec
[^Runnable r workload]
(prn :r r :w workload)
(let [^ExecutorService e (executor-for workload)]
(.execute e r)))
(alter-var-root #'dispatch/exec (constantly exec))
(def ^java.util.concurrent.Executor virtual-executor
(try (eval '(java.util.concurrent.Executors/newVirtualThreadPerTaskExecutor))
(catch Exception _ nil)))
(def ^java.util.concurrent.Executor executor @#'async/thread-macro-executor)
(defn thread-call
"Executes f in another thread, returning immediately to the calling
thread. Returns a channel which will receive the result of calling
f when completed, then close. workload is a keyword that describes
the work performed by f, where:
:io - may do blocking I/O but must not do extended computation
:compute - must not ever block
:mixed - anything else (default)
when workload not supplied, defaults to :mixed"
([f] (thread-call f :mixed))
([f workload]
(let [c (async/chan 1)
returning-to-chan (fn [bf]
#(try
(when-some [ret (bf)]
(async/>!! c ret))
(finally (async/close! c))))
f (vars/binding-conveyor-fn f)]
(-> f #_bound-fn* returning-to-chan (dispatch/exec workload))
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 [returning-to-chan (fn [bf]
#(try
(when-some [ret (bf)]
(async/>!! c ret))
(finally (async/close! c))))
f (vars/binding-conveyor-fn f)]
(.execute virtual-executor
(-> f returning-to-chan)))
(let [binds (vars/get-thread-binding-frame)]
(.execute 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
[_ _ & body]
`(~'clojure.core.async/thread-call (fn [] ~@body) :mixed))
(defn io-thread
[_ _ & body]
`(~'clojure.core.async/thread-call (fn [] ~@body) :io))
(defn -vthread
[_ _ & body]
`(~'clojure.core.async/-vthread-call (fn [] ~@body)))
`(~'clojure.core.async/thread-call (fn [] ~@body)))
(defn alt!!
"Like alt!, except as if by alts!!, will block until completed, and
@ -99,19 +38,10 @@
(defn go-loop
[_ _ bindings & body]
(list 'clojure.core.async/go (list* 'loop bindings body)))
(list 'clojure.core.async/thread (list* 'loop bindings body)))
(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
{:obj core-async-namespace
'<!! (copy-var async/<!! core-async-namespace)
@ -161,10 +91,8 @@
'take! (copy-var async/take! core-async-namespace)
'tap (copy-var async/tap core-async-namespace)
'thread (macrofy 'thread thread core-async-namespace)
'io-thread (macrofy 'io-thread io-thread core-async-namespace)
'thread-call (copy-var thread-call core-async-namespace)
'-vthread-call (copy-var -vthread-call core-async-namespace)
'timeout (copy-var timeout core-async-namespace)
'timeout (copy-var async/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)
@ -179,9 +107,7 @@
'untap (copy-var async/untap core-async-namespace)
'untap-all (copy-var async/untap-all core-async-namespace)
;; polyfill
'go (if virtual-executor
(macrofy 'go -vthread core-async-namespace)
(macrofy 'go thread core-async-namespace))
'go (macrofy 'go thread core-async-namespace)
'<! (copy-var async/<!! core-async-namespace {:name '<!})
'>! (copy-var async/>!! core-async-namespace {:name '>!})
'alt! (macrofy 'alt! alt!! core-async-namespace)
@ -193,4 +119,3 @@
(def async-protocols-namespace
{:obj async-protocols-ns
'ReadPort (copy-var protocols/ReadPort async-protocols-ns)})
;; trigger CI

View file

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

View file

@ -1,6 +0,0 @@
(ns babashka.impl.clojure.java.process
(:require [clojure.java.process]
[sci.core :as sci]))
(def cjp (sci/create-ns 'clojure.java.process nil))
(def cjp-namespace (sci/copy-ns clojure.java.process cjp))

View file

@ -55,13 +55,6 @@ by default when a new command-line REPL is started."} repl-requires
'[[clojure.repl :refer (source apropos pst dir doc find-doc)]
[clojure.pprint :refer (pp pprint)]])
(defmacro with-read-known
"Evaluates body with *read-eval* set to a \"known\" value,
i.e. substituting true for :unknown if necessary."
[& body]
`(binding [*read-eval* (if (= :unknown *read-eval*) true *read-eval*)]
~@body))
(defn repl
"Generic, reusable, read-eval-print loop. By default, reads from *in*,
writes to *out*, and prints exception summaries to *err*. If you use the
@ -118,9 +111,8 @@ by default when a new command-line REPL is started."} repl-requires
:file "<repl>"
:type :sci/error) e)))))))
(catch Throwable e
(let [e' (ex-cause e)]
(caught e)
(set! *e e')))))]
(caught e)
(set! *e e))))]
(with-bindings
(try
(init)

View file

@ -1,7 +0,0 @@
(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

@ -660,12 +660,14 @@
;;; DEFINING FIXTURES
(def ^:private ns->fixtures (atom {}))
(defn- add-ns-meta
"Adds elements in coll to the current namespace metadata as the
value of key."
{:added "1.1"}
[key coll]
(alter-meta! @sci/ns assoc key coll))
(swap! ns->fixtures assoc-in [(sci-namespaces/sci-ns-name @sci/ns) key] coll))
(defmulti use-fixtures
"Wrap test runs in a fixture function to perform setup and
@ -675,10 +677,10 @@
(fn [fixture-type & args] fixture-type))
(defmethod use-fixtures :each [fixture-type & args]
(add-ns-meta :clojure.test/each-fixtures args))
(add-ns-meta ::each-fixtures args))
(defmethod use-fixtures :once [fixture-type & args]
(add-ns-meta :clojure.test/once-fixtures args))
(add-ns-meta ::once-fixtures args))
(defn- default-fixture
"The default, empty, fixture function. Just calls its argument."
@ -729,8 +731,10 @@
[vars]
(doseq [[ns vars] (group-by (comp :ns meta) vars)
:when ns]
(let [once-fixture-fn (join-fixtures (:clojure.test/once-fixtures (meta ns)))
each-fixture-fn (join-fixtures (:clojure.test/each-fixtures (meta ns)))]
(let [ns-name (sci-namespaces/sci-ns-name ns)
fixtures (get @ns->fixtures ns-name)
once-fixture-fn (join-fixtures (::once-fixtures fixtures))
each-fixture-fn (join-fixtures (::each-fixtures fixtures))]
(once-fixture-fn
(fn []
(doseq [v vars]

View file

@ -1,11 +1,9 @@
(ns babashka.impl.clojure.tools.reader
(:refer-clojure :exclude [read read-string])
(:refer-clojure :exclude [read])
(:require
[clojure.tools.reader.reader-types :as rt]
[edamame.core :as e]
[sci.core :as sci]
[sci.ctx-store :as ctx]
[sci.impl.parser :as p]))
[clojure.tools.reader.reader-types :as rt]))
(def rns (sci/create-ns 'clojure.tools.reader))
@ -17,15 +15,6 @@
:location? seq?
: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
(defn read
"Reads the first object from an IPushbackReader or a java.io.PushbackReader.
@ -49,17 +38,7 @@
([{eof :eof :as opts :or {eof :eofthrow}} reader]
(let [opts (assoc default-opts
:read-cond (:read-cond 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)))))))
:features (:features opts))
v (e/parse-next reader opts)]
(if (identical? ::e/eof v)
(if (identical? :eofthrow eof)
@ -74,18 +53,4 @@
sentinel)
v))))
(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})
(def reader-namespace {'read (sci/copy-var read rns)})

View file

@ -3,10 +3,7 @@
[clojure.tools.reader.reader-types :as rt]
[sci.core :as sci]))
(def tr-edn-ns (sci/create-ns 'clojure.tools.reader.edn))
(def edn-namespace {'read-string (sci/copy-var edn/read-string tr-edn-ns)
'read (sci/copy-var edn/read tr-edn-ns)})
(def edn-namespace {'read-string (sci/copy-var edn/read-string (sci/create-ns 'clojure.tools.reader.edn))})
(def rtns (sci/create-ns 'clojure.tools.reader.reader-types))
@ -17,5 +14,4 @@
'read-char (sci/copy-var rt/read-char 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-reader? (sci/copy-var rt/source-logging-reader? rtns)
'string-push-back-reader (sci/copy-var rt/string-push-back-reader rtns)})
'source-logging-reader? (sci/copy-var rt/source-logging-reader? rtns)})

View file

@ -3,7 +3,6 @@
[babashka.fs :as fs]
[babashka.impl.classpath :as cp]
[babashka.impl.common :refer [bb-edn]]
[babashka.process :as process]
[borkdude.deps :as deps]
[clojure.string :as str]
[sci.core :as sci]))
@ -76,20 +75,13 @@
;; paths are added manually above
;; extra-paths are added as :paths in tasks
:paths :tasks :raw :file :deps-root
:min-bb-version)
;; associate deps-root to avoid cache conflict between different
;; bb.edns with relative local/roots by the same name NOTE:
;; deps-root is nil when bb.edn isn't used, so clashes may still
;; happen with dynamic add-deps, but at least we don't invoke
;; clojure CLI's java process each time we call a script from a
;; different directory.
deps-map (assoc deps-map :deps-root (str deps-root))]
:min-bb-version)]
(binding [*print-namespace-maps* false]
(let [deps-map (assoc-in deps-map [:aliases :org.babashka/defaults]
{:replace-paths [] ;; babashka sets paths manually
:classpath-overrides (cond->
'{org.clojure/clojure ""
org.clojure/spec.alpha ""}
'{org.clojure/clojure ""
org.clojure/spec.alpha ""}
;; only remove core specs when they are not mentioned in deps map
(not (str/includes? (str deps-map) "org.clojure/core.specs.alpha"))
(assoc 'org.clojure/core.specs.alpha ""))})
@ -99,16 +91,12 @@
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/*env* env
#'deps/*extra-env* extra-env
#'deps/*exit-fn* (fn
([_])
([_exit-code msg]
(throw (Exception. msg))))}
deps-root (assoc #'deps/*dir* (str deps-root)))
cp (with-out-str (with-bindings bindings
(apply deps/-main args)))

View file

@ -1,19 +1,10 @@
(ns babashka.impl.http-client
(:require
[babashka.http-client]
[babashka.http-client.interceptors]
[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 ins (sci/create-ns 'babashka.http-client.interceptors))
(def http-client-namespace
(sci/copy-ns babashka.http-client hns))
(def http-client-websocket-namespace
(sci/copy-ns babashka.http-client.websocket wns))
(def http-client-interceptors-namespace
(sci/copy-ns babashka.http-client.interceptors ins))

View file

@ -1,18 +1,11 @@
(ns babashka.impl.nrepl-server
{:no-doc true}
(:require
[babashka.impl.classpath :as cp]
[babashka.impl.clojure.core :as core-extras]
[babashka.impl.common :as common]
[babashka.nrepl.impl.server :refer [process-msg]]
[babashka.nrepl.server :as server]
[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!
([]
(start-server! nil))

View file

@ -2,8 +2,7 @@
{:no-doc true}
(:require [clojure.pprint :as pprint]
[sci.core :as sci]
[sci.pprint]
[babashka.impl.clojure.core.async]))
[sci.pprint]))
(defonce patched? (volatile! false))

View file

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

View file

@ -20,18 +20,6 @@
(binding [process/*defaults* @defaults]
(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
{'parse-args (copy-var process/parse-args tns)
'process* (copy-var process/process* tns)
@ -41,11 +29,11 @@
'start (copy-var process/start tns)
'pipeline (copy-var process/pipeline tns)
'$ (copy-var process/$ tns)
'sh (copy-var sh tns)
'sh (copy-var process/sh tns)
'tokenize (copy-var process/tokenize tns)
'*defaults* defaults
'destroy (copy-var process/destroy tns)
'destroy-tree (copy-var process/destroy-tree tns)
'exec (copy-var exec tns)
'shell (copy-var shell tns)
'exec (copy-var process/exec tns)
'shell (copy-var process/shell tns)
'alive? (copy-var process/alive? tns)})

View file

@ -79,18 +79,6 @@
(handle [sig]
((method-or-bust methods 'handle) this sig)))
["java.io.InputStream" #{}]
(proxy [java.io.InputStream] []
(available [] ((method-or-bust methods 'available) this))
(close [] ((method-or-bust methods 'close) this))
(read
([]
((method-or-bust methods 'read) this))
([bs]
((method-or-bust methods 'read) this bs))
([bs off len]
((method-or-bust methods 'read) this bs off len))))
["java.io.PipedInputStream" #{}]
(proxy [java.io.PipedInputStream] []
(available [] ((method-or-bust methods 'available) this))
@ -124,24 +112,6 @@
((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
)))
@ -154,9 +124,7 @@
{:methods [{:name "connectFailed"}
{:name "select"}]}
(class-sym (class (proxy-fn {:class javax.net.ssl.HostnameVerifier})))
{:methods [{:name "verify"}]}
(class-sym (class (proxy-fn {:class java.lang.ThreadLocal})))
{:methods [{:name "get"}]}})
{:methods [{:name "verify"}]}})
;;; Scratch

View file

@ -187,4 +187,5 @@
sun.misc.SignalHandler
{handle [[this signal]]}
}))

View file

@ -43,19 +43,9 @@
"Inspired by skip-if-eol from clojure.main."
[s]
(let [c (r/read-char s)]
(when-not (= \newline c )
(when-not (= c \newline)
(r/unread s c))))
(defn repl-read [sci-ctx in-stream _request-prompt request-exit]
(if (nil? (r/peek-char in-stream))
request-exit
(let [v (parser/parse-next sci-ctx in-stream)]
(skip-if-eol in-stream)
(if (or (identical? :repl/quit v)
(identical? :repl/exit v))
request-exit
v))))
(defn repl
"REPL with predefined hooks for attachable socket server."
([sci-ctx] (repl sci-ctx nil))
@ -78,8 +68,15 @@
(sio/println))
(eval-form sci-ctx `(apply require (quote ~m/repl-requires)))))
:read (or read
(fn [request-prompt request-exit]
(repl-read sci-ctx in request-prompt request-exit)))
(fn [_request-prompt request-exit]
(if (nil? (r/peek-char in))
request-exit
(let [v (parser/parse-next sci-ctx in)]
(skip-if-eol in)
(if (or (identical? :repl/quit v)
(identical? :repl/exit v))
request-exit
v)))))
:eval (or eval
(fn [expr]
(sci/with-bindings {sci/file "<repl>"

View file

@ -1,52 +0,0 @@
(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

@ -1,7 +1,6 @@
(ns babashka.impl.server
(:require [babashka.impl.clojure.core.server :as server]
[babashka.impl.common :as common]
[babashka.impl.repl :as repl]
[babashka.impl.socket-repl :as socket-repl]
[sci.core :as sci]))
@ -18,14 +17,9 @@
(fn [& args]
(apply server/start-server (common/ctx) args)))
(def repl-read
(fn [& args]
(apply repl/repl-read (common/ctx) @sci/in args)))
(def clojure-core-server-namespace
{'repl (sci/copy-var socket-repl/repl sns)
'prepl (sci/copy-var prepl sns)
'io-prepl (sci/copy-var io-prepl sns)
'start-server (sci/copy-var start-server sns)
'stop-server (sci/copy-var server/stop-server sns)
'repl-read (sci/copy-var repl-read sns)})
'stop-server (sci/copy-var server/stop-server sns)})

View file

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

View file

@ -6,7 +6,7 @@
[babashka.deps :as bdeps]
[babashka.fs :as fs]
[babashka.impl.bencode :refer [bencode-namespace]]
[babashka.impl.cheshire :refer [cheshire-core-namespace cheshire-factory-namespace]]
[babashka.impl.cheshire :refer [cheshire-core-namespace]]
[babashka.impl.classes :as classes :refer [classes-namespace]]
[babashka.impl.classpath :as cp :refer [classpath-namespace]]
[babashka.impl.cli :as cli]
@ -16,18 +16,16 @@
[babashka.impl.clojure.instant :as instant]
[babashka.impl.clojure.java.browse :refer [browse-namespace]]
[babashka.impl.clojure.java.io :refer [io-namespace]]
[babashka.impl.clojure.java.process :refer [cjp-namespace]]
[babashka.impl.clojure.java.shell :refer [shell-namespace]]
[babashka.impl.clojure.main :as clojure-main :refer [demunge]]
[babashka.impl.clojure.math :refer [math-namespace]]
[babashka.impl.clojure.reflect :refer [reflect-namespace]]
[babashka.impl.clojure.stacktrace :refer [stacktrace-namespace]]
[babashka.impl.clojure.tools.reader :refer [reader-namespace]]
[babashka.impl.clojure.tools.reader-types :refer [edn-namespace
reader-types-namespace]]
[babashka.impl.clojure.zip :refer [zip-namespace]]
[babashka.impl.common :as common]
[babashka.impl.core :as bbcore]
[babashka.impl.core :as bbcore]
[babashka.impl.curl :refer [curl-namespace]]
[babashka.impl.data :as data]
[babashka.impl.datafy :refer [datafy-namespace]]
@ -36,9 +34,7 @@
[babashka.impl.error-handler :refer [error-handler]]
[babashka.impl.features :as features]
[babashka.impl.fs :refer [fs-namespace]]
[babashka.impl.http-client :refer [http-client-namespace
http-client-websocket-namespace
http-client-interceptors-namespace]]
[babashka.impl.http-client :refer [http-client-namespace]]
[babashka.impl.nrepl-server :refer [nrepl-server-namespace]]
[babashka.impl.pods :as pods]
[babashka.impl.pprint :refer [pprint-namespace]]
@ -49,7 +45,6 @@
[babashka.impl.reify2 :refer [reify-fn]]
[babashka.impl.repl :as repl]
[babashka.impl.rewrite-clj :as rewrite]
[babashka.impl.sci :refer [sci-core-namespace]]
[babashka.impl.server :refer [clojure-core-server-namespace]]
[babashka.impl.socket-repl :as socket-repl]
[babashka.impl.tasks :as tasks :refer [tasks-namespace]]
@ -110,8 +105,6 @@
(def version common/version)
(def build-commit-sha (or (System/getenv "BABASHKA_SHA") ""))
(defn parse-version [version]
(mapv #(Integer/parseInt %)
(-> version
@ -144,12 +137,11 @@
(binding [*out* *err*]
(apply println msgs)))
(defn print-help []
(defn print-help [_ctx _command-line-args]
(println (str "Babashka v" version))
(println "
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] task [cmdline args]
or: bb [svm-opts] [global-opts] subcommand [subcommand opts] [cmdline args]
Substrate VM opts:
@ -162,13 +154,11 @@ Global opts:
-cp, --classpath Classpath to use. Overrides bb.edn classpath.
--debug Print debug information and internal stacktrace in case of exception.
--init <file> Load file after any preloads and prior to evaluation/subcommands.
--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.
--config <file> Replacing bb.edn with file. Relative paths are resolved relative to file.
--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)
-Sdeps Deps data to use as the last deps file to be merged
-f, --file <path> Run file
--jar <path> Run uberjar
Help:
@ -180,6 +170,7 @@ Help:
Evaluation:
-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.
-x, --exec <var> Call the fully qualified var. Args are parsed by babashka CLI.
@ -220,7 +211,8 @@ Tooling:
File names take precedence over subcommand names.
Remaining arguments are bound to *command-line-args*.
Use -- to separate script command line args from bb command line args.
When no eval opts or subcommand is provided, the implicit subcommand is repl."))
When no eval opts or subcommand is provided, the implicit subcommand is repl.")
[nil 0])
(defn print-doc [ctx command-line-args]
(let [arg (first command-line-args)
@ -263,7 +255,6 @@ Use bb run --help to show this help output.
(format
(str/trim "
{:babashka/version \"%s\"
:git/sha \"%s\"
:feature/csv %s
:feature/java-nio %s
:feature/java-time %s
@ -284,7 +275,6 @@ Use bb run --help to show this help output.
:feature/logging %s
:feature/priority-map %s}")
version
build-commit-sha
features/csv?
features/java-nio?
features/java-time?
@ -333,25 +323,25 @@ Use bb run --help to show this help output.
(def aliases
(cond->
'{str clojure.string
set clojure.set
tools.cli clojure.tools.cli
edn clojure.edn
wait babashka.wait
signal babashka.signal
shell clojure.java.shell
io clojure.java.io
json cheshire.core
curl babashka.curl
fs babashka.fs
bencode bencode.core
deps babashka.deps
async clojure.core.async}
features/xml? (assoc 'xml 'clojure.data.xml)
features/yaml? (assoc 'yaml 'clj-yaml.core)
features/jdbc? (assoc 'jdbc 'next.jdbc)
features/csv? (assoc 'csv 'clojure.data.csv)
features/transit? (assoc 'transit 'cognitect.transit)))
'{str clojure.string
set clojure.set
tools.cli clojure.tools.cli
edn clojure.edn
wait babashka.wait
signal babashka.signal
shell clojure.java.shell
io clojure.java.io
json cheshire.core
curl babashka.curl
fs babashka.fs
bencode bencode.core
deps babashka.deps
async clojure.core.async}
features/xml? (assoc 'xml 'clojure.data.xml)
features/yaml? (assoc 'yaml 'clj-yaml.core)
features/jdbc? (assoc 'jdbc 'next.jdbc)
features/csv? (assoc 'csv 'clojure.data.csv)
features/transit? (assoc 'transit 'cognitect.transit)))
;;(def ^:private server-ns-obj (sci/create-ns 'clojure.core.server nil))
@ -362,87 +352,88 @@ Use bb run --help to show this help output.
(defn catvec [& xs]
(into [] cat xs))
(def sci-ns (sci/create-ns 'sci.core))
(def main-var (sci/new-var 'main nil {:ns clojure-main-ns}))
(def namespaces
(cond->
{'user {'*input* (reify
sci-types/Eval
(eval [_ _ctx _bindings]
(force @input-var)))}
'clojure.core core-extras
'clojure.tools.cli tools-cli-namespace
'clojure.java.shell shell-namespace
'babashka.core bbcore/core-namespace
'babashka.nrepl.server nrepl-server-namespace
'babashka.wait wait-namespace
'babashka.signal signal-ns
'clojure.java.io io-namespace
'cheshire.core cheshire-core-namespace
'cheshire.factory cheshire-factory-namespace
'clojure.data data/data-namespace
'clojure.instant instant/instant-namespace
'clojure.stacktrace stacktrace-namespace
'clojure.zip zip-namespace
'clojure.main {:obj clojure-main-ns
'demunge (sci/copy-var demunge clojure-main-ns)
'repl-requires (sci/copy-var clojure-main/repl-requires clojure-main-ns)
'repl (sci/new-var 'repl
(fn [& opts]
(let [opts (apply hash-map opts)]
(repl/start-repl! (common/ctx) opts))) {:ns clojure-main-ns})
'with-bindings (sci/copy-var clojure-main/with-bindings clojure-main-ns)
'repl-caught (sci/copy-var repl/repl-caught clojure-main-ns)
'with-read-known (sci/copy-var clojure-main/with-read-known clojure-main-ns)
'main main-var}
'clojure.test t/clojure-test-namespace
'clojure.math math-namespace
'clojure.java.process cjp-namespace
'babashka.classpath classpath-namespace
'babashka.classes classes-namespace
'clojure.pprint pprint-namespace
'babashka.curl curl-namespace
'babashka.fs fs-namespace
'babashka.pods pods/pods-namespace
'bencode.core bencode-namespace
'clojure.java.browse browse-namespace
'clojure.datafy datafy-namespace
'clojure.core.protocols protocols-namespace
'babashka.process process-namespace
'clojure.core.server clojure-core-server-namespace
'babashka.deps deps-namespace
'babashka.tasks tasks-namespace
'clojure.tools.reader.edn edn-namespace
'clojure.tools.reader.reader-types reader-types-namespace
'clojure.tools.reader reader-namespace
'clojure.core.async async-namespace
'clojure.core.async.impl.protocols async-protocols-namespace
'clojure.reflect reflect-namespace
'rewrite-clj.node rewrite/node-namespace
'rewrite-clj.paredit rewrite/paredit-namespace
'rewrite-clj.parser rewrite/parser-namespace
'rewrite-clj.zip rewrite/zip-namespace
'rewrite-clj.zip.subedit rewrite/subedit-namespace
'clojure.core.rrb-vector (if features/rrb-vector?
@(resolve 'babashka.impl.rrb-vector/rrb-vector-namespace)
{'catvec (sci/copy-var catvec
(sci/create-ns 'clojure.core.rrb-vector))})
'edamame.core edamame-namespace
'sci.core sci-core-namespace
'babashka.cli cli/cli-namespace
'babashka.http-client http-client-namespace
'babashka.http-client.websocket http-client-websocket-namespace
'babashka.http-client.interceptors http-client-interceptors-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.tree @(resolve 'babashka.impl.xml/xml-tree-namespace))
{'user {'*input* (reify
sci-types/Eval
(eval [_ _ctx _bindings]
(force @input-var)))}
'clojure.core core-extras
'clojure.tools.cli tools-cli-namespace
'clojure.java.shell shell-namespace
'babashka.core bbcore/core-namespace
'babashka.nrepl.server nrepl-server-namespace
'babashka.wait wait-namespace
'babashka.signal signal-ns
'clojure.java.io io-namespace
'cheshire.core cheshire-core-namespace
'clojure.data data/data-namespace
'clojure.instant instant/instant-namespace
'clojure.stacktrace stacktrace-namespace
'clojure.zip zip-namespace
'clojure.main {:obj clojure-main-ns
'demunge (sci/copy-var demunge clojure-main-ns)
'repl-requires (sci/copy-var clojure-main/repl-requires clojure-main-ns)
'repl (sci/new-var 'repl
(fn [& opts]
(let [opts (apply hash-map opts)]
(repl/start-repl! (common/ctx) opts))) {:ns clojure-main-ns})
'with-bindings (sci/copy-var clojure-main/with-bindings clojure-main-ns)
'repl-caught (sci/copy-var repl/repl-caught clojure-main-ns)
'main main-var}
'clojure.test t/clojure-test-namespace
'clojure.math math-namespace
'babashka.classpath classpath-namespace
'babashka.classes classes-namespace
'clojure.pprint pprint-namespace
'babashka.curl curl-namespace
'babashka.fs fs-namespace
'babashka.pods pods/pods-namespace
'bencode.core bencode-namespace
'clojure.java.browse browse-namespace
'clojure.datafy datafy-namespace
'clojure.core.protocols protocols-namespace
'babashka.process process-namespace
'clojure.core.server clojure-core-server-namespace
'babashka.deps deps-namespace
'babashka.tasks tasks-namespace
'clojure.tools.reader.edn edn-namespace
'clojure.tools.reader.reader-types reader-types-namespace
'clojure.tools.reader reader-namespace
'clojure.core.async async-namespace
'clojure.core.async.impl.protocols async-protocols-namespace
'rewrite-clj.node rewrite/node-namespace
'rewrite-clj.paredit rewrite/paredit-namespace
'rewrite-clj.parser rewrite/parser-namespace
'rewrite-clj.zip rewrite/zip-namespace
'rewrite-clj.zip.subedit rewrite/subedit-namespace
'clojure.core.rrb-vector (if features/rrb-vector?
@(resolve 'babashka.impl.rrb-vector/rrb-vector-namespace)
{'catvec (sci/copy-var catvec
(sci/create-ns 'clojure.core.rrb-vector))})
'edamame.core edamame-namespace
'sci.core {'format-stacktrace (sci/copy-var sci/format-stacktrace sci-ns)
'stacktrace (sci/copy-var sci/stacktrace sci-ns)
;; 'eval-string (sci/copy-var sci/eval-string sci-ns)
;; 'eval-string* (sci/copy-var sci/eval-string* sci-ns)
;; 'init (sci/copy-var sci/init sci-ns)
;; 'fork (sci/copy-var sci/fork sci-ns)
}
'babashka.cli cli/cli-namespace
'babashka.http-client http-client-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.tree @(resolve 'babashka.impl.xml/xml-tree-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.set @(resolve 'babashka.impl.ordered/ordered-set-ns))
'flatland.ordered.map @(resolve 'babashka.impl.ordered/ordered-map-ns))
features/jdbc? (assoc 'next.jdbc @(resolve 'babashka.impl.jdbc/njdbc-namespace)
'next.jdbc.sql @(resolve 'babashka.impl.jdbc/next-sql-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/datascript? (assoc 'datascript.core @(resolve 'babashka.impl.datascript/datascript-namespace)
'datascript.db @(resolve 'babashka.impl.datascript/datascript-db-namespace))
@ -470,8 +461,8 @@ Use bb run --help to show this help output.
@(resolve 'babashka.impl.clojure.test.check/test-check-namespace)
;; it's better to load this from source by adding the clojure.test.check dependency
#_#_'clojure.test.check.clojure-test
@(resolve 'babashka.impl.clojure.test.check/test-check-clojure-test-namespace))
features/spec-alpha? (-> (assoc ;; spec
@(resolve 'babashka.impl.clojure.test.check/test-check-clojure-test-namespace))
features/spec-alpha? (-> (assoc ;; spec
'clojure.spec.alpha @(resolve 'babashka.impl.spec/spec-namespace)
'clojure.spec.gen.alpha @(resolve 'babashka.impl.spec/gen-namespace)
'clojure.spec.test.alpha @(resolve 'babashka.impl.spec/test-namespace)))
@ -486,8 +477,6 @@ Use bb run --help to show this help output.
'selmer.validator
@(resolve 'babashka.impl.selmer/selmer-validator-namespace))
features/logging? (assoc 'taoensso.timbre @(resolve 'babashka.impl.logging/timbre-namespace)
'taoensso.timbre.appenders.core @(resolve 'babashka.impl.logging/timbre-appenders-namespace)
'taoensso.encore @(resolve 'babashka.impl.logging/encore-namespace)
'clojure.tools.logging
@(resolve 'babashka.impl.logging/tools-logging-namespace)
'clojure.tools.logging.impl
@ -499,8 +488,7 @@ Use bb run --help to show this help output.
(def edn-readers (cond-> {}
features/yaml?
(assoc 'ordered/map @(resolve 'flatland.ordered.map/ordered-map)
'ordered/set @(resolve 'flatland.ordered.set/ordered-set))
(assoc 'ordered/map @(resolve 'flatland.ordered.map/ordered-map))
features/xml?
(assoc 'xml/ns @(resolve 'clojure.data.xml.name/uri-symbol)
'xml/element @(resolve 'clojure.data.xml.node/tagged-element))))
@ -622,9 +610,19 @@ Use bb run --help to show this help output.
(recur (next options)
(assoc opts-map
: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")
(let [options (next options)]
(recur options
(recur (next options)
(assoc opts-map
:repl true)))
("--socket-repl")
@ -723,47 +721,36 @@ Use bb run --help to show this help output.
(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])))
(defn parse-file-opt
[options opts-map]
(let [opt (first options)]
(if (and opt (and (fs/exists? opt)
(not (fs/directory? opt))))
[nil (assoc opts-map
(if (str/ends-with? opt ".jar")
:jar :file) opt
:command-line-args (next options))]
[options opts-map])))
(let [opt (first options)
opts-key (if (str/ends-with? opt ".jar")
:jar :file)]
(assoc opts-map
opts-key opt
:command-line-args (next options))))
(defn parse-opts
([options] (parse-opts options nil))
([options opts-map]
(let [opt (first options)
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.")))
tasks (into #{} (map str) (keys (:tasks @common/bb-edn)))]
(if-not opt opts-map
;; FILE > TASK > SUBCOMMAND
(cond
(and (not (or (:file opts-map)
(:jar opts-map)))
(.isFile (io/file opt)))
(parse-file-opt options opts-map)
(.isFile (io/file opt))
(if (or (:file opts-map) (:jar opts-map))
opts-map ; we've already parsed the file opt
(parse-file-opt options opts-map))
(contains? tasks opt)
(assoc opts-map
:run opt
:command-line-args (next options))
(command? opt)
(recur (cons (str "--" opt) (next options)) opts-map)
@ -793,13 +780,6 @@ Use bb run --help to show this help output.
env-os-name-present? (not= env-os-name sys-os-name)
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]
@ -843,12 +823,13 @@ Use bb run --help to show this help output.
sci/print-length @sci/print-length
;; when adding vars here, also add them to repl.clj and nrepl_server.clj
]
(let [{:keys [:shell-in :edn-in :shell-out :edn-out
:file :command-line-args
(let [{version-opt :version
:keys [:shell-in :edn-in :shell-out :edn-out
:help :file :command-line-args
:expressions :stream? :init
:repl :socket-repl :nrepl
:debug :classpath :force?
:main :uberscript
:main :uberscript :describe?
:jar :uberjar :clojure
:doc :run :list-tasks
:print-deps :prepare]
@ -889,14 +870,14 @@ Use bb run --help to show this help output.
abs-path))
_ (when jar
(cp/add-classpath jar))
load-fn (fn [{:keys [namespace reload ctx]}]
load-fn (fn [{:keys [:namespace :reload]}]
(let [loader @cp/the-url-loader]
(or
(when ;; ignore built-in namespaces when uberscripting, unless with :reload
(and uberscript
(not reload)
(or (contains? namespaces namespace)
(contains? sci-namespaces/namespaces namespace)))
(and uberscript
(not reload)
(or (contains? namespaces namespace)
(contains? sci-namespaces/namespaces namespace)))
"")
;; pod namespaces go before namespaces from source,
;; unless reload is used
@ -922,7 +903,7 @@ Use bb run --help to show this help output.
res)))
(let [rps (cp/resource-paths namespace)
rps (mapv #(str "src/babashka/" %) rps)]
(when-let [url (some io/resource rps)]
(when-let [url (some #(io/resource %) rps)]
(let [source (slurp url)]
{:file (str url)
:source source})))
@ -933,9 +914,7 @@ Use bb run --help to show this help output.
clojure.core.specs.alpha
(binding [*out* *err*]
(println "[babashka] WARNING: clojure.core.specs.alpha is removed from the classpath, unless you explicitly add the dependency."))
(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)))))))))
nil))))
main (if (and jar (not main))
(when-let [res (cp/getResource
(cp/new-loader [jar])
@ -1025,9 +1004,13 @@ Use bb run --help to show this help output.
exit-code
(or exit-code
(second
(cond doc (print-doc sci-ctx command-line-args)
repl (sci/binding [core/command-line-args command-line-args]
[(repl/start-repl! sci-ctx) 0])
(cond version-opt
[(print-version) 0]
help (print-help sci-ctx command-line-args)
doc (print-doc sci-ctx command-line-args)
describe?
[(print-describe) 0]
repl [(repl/start-repl! sci-ctx) 0]
nrepl [(start-nrepl! nrepl) 0]
uberjar [nil 0]
list-tasks [(tasks/list-tasks sci-ctx) 0]
@ -1075,54 +1058,35 @@ Use bb run --help to show this help output.
clojure [nil (if-let [proc (bdeps/clojure command-line-args)]
(-> @proc :exit)
0)]
:else (sci/binding [core/command-line-args command-line-args]
[(repl/start-repl! sci-ctx) 0])))
:else [(repl/start-repl! sci-ctx) 0]))
1)]
(flush)
(when uberscript
(if (file-write-allowed? uberscript)
(do
(spit uberscript "") ;; reset file
(doseq [s (distinct @uberscript-sources)]
(spit uberscript s :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.")))))
(let [uberscript-out uberscript]
(spit uberscript-out "") ;; reset file
(doseq [s (distinct @uberscript-sources)]
(spit uberscript-out s :append true))
(spit uberscript-out preloads :append true)
(spit uberscript-out expression :append true)))
(when uberjar
(let [cp (cp/get-classpath)]
(cond
(not (file-write-allowed? uberjar))
(throw (Exception. (str "Uberjar target file '" uberjar
"' exists and is not empty. Overwrite prohibited.")))
(not cp)
(throw (Exception. "The uberjar task needs a classpath."))
:else
(let [uber-params {:dest uberjar
:jar :uber
:classpath cp
:main-class main
:verbose debug}]
(if-let [bb-edn-pods (:pods @common/bb-edn)]
(fs/with-temp-dir [bb-edn-dir {}]
(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))))))
(if-let [cp (cp/get-classpath)]
(let [uber-params {:dest uberjar
:jar :uber
:classpath cp
:main-class main
:verbose debug}]
(if-let [bb-edn-pods (:pods @common/bb-edn)]
(fs/with-temp-dir [bb-edn-dir {}]
(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)))
(throw (Exception. "The uberjar task needs a classpath."))))
exit-code))))
(defn exec-without-deps [cli-opts]
(let [{version-opt :version
:keys [help describe?]} cli-opts]
(cond
version-opt (print-version)
help (print-help)
describe? (print-describe)))
0)
(defn satisfies-min-version? [min-version]
(let [[major-current minor-current patch-current] version-data
[major-min minor-min patch-min] (parse-version min-version)]
@ -1133,7 +1097,7 @@ Use bb run --help to show this help output.
(>= patch-current patch-min)))))))
(defn read-bb-edn [string]
(try (edn/read-string {:default tagged-literal :eof nil} string)
(try (edn/read-string {:default tagged-literal} string)
(catch java.lang.RuntimeException e
(if (re-find #"No dispatch macro for: \"" (.getMessage e))
(throw (ex-info "Invalid regex literal found in EDN config, use re-pattern instead" {}))
@ -1141,84 +1105,33 @@ Use bb run --help to show this help output.
(println "Error during loading bb.edn:"))
(throw e))))))
(defn binary-invoked-as-jar []
(and (= "executable" (System/getProperty "org.graalvm.nativeimage.kind"))
(when-let [bin (-> (java.lang.ProcessHandle/current)
.info
.command
(.orElse nil))]
(let [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))
(try
(str (fs/real-path f))
(catch Exception _
f))
f))
(defn deps-not-needed [opts]
(let [fast-path-opts [:version :help :describe?]]
(some #(contains? opts %) fast-path-opts)))
(defn main [& args]
(let [bin-jar (binary-invoked-as-jar)
args (if bin-jar
(list* "--jar" bin-jar "--" args)
args)
[args opts] (parse-global-opts args)
[args {:keys [config merge-deps debug] :as opts}]
(if-not (or (:file opts)
(:jar opts))
(parse-file-opt args opts)
[args opts])
{:keys [jar file]} opts
abs-path resolve-symbolic-link
config (cond
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))
(let [[args global-opts] (parse-global-opts args)
{:keys [:jar] :as file-opt} (when (some-> args first io/file .isFile)
(parse-file-opt args global-opts))
config (:config global-opts)
merge-deps (:merge-deps global-opts)
abs-path #(-> % io/file .getAbsolutePath)
bb-edn-file (cond
config (when (fs/exists? config) (abs-path config))
jar (some-> [jar] cp/new-loader (cp/resource "META-INF/bb.edn") .toString)
:else (when (fs/exists? "bb.edn") (abs-path "bb.edn")))
bb-edn (when (or bb-edn-file merge-deps)
(when bb-edn-file (System/setProperty "babashka.config" bb-edn-file))
(let [raw-string (when bb-edn-file (slurp bb-edn-file))
edn (when bb-edn-file (read-bb-edn raw-string))
edn (if merge-deps
(deps/merge-deps [edn (read-bb-edn merge-deps)])
edn)
edn (assoc edn
:raw raw-string
:file config)
edn (if-let [deps-root (or (:deps-root opts)
:file bb-edn-file)
edn (if-let [deps-root (or (:deps-root global-opts)
(some-> config fs/parent))]
(assoc edn :deps-root deps-root)
edn)]
(vreset! common/bb-edn edn)))
opts (parse-opts args opts)
;; _ (.println System/err (str bb-edn))
min-bb-version (:min-bb-version bb-edn)]
(System/setProperty "java.class.path" "")
(when min-bb-version
@ -1226,9 +1139,7 @@ Use bb run --help to show this help output.
(binding [*out* *err*]
(println (str "WARNING: this project requires babashka "
min-bb-version " or newer, but you have: " version)))))
(if (deps-not-needed opts)
(exec-without-deps opts)
(exec opts))))
(exec (parse-opts args (merge global-opts file-opt)))))
(def musl?
"Captured at compile time, to know if we are running inside a

View file

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

View file

@ -1,10 +0,0 @@
#!/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,9 +2,7 @@
{:org.babashka/cli {:coerce {:foo []}}})
(defn exec-test
{:org.babashka/cli
{:exec-args {:foo :foo}
:coerce {:bar :keyword}}}
{:org.babashka/cli {:coerce {:bar :keyword}}}
[m]
(if (:meta m)
(prn (meta m))

View file

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

View file

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

View file

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

View file

@ -1,22 +0,0 @@
(ns bytechannel-and-related-classes
(:require [clojure.java.io :as io])
(:import (java.nio.file OpenOption
StandardOpenOption)
(java.nio.channels ByteChannel
FileChannel
ReadableByteChannel
WritableByteChannel
Channels)))
(when (and (let [ch (-> (.getBytes "Hello")
(java.io.ByteArrayInputStream.)
(Channels/newChannel))]
(instance? ReadableByteChannel ch))
(let [ch (-> (java.io.ByteArrayOutputStream.)
(Channels/newChannel))]
(instance? WritableByteChannel ch))
(with-open [ch (FileChannel/open (-> (io/file "README.md")
(.toPath))
(into-array OpenOption [StandardOpenOption/READ]))]
(instance? ByteChannel ch)))
(println :success))

View file

@ -1,34 +0,0 @@
-----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

@ -1,41 +0,0 @@
(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

@ -1 +0,0 @@
42

View file

@ -93,15 +93,13 @@
(test-doric-cyclic-dep-problem))
;;;; babashka.process
;; test built-in babashka.process
(test-namespaces 'babashka.process-test)
(when-not (windows?)
;; test built-in babashka.process
(test-namespaces 'babashka.process-test)
(when (= "native" (System/getenv "BABASHKA_TEST_ENV"))
;; test babashka.process from source
#_{:clj-kondo/ignore [:duplicate-require]}
(require '[babashka.process] :reload)
(System/setProperty "babashka.process.test.reload" "true")
(test-namespaces 'babashka.process-test 'babashka.process-exec-test))
(test-namespaces 'babashka.process-test))
;;;; final exit code

View file

@ -94,8 +94,7 @@
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
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 "a9fd7c02bd7201f36344b47142badc3c3ef22f88"
:test-paths ["test"]}
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"}
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"}
meta-merge/meta-merge {:git-url "https://github.com/weavejester/meta-merge", :test-namespaces (meta-merge.core-test), :git-sha "c968c38baccd4219fe0ba592d89af37ea8e426bf"}
@ -187,34 +186,4 @@
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"]}
org.clj-commons/hickory {:git-url "https://github.com/clj-commons/hickory"
:git-sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"
:test-paths ["test/cljc"]
:test-namespaces [hickory.test.core
hickory.test.convert
hickory.test.hiccup-utils
hickory.test.render
hickory.test.select
hickory.test.zip]}
cheshire/cheshire {:git-url "https://github.com/dakrone/cheshire", :test-namespaces [cheshire.test.core], :manually-added true}
com.potetm/fusebox {:git-url "https://github.com/potetm/fusebox"
:git-sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"
:test-paths ["test"]
:test-namespaces [#_com.potetm.fusebox.bulkhead-test
com.potetm.fusebox.bulwark-test
com.potetm.fusebox.circuit-breaker-test
com.potetm.fusebox.fallback-test
com.potetm.fusebox.memoize-test
#_com.potetm.fusebox.rate-limit-test
com.potetm.fusebox.registry-test
com.potetm.fusebox.retry-test
#_com.potetm.fusebox.timeout-test]}
net.sekao/odoyle-rules {:git-url "https://github.com/oakes/odoyle-rules"
:git-sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"
:test-paths ["test"]
:test-namespaces [odoyle.rules-test]}}
:test-paths ["test"]}}

View file

@ -1,793 +0,0 @@
(ns cheshire.test.core
(:require [clojure.test :refer [deftest testing is are]]
[clojure.java.io :as io]
[clojure.string :as str]
[cheshire.core :as json]
;; BB-TEST-PATCH: bb does not include cheshire.exact
#_[cheshire.exact :as json-exact]
;; BB-TEST-PATCH: bb does not include cheshire.gen
#_[cheshire.generate :as gen]
[cheshire.factory :as fact]
;; BB-TEST-PATCH: bb does not include cheshire.parse
#_[cheshire.parse :as parse])
(:import ;; BB-TEST-PATCH: tests adjusted to check for general Exception instead of specific jackson exceptions
#_(com.fasterxml.jackson.core JsonGenerationException
JsonParseException)
#_(com.fasterxml.jackson.core.exc StreamConstraintsException)
(java.io StringReader StringWriter
BufferedReader BufferedWriter
IOException)
;; BB-TEST-PATCH: bb does not support creating java.sql.Timestamps
#_(java.sql Timestamp)
(java.util Date UUID)))
(defn- str-of-len
([len]
(str-of-len len "x"))
([len val]
(apply str (repeat len val))))
(defn- nested-map [depth]
(reduce (fn [acc n] {(str n) acc})
{"0" "foo"}
(range 1 depth)))
(defn- encode-stream->str [obj opts]
(let [sw (StringWriter.)
bw (BufferedWriter. sw)]
(json/generate-stream obj bw opts)
(.toString sw)))
(def test-obj {"int" 3 "long" (long -2147483647) "boolean" true
"LongObj" (Long/parseLong "2147483647") "double" 1.23
"nil" nil "string" "string" "vec" [1 2 3] "map" {"a" "b"}
"list" (list "a" "b") "short" (short 21) "byte" (byte 3)})
(deftest t-ratio
(let [n 1/2]
(is (= (double n) (:num (json/decode (json/encode {:num n}) true))))))
(deftest t-long-wrap-around
(is (= 2147483648 (json/decode (json/encode 2147483648)))))
(deftest t-bigint
(let [n 9223372036854775808]
(is (= n (:num (json/decode (json/encode {:num n}) true))))))
(deftest t-biginteger
(let [n (BigInteger. "42")]
(is (= n (:num (json/decode (json/encode {:num n}) true))))))
(deftest t-bigdecimal
(let [n (BigDecimal. "42.5")]
(is (= (.doubleValue n) (:num (json/decode (json/encode {:num n}) true))))
;; BB-TEST-PATCH:
#_(binding [parse/*use-bigdecimals?* true]
(is (= n (:num (json/decode (json/encode {:num n}) true)))))))
(deftest test-string-round-trip
(is (= test-obj (json/decode (json/encode test-obj)))))
(deftest test-generate-accepts-float
(is (= "3.14" (json/encode 3.14))))
(deftest test-keyword-encode
(is (= {"key" "val"}
(json/decode (json/encode {:key "val"})))))
(deftest test-generate-set
(is (= {"set" ["a" "b"]}
(json/decode (json/encode {"set" #{"a" "b"}})))))
(deftest test-generate-empty-set
(is (= {"set" []}
(json/decode (json/encode {"set" #{}})))))
(deftest test-generate-empty-array
(is (= {"array" []}
(json/decode (json/encode {"array" []})))))
(deftest test-key-coercion
(is (= {"foo" "bar" "1" "bat" "2" "bang" "3" "biz"}
(json/decode
(json/encode
{:foo "bar" 1 "bat" (long 2) "bang" (bigint 3) "biz"})))))
(deftest test-keywords
(is (= {:foo "bar" :bat 1}
(json/decode (json/encode {:foo "bar" :bat 1}) true))))
(deftest test-symbols
(is (= {"foo" "clojure.core/map"}
(json/decode (json/encode {"foo" 'clojure.core/map})))))
(deftest test-accepts-java-map
(is (= {"foo" 1}
(json/decode
(json/encode (doto (java.util.HashMap.) (.put "foo" 1)))))))
(deftest test-accepts-java-list
(is (= [1 2 3]
(json/decode (json/encode (doto (java.util.ArrayList. 3)
(.add 1)
(.add 2)
(.add 3)))))))
(deftest test-accepts-java-set
(is (= {"set" [1 2 3]}
(json/decode (json/encode {"set" (doto (java.util.HashSet. 3)
(.add 1)
(.add 2)
(.add 3))})))))
(deftest test-accepts-empty-java-set
(is (= {"set" []}
(json/decode (json/encode {"set" (java.util.HashSet. 3)})))))
(deftest test-nil
(is (nil? (json/decode nil true))))
(deftest test-parsed-seq
(let [br (BufferedReader. (StringReader. "1\n2\n3\n"))]
(is (= (list 1 2 3) (json/parsed-seq br)))))
;; BB-TEST-PATCH: bb does not support smile
#_(deftest test-smile-round-trip
(is (= test-obj (json/parse-smile (json/generate-smile test-obj)))))
(def bin-obj {"byte-array" (byte-array (map byte [1 2 3]))})
;; BB-TEST-PATCH: bb does not support smile/cbor
#_(deftest test-round-trip-binary
(doseq [[p g] {json/parse-string json/generate-string
json/parse-smile json/generate-smile
json/parse-cbor json/generate-cbor}]
(is (let [roundtripped (p (g bin-obj))]
;; test value equality
(is (= (->> bin-obj (get "byte-array") seq)
(->> roundtripped (get "byte-array") seq)))))))
;; BB-TEST-PATCH: bb does not support smile
#_(deftest test-smile-factory
(binding [fact/*smile-factory* (fact/make-smile-factory {})]
(is (= {"a" 1} (-> {:a 1}
json/generate-smile
json/parse-smile)))))
;; BB-TEST-PATCH: bb does not support smile/cbor
#_(deftest test-smile-duplicate-detection
(let [smile-data (byte-array [0x3a 0x29 0x0a 0x01 ;; smile header
0xFa ;; object start
0x80 0x61 ;; key a
0xC2 ;; value 1
0x80 0x61 ;; key a (again)
0xC4 ;; value 2
0xFB ;; object end
])]
(binding [fact/*smile-factory* (fact/make-smile-factory {:strict-duplicate-detection false})]
(is (= {"a" 2} (json/parse-smile smile-data))))
(binding [fact/*smile-factory* (fact/make-smile-factory {:strict-duplicate-detection true})]
(is (thrown? JsonParseException (json/parse-smile smile-data))))))
;; BB-TEST-PATCH: bb does not support cbor
#_(deftest test-cbor-factory
(binding [fact/*cbor-factory* (fact/make-cbor-factory {})]
(is (= {"a" 1} (-> {:a 1}
json/generate-cbor
json/parse-cbor)))))
;; BB-TEST-PATCH: bb does not support cbor
#_(deftest test-cbor-duplicate-detection
(let [cbor-data (byte-array [0xbf ;; object begin
0x61 0x61 ;; key a
0x01 ;; value 1
0x61 0x61 ;; key a (again)
0x02 ;; value 2
0xff ;; object end
])]
(binding [fact/*cbor-factory* (fact/make-cbor-factory {:strict-duplicate-detection false})]
(is (= {"a" 2} (json/parse-cbor cbor-data))))
(binding [fact/*cbor-factory* (fact/make-cbor-factory {:strict-duplicate-detection true})]
(is (thrown? JsonParseException (json/parse-cbor cbor-data))))))
(deftest test-aliases
(is (= {"foo" "bar" "1" "bat" "2" "bang" "3" "biz"}
(json/decode
(json/encode
{:foo "bar" 1 "bat" (long 2) "bang" (bigint 3) "biz"})))))
(deftest test-date
(is (= {"foo" "1970-01-01T00:00:00Z"}
(json/decode (json/encode {:foo (Date. (long 0))}))))
(is (= {"foo" "1970-01-01"}
(json/decode (json/encode {:foo (Date. (long 0))}
{:date-format "yyyy-MM-dd"})))
"encode with given date format"))
;; BB-TEST-PATCH: bb does not support creating java.sql.Timestamps
#_(deftest test-sql-timestamp
(is (= {"foo" "1970-01-01T00:00:00Z"}
(json/decode (json/encode {:foo (Timestamp. (long 0))}))))
(is (= {"foo" "1970-01-01"}
(json/decode (json/encode {:foo (Timestamp. (long 0))}
{:date-format "yyyy-MM-dd"})))
"encode with given date format"))
(deftest test-uuid
(let [id (UUID/randomUUID)
id-str (str id)]
(is (= {"foo" id-str} (json/decode (json/encode {:foo id}))))))
(deftest test-char-literal
(is (= "{\"foo\":\"a\"}" (json/encode {:foo \a}))))
(deftest test-streams
(testing "parse-stream"
(are [parsed parse parsee] (= parsed
(parse (BufferedReader. (StringReader. parsee))))
{"foo" "bar"} json/parse-stream "{\"foo\":\"bar\"}\n"
{"foo" "bar"} json/parse-stream-strict "{\"foo\":\"bar\"}\n")
(are [parsed parse parsee] (= parsed
(with-open [rdr (StringReader. parsee)]
(parse rdr true)))
{(keyword "foo baz") "bar"} json/parse-stream "{\"foo baz\":\"bar\"}\n"
{(keyword "foo baz") "bar"} json/parse-stream-strict "{\"foo baz\":\"bar\"}\n"))
(testing "generate-stream"
(let [sw (StringWriter.)
bw (BufferedWriter. sw)]
(json/generate-stream {"foo" "bar"} bw)
(is (= "{\"foo\":\"bar\"}" (.toString sw))))))
;; BB-TEST-PATCH: bb does not include with-writer
#_(deftest serial-writing
(is (= "[\"foo\",\"bar\"]"
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write [] :start)
(json/write "foo")
(json/write "bar")
(json/write [] :end)))))
(is (= "[1,[2,3],4]"
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write [1 [2]] :start-inner)
(json/write 3)
(json/write [] :end)
(json/write 4)
(json/write [] :end)))))
(is (= "{\"a\":1,\"b\":2,\"c\":3}"
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write {:a 1} :start)
(json/write {:b 2} :bare)
(json/write {:c 3} :end)))))
(is (= (str "[\"start\",\"continue\",[\"implicitly-nested\"],"
"[\"explicitly-nested\"],\"flatten\",\"end\"]")
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write ["start"] :start)
(json/write "continue")
(json/write ["implicitly-nested"])
(json/write ["explicitly-nested"] :all)
(json/write ["flatten"] :bare)
(json/write ["end"] :end)))))
(is (= "{\"head\":\"head info\",\"data\":[1,2,3],\"tail\":\"tail info\"}"
(.toString
(json/with-writer [(StringWriter.) nil]
(json/write {:head "head info" :data []} :start-inner)
(json/write 1)
(json/write 2)
(json/write 3)
(json/write [] :end)
(json/write {:tail "tail info"} :end))))))
;; BB-TEST-PATCH: modified so that json files could be found
(deftest test-multiple-objs-in-file
(is (= {"one" 1, "foo" "bar"}
(first (json/parsed-seq (io/reader (io/resource "cheshire/test/multi.json"))))))
(is (= {"two" 2, "foo" "bar"}
(second (json/parsed-seq (io/reader (io/resource "cheshire/test/multi.json"))))))
(with-open [r (io/reader (io/resource "cheshire/test/multi.json"))]
(is (= [{"one" 1, "foo" "bar"} {"two" 2, "foo" "bar"}]
(json/parsed-seq r)))))
(deftest test-jsondotorg-pass1
(let [;; BB-TEST-PATCH: modified so that json files could be found
string (slurp (io/resource "cheshire/test/pass1.json"))
decoded-json (json/decode string)
encoded-json (json/encode decoded-json)
re-decoded-json (json/decode encoded-json)]
(is (= decoded-json re-decoded-json))))
(deftest test-namespaced-keywords
(is (= "{\"foo\":\"user/bar\"}"
(json/encode {:foo :user/bar})))
(is (= {:foo/bar "baz/eggplant"}
(json/decode (json/encode {:foo/bar :baz/eggplant}) true))))
(deftest test-array-coerce-fn
(is (= {"set" #{"a" "b"} "array" ["a" "b"] "map" {"a" 1}}
(json/decode
(json/encode {"set" #{"a" "b"} "array" ["a" "b"] "map" {"a" 1}}) false
(fn [field-name] (if (= "set" field-name) #{} []))))))
(deftest t-symbol-encoding-for-non-resolvable-symbols
(is (= "{\"bar\":\"clojure.core/pam\",\"foo\":\"clojure.core/map\"}"
(json/encode (sorted-map :foo 'clojure.core/map :bar 'clojure.core/pam))))
(is (= "{\"bar\":\"clojure.core/pam\",\"foo\":\"foo.bar/baz\"}"
(json/encode (sorted-map :foo 'foo.bar/baz :bar 'clojure.core/pam)))))
(deftest t-bindable-factories-auto-close-source
(binding [fact/*json-factory* (fact/make-json-factory
{:auto-close-source false})]
(let [br (BufferedReader. (StringReader. "123"))]
(is (= 123 (json/parse-stream br)))
(is (= -1 (.read br)))))
(binding [fact/*json-factory* (fact/make-json-factory
{:auto-close-source true})]
(let [br (BufferedReader. (StringReader. "123"))]
(is (= 123 (json/parse-stream br)))
(is (thrown? IOException (.read br))))))
(deftest t-bindable-factories-allow-comments
(let [s "{\"a\": /* comment */ 1, // comment\n \"b\": 2}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-comments true})]
(is (= {"a" 1 "b" 2} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-comments false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-allow-unquoted-field-names
(let [s "{a: 1, b: 2}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-unquoted-field-names true})]
(is (= {"a" 1 "b" 2} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-unquoted-field-names false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-allow-single-quotes
(doseq [s ["{'a': \"one\", 'b': \"two\"}"
"{\"a\": 'one', \"b\": 'two'}"
"{'a': 'one', 'b': 'two'}"]]
(testing s
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-single-quotes true})]
(is (= {"a" "one" "b" "two"} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-single-quotes false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s)))))))
(deftest t-bindable-factories-allow-unquoted-control-chars
(let [s "{\"a\": \"one\ntwo\"}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-unquoted-control-chars true})]
(is (= {"a" "one\ntwo"} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-unquoted-control-chars false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-allow-backslash-escaping-any-char
(let [s "{\"a\": 00000000001}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-numeric-leading-zeros true})]
(is (= {"a" 1} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-numeric-leading-zeros false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-allow-numeric-leading-zeros
(let [s "{\"a\": \"\\o\\n\\e\"}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-backslash-escaping true})]
(is (= {"a" "o\ne"} (json/decode s))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-backslash-escaping false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s))))))
(deftest t-bindable-factories-non-numeric-numbers
(let [s "{\"foo\":NaN}"]
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-non-numeric-numbers true})]
(is (= (type Double/NaN)
(type (:foo (json/decode s true))))))
(binding [fact/*json-factory* (fact/make-json-factory
{:allow-non-numeric-numbers false})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_JsonParseException Exception (json/decode s true))))))
(deftest t-bindable-factories-optimization-opts
(let [s "{\"a\": \"foo\"}"]
(doseq [opts [{:intern-field-names true}
{:intern-field-names false}
{:canonicalize-field-names true}
{:canonicalize-field-names false}]]
(binding [fact/*json-factory* (fact/make-json-factory opts)]
(is (= {"a" "foo"} (json/decode s)))))))
(deftest t-bindable-factories-escape-non-ascii
;; includes testing legacy fn opt of same name can override factory
(let [edn {:foo "It costs £100"}
expected-esc "{\"foo\":\"It costs \\u00A3100\"}"
expected-no-esc "{\"foo\":\"It costs £100\"}"
opt-esc {:escape-non-ascii true}
opt-no-esc {:escape-non-ascii false}]
(testing "default factory"
(doseq [[fn-opts expected]
[[{} expected-no-esc]
[opt-esc expected-esc]
[opt-no-esc expected-no-esc]]]
(testing fn-opts
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts))))))
(testing (str "factory: " opt-esc)
(binding [fact/*json-factory* (fact/make-json-factory opt-esc)]
(doseq [[fn-opts expected]
[[{} expected-esc]
[opt-esc expected-esc]
[opt-no-esc expected-no-esc]]]
(testing (str "fn: " fn-opts)
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts)))))))
(testing (str "factory: " opt-no-esc)
(binding [fact/*json-factory* (fact/make-json-factory opt-no-esc)]
(doseq [[fn-opts expected]
[[{} expected-no-esc]
[opt-esc expected-esc]
[opt-no-esc expected-no-esc]]]
(testing (str "fn: " fn-opts)
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts)))))))))
(deftest t-bindable-factories-quoteless
(binding [fact/*json-factory* (fact/make-json-factory
{:quote-field-names true})]
(is (= "{\"a\":\"foo\"}" (json/encode {:a "foo"}))))
(binding [fact/*json-factory* (fact/make-json-factory
{:quote-field-names false})]
(is (= "{a:\"foo\"}" (json/encode {:a "foo"})))))
(deftest t-bindable-factories-strict-duplicate-detection
(binding [fact/*json-factory* (fact/make-json-factory
{:strict-duplicate-detection true})]
;; BB-TEST-PATCH: Generalized exception check
(is (thrown? #_ JsonParseException Exception
(json/decode "{\"a\": 1, \"b\": 2, \"a\": 3}"))))
(binding [fact/*json-factory* (fact/make-json-factory
{:strict-duplicate-detection false})]
(is (= {"a" 3 "b" 2}
(json/decode "{\"a\": 1, \"b\": 2, \"a\": 3}")))))
(deftest t-bindable-factories-max-input-document-length
(let [edn {"a" (apply str (repeat 10000 "x"))}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-document-length (count sample-data)})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
;; as per Jackson docs, limit is inexact, so dividing input length by 2 should do the trick
{:max-input-document-length (/ (count sample-data) 2)})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)document length .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-input-token-count
;; A token is a single unit of input, such as a number, a string, an object start or end, or an array start or end.
(let [edn {"1" 2 "3" 4}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-token-count 6})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-token-count 5})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)token count .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-input-name-length
(let [k "somekey"
edn {k 1}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-name-length (count k)})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-name-length (dec (count k))})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)name .* exceeds"
(json/decode sample-data)))))
(let [default-limit (:max-input-name-length fact/default-factory-options)]
(let [k (str-of-len default-limit)
edn {k 1}
sample-data (json/encode edn)]
(is (= edn (json/decode sample-data))))
(let [k (str-of-len (inc default-limit))
sample-data (json/encode {k 1})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)name .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-input-nesting-depth
(let [edn (nested-map 100)
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-nesting-depth 100})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-nesting-depth 99})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)nesting depth .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-input-number-length
(let [num 123456789
edn {"foo" num}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-number-length (-> num str count)})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-number-length (-> num str count dec)})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)number value length .* exceeds"
(json/decode sample-data)))))
(let [default-limit (:max-input-number-length fact/default-factory-options)]
(let [num (bigint (str-of-len default-limit 2))
edn {"foo" num}
sample-data (json/encode edn)]
(is (= edn (json/decode sample-data))))
(let [num (bigint (str-of-len (inc default-limit) 2))
sample-data (json/encode {"foo" num})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)number value length .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-input-string-length
(let [big-string (str-of-len 40000000)
edn {"big-string" big-string}
sample-data (json/encode edn)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-string-length (count big-string)})]
(is (= edn (json/decode sample-data))))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-input-string-length (dec (count big-string))})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)string value length .* exceeds"
(json/decode sample-data)))))
(let [default-limit (:max-input-string-length fact/default-factory-options)]
(let [big-string (str-of-len default-limit)
edn {"big-string" big-string}
sample-data (json/encode edn)]
(is (= edn (json/decode sample-data))))
(let [big-string (str-of-len (inc default-limit))
sample-data (json/encode {"big-string" big-string})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)string value length .* exceeds"
(json/decode sample-data))))))
(deftest t-bindable-factories-max-output-nesting-depth
(let [edn (nested-map 100)]
(binding [fact/*json-factory* (fact/make-json-factory
{:max-output-nesting-depth 100})]
(is (.contains (json/encode edn) "\"99\"")))
(binding [fact/*json-factory* (fact/make-json-factory
{:max-output-nesting-depth 99})]
(is (thrown-with-msg?
;; BB-TEST-PATCH: Generalized exception check
#_StreamConstraintsException Exception #"(?i)nesting depth .* exceeds"
(json/encode edn))))))
(deftest t-persistent-queue
(let [q (conj clojure.lang.PersistentQueue/EMPTY 1 2 3)]
(is (= q (json/decode (json/encode q))))))
(deftest t-pretty-print
(is (= (str/join (System/lineSeparator)
["{"
" \"bar\" : [ {"
" \"baz\" : 2"
" }, \"quux\", [ 1, 2, 3 ] ],"
" \"foo\" : 1"
"}"])
(json/encode (sorted-map :foo 1 :bar [{:baz 2} :quux [1 2 3]])
{:pretty true}))))
(deftest t-pretty-print-custom-linebreak
(is (= (str/join "foo"
["{"
" \"bar\" : [ {"
" \"baz\" : 2"
" }, \"quux\", [ 1, 2, 3 ] ],"
" \"foo\" : 1"
"}"])
(json/encode (sorted-map :foo 1 :bar [{:baz 2} :quux [1 2 3]])
{:pretty {:line-break "foo"}}))))
(deftest t-pretty-print-illegal-argument
; just expecting this not to throw
(json/encode {:foo "bar"}
{:pretty []})
(json/encode {:foo "bar"}
{:pretty nil}))
(deftest t-custom-pretty-print-with-defaults
(let [test-obj (sorted-map :foo 1 :bar {:baz [{:ulu "mulu"} {:moot "foo"} 3]} :quux :blub)
pretty-str-default (json/encode test-obj {:pretty true})
pretty-str-custom (json/encode test-obj {:pretty {}})]
(is (= pretty-str-default pretty-str-custom))
(when-not (= pretty-str-default pretty-str-custom)
; print for easy comparison
(println "; default pretty print")
(println pretty-str-default)
(println "; custom pretty print with default options")
(println pretty-str-custom))))
(deftest t-custom-pretty-print-with-non-defaults
(let [test-obj (sorted-map :foo 1 :bar {:baz [{:ulu "mulu"} {:moot "foo"} 3]} :quux :blub)
test-opts {:pretty {:indentation 4
:indent-arrays? false
:before-array-values ""
:after-array-values ""
:object-field-value-separator ": "}}
expected (str/join (System/lineSeparator)
["{"
" \"bar\": {"
" \"baz\": [{"
" \"ulu\": \"mulu\""
" }, {"
" \"moot\": \"foo\""
" }, 3]"
" },"
" \"foo\": 1,"
" \"quux\": \"blub\""
"}"])
pretty-str (json/encode test-obj test-opts)]
; just to be easy on the eyes in case of error
(when-not (= expected pretty-str)
(println "; pretty print with options - actual")
(println pretty-str)
(println "; pretty print with options - expected")
(println expected))
(is (= expected pretty-str))))
(deftest t-custom-pretty-print-with-noident-objects
(let [test-obj [{:foo 1 :bar 2} {:foo 3 :bar 4}]
test-opts {:pretty {:indent-objects? false}}
expected (str "[ { \"foo\" : 1, \"bar\" : 2 }, "
"{ \"foo\" : 3, \"bar\" : 4 } ]")
pretty-str (json/encode test-obj test-opts)]
; just to be easy on the eyes in case of error
(when-not (= expected pretty-str)
(println "; pretty print with options - actual")
(println pretty-str)
(println "; pretty print with options - expected")
(println expected))
(is (= expected pretty-str))))
(deftest t-custom-keyword-fn
(is (= {:FOO "bar"} (json/decode "{\"foo\": \"bar\"}"
(fn [k] (keyword (.toUpperCase k))))))
(is (= {"foo" "bar"} (json/decode "{\"foo\": \"bar\"}" nil)))
(is (= {"foo" "bar"} (json/decode "{\"foo\": \"bar\"}" false)))
(is (= {:foo "bar"} (json/decode "{\"foo\": \"bar\"}" true))))
(deftest t-custom-encode-key-fn
(is (= "{\"FOO\":\"bar\"}"
(json/encode {:foo :bar}
{:key-fn (fn [k] (.toUpperCase (name k)))}))))
;; BB-TEST-PATCH: bb does nto include cheshire.generate ns
#_(deftest test-add-remove-encoder
(gen/remove-encoder java.net.URL)
(gen/add-encoder java.net.URL gen/encode-str)
(is (= "\"http://foo.com\""
(json/encode (java.net.URL. "http://foo.com"))))
(gen/remove-encoder java.net.URL)
(is (thrown? JsonGenerationException
(json/encode (java.net.URL. "http://foo.com")))))
#_(defprotocol TestP
(foo [this] "foo method"))
#_(defrecord TestR [state])
#_(extend TestR
TestP
{:foo (constantly "bar")})
#_(deftest t-custom-protocol-encoder
(let [rec (TestR. :quux)]
(is (= {:state "quux"} (json/decode (json/encode rec) true)))
(gen/add-encoder cheshire.test.core.TestR
(fn [obj jg]
(.writeString jg (foo obj))))
(is (= "bar" (json/decode (json/encode rec))))
(gen/remove-encoder cheshire.test.core.TestR)
(is (= {:state "quux"} (json/decode (json/encode rec) true)))))
#_(defprotocol CTestP
(thing [this] "thing method"))
#_(defrecord CTestR [state])
#_(extend CTestR
CTestP
{:thing (constantly "thing")})
#_(deftest t-custom-helpers
(let [thing (CTestR. :state)
remove #(gen/remove-encoder CTestR)]
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-nil nil jg)))
(is (= nil (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-str "foo" jg)))
(is (= "foo" (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-number 5 jg)))
(is (= 5 (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-long 4 jg)))
(is (= 4 (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-int 3 jg)))
(is (= 3 (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-ratio 1/2 jg)))
(is (= 0.5 (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-seq [:foo :bar] jg)))
(is (= ["foo" "bar"] (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-date (Date. (long 0)) jg)))
(binding [gen/*date-format* "yyyy-MM-dd'T'HH:mm:ss'Z'"]
(is (= "1970-01-01T00:00:00Z" (json/decode (json/encode thing) true))))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-bool true jg)))
(is (= true (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-named :foo jg)))
(is (= "foo" (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-map {:foo "bar"} jg)))
(is (= {:foo "bar"} (json/decode (json/encode thing) true)))
(remove)
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-symbol 'foo jg)))
(is (= "foo" (json/decode (json/encode thing) true)))
(remove)))
(deftest t-float-encoding
(is (= "{\"foo\":0.01}" (json/encode {:foo (float 0.01)}))))
(deftest t-non-const-bools
(is (= {:a 1} (json/decode "{\"a\": 1}" (Boolean. true)))))
;; BB-TEST-PATCH: bb does not include cheshire.exact ns
#_(deftest t-invalid-json
(let [invalid-json-message "Invalid JSON, expected exactly one parseable object but multiple objects were found"]
(are [x y] (= x (try
y
(catch Exception e
(.getMessage e))))
invalid-json-message (json-exact/decode "{\"foo\": 1}asdf")
invalid-json-message (json-exact/decode "{\"foo\": 123}null")
invalid-json-message (json-exact/decode "\"hello\" : 123}")
{"foo" 1} (json/decode "{\"foo\": 1}")
invalid-json-message (json-exact/decode-strict "{\"foo\": 1}asdf")
invalid-json-message (json-exact/decode-strict "{\"foo\": 123}null")
invalid-json-message (json-exact/decode-strict "\"hello\" : 123}")
{"foo" 1} (json/decode-strict "{\"foo\": 1}"))))

View file

@ -1,2 +0,0 @@
{"one":1,"foo":"bar"}
{"two":2,"foo":"bar"}

View file

@ -1,58 +0,0 @@
[
"JSON Test Pattern pass1",
{"object with 1 member":["array with 1 element"]},
{},
[],
-42,
true,
false,
null,
{
"integer": 1234567890,
"real": -9876.543210,
"e": 0.123456789e-12,
"E": 1.234567890E+34,
"": 23456789012E66,
"zero": 0,
"one": 1,
"space": " ",
"quote": "\"",
"backslash": "\\",
"controls": "\b\f\n\r\t",
"slash": "/ & \/",
"alpha": "abcdefghijklmnopqrstuvwyz",
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
"digit": "0123456789",
"0123456789": "digit",
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
"true": true,
"false": false,
"null": null,
"array":[ ],
"object":{ },
"address": "50 St. James Street",
"url": "http://www.JSON.org/",
"comment": "// /* <!-- --",
"# -- --> */": " ",
" s p a c e d " :[1,2 , 3
,
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
"quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
: "A key can be any string"
},
0.5 ,98.6
,
99.44
,
1066,
1e1,
0.1e1,
1e-1,
1e00,2e+00,2e-00
,"rosebud"]

View file

@ -331,7 +331,7 @@
(deftest ^:integration test-http2
(testing "can make an http2 request"
(let [r (get "https://httpbin.org/get" {:as :json})]
(let [r (get "https://nghttp2.org/httpbin/get" {:as :json})]
(is (= :http-2 (:version r))))))
(deftest custom-middleware
@ -341,7 +341,7 @@
(is (= ::response r))))
(try (get "https://httpbin.org/gzip" {:timeout 1000})
(catch Exception _
(catch java.net.http.HttpTimeoutException _
(doseq [v (vals (ns-publics *ns*))]
(when (:integration (meta v))
(println "Removing test from" v "because httpbin is slow.")

View file

@ -1,6 +1,5 @@
(ns httpkit.client-test
(:require [cheshire.core :as json]
[clojure.string :as str]
[clojure.test :refer [deftest is testing #_*report-counters*]]
[org.httpkit.client :as client]))
@ -17,14 +16,12 @@
(deftest get-test
(is (= 200 (:status @(client/get "https://postman-echo.com/get"))))
(is (str/includes?
(is (= "https://postman-echo.com/get"
(-> @(client/get "https://postman-echo.com/get"
{:headers {"Accept" "application/json"}})
:body
(json/parse-string true)
:url)
"postman-echo.com/get"))
;; BB-TEST-PATCH: postman started responding with http:// instead of https://
:url)))
(testing "query params"
(is (= {:foo1 "bar1", :foo2 "bar2"}
(-> @(client/get "https://postman-echo.com/get" {:query-params {"foo1" "bar1" "foo2" "bar2"}})

View file

@ -0,0 +1,549 @@
(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

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

View file

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

View file

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

View file

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

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