26 Development
How to set up a development environment, run tests, author notebooks, and release new versions.
REPL Setup
Start an nREPL server with the :dev alias, which adds notebooks, tests, Clay, and related dependencies to the classpath. One way to do it is the following:
clojure -M:dev -m nrepl.cmdlineConnect to the REPL from your editor (Calva, CIDER, Cursive, etc.) using the port printed to the console (also written to .nrepl-port).
Running Tests
The test suite runs via cognitect test-runner:
./run_tests.shThis is equivalent to:
clojure -M:dev:test -m cognitect.test-runnerThere are two kinds of tests:
Hand-written tests in
test/scicloj/napkinsketch/— unit tests for core logic (view resolution, plan resolution, rendering, etc.)Generated tests in
test/napkinsketch_book/— produced from notebooks every time Clay renders notebooks using Clay’s test generation. Everykind/test-lastform in a notebook becomes an assertion in the corresponding*_generated_test.cljfile.
Regenerating Tests
After editing a notebook, you may regenerate its test file by rendering it:
(require '[scicloj.clay.v2.api :as clay])
(clay/make! {:source-path "napkinsketch_book/scatter.clj"})This updates test/napkinsketch_book/scatter_generated_test.clj. The generated test files are checked into version control.
To regenerate all notebooks at once:
(require 'dev)
(dev/make-gfm!) ; in Github Flavored Markdown format
;; or:
(dev/make-book!) ; as an HTML bookBuilding the Book
The full HTML book is rendered through Clay and Quarto:
(require '[dev :as dev])
(dev/make-book!)Chapter ordering is defined in notebooks/chapters.edn. The output goes to the docs/ directory and is published to scicloj.github.io/napkinsketch.
Generating the README
The README.md is generated from notebooks/readme.clj using Clay’s GFM (GitHub-Flavored Markdown) output. The notebook contains live code examples that produce SVG plots, so the README always shows current output.
(require '[dev :as dev])
(dev/make-readme!)This produces:
README.mdat the repo rootreadme_files/*.svg— rendered plot images referenced by the README
The book’s index.clj reads README.md and copies readme_files/ into notebooks/ so that the book’s front page shows the same images. Run make-readme! before make-book! when the README content changes.
Note: the readme notebook uses sk/plot (eager rendering) instead of auto-rendering Sketch, because GFM mode requires materialized SVG values.
Building a JAR
The build uses tools.build with deps-deploy:
clojure -T:build ci # run tests + build JAR
clojure -T:build ci :snapshot true # build snapshot JARThe JAR is written to target/.
Deploying to Clojars
Two convenience scripts handle the full build-and-deploy workflow:
./release.sh # test + build + deploy release
./snapshot.sh # test + build + deploy snapshotBoth run tests first, then build the JAR, then deploy to Clojars. Deployment requires CLOJARS_USERNAME and CLOJARS_PASSWORD environment variables (or a ~/.m2/settings.xml with credentials).
Continuous Integration
GitHub Actions runs the test suite on every push and pull request to main (see .github/workflows/tests.yml). The workflow uses Java 21 (Temurin) and the latest Clojure CLI.