The Complete Computing Environment

Arroyo Home Manager


Arroyo can construct a configuration for nix-community/home-manager from any number of org-roam files using the Arroyo System Cache and Org Babel. There is a colloquial "nixlib" directory, currently file:~/org/cce/nixlib which all NixOS files are relative to. By adding a keyword #+ARROYO_HOME_MODULE: hm/import-file.nix and then tangling to e.g. ~/org/cce/nixlib/hm/import-file.nix you can generate a modular home-manager configuration.

"ARROYO_HOME_EPKGS" used in emacs generator
(add-to-list 'arroyo-db-keywords "ARROYO_HOME_MODULE" nil #'equal)
(add-to-list 'arroyo-db-keywords "CCE_HOME_MODULE" nil #'equal)
(add-to-list 'arroyo-db--schemata
               [(file        :not-null)
                ;(file-hash   :not-null)
                (home-module :not-null)
(defun arroyo-home-manager-update-db (&optional keywords-too)
  (interactive "P")
  (when keywords-too
  (if (org-roam-file-p)
      (arroyo-db-query [:delete :from home_manager :where (= file $s1)]
    (arroyo-db-query [:delete :from home_manager]))
  (when-let* ((args
               (if (org-roam-file-p)
                   (list [:select [file value] :from keywords
                          :where (in keyword $v1) :and (= file $s2)]
                         (vector "ARROYO_HOME_MODULE" "CCE_HOME_MODULE")
                 (list [:select [file value] :from keywords
                        :where (in keyword $v1)]
                       (vector "ARROYO_HOME_MODULE" "CCE_HOME_MODULE"))))
              (results (apply #'arroyo-db-query args))
              ;; attach role
              (results (-map (pcase-lambda (`(,file ,value))
                               (list file value (arroyo-db-get "ARROYO_NIXOS_ROLE" file)))
    (arroyo-db-query [:insert :into home-manager :values $v1]
                     (-map (lambda (result) (apply #'vector result))
(add-to-list 'arroyo-db-update-functions #'arroyo-home-manager-update-db)

arroyo-home-manager-imports returns a string suitable for import'ing in home-manager's literate helpers.

(defun arroyo-home-manager-imports1 ()
  (->> [:select [home-module file] :from home-manager]

(defun arroyo-home-manager-imports (&optional role)
  (if-let* ((imports (arroyo-home-manager-imports1))
            (no-role? (not role)))
      (->> imports
           (-map #'car)
           (s-join "\n"))
      (let* ((all-files (-map #'cadr imports))
             (role-only-files (arroyo-db-query [:select role :from home-manager :where (= role $s1)] role))
             (exclude-these-files (arroyo-db-by-keyword "ARROYO_NIXOS_EXCLUDE" role))
             ;; also need to exclude things whose ARROYO_NIXOS_ROLE is not `role'!
              (-map #'car
                    (arroyo-db-query [:select file :from home-manager
                                      :where (!= role $s1)]
                                     (list role))))
             ;; combine all those lists in to a single authoritative list.
              (-union role-only-files
                      (->> all-files
                           (--remove (-contains? exclude-these-files it))
                           (--remove (-contains? not-my-role-files it)))))
             ;; make them relative to org-roam-directory for the module orderer
             (rel-files (--map (file-relative-name it org-roam-directory) amalgamated-files)))
        ;; filter imports
        (->> rel-files
             (-map (lambda (file)
                         (caar (arroyo-db-query [:select home-module :from home-manager
                                                 :where (= file $s1)]
                                                (expand-file-name file org-roam-directory)))))
             (-filter #'identity))))))
(provide 'arroyo-home-manager)

NEXT refactor arroyo-home-manager-imports and arroyo-nixos-imports to compose together more-well….