Skip to content

Commit

Permalink
Cleanup and document cljdoc fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ggeoffrey committed Sep 6, 2024
1 parent 221839d commit f499d2d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 30 deletions.
23 changes: 17 additions & 6 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,28 @@
:test {:extra-paths ["test"]
:exec-fn cognitect.test-runner.api/test
:jvm-opts ["-Dhyperfiddle.rcf.generate-tests=true" "-XX:-OmitStackTraceInFastThrow"] ;; https://archive.md/NNt9r
:extra-deps {org.clojure/core.async {:mvn/version "1.6.681", :hyperfiddle.electric.cljdoc/include? true} ; for interop helpers only
:extra-deps {org.clojure/core.async {:mvn/version "1.6.681"} ; for interop helpers only
ch.qos.logback/logback-classic {:mvn/version "1.4.14"}
io.github.cognitect-labs/test-runner {:git/url "https://github.com/cognitect-labs/test-runner.git" :sha "cc75980b43011773162b485f46f939dc5fba91e4"}
org.clojure/test.check {:mvn/version "1.1.1"}
com.datomic/local {:mvn/version "1.0.285", :hyperfiddle.electric.cljdoc/include? true} ; for hyperfiddle.transaction-test
com.datomic/client-cloud {:mvn/version "1.0.130", :hyperfiddle.electric.cljdoc/include? true} ; for hyperfiddle.transaction-test
com.datomic/local {:mvn/version "1.0.285"} ; for hyperfiddle.transaction-test
com.datomic/client-cloud {:mvn/version "1.0.130"} ; for hyperfiddle.transaction-test
thheller/shadow-cljs {:mvn/version "2.26.2"} ; for hooks tests
ring/ring-core {:mvn/version "1.11.0", :hyperfiddle.electric.cljdoc/include? true}
http-kit/http-kit {:mvn/version "2.5.1", :hyperfiddle.electric.cljdoc/include? true}
ring/ring-core {:mvn/version "1.11.0"}
http-kit/http-kit {:mvn/version "2.5.1"}
}}
:build {:extra-paths ["src-build"]
:ns-default build
:extra-deps {io.github.clojure/tools.build {:mvn/version "0.9.6"}
slipset/deps-deploy {:mvn/version "0.2.2"}}}}}
slipset/deps-deploy {:mvn/version "0.2.2"}}}
;; cljdoc loads all namespaces (even flagged ^:no-doc) and requires all deps to be listed in pom.xml
;; Our build script will include the following deps.
;; :pom/scope "provided" means it's up to the artifact's consumer to decide if they actually want
;; to load the dep at runtime. :pom/scope is not part of standard clojure deps or tools.build, our
;; build script interprets it.
:cljdoc-extra-deps
{:extra-deps {org.clojure/core.async {:mvn/version "1.6.681", :pom/scope "provided"}
com.datomic/local {:mvn/version "1.0.285", :pom/scope "provided"}
com.datomic/client-cloud {:mvn/version "1.0.130", :pom/scope "provided"}
ring/ring-core {:mvn/version "1.11.0", :pom/scope "provided"}
http-kit/http-kit {:mvn/version "2.5.1", :pom/scope "provided"}}}}}
28 changes: 4 additions & 24 deletions src-build/build.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
(:require [clojure.data.xml :as xml]
[clojure.tools.build.api :as b]
[clojure.tools.build.tasks.write-pom :as wp]
[clojure.tools.deps.util.maven :as maven]
[deps-deploy.deps-deploy :as dd]))

(def lib 'com.hyperfiddle/electric)
Expand All @@ -15,10 +14,7 @@
(defn extend-basis [basis deps]
(b/create-basis (update (:basis-config basis) :extra merge {:deps deps})))

(defn cljdoc-deps [deps]
(into {} (filter (fn [[_k v]] (contains? v :hyperfiddle.electric.cljdoc/include?)) deps)))

(def basis-with-cljdoc-provided-deps (->> (alias-deps basis :test) cljdoc-deps (extend-basis basis)))
(def basis-with-cljdoc-provided-deps (extend-basis basis (alias-deps basis :cljdoc-extra-deps)))

(def class-dir "target/classes")

Expand All @@ -29,9 +25,10 @@
(xml/alias-uri 'pom "http://maven.apache.org/POM/4.0.0")

(let [original @#'wp/to-dep]
(defn to-dep [[lib {:keys [hyperfiddle.electric.cljdoc/include?] :as coord}]]
(defn to-dep ; Add <scope> support for tools.build POM <dependency> generation. For cljdoc extra deps.
[[lib {:keys [pom/scope] :as coord}]]
(cond-> (original [lib coord])
include? (conj [::pom/scope "provided"]))))
scope (conj [::pom/scope "provided"]))))

(defn jar [{:keys [version] :or {version version}}]
(let [jar-file (format "target/%s-%s.jar" (name lib) version)
Expand Down Expand Up @@ -76,20 +73,3 @@
:basis basis
:javac-opts ["-source" "8" "-target" "8"]}))


;; To run cljdoc analysis locally:
;; 1 - build jar
;; 2 - instal
;; 3 - run next to deps.edn:
;; mkdir -p .cljdoc-preview
;; docker run --rm \
;; --volume $(pwd) \
;; --volume "$HOME/.m2:/root/.m2" \
;; --volume ./.cljdoc-preview \
;; --platform linux/amd64 \
;; --entrypoint clojure \
;; cljdoc/cljdoc -Sforce -M:cli ingest \
;; --project com.hyperfiddle/electric \
;; --version $HYPERFIDDLE_ELECTRIC_BUILD
;; --git . \
;; --rev $(git rev-parse HEAD)
39 changes: 39 additions & 0 deletions src-build/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,42 @@ env $(cat .env | xargs) clojure -T:build deploy :version '"'$HYPERFIDDLE_ELECTRI
- `CLOJARS_PASSWORD` is not your account password, but rather a genareted token granting
deploy rights to the target coordinates.
- idea: how to run tests cli? (No need, deployed artifacts already passed CI)


# About cljdoc

Cljdoc always try to generate documentation for all clojars deployments.
It will load and analyze all namespaces on the classpath.
Namespaces tagged with ^:no-doc will not generate documentation, but they will still be loaded.

Cljdoc requires:
- that all namespaces on the classpath be loadable (as per clojure.core/require),
- that all eventual dependencies required in classpath be listed in pom.xml.

Consequently, dependencies for all namespaces on classpath must be listed in the
**production** release's pom. This is inconvenient because we ship optional
namespaces in the prod artifact, like `contrib.datomic` and
`contrib.missionary-core-async` but we don't want to force a dependency on
datomic or core.async onto users.

To mitigate this issue, [cljdoc advises to list optional dependencies in our
pom.xml as `<scope>provided</scope>`](https://github.com/cljdoc/cljdoc/blob/94cbf3c357695a5a32e3c81a5f2bcdb77b3e2436/doc/userguide/for-library-authors.adoc#getting-dependencies-right),
BUT `clojure.deps` and `tools.build` do not support scopes.
Cljdoc advises to manually edit our pom.xml. We find this too error-prone to be acceptable.

We adapted our build script to generate the correct pom.xml. The generated pom
will production deps + all deps listed under the `:cljdoc-extra-deps` alias.
These deps should be tagged with `:pom/scope "provided"`:

```clojure
{:aliases {:cljdoc-extra-deps {:extra-deps {org.clojure/core.async {:mvn/version "1.6.681", :pom/scope "provided"}}}}}
```

`:pom/scope` is not supported by clojure.deps nor tools.build. Our build script interprets it.

## cljdoc and clojurescript analyzis

cljdoc analyzes cljs and cljc files with cljs.analyzer to detect all defs after
macroexpansion. As of today, cljdoc fails to analyze files containing e/defns.
For now cljdoc do not list cljs namespaces and cljs-only vars.

0 comments on commit f499d2d

Please sign in to comment.