refactor: doerg는 publisher와 결합 #40

Merged
msyds merged 3 commits from 결합 into main 2026-04-03 13:30:59 -06:00
88 changed files with 158 additions and 622 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
((nil . ((cider-clojure-cli-aliases . ":dev:test"))))
-2
View File
@@ -9,5 +9,3 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: build doerg - name: build doerg
run: nix build -L .#doerg run: nix build -L .#doerg
- name: build publisher
run: nix build -L .#publisher
-1
View File
@@ -9,7 +9,6 @@ result-*
.lsp .lsp
.nrepl .nrepl
.direnv/ .direnv/
resources/vendor/*
node_modules node_modules
.cljs_node_repl .cljs_node_repl
build/ build/
+8 -3
View File
@@ -4,8 +4,9 @@
, doerg-parser , doerg-parser
, doerg-temml-worker , doerg-temml-worker
, ibm-plex-web , ibm-plex-web
, test-emacs ? callPackage ./test-emacs.nix {}
, fake-git , fake-git
, our-tex ? callPackage ./our-tex.nix {} , our-tex
, makeWrapper , makeWrapper
, writeText , writeText
}: }:
@@ -43,7 +44,7 @@ in mkCljBin' {
name = "net.deertopia/doerg"; name = "net.deertopia/doerg";
version = "0.1.0"; version = "0.1.0";
projectSrc = lib.cleanSource ./.; projectSrc = lib.cleanSource ./.;
lockfile = ../deps-lock.json; lockfile = ./deps-lock.json;
main-ns = "net.deertopia.doerg.main"; main-ns = "net.deertopia.doerg.main";
nativeBuildInputs = [ nativeBuildInputs = [
plex plex
@@ -58,6 +59,7 @@ in mkCljBin' {
nativeCheckInputs = [ nativeCheckInputs = [
doerg-parser doerg-parser
doerg-temml-worker doerg-temml-worker
test-emacs
plex plex
our-tex our-tex
]; ];
@@ -66,7 +68,10 @@ in mkCljBin' {
''; '';
doCheck = true; doCheck = true;
checkPhase = '' checkPhase = ''
export \
EMACS=test-emacs \
XDG_STATE_HOME=$(mktemp -d "state-home-XXXXXX")
clojure -M:test clojure -M:test
''; '';
passthru = { inherit plex our-tex; }; passthru = { inherit plex our-tex test-emacs; };
} }
+1 -29
View File
@@ -1,14 +1,6 @@
{ {
"lock-version": 4, "lock-version": 4,
"git-deps": [ "git-deps": [],
{
"lib": "io.github.msyds/spec-dict",
"url": "https://github.com/msyds/spec-dict.git",
"rev": "531d629b7f05f37232261cf9e8927a4b5915714f",
"git-dir": "https/github.com/msyds/spec-dict",
"hash": "sha256-5hMdPsB8OhOCtByPZS+CHXzVLq0H+OBKKnXec21xwmg="
}
],
"mvn-deps": [ "mvn-deps": [
{ {
"mvn-path": "aero/aero/1.1.6/aero-1.1.6.jar", "mvn-path": "aero/aero/1.1.6/aero-1.1.6.jar",
@@ -145,11 +137,6 @@
"mvn-repo": "https://repo1.maven.org/maven2/", "mvn-repo": "https://repo1.maven.org/maven2/",
"hash": "sha256-ccrFOSFR4qUozJoJF58KM0F58FxS+OWWz1jd8Suyfys=" "hash": "sha256-ccrFOSFR4qUozJoJF58KM0F58FxS+OWWz1jd8Suyfys="
}, },
{
"mvn-path": "com/fasterxml/jackson/core/jackson-core/2.20.0/jackson-core-2.20.0.jar",
"mvn-repo": "https://repo1.maven.org/maven2/",
"hash": "sha256-vAz0YHWHcgH4QG7n3idBrn32wGb18EV72AYypxjAbnI="
},
{ {
"mvn-path": "com/fasterxml/jackson/core/jackson-core/2.20.0/jackson-core-2.20.0.pom", "mvn-path": "com/fasterxml/jackson/core/jackson-core/2.20.0/jackson-core-2.20.0.pom",
"mvn-repo": "https://repo1.maven.org/maven2/", "mvn-repo": "https://repo1.maven.org/maven2/",
@@ -370,11 +357,6 @@
"mvn-repo": "https://repo.clojars.org/", "mvn-repo": "https://repo.clojars.org/",
"hash": "sha256-OaawIvv0GgkuZwK6MAFtmuyw3zNcYiZVd66K/IipB2A=" "hash": "sha256-OaawIvv0GgkuZwK6MAFtmuyw3zNcYiZVd66K/IipB2A="
}, },
{
"mvn-path": "fipp/fipp/0.6.26/fipp-0.6.26.jar",
"mvn-repo": "https://repo.clojars.org/",
"hash": "sha256-98tpbM5Vr9dMg41UQUGcfl9tSRrxhajlY9+nl5aFcoM="
},
{ {
"mvn-path": "fipp/fipp/0.6.26/fipp-0.6.26.pom", "mvn-path": "fipp/fipp/0.6.26/fipp-0.6.26.pom",
"mvn-repo": "https://repo.clojars.org/", "mvn-repo": "https://repo.clojars.org/",
@@ -970,11 +952,6 @@
"mvn-repo": "https://repo1.maven.org/maven2/", "mvn-repo": "https://repo1.maven.org/maven2/",
"hash": "sha256-NnHYN2UlIwq6Ah8fYmx54g86ELYrXfgXIiWJDsSv4EU=" "hash": "sha256-NnHYN2UlIwq6Ah8fYmx54g86ELYrXfgXIiWJDsSv4EU="
}, },
{
"mvn-path": "org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.jar",
"mvn-repo": "https://repo1.maven.org/maven2/",
"hash": "sha256-UfmOunss1C7jDzgmkl3N6HkRZ/dvcSMprlG4gkToE44="
},
{ {
"mvn-path": "org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.pom", "mvn-path": "org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.pom",
"mvn-repo": "https://repo1.maven.org/maven2/", "mvn-repo": "https://repo1.maven.org/maven2/",
@@ -1125,11 +1102,6 @@
"mvn-repo": "https://repo1.maven.org/maven2/", "mvn-repo": "https://repo1.maven.org/maven2/",
"hash": "sha256-E15H98p5wKoYG2kJPML50aYyKt1qgli2aXxQCNIwv00=" "hash": "sha256-E15H98p5wKoYG2kJPML50aYyKt1qgli2aXxQCNIwv00="
}, },
{
"mvn-path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6.jar",
"mvn-repo": "https://repo1.maven.org/maven2/",
"hash": "sha256-EdGzHyxlwzVbKSu5tEuPyv2lS0TaY+NKuXt5qKs7uOA="
},
{ {
"mvn-path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6.pom", "mvn-path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6.pom",
"mvn-repo": "https://repo1.maven.org/maven2/", "mvn-repo": "https://repo1.maven.org/maven2/",
+24
View File
@@ -0,0 +1,24 @@
{:deps {aero/aero #:mvn{:version "1.1.6"}
babashka/fs #:mvn{:version "0.5.24"}
babashka/process #:mvn{:version "0.6.25"}
ch.qos.logback/logback-classic #:mvn{:version "1.1.3"}
cheshire/cheshire #:mvn{:version "6.1.0"}
com.github.seancorfield/next.jdbc #:mvn{:version "1.3.1070"}
com.rpl/specter #:mvn{:version "1.1.6"}
hiccup/hiccup #:mvn{:version "2.0.0-RC4"}
http-kit/http-kit #:mvn{:version "2.8.0"}
instaparse/instaparse #:mvn{:version "1.5.0"}
metosin/reitit #:mvn{:version "0.10.1"}
mvxcvi/clj-cbor #:mvn{:version "1.1.1"}
org.clojars.pntblnk/clj-ldap #:mvn{:version "0.0.17"}
org.clojure/clojure #:mvn{:version "1.12.0"}
org.clojure/core.match #:mvn{:version "1.1.0"}
org.clojure/test.check #:mvn{:version "1.1.3"}
org.clojure/tools.logging #:mvn{:version "1.3.0"}
org.xerial/sqlite-jdbc #:mvn{:version "3.47.1.0"}}
:paths ["src" "resources"]
:aliases
{:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
:extra-paths ["test"]
:main-opts ["-m" "kaocha.runner"]}
:dev {:extra-paths ["dev"]}}}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-6
View File
@@ -1,6 +0,0 @@
#+title: Doerg specification
#+author: Guppy
* Footnotes
- A bunch of metadata should be read into a node of type =doerg-data=
-18
View File
@@ -1,18 +0,0 @@
{:deps {org.clojure/tools.logging {:mvn/version "1.3.0"}
babashka/fs {:mvn/version "0.5.24"}
org.clojure/core.match {:mvn/version "1.1.0"}
cheshire/cheshire {:mvn/version "6.1.0"}
babashka/process {:mvn/version "0.6.25"}
io.github.msyds/spec-dict
{:git/sha "531d629b7f05f37232261cf9e8927a4b5915714f"}
hiccup/hiccup {:mvn/version "2.0.0-RC4"}
com.rpl/specter {:mvn/version "1.1.6"}
mvxcvi/clj-cbor {:mvn/version "1.1.1"}
ch.qos.logback/logback-classic {:mvn/version "1.1.3"}
org.clojure/test.check {:mvn/version "1.1.3"}
aero/aero {:mvn/version "1.1.6"}}
:paths ["src" "resources"]
:aliases
{:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
:extra-paths ["test"]
:main-opts ["-m" "kaocha.runner"]}}}
@@ -1,11 +0,0 @@
#:net.deertopia.doerg
{:ibm-plex-web #or [#xdg-data-dir "ibm-plex-web"
#env IBM_PLEX_WEB]
:latex "xelatex"
:dvisvgm "dvisvgm"
:doerg-temml-worker
#profile {:dev #file "../../../../doerg-temml-worker/index.js"
:default "doerg-temml-worker"}
:doerg-parser
#profile {:dev #file "../../../../doerg-parser/index.js"
:default "doerg-parser"}}
-27
View File
@@ -1,27 +0,0 @@
(ns scratch
(:require [clojure.spec.alpha :as s]
[spec-dict.main :refer [dict]]
[clojure.test.check.generators :as gen]))
(defmulti node-spec :type)
(s/def ::node
(s/multi-spec node-spec :type))
(s/def ::children (s/coll-of ::node :kind vector?))
(s/def ::value nat-int?)
(defmethod node-spec :branch [_]
(dict {:children ::children})
#_(s/keys :req-un [::children]))
(defmethod node-spec :leaf [_]
(dict {:value ::value})
#_
(s/keys :req-un [::value]))
(comment
(binding [s/*recursion-limit* 1]
(gen/generate (s/gen ::node))))
+38 -40
View File
@@ -15,15 +15,15 @@
]; ];
each-system = f: nixpkgs.lib.genAttrs supportedSystems (system: f rec { each-system = f: nixpkgs.lib.genAttrs supportedSystems (system: f rec {
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
overlays = [ overlays = [
inputs.sydpkgs.overlays.default inputs.sydpkgs.overlays.default
clj-nix.overlays.default clj-nix.overlays.default
self.overlays.default self.overlays.default
]; ];
}; };
inherit (pkgs) lib; inherit (pkgs) lib;
inherit system; inherit system;
}); });
in { in {
@@ -31,47 +31,45 @@
_pkgs = each-system ({ pkgs, ... }: pkgs); _pkgs = each-system ({ pkgs, ... }: pkgs);
packages = each-system ({ pkgs, ... }: { packages = each-system ({ pkgs, ... }: {
inherit (pkgs) publisher doerg doerg-parser doerg-temml-worker; inherit (pkgs) doerg doerg-parser doerg-temml-worker;
default = pkgs.publisher; default = pkgs.doerg;
}); });
overlays.default = final: prev: overlays.default = final: prev:
let graal = x: final.mkGraalBin { cljDrv = x; }; let graal = x: final.mkGraalBin { cljDrv = x; };
vendored = final.callPackage ./vendor {}; in {
in { ibm-plex-web = final.callPackage ./ibm-plex-web.nix {};
inherit (vendored) ibm-plex-web; doerg = final.callPackage ./. {};
publisher = final.callPackage ./publisher {}; doerg-parser = final.callPackage ./doerg-parser {};
doerg = final.callPackage ./doerg {}; doerg-temml-worker = final.callPackage ./doerg-temml-worker {};
doerg-parser = final.callPackage ./doerg/doerg-parser {}; our-tex = final.callPackage ./our-tex.nix {};
doerg-temml-worker = final.callPackage ./doerg/doerg-temml-worker {}; };
};
checks = each-system ({ pkgs, system, ... }: { checks = each-system ({ pkgs, system, ... }: {
build-all = build-all =
pkgs.linkFarmFromDrvs pkgs.linkFarmFromDrvs
"all" "all"
(pkgs.lib.attrValues self.packages.${system}); (pkgs.lib.attrValues self.packages.${system});
}); });
devShells = each-system ({ pkgs, system, ... }: { devShells = each-system ({ pkgs, system, ... }: {
default = pkgs.mkShell { default = pkgs.mkShell {
inputsFrom = [ inputsFrom = [
pkgs.doerg pkgs.doerg
pkgs.publisher pkgs.doerg-parser
pkgs.doerg-parser pkgs.doerg-temml-worker
pkgs.doerg-temml-worker ];
]; packages = with pkgs; [
packages = with pkgs; [ clojure-lsp
clojure-lsp doerg-parser
doerg-parser doerg-temml-worker
doerg-temml-worker zprint
zprint clojure
clojure babashka
babashka sqlite-web
sqlite-web pkgs.doerg.test-emacs
pkgs.publisher.test-emacs ];
]; };
};
}); });
}; };
} }
File renamed without changes.
View File
File renamed without changes.
-12
View File
@@ -1,12 +0,0 @@
((nil
. ((cider-clojure-cli-aliases . ":dev:test")
;; (eval
;; . (progn
;; (defun start-deertopia-server ()
;; (let ((n (cider-format-connection-params "%j" cider-launch-params)))
;; (when (equal n "net-deertopia")
;; (cider-interactive-eval
;; "(do (require '[net.deertopia.publisher.server :as server])
;; (server/start!))"))))
;; (add-hook 'cider-connected-hook #'start-deertopia-server)))
)))
-55
View File
@@ -1,55 +0,0 @@
{ mkCljBin
, doerg
, babashka
, callPackage
, test-emacs ? callPackage ./test-emacs.nix {}
, fake-git
, breakpointHook
, doerg-temml-worker
, doerg-parser
}:
let
# 이 mkCljBin에는 fake-git가 포함되지 않는다. 그것 불필요해서 dev
# shell에 없고 싶는다.
mkCljBin' = args: (mkCljBin args).overrideAttrs (final: prev: {
nativeBuildInputs =
builtins.filter
# A possibly-sketchy predicate, lol.
(x: x != fake-git)
prev.nativeBuildInputs;
});
in mkCljBin' {
name = "net.deertopia/publisher";
version = "0.1.0";
projectSrc = ./.;
lockfile = ../deps-lock.json;
main-ns = "net.deertopia.publisher.main";
buildInputs = [
doerg
];
nativeBuildInputs = [
babashka
];
nativeCheckInputs = [
doerg-parser
doerg-temml-worker
test-emacs
doerg
doerg.our-tex
doerg.plex
];
postPatch = ''
mv deps.edn deps.edn.old
bb -cp . -m override-deps < deps.edn.old > deps.edn \
net.deertopia/doerg '{:local/root "${doerg.lib}/${doerg.name}.jar"}'
'';
doCheck = true;
checkPhase = ''
export \
EMACS=test-emacs \
XDG_STATE_HOME=$(mktemp -d "state-home-XXXXXX")
clojure -M:test
'';
passthru = { inherit test-emacs; };
}
-21
View File
@@ -1,21 +0,0 @@
{:deps {org.clojure/clojure {:mvn/version "1.12.0"}
org.clojure/tools.logging {:mvn/version "1.3.0"}
hiccup/hiccup {:mvn/version "2.0.0-RC4"}
org.clojars.pntblnk/clj-ldap {:mvn/version "0.0.17"}
babashka/fs {:mvn/version "0.5.24"}
org.clojure/core.match {:mvn/version "1.1.0"}
com.github.seancorfield/next.jdbc {:mvn/version "1.3.1070"}
org.xerial/sqlite-jdbc {:mvn/version "3.47.1.0"}
cheshire/cheshire {:mvn/version "6.1.0"}
org.clojure/test.check {:mvn/version "1.1.3"}
net.deertopia/doerg {:local/root "../doerg"}
metosin/reitit {:mvn/version "0.10.1"}
http-kit/http-kit {:mvn/version "2.8.0"}
instaparse/instaparse {:mvn/version "1.5.0"}
aero/aero {:mvn/version "1.1.6"}}
:paths ["src" "resources"]
:aliases
{:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
:extra-paths ["test"]
:main-opts ["-m" "kaocha.runner"]}
:dev {:extra-paths ["dev"]}}}
-24
View File
@@ -1,24 +0,0 @@
(ns user
(:require [net.deertopia.publisher.server :as server]
[net.deertopia.doerg :as-alias doerg]
[net.deertopia.publisher :as-alias publisher]
[net.deertopia.doerg.config :as doerg-config]
[net.deertopia.publisher.config :as publisher-config]
[babashka.fs :as fs]))
(doerg-config/load-config! #'doerg-config/*cfg*
::doerg/config
doerg-config/sources
:profile :dev)
(doerg-config/load-config! #'publisher-config/*cfg*
::publisher/config
publisher-config/sources
:profile :dev)
(when (not= :running (server/status))
(server/start!))
(defn invalidate-html-cache! []
(fs/delete-tree (server/html-dir))
nil)
-56
View File
@@ -1,56 +0,0 @@
;;; -*- mode:clojure -*-
;;;
;;; USAGE:
;;;
;;; bb -cp . -m override-deps -- [DEP-NAME INFO]…
;;;
;;; This script takes a series of deps substitutions on the command
;;; line, applies them to a deps.edn file (read on stdin), and spits
;;; the result to stdout.
;;;
;;; It is used to build the Doerg server with Nix, since Clj-nix does
;;; not resolve the local deps itself.
(ns override-deps
(:require [rewrite-clj.zip :as z]
[babashka.fs :as fs]
[clojure.edn :as edn]))
(defn apply-overrides [zloc overrides]
(loop [os (seq overrides)
loc zloc]
(if-some [[[k v] & xs] os]
(do (binding [*out* *err*]
(printf "override dep %s with %s\n"
(pr-str k) (pr-str v)))
(recur xs (z/assoc loc k v)))
loc)))
(defn args->overrides [args]
(assert (even? (count args)))
(->> args (map edn/read-string) (apply hash-map)))
(defn -main [& args]
(let [zloc (-> (slurp *in*) z/of-string)
overrides (args->overrides args)]
(-> zloc
z/down
(z/find-value :deps) z/right
(apply-overrides overrides)
z/root-string
print)))
(comment
"Example overrides"
(def overrides '{net.deertopia/doerg "blah!!!!"
ring/ring-defaults {:mvn/version "xxxxx"}}))
(comment
"Behaviour of `args->overrides`."
(= (args->overrides ["net.deertopia/doerg" "{:mvn/version \"abc\"}"
"ring/ring-defaults" "{:local/root \"/path/to/jar\"}"])
'{ring/ring-defaults {:local/root "/path/to/jar"}
net.deertopia/doerg {:mvn/version "abc"}}))
@@ -1,8 +0,0 @@
#:net.deertopia.publisher
{:state-directory #join [#or [#env XDG_STATE_HOME
#envf ["%s/.local/share" HOME]]
"/doerg-publisher"]
:org-roam-db-path
#profile {:default #join [#env HOME "/.cache/emacs/org-roam.db"]
:test #join [#or [#env TMP "/tmp"] "/doerg-org-roam-test.db"]}
:port #profile {:default 8080}}
@@ -1,28 +0,0 @@
(ns net.deertopia.publisher.config
(:require [babashka.fs :as fs]
[clojure.spec.alpha :as s]
[net.deertopia.doerg.config :as doerg-config]
[net.deertopia.doerg :as-alias doerg]
[net.deertopia.publisher :as-alias p]
[aero.core :as aero]
[clojure.java.io :as io]))
(s/def ::p/config
(s/keys :req [::p/state-directory
::p/org-roam-db-path]))
(s/def ::p/state-directory ::doerg/file)
(s/def ::p/org-roam-db-path ::doerg/file)
(def sources
[;; Default config.
(io/resource "net/deertopia/publisher/default-config.edn")
;; Defaults set at build time, if any.
(io/resource "net/deertopia/publisher/extra-config.edn")
;; Config set at runtime.
(System/getenv "DOERG_PUBLISHER_CONFIG")])
(def default
(doerg-config/read-config ::p/config sources))
(def ^:dynamic *cfg* default)
@@ -1,7 +0,0 @@
(ns net.deertopia.publisher.main
(:require [net.deertopia.doerg.main :as doerg]
[net.deertopia.publisher.server :as server])
(:gen-class))
(defn -main []
(server/start!))
@@ -1,19 +0,0 @@
(ns net.deertopia.publisher.config-test
(:require [clojure.test :as t]
[net.deertopia.publisher.config :as publisher-cfg]
[net.deertopia.doerg.config :as doerg-cfg]
[net.deertopia.publisher :as-alias publisher]
[net.deertopia.doerg :as-alias doerg]))
(defn test-config-fixture
"`clojure.test` fixture to run tests with the :test configuration."
[f]
(binding [doerg-cfg/*cfg*
(doerg-cfg/read-config
::doerg/config doerg-cfg/sources
:profile :test)
publisher-cfg/*cfg*
(doerg-cfg/read-config
::publisher/config publisher-cfg/sources
:profile :test)]
(f)))
-1
View File
@@ -1 +0,0 @@
#kaocha/v1 {}
-25
View File
@@ -1,25 +0,0 @@
{ fetchzip
, fetchurl
}:
{
ibm-plex-serif = fetchzip {
url = "https://github.com/IBM/plex/releases/download/%40ibm%2Fplex-serif%401.1.0/ibm-plex-serif.zip";
hash = "sha256-8ygaAeMKygYS4GCub4YUQmkh87pYHfi3s0PQ6AbaeGw=";
};
ibm-plex-math = fetchzip {
url = "https://github.com/IBM/plex/releases/download/%40ibm%2Fplex-math%401.1.0/ibm-plex-math.zip";
hash = "sha256-dJA6uqxa/yb3eLY4l39NeP0yIl2NfrbaRpf6h0/F7Xc=";
};
ibm-plex-sans-kr = fetchzip {
url = "https://github.com/IBM/plex/releases/download/%40ibm%2Fplex-sans-kr%401.1.0/ibm-plex-sans-kr.zip";
hash = "sha256-FsHxMvLlI4yylgG96DOZIdW2DYpk7I+c5QgkVIkNZIE=";
};
"d3.v7.min.js" = fetchurl {
url = "https://d3js.org/d3.v7.min.js";
hash = "sha256-8glLv2FBs1lyLE/kVOtsSw8OQswQzHr5IfwVj864ZTk=";
};
}
@@ -0,0 +1,18 @@
#:net.deertopia.doerg.config
{:ibm-plex-web #or [#xdg-data-dir "ibm-plex-web"
#env IBM_PLEX_WEB]
:latex "xelatex"
:dvisvgm "dvisvgm"
:doerg-temml-worker
#profile {:dev #file "../../../../doerg-temml-worker/index.js"
:default "doerg-temml-worker"}
:doerg-parser
#profile {:dev #file "../../../../doerg-parser/index.js"
:default "doerg-parser"}
:state-directory #join [#or [#env XDG_STATE_HOME
#envf ["%s/.local/share" HOME]]
"/doerg-server"]
:org-roam-db-path
#profile {:default #join [#env HOME "/.cache/emacs/org-roam.db"]
:test #join [#or [#env TMP "/tmp"] "/doerg-org-roam-test.db"]}
:port #profile {:default 8080}}
@@ -1,4 +1,4 @@
(ns net.deertopia.publisher.cached-file (ns net.deertopia.doerg.cached-file
(:require [babashka.fs :as fs])) (:require [babashka.fs :as fs]))
(defn newer-than? (defn newer-than?
File renamed without changes.
@@ -1,25 +1,25 @@
(ns net.deertopia.doerg.config (ns net.deertopia.doerg.config
(:require [clojure.spec.alpha :as s] (:require [clojure.spec.alpha :as s]
[babashka.fs :as fs] [babashka.fs :as fs]
[spec-dict.main :refer [dict]]
[aero.core :as aero] [aero.core :as aero]
[net.deertopia.doerg :as-alias d]
[clojure.java.io :as io])) [clojure.java.io :as io]))
(s/def ::d/config (s/def ::config
(s/keys :req [::d/ibm-plex-web (s/keys :req [::ibm-plex-web
::d/latex ::latex
::d/dvisvgm ::dvisvgm
::d/doerg-temml-worker ::doerg-temml-worker
::d/doerg-parser])) ::doerg-parser
::state-directory
::org-roam-db-path]))
(s/def ::d/directory (s/def ::directory
(s/conformer #(fs/file %))) (s/conformer #(fs/file %)))
(s/def ::d/file (s/def ::file
(s/conformer #(-> % fs/expand-home fs/file))) (s/conformer #(-> % fs/expand-home fs/file)))
(s/def ::d/executable (s/def ::executable
(s/conformer (s/conformer
;; I'd love to use `fs/which` here, but it's fairly problematic to ;; I'd love to use `fs/which` here, but it's fairly problematic to
;; check `fs/executable?` at… build time (which `fs/which` does)? ;; check `fs/executable?` at… build time (which `fs/which` does)?
@@ -28,15 +28,18 @@
(some-> % fs/expand-home fs/file) (some-> % fs/expand-home fs/file)
::s/invalid))) ::s/invalid)))
(s/def ::d/ibm-plex-web ::d/directory) (s/def ::ibm-plex-web ::directory)
(s/def ::d/latex ::d/executable) (s/def ::latex ::executable)
(s/def ::d/dvisvgm ::d/executable) (s/def ::dvisvgm ::executable)
(s/def ::d/doerg-temml-worker ::d/executable) (s/def ::doerg-temml-worker ::executable)
(s/def ::d/doerg-parser ::d/executable) (s/def ::doerg-parser ::executable)
(s/def ::state-directory ::file)
(s/def ::org-roam-db-path ::file)
(defmethod aero/reader 'xdg-data-dir (defmethod aero/reader 'xdg-data-dir
[_opts tag value] [_opts tag value]
@@ -52,19 +55,19 @@
(-> (aero/relative-resolver source value) (-> (aero/relative-resolver source value)
fs/file)) fs/file))
(defn read-config [spec files & {:as opts}] (defn read-config [files & {:as opts}]
(let [r (->> files (let [r (->> files
(filter identity) (filter identity)
(map #(aero/read-config % opts)) (map #(aero/read-config % opts))
(apply merge)) (apply merge))
conformed (s/conform spec r)] conformed (s/conform ::config r)]
(if-not (s/invalid? conformed) (if-not (s/invalid? conformed)
conformed conformed
(throw (ex-info "Failed to conform config" (throw (ex-info "Failed to conform config"
(s/explain-data spec r)))))) (s/explain-data ::config r))))))
(defn load-config! [var spec files & {:as opts}] (defn load-config! [var spec files & {:as opts}]
(alter-var-root var (constantly (read-config spec files opts)))) (alter-var-root var (constantly (read-config files opts))))
(def sources (def sources
[;; Default config. [;; Default config.
@@ -74,6 +77,6 @@
;; Config set at runtime. ;; Config set at runtime.
(System/getenv "DOERG_CONFIG")]) (System/getenv "DOERG_CONFIG")])
(def default (read-config ::d/config sources)) (def default (read-config sources))
(def ^:dynamic *cfg* default) (def ^:dynamic *cfg* default)
@@ -7,7 +7,6 @@
[net.deertopia.doerg :as-alias doerg] [net.deertopia.doerg :as-alias doerg]
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.set :as set] [clojure.set :as set]
[clojure.spec.alpha :as s]
[clojure.string :as str] [clojure.string :as str]
[clojure.test.check.generators :as gen] [clojure.test.check.generators :as gen]
[clojure.tools.logging.readable :as lr] [clojure.tools.logging.readable :as lr]
@@ -16,7 +15,6 @@
[com.rpl.specter.zipper :as sz] [com.rpl.specter.zipper :as sz]
[net.deertopia.doerg.common :as common] [net.deertopia.doerg.common :as common]
[net.deertopia.doerg.config :as cfg] [net.deertopia.doerg.config :as cfg]
[spec-dict.main :refer [dict]]
[clojure.tools.logging :as l]) [clojure.tools.logging :as l])
(:import (:import
(java.util UUID))) (java.util UUID)))
@@ -65,8 +63,6 @@
(and (map? e) (contains? e :children))) (and (map? e) (contains? e :children)))
(defn org-element? [element] (defn org-element? [element]
#_
(s/valid? ::org-element element)
(and (map? element) (and (map? element)
(contains? element :type))) (contains? element :type)))
@@ -99,16 +95,6 @@
(and (of-type? element "latex-fragment") (and (of-type? element "latex-fragment")
(-> element :contents (str/starts-with? "\\["))))) (-> element :contents (str/starts-with? "\\[")))))
;;; Spec
(s/def ::org-element
(dict {:type string?}
^:opt {:contents-begin nat-int?
:contents-end nat-int?
:children (s/coll-of ::org-element
:kind seq?)}))
;;; Zipper ;;; Zipper
@@ -315,149 +301,3 @@
(recur (conj acc c) rest) (recur (conj acc c) rest)
[] acc)))))) [] acc))))))
;;; Specs (top-level)
;; Data taken from uniorg/index.d.ts
(comment
(defn- typescript-enum->set [s]
(as-> s
it
(str/split it #" \| ")
(map camel->kebab it)
(into #{} it))))
(def greater-element-types
#{"org-data" "section" "property-drawer" "drawer" "plain-list"
"list-item" "quote-block" "verse-block" "center-block"
"special-block" "footnote-definition" "table"})
(def element-types
#{"list-item-tag" "src-block" "comment-block" "latex-environment"
"keyword" "paragraph" "node-property" "example-block" "clock"
"planning" "diary-sexp" "fixed-width" "export-block"
"horizontal-rule" "comment" "table-row" "headline"})
(def recursive-object-types
#{"citation" "footnote-reference" "superscript" "table-cell" "link"
"italic" "citation-common-prefix" "subscript" "citation-prefix"
"citation-common-suffix" "strike-through" "citation-reference"
"bold" "underline"})
(def object-types
#{"line-break" "citation-suffix" "statistics-cookie" "timestamp"
"text" "verbatim" "citation-key" "export-snippet" "latex-fragment"
"entity" "code"})
(s/def ::greater-element-type greater-element-types)
(s/def ::element-type element-types)
(s/def ::object-type (set/union recursive-object-types object-types))
(s/def ::recursive-object-type recursive-object-types)
(s/def ::contents-begin nat-int?)
(s/def ::contents-end nat-int?)
(defmulti node-spec :type)
(defn- unimplemented-spec [x]
(lr/warnf "unimplemented method for %s" x)
(s/with-gen any?
(constantly (gen/return {}))))
(defmethod node-spec :default [x] (unimplemented-spec x))
(def ^:private nfe
"NFE — “no further expectations.” Used in sub-specs of `::element`
et al. for elements with no additional structure beyond that
provided by their parents."
(s/with-gen any?
(constantly (gen/return {}))))
(s/def ::node
(s/multi-spec node-spec :type))
(s/def :object/type ::object-type)
(s/def ::object
(s/keys :req-un [:object/type]))
(s/def :element/children (s/coll-of ::object :kind vector?))
(s/def :element/type ::element-type)
(s/def ::element
(s/keys :opt-un [::contents-begin ::contents-end]
:req-un [:element/children :element/type]))
(s/def :greater-element/children
(s/coll-of (s/merge
(dict {:type (set/union greater-element-types
element-types)})
::node)
:kind vector?))
(s/def :greater-element/type ::greater-element-type)
(s/def ::greater-element
(s/keys :req-un [::contents-begin ::contents-end
:greater-element/children
:greater-element/type]))
(s/def :recursive-object/children
(s/coll-of
(s/merge
(dict {:type ::object-type})
::node)
:kind vector?))
(s/def :recursive-object/type ::object-type)
(s/def ::recursive-object
(s/keys :opt-un [::contents-begin ::contents-end]
:req-un [:recursive-object/children
:recursive-object/type]))
(comment
(use 'net.deertopia.doerg.repl)
(def doc (-> "test/net/deertopia/doerg/element_test/paragraph-with-multiple-latex.org"
slurp
(read-string :post-processors
[gather-first-section])))
(s/explain ::node doc)
(binding [s/*recursion-limit* 1]
(gen/generate (s/gen ::node)))
(sp/select [postorder-walker (sp/must :children)
(sp/continuous-subseqs)]
doc))
(s/def ::todo-keyword string?)
(s/def ::priority string?)
(s/def ::commented boolean?)
(s/def ::level nat-int?)
(s/def ::tags (s/coll-of string? :kind vector?))
;;; Specs (specific elements)
(def ^:private string-value (dict {:value string?}))
(defmethod node-spec "text" [_] (s/merge ::object string-value))
(defmethod node-spec "verbatim" [_] (s/merge ::object string-value))
(defmethod node-spec "code" [_] (s/merge ::object string-value))
(defmethod node-spec "bold" [_] ::recursive-object)
(defmethod node-spec "italic" [_] ::recursive-object)
(defmethod node-spec "headline" [_]
(s/merge ::element
(dict {:todo-keyword (s/nilable ::todo-keyword)
:priority (s/nilable ::priority)
:level ::level
:commented ::commented
:raw-value string?
:tags ::tags})))
(defmethod node-spec "org-data" [_]
::greater-element)
(defmethod node-spec "section" [_]
::greater-element)
@@ -1,4 +1,4 @@
(ns net.deertopia.publisher.elisp (ns net.deertopia.doerg.elisp
(:require [clojure.core.match :refer [match]] (:require [clojure.core.match :refer [match]]
[clojure.java.io :as io] [clojure.java.io :as io]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
@@ -6,7 +6,7 @@
(:refer-clojure :exclude [print read read-string])) (:refer-clojure :exclude [print read read-string]))
(ip/defparser read* (ip/defparser read*
(io/resource "net/deertopia/publisher/elisp/grammar")) (io/resource "net/deertopia/doerg/elisp/grammar"))
(defn- transform-string [s] (defn- transform-string [s]
(let [s* (loop [s (seq s) (let [s* (loop [s (seq s)
@@ -106,7 +106,7 @@
(defn print [x] (defn print [x]
;; TODO: this is really not how it should be done lol. at the ;; TODO: this is really not how it should be done lol. at the
;; moment, `print` is only used in `net.deertopia.publisher.roam` ;; moment, `print` is only used in `net.deertopia.doerg.roam`
;; and only to serialise uuids, so it's not a /massive/ priority. ;; and only to serialise uuids, so it's not a /massive/ priority.
(cond (or (string? x) (uuid? x)) (str \" x \") (cond (or (string? x) (uuid? x)) (str \" x \")
:else (throw (ex-info "`print` is unimplemented lol" :else (throw (ex-info "`print` is unimplemented lol"
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,9 +1,8 @@
(ns net.deertopia.publisher.roam (ns net.deertopia.doerg.roam
(:require [babashka.fs :as fs] (:require [babashka.fs :as fs]
[net.deertopia.publisher.config :as cfg] [net.deertopia.doerg.config :as cfg]
[net.deertopia.publisher.elisp :as elisp] [net.deertopia.doerg.elisp :as elisp]
[net.deertopia.publisher.slug :as slug] [net.deertopia.doerg.slug :as slug]
[net.deertopia.publisher :as-alias publisher]
[next.jdbc :as sql]) [next.jdbc :as sql])
(:import (java.util UUID))) (:import (java.util UUID)))
@@ -15,7 +14,7 @@
(defn ds [] (defn ds []
(sql/get-datasource (sql/get-datasource
{:dbtype "sqlite" {:dbtype "sqlite"
:dbname (-> cfg/*cfg* ::publisher/org-roam-db-path str)})) :dbname (-> cfg/*cfg* ::cfg/org-roam-db-path str)}))
;;; Elisp sexp (de)serialisation ;;; Elisp sexp (de)serialisation
@@ -86,7 +85,7 @@
java.util.UUID java.util.UUID
(get-node [this] (get-node [this]
(make-node this)) (make-node this))
net.deertopia.publisher.slug.Slug net.deertopia.doerg.slug.Slug
(get-node [this] (get-node [this]
(-> this slug/to-uuid make-node)) (-> this slug/to-uuid make-node))
Node Node
@@ -1,12 +1,12 @@
(ns net.deertopia.publisher.server (ns net.deertopia.doerg.server
(:require [clojure.pprint :refer [pprint]] (:require [clojure.pprint :refer [pprint]]
[clojure.tools.logging :as l] [clojure.tools.logging :as l]
[hiccup2.core :as hiccup] [hiccup2.core :as hiccup]
[net.deertopia.doerg.html :as doerg-html] [net.deertopia.doerg.html :as doerg-html]
[net.deertopia.publisher :as-alias publisher] [net.deertopia.doerg.config :as-alias cfg]
[net.deertopia.publisher.slug :as slug] [net.deertopia.doerg.slug :as slug]
[net.deertopia.publisher.config :as cfg] [net.deertopia.doerg.config :as cfg]
[net.deertopia.publisher.roam :as roam] [net.deertopia.doerg.roam :as roam]
[org.httpkit.server :as http] [org.httpkit.server :as http]
[reitit.coercion] [reitit.coercion]
[reitit.coercion.spec] [reitit.coercion.spec]
@@ -20,7 +20,7 @@
[reitit.dev.pretty] [reitit.dev.pretty]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[net.deertopia.doerg.render :as doerg-render] [net.deertopia.doerg.render :as doerg-render]
[net.deertopia.publisher.cached-file :as cached-file] [net.deertopia.doerg.cached-file :as cached-file]
[babashka.fs :as fs] [babashka.fs :as fs]
[aero.core :as aero] [aero.core :as aero]
[clojure.string :as str] [clojure.string :as str]
@@ -49,7 +49,7 @@
(response/content-type "text/html"))) (response/content-type "text/html")))
(defn html-dir [] (defn html-dir []
(-> cfg/*cfg* ::publisher/state-directory (fs/file "html"))) (-> cfg/*cfg* ::cfg/state-directory (fs/file "html")))
(defn not-found [req] (defn not-found [req]
(response/not-found "not found")) (response/not-found "not found"))
@@ -169,7 +169,7 @@
(throw (IllegalStateException. "Server already started")) (throw (IllegalStateException. "Server already started"))
(do (reset! server (do (reset! server
(http/run-server (bound-fn* #'app) (http/run-server (bound-fn* #'app)
{:port (-> cfg/*cfg* ::publisher/port) {:port (-> cfg/*cfg* ::cfg/port)
:legacy-return-value? false})) :legacy-return-value? false}))
;; For some reason, the log messages are not flushed before ;; For some reason, the log messages are not flushed before
;; the JVM shuts dowm. Nevertheless, the server /does/ come ;; the JVM shuts dowm. Nevertheless, the server /does/ come
@@ -180,7 +180,7 @@
(ex-message e)) (ex-message e))
(throw e)))) (throw e))))
(l/infof "Server started on port %d" (l/infof "Server started on port %d"
(-> cfg/*cfg* ::publisher/port))))) (-> cfg/*cfg* ::cfg/port)))))
(defn status [] (defn status []
(if @server (if @server
@@ -1,4 +1,4 @@
(ns net.deertopia.publisher.slug (ns net.deertopia.doerg.slug
(:require [clojure.spec.alpha :as s] (:require [clojure.spec.alpha :as s]
[spec-tools.core :as st]) [spec-tools.core :as st])
(:import (java.nio ByteBuffer) (:import (java.nio ByteBuffer)
File renamed without changes.
File renamed without changes.
+9
View File
@@ -0,0 +1,9 @@
(ns net.deertopia.doerg.config-test
(:require [clojure.test :as t]
[net.deertopia.doerg.config :as cfg]))
(defn test-config-fixture
"`clojure.test` fixture to run tests with the :test configuration."
[f]
(binding [cfg/*cfg* (cfg/read-config cfg/sources :profile :test)]
(f)))
@@ -1,26 +1,25 @@
(ns net.deertopia.publisher.roam-test (ns net.deertopia.doerg.roam-test
(:require [net.deertopia.publisher.roam :as sut] (:require [net.deertopia.doerg.roam :as sut]
[clojure.test :as t] [clojure.test :as t]
[clojure.java.io :as io] [clojure.java.io :as io]
[net.deertopia.publisher.config :as publisher-cfg] [net.deertopia.doerg.config :as cfg]
[net.deertopia.publisher :as-alias publisher]
[babashka.fs :as fs] [babashka.fs :as fs]
[babashka.process :as p] [babashka.process :as p]
[net.deertopia.publisher.config-test :refer [test-config-fixture]] [net.deertopia.doerg.config-test :refer [test-config-fixture]]
[next.jdbc :as sql] [next.jdbc :as sql]
[clojure.string :as str] [clojure.string :as str]
[net.deertopia.publisher.elisp :as elisp] [net.deertopia.doerg.elisp :as elisp]
[com.rpl.specter :as sp])) [com.rpl.specter :as sp]))
(def org-roam-directory (def org-roam-directory
(fs/file "test/net/deertopia/publisher/roam-test")) (fs/file "test/net/deertopia/doerg/roam-test"))
(defn org-roam-db-sync [db-file] (defn org-roam-db-sync [db-file]
(let [script-file (fs/create-temp-file {:prefix "org-roam-db-sync-" (let [script-file (fs/create-temp-file {:prefix "org-roam-db-sync-"
:suffix ".el"}) :suffix ".el"})
emacs (->> [(System/getenv "EMACS") "test-emacs" "emacs"] emacs (->> [(System/getenv "EMACS") "test-emacs" "emacs"]
(some #(some-> % fs/which)))] (some #(some-> % fs/which)))]
(io/copy (-> "net/deertopia/publisher/org-roam-db-sync.el" (io/copy (-> "net/deertopia/doerg/org-roam-db-sync.el"
io/resource io/reader) io/resource io/reader)
(fs/file script-file)) (fs/file script-file))
(p/shell {:out :string :err :string} (p/shell {:out :string :err :string}
@@ -28,7 +27,7 @@
(fs/delete script-file))) (fs/delete script-file)))
(defn test-db-fixture [f] (defn test-db-fixture [f]
(let [db-file (-> publisher-cfg/*cfg* ::publisher/org-roam-db-path)] (let [db-file (-> cfg/*cfg* ::cfg/org-roam-db-path)]
(assert (->> db-file fs/canonicalize str (assert (->> db-file fs/canonicalize str
(re-matches #"^/(build|tmp)/.*")) (re-matches #"^/(build|tmp)/.*"))
(format "i'm scared to delete a non-test database... %s" (format "i'm scared to delete a non-test database... %s"
@@ -1,16 +1,13 @@
(ns net.deertopia.publisher.server-test (ns net.deertopia.doerg.server-test
(:require [net.deertopia.publisher.server :as sut] (:require [net.deertopia.doerg.server :as sut]
[reitit.ring] [reitit.ring]
[clojure.test :as t] [clojure.test :as t]
[net.deertopia.publisher.config :as publisher-cfg] [net.deertopia.doerg.config :as cfg]
[net.deertopia.doerg.config :as doerg-cfg] [net.deertopia.doerg.roam :as roam]
[net.deertopia.publisher :as-alias publisher]
[net.deertopia.doerg :as-alias doerg]
[net.deertopia.publisher.roam :as roam]
[babashka.fs :as fs] [babashka.fs :as fs]
[clojure.java.io :as io] [clojure.java.io :as io]
[net.deertopia.publisher.roam-test :refer [test-db-fixture]] [net.deertopia.doerg.roam-test :refer [test-db-fixture]]
[net.deertopia.publisher.config-test :refer [test-config-fixture]])) [net.deertopia.doerg.config-test :refer [test-config-fixture]]))
(t/use-fixtures (t/use-fixtures
:once (t/join-fixtures [test-config-fixture test-db-fixture])) :once (t/join-fixtures [test-config-fixture test-db-fixture]))
@@ -36,7 +33,7 @@
(fn [] (fn []
(t/is (= :running (sut/status))) (t/is (= :running (sut/status)))
(t/is (->> (format "http://localhost:%d" (t/is (->> (format "http://localhost:%d"
(::publisher/port publisher-cfg/*cfg*)) (::cfg/port cfg/*cfg*))
slurp slurp
string?))))) string?)))))
View File
File renamed without changes.
-8
View File
@@ -1,8 +0,0 @@
{ fetchzip
, fetchurl
, callPackage
}:
{
ibm-plex-web = callPackage ./ibm-plex-web.nix {};
}