diff --git a/README.md b/README.md index 34b993d..ef2b599 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# vibe +# tbd A small Clojure HTTP API built on [Ring](https://github.com/ring-clojure/ring) (Jetty) and [reitit](https://github.com/metosin/reitit), with Swagger UI docs, unit tests, dockerized @@ -24,8 +24,8 @@ PORT=8080 clojure -X:run Or build and run the container: ```bash -docker build -t vibe . -docker run --rm -p 3000:3000 vibe +docker build -t tbd . +docker run --rm -p 3000:3000 tbd ``` ## API @@ -80,7 +80,7 @@ collected. ## Project layout ``` -src/vibe/ +src/tbd/ core.clj Router, Ring app, and server startup /routes.clj Each route group (health, math, ...) owns its route subtree /core.clj Business logic for the group, with no HTTP concerns @@ -89,5 +89,5 @@ integration-test/ Dockerized integration tests and coverage harness script/ Bash entry points (test, coverage, repl, ...) and coverage helpers ``` -To add a new group, create `vibe..routes` with a `routes` fn that returns a reitit route -vector, then add it to the router in `src/vibe/core.clj`. +To add a new group, create `tbd..routes` with a `routes` fn that returns a reitit route +vector, then add it to the router in `src/tbd/core.clj`. diff --git a/deps.edn b/deps.edn index 458f9c6..29c4bbf 100644 --- a/deps.edn +++ b/deps.edn @@ -16,8 +16,8 @@ :extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}} :main-opts ["-m" "cognitect.test-runner"]} ;; Line coverage via Cloverage. Only adds the dep + test path; the entry points - ;; (unit: cloverage.coverage, integration: vibe.integration.coverage) are chosen in script/unit-coverage and script/integration-coverage. + ;; (unit: cloverage.coverage, integration: tbd.integration.coverage) are chosen in script/unit-coverage and script/integration-coverage. :cov {:extra-paths ["test"] :extra-deps {cloverage/cloverage {:mvn/version "1.2.4"}}} - :run {:exec-fn vibe.core/start-server}}} + :run {:exec-fn tbd.core/start-server}}} diff --git a/integration-test/README.md b/integration-test/README.md index 4abfc28..9855395 100644 --- a/integration-test/README.md +++ b/integration-test/README.md @@ -1,6 +1,6 @@ # Integration Tests -Dockerized integration tests for the vibe server. +Dockerized integration tests for the tbd server. ## Quick Start @@ -13,7 +13,7 @@ docker-compose up --abort-on-container-exit ## Manual Run (app already running) -If your vibe app is running locally on port 3000: +If your tbd app is running locally on port 3000: ```bash cd integration-test @@ -65,7 +65,7 @@ unit tests, the integration tests, and both combined. From the repo root: | Task | What it does | Output | |------|--------------|--------| | `script/unit-coverage` | Runs `test/` under Cloverage | `target/coverage/unit/` | -| `script/integration-coverage` | Runs the integration suite against a Cloverage-instrumented `vibe-app` container | `target/coverage/integration/` | +| `script/integration-coverage` | Runs the integration suite against a Cloverage-instrumented `tbd-app` container | `target/coverage/integration/` | | `script/coverage-report` | Merges the two `lcov.info` files, prints a per-file table | `target/coverage/merged/` | | `script/coverage` | All three, in order (the full suite with a joint report) | all of the above | @@ -74,7 +74,7 @@ merged report a line counts as covered if either suite hit it; the HTML shows pe counts per suite (`u:` unit, `i:` integration). How the integration numbers are collected: `docker-compose.coverage.yml` starts the app via -`vibe.integration.coverage`, which lets Cloverage instrument `src/` and then serves real +`tbd.integration.coverage`, which lets Cloverage instrument `src/` and then serves real traffic until it receives SIGTERM. `script/integration-coverage` stops the container (`docker compose stop`) so the report gets written, then copies it out with `docker compose cp`. Plain `script/integration-test` / `script/test` are unchanged and run the uninstrumented app. diff --git a/integration-test/docker-compose.coverage.yml b/integration-test/docker-compose.coverage.yml index fb7fa77..2541d0d 100644 --- a/integration-test/docker-compose.coverage.yml +++ b/integration-test/docker-compose.coverage.yml @@ -1,8 +1,8 @@ -# Overlay for `script/integration-coverage`: runs vibe-app under Cloverage instead of plainly. +# Overlay for `script/integration-coverage`: runs tbd-app under Cloverage instead of plainly. # Reports land in /app/target/coverage/integration inside the container; script/integration-test copies # them out after the app is stopped (SIGTERM is what triggers the report). services: - vibe-app: + tbd-app: build: args: DEPS_ALIASES: run:cov @@ -10,13 +10,13 @@ services: - clojure - -M:cov - -m - - vibe.integration.coverage + - tbd.integration.coverage - --runner - integration - --src-ns-path - src - --extra-test-ns - - vibe.integration.coverage + - tbd.integration.coverage - --lcov - --html - --output diff --git a/integration-test/docker-compose.yml b/integration-test/docker-compose.yml index ae11fe4..2fd5235 100644 --- a/integration-test/docker-compose.yml +++ b/integration-test/docker-compose.yml @@ -1,15 +1,15 @@ services: - vibe-app: - image: vibe-app-integration + tbd-app: + image: tbd-app-integration build: context: .. dockerfile: Dockerfile ports: - - "${VIBE_PORT:-3000}:${VIBE_PORT:-3000}" + - "${TBD_PORT:-3000}:${TBD_PORT:-3000}" security_opt: - apparmor:unconfined environment: - - PORT=${VIBE_PORT:-3000} + - PORT=${TBD_PORT:-3000} # No container healthcheck: healthchecks run via `docker exec`, which hits the # same LXC/AppArmor runc bug (opencontainers/runc#5007) as image builds and # always fails here. integration_test.bb polls the server until it's ready. @@ -17,12 +17,12 @@ services: # The suite is baked into the image (Dockerfile) rather than bind-mounted: bind mounts # resolve on the Docker host, so they break when run from inside a CI job container. integration-test: - image: vibe-integration-test + image: tbd-integration-test build: context: . security_opt: - apparmor:unconfined depends_on: - vibe-app: + tbd-app: condition: service_started - entrypoint: ["bb", "/integration_test.bb", "http://vibe-app:${VIBE_PORT:-3000}"] + entrypoint: ["bb", "/integration_test.bb", "http://tbd-app:${TBD_PORT:-3000}"] diff --git a/integration-test/vibe/integration/coverage.clj b/integration-test/tbd/integration/coverage.clj similarity index 82% rename from integration-test/vibe/integration/coverage.clj rename to integration-test/tbd/integration/coverage.clj index e87ef90..43c1d4d 100644 --- a/integration-test/vibe/integration/coverage.clj +++ b/integration-test/tbd/integration/coverage.clj @@ -1,12 +1,12 @@ -(ns vibe.integration.coverage - "Entry point that runs the vibe server under Cloverage instrumentation so the +(ns tbd.integration.coverage + "Entry point that runs the tbd server under Cloverage instrumentation so the black-box integration tests produce a line-coverage report. Cloverage normally instruments the source and then runs a test suite in-process. Here the 'suite' is the outside world: the runner starts the real server and blocks until the JVM gets SIGTERM (`docker compose stop`), then Cloverage writes its reports. - Deliberately does not require any vibe.* source namespace at load time: those must + Deliberately does not require any tbd.* source namespace at load time: those must be loaded by Cloverage (instrumented), not by us." (:require [cloverage.coverage :as cov])) @@ -14,7 +14,7 @@ (fn [_nses] (let [stop (promise) main (Thread/currentThread)] - ((requiring-resolve 'vibe.core/start-server)) + ((requiring-resolve 'tbd.core/start-server)) ;; The report is written by the main thread after the runner returns, but the JVM ;; only stays up while shutdown hooks run, so the hook must wait for the main thread. (.addShutdownHook (Runtime/getRuntime) diff --git a/script/coverage_report.clj b/script/coverage_report.clj index af829b6..98ae8c4 100644 --- a/script/coverage_report.clj +++ b/script/coverage_report.clj @@ -37,7 +37,7 @@ (format "%3d/%-3d %6.1f%%" hit total pct)) (defn read-source [file] - ;; Cloverage's SF: paths are usually project-relative already (src/vibe/core.clj); fall + ;; Cloverage's SF: paths are usually project-relative already (src/tbd/core.clj); fall ;; back to the source roots in case they are classpath-relative. (some (fn [dir] (let [f (io/file dir file)] (when (.isFile f) (slurp f)))) [nil "src" "test" "integration-test"])) @@ -52,7 +52,7 @@ (format "%.1f%% (%d/%d)" (pct-class (:pct s)) (:pct s) (:hit s) (:total s)))) files (sort (keys merged))] - (str "vibe line coverage + (str "tbd line coverage -

vibe line coverage

+

tbd line coverage

" (apply str (for [k (keys per-suite)] (str ""))) "" diff --git a/script/docker-unit-coverage b/script/docker-unit-coverage index 024a2cc..5e677a5 100755 --- a/script/docker-unit-coverage +++ b/script/docker-unit-coverage @@ -8,7 +8,7 @@ source script/lib/docker.sh build_unit_image -id=$(docker create --security-opt apparmor=unconfined vibe-unit \ +id=$(docker create --security-opt apparmor=unconfined tbd-unit \ clojure -M:cov -m cloverage.coverage \ --src-ns-path src --test-ns-path test \ --lcov --html --output target/coverage/unit) diff --git a/script/docker-unit-test b/script/docker-unit-test index 29e1a4d..83d0917 100755 --- a/script/docker-unit-test +++ b/script/docker-unit-test @@ -5,4 +5,4 @@ cd "$(dirname "$0")/.." source script/lib/docker.sh build_unit_image -exec docker run --rm --security-opt apparmor=unconfined vibe-unit clojure -M:test "$@" +exec docker run --rm --security-opt apparmor=unconfined tbd-unit clojure -M:test "$@" diff --git a/script/integration-test b/script/integration-test index ca14e3d..9b88a42 100755 --- a/script/integration-test +++ b/script/integration-test @@ -28,7 +28,7 @@ free_port_in_range() { } port=$(free_port_in_range 30000 40000) -echo "[test] starting vibe-app on random port $port${COVERAGE:+ (under coverage instrumentation)}" +echo "[test] starting tbd-app on random port $port${COVERAGE:+ (under coverage instrumentation)}" compose=(docker compose) if [[ -n "${COVERAGE:-}" ]]; then @@ -38,7 +38,7 @@ fi use_builder cd integration-test -export VIBE_PORT=$port +export TBD_PORT=$port teardown() { local status=$? @@ -56,9 +56,9 @@ trap 'exit 143' TERM # builds. DEPS_ALIASES must match build.args in docker-compose.coverage.yml. docker buildx build --load \ --build-arg "DEPS_ALIASES=run${COVERAGE:+:cov}" \ - -t vibe-app-integration \ + -t tbd-app-integration \ -f "$root/Dockerfile" "$root" -docker buildx build --load -t vibe-integration-test "$root/integration-test" +docker buildx build --load -t tbd-integration-test "$root/integration-test" # `run` returns the test container's own exit code; `up --abort-on-container-exit` can leak # the app's SIGTERM exit (143) during teardown instead. @@ -69,11 +69,11 @@ if [[ -n "${COVERAGE:-}" ]]; then # SIGTERM is what makes Cloverage write its report, so stop (not kill) the app and pull # the report out of the stopped container before `down` removes it. out_dir=$root/target/coverage - echo "[test] stopping vibe-app to flush coverage report" - "${compose[@]}" stop -t 120 vibe-app || true + echo "[test] stopping tbd-app to flush coverage report" + "${compose[@]}" stop -t 120 tbd-app || true rm -rf "$out_dir/integration" mkdir -p "$out_dir" - if ! "${compose[@]}" cp vibe-app:/app/target/coverage/integration "$out_dir" \ + if ! "${compose[@]}" cp tbd-app:/app/target/coverage/integration "$out_dir" \ || [[ ! -f $out_dir/integration/lcov.info ]]; then echo "[test] WARNING: no integration coverage report was produced" fi diff --git a/script/lib/docker.sh b/script/lib/docker.sh index c85d0d0..c1a2345 100644 --- a/script/lib/docker.sh +++ b/script/lib/docker.sh @@ -4,7 +4,7 @@ # (opencontainers/runc#5007) that fails RUN steps during image build. use_builder() { - local builder=vibe-builder + local builder=tbd-builder if ! docker buildx inspect "$builder" >/dev/null 2>&1; then docker buildx create --name "$builder" \ --driver docker-container \ @@ -13,8 +13,8 @@ use_builder() { docker buildx use "$builder" } -# Builds the app image with the test and coverage deps pre-fetched, tagged vibe-unit. +# Builds the app image with the test and coverage deps pre-fetched, tagged tbd-unit. build_unit_image() { use_builder - docker buildx build --load --build-arg DEPS_ALIASES=test:cov -t vibe-unit . + docker buildx build --load --build-arg DEPS_ALIASES=test:cov -t tbd-unit . } diff --git a/src/vibe/core.clj b/src/tbd/core.clj similarity index 75% rename from src/vibe/core.clj rename to src/tbd/core.clj index 35c62da..f5e1388 100644 --- a/src/vibe/core.clj +++ b/src/tbd/core.clj @@ -1,4 +1,4 @@ -(ns vibe.core +(ns tbd.core (:require [ring.adapter.jetty :as jetty] [ring.middleware.defaults :refer [wrap-defaults api-defaults]] [ring.middleware.head :refer [wrap-head]] @@ -7,22 +7,22 @@ [reitit.swagger-ui :as swagger-ui] [reitit.ring.middleware.muuntaja :as muuntaja-middleware] [muuntaja.core :as m] - [vibe.health.routes :as health] - [vibe.math.routes :as math])) + [tbd.health.routes :as health] + [tbd.math.routes :as math])) -;; Each logical group (health, users, orders, ...) owns a `vibe..routes` +;; Each logical group (health, users, orders, ...) owns a `tbd..routes` ;; namespace that returns its own route subtree; they're concatenated here. (def router (ring/router [["/swagger.json" {:get {:no-doc true - :swagger {:info {:title "vibe API" :version "1.0.0"}} + :swagger {:info {:title "tbd API" :version "1.0.0"}} :handler (swagger/create-swagger-handler)}}] ["/" {:get {:no-doc true :handler (fn [_req] {:status 200 :headers {"Content-Type" "text/plain; charset=utf-8"} - :body "vibe API — see /api-docs for documentation, /swagger.json for the spec"})}}] + :body "tbd API — see /api-docs for documentation, /swagger.json for the spec"})}}] (health/routes) (math/routes)] {:data {:muuntaja m/instance @@ -44,15 +44,15 @@ (defn start-server [& [_ opts]] (let [port (Integer/parseInt (str (or (System/getenv "PORT") (get opts :port 3000))))] - (println (format "[vibe] starting server on port %d..." port)) + (println (format "[tbd] starting server on port %d..." port)) (try (let [server (jetty/run-jetty (wrap-defaults app api-defaults) {:port port :join? false})] - (println (format "vibe server running on http://localhost:%d" port)) + (println (format "tbd server running on http://localhost:%d" port)) (add-shutdown-hook server)) (catch Throwable t - (println "[vibe] FAILED to start server:" (.getMessage t)) + (println "[tbd] FAILED to start server:" (.getMessage t)) (.printStackTrace t) (throw t))))) diff --git a/src/vibe/health/routes.clj b/src/tbd/health/routes.clj similarity index 92% rename from src/vibe/health/routes.clj rename to src/tbd/health/routes.clj index cbb0a89..0ad84ab 100644 --- a/src/vibe/health/routes.clj +++ b/src/tbd/health/routes.clj @@ -1,4 +1,4 @@ -(ns vibe.health.routes) +(ns tbd.health.routes) (defn routes [] ["/api/ping" diff --git a/src/vibe/math/core.clj b/src/tbd/math/core.clj similarity index 83% rename from src/vibe/math/core.clj rename to src/tbd/math/core.clj index b0f6d0c..6b106d0 100644 --- a/src/vibe/math/core.clj +++ b/src/tbd/math/core.clj @@ -1,4 +1,4 @@ -(ns vibe.math.core +(ns tbd.math.core "Business logic for the math group. No HTTP concerns in here.") (defn add [x y] diff --git a/src/vibe/math/routes.clj b/src/tbd/math/routes.clj similarity index 91% rename from src/vibe/math/routes.clj rename to src/tbd/math/routes.clj index e60da7c..a4fb788 100644 --- a/src/vibe/math/routes.clj +++ b/src/tbd/math/routes.clj @@ -1,5 +1,5 @@ -(ns vibe.math.routes - (:require [vibe.math.core :as math])) +(ns tbd.math.routes + (:require [tbd.math.core :as math])) (defn- parse-num [s] (when s diff --git a/test/vibe/math/core_test.clj b/test/tbd/math/core_test.clj similarity index 85% rename from test/vibe/math/core_test.clj rename to test/tbd/math/core_test.clj index 887dad8..2f66f63 100644 --- a/test/vibe/math/core_test.clj +++ b/test/tbd/math/core_test.clj @@ -1,6 +1,6 @@ -(ns vibe.math.core-test +(ns tbd.math.core-test (:require [clojure.test :refer [deftest is testing]] - [vibe.math.core :as math])) + [tbd.math.core :as math])) (deftest add-test (testing "integers"
File" (name k) "merged