NEXT Arroyo minor-mode
NEXT Menu Bar entries
in org-mode
buffers
- flood
- build
- sqlite
- update db
NEXT yasnippets for common document patterns
- inserting the keywords for the generators
Arroyo Dependency Sorting
Arroyo uses tsort
from GNU Coreutils to
order dependencies, because let's face it: implementing data structures
is not the sort of fun I want to have. home-manager itself has a small
DAG topological sort implementation which I could probably use as a
base to port across, but I could also shell out to coreutils. I think
it's fair to make GNU coreutils a dependency to the emacs arroyo
subsystems… Previous generations used a simple CCE_PRIORITY
keyword and a general ordering
scheme which I tried to manage on my own. I think doing a true
topological sort will be much better than this.
ARROYO_MODULE_WANTS
will be a keyword
whose value is a another arroyo file, relative to org-roam-directory
, which the module requires to
be loaded beforehand. This is only used in the Arroyo Emacs Generator at the moment as Nix
can handle its own resolution. it can be specified multiple times for
multiple dependencies.
'arroyo-db-keywords "ARROYO_MODULE_DEP" nil #'equal)
(add-to-list 'arroyo-db-keywords "ARROYO_MODULE_WANTS" nil #'equal)
(add-to-list 'arroyo-db-keywords "ARROYO_MODULE_WANTED" nil #'equal) (add-to-list
Arroyo uses tsort
to order the deps;
this is really decomposed and should be started with arroyo-utils-order-modules
to read it.
defun arroyo-utils--format-dep-pairs (line-fmt final-fmt want-rows wanted-rows)
(append (-map (pcase-lambda (`(,file ,keyword ,value))
(->> (list (file-relative-name file org-roam-directory) value))
(
want-rows)keyword ,value))
(-map (pcase-lambda (`(,file ,list value (file-relative-name file org-roam-directory)))
(
wanted-rows))
(-map (pcase-lambda (`(,thing ,dep))format line-fmt dep thing)))
("\n")
(s-join format final-fmt)))
(
defun arroyo-utils--filter-files (rows files)
(keyword, value))
(-filter (pcase-lambda (`(,file ,or (not files)
(
(-contains? files file)))
rows))
defun arroyo-utils--order-command (want-rows wanted-rows)
("%s %s" "tsort <<EOF\n%s\nEOF"
(arroyo-utils--format-dep-pairs
want-rows wanted-rows))
defun arroyo-utils-order-modules (&optional files skip-cmd)
(let* ((want-rows
(
(arroyo-utils--filter-fileskeyword value] :from keywords
(arroyo-db-query [:select [file keyword $v1)]
:where (in vector "ARROYO_MODULE_DEP" "ARROYO_MODULE_WANTS"))
(
files))
(wanted-rows
(arroyo-utils--filter-fileskeyword value] :from keywords
(arroyo-db-query [:select [file = keyword "ARROYO_MODULE_WANTED")])
:where (
files))#'car wanted-rows))
(wanted-files (-map #'car want-rows))
(want-files (-map
(missing
(-difference files (-union wanted-files want-files)))
(cmd (arroyo-utils--order-command want-rows wanted-rows)))if skip-cmd
(
cmdappend
(
(->> cmd
(shell-command-to-string)"\n")
(s-split #'string-empty-p))
(-remove missing))))
generate a dependency graph, this is quite similar to the order-command
function above:
defun arroyo-utils--gen-digraph (want-rows wanted-rows)
("\"%2s\" -> \"%1s\";" "digraph {\n%s\n}"
(arroyo-utils--format-dep-pairs
want-rows wanted-rows))
defun arroyo-utils--write-digraph (contents &optional file)
(let ((file (or file "/tmp/arroyo.dot")))
(
(with-current-buffer (find-file-noselect file)
(erase-buffer)
(insert contents)
(save-buffer))
file))
defun arroyo-utils-module-digraph ()
(
(interactive)let* ((want-rows (arroyo-db-query [:select [file keyword value] :from keywords
(keyword $v1)]
:where (in vector "ARROYO_MODULE_DEP" "ARROYO_MODULE_WANTS")))
(keyword value] :from keywords
(wanted-rows (arroyo-db-query [:select [file = keyword "ARROYO_MODULE_WANTED")])))
:where (
(->> (arroyo-utils--gen-digraph want-rows wanted-rows)
(arroyo-utils--write-digraph) (find-file))))
Footmatter
provide 'arroyo-utils) (