Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add babashka pod #674

Merged
merged 5 commits into from
Dec 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dir-locals.el
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
((clojure-mode
(cider-clojure-cli-aliases . "-A:test")))
(cider-clojure-cli-aliases . "test")))
11 changes: 9 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ jobs:
- name: Generate embedded binary
run: make prod-bin

- name: Run babashka pod tests
run: make pod-test

- name: Run integration tests
run: make integration-test

Expand Down Expand Up @@ -164,6 +167,10 @@ jobs:
mv clojure-lsp-native/clojure-lsp .
chmod +x clojure-lsp

- name: Run babashka pod tests
env:
CLOJURE_LSP_TEST_ENV: native
run: make pod-test

- name: Run integration tests
run: |
make integration-test
run: make integration-test
10 changes: 10 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ jobs:
with:
file: clojure-lsp

- name: Run babashka pod tests
env:
CLOJURE_LSP_TEST_ENV: native
run: make pod-test

- name: Run integration tests
run: |
make integration-test
Expand Down Expand Up @@ -231,6 +236,11 @@ jobs:
# with:
# file: clojure-lsp

- name: Run babashka pod tests
env:
CLOJURE_LSP_TEST_ENV: native
run: make pod-test

- name: Run integration tests
run: |
make integration-test
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Avoid high CPU and lockup when clj-kondo throws exceptions. #671
- Allow absolute paths in deps.edn :local/root #672
- Fix clojure-lsp not loading for some mono-repo cases, improving local/root support for polylith projects. #673
- Add babashka pod. #555

- Editor
- Change call hierarchy to return selection range of usage, not function definition.
Expand Down
13 changes: 8 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ all: debug-bin
# https://clojure.org/guides/getting_started#_clojure_installer_and_cli_tools

clean:
rm -rf classes clojure-lsp clojure-lsp.jar docs/README.md
rm -rf classes clojure-lsp clojure-lsp.jar docs/README.md docs/CHANGELOG.md

classes:
clojure -X:javac
Expand All @@ -34,6 +34,12 @@ prod-native:
test: classes
clojure -M:test

pod-test: classes
clojure -M:pod-test

integration-test:
bb integration-test ./clojure-lsp

lint-clean:
clojure -M:run clean-ns --dry --ns-exclude-regex "sample-test.*"

Expand All @@ -50,12 +56,9 @@ lint-fix:
release:
./release

integration-test:
bb integration-test ./clojure-lsp

local-webpage:
cp -rf CHANGELOG.md README.md images docs
docker login docker.pkg.github.com
docker run --rm -it -p 8000:8000 -v ${PWD}:/docs docker.pkg.github.com/clojure-lsp/docs-image/docs-image

.PHONY: all classes debug-bin prod-jar prod-jar-for-native prod-bin prod-native test integration-test local-webpage clean release
.PHONY: all classes debug-bin prod-jar prod-jar-for-native prod-bin prod-native test pod-test integration-test local-webpage clean release
9 changes: 9 additions & 0 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
:exclusions [rewrite-cljs/rewrite-cljs
com.googlecode.java-diff-utils/diffutils]}
com.googlecode.java-diff-utils/diffutils {:mvn/version "1.3.0"}
nrepl/bencode {:mvn/version "1.1.0"}
medley/medley {:mvn/version "1.3.0"}
anonimitoraf/clj-flx {:mvn/version "1.2.0"}
clj-kondo/clj-kondo {:mvn/version "2021.12.16"}
Expand All @@ -25,6 +26,14 @@
:aliases {:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.60.972"}}
:extra-paths ["test"]
:main-opts ["-m" "kaocha.runner"]}
:pod-test
{:replace-paths ["pod-test"]
:replace-deps {com.cognitect/transit-clj {:mvn/version "1.0.324"}
cognitect/test-runner {:git/url "https://github.com/cognitect-labs/test-runner"
:sha "cb96e80f6f3d3b307c59cbeb49bb0dcb3a2a780b"}
babashka/babashka.pods {:git/url "https://github.com/babashka/babashka.pods"
:sha "f360afa6135b8bd2d384d9ba4582c0de6fdac804"}}
:main-opts ["-m" "cognitect.test-runner" "-d" "pod-test"]}
:javac {:replace-deps {org.suskalo/americano {:mvn/version "1.2.0"}}
:exec-fn americano.cli/javac
:exec-args {:source-paths ["src-java"]}}
Expand Down
4 changes: 4 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Remember to install your build tool, like `clojure` or `leiningen` as well in yo

To run clojure-lsp from Leiningen easily, check [lein-clojure-lsp](https://github.com/clojure-lsp/lein-clojure-lsp) plugin.

### Babashka pod

It's possible to load clojure-lsp as a babashka pod giving access to the `clojure-lsp.api` namespace, Check babashka pod registry [example](https://github.com/babashka/pod-registry/blob/master/examples/clojure-lsp.clj).

## Settings

clojure-lsp will check for `.lsp/config.edn` in the project or home dir, but it's possible to force override the settings via the `:settings` option of the API or `--settings` option of the CLI.
Expand Down
2 changes: 2 additions & 0 deletions pod-test/clojure_lsp/.dir-locals.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
((clojure-mode
(cider-clojure-cli-aliases . "pod-test")))
43 changes: 43 additions & 0 deletions pod-test/clojure_lsp/pod_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(ns clojure-lsp.pod-test
(:require
[babashka.pods :as pods]
[clojure.java.io :as io]
[clojure.test :refer [deftest is testing]]))

(def pod-spec (if (= "native" (System/getenv "CLOJURE_LSP_TEST_ENV"))
["./clojure-lsp"]
["clojure" "-M:run"]))

(pods/load-pod pod-spec)
(require '[clojure-lsp.api :as clojure-lsp])

#_{:clj-kondo/ignore [:unresolved-var]}
(deftest pod-test
(testing "analyze-project!"
(let [result (clojure-lsp/analyze-project!
{:project-root (io/file "integration-test/sample-test")
:raw? true})]
(is result)))
(testing "clean-ns!"
(let [result (clojure-lsp/clean-ns!
{:project-root (io/file "integration-test/sample-test")
:namespace '[sample-test.api.format.a]
:raw? true
:dry? true})]
(is (= 1 (:result-code result)))
(is (seq (:edits result)))))
(testing "diagnostics"
(let [result (clojure-lsp/diagnostics
{:project-root (io/file "integration-test/sample-test")
:raw? true
:dry? true})]
(is (not= 0 (:result-code result)))
(is (seq (:diagnostics result)))))
(testing "format!"
(let [result (clojure-lsp/format!
{:project-root (io/file "integration-test/sample-test")
:namespace '[sample-test.api.format.a]
:raw? true
:dry? true})]
(is (= 1 (:result-code result)))
(is (seq (:edits result))))))
8 changes: 7 additions & 1 deletion src/clojure_lsp/main.clj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
[clojure.java.io :as io]
[clojure.string :as string]
[clojure.tools.cli :refer [parse-opts]]
[pod.clojure-lsp.api :as pod]
[taoensso.timbre :as log])
(:import
[clojure_lsp WarningLogDisabler])
Expand Down Expand Up @@ -93,8 +94,12 @@
(string/join \newline errors)))

(defn ^:private parse [args]
(let [{:keys [options arguments errors summary]} (parse-opts args (cli-options))]
(let [{:keys [options arguments errors summary]} (parse-opts args (cli-options))
pod? (= "true" (System/getenv "BABASHKA_POD"))]
(cond
pod?
{:action "pod" :options options}

(:help options)
{:exit-message (help summary) :ok? true}

Expand Down Expand Up @@ -134,6 +139,7 @@
{:exit-code 0})
(try
(case action
"pod" (pod/run-pod)
"clean-ns" (internal-api/clean-ns! options)
"diagnostics" (internal-api/diagnostics options)
"format" (internal-api/format! options)
Expand Down
135 changes: 135 additions & 0 deletions src/pod/clojure_lsp/api.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
(ns pod.clojure-lsp.api
{:no-doc true}
(:refer-clojure :exclude [read read-string])
(:require
[bencode.core :as bencode]
[clojure-lsp.api :as api]
[cognitect.transit :as transit])
(:import
[java.io PushbackInputStream])
(:gen-class))

(set! *warn-on-reflection* true)

(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))

;; transit

;;; payload
(def jiofile-key (str ::file))

(def jiofile-read-handler
(transit/read-handler (fn [^String s] (java.io.File. s))))

(def jiofile-write-handler
(transit/write-handler jiofile-key str))

(defn reg-transit-handlers
[]
(format "
(require 'babashka.pods)
(babashka.pods/add-transit-read-handler!
\"%s\"
(fn [s] (java.io.File. s)))
(babashka.pods/add-transit-write-handler!
#{java.io.File}
\"%s\"
str)
"
jiofile-key jiofile-key))

(def transit-read-handlers
(delay
(transit/read-handler-map
{jiofile-key jiofile-read-handler})))

(def transit-write-handlers
(delay
(transit/write-handler-map
{java.io.File jiofile-write-handler})))

(defn read-transit [^String v]
(transit/read
(transit/reader
(java.io.ByteArrayInputStream. (.getBytes v "utf-8"))
:json
{:handlers @transit-read-handlers})))

(defn write-transit [v]
(let [baos (java.io.ByteArrayOutputStream.)]
(transit/write
(transit/writer
baos
:json
{:handlers @transit-write-handlers}) v)
(.toString baos "utf-8")))

(def api-vars
{'clojure-lsp.api/analyze-project! api/analyze-project!
'clojure-lsp.api/clean-ns! api/clean-ns!
'clojure-lsp.api/diagnostics api/diagnostics
'clojure-lsp.api/format! api/format!
'clojure-lsp.api/rename! api/rename!})

(defn run-pod []
(loop []
(let [message (try (read)
(catch java.io.EOFException _
::EOF))]
(when-not (identical? ::EOF message)
(let [op (-> (get message "op")
read-string
keyword)
id (some-> (get message "id")
read-string
(or "unknown"))]
(case op
:describe (do (write {"format" "transit+json"
"namespaces" [{:name "borkdude.tdn.pod"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a borkdude.tnd.pod from tools-deps-native here. Probably want to rename that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, thanks!

:vars [{:name '-reg-transit-handlers
:code (reg-transit-handlers)}]}
{"name" "clojure-lsp.api"
"vars" (->> api-vars
keys
(mapv (fn [k] {"name" (name k)})))}]
"id" id})
(recur))
:invoke (do (try
(let [var (-> (get message "var")
read-string
symbol)
args (some-> (get message "args")
read-string
read-transit)]
(if-let [f (api-vars var)]
(let [value (-> (apply f args)
write-transit)
reply {"value" value
"id" id
"status" ["done"]}]
(write reply))
(throw (ex-info (str "Var not found: " var) {}))))
(catch Throwable e
(binding [*out* *err*]
(println e))
(let [reply {"ex-message" (.getMessage e)
"ex-data" (write-transit
(assoc (ex-data e)
:type (class e)))
"id" id
"status" ["done" "error"]}]
(write reply))))
(recur))
(do
(write {"err" (str "unknown op:" (name op))})
(recur))))))))