[#44] socket-REPL: fix problem with EOF
This commit is contained in:
parent
790f0d4dba
commit
4a485d51a0
4 changed files with 54 additions and 41 deletions
2
sci
2
sci
|
|
@ -1 +1 @@
|
||||||
Subproject commit 225dfe2314f2789b3050be2a70f10c123c13d277
|
Subproject commit ade0d29a4d3d97d9d6c958434368d5fa4359debf
|
||||||
|
|
@ -106,10 +106,7 @@
|
||||||
read-eval-print
|
read-eval-print
|
||||||
(fn []
|
(fn []
|
||||||
(try
|
(try
|
||||||
(let [input (try
|
(let [input (read request-prompt request-exit)]
|
||||||
(read request-prompt request-exit)
|
|
||||||
(catch LispReader$ReaderException e
|
|
||||||
(throw (ex-info nil {:clojure.error/phase :read-source} e))))]
|
|
||||||
(or (#{request-prompt request-exit} input)
|
(or (#{request-prompt request-exit} input)
|
||||||
(let [value (eval input)]
|
(let [value (eval input)]
|
||||||
(set! *3 *2)
|
(set! *3 *2)
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,46 @@
|
||||||
(ns babashka.impl.socket-repl
|
(ns babashka.impl.socket-repl
|
||||||
{:no-doc true}
|
{:no-doc true}
|
||||||
(:require [babashka.impl.clojure.core.server :as server]
|
(:require
|
||||||
[babashka.impl.clojure.main :as m]
|
[babashka.impl.clojure.core.server :as server]
|
||||||
[sci.core :refer [eval-string]]
|
[babashka.impl.clojure.main :as m]
|
||||||
[sci.impl.parser :as parser]
|
[clojure.java.io :as io]
|
||||||
[sci.impl.toolsreader.v1v3v2.clojure.tools.reader.reader-types :as r]
|
[clojure.string :as str]
|
||||||
[clojure.string :as str]
|
[sci.core :refer [eval-string]]
|
||||||
[clojure.java.io :as io]))
|
[sci.impl.parser :as parser]
|
||||||
|
[sci.impl.toolsreader.v1v3v2.clojure.tools.reader.reader-types :as r]))
|
||||||
|
|
||||||
(set! *warn-on-reflection* true)
|
(set! *warn-on-reflection* true)
|
||||||
|
|
||||||
(defn repl
|
(defn repl
|
||||||
"REPL with predefined hooks for attachable socket server."
|
"REPL with predefined hooks for attachable socket server."
|
||||||
[sci-opts]
|
[sci-opts]
|
||||||
(m/repl
|
(let [in (r/indexing-push-back-reader (r/push-back-reader *in*))]
|
||||||
:init #(do (println "Babashka"
|
(m/repl
|
||||||
(str "v" (str/trim (slurp (io/resource "BABASHKA_VERSION"))))
|
:init #(do (println "Babashka"
|
||||||
"REPL.")
|
(str "v" (str/trim (slurp (io/resource "BABASHKA_VERSION"))))
|
||||||
(println "Use :repl/quit or :repl/exit to quit the REPL.")
|
"REPL.")
|
||||||
(println "Clojure rocks, Bash reaches.")
|
(println "Use :repl/quit or :repl/exit to quit the REPL.")
|
||||||
(println))
|
(println "Clojure rocks, Bash reaches.")
|
||||||
:read (fn [request-prompt request-exit]
|
(println))
|
||||||
(let [in (r/indexing-push-back-reader (r/push-back-reader *in*))
|
:read (fn [_request-prompt request-exit]
|
||||||
p (r/peek-char in)]
|
(if (r/peek-char in) ;; if this is nil, we reached EOF
|
||||||
(if (= \newline p)
|
|
||||||
(do (r/read-char in) request-prompt)
|
|
||||||
(let [v (parser/parse-next {} in)]
|
(let [v (parser/parse-next {} in)]
|
||||||
(if (or (identical? :repl/quit v)
|
(if (or (identical? :repl/quit v)
|
||||||
(identical? :repl/exit v))
|
(identical? :repl/exit v)
|
||||||
|
(identical? :sci.impl.parser/eof v))
|
||||||
request-exit
|
request-exit
|
||||||
v)))))
|
v))
|
||||||
:eval (fn [expr]
|
request-exit))
|
||||||
(eval-string (str expr)
|
:eval (fn [expr]
|
||||||
(update sci-opts
|
(let [ret (eval-string (pr-str expr)
|
||||||
:bindings
|
(update sci-opts
|
||||||
merge {'*1 *1
|
:bindings
|
||||||
'*2 *2
|
merge {'*1 *1
|
||||||
'*3 *3
|
'*2 *2
|
||||||
'*e *e})))))
|
'*3 *3
|
||||||
|
'*e *e}))]
|
||||||
|
ret))
|
||||||
|
:need-prompt (fn [] true))))
|
||||||
|
|
||||||
(defn start-repl! [host+port sci-opts]
|
(defn start-repl! [host+port sci-opts]
|
||||||
(let [parts (str/split host+port #":")
|
(let [parts (str/split host+port #":")
|
||||||
|
|
@ -60,7 +63,6 @@
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(def sock (start-repl! "0.0.0.0:1666" {:env (atom {})}))
|
(def sock (start-repl! "0.0.0.0:1666" {:env (atom {})}))
|
||||||
(.accept sock)
|
|
||||||
@#'server/servers
|
@#'server/servers
|
||||||
(stop-repl!)
|
(stop-repl!)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,31 @@
|
||||||
[babashka.test-utils :as tu]
|
[babashka.test-utils :as tu]
|
||||||
[clojure.java.shell :refer [sh]]
|
[clojure.java.shell :refer [sh]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.test :as t :refer [deftest is]]))
|
[clojure.test :as t :refer [deftest is testing]]))
|
||||||
|
|
||||||
|
(def mac?
|
||||||
|
(str/includes?
|
||||||
|
(str/lower-case (System/getProperty "os.name"))
|
||||||
|
"mac"))
|
||||||
|
|
||||||
(deftest socket-repl-test
|
(deftest socket-repl-test
|
||||||
(when tu/jvm?
|
(when tu/jvm?
|
||||||
(start-repl! "0.0.0.0:1666" {:env (atom {})})
|
(try
|
||||||
(is (str/includes? (:out (sh "bash" "-c"
|
(start-repl! "0.0.0.0:1666" {:env (atom {})})
|
||||||
"echo \"(+ 1 2 3)\n:repl/exit\" | nc 127.0.0.1 1666"))
|
(is (str/includes? (:out (sh "bash" "-c"
|
||||||
"bb=> 6"))
|
"echo \"(+ 1 2 3)\n:repl/exit\" | nc 127.0.0.1 1666"))
|
||||||
(stop-repl!)))
|
"bb=> 6"))
|
||||||
|
(testing "ctrl-d exits normally, doesn't print nil"
|
||||||
|
(is (str/ends-with? (:out (sh "bash" "-c"
|
||||||
|
(if mac? ;; mac doesn't support -q
|
||||||
|
"echo \"(inc 1336)\" | nc 127.0.0.1 1666"
|
||||||
|
"echo \"(inc 1336)\" | nc -q 1 127.0.0.1 1666")))
|
||||||
|
"1337\nbb=> ")))
|
||||||
|
(finally
|
||||||
|
(stop-repl!)))))
|
||||||
|
|
||||||
;;;; Scratch
|
;;;; Scratch
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
|
(socket-repl-test)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue