[Git][clojure-team/trapperkeeper-clojure][upstream] New upstream version 5.0.6

Jérôme Charaoui (@lavamind) gitlab at salsa.debian.org
Tue Sep 8 23:09:17 BST 2026



Jérôme Charaoui pushed to branch upstream at Debian Clojure Maintainers / trapperkeeper-clojure


Commits:
40123b56 by Jérôme Charaoui at 2026-09-08T17:11:09-04:00
New upstream version 5.0.6
- - - - -


9 changed files:

- .github/workflows/backport.yml
- .github/workflows/tests.yml
- project.clj
- src/puppetlabs/trapperkeeper/core.clj
- src/puppetlabs/trapperkeeper/internal.clj
- src/puppetlabs/trapperkeeper/logging.clj
- src/puppetlabs/trapperkeeper/services.clj
- test/puppetlabs/trapperkeeper/internal_test.clj
- test/puppetlabs/trapperkeeper/services_test.clj


Changes:

=====================================
.github/workflows/backport.yml
=====================================
@@ -40,7 +40,7 @@ jobs:
           git config --global commit.gpgsign true
           git config --global tag.gpgsign true
       - name: Checkout repository
-        uses: actions/checkout at 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+        uses: actions/checkout at 3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           token: ${{ secrets.OPENVOXBOT_COMMIT_AND_PRS }}
           ref: main


=====================================
.github/workflows/tests.yml
=====================================
@@ -17,12 +17,12 @@ jobs:
     runs-on: ubuntu-24.04
     steps:
       - name: setup java
-        uses: actions/setup-java at 0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0
+        uses: actions/setup-java at dd06d9cba3e5552c54d9f8ea23572deb30010f7c # v6.0.0
         with:
           distribution: temurin
           java-version: 21
       - name: checkout repo
-        uses: actions/checkout at 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+        uses: actions/checkout at 3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
       - name: Install Clojure tools
         uses: DeLaGuardo/setup-clojure at 4c7a6f613e5089821bb3bb2a33a3ee115578580d # 13.6.1
         with:
@@ -44,11 +44,11 @@ jobs:
     runs-on: ubuntu-24.04
     steps:
       - name: checkout repo
-        uses: actions/checkout at 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+        uses: actions/checkout at 3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
         with:
           submodules: recursive
       - name: setup java
-        uses: actions/setup-java at 0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0
+        uses: actions/setup-java at dd06d9cba3e5552c54d9f8ea23572deb30010f7c # v6.0.0
         with:
           distribution: 'temurin'
           java-version: ${{ matrix.version }}


=====================================
project.clj
=====================================
@@ -1,14 +1,14 @@
 (def slf4j-version "2.0.18")
-(def logback-version "1.5.38")
-(def i18n-version "1.0.4")
+(def logback-version "1.6.3")
+(def i18n-version "1.0.5")
 
-(defproject org.openvoxproject/trapperkeeper "5.0.4"
+(defproject org.openvoxproject/trapperkeeper "5.0.6"
   :description "A framework for configuring, composing, and running Clojure services."
 
   :license {:name "Apache License, Version 2.0"
             :url "http://www.apache.org/licenses/LICENSE-2.0.html"}
 
-  :min-lein-version "2.9.1"
+  :min-lein-version "2.12.0"
 
   ;; Abort when version ranges or version conflicts are detected in
   ;; dependencies. Also supports :warn to simply emit warnings.
@@ -19,7 +19,7 @@
   ;; this project actually uses in :dependencies, inheriting the version from
   ;; :managed-dependencies. This prevents endless version conflicts due to deps of deps.
   ;; Renovate should keep the versions largely in sync between projects.
-  :managed-dependencies [[org.clojure/clojure "1.12.5"]
+  :managed-dependencies [[org.clojure/clojure "1.12.6"]
                          [org.clojure/core.async "1.9.865"]
                          [org.clojure/tools.logging "1.3.1"]
                          [org.clojure/tools.macro "0.2.2"]
@@ -28,20 +28,20 @@
                          [org.slf4j/log4j-over-slf4j ~slf4j-version]
                          [ch.qos.logback/logback-classic ~logback-version]
                          [ch.qos.logback/logback-core ~logback-version]
-                         [ch.qos.logback.access/logback-access-common "2.0.13"]
+                         [ch.qos.logback.access/logback-access-common "2.0.15"]
 
                          [beckon "0.1.1"]
                          [clj-commons/fs "1.6.312"]
-                         [com.kohlschutter.junixsocket/junixsocket-core "2.10.1" :extension "pom"]
+                         [com.kohlschutter.junixsocket/junixsocket-core "2.11.1" :extension "pom"]
                          [commons-io "2.22.0"]
                          [io.github.clj-kondo/config-slingshot-slingshot "1.0.0"]
                          [nrepl/nrepl "0.9.0"]
                          [org.openvoxproject/i18n ~i18n-version]
-                         [org.openvoxproject/kitchensink "3.5.7"]
-                         [org.openvoxproject/kitchensink "3.5.7" :classifier "test"]
+                         [org.openvoxproject/kitchensink "3.5.8"]
+                         [org.openvoxproject/kitchensink "3.5.8" :classifier "test"]
                          [org.openvoxproject/typesafe-config "1.0.4"]
                          [prismatic/plumbing "0.6.0"]
-                         [prismatic/schema "1.4.1"]]
+                         [prismatic/schema "1.4.2"]]
 
   :dependencies [[org.clojure/clojure]
                  [org.clojure/core.async]
@@ -94,9 +94,7 @@
   :plugins [[jonase/eastwood "1.4.3" :exclusions [org.clojure/clojure]]
             [org.openvoxproject/i18n ~i18n-version]]
 
-  :eastwood {:ignored-faults {:reflection {puppetlabs.trapperkeeper.logging [{:line 92}]
-                                           puppetlabs.trapperkeeper.internal [{:line 230}]
-                                           puppetlabs.trapperkeeper.testutils.logging true
+  :eastwood {:ignored-faults {:reflection {puppetlabs.trapperkeeper.testutils.logging true
                                            puppetlabs.trapperkeeper.testutils.logging-test true
                                            puppetlabs.trapperkeeper.services.nrepl.nrepl-service-test true
                                            puppetlabs.trapperkeeper.plugins-test true}


=====================================
src/puppetlabs/trapperkeeper/core.clj
=====================================
@@ -13,19 +13,17 @@
   (:import
    (clojure.lang ExceptionInfo)))
 
-(defmacro service
-  "An alias for the `puppetlabs.trapperkeeper.services/service` macro
-  so that it is accessible from the core namespace along with the
-  rest of the API."
-  [& forms]
-  `(services/service ~@forms))
-
-(defmacro defservice
-  "An alias for the `puppetlabs.trapperkeeper.services/defservice` macro
-  so that it is accessible from the core namespace along with the
-  rest of the API."
-  [svc-name & forms]
-  `(services/defservice ~svc-name ~@forms))
+(def #^{:macro true
+        :doc "An alias for the `puppetlabs.trapperkeeper.services/service` macro
+             so that it is accessible from the core namespace along with the
+             rest of the API."}
+       service #'services/service)
+
+(def #^{:macro true
+        :doc "An alias for the `puppetlabs.trapperkeeper.services/defservice` macro
+             so that it is accessible from the core namespace along with the
+             rest of the API."}
+       defservice #'services/defservice)
 
 (defn build-app
   "Given a list of services and a map of configuration data, build an instance


=====================================
src/puppetlabs/trapperkeeper/internal.clj
=====================================
@@ -10,7 +10,6 @@
 
   (:require [clojure.tools.logging :as log]
             [beckon]
-            [clojure.set :as set]
             [plumbing.graph :as graph]
             [slingshot.slingshot :refer [throw+]]
             [puppetlabs.trapperkeeper.config :refer [config-service get-in-config]]
@@ -74,26 +73,16 @@
             (log/warn (i18n/trs "Unable to connect to NOTIFY_SOCKET {0}"
                                 (pr-str socket-path)))))))))
 
+;;; Messages sent to the SystemD socket to indicate various service states.
+;;; See the "Type=" section of the man page for "systemd.service" for schema:
+;;;
+;;;   https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html#Type=
 (defn notice-service-ready [] (maybe-notify-systemd "READY=1\n"))
-(defn notice-service-reloading [] (maybe-notify-systemd "RELOADING=1\n"))
+(defn notice-service-reloading []
+  (maybe-notify-systemd
+    (str "RELOADING=1\nMONOTONIC_USEC=" (quot (System/nanoTime) 1000) "\n")))
 (defn notice-service-stopping [] (maybe-notify-systemd "STOPPING=1\n"))
 
-(defn maybe-send-ready-notice!
-  [readiness-state]
-  (let [send-notice? (atom false)]
-    (swap! readiness-state
-           (fn [{:keys [notifications-enabled? registered ready notice-sent?] :as state}]
-             (if (and notifications-enabled?
-                      (not notice-sent?)
-                      (seq registered)
-                      (set/subset? registered ready))
-               (do
-                 (reset! send-notice? true)
-                 (assoc state :notice-sent? true))
-               state)))
-    (when @send-notice?
-      (notice-service-ready))))
-
 ;; This is (eww) a global variable that holds a reference to all of the running
 ;; Trapperkeeper apps in the process. It can be used when connecting via nrepl
 ;; to allow you to do useful things, and also may be used for other things
@@ -102,42 +91,6 @@
 
 (def max-pending-lifecycle-events 5)
 
-;; Debounce at the signal handler boundary to avoid back-to-back
-;; restart cycles that can interrupt in-flight agent requests.
-(def min-sighup-restart-interval-ms 500)
-(def last-sighup-restart-ms (atom nil))
-
-(defn now-ms []
-  (System/currentTimeMillis))
-
-(defn should-handle-sighup-restart?
-  []
-  (let [current-ms (now-ms)
-        accepted? (atom false)
-        previous-ms (atom nil)]
-    (swap! last-sighup-restart-ms
-           (fn [last-ms]
-             (reset! previous-ms last-ms)
-             (if (and (some? last-ms)
-                      (< (- current-ms last-ms) min-sighup-restart-interval-ms))
-               last-ms
-               (do
-                 (reset! accepted? true)
-                 current-ms))))
-    (if @accepted?
-      (log/debug (i18n/trs "Accepting SIGHUP restart at {0}; previous accepted restart was {1}"
-                           current-ms
-                           @previous-ms))
-      (log/warn (i18n/trs "Ignoring duplicate SIGHUP restart at {0}; previous accepted restart was {1}; minimum interval is {2} ms"
-                          current-ms
-                          @previous-ms
-                          min-sighup-restart-interval-ms)))
-    @accepted?))
-
-(defn app-log-id
-  [app]
-  (str "app=0x" (Integer/toHexString (System/identityHashCode app))))
-
 (defn service-graph?
   "Predicate that tests whether or not the argument is a valid trapperkeeper
   service graph."
@@ -227,7 +180,7 @@
       (if (sequential? (:error data))
         (let [missing-services (keys (ks/filter-map
                                       (fn [_ v] (= v 'missing-required-key))
-                                      (.error (first (:error data)))))]
+                                      (.error ^schema.utils.NamedError (first (:error data)))))]
           (if (= 1 (count missing-services))
             (throw (RuntimeException.
                     (i18n/trs "Service ''{0}'' not found" (first missing-services))))
@@ -404,7 +357,6 @@
   [apps]
   (log/info (i18n/trs "SIGHUP handler restarting TK apps."))
   (doseq [app apps]
-    (log/info (i18n/trs "Queueing SIGHUP restart for TK {0}" (app-log-id app)))
     (let [{:keys [lifecycle-channel]} @(a/app-context app)
           restart-fn #(a/restart app)]
       (when-not (async/offer! lifecycle-channel
@@ -413,14 +365,6 @@
         (log/warn (i18n/trs "Ignoring new SIGHUP restart requests; too many requests queued ({0})"
                             max-pending-lifecycle-events))))))
 
-(defn maybe-restart-tk-apps
-  "Restart all TK apps unless this SIGHUP request is a rapid duplicate."
-  [apps]
-  (if (should-handle-sighup-restart?)
-    (restart-tk-apps apps)
-    (log/warn (i18n/trs "Ignoring duplicate SIGHUP restart request received within {0} ms"
-                        min-sighup-restart-interval-ms))))
-
 (defn register-sighup-handler
   "Register a handler for SIGHUP that restarts all trapperkeeper apps. The
   default handler terminates the process, so we always overwrite that. This
@@ -429,7 +373,7 @@
    (register-sighup-handler @tk-apps))
   ([apps]
    (log/debug (i18n/trs "Registering SIGHUP handler for restarting TK apps"))
-    (reset! (beckon/signal-atom "HUP") #{(partial maybe-restart-tk-apps apps)})))
+   (reset! (beckon/signal-atom "HUP") #{(partial restart-tk-apps apps)})))
 
 ;;;; Application Shutdown Support
 ;;;;
@@ -531,20 +475,6 @@
     "Higher-order function to execute application logic and trigger shutdown in
     the event of an exception"))
 
-(defprotocol ReadinessService
-  (register-ready! [this service-id]
-    "Register a service that will signal readiness explicitly.")
-  (signal-ready! [this service-id]
-    "Mark a registered service as ready.")
-  (readiness-coordinated? [this]
-    "Returns true if any services have registered explicit readiness coordination.")
-  (enable-ready-notifications! [this]
-    "Allow readiness notifications to be emitted once all registered services are ready.")
-  (reset-readiness! [this]
-    "Reset readiness tracking for a boot or restart cycle.")
-  (readiness-state [this]
-    "Return the current readiness tracking state."))
-
 (schema/defn shutdown-service
   "Provides various functions for triggering application shutdown programatically.
   Primarily intended to serve application services, though TrapperKeeper also uses
@@ -573,60 +503,6 @@
     (shutdown-on-error [this svc-id f] (shutdown-on-error* shutdown-reason-promise app-context svc-id f))
     (shutdown-on-error [this svc-id f on-error] (shutdown-on-error* shutdown-reason-promise app-context svc-id f on-error))))
 
-(schema/defn readiness-service :- (schema/protocol s/ServiceDefinition)
-  "Provides explicit readiness coordination for services that need to delay
-  systemd READY=1 until after their own startup work is complete. Services that
-  participate should call `register-ready!` before app startup completes and
-  `signal-ready!` when they are actually ready to serve traffic."
-  []
-  (let [state (atom {:notifications-enabled? false
-                     :registered #{}
-                     :ready #{}
-                     :notice-sent? false})]
-    (s/service ReadinessService
-      []
-      (register-ready! [_ service-id]
-        (schema/validate schema/Keyword service-id)
-        (swap! state update :registered conj service-id)
-        (maybe-send-ready-notice! state)
-        nil)
-      (signal-ready! [_ service-id]
-        (schema/validate schema/Keyword service-id)
-        (swap! state update :ready conj service-id)
-        (maybe-send-ready-notice! state)
-        nil)
-      (readiness-coordinated? [_]
-        (boolean (seq (:registered @state))))
-      (enable-ready-notifications! [_]
-        (swap! state assoc :notifications-enabled? true)
-        (maybe-send-ready-notice! state)
-        nil)
-      (reset-readiness! [_]
-        (reset! state {:notifications-enabled? false
-                       :registered #{}
-                       :ready #{}
-                       :notice-sent? false})
-        nil)
-      (readiness-state [_]
-        @state))))
-
-(defn reset-readiness-tracking!
-  [services-by-id]
-  (when-let [readiness-service (services-by-id :ReadinessService)]
-    (reset-readiness! readiness-service)))
-
-(defn enable-ready-notifications-for-app!
-  [services-by-id]
-  (when-let [readiness-service (services-by-id :ReadinessService)]
-    (enable-ready-notifications! readiness-service)))
-
-(defn notice-service-ready-if-uncoordinated!
-  [services-by-id]
-  (if-let [readiness-service (services-by-id :ReadinessService)]
-    (when-not (readiness-coordinated? readiness-service)
-      (notice-service-ready))
-    (notice-service-ready)))
-
 (schema/defn ^:always-validate shutdown! :- [Throwable]
   "Perform shutdown calling the `stop` lifecycle function on each service,
    in reverse order (to account for dependency relationships).
@@ -671,6 +547,7 @@
     (ks/add-shutdown-hook! (fn []
                           (when-not (realized? shutdown-reason-promise)
                             (log/info (i18n/trs "Shutting down due to JVM shutdown hook."))
+                            (notice-service-stopping)
                             (shutdown! app-context)
                             (deliver shutdown-reason-promise {:cause :jvm-shutdown-hook}))))
     shutdown-service))
@@ -763,7 +640,6 @@
         service-refs (atom {})
         services (conj services
                        (config-service config-data-fn)
-                       (readiness-service)
                        (initialize-shutdown-service! app-context
                                                      shutdown-reason-promise))
         service-map (apply merge (map s/service-map services))
@@ -791,14 +667,12 @@
       (a/check-for-errors! [this] (throw-app-error-if-exists!
                                    this))
       (a/init [this]
-        (reset-readiness-tracking! services-by-id)
         (run-lifecycle-fns app-context s/init "init" ordered-services)
         this)
       (a/start [this]
         (run-lifecycle-fns app-context s/start "start" ordered-services)
-        (enable-ready-notifications-for-app! services-by-id)
-        (notice-service-ready-if-uncoordinated! services-by-id)
         (inc-restart-counter! this)
+        (notice-service-ready)
         this)
       (a/stop [this]
         (a/stop this false))
@@ -812,17 +686,13 @@
             this)))
       (a/restart [this]
         (try
-          (log/info (i18n/trs "Starting restart for TK {0}" (app-log-id this)))
           (notice-service-reloading)
           (run-lifecycle-fns app-context s/stop "stop" (reverse ordered-services))
           (doseq [svc-id (keys services-by-id)] (swap! app-context assoc-in [:service-contexts svc-id] {}))
-          (reset-readiness-tracking! services-by-id)
           (run-lifecycle-fns app-context s/init "init" ordered-services)
           (run-lifecycle-fns app-context s/start "start" ordered-services)
-          (enable-ready-notifications-for-app! services-by-id)
-          (notice-service-ready-if-uncoordinated! services-by-id)
-          (log/info (i18n/trs "Finished restart for TK {0}" (app-log-id this)))
           (inc-restart-counter! this)
+          (notice-service-ready)
           this
           (catch Throwable t
             (deliver shutdown-reason-promise {:cause :service-error


=====================================
src/puppetlabs/trapperkeeper/logging.clj
=====================================
@@ -77,6 +77,17 @@
               (.toInt ^Level level))
        (.setLevel root level)))))
 
+(defn- do-configure
+  "Calls the appropriate overload of `doConfigure` for the runtime type of
+  `logging-conf`, so that the call can be resolved without reflection."
+  [^JoranConfigurator configurator logging-conf]
+  (condp instance? logging-conf
+    java.io.File (.doConfigure configurator ^java.io.File logging-conf)
+    java.io.InputStream (.doConfigure configurator ^java.io.InputStream logging-conf)
+    java.net.URL (.doConfigure configurator ^java.net.URL logging-conf)
+    org.xml.sax.InputSource (.doConfigure configurator ^org.xml.sax.InputSource logging-conf)
+    (.doConfigure configurator ^String logging-conf)))
+
 (defn configure-logger!
   "Reconfigures the current logger based on the supplied configuration.
 
@@ -89,7 +100,7 @@
         context      (logging-context)]
     (.setContext configurator context)
     (.reset context)
-    (.doConfigure configurator logging-conf)))
+    (do-configure configurator logging-conf)))
 
 (defn configure-logging!
   "Takes a file path, url, file, InputStream, or InputSource which can


=====================================
src/puppetlabs/trapperkeeper/services.clj
=====================================
@@ -103,7 +103,7 @@
                          (get-services [this#]
                            (-> ~'@tk-app-context
                                :services-by-id
-                               (dissoc :ConfigService :ShutdownService :ReadinessService)
+                               (dissoc :ConfigService :ShutdownService)
                                vals))
                          (service-symbol [this#] '~service-sym)
                          (service-included? [this# service-id#]


=====================================
test/puppetlabs/trapperkeeper/internal_test.clj
=====================================
@@ -108,23 +108,4 @@
       (tk-app/stop app)
       ;; and make sure that we got one last :stop
       (is (= (conj expected-lifecycle-events :stop)
-             @lifecycle-events)))))
-
-(deftest test-sighup-restart-debounce
-  (let [restart-calls (atom 0)]
-    (with-redefs [internal/now-ms (let [times (atom [1000 1100 2000])]
-                                    (fn []
-                                      (let [t (first @times)]
-                                        (swap! times rest)
-                                        t)))
-                  internal/restart-tk-apps (fn [_apps]
-                                             (swap! restart-calls inc))
-                  internal/last-sighup-restart-ms (atom nil)]
-      (internal/maybe-restart-tk-apps [:app])
-      (logging/with-test-logging
-        (internal/maybe-restart-tk-apps [:app])
-        (is (logged? "Ignoring duplicate SIGHUP restart request received within 500 ms"
-                     :warn)
-            "Missing expected warning log for duplicate SIGHUP"))
-      (internal/maybe-restart-tk-apps [:app])
-      (is (= 2 @restart-calls)))))
+             @lifecycle-events)))))
\ No newline at end of file


=====================================
test/puppetlabs/trapperkeeper/services_test.clj
=====================================
@@ -55,10 +55,6 @@
 (defprotocol Service3
   (service3-fn [this]))
 
-(defprotocol CoordinatedReadyService
-  (mark-ready [this])
-  (current-readiness-state [this]))
-
 (deftest test-services-not-required
   (testing "services are not required to define lifecycle functions"
     (let [service1 (service Service1
@@ -524,66 +520,6 @@
               (is (= #{:EmptyService :HelloService}
                      (set (map svcs/service-id all-services)))))))))))
 
-(deftest readiness-service-falls-back-to-central-ready-notice
-  (let [ready-notices (atom 0)
-        service1 (service Service1
-                          []
-                          (service1-fn [_] "hi"))]
-    (with-redefs [internal/notice-service-ready #(swap! ready-notices inc)]
-      (with-app-with-empty-config app [service1]
-        (is (= 1 @ready-notices))))))
-
-(deftest readiness-service-defers-ready-notice-until-signaled
-  (let [ready-notices (atom 0)
-        coordinated-service
-        (service CoordinatedReadyService
-                 [[:ReadinessService register-ready! signal-ready! readiness-state]]
-                 (init [_ context]
-                   (register-ready! :CoordinatedReadyService)
-                   context)
-                 (start [_ context]
-                   context)
-                 (mark-ready [_]
-                   (signal-ready! :CoordinatedReadyService))
-                 (current-readiness-state [_]
-                   (readiness-state)))]
-    (with-redefs [internal/notice-service-ready #(swap! ready-notices inc)]
-      (with-app-with-empty-config app [coordinated-service]
-        (let [service (app/get-service app :CoordinatedReadyService)]
-          (is (zero? @ready-notices))
-          (is (= #{:CoordinatedReadyService}
-                 (get-in (current-readiness-state service) [:registered])))
-          (mark-ready service)
-          (is (= 1 @ready-notices))
-          (mark-ready service)
-          (is (= 1 @ready-notices)))))))
-
-(deftest readiness-service-resets-across-restart
-  (let [ready-notices (atom 0)
-        coordinated-service
-        (service CoordinatedReadyService
-                 [[:ReadinessService register-ready! signal-ready! readiness-state]]
-                 (init [_ context]
-                   (register-ready! :CoordinatedReadyService)
-                   context)
-                 (start [_ context]
-                   context)
-                 (mark-ready [_]
-                   (signal-ready! :CoordinatedReadyService))
-                 (current-readiness-state [_]
-                   (readiness-state)))]
-    (with-redefs [internal/notice-service-ready #(swap! ready-notices inc)]
-      (with-app-with-empty-config app [coordinated-service]
-        (let [service (app/get-service app :CoordinatedReadyService)]
-          (mark-ready service)
-          (is (= 1 @ready-notices))
-          (app/restart app)
-          (is (= 1 @ready-notices))
-          (is (= #{:CoordinatedReadyService}
-                 (get-in (current-readiness-state service) [:registered])))
-          (mark-ready service)
-          (is (= 2 @ready-notices)))))))
-
 (deftest minimal-services-test
   (testing "minimal services can be defined without a protocol"
     (let [call-seq (atom [])



View it on GitLab: https://salsa.debian.org/clojure-team/trapperkeeper-clojure/-/commit/40123b56bd17bfc80e94ec27bf1474b88489a36c

-- 
View it on GitLab: https://salsa.debian.org/clojure-team/trapperkeeper-clojure/-/commit/40123b56bd17bfc80e94ec27bf1474b88489a36c
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20260908/c0d7d4a6/attachment.htm>


More information about the pkg-java-commits mailing list