refactor: doerg는 publisher와 결합
All checks were successful
build / build (push) Successful in 5s

This commit is contained in:
2026-04-03 11:20:36 -06:00
parent 5ca59fdb5e
commit dcaac98252
88 changed files with 158 additions and 622 deletions

1
.dir-locals.el Normal file
View File

@@ -0,0 +1 @@
((nil . ((cider-clojure-cli-aliases . ":dev:test"))))

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
.gitignore vendored
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/

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; };
} }

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
deps.edn Normal file
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"]}}}

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=

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"]}}}

View File

@@ -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"}}

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))))

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 ];
]; };
};
}); });
}; };
} }

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)))
)))

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; };
}

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"]}}}

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)

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"}}))

View File

@@ -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}}

View File

@@ -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)

View File

@@ -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!))

View File

@@ -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)))

View File

@@ -1 +0,0 @@
#kaocha/v1 {}

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=";
};
}

View File

@@ -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}}

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -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?

View File

@@ -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)

View File

@@ -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)

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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)

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)))

View File

@@ -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"

View File

@@ -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?)))))

8
vendor/default.nix vendored
View File

@@ -1,8 +0,0 @@
{ fetchzip
, fetchurl
, callPackage
}:
{
ibm-plex-web = callPackage ./ibm-plex-web.nix {};
}