Merge branch 'master' into feature-malli
This commit is contained in:
commit
151583e0b5
54 changed files with 1608 additions and 507 deletions
|
|
@ -225,6 +225,95 @@ jobs:
|
||||||
name: Publish artifact link to Slack
|
name: Publish artifact link to Slack
|
||||||
command: |
|
command: |
|
||||||
./bb .circleci/script/publish_artifact.clj || true
|
./bb .circleci/script/publish_artifact.clj || true
|
||||||
|
linux-aarch64:
|
||||||
|
machine:
|
||||||
|
enabled: true
|
||||||
|
image: ubuntu-2004:202101-01
|
||||||
|
resource_class: arm.large
|
||||||
|
working_directory: ~/repo
|
||||||
|
environment:
|
||||||
|
LEIN_ROOT: "true"
|
||||||
|
GRAALVM_HOME: /home/circleci/graalvm-ce-java11-21.0.0
|
||||||
|
BABASHKA_PLATFORM: linux # used in release script
|
||||||
|
BABASHKA_ARCH: aarch64
|
||||||
|
BABASHKA_TEST_ENV: native
|
||||||
|
BABASHKA_XMX: "-J-Xmx6500m"
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: "Pull Submodules"
|
||||||
|
command: |
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
- run:
|
||||||
|
name: "Short circuit on SNAPSHOT"
|
||||||
|
command: |
|
||||||
|
VERSION=$(cat resources/BABASHKA_VERSION)
|
||||||
|
if [[ "$VERSION" == *-SNAPSHOT ]]
|
||||||
|
then
|
||||||
|
circleci task halt
|
||||||
|
fi
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- linux-aarch64-{{ checksum "project.clj" }}-{{ checksum ".circleci/config.yml" }}
|
||||||
|
- run:
|
||||||
|
name: Install Leiningen
|
||||||
|
command: |
|
||||||
|
sudo script/install-leiningen
|
||||||
|
- run:
|
||||||
|
name: Install Clojure
|
||||||
|
command: |
|
||||||
|
wget https://download.clojure.org/install/linux-install-1.10.1.447.sh
|
||||||
|
chmod +x linux-install-1.10.1.447.sh
|
||||||
|
sudo ./linux-install-1.10.1.447.sh
|
||||||
|
- run:
|
||||||
|
name: Install lsof
|
||||||
|
command: |
|
||||||
|
sudo apt-get install lsof
|
||||||
|
- run:
|
||||||
|
name: Install native dev tools
|
||||||
|
command: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get -y install gcc g++ zlib1g-dev
|
||||||
|
- run:
|
||||||
|
name: Download GraalVM
|
||||||
|
command: |
|
||||||
|
cd ~
|
||||||
|
if ! [ -d graalvm-ce-java11-21.0.0 ]; then
|
||||||
|
curl -O -sL https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0/graalvm-ce-java11-linux-aarch64-21.0.0.tar.gz
|
||||||
|
tar xzf graalvm-ce-java11-linux-aarch64-21.0.0.tar.gz
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Build binary
|
||||||
|
command: |
|
||||||
|
script/uberjar
|
||||||
|
script/compile
|
||||||
|
no_output_timeout: 30m
|
||||||
|
- run:
|
||||||
|
name: Run tests
|
||||||
|
command: |
|
||||||
|
script/test
|
||||||
|
script/run_lib_tests
|
||||||
|
- run:
|
||||||
|
name: Release
|
||||||
|
command: |
|
||||||
|
.circleci/script/release
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: /tmp
|
||||||
|
paths:
|
||||||
|
- release
|
||||||
|
- save_cache:
|
||||||
|
paths:
|
||||||
|
- ~/.m2
|
||||||
|
- ~/graalvm-ce-java11-21.0.0
|
||||||
|
key: linux-aarch64-{{ checksum "project.clj" }}-{{ checksum ".circleci/config.yml" }}
|
||||||
|
- store_artifacts:
|
||||||
|
path: /tmp/release
|
||||||
|
destination: release
|
||||||
|
- run:
|
||||||
|
name: Publish artifact link to Slack
|
||||||
|
command: |
|
||||||
|
./bb .circleci/script/publish_artifact.clj || true
|
||||||
mac:
|
mac:
|
||||||
macos:
|
macos:
|
||||||
xcode: "12.0.0"
|
xcode: "12.0.0"
|
||||||
|
|
@ -336,6 +425,7 @@ workflows:
|
||||||
- linux
|
- linux
|
||||||
- linux-static
|
- linux-static
|
||||||
- mac
|
- mac
|
||||||
|
- linux-aarch64
|
||||||
- deploy:
|
- deploy:
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ fi
|
||||||
if [ -z "$CIRCLE_PULL_REQUEST" ] && [ "$CIRCLE_BRANCH" = "master" ]; then
|
if [ -z "$CIRCLE_PULL_REQUEST" ] && [ "$CIRCLE_BRANCH" = "master" ]; then
|
||||||
echo "Building Docker image $image_name:$image_tag"
|
echo "Building Docker image $image_name:$image_tag"
|
||||||
echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USER" --password-stdin
|
echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USER" --password-stdin
|
||||||
unzip "/tmp/release/babashka-${image_tag}-linux-amd64.zip"
|
tar zxvf "/tmp/release/babashka-${image_tag}-linux-amd64.tar.gz"
|
||||||
docker build -t "$image_name" -f Dockerfile.ci .
|
docker build -t "$image_name" -f Dockerfile.ci .
|
||||||
docker tag "$image_name:$latest_tag" "$image_name:$image_tag"
|
docker tag "$image_name:$latest_tag" "$image_name:$image_tag"
|
||||||
rm -f bb
|
rm -f bb
|
||||||
if [[ $snapshot == "false" ]]; then
|
if [[ $snapshot == "false" ]]; then
|
||||||
unzip "/tmp/release/babashka-${image_tag}-linux-static-amd64.zip"
|
tar zxvf "/tmp/release/babashka-${image_tag}-linux-static-amd64.tar.gz"
|
||||||
docker build -t "$image_name:alpine" -f Dockerfile.alpine .
|
docker build -t "$image_name:alpine" -f Dockerfile.alpine .
|
||||||
docker tag "$image_name:alpine" "$image_name:$image_tag-alpine"
|
docker tag "$image_name:alpine" "$image_name:$image_tag-alpine"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
(curl/post slack-hook-url {:headers {"content-type" "application/json"}
|
(curl/post slack-hook-url {:headers {"content-type" "application/json"}
|
||||||
:body json}))))
|
:body json}))))
|
||||||
|
|
||||||
(def release-text (format "[%s - %s@%s]: https://%s-201467090-gh.circle-artifacts.com/0/release/babashka-%s-%s-amd64.zip"
|
(def release-text (format "[%s - %s@%s]: https://%s-201467090-gh.circle-artifacts.com/0/release/babashka-%s-%s-amd64.tar.gz"
|
||||||
(System/getenv "BABASHKA_PLATFORM")
|
(System/getenv "BABASHKA_PLATFORM")
|
||||||
(System/getenv "CIRCLE_BRANCH")
|
(System/getenv "CIRCLE_BRANCH")
|
||||||
(System/getenv "CIRCLE_SHA1")
|
(System/getenv "CIRCLE_SHA1")
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,11 @@ cd /tmp/release
|
||||||
mkdir -p /tmp/bb_size
|
mkdir -p /tmp/bb_size
|
||||||
./bb '(spit "/tmp/bb_size/size" (.length (io/file "bb")))'
|
./bb '(spit "/tmp/bb_size/size" (.length (io/file "bb")))'
|
||||||
|
|
||||||
## release binary as zip archive
|
## release binary as tar.gz archive
|
||||||
|
|
||||||
zip "babashka-$VERSION-$BABASHKA_PLATFORM-amd64.zip" bb # bbk
|
arch=${BABASHKA_ARCH:-amd64}
|
||||||
|
|
||||||
|
tar zcvf "babashka-$VERSION-$BABASHKA_PLATFORM-$arch.tar.gz" bb # bbk
|
||||||
|
|
||||||
## cleanup
|
## cleanup
|
||||||
|
|
||||||
|
|
|
||||||
126
CHANGELOG.md
126
CHANGELOG.md
|
|
@ -2,24 +2,126 @@
|
||||||
|
|
||||||
For a list of breaking changes, check [here](#breaking-changes).
|
For a list of breaking changes, check [here](#breaking-changes).
|
||||||
|
|
||||||
## Unreleased
|
## 0.3.1
|
||||||
|
|
||||||
|
Babashka proper:
|
||||||
|
|
||||||
|
- Support `bb.edn` project config with `:paths` and `:deps`. See [docs](https://book.babashka.org/index.html#_bb_edn).
|
||||||
|
- Rewrite CLI arg parsing to to subcommand style invocations: `bb --uberjar` becomes `bb uberjar`
|
||||||
|
- Support fully qualified symbol in `--main` option [#758](https://github.com/babashka/babashka/issues/758). See [docs](https://book.babashka.org/index.html#_invoking_a_main_function ).
|
||||||
|
- Support new `doc` option to retrieve a docstring from the command line
|
||||||
|
|
||||||
|
Babashka.fs:
|
||||||
|
|
||||||
|
- Create target dir automatically in `copy-tree`
|
||||||
|
|
||||||
|
Babashka.nrepl:
|
||||||
|
|
||||||
|
- Implement `cider-nrepl` `info` / `lookup` op [#30](https://github.com/babashka/babashka.nrepl/issues/30) [(@brdloush)](https://github.com/brdloush)
|
||||||
|
|
||||||
|
Babashka.process:
|
||||||
|
|
||||||
|
- Support tokenizing single string [#39](https://github.com/babashka/process/issues/39)
|
||||||
|
- Support `:extra-env` option [#40](https://github.com/babashka/process/issues/40)
|
||||||
|
|
||||||
|
Deps.clj:
|
||||||
|
|
||||||
|
- Catch up with Clojure CLI 1.10.3.814 [#40](https://github.com/borkdude/deps.clj/issues/40)
|
||||||
|
|
||||||
|
Sci:
|
||||||
|
|
||||||
|
- Support new kwargs handling from 1.11.0 [#553](https://github.com/borkdude/sci/issues/553)
|
||||||
|
- Allow dynamic `:doc` on `def`/`defn` [#554](https://github.com/borkdude/sci/issues/554)
|
||||||
|
|
||||||
|
## 0.3.0
|
||||||
|
|
||||||
|
### New
|
||||||
|
|
||||||
|
- Linux support for AArch64 [#241](https://github.com/babashka/babashka/issues/241). This means you can now run babashka on Raspberry Pi 64bit and Chromebooks with ARM 64-bit processors!
|
||||||
|
|
||||||
|
A major thanks to [CircleCI](https://circleci.com/) for enabling AArch64 support
|
||||||
|
in the babashka organization and [GraalVM](http://graalvm.org/) for supporting this platform.
|
||||||
|
|
||||||
|
### Enhancements / fixes
|
||||||
|
|
||||||
|
- Fix `print-method` when writing to stdout [#667](https://github.com/babashka/babashka/issues/667)
|
||||||
|
- Fix interop with `System/out` [#754](https://github.com/babashka/babashka/issues/754)
|
||||||
|
- Support [version-clj](https://github.com/xsc/version-clj) v2.0.1 by adding `java.util.regex.Matcher` to the reflection config
|
||||||
|
- Distribute linux and macOS archives as `tar.gz`. The reason is that `unzip` is
|
||||||
|
not pre-installed on most unix-y systems. ([@grazfather](https://github.com/grazfather))
|
||||||
|
|
||||||
|
Babashka.fs:
|
||||||
|
|
||||||
|
- Fix globbing on Windows
|
||||||
|
- Fix Windows tests
|
||||||
|
- Fix issue with `copy-tree` when dest dir doesn't exist yet
|
||||||
|
|
||||||
|
Thanks [@lread](https://github.com/lread) for his help on fixing issues with Windows.
|
||||||
|
|
||||||
|
Sci:
|
||||||
|
|
||||||
|
- Support `:reload-all` [#552](https://github.com/borkdude/sci/issues/552)
|
||||||
|
- Narrow `reify` to just one class. See discussion in
|
||||||
|
[sci#549](https://github.com/borkdude/sci/issues/549).
|
||||||
|
- Add preliminary support for `proxy` (mainly to support pathom3 smart maps)
|
||||||
|
[sci#550](https://github.com/borkdude/sci/issues/550).
|
||||||
|
|
||||||
|
Thanks to [@wilkerlucio](https://github.com/wilkerlucio) and
|
||||||
|
[@GreshamDanielStephens](https://github.com/GreshamDanielStephens) for their
|
||||||
|
help and discussions.
|
||||||
|
|
||||||
|
## v0.2.13
|
||||||
|
|
||||||
|
### Enhancements / fixes
|
||||||
|
|
||||||
|
- Add more interfaces to be used with `reify` ([@wilkerlucio](https://github.com/wilkerlucio)) (mostly to support smart maps with [pathom3](https://github.com/wilkerlucio/pathom3))
|
||||||
|
|
||||||
|
Babashka.curl:
|
||||||
|
|
||||||
|
- Use `--data-binary` when sending files or streams [#35](https://github.com/babashka/babashka.curl/issues/35)
|
||||||
|
|
||||||
|
Babashka.fs:
|
||||||
|
|
||||||
|
- Add `create-link` and `split-paths` ([@eamonnsullivan](https://github.com/eamonnsullivan))
|
||||||
|
- Add `split-ext` and `extension` ([@kiramclean](https://github.com/kiramclean))
|
||||||
|
- Add `regular-file?`([@tekacs](https://github.com/tekacs))
|
||||||
|
- Globbing is always recursive but should not be [#18](https://github.com/babashka/fs/issues/18)
|
||||||
|
|
||||||
|
Sci:
|
||||||
|
|
||||||
|
- Allow combinations of interfaces and protocols in `reify` [#540](https://github.com/borkdude/sci/issues/540)
|
||||||
|
([@GreshamDanielStephens](https://github.com/GreshamDanielStephens))
|
||||||
|
- Fix metadata on non-constant map literal expression [#546](https://github.com/borkdude/sci/issues/546)
|
||||||
|
|
||||||
|
## 0.2.12
|
||||||
|
|
||||||
|
### Enhancements / fixes
|
||||||
|
|
||||||
|
- Fix false positive cyclic dep problem with doric lib [#741](https://github.com/babashka/babashka/issues/741)
|
||||||
|
|
||||||
|
## 0.2.11
|
||||||
|
|
||||||
### Enhancements / fixes
|
### Enhancements / fixes
|
||||||
|
|
||||||
- Use default `*print-right-margin*` value from `clojure.pprint`
|
- Use default `*print-right-margin*` value from `clojure.pprint`
|
||||||
|
- Upgrade httpkit to 2.5.3 [#738](https://github.com/babashka/babashka/issues/738)
|
||||||
|
- Upgrade tools.cli to 1.0.206
|
||||||
|
- Add several classes to be used with `defprotocol` (`PersistentVector`, `PersistentHashSet`, ...)
|
||||||
|
- Support reifying `clojure.lang.IFn` and `clojure.lang.ILookup`
|
||||||
|
|
||||||
Sci:
|
Sci:
|
||||||
|
|
||||||
- Detect cyclic load dependencies [#531](https://github.com/babashka/babashka/issues/531)
|
- Detect cyclic load dependencies [#531](https://github.com/borkdude/sci/issues/531)
|
||||||
- Pick fn arity independent of written order [#532](https://github.com/babashka/babashka/issues/532) ([@GreshamDanielStephens](https://github.com/GreshamDanielStephens))
|
- Pick fn arity independent of written order [#532](https://github.com/borkdude/sci/issues/532) ([@GreshamDanielStephens](https://github.com/GreshamDanielStephens))
|
||||||
|
- `(instance? clojure.lang.IAtom 1)` returns `true` [#537](https://github.com/borkdude/sci/issues/537)
|
||||||
Babashka.fs:
|
- Add `dissoc!`([@wilkerlucio](https://github.com/wilkerlucio))
|
||||||
|
- Add `force`
|
||||||
- Add `create-link` and `split-paths`
|
- Fix `ns-unmap` on referred var [#539](https://github.com/borkdude/sci/issues/539)
|
||||||
|
|
||||||
Babashka.nrepl:
|
Babashka.nrepl:
|
||||||
|
|
||||||
- Fix printing in lazy value [#36](https://github.com/babashka/babashka.nrepl/issues/36)
|
- Fix printing in lazy value [#36](https://github.com/babashka/babashka.nrepl/issues/36)
|
||||||
|
- Update link in nREPL server message [#37](https://github.com/babashka/babashka.nrepl/issues/37)
|
||||||
|
|
||||||
## 0.2.10
|
## 0.2.10
|
||||||
|
|
||||||
|
|
@ -44,11 +146,11 @@ Babashka.nrepl:
|
||||||
|
|
||||||
Sci:
|
Sci:
|
||||||
|
|
||||||
- Fix error reporting in case of arity error [#518](https://github.com/babashka/babashka/issues/518)
|
- Fix error reporting in case of arity error [#518](https://github.com/borkdude/sci/issues/518)
|
||||||
- Shadowing record field names in protocol functions [#513](https://github.com/babashka/babashka/issues/513)
|
- Shadowing record field names in protocol functions [#513](https://github.com/borkdude/sci/issues/513)
|
||||||
- Fix destructuring in protocol method for record [#512](https://github.com/babashka/babashka/issues/512)
|
- Fix destructuring in protocol method for record [#512](https://github.com/borkdude/sci/issues/512)
|
||||||
- Faster processing of maps, sets and vectors [#482](https://github.com/babashka/babashka/issues/482)
|
- Faster processing of maps, sets and vectors [#482](https://github.com/borkdude/sci/issues/482)
|
||||||
- Prioritize current namespace vars in syntax quote [#509](https://github.com/babashka/babashka/issues/509)
|
- Prioritize current namespace vars in syntax quote [#509](https://github.com/borkdude/sci/issues/509)
|
||||||
- Fix ns-publics to not include refers [#520](https://github.com/borkdude/sci/issues/520)
|
- Fix ns-publics to not include refers [#520](https://github.com/borkdude/sci/issues/520)
|
||||||
- Add `refer-clojure` macro [#519](https://github.com/borkdude/sci/issues/519)
|
- Add `refer-clojure` macro [#519](https://github.com/borkdude/sci/issues/519)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswit
|
||||||
RUN bb -e "(curl/get \"https://httpstat.us/200\")" # cURL 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 "(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 "(.length \"Hello, Babashka\")" # Java interop test
|
||||||
RUN bb -e "(require '[babashka.pods :as pods]) (pods/load-pod 'org.babashka/sqlite3 \"0.0.1\") (require '[pod.babashka.sqlite3 :as sqlite]) (sqlite/execute! \"/tmp/foo.db\" [\"SELECT 1 + 1\"])" # Pod test
|
RUN bb -e "(require '[babashka.pods :as pods]) (pods/load-pod 'org.babashka/go-sqlite3 \"0.0.1\") (require '[pod.babashka.go-sqlite3 :as sqlite]) (sqlite/execute! \"/tmp/foo.db\" [\"SELECT 1 + 1\"])" # Pod test
|
||||||
|
|
||||||
|
|
||||||
FROM alpine:3
|
FROM alpine:3
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
[](https://opencollective.com/babashka) [](https://clojars.org/babashka/babashka)
|
[](https://opencollective.com/babashka) [](https://clojars.org/babashka/babashka)
|
||||||
[](https://twitter.com/search?q=%23babashka&src=typed_query&f=live)
|
[](https://twitter.com/search?q=%23babashka&src=typed_query&f=live)
|
||||||
|
|
||||||
A Clojure [babushka](https://en.wikipedia.org/wiki/Headscarf) for the grey areas of Bash.
|
|
||||||
|
|
||||||
<blockquote class="twitter-tweet" data-lang="en">
|
<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>
|
<p lang="en" dir="ltr">Life's too short to remember how to write Bash code. I feel liberated.</p>
|
||||||
—
|
—
|
||||||
|
|
@ -15,8 +13,9 @@ A Clojure [babushka](https://en.wikipedia.org/wiki/Headscarf) for the grey areas
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
The main idea behind babashka is to leverage Clojure in places where you would
|
Babashka is a native Clojure interpreter for scripting with fast startup. Its
|
||||||
be using bash otherwise.
|
main goal is to leverage Clojure in places where you would be using bash
|
||||||
|
otherwise.
|
||||||
|
|
||||||
As one user described it:
|
As one user described it:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 33bfad1b844927966a2a681d3e73e4d2a8eae54b
|
Subproject commit e1f33ffa22728553bf2242db5e2a4ca349fab04b
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 15ff3c1b43bfc30e806336547bdb0918f9e2521c
|
Subproject commit 3a790c3d378ddda190d650202cefba9b9930176c
|
||||||
2
deps.clj
2
deps.clj
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0b70844983bf23fff4c2991dadb3fd14c4102b27
|
Subproject commit ca0e98fcefb916c6c0e6fdac73800395b8923af8
|
||||||
16
deps.edn
16
deps.edn
|
|
@ -13,13 +13,13 @@
|
||||||
"depstar/src" "process/src"
|
"depstar/src" "process/src"
|
||||||
"deps.clj/src" "deps.clj/resources"
|
"deps.clj/src" "deps.clj/resources"
|
||||||
"resources" "sci/resources"],
|
"resources" "sci/resources"],
|
||||||
:deps {org.clojure/clojure {:mvn/version "1.10.2"},
|
:deps {org.clojure/clojure {:mvn/version "1.10.3"},
|
||||||
borkdude/sci {:local/root "sci"}
|
borkdude/sci {:local/root "sci"}
|
||||||
babashka/babasha.curl {:local/root "babashka.curl"}
|
babashka/babasha.curl {:local/root "babashka.curl"}
|
||||||
babashka/fs {:local/root "fs"}
|
babashka/fs {:local/root "fs"}
|
||||||
borkdude/graal.locking {:mvn/version "0.0.2"},
|
borkdude/graal.locking {:mvn/version "0.0.2"},
|
||||||
org.clojure/core.async {:mvn/version "1.3.610"},
|
org.clojure/core.async {:mvn/version "1.3.610"},
|
||||||
org.clojure/tools.cli {:mvn/version "1.0.194"},
|
org.clojure/tools.cli {:mvn/version "1.0.206"},
|
||||||
org.clojure/data.csv {:mvn/version "1.0.0"},
|
org.clojure/data.csv {:mvn/version "1.0.0"},
|
||||||
cheshire/cheshire {:mvn/version "5.10.0"}
|
cheshire/cheshire {:mvn/version "5.10.0"}
|
||||||
org.clojure/data.xml {:mvn/version "0.2.0-alpha6"}
|
org.clojure/data.xml {:mvn/version "0.2.0-alpha6"}
|
||||||
|
|
@ -31,13 +31,12 @@
|
||||||
org.postgresql/postgresql {:mvn/version "42.2.18"}
|
org.postgresql/postgresql {:mvn/version "42.2.18"}
|
||||||
org.hsqldb/hsqldb {:mvn/version "2.5.1"}
|
org.hsqldb/hsqldb {:mvn/version "2.5.1"}
|
||||||
datascript/datascript {:mvn/version "1.0.1"}
|
datascript/datascript {:mvn/version "1.0.1"}
|
||||||
http-kit/http-kit {:mvn/version "2.5.1"}
|
http-kit/http-kit {:mvn/version "2.5.3"}
|
||||||
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
|
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
|
||||||
org.clojure/math.combinatorics {:mvn/version "0.1.6"}
|
|
||||||
org.clojure/core.match {:mvn/version "1.0.0"}
|
org.clojure/core.match {:mvn/version "1.0.0"}
|
||||||
hiccup/hiccup {:mvn/version "2.0.0-alpha2"}
|
hiccup/hiccup {:mvn/version "2.0.0-alpha2"}
|
||||||
metosin/malli {:mvn/version "0.3.0-SNAPSHOT"}}
|
metosin/malli {:mvn/version "0.3.0-SNAPSHOT"}}
|
||||||
:aliases {:main
|
:aliases {:babashka/dev
|
||||||
{:main-opts ["-m" "babashka.main"]}
|
{:main-opts ["-m" "babashka.main"]}
|
||||||
:profile
|
:profile
|
||||||
{:extra-deps
|
{:extra-deps
|
||||||
|
|
@ -72,9 +71,12 @@
|
||||||
honeysql/honeysql {:mvn/version "1.0.444"}
|
honeysql/honeysql {:mvn/version "1.0.444"}
|
||||||
minimallist/minimallist {:mvn/version "0.0.6"}
|
minimallist/minimallist {:mvn/version "0.0.6"}
|
||||||
circleci/bond {:mvn/version "0.4.0"}
|
circleci/bond {:mvn/version "0.4.0"}
|
||||||
version-clj/version-clj {:mvn/version "0.1.2"}
|
version-clj/version-clj {:mvn/version "2.0.1"}
|
||||||
gaka/gaka {:mvn/version "0.3.0"}
|
gaka/gaka {:mvn/version "0.3.0"}
|
||||||
failjure/failjure {:mvn/version "2.1.1"}}}
|
failjure/failjure {:mvn/version "2.1.1"}}
|
||||||
|
:classpath-overrides {org.clojure/clojure nil
|
||||||
|
org.clojure/spec.alpha nil
|
||||||
|
org.clojure/core.specs.alpha nil}}
|
||||||
:clj-nvd
|
:clj-nvd
|
||||||
{:extra-deps {clj-nvd/clj-nvd {:git/url "https://github.com/miikka/clj-nvd.git"
|
{:extra-deps {clj-nvd/clj-nvd {:git/url "https://github.com/miikka/clj-nvd.git"
|
||||||
:sha "f2ec98699e057a379baf170cb49cf7ad76874a70"}}
|
:sha "f2ec98699e057a379baf170cb49cf7ad76874a70"}}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ $ git clone https://github.com/babashka/babashka --recursive
|
||||||
To update later on:
|
To update later on:
|
||||||
|
|
||||||
``` shellsession
|
``` shellsession
|
||||||
$ git submodule update --recursive
|
$ git submodule update --init --recursive
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
|
||||||
31
doc/news.md
31
doc/news.md
|
|
@ -5,10 +5,19 @@ you have anything to add. Also see
|
||||||
[#babashka](https://twitter.com/hashtag/babashka?src=hashtag_click&f=live) on
|
[#babashka](https://twitter.com/hashtag/babashka?src=hashtag_click&f=live) on
|
||||||
Twitter.
|
Twitter.
|
||||||
|
|
||||||
|
## 2021-03
|
||||||
|
|
||||||
|
- A `python -m http.server` [replacement in babashka](https://gist.github.com/holyjak/36c6284c047ffb7573e8a34399de27d8)
|
||||||
|
- A [PR](https://github.com/ring-clojure/ring-codec/issues/26) to make `ring-codec` compatible with babashka
|
||||||
|
- The [stuartsierra/component](https://github.com/stuartsierra/component) library [seems to work with babashka](https://github.com/babashka/babashka/issues/742)
|
||||||
|
- [pathom3](https://pathom3.wsscode.com/docs/tutorials/babashka/) works with babashka!
|
||||||
|
|
||||||
## 2021-02
|
## 2021-02
|
||||||
|
|
||||||
- Babashka 0.2.9 released
|
- Babashka 0.2.9 - 0.2.12 released
|
||||||
- [babashka.fs](https://github.com/babashka/fs): utility library for dealing with files (based on java.nio). Bundled with bb 0.2.9.
|
- [babashka.fs](https://github.com/babashka/fs): utility library for dealing with files (based on java.nio). Bundled with bb 0.2.9.
|
||||||
|
- New [Youtube channel](https://www.youtube.com/channel/UCRCl_R1ihLJt7IOgICdb9Lw) with babashka related videos
|
||||||
|
- MS SQL support for the [babashka sql pods](https://github.com/babashka/babashka-sql-pods/)
|
||||||
|
|
||||||
- [Clojure like its PHP](https://eccentric-j.com/blog/clojure-like-its-php.html): run babashka scripts as CGI scripts
|
- [Clojure like its PHP](https://eccentric-j.com/blog/clojure-like-its-php.html): run babashka scripts as CGI scripts
|
||||||
- [Automating Video Edits with Clojure and ffmpeg](https://youtu.be/Tmgy57R9HZM) by Adam James
|
- [Automating Video Edits with Clojure and ffmpeg](https://youtu.be/Tmgy57R9HZM) by Adam James
|
||||||
|
|
@ -19,12 +28,20 @@ Twitter.
|
||||||
lein imitation script built on deps.edn
|
lein imitation script built on deps.edn
|
||||||
- [failjure](https://github.com/adambard/failjure) works with babashka.
|
- [failjure](https://github.com/adambard/failjure) works with babashka.
|
||||||
- A [script](https://gist.github.com/borkdude/58f099b2694d206e6eec18daedc5077b) to solve our mono-repo problem with deps.edn at work.
|
- A [script](https://gist.github.com/borkdude/58f099b2694d206e6eec18daedc5077b) to solve our mono-repo problem with deps.edn at work.
|
||||||
|
- [Single-script vega-lite plotter](https://gist.github.com/vdikan/6b6063d6e1b00a3cd79bc7b3ce3853d6/)
|
||||||
|
- [Find vars with the clj-kondo pod](https://gist.github.com/borkdude/841d85d5ad04c517337166b3928697bd). Also see [video](https://youtu.be/TvBmtGS0KJE).
|
||||||
|
- [Another setup babashka Github action](https://github.com/marketplace/actions/setup-babashka)
|
||||||
|
- [AWS Lambda + babashka + minimal container image](https://gist.github.com/lukaszkorecki/a1fe27bf08f9b98e9def9da4bcb3264e)
|
||||||
|
- [football script](https://gist.github.com/mmzsource/a732950aa43d19c5a9b63bbb7f20b7eb)
|
||||||
|
- [ffclj](https://github.com/luissantos/ffclj): Clojure ffmpeg wrapper
|
||||||
|
- [clj-lineart](https://github.com/eccentric-j/clj-lineart): Generative line art from a clojure-cgi script
|
||||||
|
- [bunpack](https://github.com/robertfw/bunpack): remembers how to unpack things, so you don't have to
|
||||||
|
- A script to download deps for [all `deps.edn` aliases](https://github.com/babashka/babashka/blob/master/examples/download-aliases.clj)
|
||||||
|
|
||||||
## 2021-01
|
## 2021-01
|
||||||
|
|
||||||
Babashka [0.2.8](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v028) released. This includes new libraries: hiccup, core.match and clojure.test.check.
|
- Babashka [0.2.8](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v028) released. This includes new libraries: hiccup, core.match and clojure.test.check.
|
||||||
|
- On 27th of February, Michiel (a.k.a. @borkdude) will do a talk about babashka at the [2021 GraalVM workshop](https://graalworkshop.github.io/2021/).
|
||||||
On 27th of February, Michiel (a.k.a. @borkdude) will do a talk about babashka at the [2021 GraalVM workshop](https://graalworkshop.github.io/2021/).
|
|
||||||
|
|
||||||
- First release of the [aws pod](https://github.com/babashka/pod-babashka-aws).
|
- First release of the [aws pod](https://github.com/babashka/pod-babashka-aws).
|
||||||
- A [script](https://gist.github.com/borkdude/ba372c8cee311e31020b04063d88e1be) to print API breakage warnings.
|
- A [script](https://gist.github.com/borkdude/ba372c8cee311e31020b04063d88e1be) to print API breakage warnings.
|
||||||
|
|
@ -38,16 +55,16 @@ On 27th of February, Michiel (a.k.a. @borkdude) will do a talk about babashka at
|
||||||
|
|
||||||
## 2020-12
|
## 2020-12
|
||||||
|
|
||||||
A new babashka talk: [Babashka and sci
|
- A new babashka talk: [Babashka and sci
|
||||||
internals](https://youtu.be/pgNp4Lk3gf0). Also see
|
internals](https://youtu.be/pgNp4Lk3gf0). Also see
|
||||||
[slides](https://speakerdeck.com/babashka/babashka-and-sci-internals-at-london-clojurians-december-2020)
|
[slides](https://speakerdeck.com/babashka/babashka-and-sci-internals-at-london-clojurians-december-2020)
|
||||||
and [REPL
|
and [REPL
|
||||||
session](https://gist.github.com/borkdude/66a4d844668e12ae1a8277af10d6cc4b).
|
session](https://gist.github.com/borkdude/66a4d844668e12ae1a8277af10d6cc4b).
|
||||||
|
|
||||||
Babashka 0.2.6 released. See [release
|
- Babashka 0.2.6 released. See [release
|
||||||
notes](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v026).
|
notes](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v026).
|
||||||
|
|
||||||
Babashka 0.2.5 released. See [release
|
- Babashka 0.2.5 released. See [release
|
||||||
notes](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v025).
|
notes](https://github.com/babashka/babashka/blob/master/CHANGELOG.md#v025).
|
||||||
|
|
||||||
- First release of the [sqlite pod](https://github.com/babashka/pod-babashka-sqlite3)
|
- First release of the [sqlite pod](https://github.com/babashka/pod-babashka-sqlite3)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ The following libraries and projects are known to work with babashka.
|
||||||
- [environ](#environ)
|
- [environ](#environ)
|
||||||
- [gaka](#gaka)
|
- [gaka](#gaka)
|
||||||
- [failjure](#failjure)
|
- [failjure](#failjure)
|
||||||
|
- [pretty](#pretty)
|
||||||
|
- [clojure-term-colors](#clojure-term-colors)
|
||||||
- [Pods](#pods)
|
- [Pods](#pods)
|
||||||
- [Projects](#projects-1)
|
- [Projects](#projects-1)
|
||||||
- [babashka-test-action](#babashka-test-action)
|
- [babashka-test-action](#babashka-test-action)
|
||||||
|
|
@ -450,6 +452,42 @@ Working with failed computations in Clojure.
|
||||||
(f/fail "foo")
|
(f/fail "foo")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### [pretty](https://github.com/AvisoNovate/pretty)
|
||||||
|
|
||||||
|
The `io.aviso.ansi` namespace provides ANSI font and background color support.
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
(require '[babashka.deps :as deps])
|
||||||
|
|
||||||
|
(deps/add-deps
|
||||||
|
'{:deps {io.aviso/pretty {:mvn/version "0.1.36"}}})
|
||||||
|
|
||||||
|
(require '[io.aviso.ansi :as ansi])
|
||||||
|
|
||||||
|
(println
|
||||||
|
(str "The following text will be "
|
||||||
|
ansi/bold-red-font "bold and red "
|
||||||
|
ansi/reset-font "but this text will not."))
|
||||||
|
```
|
||||||
|
|
||||||
|
### [clojure-term-colors](https://github.com/trhura/clojure-term-colors)
|
||||||
|
|
||||||
|
Clojure ASCII color formatting for terminal output.
|
||||||
|
|
||||||
|
``` clojure
|
||||||
|
(require '[babashka.deps :as deps])
|
||||||
|
|
||||||
|
(deps/add-deps
|
||||||
|
'{:deps {clojure-term-colors/clojure-term-colors {:mvn/version "0.1.0"}}})
|
||||||
|
|
||||||
|
(require '[clojure.term.colors :as c])
|
||||||
|
|
||||||
|
(println
|
||||||
|
(c/yellow "Yellow")
|
||||||
|
(c/red "Red")
|
||||||
|
"No color")
|
||||||
|
```
|
||||||
|
|
||||||
## Pods
|
## Pods
|
||||||
|
|
||||||
[Babashka pods](https://github.com/babashka/babashka.pods) are programs that can
|
[Babashka pods](https://github.com/babashka/babashka.pods) are programs that can
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,37 @@
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
|
- [Examples](#examples)
|
||||||
|
- [Delete a list of files returned by a Unix command](#delete-a-list-of-files-returned-by-a-unix-command)
|
||||||
|
- [Calculate aggregate size of directory](#calculate-aggregate-size-of-directory)
|
||||||
|
- [Shuffle the lines of a file](#shuffle-the-lines-of-a-file)
|
||||||
|
- [Fetch latest Github release tag](#fetch-latest-github-release-tag)
|
||||||
|
- [Generate deps.edn entry for a gitlib](#generate-depsedn-entry-for-a-gitlib)
|
||||||
|
- [View download statistics from Clojars](#view-download-statistics-from-clojars)
|
||||||
|
- [Portable tree command](#portable-tree-command)
|
||||||
|
- [List outdated maven dependencies](#list-outdated-maven-dependencies)
|
||||||
|
- [Convert project.clj to deps.edn](#convert-projectclj-to-depsedn)
|
||||||
|
- [Print current time in California](#print-current-time-in-california)
|
||||||
|
- [Tiny http server](#tiny-http-server)
|
||||||
|
- [Print random docstring](#print-random-docstring)
|
||||||
|
- [Cryptographic hash](#cryptographic-hash)
|
||||||
|
- [Package script as Docker image](#package-script-as-docker-image)
|
||||||
|
- [Extract single file from zip](#extract-single-file-from-zip)
|
||||||
|
- [Note taking app](#note-taking-app)
|
||||||
|
- [which](#which)
|
||||||
|
- [pom.xml version](#pomxml-version)
|
||||||
|
- [Whatsapp frequencies](#whatsapp-frequencies)
|
||||||
|
- [Find unused vars](#find-unused-vars)
|
||||||
|
- [List contents of jar file](#list-contents-of-jar-file)
|
||||||
|
- [Invoke vim inside a script](#invoke-vim-inside-a-script)
|
||||||
|
- [Portal](#portal)
|
||||||
|
- [Image viewer](#image-viewer)
|
||||||
|
- [File server](#file-server)
|
||||||
|
- [Torrent viewer](#torrent-viewer)
|
||||||
|
- [cprop.clj](#cpropclj)
|
||||||
|
- [fzf](#fzf)
|
||||||
|
- [digitalocean-ping.clj](#digitalocean-pingclj)
|
||||||
|
- [download-aliases.clj](#download-aliasesclj)
|
||||||
|
|
||||||
Here's a gallery of useful examples. Do you have a useful example? PR welcome!
|
Here's a gallery of useful examples. Do you have a useful example? PR welcome!
|
||||||
|
|
||||||
## Delete a list of files returned by a Unix command
|
## Delete a list of files returned by a Unix command
|
||||||
|
|
@ -161,7 +193,9 @@ See [examples/pst.clj](https://github.com/babashka/babashka/blob/master/examples
|
||||||
|
|
||||||
## Tiny http server
|
## Tiny http server
|
||||||
|
|
||||||
See [examples/http_server.clj](https://github.com/babashka/babashka/blob/master/examples/http_server.clj)
|
This implements an http server from scratch. Note that babashka comes with `org.httpkit.server` now, so you don't need to build an http server from scratch anymore.
|
||||||
|
|
||||||
|
See [examples/http_server_from_scratch.clj](https://github.com/babashka/babashka/blob/master/examples/http_server_from_scratch.clj)
|
||||||
|
|
||||||
Original by [@souenzzo](https://gist.github.com/souenzzo/a959a4c5b8c0c90df76fe33bb7dfe201)
|
Original by [@souenzzo](https://gist.github.com/souenzzo/a959a4c5b8c0c90df76fe33bb7dfe201)
|
||||||
|
|
||||||
|
|
@ -330,10 +364,22 @@ Opens browser window and lets user navigate through images of all sub-directorie
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
$ examples/image_viewer.clj
|
$ examples/image-viewer.clj
|
||||||
```
|
```
|
||||||
|
|
||||||
See [image_viewer.clj](image_viewer.clj).
|
See [image-viewer.clj](image-viewer.clj).
|
||||||
|
|
||||||
|
## File server
|
||||||
|
|
||||||
|
Opens browser window and lets user navigate through filesystem.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
$ examples/file-server.clj
|
||||||
|
```
|
||||||
|
|
||||||
|
See [file-server.clj](file-server.clj).
|
||||||
|
|
||||||
## Torrent viewer
|
## Torrent viewer
|
||||||
|
|
||||||
|
|
@ -370,18 +416,6 @@ Example usage:
|
||||||
$ cat src/babashka/main.clj | bb examples/fzf.clj
|
$ cat src/babashka/main.clj | bb examples/fzf.clj
|
||||||
```
|
```
|
||||||
|
|
||||||
## [rofi](rofi.clj)
|
|
||||||
|
|
||||||
Invoke [rofi](https://github.com/davatorium/rofi), a type-to-filter menu on linux, from babashka.
|
|
||||||
|
|
||||||
See [rofi.clj](rofi.clj)
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
|
|
||||||
``` shell
|
|
||||||
$ cat src/babashka/main.clj | bb examples/rofi.clj
|
|
||||||
```
|
|
||||||
|
|
||||||
## [digitalocean-ping.clj](digitalocean-ping.clj)
|
## [digitalocean-ping.clj](digitalocean-ping.clj)
|
||||||
|
|
||||||
The script allows to define which DigitalOcean cloud datacenter (region) has best network performance (ping latency).
|
The script allows to define which DigitalOcean cloud datacenter (region) has best network performance (ping latency).
|
||||||
|
|
|
||||||
196
examples/file-server.clj
Executable file
196
examples/file-server.clj
Executable file
|
|
@ -0,0 +1,196 @@
|
||||||
|
#!/usr/bin/env bb
|
||||||
|
#_" -*- mode: clojure; -*-"
|
||||||
|
;; Source: https://gist.github.com/holyjak/36c6284c047ffb7573e8a34399de27d8
|
||||||
|
|
||||||
|
;; Based on https://github.com/babashka/babashka/blob/master/examples/image_viewer.clj
|
||||||
|
(ns file-server
|
||||||
|
(:require [babashka.fs :as fs]
|
||||||
|
[clojure.java.browse :as browse]
|
||||||
|
[clojure.string :as str]
|
||||||
|
[clojure.tools.cli :refer [parse-opts]]
|
||||||
|
[hiccup2.core :as html]
|
||||||
|
[org.httpkit.server :as server])
|
||||||
|
(:import [java.net URLDecoder URLEncoder]))
|
||||||
|
|
||||||
|
(def cli-options [["-p" "--port PORT" "Port for HTTP server" :default 8090 :parse-fn #(Integer/parseInt %)]
|
||||||
|
["-d" "--dir DIR" "Directory to serve files from" :default "."]
|
||||||
|
["-h" "--help" "Print usage info"]])
|
||||||
|
|
||||||
|
(def parsed-args (parse-opts *command-line-args* cli-options))
|
||||||
|
(def opts (:options parsed-args))
|
||||||
|
|
||||||
|
(cond
|
||||||
|
(:help opts)
|
||||||
|
(do (println "Start a http server for static files in the given dir. Usage:\n" (:summary parsed-args))
|
||||||
|
(System/exit 0))
|
||||||
|
|
||||||
|
(:errors parsed-args)
|
||||||
|
(do (println "Invalid arguments:\n" (str/join "\n" (:errors parsed-args)))
|
||||||
|
(System/exit 1))
|
||||||
|
|
||||||
|
:else
|
||||||
|
:continue)
|
||||||
|
|
||||||
|
|
||||||
|
(def port (:port opts))
|
||||||
|
(def dir (fs/path (:dir opts)))
|
||||||
|
|
||||||
|
(assert (fs/directory? dir) (str "The given dir `" dir "` is not a directory."))
|
||||||
|
|
||||||
|
;; A simple mime type utility from https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/mime_type.clj
|
||||||
|
(def ^{:doc "A map of file extensions to mime-types."}
|
||||||
|
default-mime-types
|
||||||
|
{"7z" "application/x-7z-compressed"
|
||||||
|
"aac" "audio/aac"
|
||||||
|
"ai" "application/postscript"
|
||||||
|
"appcache" "text/cache-manifest"
|
||||||
|
"asc" "text/plain"
|
||||||
|
"atom" "application/atom+xml"
|
||||||
|
"avi" "video/x-msvideo"
|
||||||
|
"bin" "application/octet-stream"
|
||||||
|
"bmp" "image/bmp"
|
||||||
|
"bz2" "application/x-bzip"
|
||||||
|
"class" "application/octet-stream"
|
||||||
|
"cer" "application/pkix-cert"
|
||||||
|
"crl" "application/pkix-crl"
|
||||||
|
"crt" "application/x-x509-ca-cert"
|
||||||
|
"css" "text/css"
|
||||||
|
"csv" "text/csv"
|
||||||
|
"deb" "application/x-deb"
|
||||||
|
"dart" "application/dart"
|
||||||
|
"dll" "application/octet-stream"
|
||||||
|
"dmg" "application/octet-stream"
|
||||||
|
"dms" "application/octet-stream"
|
||||||
|
"doc" "application/msword"
|
||||||
|
"dvi" "application/x-dvi"
|
||||||
|
"edn" "application/edn"
|
||||||
|
"eot" "application/vnd.ms-fontobject"
|
||||||
|
"eps" "application/postscript"
|
||||||
|
"etx" "text/x-setext"
|
||||||
|
"exe" "application/octet-stream"
|
||||||
|
"flv" "video/x-flv"
|
||||||
|
"flac" "audio/flac"
|
||||||
|
"gif" "image/gif"
|
||||||
|
"gz" "application/gzip"
|
||||||
|
"htm" "text/html"
|
||||||
|
"html" "text/html"
|
||||||
|
"ico" "image/x-icon"
|
||||||
|
"iso" "application/x-iso9660-image"
|
||||||
|
"jar" "application/java-archive"
|
||||||
|
"jpe" "image/jpeg"
|
||||||
|
"jpeg" "image/jpeg"
|
||||||
|
"jpg" "image/jpeg"
|
||||||
|
"js" "text/javascript"
|
||||||
|
"json" "application/json"
|
||||||
|
"lha" "application/octet-stream"
|
||||||
|
"lzh" "application/octet-stream"
|
||||||
|
"mov" "video/quicktime"
|
||||||
|
"m3u8" "application/x-mpegurl"
|
||||||
|
"m4v" "video/mp4"
|
||||||
|
"mjs" "text/javascript"
|
||||||
|
"mp3" "audio/mpeg"
|
||||||
|
"mp4" "video/mp4"
|
||||||
|
"mpd" "application/dash+xml"
|
||||||
|
"mpe" "video/mpeg"
|
||||||
|
"mpeg" "video/mpeg"
|
||||||
|
"mpg" "video/mpeg"
|
||||||
|
"oga" "audio/ogg"
|
||||||
|
"ogg" "audio/ogg"
|
||||||
|
"ogv" "video/ogg"
|
||||||
|
"pbm" "image/x-portable-bitmap"
|
||||||
|
"pdf" "application/pdf"
|
||||||
|
"pgm" "image/x-portable-graymap"
|
||||||
|
"png" "image/png"
|
||||||
|
"pnm" "image/x-portable-anymap"
|
||||||
|
"ppm" "image/x-portable-pixmap"
|
||||||
|
"ppt" "application/vnd.ms-powerpoint"
|
||||||
|
"ps" "application/postscript"
|
||||||
|
"qt" "video/quicktime"
|
||||||
|
"rar" "application/x-rar-compressed"
|
||||||
|
"ras" "image/x-cmu-raster"
|
||||||
|
"rb" "text/plain"
|
||||||
|
"rd" "text/plain"
|
||||||
|
"rss" "application/rss+xml"
|
||||||
|
"rtf" "application/rtf"
|
||||||
|
"sgm" "text/sgml"
|
||||||
|
"sgml" "text/sgml"
|
||||||
|
"svg" "image/svg+xml"
|
||||||
|
"swf" "application/x-shockwave-flash"
|
||||||
|
"tar" "application/x-tar"
|
||||||
|
"tif" "image/tiff"
|
||||||
|
"tiff" "image/tiff"
|
||||||
|
"ts" "video/mp2t"
|
||||||
|
"ttf" "font/ttf"
|
||||||
|
"txt" "text/plain"
|
||||||
|
"webm" "video/webm"
|
||||||
|
"wmv" "video/x-ms-wmv"
|
||||||
|
"woff" "font/woff"
|
||||||
|
"woff2" "font/woff2"
|
||||||
|
"xbm" "image/x-xbitmap"
|
||||||
|
"xls" "application/vnd.ms-excel"
|
||||||
|
"xml" "text/xml"
|
||||||
|
"xpm" "image/x-xpixmap"
|
||||||
|
"xwd" "image/x-xwindowdump"
|
||||||
|
"zip" "application/zip"})
|
||||||
|
|
||||||
|
;; https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/mime_type.clj
|
||||||
|
(defn- filename-ext
|
||||||
|
"Returns the file extension of a filename or filepath."
|
||||||
|
[filename]
|
||||||
|
(if-let [ext (second (re-find #"\.([^./\\]+)$" filename))]
|
||||||
|
(str/lower-case ext)))
|
||||||
|
|
||||||
|
;; https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/mime_type.clj
|
||||||
|
(defn ext-mime-type
|
||||||
|
"Get the mimetype from the filename extension. Takes an optional map of
|
||||||
|
extensions to mimetypes that overrides values in the default-mime-types map."
|
||||||
|
([filename]
|
||||||
|
(ext-mime-type filename {}))
|
||||||
|
([filename mime-types]
|
||||||
|
(let [mime-types (merge default-mime-types mime-types)]
|
||||||
|
(mime-types (filename-ext filename)))))
|
||||||
|
|
||||||
|
(defn index [f]
|
||||||
|
(let [files (map #(str (.relativize dir %))
|
||||||
|
(fs/list-dir f))]
|
||||||
|
{:body (-> [:html
|
||||||
|
[:head
|
||||||
|
[:meta {:charset "UTF-8"}]
|
||||||
|
[:title (str "Index of `" f "`")]]
|
||||||
|
[:body
|
||||||
|
[:h1 "Index of " [:code (str f)]]
|
||||||
|
[:ul
|
||||||
|
(for [child files]
|
||||||
|
[:li [:a {:href (URLEncoder/encode (str child))} child
|
||||||
|
(when (fs/directory? (fs/path dir child)) "/")]])]
|
||||||
|
[:hr]
|
||||||
|
[:footer {:style {"text-aling" "center"}} "Served by http-server.clj"]]]
|
||||||
|
html/html
|
||||||
|
str)}))
|
||||||
|
|
||||||
|
(defn body [path]
|
||||||
|
{:headers {"Content-Type" (ext-mime-type (fs/file-name path))}
|
||||||
|
:body (fs/file path)})
|
||||||
|
|
||||||
|
(server/run-server
|
||||||
|
(fn [{:keys [:uri]}]
|
||||||
|
(let [f (fs/path dir (str/replace-first (URLDecoder/decode uri) #"^/" ""))
|
||||||
|
index-file (fs/path f "index.html")]
|
||||||
|
(cond
|
||||||
|
(and (fs/directory? f) (fs/readable? index-file))
|
||||||
|
(body index-file)
|
||||||
|
|
||||||
|
(fs/directory? f)
|
||||||
|
(index f)
|
||||||
|
|
||||||
|
(fs/readable? f)
|
||||||
|
(body f)
|
||||||
|
|
||||||
|
:else
|
||||||
|
{:status 404 :body (str "Not found `" f "` in " dir)})))
|
||||||
|
{:port port})
|
||||||
|
|
||||||
|
(println "Starting http server at " port "for" (str dir))
|
||||||
|
(browse/browse-url (format "http://localhost:%s/" port))
|
||||||
|
|
||||||
|
@(promise)
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
#!/usr/bin/env bb
|
#!/usr/bin/env bb
|
||||||
|
|
||||||
;; This example creates a file serving web server
|
;; This example creates a file serving web server from scratch.
|
||||||
;; It accepts a single connection from a browser and serves content to the connected browser
|
;; It accepts a single connection from a browser and serves content to the connected browser
|
||||||
;; after the connection times out, this script will serve no more.
|
;; after the connection times out, this script will serve no more.
|
||||||
;; Also see notes.clj for another web app example.
|
;; Also see notes.clj for another web app example.
|
||||||
|
|
||||||
|
;; Note that babashka comes with org.httpkit.server now, so you don't need to
|
||||||
|
;; build an http server from scratch anymore. We leave this script here for educational purposes.
|
||||||
|
|
||||||
(import (java.net ServerSocket))
|
(import (java.net ServerSocket))
|
||||||
(require '[clojure.java.io :as io]
|
(require '[clojure.java.io :as io]
|
||||||
'[clojure.string :as string])
|
'[clojure.string :as string])
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
#!/usr/bin/env bb
|
#!/usr/bin/env bb
|
||||||
|
|
||||||
(import (java.net ServerSocket))
|
|
||||||
(require '[clojure.java.io :as io]
|
(require '[clojure.java.io :as io]
|
||||||
'[clojure.string :as str])
|
'[clojure.pprint :refer [pprint]]
|
||||||
|
'[clojure.string :as str]
|
||||||
|
'[org.httpkit.server :as server])
|
||||||
|
|
||||||
(def debug? true)
|
(def debug? true)
|
||||||
(def user "admin")
|
(def user "admin")
|
||||||
|
|
@ -35,24 +36,11 @@
|
||||||
(str/join " " (map html v))
|
(str/join " " (map html v))
|
||||||
:else (str v)))
|
:else (str v)))
|
||||||
|
|
||||||
(defn write-response [out session-id status headers content]
|
|
||||||
(let [cookie-header (str "Set-Cookie: notes-id=" session-id)
|
|
||||||
headers (str/join "\r\n" (conj headers cookie-header))
|
|
||||||
response (str "HTTP/1.1 " status "\r\n"
|
|
||||||
(str headers "\r\n")
|
|
||||||
"Content-Length: " (if content (count content)
|
|
||||||
0)
|
|
||||||
"\r\n\r\n"
|
|
||||||
(when content
|
|
||||||
(str content)))]
|
|
||||||
(when debug? (println response))
|
|
||||||
(binding [*out* out]
|
|
||||||
(print response)
|
|
||||||
(flush))))
|
|
||||||
|
|
||||||
;; the home page
|
;; the home page
|
||||||
(defn home-response [out session-id]
|
(defn home-response [session-id]
|
||||||
(let [body (str
|
{:status 200
|
||||||
|
:headers {"Set-Cookie" (str "notes-id=" session-id)}
|
||||||
|
:body (str
|
||||||
"<!DOCTYPE html>\n"
|
"<!DOCTYPE html>\n"
|
||||||
(html
|
(html
|
||||||
[:html
|
[:html
|
||||||
|
|
@ -64,14 +52,7 @@
|
||||||
(slurp notes-file))]
|
(slurp notes-file))]
|
||||||
[:form {:action "/" :method "post"}
|
[:form {:action "/" :method "post"}
|
||||||
[:input {:type "text" :name "note"}]
|
[:input {:type "text" :name "note"}]
|
||||||
[:input {:type "submit" :value "Submit"}]]]]))]
|
[:input {:type "submit" :value "Submit"}]]]]))})
|
||||||
(write-response out session-id "200 OK" nil body)))
|
|
||||||
|
|
||||||
(defn basic-auth-response [out session-id]
|
|
||||||
(write-response out session-id
|
|
||||||
"401 Unauthorized"
|
|
||||||
["WWW-Authenticate: Basic realm=\"notes\""]
|
|
||||||
nil))
|
|
||||||
|
|
||||||
(def known-sessions
|
(def known-sessions
|
||||||
(atom #{}))
|
(atom #{}))
|
||||||
|
|
@ -81,67 +62,54 @@
|
||||||
(swap! known-sessions conj uuid)
|
(swap! known-sessions conj uuid)
|
||||||
uuid))
|
uuid))
|
||||||
|
|
||||||
(defn get-session-id [headers]
|
|
||||||
(if-let [cookie-header (first (filter #(str/starts-with? % "Cookie: ") headers))]
|
|
||||||
(let [parts (str/split cookie-header #"; ")]
|
|
||||||
(if-let [notes-id (first (filter #(str/starts-with? % "notes-id") parts))]
|
|
||||||
(str/replace notes-id "notes-id=" "")
|
|
||||||
(new-session!)))
|
|
||||||
(new-session!)))
|
|
||||||
|
|
||||||
(defn basic-auth-header [headers]
|
|
||||||
(some #(str/starts-with? % "Basic-Auth: ") headers))
|
|
||||||
|
|
||||||
(def authenticated-sessions
|
(def authenticated-sessions
|
||||||
(atom #{}))
|
(atom #{}))
|
||||||
|
|
||||||
(defn authenticate! [session-id headers]
|
(defn authenticate! [session-id headers]
|
||||||
(or (contains? @authenticated-sessions session-id)
|
(or (contains? @authenticated-sessions session-id)
|
||||||
(when (some #(= % (str "Authorization: Basic " base64)) headers)
|
(when (= (headers "authorization") (str "Basic " base64))
|
||||||
(swap! authenticated-sessions conj session-id)
|
(swap! authenticated-sessions conj session-id)
|
||||||
true)))
|
true)))
|
||||||
|
|
||||||
|
(defn parse-session-id [cookie]
|
||||||
|
(when cookie
|
||||||
|
(when-let [notes-id (first (filter #(str/starts-with? % "notes-id")
|
||||||
|
(str/split cookie #"; ")))]
|
||||||
|
(str/replace notes-id "notes-id=" ""))))
|
||||||
|
|
||||||
|
(defn basic-auth-response [session-id]
|
||||||
|
{:status 401
|
||||||
|
:headers {"WWW-Authenticate" "Basic realm=\"notes\""
|
||||||
|
"Set-Cookie" (str "notes-id=" session-id)}})
|
||||||
|
|
||||||
;; run the server
|
;; run the server
|
||||||
(with-open [server-socket (let [s (new ServerSocket 8080)]
|
(defn handler [req]
|
||||||
(println "Server started on port 8080.")
|
(when debug?
|
||||||
s)]
|
(println "Request:")
|
||||||
(loop []
|
(pprint req))
|
||||||
(let [client-socket (.accept server-socket)]
|
(let [body (some-> req :body slurp java.net.URLDecoder/decode)
|
||||||
(future
|
session-id (parse-session-id (get-in req [:headers "cookie"]))
|
||||||
(with-open [conn client-socket]
|
_ (when (and debug? body)
|
||||||
(try
|
(println "Request body:" body))
|
||||||
(let [out (io/writer (.getOutputStream conn))
|
response (cond
|
||||||
is (.getInputStream conn)
|
;; if we didn't see this session before, we want the user to
|
||||||
in (io/reader is)
|
;; re-authenticate
|
||||||
[_req & headers :as response]
|
|
||||||
(loop [headers []]
|
|
||||||
(let [line (.readLine in)]
|
|
||||||
(if (str/blank? line)
|
|
||||||
headers
|
|
||||||
(recur (conj headers line)))))
|
|
||||||
session-id (get-session-id headers)
|
|
||||||
form-data (let [sb (StringBuilder.)]
|
|
||||||
(loop []
|
|
||||||
(when (.ready in)
|
|
||||||
(.append sb (char (.read in)))
|
|
||||||
(recur)))
|
|
||||||
(-> (str sb)
|
|
||||||
(java.net.URLDecoder/decode)))
|
|
||||||
_ (when debug? (println (str/join "\n" response)))
|
|
||||||
_ (when-not (str/blank? form-data)
|
|
||||||
(when debug? (println form-data))
|
|
||||||
(let [note (str/replace form-data "note=" "")]
|
|
||||||
(write-note! note)))
|
|
||||||
_ (when debug? (println))]
|
|
||||||
(cond
|
|
||||||
;; if we didn't see this session before, we want the user to re-authenticate
|
|
||||||
(not (contains? @known-sessions session-id))
|
(not (contains? @known-sessions session-id))
|
||||||
(let [uuid (new-session!)]
|
(basic-auth-response (new-session!))
|
||||||
(basic-auth-response out uuid))
|
|
||||||
(not (authenticate! session-id headers))
|
(not (authenticate! session-id (:headers req)))
|
||||||
(basic-auth-response out session-id)
|
(basic-auth-response session-id)
|
||||||
:else (home-response out session-id)))
|
|
||||||
(catch Throwable t
|
:else (do (when-not (str/blank? body)
|
||||||
(binding [*err* *out*]
|
(let [note (str/replace body "note=" "")]
|
||||||
(println t)))))))
|
(write-note! note)))
|
||||||
(recur)))
|
(home-response session-id)))]
|
||||||
|
(when debug?
|
||||||
|
(println "Response:")
|
||||||
|
(pprint (dissoc response :body))
|
||||||
|
(println))
|
||||||
|
response))
|
||||||
|
|
||||||
|
(server/run-server handler {:port 8080})
|
||||||
|
(println "Server started on port 8080.")
|
||||||
|
@(promise) ;; wait until SIGINT
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
(require '[babashka.process :as p])
|
|
||||||
|
|
||||||
(defn rofi [s]
|
|
||||||
(let [proc (p/process
|
|
||||||
["rofi" "-i" "-dmenu" "-mesg" "Select" "-sync" "-p" "*"]
|
|
||||||
{:in s :err :inherit
|
|
||||||
:out :string})]
|
|
||||||
(:out @proc)))
|
|
||||||
|
|
||||||
(rofi (slurp *in*))
|
|
||||||
|
|
||||||
;; `echo "hi\nthere\nclj" | bb examples/rofi.clj`
|
|
||||||
2
fs
2
fs
|
|
@ -1 +1 @@
|
||||||
Subproject commit caa1cb383329c353114ae24954c52b9d6fa038ea
|
Subproject commit 19c03977282bd63a3ecfd3e6a261a433aa9e8745
|
||||||
32
install
32
install
|
|
@ -64,25 +64,41 @@ case "$(uname -s)" in
|
||||||
Darwin*) platform=macos;;
|
Darwin*) platform=macos;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
download_url="https://github.com/babashka/babashka/releases/download/v$version/babashka-$version-$platform-amd64.zip"
|
case "$(uname -m)" in
|
||||||
|
aarch64) arch=aarch64;;
|
||||||
|
esac
|
||||||
|
arch=${arch:-amd64}
|
||||||
|
|
||||||
|
# Ugly ugly conversion of version to a comparable number
|
||||||
|
IFS='.' read -ra VER <<< "$version"
|
||||||
|
vernum=$(printf "%03d%03d%03d" "${VER[0]}" "${VER[1]}" "${VER[2]}")
|
||||||
|
|
||||||
|
if [[ $vernum -le 000002013 ]]; then
|
||||||
|
ext="zip"
|
||||||
|
util="$(which unzip) -qqo"
|
||||||
|
else
|
||||||
|
ext="tar.gz"
|
||||||
|
util="$(which tar) -zxf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
download_url="https://github.com/babashka/babashka/releases/download/v$version/babashka-$version-$platform-$arch."$ext
|
||||||
|
|
||||||
mkdir -p "$download_dir"
|
mkdir -p "$download_dir"
|
||||||
cd "$download_dir"
|
cd "$download_dir"
|
||||||
echo -e "Downloading $download_url to $download_dir"
|
echo -e "Downloading $download_url to $download_dir"
|
||||||
rm -rf "babashka-$version-$platform-amd64.zip"
|
rm -rf "babashka-$version-$platform-$arch."$ext
|
||||||
rm -rf "bb"
|
rm -rf "bb"
|
||||||
curl -o "babashka-$version-$platform-amd64.zip" -sL "https://github.com/babashka/babashka/releases/download/v$version/babashka-$version-$platform-amd64.zip"
|
curl -o "babashka-$version-$platform-$arch."$ext -sL $download_url
|
||||||
unzip -qqo "babashka-$version-$platform-amd64.zip"
|
$util "babashka-$version-$platform-$arch."$ext
|
||||||
rm "babashka-$version-$platform-amd64.zip"
|
rm "babashka-$version-$platform-$arch."$ext
|
||||||
|
|
||||||
if [ "$download_dir" != "$install_dir" ]
|
if [ "$download_dir" != "$install_dir" ]
|
||||||
then
|
then
|
||||||
mkdir -p "$install_dir"
|
mkdir -p "$install_dir"
|
||||||
cd "$install_dir"
|
if [ -f "$install_dir/bb" ]; then
|
||||||
if [ -f bb ]; then
|
|
||||||
echo "Moving $install_dir/bb to $install_dir/bb.old"
|
echo "Moving $install_dir/bb to $install_dir/bb.old"
|
||||||
fi
|
fi
|
||||||
mv -f "$download_dir/bb" "$PWD/bb"
|
mv -f "$download_dir/bb" "$install_dir/bb"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Successfully installed bb in $install_dir"
|
echo "Successfully installed bb in $install_dir"
|
||||||
|
|
|
||||||
2
pods
2
pods
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0bffce3573d0361cf2592d65cefc8a4048454ff9
|
Subproject commit 82aa3627106181a0ad58c289cd45129603e4fa24
|
||||||
2
process
2
process
|
|
@ -1 +1 @@
|
||||||
Subproject commit f5b531f706fd2b3cfba93c15411d3308e25b5917
|
Subproject commit 692195db27fe411b65e24dbacec75c9f4721a486
|
||||||
12
project.clj
12
project.clj
|
|
@ -17,12 +17,11 @@
|
||||||
:dependencies [[org.clojure/clojure "1.10.2"]
|
:dependencies [[org.clojure/clojure "1.10.2"]
|
||||||
[borkdude/edamame "0.0.11-alpha.29"]
|
[borkdude/edamame "0.0.11-alpha.29"]
|
||||||
[borkdude/graal.locking "0.0.2"]
|
[borkdude/graal.locking "0.0.2"]
|
||||||
[org.clojure/tools.cli "1.0.194"]
|
[org.clojure/tools.cli "1.0.206"]
|
||||||
[cheshire "5.10.0"]
|
[cheshire "5.10.0"]
|
||||||
[nrepl/bencode "1.1.0"]
|
[nrepl/bencode "1.1.0"]
|
||||||
[borkdude/sci.impl.reflector "0.0.1"]
|
[borkdude/sci.impl.reflector "0.0.1"]
|
||||||
[org.clojure/test.check "1.1.0"]
|
[org.clojure/test.check "1.1.0"]]
|
||||||
[org.clojure/math.combinatorics "0.1.6"]]
|
|
||||||
:profiles {:feature/xml {:source-paths ["feature-xml"]
|
:profiles {:feature/xml {:source-paths ["feature-xml"]
|
||||||
:dependencies [[org.clojure/data.xml "0.2.0-alpha6"]]}
|
:dependencies [[org.clojure/data.xml "0.2.0-alpha6"]]}
|
||||||
:feature/yaml {:source-paths ["feature-yaml"]
|
:feature/yaml {:source-paths ["feature-yaml"]
|
||||||
|
|
@ -42,9 +41,9 @@
|
||||||
:feature/datascript {:source-paths ["feature-datascript"]
|
:feature/datascript {:source-paths ["feature-datascript"]
|
||||||
:dependencies [[datascript "1.0.1"]]}
|
:dependencies [[datascript "1.0.1"]]}
|
||||||
:feature/httpkit-client {:source-paths ["feature-httpkit-client"]
|
:feature/httpkit-client {:source-paths ["feature-httpkit-client"]
|
||||||
:dependencies [[http-kit "2.5.1"]]}
|
:dependencies [[http-kit "2.5.3"]]}
|
||||||
:feature/httpkit-server {:source-paths ["feature-httpkit-server"]
|
:feature/httpkit-server {:source-paths ["feature-httpkit-server"]
|
||||||
:dependencies [[http-kit "2.5.1"]]}
|
:dependencies [[http-kit "2.5.3"]]}
|
||||||
:feature/lanterna {:source-paths ["feature-lanterna"]
|
:feature/lanterna {:source-paths ["feature-lanterna"]
|
||||||
:dependencies [[babashka/clojure-lanterna "0.9.8-SNAPSHOT"]]}
|
:dependencies [[babashka/clojure-lanterna "0.9.8-SNAPSHOT"]]}
|
||||||
:feature/core-match {:source-paths ["feature-core-match"]
|
:feature/core-match {:source-paths ["feature-core-match"]
|
||||||
|
|
@ -70,8 +69,7 @@
|
||||||
:feature/hiccup
|
:feature/hiccup
|
||||||
:feature/test-check
|
:feature/test-check
|
||||||
:feature/spec-alpha
|
:feature/spec-alpha
|
||||||
{:dependencies [[clj-commons/conch "0.9.2"]
|
{:dependencies [[com.clojure-goes-fast/clj-async-profiler "0.4.1"]
|
||||||
[com.clojure-goes-fast/clj-async-profiler "0.4.1"]
|
|
||||||
[com.opentable.components/otj-pg-embedded "0.13.3"]]}]
|
[com.opentable.components/otj-pg-embedded "0.13.3"]]}]
|
||||||
:uberjar {:global-vars {*assert* false}
|
:uberjar {:global-vars {*assert* false}
|
||||||
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
|
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
0.2.10
|
0.3.1
|
||||||
|
|
@ -1 +1 @@
|
||||||
0.2.11-SNAPSHOT
|
0.3.2-SNAPSHOT
|
||||||
2
sci
2
sci
|
|
@ -1 +1 @@
|
||||||
Subproject commit 043f5e60d674f5aeee0866e427cef58812ad5547
|
Subproject commit 106919aad41062055828df832acb863080e4b5bd
|
||||||
|
|
@ -60,6 +60,7 @@ args=( "-jar" "$BABASHKA_JAR"
|
||||||
"--no-server"
|
"--no-server"
|
||||||
"--report-unsupported-elements-at-runtime"
|
"--report-unsupported-elements-at-runtime"
|
||||||
"--initialize-at-run-time=org.postgresql.sspi.SSPIClient"
|
"--initialize-at-run-time=org.postgresql.sspi.SSPIClient"
|
||||||
|
"--initialize-at-run-time=org.httpkit.client.ClientSslEngineFactory\$SSLHolder"
|
||||||
"--native-image-info"
|
"--native-image-info"
|
||||||
"--verbose"
|
"--verbose"
|
||||||
"-H:ServiceLoaderFeatureExcludeServices=javax.sound.sampled.spi.AudioFileReader"
|
"-H:ServiceLoaderFeatureExcludeServices=javax.sound.sampled.spi.AudioFileReader"
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ call %GRAALVM_HOME%\bin\native-image.cmd ^
|
||||||
"-H:ReflectionConfigurationFiles=reflection.json" ^
|
"-H:ReflectionConfigurationFiles=reflection.json" ^
|
||||||
"--initialize-at-build-time" ^
|
"--initialize-at-build-time" ^
|
||||||
"--initialize-at-run-time=org.postgresql.sspi.SSPIClient" ^
|
"--initialize-at-run-time=org.postgresql.sspi.SSPIClient" ^
|
||||||
|
"--initialize-at-run-time=org.httpkit.client.ClientSslEngineFactory\$SSLHolder" ^
|
||||||
"-H:EnableURLProtocols=http,https,jar" ^
|
"-H:EnableURLProtocols=http,https,jar" ^
|
||||||
"--enable-all-security-services" ^
|
"--enable-all-security-services" ^
|
||||||
"-H:+JNI" ^
|
"-H:+JNI" ^
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ unset BABASHKA_CLASSPATH
|
||||||
unset BABASHKA_PRELOADS_TEST
|
unset BABASHKA_PRELOADS_TEST
|
||||||
|
|
||||||
echo "running tests part 1"
|
echo "running tests part 1"
|
||||||
lein test "$@"
|
lein "do" clean, test "$@"
|
||||||
|
|
||||||
export BABASHKA_PRELOADS='(defn __bb__foo [] "foo") (defn __bb__bar [] "bar")'
|
export BABASHKA_PRELOADS='(defn __bb__foo [] "foo") (defn __bb__bar [] "bar")'
|
||||||
export BABASHKA_PRELOADS_TEST=true
|
export BABASHKA_PRELOADS_TEST=true
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@
|
||||||
java.io.OutputStream
|
java.io.OutputStream
|
||||||
java.io.FileReader
|
java.io.FileReader
|
||||||
java.io.InputStreamReader
|
java.io.InputStreamReader
|
||||||
|
java.io.OutputStreamWriter
|
||||||
|
java.io.PrintStream
|
||||||
java.io.PushbackInputStream
|
java.io.PushbackInputStream
|
||||||
java.io.Reader
|
java.io.Reader
|
||||||
java.io.SequenceInputStream
|
java.io.SequenceInputStream
|
||||||
|
|
@ -118,6 +120,7 @@
|
||||||
java.lang.Exception
|
java.lang.Exception
|
||||||
java.lang.Float
|
java.lang.Float
|
||||||
java.lang.IllegalArgumentException
|
java.lang.IllegalArgumentException
|
||||||
|
java.lang.IndexOutOfBoundsException
|
||||||
java.lang.Integer
|
java.lang.Integer
|
||||||
java.lang.Iterable
|
java.lang.Iterable
|
||||||
java.lang.Long
|
java.lang.Long
|
||||||
|
|
@ -216,7 +219,7 @@
|
||||||
java.util.jar.JarFile$JarFileEntry
|
java.util.jar.JarFile$JarFileEntry
|
||||||
java.util.stream.Stream
|
java.util.stream.Stream
|
||||||
java.util.Random
|
java.util.Random
|
||||||
;; java.util.regex.Matcher
|
java.util.regex.Matcher
|
||||||
java.util.regex.Pattern
|
java.util.regex.Pattern
|
||||||
java.util.Base64
|
java.util.Base64
|
||||||
java.util.Base64$Decoder
|
java.util.Base64$Decoder
|
||||||
|
|
@ -249,35 +252,58 @@
|
||||||
:methods [borkdude.graal.LockFix] ;; support for locking
|
:methods [borkdude.graal.LockFix] ;; support for locking
|
||||||
|
|
||||||
:fields [clojure.lang.PersistentQueue]
|
:fields [clojure.lang.PersistentQueue]
|
||||||
:instance-checks [clojure.lang.Cons
|
:instance-checks [clojure.lang.APersistentMap ;; for proxy
|
||||||
|
clojure.lang.AMapEntry ;; for proxy
|
||||||
|
clojure.lang.Associative
|
||||||
|
clojure.lang.Atom
|
||||||
|
clojure.lang.Cons
|
||||||
|
clojure.lang.Counted
|
||||||
clojure.lang.Cycle
|
clojure.lang.Cycle
|
||||||
clojure.lang.IObj
|
clojure.lang.IObj
|
||||||
clojure.lang.Fn ;; to distinguish fns from maps, etc.
|
clojure.lang.Fn ;; to distinguish fns from maps, etc.
|
||||||
clojure.lang.IFn
|
clojure.lang.IFn
|
||||||
clojure.lang.IPending
|
clojure.lang.IPending
|
||||||
;; clojure.lang.IDeref
|
;; clojure.lang.IDeref ;; implemented as protocol in sci
|
||||||
;; clojure.lang.IAtom
|
;; clojure.lang.IAtom ;; implemented as protocol in sci
|
||||||
clojure.lang.IEditableCollection
|
clojure.lang.IEditableCollection
|
||||||
clojure.lang.IMapEntry
|
clojure.lang.IMapEntry
|
||||||
|
clojure.lang.IMeta
|
||||||
clojure.lang.ILookup
|
clojure.lang.ILookup
|
||||||
clojure.lang.IPersistentCollection
|
clojure.lang.IPersistentCollection
|
||||||
clojure.lang.IPersistentMap
|
clojure.lang.IPersistentMap
|
||||||
clojure.lang.IPersistentSet
|
clojure.lang.IPersistentSet
|
||||||
;;clojure.lang.PersistentHashSet ;; temp for meander
|
clojure.lang.IPersistentStack
|
||||||
clojure.lang.IPersistentVector
|
clojure.lang.IPersistentVector
|
||||||
clojure.lang.IRecord
|
clojure.lang.IRecord
|
||||||
|
clojure.lang.IReduce
|
||||||
|
clojure.lang.IReduceInit
|
||||||
|
clojure.lang.IKVReduce
|
||||||
clojure.lang.IRef
|
clojure.lang.IRef
|
||||||
clojure.lang.ISeq
|
clojure.lang.ISeq
|
||||||
|
clojure.lang.Indexed
|
||||||
clojure.lang.Iterate
|
clojure.lang.Iterate
|
||||||
clojure.lang.LazySeq
|
clojure.lang.LazySeq
|
||||||
clojure.lang.Named
|
clojure.lang.Named
|
||||||
clojure.lang.Keyword
|
clojure.lang.Keyword
|
||||||
|
clojure.lang.PersistentArrayMap
|
||||||
|
clojure.lang.PersistentHashMap
|
||||||
|
clojure.lang.PersistentHashSet
|
||||||
|
clojure.lang.PersistentList
|
||||||
|
clojure.lang.PersistentQueue
|
||||||
|
clojure.lang.PersistentStructMap
|
||||||
|
clojure.lang.PersistentTreeMap
|
||||||
|
clojure.lang.PersistentTreeSet
|
||||||
|
clojure.lang.PersistentVector
|
||||||
clojure.lang.Ratio
|
clojure.lang.Ratio
|
||||||
clojure.lang.Repeat
|
clojure.lang.Repeat
|
||||||
|
clojure.lang.Reversible
|
||||||
clojure.lang.Symbol
|
clojure.lang.Symbol
|
||||||
clojure.lang.Sequential
|
clojure.lang.Sequential
|
||||||
clojure.lang.Seqable
|
clojure.lang.Seqable
|
||||||
java.util.List]
|
clojure.lang.Volatile
|
||||||
|
java.util.List
|
||||||
|
java.util.Iterator
|
||||||
|
java.util.Map$Entry]
|
||||||
:custom ~custom-map})
|
:custom ~custom-map})
|
||||||
|
|
||||||
(defmacro gen-class-map []
|
(defmacro gen-class-map []
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@
|
||||||
resource-paths)))
|
resource-paths)))
|
||||||
|
|
||||||
(defn path-from-jar
|
(defn path-from-jar
|
||||||
[^java.io.File jar-file resource-paths {:keys [:url?]}]
|
[^java.io.File jar-file resource-paths opts]
|
||||||
|
(let [url? (:url? opts)]
|
||||||
(with-open [jar (JarFile. jar-file)]
|
(with-open [jar (JarFile. jar-file)]
|
||||||
(some (fn [path]
|
(some (fn [path]
|
||||||
(when-let [entry (.getEntry jar path)]
|
(when-let [entry (.getEntry jar path)]
|
||||||
|
|
@ -38,7 +39,7 @@
|
||||||
(str "file:" (.getAbsolutePath jar-file) "!/" path))
|
(str "file:" (.getAbsolutePath jar-file) "!/" path))
|
||||||
{:file path
|
{:file path
|
||||||
:source (slurp (.getInputStream jar entry))})))
|
:source (slurp (.getInputStream jar entry))})))
|
||||||
resource-paths)))
|
resource-paths))))
|
||||||
|
|
||||||
(deftype JarFileResolver [jar-file]
|
(deftype JarFileResolver [jar-file]
|
||||||
IResourceResolver
|
IResourceResolver
|
||||||
|
|
@ -57,8 +58,10 @@
|
||||||
(getResources [_ resource-paths opts]
|
(getResources [_ resource-paths opts]
|
||||||
(keep #(getResource % resource-paths opts) entries)))
|
(keep #(getResource % resource-paths opts) entries)))
|
||||||
|
|
||||||
|
(def path-sep (System/getProperty "path.separator"))
|
||||||
|
|
||||||
(defn loader [^String classpath]
|
(defn loader [^String classpath]
|
||||||
(let [parts (.split classpath (System/getProperty "path.separator"))
|
(let [parts (.split classpath path-sep)
|
||||||
entries (map part->entry parts)]
|
entries (map part->entry parts)]
|
||||||
(Loader. entries)))
|
(Loader. entries)))
|
||||||
|
|
||||||
|
|
@ -88,7 +91,7 @@
|
||||||
(fn [{:keys [:cp]}]
|
(fn [{:keys [:cp]}]
|
||||||
(let [new-cp
|
(let [new-cp
|
||||||
(if-not cp extra-classpath
|
(if-not cp extra-classpath
|
||||||
(str cp (System/getProperty "path.separator") extra-classpath))]
|
(str cp path-sep extra-classpath))]
|
||||||
{:loader (loader new-cp)
|
{:loader (loader new-cp)
|
||||||
:cp new-cp})))
|
:cp new-cp})))
|
||||||
nil)
|
nil)
|
||||||
|
|
@ -96,7 +99,7 @@
|
||||||
(defn split-classpath
|
(defn split-classpath
|
||||||
"Returns the classpath as a seq of strings, split by the platform
|
"Returns the classpath as a seq of strings, split by the platform
|
||||||
specific path separator."
|
specific path separator."
|
||||||
([^String cp] (vec (.split cp (System/getProperty "path.separator")))))
|
([^String cp] (vec (.split cp path-sep))))
|
||||||
|
|
||||||
(defn get-classpath
|
(defn get-classpath
|
||||||
"Returns the current classpath as set by --classpath, BABASHKA_CLASSPATH and add-classpath."
|
"Returns the current classpath as set by --classpath, BABASHKA_CLASSPATH and add-classpath."
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
ret#))
|
ret#))
|
||||||
|
|
||||||
(def data-readers (sci/new-dynamic-var '*data-readers* nil))
|
(def data-readers (sci/new-dynamic-var '*data-readers* nil))
|
||||||
|
(def command-line-args (sci/new-dynamic-var '*command-line-args* nil))
|
||||||
|
(def warn-on-reflection (sci/new-dynamic-var '*warn-on-reflection* false))
|
||||||
|
|
||||||
(defn read+string
|
(defn read+string
|
||||||
"Added for compatibility. Must be used with
|
"Added for compatibility. Must be used with
|
||||||
|
|
@ -59,4 +61,6 @@
|
||||||
'default-data-readers default-data-readers
|
'default-data-readers default-data-readers
|
||||||
'xml-seq (copy-core-var xml-seq)
|
'xml-seq (copy-core-var xml-seq)
|
||||||
'read+string (fn [& args]
|
'read+string (fn [& args]
|
||||||
(apply read+string @common/ctx args))})
|
(apply read+string @common/ctx args))
|
||||||
|
'*command-line-args* command-line-args
|
||||||
|
'*warn-on-reflection* warn-on-reflection})
|
||||||
|
|
|
||||||
|
|
@ -57,11 +57,20 @@
|
||||||
then used to resolve dependencies in babashka."
|
then used to resolve dependencies in babashka."
|
||||||
([deps-map] (add-deps deps-map nil))
|
([deps-map] (add-deps deps-map nil))
|
||||||
([deps-map {:keys [:aliases]}]
|
([deps-map {:keys [:aliases]}]
|
||||||
(let [args ["-Spath" "-Sdeps" (str deps-map)]
|
(when-let [paths (:paths deps-map)]
|
||||||
args (cond-> args
|
(cp/add-classpath (str/join cp/path-sep paths)))
|
||||||
aliases (conj (str "-A:" (str/join ":" aliases))))
|
(when-let [deps-map (not-empty (dissoc deps-map :paths :tasks))]
|
||||||
cp (with-out-str (apply deps/-main args))]
|
(let [deps-map (assoc-in deps-map [:aliases :org.babashka/defaults]
|
||||||
(cp/add-classpath cp))))
|
'{:replace-paths [] ;; babashka sets paths manually
|
||||||
|
:classpath-overrides {org.clojure/clojure ""
|
||||||
|
org.clojure/spec.alpha ""
|
||||||
|
org.clojure/core.specs.alpha ""}})
|
||||||
|
args ["-Spath" "-Sdeps" (str deps-map)]
|
||||||
|
args (conj args (str "-A:" (str/join ":" (cons ":org.babashka/defaults" aliases))))
|
||||||
|
cp (with-out-str (apply deps/-main args))
|
||||||
|
cp (str/trim cp)
|
||||||
|
cp (str/replace cp (re-pattern (str cp/path-sep "+$")) "")]
|
||||||
|
(cp/add-classpath cp)))))
|
||||||
|
|
||||||
(defn clojure
|
(defn clojure
|
||||||
"Starts clojure similar to CLI. Use `rlwrap bb` for `clj`-like invocation.
|
"Starts clojure similar to CLI. Use `rlwrap bb` for `clj`-like invocation.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
'create-dir (sci/copy-var fs/create-dir fns)
|
'create-dir (sci/copy-var fs/create-dir fns)
|
||||||
'create-dirs (sci/copy-var fs/create-dirs fns)
|
'create-dirs (sci/copy-var fs/create-dirs fns)
|
||||||
'create-file (sci/copy-var fs/create-file fns)
|
'create-file (sci/copy-var fs/create-file fns)
|
||||||
|
'create-link (sci/copy-var fs/create-link fns)
|
||||||
'create-sym-link (sci/copy-var fs/create-sym-link fns)
|
'create-sym-link (sci/copy-var fs/create-sym-link fns)
|
||||||
'create-temp-dir (sci/copy-var fs/create-temp-dir fns)
|
'create-temp-dir (sci/copy-var fs/create-temp-dir fns)
|
||||||
'creation-time (sci/copy-var fs/creation-time fns)
|
'creation-time (sci/copy-var fs/creation-time fns)
|
||||||
|
|
@ -37,6 +38,7 @@
|
||||||
'exec-paths (sci/copy-var fs/exec-paths fns)
|
'exec-paths (sci/copy-var fs/exec-paths fns)
|
||||||
'executable? (sci/copy-var fs/executable? fns)
|
'executable? (sci/copy-var fs/executable? fns)
|
||||||
'exists? (sci/copy-var fs/exists? fns)
|
'exists? (sci/copy-var fs/exists? fns)
|
||||||
|
'extension (sci/copy-var fs/extension fns)
|
||||||
'file (sci/copy-var fs/file fns)
|
'file (sci/copy-var fs/file fns)
|
||||||
'file-name (sci/copy-var fs/file-name fns)
|
'file-name (sci/copy-var fs/file-name fns)
|
||||||
'file-separator (sci/copy-var fs/file-separator fns)
|
'file-separator (sci/copy-var fs/file-separator fns)
|
||||||
|
|
@ -62,6 +64,7 @@
|
||||||
'read-attributes (sci/copy-var fs/read-attributes fns)
|
'read-attributes (sci/copy-var fs/read-attributes fns)
|
||||||
'readable? (sci/copy-var fs/readable? fns)
|
'readable? (sci/copy-var fs/readable? fns)
|
||||||
'real-path (sci/copy-var fs/real-path fns)
|
'real-path (sci/copy-var fs/real-path fns)
|
||||||
|
'regular-file? (sci/copy-var fs/regular-file? fns)
|
||||||
'relative? (sci/copy-var fs/relative? fns)
|
'relative? (sci/copy-var fs/relative? fns)
|
||||||
'relativize (sci/copy-var fs/relativize fns)
|
'relativize (sci/copy-var fs/relativize fns)
|
||||||
'same-file? (sci/copy-var fs/same-file? fns)
|
'same-file? (sci/copy-var fs/same-file? fns)
|
||||||
|
|
@ -70,6 +73,7 @@
|
||||||
'set-last-modified-time (sci/copy-var fs/set-last-modified-time fns)
|
'set-last-modified-time (sci/copy-var fs/set-last-modified-time fns)
|
||||||
'set-posix-file-permissions (sci/copy-var fs/set-posix-file-permissions fns)
|
'set-posix-file-permissions (sci/copy-var fs/set-posix-file-permissions fns)
|
||||||
'size (sci/copy-var fs/size fns)
|
'size (sci/copy-var fs/size fns)
|
||||||
|
'split-ext (sci/copy-var fs/split-ext fns)
|
||||||
'split-paths (sci/copy-var fs/split-paths fns)
|
'split-paths (sci/copy-var fs/split-paths fns)
|
||||||
'starts-with? (sci/copy-var fs/starts-with? fns)
|
'starts-with? (sci/copy-var fs/starts-with? fns)
|
||||||
'str->posix (sci/copy-var fs/str->posix fns)
|
'str->posix (sci/copy-var fs/str->posix fns)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@
|
||||||
'start (copy-var process/start tns)
|
'start (copy-var process/start tns)
|
||||||
'pipeline (copy-var process/pipeline tns)
|
'pipeline (copy-var process/pipeline tns)
|
||||||
'$ (copy-var process/$ tns)
|
'$ (copy-var process/$ tns)
|
||||||
|
'sh (copy-var process/sh tns)
|
||||||
|
'tokenize (copy-var process/tokenize tns)
|
||||||
'*defaults* defaults
|
'*defaults* defaults
|
||||||
'destroy (copy-var process/destroy tns)
|
'destroy (copy-var process/destroy tns)
|
||||||
'destroy-tree (copy-var process/destroy-tree tns)})
|
'destroy-tree (copy-var process/destroy-tree tns)})
|
||||||
|
|
|
||||||
60
src/babashka/impl/proxy.clj
Normal file
60
src/babashka/impl/proxy.clj
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
(ns babashka.impl.proxy
|
||||||
|
{:no-doc true}
|
||||||
|
(:require [sci.impl.types]))
|
||||||
|
|
||||||
|
(set! *warn-on-reflection* false)
|
||||||
|
|
||||||
|
(defn method-or-bust [methods k]
|
||||||
|
(or (get methods k)
|
||||||
|
(throw (UnsupportedOperationException. (str "Method not implemented: " k)))))
|
||||||
|
|
||||||
|
(defn class-name [^Class clazz]
|
||||||
|
(.getName clazz))
|
||||||
|
|
||||||
|
(defn proxy-fn [{:keys [class interfaces protocols methods]}]
|
||||||
|
(let [interface-names (set (map class-name interfaces))]
|
||||||
|
(case [(class-name class) interface-names]
|
||||||
|
;; This combination is used by pathom3
|
||||||
|
["clojure.lang.APersistentMap" #{"clojure.lang.IMeta" "clojure.lang.IObj"}]
|
||||||
|
(proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj sci.impl.types.IReified] []
|
||||||
|
(getInterfaces []
|
||||||
|
interfaces)
|
||||||
|
(getMethods []
|
||||||
|
methods)
|
||||||
|
(getProtocols []
|
||||||
|
protocols)
|
||||||
|
(iterator [] ((method-or-bust methods 'iterator) this))
|
||||||
|
(containsKey [k] ((method-or-bust methods 'containsKey) this k))
|
||||||
|
(entryAt [k] ((method-or-bust methods 'entryAt) this k))
|
||||||
|
(valAt
|
||||||
|
([k]
|
||||||
|
((method-or-bust methods 'valAt) this k))
|
||||||
|
([k default] ((method-or-bust methods 'valAt) this k default)))
|
||||||
|
(cons [v]
|
||||||
|
(if-let [m (get methods 'cons)]
|
||||||
|
(m this v)
|
||||||
|
(proxy-super cons v)))
|
||||||
|
(count [] ((method-or-bust methods 'count) this))
|
||||||
|
(assoc [k v] ((method-or-bust methods 'assoc) this k v))
|
||||||
|
(without [k] ((method-or-bust methods 'without) this k))
|
||||||
|
(seq [] ((method-or-bust methods 'seq) this))
|
||||||
|
|
||||||
|
(equiv [other]
|
||||||
|
(if-let [m (get methods 'equiv)]
|
||||||
|
(m this other)
|
||||||
|
(proxy-super equiv other)))
|
||||||
|
(empty [] ((method-or-bust methods 'empty) this))
|
||||||
|
|
||||||
|
(meta [] ((method-or-bust methods 'meta) this))
|
||||||
|
(withMeta [meta] ((method-or-bust methods 'withMeta) this meta))
|
||||||
|
|
||||||
|
(toString []
|
||||||
|
(if-let [m (get methods 'toString)]
|
||||||
|
(m this)
|
||||||
|
(proxy-super toString))))
|
||||||
|
["clojure.lang.AMapEntry" #{}]
|
||||||
|
(proxy [clojure.lang.AMapEntry] []
|
||||||
|
(key [] ((method-or-bust methods 'key) this))
|
||||||
|
(val [] ((method-or-bust methods 'val) this))
|
||||||
|
(getKey [] ((method-or-bust methods 'getKey) this))
|
||||||
|
(getValue [] ((method-or-bust methods 'getValue) this))))))
|
||||||
|
|
@ -1,40 +1,153 @@
|
||||||
(ns babashka.impl.reify
|
(ns babashka.impl.reify
|
||||||
{:no-doc true}
|
{:no-doc true}
|
||||||
(:require [clojure.math.combinatorics :as combo]))
|
(:require [sci.impl.types]))
|
||||||
|
|
||||||
(set! *warn-on-reflection* false)
|
(set! *warn-on-reflection* false)
|
||||||
|
|
||||||
|
;; Notes
|
||||||
|
|
||||||
|
;; We abandoned the 'one reify object that implements all interfaces' approach
|
||||||
|
;; due to false positives. E.g. when you would print a reified object, you would
|
||||||
|
;; get: 'Not implemented: seq', because print-method thought this object was
|
||||||
|
;; seqable, while in fact, it wasn't.
|
||||||
|
|
||||||
|
(defn method-or-bust [methods k]
|
||||||
|
(or (get methods k)
|
||||||
|
(throw (UnsupportedOperationException. "Method not implemented: " k))))
|
||||||
|
|
||||||
(defmacro gen-reify-combos
|
(defmacro gen-reify-combos
|
||||||
"Generates pre-compiled reify combinations"
|
"Generates pre-compiled reify combinations"
|
||||||
[methods]
|
[methods]
|
||||||
(let [subsets (rest (combo/subsets (seq methods)))]
|
(let [prelude '(reify
|
||||||
(reduce (fn [opts classes]
|
sci.impl.types.IReified
|
||||||
(assoc opts
|
(getInterfaces [this]
|
||||||
(set (map (fn [[class _]]
|
interfaces)
|
||||||
(list 'quote class))
|
(getMethods [this]
|
||||||
classes))
|
methods)
|
||||||
(list 'fn ['methods]
|
(getProtocols [this]
|
||||||
(list* 'reify
|
protocols))]
|
||||||
(mapcat
|
(list 'fn [{:keys '[interfaces methods protocols]}]
|
||||||
|
`(cond ~'(empty? interfaces) ~prelude ~'(> (count interfaces)
|
||||||
|
1) (throw (new Exception "Babashka currently does not support reifying more than one interface."))
|
||||||
|
:else
|
||||||
|
(case (.getName ~(with-meta '(first interfaces)
|
||||||
|
{:tag 'Class}))
|
||||||
|
~@(mapcat
|
||||||
(fn [[clazz methods]]
|
(fn [[clazz methods]]
|
||||||
|
(list
|
||||||
|
(str clazz)
|
||||||
|
(concat prelude
|
||||||
(cons clazz
|
(cons clazz
|
||||||
|
(mapcat
|
||||||
|
(fn [[meth arities]]
|
||||||
(map
|
(map
|
||||||
(fn [[meth args]]
|
(fn [arity]
|
||||||
(list meth args
|
(list meth arity
|
||||||
(list*
|
(list*
|
||||||
(list 'get-in 'methods
|
(list 'or (list 'get 'methods (list 'quote meth))
|
||||||
[(list 'quote clazz) (list 'quote meth)])
|
`(throw (new Exception (str "Not implemented: "
|
||||||
args)))
|
~(str meth)))))
|
||||||
methods)))
|
arity)))
|
||||||
classes)))))
|
arities))
|
||||||
{}
|
methods)))))
|
||||||
subsets)))
|
methods))))))
|
||||||
|
|
||||||
|
;; (require 'clojure.pprint)
|
||||||
|
;; (clojure.pprint/pprint
|
||||||
|
;; (macroexpand '(gen-reify-combos {java.nio.file.FileVisitor
|
||||||
|
;; {preVisitDirectory [[this p attrs]]
|
||||||
|
;; postVisitDirectory [[this p attrs]]
|
||||||
|
;; visitFile [[this p attrs]]}})))
|
||||||
|
|
||||||
#_:clj-kondo/ignore
|
#_:clj-kondo/ignore
|
||||||
(def reify-opts
|
(def reify-fn
|
||||||
(gen-reify-combos
|
(gen-reify-combos
|
||||||
{java.nio.file.FileVisitor {preVisitDirectory [this p attrs]
|
{java.lang.Object
|
||||||
postVisitDirectory [this p attrs]
|
{toString [[this]]}
|
||||||
visitFile [this p attrs]}
|
java.nio.file.FileVisitor
|
||||||
java.io.FileFilter {accept [this f]}
|
{preVisitDirectory [[this p attrs]]
|
||||||
java.io.FilenameFilter {accept [this f s]}}))
|
postVisitDirectory [[this p attrs]]
|
||||||
|
visitFile [[this p attrs]]}
|
||||||
|
|
||||||
|
java.io.FileFilter
|
||||||
|
{accept [[this f]]}
|
||||||
|
|
||||||
|
java.io.FilenameFilter
|
||||||
|
{accept [[this f s]]}
|
||||||
|
|
||||||
|
clojure.lang.Associative
|
||||||
|
{containsKey [[this k]]
|
||||||
|
entryAt [[this k]]
|
||||||
|
assoc [[this k v]]}
|
||||||
|
|
||||||
|
clojure.lang.ILookup
|
||||||
|
{valAt [[this k] [this k default]]}
|
||||||
|
|
||||||
|
java.util.Map$Entry
|
||||||
|
{getKey [[this]]
|
||||||
|
getValue [[this]]}
|
||||||
|
|
||||||
|
clojure.lang.IFn
|
||||||
|
{applyTo [[this arglist]]
|
||||||
|
invoke [[this]
|
||||||
|
[this a1]
|
||||||
|
[this a1 a2]
|
||||||
|
[this a1 a2 a3]
|
||||||
|
[this a1 a2 a3 a4]
|
||||||
|
[this a1 a2 a3 a4 a5]
|
||||||
|
[this a1 a2 a3 a4 a5 a6]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20]
|
||||||
|
[this a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 varargs]]}
|
||||||
|
|
||||||
|
clojure.lang.IPersistentCollection
|
||||||
|
{count [[this]]
|
||||||
|
cons [[this x]]
|
||||||
|
empty [[this]]
|
||||||
|
equiv [[this x]]}
|
||||||
|
|
||||||
|
clojure.lang.IReduce
|
||||||
|
{reduce [[this f]]}
|
||||||
|
|
||||||
|
clojure.lang.IReduceInit
|
||||||
|
{reduce [[this f initial]]}
|
||||||
|
|
||||||
|
clojure.lang.IKVReduce
|
||||||
|
{kvreduce [[this f initial]]}
|
||||||
|
|
||||||
|
clojure.lang.Indexed
|
||||||
|
{nth [[this n] [this n not-found]]}
|
||||||
|
|
||||||
|
clojure.lang.IPersistentMap
|
||||||
|
{assocEx [[this k v]]
|
||||||
|
without [[this k]]}
|
||||||
|
|
||||||
|
clojure.lang.IPersistentStack
|
||||||
|
{peek [[this]]
|
||||||
|
pop [[this]]}
|
||||||
|
|
||||||
|
clojure.lang.Reversible
|
||||||
|
{rseq [[this]]}
|
||||||
|
|
||||||
|
clojure.lang.Seqable
|
||||||
|
{seq [[this]]}
|
||||||
|
|
||||||
|
java.lang.Iterable
|
||||||
|
{iterator [[this]]
|
||||||
|
forEach [[this action]]}
|
||||||
|
|
||||||
|
java.util.Iterator
|
||||||
|
{hasNext [[this]]
|
||||||
|
next [[this]]}}))
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
{:no-doc true}
|
{:no-doc true}
|
||||||
(:refer-clojure :exclude [error-handler])
|
(:refer-clojure :exclude [error-handler])
|
||||||
(:require
|
(:require
|
||||||
|
[babashka.fs :as fs]
|
||||||
[babashka.impl.bencode :refer [bencode-namespace]]
|
[babashka.impl.bencode :refer [bencode-namespace]]
|
||||||
[babashka.impl.cheshire :refer [cheshire-core-namespace]]
|
[babashka.impl.cheshire :refer [cheshire-core-namespace]]
|
||||||
[babashka.impl.classes :as classes]
|
[babashka.impl.classes :as classes]
|
||||||
|
|
@ -26,7 +27,8 @@
|
||||||
[babashka.impl.pprint :refer [pprint-namespace]]
|
[babashka.impl.pprint :refer [pprint-namespace]]
|
||||||
[babashka.impl.process :refer [process-namespace]]
|
[babashka.impl.process :refer [process-namespace]]
|
||||||
[babashka.impl.protocols :refer [protocols-namespace]]
|
[babashka.impl.protocols :refer [protocols-namespace]]
|
||||||
[babashka.impl.reify :refer [reify-opts]]
|
[babashka.impl.proxy :refer [proxy-fn]]
|
||||||
|
[babashka.impl.reify :refer [reify-fn]]
|
||||||
[babashka.impl.repl :as repl]
|
[babashka.impl.repl :as repl]
|
||||||
[babashka.impl.socket-repl :as socket-repl]
|
[babashka.impl.socket-repl :as socket-repl]
|
||||||
[babashka.impl.test :as t]
|
[babashka.impl.test :as t]
|
||||||
|
|
@ -73,161 +75,74 @@
|
||||||
;; echo '1' | java -agentlib:native-image-agent=config-output-dir=/tmp -jar target/babashka-xxx-standalone.jar '...'
|
;; echo '1' | java -agentlib:native-image-agent=config-output-dir=/tmp -jar target/babashka-xxx-standalone.jar '...'
|
||||||
;; with the java provided by GraalVM.
|
;; with the java provided by GraalVM.
|
||||||
|
|
||||||
(defn parse-opts [options]
|
|
||||||
(let [opts (loop [options options
|
|
||||||
opts-map {}]
|
|
||||||
(if options
|
|
||||||
(let [opt (first options)]
|
|
||||||
(case opt
|
|
||||||
("--") (assoc opts-map :command-line-args (next options))
|
|
||||||
("--clojure") (assoc opts-map :clojure true
|
|
||||||
:opts (rest options))
|
|
||||||
("--version") {:version true}
|
|
||||||
("--help" "-h" "-?") {:help? true}
|
|
||||||
("--verbose")(recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:verbose? true))
|
|
||||||
("--describe") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:describe? true))
|
|
||||||
("--stream") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:stream? true))
|
|
||||||
("-i") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:shell-in true))
|
|
||||||
("-I") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:edn-in true))
|
|
||||||
("-o") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:shell-out true))
|
|
||||||
("-O") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:edn-out true))
|
|
||||||
("-io") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:shell-in true
|
|
||||||
:shell-out true))
|
|
||||||
("-iO") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:shell-in true
|
|
||||||
:edn-out true))
|
|
||||||
("-Io") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:edn-in true
|
|
||||||
:shell-out true))
|
|
||||||
("-IO") (recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:edn-in true
|
|
||||||
:edn-out true))
|
|
||||||
("--classpath", "-cp")
|
|
||||||
(let [options (next options)]
|
|
||||||
(recur (next options)
|
|
||||||
(assoc opts-map :classpath (first options))))
|
|
||||||
("--uberscript")
|
|
||||||
(let [options (next options)]
|
|
||||||
(recur (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:uberscript (first options))))
|
|
||||||
("--uberjar")
|
|
||||||
(let [options (next options)]
|
|
||||||
(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 (next options)
|
|
||||||
(assoc opts-map
|
|
||||||
:repl true)))
|
|
||||||
("--socket-repl")
|
|
||||||
(let [options (next options)
|
|
||||||
opt (first options)
|
|
||||||
opt (when (and opt (not (str/starts-with? opt "-")))
|
|
||||||
opt)
|
|
||||||
options (if opt (next options)
|
|
||||||
options)]
|
|
||||||
(recur options
|
|
||||||
(assoc opts-map
|
|
||||||
:socket-repl (or opt "1666"))))
|
|
||||||
("--nrepl-server")
|
|
||||||
(let [options (next options)
|
|
||||||
opt (first options)
|
|
||||||
opt (when (and opt (not (str/starts-with? opt "-")))
|
|
||||||
opt)
|
|
||||||
options (if opt (next options)
|
|
||||||
options)]
|
|
||||||
(recur options
|
|
||||||
(assoc opts-map
|
|
||||||
:nrepl (or opt "1667"))))
|
|
||||||
("--eval", "-e")
|
|
||||||
(let [options (next options)]
|
|
||||||
(recur (next options)
|
|
||||||
(update opts-map :expressions (fnil conj []) (first options))))
|
|
||||||
("--main", "-m")
|
|
||||||
(let [options (next options)]
|
|
||||||
(recur (next options)
|
|
||||||
(assoc opts-map :main (first options))))
|
|
||||||
(if (some opts-map [:file :jar :socket-repl :expressions :main])
|
|
||||||
(assoc opts-map
|
|
||||||
:command-line-args options)
|
|
||||||
(let [trimmed-opt (str/triml opt)
|
|
||||||
c (.charAt trimmed-opt 0)]
|
|
||||||
(case c
|
|
||||||
(\( \{ \[ \* \@ \#)
|
|
||||||
(-> opts-map
|
|
||||||
(update :expressions (fnil conj []) (first options))
|
|
||||||
(assoc :command-line-args (next options)))
|
|
||||||
(assoc opts-map
|
|
||||||
(if (str/ends-with? opt ".jar")
|
|
||||||
:jar :file) opt
|
|
||||||
:command-line-args (next options)))))))
|
|
||||||
opts-map))]
|
|
||||||
opts))
|
|
||||||
|
|
||||||
(def version (str/trim (slurp (io/resource "BABASHKA_VERSION"))))
|
(def version (str/trim (slurp (io/resource "BABASHKA_VERSION"))))
|
||||||
|
|
||||||
(defn print-version []
|
(defn print-version []
|
||||||
(println (str "babashka v" version)))
|
(println (str "babashka v" version)))
|
||||||
|
|
||||||
|
(def bb-edn
|
||||||
|
(volatile! nil))
|
||||||
|
|
||||||
(defn print-help []
|
(defn command? [x]
|
||||||
|
(case x
|
||||||
|
("clojure"
|
||||||
|
"version"
|
||||||
|
"help"
|
||||||
|
"doc"
|
||||||
|
"tasks"
|
||||||
|
"uberjar"
|
||||||
|
"uberscript"
|
||||||
|
"repl"
|
||||||
|
"socket-repl"
|
||||||
|
"nrepl-server"
|
||||||
|
"describe") true
|
||||||
|
false))
|
||||||
|
|
||||||
|
(defn print-error [& msgs]
|
||||||
|
(binding [*out* *err*]
|
||||||
|
(apply println msgs)))
|
||||||
|
|
||||||
|
(defn print-help [_ctx _command-line-args]
|
||||||
(println (str "Babashka v" version))
|
(println (str "Babashka v" version))
|
||||||
;; (println (str "sci v" (str/trim (slurp (io/resource "SCI_VERSION")))))
|
|
||||||
(println)
|
|
||||||
(println "Options must appear in the order of groups mentioned below.")
|
|
||||||
(println "
|
(println "
|
||||||
Help:
|
Usage: bb [classpath opts] [eval opts] [cmdline args]
|
||||||
|
or: bb [classpath opts] file [cmdline args]
|
||||||
|
or: bb [classpath opts] subcommand [subcommand opts] [cmdline args]
|
||||||
|
|
||||||
--help, -h or -? Print this help text.
|
Classpath:
|
||||||
--version Print the current version of babashka.
|
|
||||||
--describe Print an EDN map with information about this version of babashka.
|
-cp, --classpath Classpath to use. Overrides bb.edn classpath.
|
||||||
|
|
||||||
Evaluation:
|
Evaluation:
|
||||||
|
|
||||||
-e, --eval <expr> Evaluate an expression.
|
-e, --eval <expr> Evaluate an expression.
|
||||||
-f, --file <path> Evaluate a file.
|
-f, --file <path> Evaluate a file.
|
||||||
-cp, --classpath Classpath to use.
|
-m, --main <ns|var> Call the -main function from a namespace or call a fully qualified var.
|
||||||
-m, --main <ns> Call the -main function from namespace with args.
|
|
||||||
--verbose Print debug information and entire stacktrace in case of exception.
|
--verbose Print debug information and entire stacktrace in case of exception.
|
||||||
|
|
||||||
|
Help:
|
||||||
|
|
||||||
|
help, -h or -? Print this help text.
|
||||||
|
version Print the current version of babashka.
|
||||||
|
describe Print an EDN map with information about this version of babashka.
|
||||||
|
doc <var|ns> Print docstring of var or namespace. Requires namespace if necessary.
|
||||||
|
|
||||||
REPL:
|
REPL:
|
||||||
|
|
||||||
--repl Start REPL. Use rlwrap for history.
|
repl Start REPL. Use rlwrap for history.
|
||||||
--socket-repl Start socket REPL. Specify port (e.g. 1666) or host and port separated by colon (e.g. 127.0.0.1:1666).
|
socket-repl [addr] Start a socket REPL. Addr opt defaults to localhost:1666.
|
||||||
--nrepl-server Start nREPL server. Specify port (e.g. 1667) or host and port separated by colon (e.g. 127.0.0.1:1667).
|
nrepl-server [addr] Start nREPL server. Address option defaults to locahost:1667.
|
||||||
|
|
||||||
In- and output flags:
|
Clojure:
|
||||||
|
|
||||||
|
clojure [args...] Invokes clojure. Takes same args as the official clojure CLI.
|
||||||
|
|
||||||
|
Packaging:
|
||||||
|
|
||||||
|
uberscript <file> [eval-opt] Collect all required namespaces from the classpath into a single file. Accepts additional eval opts, like `-m`.
|
||||||
|
uberjar <jar> [eval-opt] Similar to uberscript but creates jar file.
|
||||||
|
|
||||||
|
In- and output flags (only to be used with -e one-liners):
|
||||||
|
|
||||||
-i Bind *input* to a lazy seq of lines from stdin.
|
-i Bind *input* to a lazy seq of lines from stdin.
|
||||||
-I Bind *input* to a lazy seq of EDN values from stdin.
|
-I Bind *input* to a lazy seq of EDN values from stdin.
|
||||||
|
|
@ -235,23 +150,26 @@ In- and output flags:
|
||||||
-O Write EDN values to stdout.
|
-O Write EDN values to stdout.
|
||||||
--stream Stream over lines or EDN values from stdin. Combined with -i or -I *input* becomes a single value per iteration.
|
--stream Stream over lines or EDN values from stdin. Combined with -i or -I *input* becomes a single value per iteration.
|
||||||
|
|
||||||
Uberscript:
|
File names take precedence over subcommand names.
|
||||||
|
Remaining arguments are bound to *command-line-args*.
|
||||||
--uberscript <file> Collect preloads, -e, -f and -m and all required namespaces from the classpath into a single file.
|
|
||||||
|
|
||||||
Uberjar:
|
|
||||||
|
|
||||||
--uberjar <jar> Similar to --uberscript but creates jar file.
|
|
||||||
|
|
||||||
Clojure:
|
|
||||||
|
|
||||||
--clojure [args...] Invokes clojure. Takes same args as the official clojure CLI.
|
|
||||||
|
|
||||||
If the first argument is not any of the above options, then it treated as a file if it exists, or as an expression otherwise.
|
|
||||||
Everything after that is bound to *command-line-args*.
|
|
||||||
|
|
||||||
Use -- to separate script command line args from bb 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.")
|
||||||
|
[nil 0])
|
||||||
|
|
||||||
|
(defn print-doc [ctx command-line-args]
|
||||||
|
(let [arg (first command-line-args)]
|
||||||
|
(if (sci/eval-string* ctx (format "
|
||||||
|
(when (or (resolve '%1$s)
|
||||||
|
(if (simple-symbol? '%1$s)
|
||||||
|
(try (require '%1$s) true
|
||||||
|
(catch Exception e nil))
|
||||||
|
(try (requiring-resolve '%1$s) true
|
||||||
|
(catch Exception e nil))))
|
||||||
|
(clojure.repl/doc %1$s)
|
||||||
|
true)" arg))
|
||||||
|
[nil 0]
|
||||||
|
[nil 1]))
|
||||||
|
,)
|
||||||
|
|
||||||
(defn print-describe []
|
(defn print-describe []
|
||||||
(println
|
(println
|
||||||
|
|
@ -302,8 +220,6 @@ Use -- to separate script command line args from bb command line args.
|
||||||
(str/replace x #"^#!.*" ""))
|
(str/replace x #"^#!.*" ""))
|
||||||
(throw (Exception. (str "File does not exist: " file))))))
|
(throw (Exception. (str "File does not exist: " file))))))
|
||||||
|
|
||||||
(def reflection-var (sci/new-dynamic-var '*warn-on-reflection* false))
|
|
||||||
|
|
||||||
(defn load-file* [f]
|
(defn load-file* [f]
|
||||||
(let [f (io/file f)
|
(let [f (io/file f)
|
||||||
s (slurp f)]
|
s (slurp f)]
|
||||||
|
|
@ -320,7 +236,7 @@ Use -- to separate script command line args from bb command line args.
|
||||||
nrepl-opts (assoc nrepl-opts
|
nrepl-opts (assoc nrepl-opts
|
||||||
:debug dev?
|
:debug dev?
|
||||||
:describe {"versions" {"babashka" version}}
|
:describe {"versions" {"babashka" version}}
|
||||||
:thread-bind [reflection-var])]
|
:thread-bind [core/warn-on-reflection])]
|
||||||
(nrepl-server/start-server! ctx nrepl-opts)
|
(nrepl-server/start-server! ctx nrepl-opts)
|
||||||
(binding [*out* *err*]
|
(binding [*out* *err*]
|
||||||
(println "For more info visit: https://book.babashka.org/#_nrepl")))
|
(println "For more info visit: https://book.babashka.org/#_nrepl")))
|
||||||
|
|
@ -444,6 +360,7 @@ Use -- to separate script command line args from bb command line args.
|
||||||
Comparable java.lang.Comparable
|
Comparable java.lang.Comparable
|
||||||
Double java.lang.Double
|
Double java.lang.Double
|
||||||
Exception java.lang.Exception
|
Exception java.lang.Exception
|
||||||
|
IndexOutOfBoundsException java.lang.IndexOutOfBoundsException
|
||||||
IllegalArgumentException java.lang.IllegalArgumentException
|
IllegalArgumentException java.lang.IllegalArgumentException
|
||||||
Integer java.lang.Integer
|
Integer java.lang.Integer
|
||||||
Iterable java.lang.Iterable
|
Iterable java.lang.Iterable
|
||||||
|
|
@ -483,27 +400,156 @@ Use -- to separate script command line args from bb command line args.
|
||||||
(defn shell-seq [in]
|
(defn shell-seq [in]
|
||||||
(line-seq (java.io.BufferedReader. in)))
|
(line-seq (java.io.BufferedReader. in)))
|
||||||
|
|
||||||
(defn main
|
(defn parse-opts [options]
|
||||||
[& args]
|
(let [opt (first options)]
|
||||||
(handle-pipe!)
|
(cond (and (command? opt)
|
||||||
(handle-sigint!)
|
(not (fs/regular-file? opt)))
|
||||||
|
(recur (cons (str "--" opt) (next options)))
|
||||||
|
:else
|
||||||
|
(let [opts (loop [options options
|
||||||
|
opts-map {}]
|
||||||
|
(if options
|
||||||
|
(let [opt (first options)]
|
||||||
|
(case opt
|
||||||
|
("--") (assoc opts-map :command-line-args (next options))
|
||||||
|
("--clojure") (assoc opts-map :clojure true
|
||||||
|
:command-line-args (rest options))
|
||||||
|
("--version") {:version true}
|
||||||
|
("--help" "-h" "-?" "help")
|
||||||
|
{:help true
|
||||||
|
:command-line-args (rest options)}
|
||||||
|
("--doc")
|
||||||
|
{:doc true
|
||||||
|
:command-line-args (rest options)}
|
||||||
|
("--verbose") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:verbose? true))
|
||||||
|
("--describe") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:describe? true))
|
||||||
|
("--stream") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:stream? true))
|
||||||
|
("-i") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:shell-in true))
|
||||||
|
("-I") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:edn-in true))
|
||||||
|
("-o") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:shell-out true))
|
||||||
|
("-O") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:edn-out true))
|
||||||
|
("-io") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:shell-in true
|
||||||
|
:shell-out true))
|
||||||
|
("-iO") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:shell-in true
|
||||||
|
:edn-out true))
|
||||||
|
("-Io") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:edn-in true
|
||||||
|
:shell-out true))
|
||||||
|
("-IO") (recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:edn-in true
|
||||||
|
:edn-out true))
|
||||||
|
("--classpath", "-cp")
|
||||||
|
(let [options (next options)]
|
||||||
|
(recur (next options)
|
||||||
|
(assoc opts-map :classpath (first options))))
|
||||||
|
("--uberscript")
|
||||||
|
(let [options (next options)]
|
||||||
|
(recur (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:uberscript (first options))))
|
||||||
|
("--uberjar")
|
||||||
|
(let [options (next options)]
|
||||||
|
(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 (next options)
|
||||||
|
(assoc opts-map
|
||||||
|
:repl true)))
|
||||||
|
("--socket-repl")
|
||||||
|
(let [options (next options)
|
||||||
|
opt (first options)
|
||||||
|
opt (when (and opt (not (str/starts-with? opt "-")))
|
||||||
|
opt)
|
||||||
|
options (if opt (next options)
|
||||||
|
options)]
|
||||||
|
(recur options
|
||||||
|
(assoc opts-map
|
||||||
|
:socket-repl (or opt "1666"))))
|
||||||
|
("--nrepl-server")
|
||||||
|
(let [options (next options)
|
||||||
|
opt (first options)
|
||||||
|
opt (when (and opt (not (str/starts-with? opt "-")))
|
||||||
|
opt)
|
||||||
|
options (if opt (next options)
|
||||||
|
options)]
|
||||||
|
(recur options
|
||||||
|
(assoc opts-map
|
||||||
|
:nrepl (or opt "1667"))))
|
||||||
|
("--eval", "-e")
|
||||||
|
(let [options (next options)]
|
||||||
|
(recur (next options)
|
||||||
|
(update opts-map :expressions (fnil conj []) (first options))))
|
||||||
|
("--main", "-m",)
|
||||||
|
(let [options (next options)]
|
||||||
|
(recur (next options)
|
||||||
|
(assoc opts-map :main (first options))))
|
||||||
|
;; fallback
|
||||||
|
(if (some opts-map [:file :jar :socket-repl :expressions :main])
|
||||||
|
(assoc opts-map
|
||||||
|
:command-line-args options)
|
||||||
|
(let [trimmed-opt (str/triml opt)
|
||||||
|
c (.charAt trimmed-opt 0)]
|
||||||
|
(case c
|
||||||
|
(\( \{ \[ \* \@ \#)
|
||||||
|
(-> opts-map
|
||||||
|
(update :expressions (fnil conj []) (first options))
|
||||||
|
(assoc :command-line-args (next options)))
|
||||||
|
(assoc opts-map
|
||||||
|
(if (str/ends-with? opt ".jar")
|
||||||
|
:jar :file) opt
|
||||||
|
:command-line-args (next options)))))))
|
||||||
|
opts-map))]
|
||||||
|
opts))))
|
||||||
|
|
||||||
|
(def env (atom {}))
|
||||||
|
|
||||||
|
(defn exec [opts]
|
||||||
(binding [*unrestricted* true]
|
(binding [*unrestricted* true]
|
||||||
(sci/binding [reflection-var false
|
(sci/binding [core/warn-on-reflection @core/warn-on-reflection
|
||||||
core/data-readers @core/data-readers
|
core/data-readers @core/data-readers
|
||||||
sci/ns @sci/ns]
|
sci/ns @sci/ns]
|
||||||
(let [{version-opt :version
|
(let [{version-opt :version
|
||||||
:keys [:shell-in :edn-in :shell-out :edn-out
|
:keys [:shell-in :edn-in :shell-out :edn-out
|
||||||
:help? :file :command-line-args
|
:help :file :command-line-args
|
||||||
:expressions :stream?
|
:expressions :stream?
|
||||||
:repl :socket-repl :nrepl
|
:repl :socket-repl :nrepl
|
||||||
:verbose? :classpath
|
:verbose? :classpath
|
||||||
:main :uberscript :describe?
|
:main :uberscript :describe?
|
||||||
:jar :uberjar :clojure] :as opts}
|
:jar :uberjar :clojure
|
||||||
(parse-opts args)
|
:doc]}
|
||||||
_ (when clojure
|
opts
|
||||||
(if-let [proc (deps/clojure (:opts opts))]
|
|
||||||
(-> @proc :exit (System/exit))
|
|
||||||
(System/exit 0)))
|
|
||||||
_ (when verbose? (vreset! common/verbose? true))
|
_ (when verbose? (vreset! common/verbose? true))
|
||||||
_ (do ;; set properties
|
_ (do ;; set properties
|
||||||
(when main (System/setProperty "babashka.main" main))
|
(when main (System/setProperty "babashka.main" main))
|
||||||
|
|
@ -522,11 +568,18 @@ Use -- to separate script command line args from bb command line args.
|
||||||
:else
|
:else
|
||||||
(edn/read {:readers edn-readers} *in*))))))
|
(edn/read {:readers edn-readers} *in*))))))
|
||||||
uberscript-sources (atom ())
|
uberscript-sources (atom ())
|
||||||
env (atom {})
|
|
||||||
classpath (or classpath
|
classpath (or classpath
|
||||||
(System/getenv "BABASHKA_CLASSPATH"))
|
(System/getenv "BABASHKA_CLASSPATH"))
|
||||||
_ (when classpath
|
_ (if classpath
|
||||||
(cp/add-classpath classpath))
|
(cp/add-classpath classpath)
|
||||||
|
;; when classpath isn't set, we calculate it from bb.edn, if present
|
||||||
|
(let [bb-edn-file (or (System/getenv "BABASHKA_EDN")
|
||||||
|
"bb.edn")]
|
||||||
|
(when (fs/exists? bb-edn-file)
|
||||||
|
(let [edn (edn/read-string (slurp bb-edn-file))]
|
||||||
|
(vreset! bb-edn edn)))
|
||||||
|
;; we mutate the atom from tests as well, so despite the above it can contain a bb.edn
|
||||||
|
(when-let [bb-edn @bb-edn] (deps/add-deps bb-edn))))
|
||||||
abs-path (when file
|
abs-path (when file
|
||||||
(let [abs-path (.getAbsolutePath (io/file file))]
|
(let [abs-path (.getAbsolutePath (io/file file))]
|
||||||
(vars/bindRoot sci/file abs-path)
|
(vars/bindRoot sci/file abs-path)
|
||||||
|
|
@ -552,15 +605,11 @@ Use -- to separate script command line args from bb command line args.
|
||||||
["META-INF/MANIFEST.MF"] {:url? true})]
|
["META-INF/MANIFEST.MF"] {:url? true})]
|
||||||
(cp/main-ns res))
|
(cp/main-ns res))
|
||||||
main)
|
main)
|
||||||
|
|
||||||
;; TODO: pull more of these values to compile time
|
;; TODO: pull more of these values to compile time
|
||||||
opts {:aliases aliases
|
opts {:aliases aliases
|
||||||
:namespaces (-> namespaces
|
:namespaces (-> namespaces
|
||||||
(assoc 'clojure.core
|
(assoc 'clojure.core
|
||||||
(assoc core-extras
|
(assoc core-extras
|
||||||
'*command-line-args*
|
|
||||||
(sci/new-dynamic-var '*command-line-args* command-line-args)
|
|
||||||
'*warn-on-reflection* reflection-var
|
|
||||||
'load-file load-file*))
|
'load-file load-file*))
|
||||||
(assoc-in ['clojure.java.io 'resource]
|
(assoc-in ['clojure.java.io 'resource]
|
||||||
(fn [path]
|
(fn [path]
|
||||||
|
|
@ -577,15 +626,23 @@ Use -- to separate script command line args from bb command line args.
|
||||||
:load-fn load-fn
|
:load-fn load-fn
|
||||||
:uberscript uberscript
|
:uberscript uberscript
|
||||||
:readers core/data-readers
|
:readers core/data-readers
|
||||||
:reify reify-opts}
|
:reify-fn reify-fn
|
||||||
|
:proxy-fn proxy-fn}
|
||||||
opts (addons/future opts)
|
opts (addons/future opts)
|
||||||
sci-ctx (sci/init opts)
|
sci-ctx (sci/init opts)
|
||||||
_ (vreset! common/ctx sci-ctx)
|
_ (vreset! common/ctx sci-ctx)
|
||||||
preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim))
|
preloads (some-> (System/getenv "BABASHKA_PRELOADS") (str/trim))
|
||||||
[expressions exit-code]
|
[expressions exit-code]
|
||||||
(cond expressions [expressions nil]
|
(cond expressions [expressions nil]
|
||||||
main [[(format "(ns user (:require [%1$s])) (apply %1$s/-main *command-line-args*)"
|
main
|
||||||
main)] nil]
|
(let [sym (symbol main)
|
||||||
|
ns? (namespace sym)
|
||||||
|
ns (or ns? sym)
|
||||||
|
var-name (if ns?
|
||||||
|
(name sym)
|
||||||
|
"-main")]
|
||||||
|
[[(format "(ns user (:require [%1$s])) (apply %1$s/%2$s *command-line-args*)"
|
||||||
|
ns var-name)] nil])
|
||||||
file (try [[(read-file file)] nil]
|
file (try [[(read-file file)] nil]
|
||||||
(catch Exception e
|
(catch Exception e
|
||||||
(error-handler e {:expression expressions
|
(error-handler e {:expression expressions
|
||||||
|
|
@ -615,8 +672,8 @@ Use -- to separate script command line args from bb command line args.
|
||||||
(second
|
(second
|
||||||
(cond version-opt
|
(cond version-opt
|
||||||
[(print-version) 0]
|
[(print-version) 0]
|
||||||
help?
|
help (print-help sci-ctx command-line-args)
|
||||||
[(print-help) 0]
|
doc (print-doc sci-ctx command-line-args)
|
||||||
describe?
|
describe?
|
||||||
[(print-describe) 0]
|
[(print-describe) 0]
|
||||||
repl [(repl/start-repl! sci-ctx) 0]
|
repl [(repl/start-repl! sci-ctx) 0]
|
||||||
|
|
@ -631,7 +688,8 @@ Use -- to separate script command line args from bb command line args.
|
||||||
[nil 0] ;; done streaming
|
[nil 0] ;; done streaming
|
||||||
(let [res [(let [res
|
(let [res [(let [res
|
||||||
(sci/binding [sci/file (or @sci/file "<expr>")
|
(sci/binding [sci/file (or @sci/file "<expr>")
|
||||||
input-var in]
|
input-var in
|
||||||
|
core/command-line-args command-line-args]
|
||||||
(sci/eval-string* sci-ctx expression))]
|
(sci/eval-string* sci-ctx expression))]
|
||||||
(when (some? res)
|
(when (some? res)
|
||||||
(if-let [pr-f (cond shell-out println
|
(if-let [pr-f (cond shell-out println
|
||||||
|
|
@ -650,6 +708,9 @@ Use -- to separate script command line args from bb command line args.
|
||||||
:verbose? verbose?
|
:verbose? verbose?
|
||||||
:preloads preloads
|
:preloads preloads
|
||||||
:loader (:loader @cp/cp-state)}))))
|
:loader (:loader @cp/cp-state)}))))
|
||||||
|
clojure [nil (if-let [proc (deps/clojure command-line-args)]
|
||||||
|
(-> @proc :exit)
|
||||||
|
0)]
|
||||||
uberscript [nil 0]
|
uberscript [nil 0]
|
||||||
:else [(repl/start-repl! sci-ctx) 0]))
|
:else [(repl/start-repl! sci-ctx) 0]))
|
||||||
1)]
|
1)]
|
||||||
|
|
@ -669,8 +730,14 @@ Use -- to separate script command line args from bb command line args.
|
||||||
:verbose verbose?}))
|
:verbose verbose?}))
|
||||||
exit-code))))
|
exit-code))))
|
||||||
|
|
||||||
|
(defn main [& args]
|
||||||
|
(let [opts (parse-opts args)]
|
||||||
|
(exec opts)))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
[& args]
|
[& args]
|
||||||
|
(handle-pipe!)
|
||||||
|
(handle-sigint!)
|
||||||
(if-let [dev-opts (System/getenv "BABASHKA_DEV")]
|
(if-let [dev-opts (System/getenv "BABASHKA_DEV")]
|
||||||
(let [{:keys [:n]} (if (= "true" dev-opts) {:n 1}
|
(let [{:keys [:n]} (if (= "true" dev-opts) {:n 1}
|
||||||
(edn/read-string dev-opts))
|
(edn/read-string dev-opts))
|
||||||
|
|
|
||||||
10
test-resources/bb-edn/user.clj
Normal file
10
test-resources/bb-edn/user.clj
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
(ns user
|
||||||
|
(:require [babashka.process :as p]
|
||||||
|
[clojure.string :as str]))
|
||||||
|
|
||||||
|
(defn bash [& args]
|
||||||
|
;; (prn :cmd *command-line-args*)
|
||||||
|
(-> (p/process ["bash" "-c" (str/join " " args)]
|
||||||
|
{:inherit true})
|
||||||
|
p/check)
|
||||||
|
nil)
|
||||||
|
|
@ -6,10 +6,12 @@
|
||||||
|
|
||||||
(def status (atom {}))
|
(def status (atom {}))
|
||||||
|
|
||||||
|
(defn test-namespace? [ns]
|
||||||
|
(or (empty? ns-args)
|
||||||
|
(contains? ns-args ns)))
|
||||||
|
|
||||||
(defn test-namespaces [& namespaces]
|
(defn test-namespaces [& namespaces]
|
||||||
(let [namespaces (if (seq ns-args)
|
(let [namespaces (seq (filter test-namespace? namespaces))]
|
||||||
(seq (keep ns-args namespaces))
|
|
||||||
namespaces)]
|
|
||||||
(when namespaces
|
(when namespaces
|
||||||
(doseq [ns namespaces]
|
(doseq [ns namespaces]
|
||||||
(require ns))
|
(require ns))
|
||||||
|
|
@ -121,7 +123,14 @@
|
||||||
|
|
||||||
;;;; doric
|
;;;; doric
|
||||||
|
|
||||||
(test-namespaces 'doric.test.core)
|
(defn test-doric-cyclic-dep-problem
|
||||||
|
[]
|
||||||
|
(require '[doric.core :as d])
|
||||||
|
((resolve 'doric.core/table) [:a :b] [{:a 1 :b 2}]))
|
||||||
|
|
||||||
|
(when (test-namespace? 'doric.test.core)
|
||||||
|
(test-doric-cyclic-dep-problem)
|
||||||
|
(test-namespaces 'doric.test.core))
|
||||||
|
|
||||||
;;;; cljc-java-time
|
;;;; cljc-java-time
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
(ns version-clj.compare-test
|
(ns version-clj.compare-test
|
||||||
(:require [clojure.test :refer [deftest are]]
|
(:require #?(:clj [clojure.test :refer [deftest are]]
|
||||||
|
:cljs [cljs.test :refer-macros [deftest are]])
|
||||||
[version-clj.compare :refer [version-compare]]))
|
[version-clj.compare :refer [version-compare]]))
|
||||||
|
|
||||||
(deftest t-version-compare
|
(deftest t-version-compare
|
||||||
(are [v0 v1 r] (= (version-compare v0 v1) r)
|
(are [v0 v1 r] (= r (version-compare v0 v1))
|
||||||
;; Numeric Comparison
|
;; Numeric Comparison
|
||||||
"1.0.0" "1.0.0" 0
|
"1.0.0" "1.0.0" 0
|
||||||
"1.0.0" "1.0" 0
|
"1.0.0" "1.0" 0
|
||||||
|
|
@ -36,6 +37,19 @@
|
||||||
"1.0-RC5" "1.0-RC20" -1
|
"1.0-RC5" "1.0-RC20" -1
|
||||||
"1.0-RC11" "1.0-RC6" 1
|
"1.0-RC11" "1.0-RC6" 1
|
||||||
|
|
||||||
|
;; Comparison nested vs. value
|
||||||
|
"1.0.0" "1.0-1.0" -1
|
||||||
|
"1.0-1.0" "1.0.0" 1
|
||||||
|
"1.0-0.0" "1.0.0" 0
|
||||||
|
"1.0.0" "1.0-0.0" 0
|
||||||
|
"1.x.0" "1.x-1.0" -1
|
||||||
|
"1.x-1.0" "1.x.0" 1
|
||||||
|
"1.0-612" "1.0.613" -1
|
||||||
|
|
||||||
|
;; Numbers are newer than strings
|
||||||
|
"1.x.1" "1.0.1" -1
|
||||||
|
"1.0.1" "1.x.1" 1
|
||||||
|
|
||||||
;; Releases are newer than SNAPSHOTs
|
;; Releases are newer than SNAPSHOTs
|
||||||
"1.0.0" "1.0.0-SNAPSHOT" 1
|
"1.0.0" "1.0.0-SNAPSHOT" 1
|
||||||
"1.0.0-SNAPSHOT" "1.0.0-SNAPSHOT" 0
|
"1.0.0-SNAPSHOT" "1.0.0-SNAPSHOT" 0
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
(ns version-clj.core-test
|
(ns version-clj.core-test
|
||||||
(:require [clojure.test :refer [deftest are]]
|
(:require #?(:clj [clojure.test :refer [deftest is are]]
|
||||||
[version-clj.core :refer [snapshot? qualified?]]))
|
:cljs [cljs.test :refer-macros [deftest is are]])
|
||||||
|
[version-clj.core :as v]))
|
||||||
|
|
||||||
(deftest t-snapshot
|
(deftest t-snapshot?
|
||||||
(are [v r] (= (boolean (snapshot? v)) r)
|
(are [v r] (= r (boolean (v/snapshot? v)))
|
||||||
"1.0.0" false
|
"1.0.0" false
|
||||||
"SNAPSHOT" true
|
"SNAPSHOT" true
|
||||||
"1-SNAPSHOT" true
|
"1-SNAPSHOT" true
|
||||||
|
|
@ -11,15 +12,70 @@
|
||||||
"1.0-SNAPSHOT.2" true
|
"1.0-SNAPSHOT.2" true
|
||||||
"1.0-NOSNAPSHOT" false))
|
"1.0-NOSNAPSHOT" false))
|
||||||
|
|
||||||
(deftest t-qualified
|
(deftest t-qualified?
|
||||||
(are [v r] (= (boolean (qualified? v)) r)
|
(are [v r] (= r (boolean (v/qualified? v)))
|
||||||
"1.0.0" false
|
"1.0.0" false
|
||||||
"SNAPSHOT" true
|
"SNAPSHOT" true
|
||||||
|
"SNAPSHOT2" true
|
||||||
"1-SNAPSHOT" true
|
"1-SNAPSHOT" true
|
||||||
"1.0-SNAPSHOT" true
|
"1.0-SNAPSHOT" true
|
||||||
"1.0-SNAPSHOT.2" true
|
"1.0-SNAPSHOT.2" true
|
||||||
"1.0-NOSNAPSHOT" true
|
"1.0-NOSNAPSHOT" true
|
||||||
|
"1.0-NOSNAPSHOT.1" true
|
||||||
|
"1.0-NOSNAPSHOT.1.1" true
|
||||||
|
"1.0-NOSNAPSHOT1.1" true
|
||||||
|
"0.5.3-alpha.1.pre.0" true
|
||||||
"1.x.2" false
|
"1.x.2" false
|
||||||
"1.2y" true
|
"1.2y" false
|
||||||
"1.y2" false
|
"1.y2" false
|
||||||
"1.y" false))
|
"1.y" false))
|
||||||
|
|
||||||
|
(let [v0 "1.0.0-SNAPSHOT"
|
||||||
|
v1 "1.0.0"
|
||||||
|
v2 "1.0.1-RC"
|
||||||
|
v3 "1.0.1"
|
||||||
|
ordered [v0 v1 v2 v3]]
|
||||||
|
(deftest t-version-sort
|
||||||
|
(is (= ordered (v/version-sort (shuffle ordered))))
|
||||||
|
(is (= (map v/version->seq ordered)
|
||||||
|
(v/version-seq-sort (map v/version->seq ordered)))))
|
||||||
|
|
||||||
|
(deftest t-version-compare
|
||||||
|
(is (pos? (v/version-compare v1 v0)))
|
||||||
|
(is (neg? (v/version-compare v0 v1)))
|
||||||
|
(is (zero? (v/version-compare v0 v0)))
|
||||||
|
(is (v/older? v0 v1))
|
||||||
|
(is (v/newer? v1 v0))
|
||||||
|
(is (v/older-or-equal? v0 v1))
|
||||||
|
(is (v/older-or-equal? v0 v0))
|
||||||
|
(is (v/newer-or-equal? v1 v0))
|
||||||
|
(is (v/newer-or-equal? v0 v0)))
|
||||||
|
|
||||||
|
(deftest t-version-seq-compare
|
||||||
|
(is (pos? (v/version-seq-compare
|
||||||
|
(v/version->seq v1)
|
||||||
|
(v/version->seq v0))))
|
||||||
|
(is (neg? (v/version-seq-compare
|
||||||
|
(v/version->seq v0)
|
||||||
|
(v/version->seq v1))))
|
||||||
|
(is (zero? (v/version-seq-compare
|
||||||
|
(v/version->seq v0)
|
||||||
|
(v/version->seq v0))))))
|
||||||
|
|
||||||
|
(deftest t-parse
|
||||||
|
(let [s "1.0.1", version (v/parse s)]
|
||||||
|
(is (= [[1 0 1]] (:version version)))
|
||||||
|
(is (= #{} (:qualifiers version)))
|
||||||
|
(is (not (:snapshot? version)))
|
||||||
|
(is (not (:qualified? version))))
|
||||||
|
(let [s "1.0.1-RC1-SNAPSHOT", version (v/parse s)]
|
||||||
|
(is (= [[1 0 1] [["rc" 1] "snapshot"]] (:version version)))
|
||||||
|
(is (= #{"rc" "snapshot"} (:qualifiers version)))
|
||||||
|
(is (:snapshot? version))
|
||||||
|
(is (:qualified? version)))
|
||||||
|
(let [s "1.0.1"]
|
||||||
|
(is (= (v/parse s) (v/parse (v/version->seq s))))))
|
||||||
|
|
||||||
|
(deftest t-version-and-qualifier-data
|
||||||
|
(is (= [1 0 1] (v/version-data "1.0.1-RC")))
|
||||||
|
(is (= ["rc"] (v/qualifier-data "1.0.1-RC"))))
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,19 @@
|
||||||
(ns version-clj.split-test
|
(ns version-clj.split-test
|
||||||
(:require [clojure.test :refer [deftest are is]]
|
(:require #?(:clj [clojure.test :refer [deftest testing are is]]
|
||||||
|
:cljs [cljs.test :refer-macros [deftest testing are is]])
|
||||||
[version-clj.split :refer [version->seq]]))
|
[version-clj.split :refer [version->seq]]))
|
||||||
|
|
||||||
|
(deftest t-split-once-sanity-check
|
||||||
|
(let [split-once @#'version-clj.split/split-once
|
||||||
|
rx #"(^|(?<=\d)|-)(?=alpha)"]
|
||||||
|
(are [in out] (= out (split-once rx in))
|
||||||
|
"1-alpha2.2" ["1" "alpha2.2"]
|
||||||
|
"alpha" ["" "alpha"]
|
||||||
|
"1alpha" ["1" "alpha"]
|
||||||
|
"0.0.3-alpha.8+oryOS.15" ["0.0.3" "alpha.8+oryOS.15"])))
|
||||||
|
|
||||||
(deftest t-split
|
(deftest t-split
|
||||||
(are [version v] (= (version->seq version) v)
|
(are [version v] (= v (version->seq version))
|
||||||
"1.0.0" [[1 0 0]]
|
"1.0.0" [[1 0 0]]
|
||||||
"1.0" [[1 0]]
|
"1.0" [[1 0]]
|
||||||
"1" [[1]]
|
"1" [[1]]
|
||||||
|
|
@ -12,11 +22,51 @@
|
||||||
"1.0.1-SNAPSHOT" [[1 0 1] ["snapshot"]]
|
"1.0.1-SNAPSHOT" [[1 0 1] ["snapshot"]]
|
||||||
"1.0.1-alpha2" [[1 0 1] ["alpha" 2]]
|
"1.0.1-alpha2" [[1 0 1] ["alpha" 2]]
|
||||||
"11.2.0.3.0" [[11 2 0 3 0]]
|
"11.2.0.3.0" [[11 2 0 3 0]]
|
||||||
"1.0-1-0.2-RC" [[1 [0 1 0] 2] ["rc"]]))
|
"1.0-1-0.2-RC" [[1 [0 1 0] 2] ["rc"]]
|
||||||
|
"1.0-612" [[1 0] [612]]
|
||||||
|
"alpha" [[] ["alpha"]]
|
||||||
|
"alpha-2" [[] ["alpha" 2]]
|
||||||
|
"1.alpha" [[1] ["alpha"]]
|
||||||
|
"1.alpha.2" [[1] ["alpha" 2]]
|
||||||
|
"1-alpha.2" [[1] ["alpha" 2]]
|
||||||
|
"1-alpha.2.2" [[1] ["alpha" 2 2]]
|
||||||
|
"1-alpha2.2" [[1] [["alpha" 2] 2]]
|
||||||
|
"1.alpha-1.0" [[1] ["alpha" [1 0]]]
|
||||||
|
"0.5.0-alpha.1" [[0 5 0] ["alpha" 1]]
|
||||||
|
"0.5.0-alpha.1" [[0 5 0] ["alpha" 1]]
|
||||||
|
"0.0.3-alpha.8+oryOS.15" [[0 0 3] ["alpha" [8 "+oryos"] 15]]
|
||||||
|
))
|
||||||
|
|
||||||
|
(deftest t-split-without-qualifiers
|
||||||
|
(testing "well-behaving."
|
||||||
|
(are [version] (= (version->seq version)
|
||||||
|
(version->seq version {:qualifiers {}}))
|
||||||
|
"1.0.0"
|
||||||
|
"1.0"
|
||||||
|
"1"
|
||||||
|
"1-a"
|
||||||
|
"1.0.1-SNAPSHOT"
|
||||||
|
"1.0.1-alpha2"
|
||||||
|
"11.2.0.3.0"
|
||||||
|
"1.0-1-0.2-RC"
|
||||||
|
"1-alpha.2"
|
||||||
|
"1-alpha.2.2"
|
||||||
|
"1-alpha2.2"
|
||||||
|
"0.5.0-alpha.1"
|
||||||
|
"0.5.0-alpha.1"
|
||||||
|
"0.0.3-alpha.8+oryOS.15"))
|
||||||
|
(testing "deviants."
|
||||||
|
(are [version v] (= v (version->seq version {:qualifiers {}}))
|
||||||
|
"alpha" [["alpha"]]
|
||||||
|
"alpha-2" [["alpha"] [2]]
|
||||||
|
"1a" [[1 "a"]]
|
||||||
|
"1.alpha" [[1 "alpha"]]
|
||||||
|
"1.alpha.2" [[1 "alpha" 2]]
|
||||||
|
"1.alpha-1.0" [[1 ["alpha" 1] 0]])))
|
||||||
|
|
||||||
(deftest t-split-with-large-number
|
(deftest t-split-with-large-number
|
||||||
(is (= (version->seq "0.0.1-20141002100138")
|
(is (= [[0 0 1] [20141002100138]]
|
||||||
[[0 0 1] [20141002100138]]))
|
(version->seq "0.0.1-20141002100138")))
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(let [v (str Long/MAX_VALUE "12345")]
|
(let [v (str Long/MAX_VALUE "12345")]
|
||||||
(is (= (version->seq v) [[(bigint v)]])))))
|
(is (= (version->seq v) [[(bigint v)]])))))
|
||||||
|
|
|
||||||
11
test-resources/task_scripts/tasks.clj
Normal file
11
test-resources/task_scripts/tasks.clj
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
(ns tasks
|
||||||
|
"This is task ns docstring.")
|
||||||
|
|
||||||
|
(defn -main
|
||||||
|
"Main docstring"
|
||||||
|
[& args]
|
||||||
|
args)
|
||||||
|
|
||||||
|
(defn foo
|
||||||
|
"Foo docstring"
|
||||||
|
[])
|
||||||
51
test/babashka/bb_edn_test.clj
Normal file
51
test/babashka/bb_edn_test.clj
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
(ns babashka.bb-edn-test
|
||||||
|
(:require
|
||||||
|
[babashka.fs :as fs]
|
||||||
|
[babashka.test-utils :as test-utils]
|
||||||
|
[clojure.edn :as edn]
|
||||||
|
[clojure.string :as str]
|
||||||
|
[clojure.test :as test :refer [deftest is testing]]))
|
||||||
|
|
||||||
|
(defn bb [& args]
|
||||||
|
(edn/read-string
|
||||||
|
{:readers *data-readers*
|
||||||
|
:eof nil}
|
||||||
|
(apply test-utils/bb nil (map str args))))
|
||||||
|
|
||||||
|
(defmacro with-config [cfg & body]
|
||||||
|
`(let [temp-dir# (fs/create-temp-dir)
|
||||||
|
bb-edn-file# (fs/file temp-dir# "bb.edn")]
|
||||||
|
(binding [*print-meta* true]
|
||||||
|
(spit bb-edn-file# ~cfg))
|
||||||
|
(binding [test-utils/*bb-edn-path* (str bb-edn-file#)]
|
||||||
|
~@body)))
|
||||||
|
|
||||||
|
(deftest doc-test
|
||||||
|
(with-config {:paths ["test-resources/task_scripts"]}
|
||||||
|
(is (str/includes? (apply test-utils/bb nil
|
||||||
|
(map str ["doc" "tasks"]))
|
||||||
|
"This is task ns docstring."))
|
||||||
|
(is (str/includes? (apply test-utils/bb nil
|
||||||
|
(map str ["doc" "tasks/foo"]))
|
||||||
|
"Foo docstring"))
|
||||||
|
(is (str/includes? (apply test-utils/bb nil
|
||||||
|
(map str ["doc" "tasks/-main"]))
|
||||||
|
"Main docstring"))))
|
||||||
|
|
||||||
|
(deftest deps-test
|
||||||
|
(with-config '{:deps {medley/medley {:mvn/version "1.3.0"}}}
|
||||||
|
(is (= '{1 {:id 1}, 2 {:id 2}}
|
||||||
|
(bb "-e" "(require 'medley.core)" "-e" "(medley.core/index-by :id [{:id 1} {:id 2}])"))))
|
||||||
|
(testing "--classpath option overrides bb.edn"
|
||||||
|
(with-config '{:deps {medley/medley {:mvn/version "1.3.0"}}}
|
||||||
|
(is (= "src"
|
||||||
|
(bb "-cp" "src" "-e" "(babashka.classpath/get-classpath)"))))))
|
||||||
|
|
||||||
|
;; TODO:
|
||||||
|
;; Do we want to support the same parsing as the clj CLI?
|
||||||
|
;; Or do we want `--aliases :foo:bar`
|
||||||
|
;; Let's wait for a good use case
|
||||||
|
#_(deftest alias-deps-test
|
||||||
|
(with-config '{:aliases {:medley {:deps {medley/medley {:mvn/version "1.3.0"}}}}}
|
||||||
|
(is (= '{1 {:id 1}, 2 {:id 2}}
|
||||||
|
(bb "-A:medley" "-e" "(require 'medley.core)" "-e" "(medley.core/index-by :id [{:id 1} {:id 2}])")))))
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
:features #{:bb}})
|
:features #{:bb}})
|
||||||
nrepl-opts)]
|
nrepl-opts)]
|
||||||
(reset! server-state server))
|
(reset! server-state server))
|
||||||
(let [pb (ProcessBuilder. ["./bb" "--nrepl-server" "0.0.0.0:1668"])
|
(let [pb (ProcessBuilder. ["./bb" "nrepl-server" "0.0.0.0:1668"])
|
||||||
_ (.redirectError pb ProcessBuilder$Redirect/INHERIT)
|
_ (.redirectError pb ProcessBuilder$Redirect/INHERIT)
|
||||||
;; _ (.redirectOutput pb ProcessBuilder$Redirect/INHERIT)
|
;; _ (.redirectOutput pb ProcessBuilder$Redirect/INHERIT)
|
||||||
;; env (.environment pb)
|
;; env (.environment pb)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
(vreset! common/ctx ctx)
|
(vreset! common/ctx ctx)
|
||||||
(start-repl! "0.0.0.0:1666" ctx))
|
(start-repl! "0.0.0.0:1666" ctx))
|
||||||
(do (vreset! server-process
|
(do (vreset! server-process
|
||||||
(p/process ["./bb" "--socket-repl" "localhost:1666"]))
|
(p/process ["./bb" "socket-repl" "localhost:1666"]))
|
||||||
(w/wait-for-port "localhost" 1666)))
|
(w/wait-for-port "localhost" 1666)))
|
||||||
(Thread/sleep 50)
|
(Thread/sleep 50)
|
||||||
(is (socket-command "(+ 1 2 3)" "user=> 6"))
|
(is (socket-command "(+ 1 2 3)" "user=> 6"))
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,10 @@
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.java.shell :refer [sh]]
|
[clojure.java.shell :refer [sh]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.test :as test :refer [deftest is testing *report-counters*]]
|
[clojure.test :as test :refer [deftest is testing]]
|
||||||
[flatland.ordered.map :refer [ordered-map]]
|
[flatland.ordered.map :refer [ordered-map]]
|
||||||
[sci.core :as sci]))
|
[sci.core :as sci]))
|
||||||
|
|
||||||
(defmethod clojure.test/report :begin-test-var [m]
|
|
||||||
(println "===" (-> m :var meta :name))
|
|
||||||
(println))
|
|
||||||
|
|
||||||
(defmethod clojure.test/report :end-test-var [_m]
|
|
||||||
(let [{:keys [:fail :error]} @*report-counters*]
|
|
||||||
(when (and (= "true" (System/getenv "BABASHKA_FAIL_FAST"))
|
|
||||||
(or (pos? fail) (pos? error)))
|
|
||||||
(println "=== Failing fast")
|
|
||||||
(System/exit 1))))
|
|
||||||
|
|
||||||
(defn bb [input & args]
|
(defn bb [input & args]
|
||||||
(edn/read-string
|
(edn/read-string
|
||||||
{:readers *data-readers*
|
{:readers *data-readers*
|
||||||
|
|
@ -363,16 +352,7 @@
|
||||||
(is (.exists f2))
|
(is (.exists f2))
|
||||||
(let [v (bb nil "-f" (.getPath (io/file "test-resources" "babashka" "glob.clj")))]
|
(let [v (bb nil "-f" (.getPath (io/file "test-resources" "babashka" "glob.clj")))]
|
||||||
(is (vector? v))
|
(is (vector? v))
|
||||||
(is (.exists (io/file (first v))))))
|
(is (.exists (io/file (first v)))))))
|
||||||
(testing "reify can handle multiple classes at once"
|
|
||||||
(is (true? (bb nil "
|
|
||||||
(def filter-obj (reify java.io.FileFilter
|
|
||||||
(accept [this f] (prn (.getPath f)) true)
|
|
||||||
java.io.FilenameFilter
|
|
||||||
(accept [this f name] (prn name) true)))
|
|
||||||
(def s1 (with-out-str (.listFiles (clojure.java.io/file \".\") filter-obj)))
|
|
||||||
(def s2 (with-out-str (.list (clojure.java.io/file \".\") filter-obj)))
|
|
||||||
(and (pos? (count s1)) (pos? (count s2)))")))))
|
|
||||||
|
|
||||||
(deftest future-print-test
|
(deftest future-print-test
|
||||||
(testing "the root binding of sci/*out*"
|
(testing "the root binding of sci/*out*"
|
||||||
|
|
@ -574,7 +554,12 @@
|
||||||
|
|
||||||
(deftest var-print-method-test
|
(deftest var-print-method-test
|
||||||
(when test-utils/native?
|
(when test-utils/native?
|
||||||
(is (bb nil "(defmethod print-method sci.lang.IVar [o w] (.write w (str :foo (symbol o)))) (def x 1) (= \":foouser/x\" (pr-str #'x))"))))
|
(is (bb nil "(defmethod print-method sci.lang.IVar [o w] (.write w (str :foo (symbol o)))) (def x 1) (= \":foouser/x\" (pr-str #'x))"))
|
||||||
|
(is (= :foouser/x (bb nil "(defmethod print-method sci.lang.IVar [o w] (.write w (str :foo (symbol o)))) (def x 1)")))))
|
||||||
|
|
||||||
|
(deftest stdout-interop-test
|
||||||
|
(when test-utils/native?
|
||||||
|
(is (= 'Something (bb nil "(.print (System/out) \"Something\")")))))
|
||||||
|
|
||||||
;;;; Scratch
|
;;;; Scratch
|
||||||
|
|
||||||
|
|
|
||||||
80
test/babashka/proxy_test.clj
Normal file
80
test/babashka/proxy_test.clj
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
(ns babashka.proxy-test
|
||||||
|
(:require
|
||||||
|
[babashka.test-utils :as test-utils]
|
||||||
|
[clojure.edn :as edn]
|
||||||
|
[clojure.test :as test :refer [deftest is]]))
|
||||||
|
|
||||||
|
(defn bb [& args]
|
||||||
|
(edn/read-string
|
||||||
|
{:readers *data-readers*
|
||||||
|
:eof nil}
|
||||||
|
(apply test-utils/bb nil (map str args))))
|
||||||
|
|
||||||
|
(def code
|
||||||
|
'(do
|
||||||
|
(require '[clojure.core.protocols])
|
||||||
|
(require '[clojure.datafy :as d])
|
||||||
|
(defn auto-deref
|
||||||
|
"If value implements IDeref, deref it, otherwise return original."
|
||||||
|
[x]
|
||||||
|
(if (instance? clojure.lang.IDeref x)
|
||||||
|
@x
|
||||||
|
x))
|
||||||
|
(defn proxy-deref-map
|
||||||
|
{:added "1.0"}
|
||||||
|
[m]
|
||||||
|
(proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj clojure.core.protocols.Datafiable]
|
||||||
|
[]
|
||||||
|
(iterator []
|
||||||
|
::TODO)
|
||||||
|
(containsKey [k] (contains? m k))
|
||||||
|
(entryAt [k] (when (contains? m k) (proxy [clojure.lang.AMapEntry] []
|
||||||
|
(key [] k)
|
||||||
|
(val [] (auto-deref (get m k))))))
|
||||||
|
(valAt ([k] (auto-deref (get m k)))
|
||||||
|
([k default] (auto-deref (get m k default))))
|
||||||
|
(cons [v] (proxy-deref-map (conj m v)))
|
||||||
|
(count [] (count m))
|
||||||
|
(assoc [k v] (proxy-deref-map (assoc m k v)))
|
||||||
|
(without [k] (proxy-deref-map (dissoc m k)))
|
||||||
|
(seq [] (map (fn [[k v]](proxy [clojure.lang.AMapEntry] []
|
||||||
|
(key [] k)
|
||||||
|
(val [] (auto-deref (get m k))))) m))
|
||||||
|
(withMeta [md] (proxy-deref-map (with-meta m md)))
|
||||||
|
(meta [] (meta m))
|
||||||
|
|
||||||
|
(datafy [] {:datafied true})))
|
||||||
|
(let [m (proxy-deref-map
|
||||||
|
{:a (delay 1)
|
||||||
|
:b (delay 2)
|
||||||
|
:c 3})]
|
||||||
|
[(:a m)
|
||||||
|
(:b m)
|
||||||
|
(:c m)
|
||||||
|
(contains? m :c)
|
||||||
|
(find m :c)
|
||||||
|
(-> (conj m [:d (delay 5)])
|
||||||
|
:d)
|
||||||
|
(count m)
|
||||||
|
(-> (assoc m :d (delay 5))
|
||||||
|
:d)
|
||||||
|
(-> (dissoc m :a)
|
||||||
|
(contains? :a))
|
||||||
|
(seq m)
|
||||||
|
(meta (with-meta m {:a 1}))
|
||||||
|
(d/datafy m)
|
||||||
|
(instance? clojure.lang.APersistentMap m)
|
||||||
|
(instance? java.io.FilenameFilter m)
|
||||||
|
,])))
|
||||||
|
|
||||||
|
(require 'clojure.pprint)
|
||||||
|
|
||||||
|
(deftest APersistentMap-proxy-test
|
||||||
|
(is (= [1 2 3 true [:c 3]
|
||||||
|
5 3 5 false
|
||||||
|
'([:a 1] [:b 2] [:c 3])
|
||||||
|
{:a 1}
|
||||||
|
{:datafied true}
|
||||||
|
true
|
||||||
|
false]
|
||||||
|
(bb (with-out-str (clojure.pprint/pprint code))))))
|
||||||
67
test/babashka/reify_test.clj
Normal file
67
test/babashka/reify_test.clj
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
(ns babashka.reify-test
|
||||||
|
(:require
|
||||||
|
[babashka.test-utils :as test-utils]
|
||||||
|
[clojure.edn :as edn]
|
||||||
|
[clojure.test :as test :refer [deftest is testing]]))
|
||||||
|
|
||||||
|
(defn bb [input & args]
|
||||||
|
(edn/read-string
|
||||||
|
{:readers *data-readers*
|
||||||
|
:eof nil}
|
||||||
|
(apply test-utils/bb (when (some? input) (str input)) (map str args))))
|
||||||
|
|
||||||
|
(deftest file-filter-test
|
||||||
|
(is (true? (bb nil "
|
||||||
|
(def filter-obj (reify java.io.FileFilter
|
||||||
|
(accept [this f] (prn (.getPath f)) true)))
|
||||||
|
(def filename-filter-obj
|
||||||
|
(reify java.io.FilenameFilter
|
||||||
|
(accept [this f name] (prn name) true)))
|
||||||
|
(def s1 (with-out-str (.listFiles (clojure.java.io/file \".\") filter-obj)))
|
||||||
|
(def s2 (with-out-str (.listFiles (clojure.java.io/file \".\") filename-filter-obj)))
|
||||||
|
(and (pos? (count s1)) (pos? (count s2)))"))))
|
||||||
|
|
||||||
|
(deftest reify-multiple-arities-test
|
||||||
|
(testing "ILookup"
|
||||||
|
(is (= ["->:foo" 10]
|
||||||
|
(bb nil "
|
||||||
|
(def m (reify clojure.lang.ILookup
|
||||||
|
(valAt [this x] (str \"->\" x))
|
||||||
|
(valAt [this x y] y)))
|
||||||
|
[(:foo m) (:foo m 10)]"))))
|
||||||
|
(testing "IFn"
|
||||||
|
(is (= [:yo :three :six :twelve :eighteen :nineteen 19]
|
||||||
|
(bb nil "
|
||||||
|
(def m (reify clojure.lang.IFn
|
||||||
|
(invoke [this] :yo)
|
||||||
|
(invoke [this _ _ _] :three)
|
||||||
|
(invoke [this _ _ _ _ _ _] :six)
|
||||||
|
(invoke [this _ _ _ _ _ _ _ _ _ _ _ _] :twelve)
|
||||||
|
(invoke [this _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _] :eighteen)
|
||||||
|
(invoke [this _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _] :nineteen)
|
||||||
|
(applyTo [this args] (last args))))
|
||||||
|
[
|
||||||
|
(m)
|
||||||
|
(m 1 2 3)
|
||||||
|
(m 1 2 3 4 5 6)
|
||||||
|
(m 1 2 3 4 5 6 1 2 3 4 5 6)
|
||||||
|
(m 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6)
|
||||||
|
(m 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1)
|
||||||
|
(apply m (range 20))
|
||||||
|
]")))))
|
||||||
|
|
||||||
|
(deftest reify-object
|
||||||
|
(testing "toString"
|
||||||
|
(is (= ":foo"
|
||||||
|
(bb nil "
|
||||||
|
(def m (reify Object
|
||||||
|
(toString [_] (str :foo))))
|
||||||
|
(str m)
|
||||||
|
"))))
|
||||||
|
(testing "Hashcode still works when only overriding toString"
|
||||||
|
(is (number?
|
||||||
|
(bb nil "
|
||||||
|
(def m (reify Object
|
||||||
|
(toString [_] (str :foo))))
|
||||||
|
(hash m)
|
||||||
|
")))))
|
||||||
|
|
@ -2,14 +2,33 @@
|
||||||
(:require
|
(:require
|
||||||
[babashka.impl.classpath :as cp]
|
[babashka.impl.classpath :as cp]
|
||||||
[babashka.main :as main]
|
[babashka.main :as main]
|
||||||
[me.raynes.conch :refer [let-programs] :as sh]
|
[babashka.process :as p]
|
||||||
|
[clojure.edn :as edn]
|
||||||
|
[clojure.test :as test :refer [*report-counters*]]
|
||||||
[sci.core :as sci]
|
[sci.core :as sci]
|
||||||
[sci.impl.vars :as vars]))
|
[sci.impl.vars :as vars]))
|
||||||
|
|
||||||
(set! *warn-on-reflection* true)
|
(set! *warn-on-reflection* true)
|
||||||
|
|
||||||
|
(def ^:dynamic *bb-edn-path* nil)
|
||||||
|
|
||||||
|
(defmethod clojure.test/report :begin-test-var [m]
|
||||||
|
(println "===" (-> m :var meta :name))
|
||||||
|
(println))
|
||||||
|
|
||||||
|
(defmethod clojure.test/report :end-test-var [_m]
|
||||||
|
(let [{:keys [:fail :error]} @*report-counters*]
|
||||||
|
(when (and (= "true" (System/getenv "BABASHKA_FAIL_FAST"))
|
||||||
|
(or (pos? fail) (pos? error)))
|
||||||
|
(println "=== Failing fast")
|
||||||
|
(System/exit 1))))
|
||||||
|
|
||||||
(defn bb-jvm [input-or-opts & args]
|
(defn bb-jvm [input-or-opts & args]
|
||||||
(reset! cp/cp-state nil)
|
(reset! cp/cp-state nil)
|
||||||
|
(reset! main/env {})
|
||||||
|
(if-let [path *bb-edn-path*]
|
||||||
|
(vreset! main/bb-edn (edn/read-string (slurp path)))
|
||||||
|
(vreset! main/bb-edn nil))
|
||||||
(let [os (java.io.StringWriter.)
|
(let [os (java.io.StringWriter.)
|
||||||
es (if-let [err (:err input-or-opts)]
|
es (if-let [err (:err input-or-opts)]
|
||||||
err (java.io.StringWriter.))
|
err (java.io.StringWriter.))
|
||||||
|
|
@ -30,26 +49,33 @@
|
||||||
(if (string? input-or-opts)
|
(if (string? input-or-opts)
|
||||||
(with-in-str input-or-opts (apply main/main args))
|
(with-in-str input-or-opts (apply main/main args))
|
||||||
(apply main/main args)))]
|
(apply main/main args)))]
|
||||||
|
;; (prn :err (str es))
|
||||||
(if (zero? res)
|
(if (zero? res)
|
||||||
(str os)
|
(str os)
|
||||||
|
(do
|
||||||
|
(println (str os))
|
||||||
(throw (ex-info (str es)
|
(throw (ex-info (str es)
|
||||||
{:stdout (str os)
|
{:stdout (str os)
|
||||||
:stderr (str es)})))))
|
:stderr (str es)}))))))
|
||||||
(finally
|
(finally
|
||||||
(when (string? input-or-opts) (vars/bindRoot sci/in *in*))
|
(when (string? input-or-opts) (vars/bindRoot sci/in *in*))
|
||||||
(vars/bindRoot sci/out *out*)
|
(vars/bindRoot sci/out *out*)
|
||||||
(vars/bindRoot sci/err *err*)))))
|
(vars/bindRoot sci/err *err*)))))
|
||||||
|
|
||||||
(defn bb-native [input & args]
|
(defn bb-native [input & args]
|
||||||
(let-programs [bb "./bb"]
|
(let [res (p/process (into ["./bb"] args)
|
||||||
(try (if input
|
(cond-> {:in input
|
||||||
(apply bb (conj (vec args)
|
:out :string
|
||||||
{:in input}))
|
:err :string}
|
||||||
(apply bb args))
|
*bb-edn-path*
|
||||||
(catch Exception e
|
(assoc
|
||||||
(let [d (ex-data e)
|
:env (assoc (into {} (System/getenv))
|
||||||
err-msg (or (:stderr (ex-data e)) "")]
|
"BABASHKA_EDN" *bb-edn-path*))))
|
||||||
(throw (ex-info err-msg d)))))))
|
res (deref res)
|
||||||
|
exit (:exit res)
|
||||||
|
error? (pos? exit)]
|
||||||
|
(if error? (throw (ex-info (or (:err res) "") {}))
|
||||||
|
(:out res))))
|
||||||
|
|
||||||
(def bb
|
(def bb
|
||||||
(case (System/getenv "BABASHKA_TEST_ENV")
|
(case (System/getenv "BABASHKA_TEST_ENV")
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
(ns babashka.uberjar-test
|
(ns babashka.uberjar-test
|
||||||
(:require
|
(:require
|
||||||
[babashka.test-utils :as tu]
|
[babashka.test-utils :as tu]
|
||||||
[clojure.edn :as edn]
|
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.test :as t :refer [deftest is testing]]))
|
[clojure.test :as t :refer [deftest is testing]]))
|
||||||
|
|
||||||
|
|
@ -10,7 +9,7 @@
|
||||||
path (.getPath tmp-file)]
|
path (.getPath tmp-file)]
|
||||||
(.deleteOnExit tmp-file)
|
(.deleteOnExit tmp-file)
|
||||||
(testing "uberjar"
|
(testing "uberjar"
|
||||||
(tu/bb nil "--classpath" "test-resources/babashka/uberjar/src" "-m" "my.main-main" "--uberjar" path)
|
(tu/bb nil "uberjar" path "--classpath" "test-resources/babashka/uberjar/src" "-m" "my.main-main")
|
||||||
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
||||||
(tu/bb nil "--jar" path "1" "2" "3" "4")))
|
(tu/bb nil "--jar" path "1" "2" "3" "4")))
|
||||||
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
(is (= "(\"1\" \"2\" \"3\" \"4\")\n"
|
||||||
|
|
@ -25,5 +24,5 @@
|
||||||
(let [tmp-file (java.io.File/createTempFile "uber" ".jar")
|
(let [tmp-file (java.io.File/createTempFile "uber" ".jar")
|
||||||
path (.getPath tmp-file)]
|
path (.getPath tmp-file)]
|
||||||
(.deleteOnExit tmp-file)
|
(.deleteOnExit tmp-file)
|
||||||
(tu/bb nil "--classpath" "test-resources/babashka/uberjar/src" "--uberjar" path)
|
(tu/bb nil "uberjar" path "--classpath" "test-resources/babashka/uberjar/src")
|
||||||
(is (str/includes? (tu/bb "(+ 1 2 3)" path) "6")))))
|
(is (str/includes? (tu/bb "(+ 1 2 3)" path) "6")))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue