v0.0.7
This commit is contained in:
parent
aa8a66c230
commit
a0cd0b58d8
9 changed files with 138 additions and 40 deletions
23
README.md
23
README.md
|
|
@ -17,7 +17,7 @@ $ bb '(vec (dedupe *in*))' <<< '[1 1 1 1 2]'
|
||||||
## Rationale
|
## Rationale
|
||||||
|
|
||||||
If you're a bash expert, you probably don't need this. But for those of us who
|
If you're a bash expert, you probably don't need this. But for those of us who
|
||||||
can use a bit of Clojure in their shell scripts, it may be useful.
|
scan use a bit of Clojure in their shell scripts, it may be useful.
|
||||||
|
|
||||||
Properties:
|
Properties:
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ You may also download a binary from [Github](https://github.com/borkdude/babashk
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
``` shellsession
|
``` shellsession
|
||||||
... | bb [-i] [-o] '<Clojure form>'
|
bb [ --help ] [ -i ] [ -o ] [ -io ] [ --version ] [ expression ]
|
||||||
```
|
```
|
||||||
|
|
||||||
There is one special variable, `*in*`, which is the input read from stdin. The
|
There is one special variable, `*in*`, which is the input read from stdin. The
|
||||||
|
|
@ -77,8 +77,14 @@ shell-scripting friendly output. To combine `-i` and `-o` you can use `-io`.
|
||||||
|
|
||||||
The current version can be printed with `bb --version`.
|
The current version can be printed with `bb --version`.
|
||||||
|
|
||||||
Currently only the macros `if`, `when`, `and`, `or`, `->`, `->>` and `as->` are
|
Currently only the following special forms/macros are supported: anonymous
|
||||||
supported.
|
function literals like `#(%1 %2)`, `quote`, `do`,`if`, `when`, `let`, `and`,
|
||||||
|
`or`, `->`, `->>`, `as->`.
|
||||||
|
|
||||||
|
The `clojure.core` functions are accessible without a namespace alias. Those in
|
||||||
|
`clojure.string` are accessed through the alias `str`, like:
|
||||||
|
`str/includes?`. Those in `clojure.set` using the alias `set`, like:
|
||||||
|
`set/difference`.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
|
@ -109,6 +115,15 @@ $ ls | bb -i '(filterv #(re-find #"reflection" %) *in*)'
|
||||||
["reflection.json"]
|
["reflection.json"]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Shell commands can be executed using `csh` which is an alias for
|
||||||
|
`clojure.java.shell/sh`:
|
||||||
|
|
||||||
|
``` shellsession
|
||||||
|
$ bb '(run! #(csh "touch" (str "/tmp/test/" %)) (range 100))'
|
||||||
|
$ ls /tmp/test | bb -i '*in*'
|
||||||
|
["0" "1" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "2" "20" "21" ...]
|
||||||
|
```
|
||||||
|
|
||||||
More examples can be found in the [gallery](#gallery).
|
More examples can be found in the [gallery](#gallery).
|
||||||
|
|
||||||
## Test
|
## Test
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
:url "http://opensource.org/licenses/eclipse-1.0.php"}
|
:url "http://opensource.org/licenses/eclipse-1.0.php"}
|
||||||
:source-paths ["src"]
|
:source-paths ["src"]
|
||||||
:dependencies [[org.clojure/clojure "1.9.0"]
|
:dependencies [[org.clojure/clojure "1.9.0"]
|
||||||
[borkdude/sci "0.0.2"]]
|
[borkdude/sci "0.0.4"]]
|
||||||
:profiles {:clojure-1.9.0 {:dependencies [[org.clojure/clojure "1.9.0"]]}
|
:profiles {:clojure-1.9.0 {:dependencies [[org.clojure/clojure "1.9.0"]]}
|
||||||
:clojure-1.10.1 {:dependencies [[org.clojure/clojure "1.10.1"]]}
|
:clojure-1.10.1 {:dependencies [[org.clojure/clojure "1.10.1"]]}
|
||||||
:test {:dependencies [[clj-commons/conch "0.9.2"]]}
|
:test {:dependencies [[clj-commons/conch "0.9.2"]]}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,33 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "java.lang.Class",
|
"name": "java.lang.Class",
|
||||||
"allDeclaredConstructors": true,
|
"allDeclaredConstructors": true,
|
||||||
"allPublicConstructors": true,
|
"allPublicConstructors": true,
|
||||||
"allDeclaredMethods": true,
|
"allDeclaredMethods": true,
|
||||||
"allPublicMethods": true
|
"allPublicMethods": true
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"name":"java.io.BufferedReader",
|
||||||
|
"allPublicMethods":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"java.lang.Process",
|
||||||
|
"allPublicMethods":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"java.lang.ProcessBuilder",
|
||||||
|
"allPublicConstructors":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"java.lang.String",
|
||||||
|
"allPublicMethods":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"java.lang.UNIXProcess",
|
||||||
|
"allPublicMethods":true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"java.util.concurrent.LinkedBlockingQueue",
|
||||||
|
"allPublicMethods":true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
0.0.7-SNAPSHOT
|
0.0.7
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,10 @@ $GRAALVM_HOME/bin/native-image \
|
||||||
-J-Dclojure.spec.skip-macros=true \
|
-J-Dclojure.spec.skip-macros=true \
|
||||||
-J-Dclojure.compiler.direct-linking=true \
|
-J-Dclojure.compiler.direct-linking=true \
|
||||||
"-H:IncludeResources=BABASHKA_VERSION" \
|
"-H:IncludeResources=BABASHKA_VERSION" \
|
||||||
|
"-H:IncludeResources=SCI_VERSION" \
|
||||||
-H:ReflectionConfigurationFiles=reflection.json \
|
-H:ReflectionConfigurationFiles=reflection.json \
|
||||||
--initialize-at-build-time \
|
--initialize-at-run-time=java.lang.Math\$RandomNumberGeneratorHolder \
|
||||||
|
--initialize-at-build-time \
|
||||||
-H:Log=registerResource: \
|
-H:Log=registerResource: \
|
||||||
--verbose \
|
--verbose \
|
||||||
--no-fallback \
|
--no-fallback \
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
if [ "$JET_TEST_ENV" = "native" ]; then
|
if [ "$BABASHKA_TEST_ENV" = "native" ]; then
|
||||||
lein test
|
lein test
|
||||||
else
|
else
|
||||||
echo "Testing with Clojure 1.9.0"
|
echo "Testing with Clojure 1.9.0"
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,15 @@
|
||||||
(:require
|
(:require
|
||||||
[clojure.edn :as edn]
|
[clojure.edn :as edn]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
|
[clojure.java.shell :as cjs]
|
||||||
[clojure.string :as str :refer [starts-with?]]
|
[clojure.string :as str :refer [starts-with?]]
|
||||||
[sci.core :as sci])
|
[sci.core :as sci])
|
||||||
(:gen-class))
|
(:gen-class))
|
||||||
|
|
||||||
(set! *warn-on-reflection* true)
|
(set! *warn-on-reflection* true)
|
||||||
|
;; To detect problems when generating the image, run:
|
||||||
|
;; echo '1' | java -agentlib:native-image-agent=config-output-dir=/tmp -jar target/babashka-xxx-standalone.jar '...'
|
||||||
|
;; with the java provided by GraalVM.
|
||||||
|
|
||||||
(defn read-edn [s]
|
(defn read-edn [s]
|
||||||
(edn/read-string
|
(edn/read-string
|
||||||
|
|
@ -33,35 +37,83 @@
|
||||||
(get opts "-io")))
|
(get opts "-io")))
|
||||||
raw-out (boolean (or (get opts "-o")
|
raw-out (boolean (or (get opts "-o")
|
||||||
(get opts "-io")))
|
(get opts "-io")))
|
||||||
println? (boolean (get opts "--println"))]
|
println? (boolean (get opts "--println"))
|
||||||
|
help? (boolean (get opts "--help"))]
|
||||||
{:version version
|
{:version version
|
||||||
:raw-in raw-in
|
:raw-in raw-in
|
||||||
:raw-out raw-out
|
:raw-out raw-out
|
||||||
:println? println?}))
|
:println? println?
|
||||||
|
:help? help?}))
|
||||||
|
|
||||||
|
(defn parse-shell-string [s]
|
||||||
|
(str/split s #"\n"))
|
||||||
|
|
||||||
|
(defn print-version []
|
||||||
|
(println (str "babashka v"(str/trim (slurp (io/resource "BABASHKA_VERSION"))))))
|
||||||
|
|
||||||
|
(def usage-string "Usage: [ --help ] [ -i ] [ -o ] [ -io ] [ --version ] [ expression ]")
|
||||||
|
(defn print-usage []
|
||||||
|
(println usage-string))
|
||||||
|
|
||||||
|
(defn print-help []
|
||||||
|
(println (str "babashka v" (str/trim (slurp (io/resource "BABASHKA_VERSION")))))
|
||||||
|
(println (str "sci v" (str/trim (slurp (io/resource "SCI_VERSION")))))
|
||||||
|
(println)
|
||||||
|
(print-usage)
|
||||||
|
(println)
|
||||||
|
(println "Options:")
|
||||||
|
(println "
|
||||||
|
--help: print this help text.
|
||||||
|
--version: print the current version of babashka.
|
||||||
|
|
||||||
|
-i: read shell input into a list of strings instead of reading EDN.
|
||||||
|
-o: write shell output instead of EDN.
|
||||||
|
-io: combination of -i and -o.
|
||||||
|
"))
|
||||||
|
|
||||||
|
(defn main
|
||||||
|
[& args]
|
||||||
|
(or
|
||||||
|
(let [{:keys [:version :raw-in :raw-out :println?
|
||||||
|
:help?]} (parse-opts args)]
|
||||||
|
(second
|
||||||
|
(cond version
|
||||||
|
[(print-version) 0]
|
||||||
|
help?
|
||||||
|
[(print-help) 0]
|
||||||
|
:else
|
||||||
|
(try
|
||||||
|
[(let [exprs (drop-while #(str/starts-with? % "-") args)
|
||||||
|
_ (when (not= (count exprs) 1)
|
||||||
|
(throw (Exception. ^String usage-string)))
|
||||||
|
expr (last args)
|
||||||
|
in (delay (let [in (slurp *in*)]
|
||||||
|
(if raw-in
|
||||||
|
(parse-shell-string in)
|
||||||
|
(read-edn in))))
|
||||||
|
res (sci/eval-string
|
||||||
|
expr
|
||||||
|
{:bindings {(with-meta '*in*
|
||||||
|
{:sci/deref! true}) in
|
||||||
|
'run! run!
|
||||||
|
'csh cjs/sh}})]
|
||||||
|
(if raw-out
|
||||||
|
(if (coll? res)
|
||||||
|
(doseq [l res]
|
||||||
|
(println l))
|
||||||
|
(println res))
|
||||||
|
((if println? println? prn) res))) 0]
|
||||||
|
(catch Exception e
|
||||||
|
(binding [*out* *err*]
|
||||||
|
(println (str/trim
|
||||||
|
(or (:stderr (ex-data e))
|
||||||
|
(.getMessage e))) ))
|
||||||
|
[nil 1])))))
|
||||||
|
1))
|
||||||
|
|
||||||
(defn -main
|
(defn -main
|
||||||
[& args]
|
[& args]
|
||||||
(let [{:keys [:version :raw-in :raw-out :println?]} (parse-opts args)]
|
(System/exit (apply main args)))
|
||||||
(cond version
|
|
||||||
(println (str/trim (slurp (io/resource "BABASHKA_VERSION"))))
|
|
||||||
:else
|
|
||||||
(let [expr (last args)
|
|
||||||
in (slurp *in*)
|
|
||||||
in (if raw-in
|
|
||||||
(str/split in #"\n")
|
|
||||||
(read-edn in))
|
|
||||||
;; _ (prn in)
|
|
||||||
res (try (sci/eval-string expr {:bindings {'*in* in}})
|
|
||||||
(catch Exception e
|
|
||||||
(binding [*out* *err*]
|
|
||||||
(println (.getMessage e)))
|
|
||||||
(System/exit 1)))]
|
|
||||||
(if raw-out
|
|
||||||
(if (coll? res)
|
|
||||||
(doseq [l res]
|
|
||||||
(println l))
|
|
||||||
(println res))
|
|
||||||
((if println? println? prn) res))))))
|
|
||||||
|
|
||||||
;;;; Scratch
|
;;;; Scratch
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
(:require
|
(:require
|
||||||
[clojure.test :as test :refer [deftest is testing]]
|
[clojure.test :as test :refer [deftest is testing]]
|
||||||
[babashka.test-utils :as test-utils]
|
[babashka.test-utils :as test-utils]
|
||||||
|
[babashka.main :as main]
|
||||||
[clojure.edn :as edn]
|
[clojure.edn :as edn]
|
||||||
[clojure.string :as str]))
|
[clojure.string :as str]))
|
||||||
|
|
||||||
|
|
@ -50,7 +51,7 @@
|
||||||
"-io"
|
"-io"
|
||||||
(str '(shuffle *in*)))
|
(str '(shuffle *in*)))
|
||||||
out-lines (set (str/split out #"\n"))]
|
out-lines (set (str/split out #"\n"))]
|
||||||
(= in-lines out-lines)))
|
(is (= in-lines out-lines))))
|
||||||
(testing "find occurrences in file by line number"
|
(testing "find occurrences in file by line number"
|
||||||
(is (= '(1 3)
|
(is (= '(1 3)
|
||||||
(->
|
(->
|
||||||
|
|
@ -58,3 +59,7 @@
|
||||||
"-i"
|
"-i"
|
||||||
"(map-indexed #(-> [%1 %2]) *in*)")
|
"(map-indexed #(-> [%1 %2]) *in*)")
|
||||||
(bb "(keep #(when (re-find #\"(?i)clojure\" (second %)) (first %)) *in*)"))))))
|
(bb "(keep #(when (re-find #\"(?i)clojure\" (second %)) (first %)) *in*)"))))))
|
||||||
|
|
||||||
|
(deftest input-test
|
||||||
|
(testing "bb doesn't wait for input if *in* isn't used"
|
||||||
|
(is (= "2\n" (with-out-str (main/main "(inc 1)"))))))
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
(defn bb-jvm [input & args]
|
(defn bb-jvm [input & args]
|
||||||
(with-out-str
|
(with-out-str
|
||||||
(with-in-str input
|
(with-in-str input
|
||||||
(apply main/-main args))))
|
(apply main/main args))))
|
||||||
|
|
||||||
(defn bb-native [input & args]
|
(defn bb-native [input & args]
|
||||||
(let-programs [bb "./bb"]
|
(let-programs [bb "./bb"]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue