complete-computing-environment/nix-update.org

266 lines
13 KiB
Org Mode

:PROPERTIES:
:roam_refs: https://github.com/jwiegley/nix-update-el
:ID: 20220913T104837.013589
:ROAM_ALIASES: nix-update
:END:
#+title: jwiegley/nix-update-el
#+filetags: :Archive:
#+AUTO_TANGLE: t
#+ARCOLOGY_KEY: cce/nix-update-el
[[file:archive.org][Archive]] an [[id:cce/emacs][Emacs]] [[id:a7420bb9-395f-4afa-92fb-8eaa0b8a4cd8][Tool]] to update the =sha256= of [[id:cce/version_pins][Nix Version Pins]] etc... I have a modified version that will work in Org-mode and will process all of the declerations on the buffer that *aren't* missing =sha256= already, to bypass =builtins.fetchGit= not requiring/accepting one...
#+BEGIN_QUOTE
Bind nix-update-fetch to a key (I use C-. u), and then you can very easily update the rev/sha of a fetchgit declaration. Also works for several other fetch types.
#+END_QUOTE
#+ARROYO_EMACS_MODULE: nix-update
#+ARROYO_HOME_MODULE: hm/nix-update.nix
#+ARROYO_MODULE_WANTS: cce/nixos.org
I've extended it to ignore =builtins.fetchGit= blocks and iterate over the entire document:
#+begin_src emacs-lisp :tangle ~/org/cce/nix-update.el
;; (use-package nix-update
;; :bind (:map nix-mode-map)
;; ("M-o" . nix-update-fetch))
(defun nix-update-branch-revs ()
(interactive)
(save-excursion
(goto-char (point-min))
(while (search-forward "#+CALL: prefetch-git-rev" nil t)
(let* ((context (org-element-lineage (org-element-context)
'(babel-call)))
(info (org-babel-lob-get-info context)))
(when info (org-babel-execute-src-block nil info))))
(message "Fetched latest revisions.")))
(defun nix-update-decls (&optional arg)
"Update the nix fetch expression at point."
(interactive "P")
(save-excursion
(goto-char (point-min))
(while (re-search-forward (rx (and (submatch
(or "compileEmacsWikiFile"
(and "fetch"
(or "url"
"git"
"Pypi"
"zip"
(and "FromGit" (or "Hub" "Lab"))))))
(1+ space)
"{"))
nil t)
(goto-char (1- (match-end 0)))
(let ((begin (point))
(type (match-string 1)))
(forward-sexp)
(save-restriction
(narrow-to-region begin (point))
(cl-flet ((get-field
(field)
(goto-char (point-min))
(let ((field-re (concat field "\\s-+=\\s-+\"?\\(.+?\\)\"?\\s-*;"))
(res))
(cond
((re-search-forward field-re nil t)
(match-string 1))
((and (re-search-forward
(concat "inherit\\s-+.*" field ".*;")
nil
t)
(save-restriction
(widen)
(backward-up-list) (backward-up-list)
(prog1
(re-search-forward field-re nil t)
(setq res (match-string 1)))))
res))))
(set-field
(field value)
(goto-char (point-min))
(if (re-search-forward
(concat field "\\s-+=\\s-+\"?\\(.+?\\)\"?\\s-*;")
nil t)
(replace-match value nil t nil 1)
(goto-char (point-max))
(search-backward ";")
(goto-char (line-beginning-position))
(let ((leader " "))
(when (looking-at "^\\(\\s-+\\)")
(setq leader (match-string 1)))
(goto-char (line-end-position))
(when value
(insert ?\n leader field " = \"" value "\";"))))))
(let ((data
(pcase type
(`"fetchFromGitHub"
(let ((owner (get-field "owner"))
(repo (get-field "repo"))
(rev (or (and (null arg) (get-field "rev")) ""))
(submodules
(let ((subs (get-field "fetchSubmodules")))
(and subs (string-equal subs "true")))))
(with-temp-buffer
(message "Fetching GitHub repository: %s/%s ..."
owner repo)
(let ((inhibit-redisplay t))
(shell-command
(format
(concat
"nix-prefetch-git --no-deepClone"
(if submodules " --fetch-submodules" "")
" --quiet https://github.com/%s/%s.git %s")
owner repo rev)
(current-buffer))
(message
"Fetching GitHub repository: %s/%s:%s ...done"
owner repo rev))
(goto-char (point-min))
(json-read-object))))
(`"fetchFromGitLab"
(let ((owner (get-field "owner"))
(repo (get-field "repo"))
(rev (or (and (null arg) (get-field "rev")) "")))
(with-temp-buffer
(message "Fetching GitLab repository: %s/%s ..."
owner repo)
(let ((inhibit-redisplay t))
(shell-command
(format
(concat
"nix-prefetch-git --no-deepClone"
" --quiet https://gitlab.com/%s/%s.git %s")
owner repo rev)
(current-buffer))
(message
"Fetching GitLab repository: %s/%s ...done"
owner repo))
(goto-char (point-min))
(json-read-object))))
(`"fetchgit"
(let ((url (get-field "url"))
(rev (or (and (null arg) (get-field "rev")) "")))
(with-temp-buffer
(message "Fetching Git URL: %s ..." url)
(let ((inhibit-redisplay t))
(shell-command
(format (concat
"nix-prefetch-git --no-deepClone"
" --quiet '%s' %s")
url rev)
(current-buffer))
(message "Fetching Git URL: %s ...done" url))
(goto-char (point-min))
(json-read-object))))
(`"fetchurl"
(let ((url (get-field "url")))
(with-temp-buffer
(message "Fetching URL %s: ..." url)
(let ((inhibit-redisplay t))
(shell-command (format "nix-prefetch-url '%s'" url)
(current-buffer))
(message "Fetching URL %s: ...done" url))
(goto-char (point-min))
(while (looking-at "^\\(path is\\|warning\\)")
(forward-line))
(list
(cons 'date
(format-time-string "%Y-%m-%dT%H:%M:%S%z"))
(cons 'sha256
(buffer-substring
(line-beginning-position)
(line-end-position)))))))
(`"fetchzip"
(let ((url (get-field "url")))
(with-temp-buffer
(message "Fetching URL %s: ..." url)
(let ((inhibit-redisplay t))
(shell-command (format "nix-prefetch-url --unpack '%s'" url)
(current-buffer))
(message "Fetching URL %s: ...done" url))
(goto-char (point-min))
(while (looking-at "^\\(path is\\|warning\\)")
(forward-line))
(list
(cons 'date
(format-time-string "%Y-%m-%dT%H:%M:%S%z"))
(cons 'sha256
(buffer-substring
(line-beginning-position)
(line-end-position)))))))
(`"compileEmacsWikiFile"
(let ((name (get-field "name")))
(with-temp-buffer
(message "Fetching EmacsWiki file %s: ..." name)
(let ((inhibit-redisplay t))
(shell-command
(format
"nix-prefetch-url 'https://www.emacswiki.org/emacs/download/%s'" name)
(current-buffer))
(message "Fetching EmacsWiki file %s: ...done" name))
(goto-char (point-min))
(while (looking-at "^\\(path is\\|warning\\)")
(forward-line))
(list
(cons 'date
(format-time-string "%Y-%m-%dT%H:%M:%S%z"))
(cons 'sha256
(buffer-substring
(line-beginning-position)
(line-end-position)))))))
(`"fetchPypi"
(let ((pname (get-field "pname"))
(version (get-field "version")))
(message "version: %s" version)
(with-temp-buffer
(message "Fetching PyPi Package: %s-%s: ..." pname version)
(let ((inhibit-redisplay t))
(shell-command
(format
"nix-prefetch-url mirror://pypi/%s/%s/%s-%s.tar.gz"
(substring pname 0 1)
pname
pname
version)
(current-buffer))
(message "Fetching PyPi Package: %s-%s: ...done" pname version))
(goto-char (point-min))
(while (looking-at "^\\(path is\\|warning\\)")
(forward-line))
(list
(cons 'sha256
(buffer-substring
(line-beginning-position)
(line-end-position))))))))))
(if (assq 'rev data)
(progn
(message "Updating rev to %s" (alist-get 'rev data))
(set-field "rev" (alist-get 'rev data))))
(set-field "sha256" (alist-get 'sha256 data))
(if (assq 'date data)
(set-field "# date"
(let ((date (alist-get 'date data)))
(if (string-match "\\`\"\\(.+\\)\"\\'" date)
(match-string 1 date)
date)))))))))))
(bind-key "M-o o" #'nix-update-decls nix-mode-map)
(bind-key "M-o o" #'nix-update-decls org-mode-map)
(bind-key "M-o i" #'nix-update-branch-revs nix-mode-map)
(bind-key "M-o i" #'nix-update-branch-revs org-mode-map)
(provide 'cce/nix-update)
#+end_src
#+begin_src nix :tangle ~/arroyo-nix/hm/nix-update.nix
{ pkgs, ... }:
{
home.packages = with pkgs; [ nix-prefetch-git ];
}
#+end_src