diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..90c1bfd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,40 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '21' + + - name: Install Clojure tooling + uses: DeLaGuardo/setup-clojure@13.4 + with: + lein: latest + + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('project.clj') }} + restore-keys: ${{ runner.os }}-m2- + + - name: Compile Clojure sources + run: lein check + + - name: Run tests + run: lein test + + - name: Compile ClojureScript client + run: lein cljsbuild once smoke diff --git a/.gitignore b/.gitignore index 81b655c..d1d6246 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ pom.xml .lein-deps-sum .lein-repl-history .lein-plugins/ +.lein-failures +.cpcache/ /.nrepl-port .repl /checkouts diff --git a/CHANGES.md b/CHANGES.md index 10b03f5..05095ba 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,17 @@ # Changelog +## 0.8.0 (unreleased) + +### Changes + +* Bump the minimum dependencies to Clojure 1.12 and ClojureScript 1.12. +* Bump `http-kit` to 2.8.1 and (dev-only) `piggieback` to 0.6.0. + +### Enhancements + +* Ship a `deps.edn` so the library can be consumed via the Clojure CLI / tools.deps. +* Add a GitHub Actions CI pipeline and a basic test suite. + ## 0.7.0 ### Enhancements diff --git a/README.md b/README.md index bca31c7..c0889a9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Weasel [![Clojars Project](http://clojars.org/weasel/latest-version.svg)](http://clojars.org/weasel) +[![CI](https://github.com/nrepl/weasel/actions/workflows/ci.yml/badge.svg)](https://github.com/nrepl/weasel/actions/workflows/ci.yml) Weasel uses WebSockets to communicate between a ClojureScript REPL, which is typically hosted on [nREPL][] using [piggieback][], and an @@ -35,6 +36,12 @@ add Weasel as a dependency to `project.clj`: [weasel "0.7.1" :exclusions [org.clojure/clojurescript]] ``` +Or, if you're using `deps.edn`: + +```clojure +{:deps {weasel/weasel {:mvn/version "0.7.1"}}} +``` + Start up `lein repl` and piggieback the Weasel REPL environment onto the nREPL session, optionally specifying a port (defaults to 9001) and an address to bind to (defaults to "127.0.0.1"). diff --git a/deps.edn b/deps.edn new file mode 100644 index 0000000..6af1f43 --- /dev/null +++ b/deps.edn @@ -0,0 +1,15 @@ +{:paths ["src/clj" "src/cljs"] + + :deps {org.clojure/clojure {:mvn/version "1.12.5"} + org.clojure/clojurescript {:mvn/version "1.12.134"} + http-kit/http-kit {:mvn/version "2.8.1"}} + + :aliases + {;; clj -M:dev to get piggieback on the classpath + :dev {:extra-deps {cider/piggieback {:mvn/version "0.6.0"}}} + + ;; clj -M:test to run the test suite via Cognitect's test runner + :test {:extra-paths ["test/clj"] + :extra-deps {io.github.cognitect-labs/test-runner + {:git/tag "v0.5.1" :git/sha "dfb30dd"}} + :main-opts ["-m" "cognitect.test-runner"]}}} diff --git a/project.clj b/project.clj index d6cf0b1..5bf767c 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject weasel "0.7.1" +(defproject weasel "0.8.0-SNAPSHOT" :description "websocket REPL environment for ClojureScript" :url "http://github.com/nrepl/weasel" :license {:name "Unlicense" @@ -7,9 +7,9 @@ :scm {:name "git" :url "https://github.com/nrepl/weasel"} - :dependencies [[org.clojure/clojure "1.10.0"] - [org.clojure/clojurescript "1.10.520"] - [http-kit "2.3.0"]] + :dependencies [[org.clojure/clojure "1.12.5"] + [org.clojure/clojurescript "1.12.134"] + [http-kit "2.8.1"]] :deploy-repositories [["clojars" {:url "https://clojars.org/repo" :username :env/clojars_username @@ -20,5 +20,11 @@ [:name "Tom Jakubowski"] [:email "tom@crystae.net"] [:url "https://github.com/tomjakubowski"]]] - :profiles {:dev {:dependencies [[cider/piggieback "0.4.2"]]}} - :source-paths ["src/clj" "src/cljs"]) + :source-paths ["src/clj" "src/cljs"] + :test-paths ["test/clj"] + :profiles {:dev {:dependencies [[cider/piggieback "0.6.0"]] + :plugins [[lein-cljsbuild "1.1.8"]] + :cljsbuild {:builds [{:id "smoke" + :source-paths ["src/cljs"] + :compiler {:output-to "target/weasel-smoke.js" + :optimizations :advanced}}]}}}) diff --git a/test/clj/weasel/repl/server_test.clj b/test/clj/weasel/repl/server_test.clj new file mode 100644 index 0000000..9fa2623 --- /dev/null +++ b/test/clj/weasel/repl/server_test.clj @@ -0,0 +1,23 @@ +(ns weasel.repl.server-test + (:require [clojure.test :refer [deftest is testing]] + [weasel.repl.server :as server])) + +(deftest start-and-stop + (testing "starting the server populates the shared state" + (try + (server/start (fn [_]) :ip "127.0.0.1" :port 0) + (is (some? (:server @server/state)) "a stop fn is stored") + (is (instance? clojure.lang.IPending (:channel @server/state)) + "a pending client promise is stored") + (finally + (server/stop)))) + + (testing "stopping the server clears the shared state" + (is (nil? (:server @server/state))) + (is (nil? (:channel @server/state))) + (is (nil? (:response-fn @server/state))))) + +(deftest send-without-server-throws + (testing "sending with no running server raises an IOException" + (server/stop) + (is (thrown? java.io.IOException (server/send! "anything"))))) diff --git a/weasel-example/project.clj b/weasel-example/project.clj index ad210c1..7b32cb4 100644 --- a/weasel-example/project.clj +++ b/weasel-example/project.clj @@ -5,8 +5,8 @@ :url "http://unlicense.org/UNLICENSE" :distribution :repo} - :dependencies [[org.clojure/clojure "1.10.0"] - [org.clojure/clojurescript "1.10.520"] + :dependencies [[org.clojure/clojure "1.12.5"] + [org.clojure/clojurescript "1.12.134"] [weasel "0.7.1"]] :repl-options {:welcome (println "Run (start-weasel) to start a Weasel REPL.") @@ -16,8 +16,8 @@ (cider.piggieback/cljs-repl (apply weasel.repl.websocket/repl-env opts))))} :source-paths ["src"] - :profiles {:dev {:dependencies [[cider/piggieback "0.4.2"]] - :plugins [[lein-cljsbuild "1.1.7"]] + :profiles {:dev {:dependencies [[cider/piggieback "0.6.0"]] + :plugins [[lein-cljsbuild "1.1.8"]] :repl-options {:nrepl-middleware [cider.piggieback/wrap-cljs-repl]} :cljsbuild {:builds [{:id "weasel-example" :source-paths ["src"]