pods/test-pod/pod/test_pod.clj

199 lines
8.7 KiB
Clojure
Raw Normal View History

2020-05-09 12:03:50 +00:00
(ns pod.test-pod
(:refer-clojure :exclude [read read-string])
(:require [bencode.core :as bencode]
[cheshire.core :as cheshire]
[clojure.edn :as edn]
[clojure.java.io :as io])
(:import [java.io PushbackInputStream])
(:gen-class))
(def debug? false)
(defn debug [& args]
(when debug?
(binding [*out* (io/writer "/tmp/log.txt" :append true)]
(apply println args))))
(def stdin (PushbackInputStream. System/in))
(defn write [v]
(bencode/write-bencode System/out v)
(.flush System/out))
(defn read-string [^"[B" v]
(String. v))
(defn read []
(bencode/read-bencode stdin))
2020-05-21 15:28:14 +00:00
(def dependents
(for [i (range 10)]
{"name" (str "x" i)
"code"
(if-not (zero? i)
(format "(def x%s (inc x%s))" i (dec i))
"(def x0 0)")}))
2020-05-09 12:03:50 +00:00
(defn run-pod [cli-args]
(let [format (if (contains? cli-args "--json")
:json
:edn)
write-fn (if (identical? :json format)
cheshire/generate-string
pr-str)
read-fn (if (identical? :json format)
#(cheshire/parse-string % true)
edn/read-string)]
2020-05-20 18:11:46 +00:00
(try
(loop []
(let [message (try (read)
(catch java.io.EOFException _
::EOF))]
(when-not (identical? ::EOF message)
(let [op (get message "op")
op (read-string op)
op (keyword op)]
(case op
:describe
(do (write {"format" (if (= format :json)
"json"
"edn")
2020-05-22 15:45:01 +00:00
"readers" {"my/tag" "identity"
;; NOTE: this function is defined later,
;; which should be supported
"my/other-tag" "pod.test-pod/read-other-tag"}
2020-05-20 18:11:46 +00:00
"namespaces"
[{"name" "pod.test-pod"
2020-05-21 15:28:14 +00:00
"vars" (into [{"name" "add-sync"}
{"name" "range-stream"
"async" "true"}
{"name" "assoc"}
{"name" "error"}
{"name" "print"}
{"name" "print-err"}
{"name" "return-nil"}
{"name" "do-twice"
2020-05-22 15:45:01 +00:00
"code" "(defmacro do-twice [x] `(do ~x ~x))"}
2020-09-28 14:40:21 +00:00
{"name" "fn-call"
"code" "(defn fn-call [f x] (f x))"}
2020-05-22 15:45:01 +00:00
{"name" "reader-tag"}
;; returns thing with other tag
{"name" "other-tag"}
;; reads thing with other tag
{"name" "read-other-tag"
"code" "(defn read-other-tag [x] [x x])"}]
2020-05-26 14:30:46 +00:00
dependents)}
{"name" "pod.test-pod.loaded"
"defer" "true"}
{"name" "pod.test-pod.loaded2"
"defer" "true"}
{"name" "pod.test-pod.only-code"
"vars" [{"name" "foo"
"code" "(defn foo [] 1)"}]}]
2020-05-20 18:11:46 +00:00
"ops" {"shutdown" {}}})
(recur))
:invoke (let [var (-> (get message "var")
read-string
symbol)
_ (debug "var" var)
id (-> (get message "id")
read-string)
args (get message "args")
args (read-string args)
args (read-fn args)]
(case var
pod.test-pod/add-sync
(try (let [ret (apply + args)]
(write
{"value" (write-fn ret)
"id" id
"status" ["done"]}))
(catch Exception e
(write
{"ex-data" (write-fn {:args args})
"ex-message" (.getMessage e)
"status" ["done" "error"]
"id" id})))
pod.test-pod/range-stream
(let [rng (apply range args)]
(doseq [v rng]
(write
{"value" (write-fn v)
"id" id})
(Thread/sleep 100))
2020-05-09 12:03:50 +00:00
(write
{"status" ["done"]
2020-05-16 21:42:00 +00:00
"id" id}))
2020-05-20 18:11:46 +00:00
pod.test-pod/assoc
(write
{"value" (write-fn (apply assoc args))
"status" ["done"]
"id" id})
pod.test-pod/error
(write
{"ex-data" (write-fn {:args args})
"ex-message" (str "Illegal arguments")
"status" ["done" "error"]
"id" id})
pod.test-pod/print
(do (write
{"out" (pr-str args)
"id" id})
(write
{"status" ["done"]
"id" id}))
pod.test-pod/print-err
(do (write
{"err" (pr-str args)
"id" id})
(write
{"status" ["done"]
"id" id}))
pod.test-pod/return-nil
(write
{"status" ["done"]
"id" id
2020-10-15 08:35:23 +00:00
"value" (write-fn nil)})
2020-05-22 15:45:01 +00:00
pod.test-pod/reader-tag
(write
{"status" ["done"]
"id" id
"value" "#my/tag[1 2 3]"})
pod.test-pod/other-tag
(write
{"status" ["done"]
"id" id
"value" "#my/other-tag[1]"}))
2020-05-20 18:11:46 +00:00
(recur))
2020-05-26 14:30:46 +00:00
:shutdown (System/exit 0)
:load-ns (let [ns (-> (get message "ns")
read-string
symbol)
id (-> (get message "id")
read-string)]
(case ns
pod.test-pod.loaded
(write
{"status" ["done"]
"id" id
"name" "pod.test-pod.loaded"
"vars" [{"name" "loaded"
"code" "(defn loaded [x] (inc x))"}]})
pod.test-pod.loaded2
(write
{"status" ["done"]
"id" id
"name" "pod.test-pod.loaded2"
"vars" [{"name" "x"
"code" "(require '[pod.test-pod.loaded :as loaded])"}
{"name" "loaded"
"code" "(defn loaded [x] (loaded/loaded x))"}]}))
(recur)))))))
2020-05-20 18:11:46 +00:00
(catch Exception e
(binding [*out* *err*]
(prn e))))))
2020-05-09 12:03:50 +00:00
(defn -main [& args]
2020-05-09 17:31:25 +00:00
(when (= "true" (System/getenv "BABASHKA_POD"))
2020-05-09 15:30:20 +00:00
(run-pod (set args))))