Emacs/Guix: Support installing multiple manifests at once.
parent
83b8b865d6
commit
ef2105d0e7
|
@ -59,11 +59,13 @@ The channel specification is looked up in
|
|||
(cl-defun ambrevar/guix-query-file (&key file directory
|
||||
(filter ".")
|
||||
(prompt "File: ")
|
||||
(name-function #'identity))
|
||||
(name-function #'identity)
|
||||
(multiple? nil))
|
||||
"Query a file matching FILTER in DIRECTORY.
|
||||
Return (NAME FILE).
|
||||
If FILE is non-nil, then this function is useful to derive the name of the manifest.
|
||||
NAME-FUNCTION take the file base name as argument and returns NAME."
|
||||
NAME-FUNCTION take the file base name as argument and returns NAME.
|
||||
If MULTIPLE? is non-nil, return a list of (NAME FILE) of the selected manifests."
|
||||
(cl-flet ((name (file)
|
||||
(replace-regexp-in-string
|
||||
"-?guix-?" ""
|
||||
|
@ -74,20 +76,26 @@ NAME-FUNCTION take the file base name as argument and returns NAME."
|
|||
(let ((files (mapcar (lambda (file)
|
||||
(list (name file) file))
|
||||
(directory-files directory 'full filter))))
|
||||
(assoc (completing-read prompt (mapcar #'first files))
|
||||
files)))))
|
||||
(if multiple?
|
||||
(mapcar (lambda (name)
|
||||
(assoc name files))
|
||||
(completing-read-multiple prompt (mapcar #'first files)))
|
||||
(assoc (completing-read prompt (mapcar #'first files))
|
||||
files))))))
|
||||
|
||||
(defun ambrevar/guix-query-manifest (&optional manifest)
|
||||
(defun ambrevar/guix-query-manifest (&optional manifest multiple?)
|
||||
"Query a manifest as found in `ambrevar/guix-manifest-directory'.
|
||||
Return (NAME FILE).
|
||||
If MANIFEST is non-nil, then this function is useful to derive the name of the manifest."
|
||||
If MANIFEST is non-nil, then this function is useful to derive the name of the manifest.
|
||||
If MULTIPLE? is non-nil, allow querying multiple manifests."
|
||||
(ambrevar/guix-query-file
|
||||
:file manifest
|
||||
:directory ambrevar/guix-manifest-directory
|
||||
:filter "manifest"
|
||||
:prompt "Manifest: "
|
||||
:prompt "Manifest(s): "
|
||||
:name-function (lambda (name)
|
||||
(replace-regexp-in-string "-?manifest-?" "" name))))
|
||||
(replace-regexp-in-string "-?manifest-?" "" name))
|
||||
:multiple? multiple?))
|
||||
|
||||
(defun ambrevar/guix-query-channel-spec (&optional channel-spec)
|
||||
"Query a channel specification as found in `ambrevar/guix-channel-spec-directory'.
|
||||
|
@ -157,6 +165,54 @@ If MANIFEST is nil, it is queried from the manifests found in `ambrevar/guix-man
|
|||
(not (eql (point)
|
||||
(marker-position (cdr comint-last-prompt)))))))
|
||||
|
||||
(defun %ambrevar/guix-install-manifest (&optional manifests channel)
|
||||
"Install list of (NAME MANIFEST-FILE) using CHANNEL."
|
||||
(require 'init-eshell) ; For `ambrevar/prefer-eshell'.
|
||||
(let* ((guix (if channel
|
||||
(let ((dest (expand-file-name
|
||||
manifest-name
|
||||
ambrevar/guix-extra-channels)))
|
||||
(make-directory dest 'parents)
|
||||
(format "guix pull --channels=%s --profile=%s/guix && %s/guix/bin/guix"
|
||||
(shell-quote-argument channel)
|
||||
(shell-quote-argument dest)
|
||||
(shell-quote-argument dest)))
|
||||
"guix")))
|
||||
(dolist (manifest-pair manifests)
|
||||
(let ((manifest-name (first manifest-pair)))
|
||||
(make-directory (expand-file-name manifest-name
|
||||
ambrevar/guix-extra-profiles)
|
||||
'parents)))
|
||||
(funcall (if ambrevar/prefer-eshell
|
||||
'ambrevar/run-in-eshell
|
||||
'ambrevar/run-in-shell)
|
||||
(mapconcat #'identity
|
||||
(mapcar (lambda (manifest-pair)
|
||||
(let ((manifest-name (first manifest-pair))
|
||||
(manifest (second manifest-pair))
|
||||
(profile (expand-file-name ambrevar/guix-extra-profiles)))
|
||||
(string-join
|
||||
(list "echo" (format "'==> Installing manifest %S to profile %S'"
|
||||
manifest-name profile)
|
||||
";"
|
||||
guix "package" (concat "--manifest=" manifest)
|
||||
(if (string= "default" manifest-name)
|
||||
""
|
||||
(concat "--profile=" profile
|
||||
"/" manifest-name
|
||||
"/" manifest-name)))
|
||||
" ")))
|
||||
manifests)
|
||||
" ; "))
|
||||
(unless channel
|
||||
;; TODO: Only do this when manifest install has succeeded.
|
||||
(dolist (manifest-pair manifests)
|
||||
(let ((manifest-name (first manifest-pair)))
|
||||
(ambrevar/guix-save-channel-specs
|
||||
(format "%s/guix-%s-channels.scm"
|
||||
ambrevar/guix-channel-spec-directory
|
||||
manifest-name)))))))
|
||||
|
||||
(defun ambrevar/guix-install-manifest (&optional manifest channel)
|
||||
"Install Guix manifest to `ambrevar/guix-extra-profiles'.
|
||||
|
||||
|
@ -169,7 +225,6 @@ If CHANNEL is nil and `ambrevar/guix-always-use-channel-specs' is
|
|||
non-nil, then try to use a channel specification file from
|
||||
`ambrevar/guix-channel-spec-directory' if any."
|
||||
(interactive)
|
||||
(require 'init-eshell) ; For `ambrevar/prefer-eshell'.
|
||||
(let* ((manifest-pair (ambrevar/guix-query-manifest manifest))
|
||||
(manifest-name (first manifest-pair))
|
||||
(manifest (second manifest-pair))
|
||||
|
@ -177,40 +232,26 @@ non-nil, then try to use a channel specification file from
|
|||
(and current-prefix-arg
|
||||
(second (ambrevar/guix-query-channel-spec)))
|
||||
(and ambrevar/guix-always-use-channel-specs
|
||||
(ambrevar/guix-find-channel-from-manifest manifest-name))))
|
||||
(guix (if channel
|
||||
(let ((dest (expand-file-name
|
||||
manifest-name
|
||||
ambrevar/guix-extra-channels)))
|
||||
(make-directory dest 'parents)
|
||||
(format "guix pull --channels=%s --profile=%s/guix && %s/guix/bin/guix"
|
||||
(shell-quote-argument channel)
|
||||
(shell-quote-argument dest)
|
||||
(shell-quote-argument dest)))
|
||||
"guix")))
|
||||
(make-directory (expand-file-name manifest-name
|
||||
ambrevar/guix-extra-profiles)
|
||||
'parents)
|
||||
(funcall (if ambrevar/prefer-eshell
|
||||
'ambrevar/run-in-eshell
|
||||
'ambrevar/run-in-shell)
|
||||
(string-join
|
||||
(list guix " package" (concat " --manifest=" manifest)
|
||||
(if (string= "default" manifest-name)
|
||||
""
|
||||
(concat " --profile=" (expand-file-name ambrevar/guix-extra-profiles)
|
||||
"/" manifest-name
|
||||
"/" manifest-name)))))
|
||||
(unless channel
|
||||
;; TODO: Only do this when manifest install has succeeded.
|
||||
(ambrevar/guix-save-channel-specs
|
||||
(format "%s/guix-%s-channels.scm"
|
||||
ambrevar/guix-channel-spec-directory
|
||||
manifest-name)))))
|
||||
(global-set-key (kbd "C-x c G") #'ambrevar/guix-install-manifest)
|
||||
(ambrevar/guix-find-channel-from-manifest manifest-name)))))
|
||||
(%ambrevar/guix-install-manifest (list manifest-pair) channel)))
|
||||
|
||||
(defun ambrevar/guix-install-manifests (&optional manifests channel)
|
||||
"Install Guix manifests to `ambrevar/guix-extra-profiles'.
|
||||
|
||||
Manifests are queried from those found in `ambrevar/guix-manifest-directory'.
|
||||
Guix channel specification is stored in `ambrevar/guix-channel-spec-directory'.
|
||||
|
||||
With a prefix argument, query for a channel specification file."
|
||||
(interactive)
|
||||
(let* ((manifests (or manifests (ambrevar/guix-query-manifest nil :multiple)))
|
||||
(channel (or channel
|
||||
(and current-prefix-arg
|
||||
(second (ambrevar/guix-query-channel-spec))))))
|
||||
(%ambrevar/guix-install-manifest manifests channel)))
|
||||
(global-set-key (kbd "C-x c G") #'ambrevar/guix-install-manifests)
|
||||
(with-eval-after-load 'evil
|
||||
(dolist (mode '(normal insert))
|
||||
(evil-global-set-key mode (kbd "C-x c G") #'ambrevar/guix-install-manifest)))
|
||||
(evil-global-set-key mode (kbd "C-x c G") #'ambrevar/guix-install-manifests)))
|
||||
|
||||
;; TODO: See `guix-apply-manifest' and expand on it.
|
||||
;; TODO: Use --max-jobs=N.
|
||||
|
|
Loading…
Reference in New Issue