From 9cbe6b1696f3290dced7241988dfb54a15742881 Mon Sep 17 00:00:00 2001 From: awb99 Date: Wed, 11 Sep 2024 16:16:47 -0500 Subject: [PATCH] quanta-studio move-out --- .github/workflows/ci.yml | 37 ++++++++++++++ .gitignore | 36 +++++++++++++ README.md | 12 ++++- build.clj | 53 ++++++++++++++++++++ deps.edn | 16 ++++++ resources/ext/docy.edn | 9 ++++ src/docy/core.clj | 88 ++++++++++++++++++++++++++++++++ src/docy/page.cljs | 106 +++++++++++++++++++++++++++++++++++++++ src/docy/util.cljs | 34 +++++++++++++ 9 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 build.clj create mode 100644 deps.edn create mode 100644 resources/ext/docy.edn create mode 100644 src/docy/core.clj create mode 100644 src/docy/page.cljs create mode 100644 src/docy/util.cljs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d9311fd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Prepare java + uses: actions/setup-java@v2 + with: + distribution: 'zulu' # https://github.com/actions/setup-java/blob/main/README.md#Supported-distributions + java-version: '14' + java-package: jdk # optional (jdk or jre) - defaults to jdk + - name: Install clojure tools + uses: DeLaGuardo/setup-clojure@3.5 + with: + cli: 1.11.1.1413 # Clojure CLI based on tools.deps + clj-kondo: 2022.05.31 # Clj-kondo + cljfmt: 0.10.2 # cljfmt + - name: deploy to clojars + if: success() + env: + CLOJARS_USERNAME: ${{ secrets.ReleaseUsername }} + CLOJARS_PASSWORD: ${{ secrets.ReleasePassword }} + run: | + git config --global user.email "ci@pinkgorilla.org" + git config --global user.name "CI/CD" + clojure -T:build jar + clojure -T:build deploy diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ef6e4f --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +*.jar +*.class +/lib/ +/classes/ +/target/ +/checkouts/ +.nrepl-port +.cpcache/ +/test/creds.edn +.classpath +.project +.settings/* +.calva +.lsp/ +.webly +certs +target/ +ci/deps.edn +demo-webly/karma.conf.js +\#*\# +creds.edn +creds-wien.edn +creds-localhost.edn +.clj-kondo +*~ +\#*\# +.\#* +.~* +.shadow-cljs +node_modules +karma.conf.js +package.json +package-lock.json +shadow-cljs.edn +goldly_bindings_generated.cljs +resources/META-INF \ No newline at end of file diff --git a/README.md b/README.md index d3a2ff8..b2a0a34 100644 --- a/README.md +++ b/README.md @@ -1 +1,11 @@ -# docy \ No newline at end of file +# docy [![GitHub Actions status |pink-gorilla/docy](https://github.com/pink-gorilla/docy/workflows/CI/badge.svg)](https://github.com/pink-gorilla/docy/actions?workflow=CI)[![Clojars Project](https://img.shields.io/clojars/v/org.pinkgorilla/docy.svg)](https://clojars.org/org.pinkgorilla/docy) + + +## features + +- Docy shows dynamically customizable documentation for clojure namespaces. +- Generated Documentation can be shown statically (say on github pages) +- or it can be run interactively, which allows evaluating discovered examples. + + + diff --git a/build.clj b/build.clj new file mode 100644 index 0000000..edf7193 --- /dev/null +++ b/build.clj @@ -0,0 +1,53 @@ +(ns build + (:require + [babashka.fs :as fs] + [clojure.tools.build.api :as b] + [deps-deploy.deps-deploy :as dd])) + +(def lib 'org.pinkgorilla/docy) +(def version (format "0.0.%s" (b/git-count-revs nil))) +(def class-dir "target/classes") +(def basis (b/create-basis {:project "deps.edn"})) +(def jar-file (format "target/%s-%s.jar" (name lib) version)) + +(defn clean [_] + (b/delete {:path "target"})) + + +(def pom-template + [[:licenses + [:license + [:name "Eclipse Public License"] + [:url "https://www.eclipse.org/legal/epl-v10.html"]]] + [:developers + [:developer + [:name "pink-gorilla"]]] + [:scm + [:url "https://github.com/pink-gorilla/docy"] + [:connection "scm:git:git://github.com/pink-gorilla/docy.git"] + [:developerConnection "scm:git:ssh://git@github.com/pink-gorilla/docy.git"]]]) + + +(def opts {:class-dir class-dir + :lib lib + :version version + :basis basis + :pom-data pom-template + :src-dirs ["src"]}) + +(defn jar [_] + (b/write-pom opts) + (b/copy-dir {:src-dirs ["src" "resources"] + :target-dir class-dir}) + (b/jar {:class-dir class-dir + :jar-file jar-file})) + + +(defn deploy "Deploy the JAR to Clojars." [_] + (println "Deploying to Clojars.") + (dd/deploy {:installer :remote + ;:sign-releases? true + :pom-file (b/pom-path (select-keys opts [:lib :class-dir])) + ;:artifact "target/tech.ml.dataset.jar" + :artifact (b/resolve-path jar-file)})) + diff --git a/deps.edn b/deps.edn new file mode 100644 index 0000000..e266532 --- /dev/null +++ b/deps.edn @@ -0,0 +1,16 @@ +{:paths ["src" + "resources" ; extension data + ] + :deps + {org.clojure/clojure {:mvn/version "1.11.3"} + cider/orchard {:mvn/version "0.26.1"} + org.pinkgorilla/extension {:mvn/version "0.0.12"} + org.pinkgorilla/clj-service {:mvn/version "0.3.20"}} + :aliases + {; github ci + :build {:deps {io.github.clojure/tools.build {:mvn/version "0.9.6"} + slipset/deps-deploy {:mvn/version "0.2.1"} + babashka/fs {:mvn/version "0.0.5"}} + :ns-default build}} +; + } diff --git a/resources/ext/docy.edn b/resources/ext/docy.edn new file mode 100644 index 0000000..dca3f61 --- /dev/null +++ b/resources/ext/docy.edn @@ -0,0 +1,9 @@ +{:name "docy" + ; run-time + :sci-cljs-ns [docy.page] + :cljs-routes {"docy" {"" docy.page/docy-page + ["/ns/" :nss] docy.page/docy-ns-page + ["/ns/" :nss "/" :fun] docy.page/docy-fun-page}} + +; + } \ No newline at end of file diff --git a/src/docy/core.clj b/src/docy/core.clj new file mode 100644 index 0000000..6bab3bf --- /dev/null +++ b/src/docy/core.clj @@ -0,0 +1,88 @@ +(ns docy.core + (:require + [orchard.info :as orchard] + [taoensso.timbre :refer [info warn error]] + [extension :as ext] + [clj-service.core :refer [expose-functions]])) + +(defn docstring [symbol] + (:doc (meta (resolve symbol)))) + +(defn describe-fun [nss fun] + (let [data (orchard/info nss fun)] + (merge + data + {:ns (str (:ns data)) + :name (str (:name data))}))) + + +(defn describe-ns [nss] + (require [nss]) + (let [symbols (keys (ns-publics nss))] + {:ns (str nss) + :names (->> symbols + (map #(describe-fun nss %)) + (filter :doc) + (remove :deprecated ) + (sort-by :name) + )})) + +(defn build-namespaces [ns-symbol-seq] + (info "building namespaces: " (count ns-symbol-seq)) + (let [r (->> (map describe-ns ns-symbol-seq) + (sort-by :ns) + ;(take 1) + (into []))] + ;(info "result: " r) + r)) + +(defn start-docy [{:keys [exts clj role namespaces]}] + (info "starting docy .. ") + (assert (vector? namespaces)) + (info "starting docy namespaces: " (count namespaces)) + ;(add-discovered-namespaces this exts) + (if clj + (do + (info "starting docy clj-services..") + (expose-functions clj + {:name "docy" + :symbols ['docy.core/build-namespaces] + :permission role + :fixed-args [namespaces]})) + (warn "docy starting without clj-services, perhaps you want to pass :clj key")) + (info "docy running!") + namespaces) + +(comment + (orchard/info 'missionary.core 'amb>) + (describe-fun 'missionary.core 'amb>) + + ; deprecated should be removed + ; so amb and amb= should exist, but amb> should not + (->> (describe-ns 'missionary.core) + :names + (map :name)) + + (->> (describe-ns 'missionary.core) + :names + (filter #(= "amb" (:name %))) + ) + + + (describe-ns 'ta.calendar.core) + + (describe-ns 'ta.indicator.band) + + + (require '[modular.system]) + + (def d (modular.system/system :docy)) + + d + + (build-namespaces d) + + + + ; + ) \ No newline at end of file diff --git a/src/docy/page.cljs b/src/docy/page.cljs new file mode 100644 index 0000000..247d441 --- /dev/null +++ b/src/docy/page.cljs @@ -0,0 +1,106 @@ +(ns docy.page + (:require + [reagent.core :as r] + [promesa.core :as p] + [frontend.notification :refer [show-notification]] + [goldly.service.core :refer [clj]] + [docy.util :refer [link text]])) + +(def namespaces-dict-a (r/atom {})) + +(defn ns-seq->dict [ns-seq] + (->> ns-seq + (map (fn [{:keys [ns names]}] + [ns names])) + (into {}))) + +(defn ^:export init-docy! + [new-namespaces] + (println "init-docy: " new-namespaces) + (println "init-docy! ns-count: " (count new-namespaces)) + (reset! namespaces-dict-a (ns-seq->dict new-namespaces))) + +(defn get-data [] + (let [rp (clj 'docy.core/build-namespaces)] + (-> rp + (p/then (fn [ns-seq] + (init-docy! ns-seq))) + (p/catch (fn [err] + (println "docy fetch ns-seq error: " err) + (show-notification :error "docy ns-seq fetch failed!")))))) + +; this makes sense because it only needs to be done once. +(get-data) + +(defn docy-fun-page [{:keys [route-params] :as route}] + (fn [{:keys [route-params] :as route}] + (let [{:keys [nss fun]} route-params + data (get @namespaces-dict-a nss)] + [:div + [:h1.text-xxl.text-blue-800 "Namespace: " (str nss) " Function: " (str fun)] + [:div (pr-str data)]]))) + +;{:ns "missionary.core", +; :name "amb", +; :doc "In an `ap` block, evaluates each form sequentially and returns successive results.", +; :file "missionary/core.cljc", +; :arglists ([] [form] [form & forms]), +; :macro true, +; :line 496, +; :column 1} + + +(defn fun-ui [{:keys [name doc file line column arglists macro] :as fun}] + [:<> + ; colum left - function name + [:h1.text-xxl.text-blue-800.m-1.p-1 + name] + ; column right - arglist and docstring + [:div {:class "bg-gray-300 border-solid border-green-300" + :style {:max-height "4cm" + :overflow "auto"}} + (when arglists + [:span {:class "text-blue-900 text-bold"} + (str arglists)]) + (when macro + [:span {:class "text-red-500 p-1"} "macro"]) + [text doc]]]) + +(defn docy-ns-page [{:keys [route-params] :as route}] + (fn [{:keys [route-params] :as route}] + (let [{:keys [nss]} route-params + data (get @namespaces-dict-a nss)] + [:div.p-5 + [:h1.text-xxl.text-blue-800 "Namespace: " (str nss)] + ;[:div (pr-str data)] + [into [:div + {:class "grid gap-1" ;.grid-cols-2.auto-cols-min + :style {:grid-template-columns "1fr 4fr" + :max-width "1200px"}}] (map fun-ui data)]]))) + +(defn ns-entry [ns-name] + [:li {:style {:width "100px" + :min-width "100px"}} + [link {:to ['docy.page/docy-ns-page :nss (str ns-name)]} + [:span {:style {:width "100px" + :min-width "100px"} + :class "w-64" + } + (str ns-name)]]]) + +(defn ns-list [ns-symbol-seq] + (if (seq? ns-symbol-seq) + (into [:ul {:style {:width "100px" + :min-width "100px"}}] + + (map ns-entry ns-symbol-seq)) + [:div "no docs available!"])) + +(defn docy-page [_route] + (fn [{:keys [route-params] :as route}] + (let [ns-symbol-seq (keys @namespaces-dict-a)] + [:div.m-3.h-screen.w-screen + [:h1.text-xxl.text-blue-800.p-2 "Docy Documentation "] + [ns-list ns-symbol-seq] + ;[:div (pr-str ns-symbol-seq)] + ]))) diff --git a/src/docy/util.cljs b/src/docy/util.cljs new file mode 100644 index 0000000..125fddd --- /dev/null +++ b/src/docy/util.cljs @@ -0,0 +1,34 @@ +(ns docy.util + (:require + [clojure.string :as str] + [re-frame.core :as rf])) + +;; links + +(defn link [{:keys [to class style] :as opts + :or {class "bg-blue-600 cursor-pointer hover:bg-red-700 m-1" + style {}}} & body] + (let [v (->> (concat [:bidi/goto] to) + (into [])) + goto-link (fn [& _] + (println "going to: " v) + (rf/dispatch v))] + (println "link: " v) + (into [:a {:class class + :style style + :on-click goto-link}] body))) + + +(defn line-with-br [t] + [:div + [:span.font-mono.text-xs.whitespace-pre t] + [:br]]) + +(defn text + "Render text (as string) to html + works with \\n (newlines) + Needed because \\n is meaningless in html" + [t] + (let [lines (str/split t #"\n")] + (into [:div ] (map line-with-br lines)))) +