NixOS is a big
fan of reproduceability – indeed that's what i'm using it for. But then
I go read READMEs that say to do things like say "hey just download the
code here from github's master.tar.gz
and
use it unconditionally". Nuh-uh, no can-do, bad idea. I'm going to
maintain versions in a single Nix module which can be imported and used
and updated when necessary.
To update this document:
- Call cce/update-nixpkgs-checkout to update nixpkgs and then possibly resolve merge conflicts myself.
M-o i
will callnix-update-branch-revs
to fetch the latest revision for modules usingbuiltins.fetchGit
.1C-u M-o o
will callnix-update-decls
to update therev
andsha256
for the rest. Note the prefix argument which will forcenix-prefetch-git
to fetch the latest revisions of the default (or specified) branch.
To understand why/how read on:
This document contains Magic
To get the org-auto-tangle to work with the document I have had to be quite careful in how I construct it. I would like to be able to update all the refs on the page at once, by an affirmative user-action. The process for updating this file involves using modifications I've made of jweigley's nix-update-el and is simple to operate:
There is some scaffolding and nuance required to make this work in the tangle stage.
First of all, org-auto-tangle
is smart
enough to not execute Org
Babel functions by default. It's imperative to customize help:org-auto-tangle-babel-safelist.
Consider nix-update-branch-revs
. These
are fetched using this code block referenced in the document as prefetch-git-rev
, evaluated, and the results
inserted in to versions.nix
using noweb syntax. If this
was evaluated every time I saved the document, the version of
home-manager and emacs-overlay which are imported would change every
time I save!
require 's)
(
(s-chomp
(shell-command-to-stringformat "curl -s https://api.github.com/repos/%s/branches/%s | jq .commit.sha" REPO BRANCH))) (
This require
's things which aren't a
part of Emacs by default, so I have to modify my AUTO_TANGLE
document keyword with a new
feature to pass variables in to the async Emacs invocation, thus
#+AUTO_TANGLE: vars:load-path
. This is,
unfortunately, much slower to load and thus tangle now.
You'll note that this prefetch-git-rev
is an elisp function, why not just use a shell-script? well, org doesn't
load ob-shell
by default, and passing
org-babel-load-languages
in to the async
function was not enough to get it to work. oh well. Luckily I don't need
anything too special here.
And so we are quite careful in how this document is constructed.
Consider the home-manager example. If (NAME) were attached to the inline
org-babel CALL
, this would update every
save. So the results have to be named. The (invocation)
looks like a function call but will actually use the cached value.
#+CALL: prefetch-git-rev(REPO="nix-community/home-manager", BRANCH="master")
#+NAME: prefetch-hm (ref:NAME)
#+results:
: "60c6bfe322944d04bb38e76b64effcbd01258824"
#+begin_src nix :noweb-ref homeManager :noweb yes
homeManager = _: builtins.fetchGit {
url = "https://github.com/nix-community/home-manager.git";
rev =
<<prefetch-hm()>> (ref:invocation)
;
};
#+end_src
By structuring these invocations like this it is possible to write a
function contained in my nix-update page which will iterate
over all the call sections and update the builtins.fetchGit
entities, and then update the
revisions and sha256
of the rest of the
document, and safely tangle the new values out on save. This is probably
a useful pattern in developing Hypermedia in
org-mode.
NEXT update my NixOS version pins and deploy
sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
{ ... }:
{
homeManager>>
<<emacsOverlay>>
<<nixpkgs>>
<<
nixgl>>
<<mastodon>>
<<
# org libraries
consult-org-roam>>
<<ox-rss>>
<<org-fc>>
<<delve>>
<<
tabfs>>
<<cpmtools>>
<<tuhc>>
<<
# pythons
beetcamp>>
<<bandcamp-dl>>
<<mopidy-bandcamp>>
<<jisho-api>>
<<twitter-to-sqlite>>
<<inaturalist-to-sqlite>>
<<
ttrss>>
<<}
Run elisp:(cce/update-nixpkgs-checkout) first
Right now I am running off a branch of nixpkgs which builds
vsketch and vpype for my Plotter Art, so it's kind of a pain
to update rather than simply checking out the nixpkgs-unstable
branch.. Might have to elisp:(magit-status
"/home/rrix/Code/nixpkgs") and resolve some merge conflicts… I
should upstream these packages!!!
Update home-manager by hand
"5bac4a1c06cd77cf8fc35a658ccb035a6c50cd2c"
_: builtins.fetchGit {
homeManager = url = "https://github.com/nix-community/home-manager.git";
allRefs = true;
rev =
-hm()>>
<<prefetch;
};
Update emacs-overlay used in Arroyo Emacs by hand
"badf38fcef05e02764781847ffe498016401e5a5"
_: builtins.fetchGit {
emacsOverlay = url = "https://github.com/nix-community/emacs-overlay/";
rev =
-em()>>
<<prefetch;
};
^ This is upstream; I also have a checkout which I can manage with elisp:(magit-status
"~/Code/emacs-overlay"); I can move the #+NAME
keyword on the above code segment to this
one to build a local instance:
_: /home/rrix/Code/emacs-overlay; emacsOverlay =
mastodon in Emacs ->
builds from https://codeberg.org/martianh/mastodon.el/commits/branch/main
{ pkgs, ... }: pkgs.fetchgit {
mastodon = url = "https://codeberg.org/martianh/mastodon.el";
rev = "d4c105cc39315de3c9f3f29b97de0c0dec718770";
sha256 = "0jzgkbr7dmpv66cabmf8lnz3223m5vs25v06v27s1dfpy3grcxwf";
# date = "2023-08-31T12:12:05+02:00";
};
nixGL ->
{ pkgs, ... }: pkgs.fetchFromGitHub {
nixGL = owner = "guibou";
repo = "nixGL";
rev = "489d6b095ab9d289fe11af0219a9ff00fe87c7c5";
sha256 = "03kwsz8mf0p1v1clz42zx8cmy6hxka0cqfbfasimbj858lyd930k";
# date = "2023-06-04T21:57:57+02:00";
};
TabFS ->
-rev = "09d57f94b507f68ec5e16f53b1cc868fbaf6cceb";
tabfs-fetch = {pkgs, ...}: pkgs.fetchFromGitHub {
tabfsowner = "osnr";
repo = "TabFS";
rev = "e056ff9073470192ef4c8498aaa7e722edae87c2";
sha256 = "1xbnx30m6dcd10i5xrma5q0azky5w6hgas500ginqg9s9skgciiw";
# date = "2023-03-02T15:45:33-05:00";
};
consult-org-roam
-org-roam-rev = "268f436858e1ea3b263782af466a54e4d603a7d2";
consult-org-roam = {pkgs, ...}: pkgs.fetchFromGitHub {
consultowner = "jgru";
repo = "consult-org-roam";
rev = "2ca42a1c1641a29f1447d35be01bd1fda368a9e2";
sha256 = "142fra7wap6dfwd4c82j7z3nk1yw78slrwhjx6vkiql8ylbiw5fi";
# date = "2023-05-28T10:55:47+02:00";
};
ox-rss
-rss = rec {
oxversion = "20220704.0450";
rev = "83dc898fa5493925b01716e5dd495d5e07c3d41a";
url = "https://gitlab.com/nsavage/ox-rss.git/";
src = { pkgs, ... }: pkgs.fetchgit {
rev = "3b8bbe8a392bbb04f17bf426400c53283fd3647a";
url = "https://gitlab.com/nsavage/ox-rss.git/";
sha256 = "02k9mbi3shjzpmc2z6w5ypjvxq9mlnw6qjkrs8bi10fqsw6fjkpq";
# date = "2023-01-22T11:36:35+00:00";
};
};
org-fc
-fc = rec {
orgrev = "f64b5336485a42be91cfe77850c02a41575f5984";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "l3kn";
repo = "org-fc";
rev = "7ab1791dfa6aa6ca252a69d8f43d5b5e8c841190";
sha256 = "0hq11kp4l5qs0jgcvjfhggdr31jyl6mcgaj5c8dwr9x7b8awnh6j";
# date = "2023-05-14T13:41:04+02:00";
};
};
Ement.el
rec {
ement = rev = "8aea26acefd9e3eafa24db240e41aa9d41603586";
src = { pkgs, ... }: pkgs.fetchurl {
url = "https://github.com/alphapapa/ement.el/archive/8aea26acefd9e3eafa24db240e41aa9d41603586.tar.gz";
sha256 = "1zs8j9zvwda029ld2lnqkw03i7zsibrdy68fpsz5ylw7czd6qfzi";
# date = "2023-09-08T18:39:41-0700";
};
};
cpmtools
{
cpmtools = version = "2.21";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "lipro-cpm4l";
repo = "cpmtools";
rev = "e534e20c15973a9559e981efb498a102020e5db7";
sha256 = "0klad0zpxsllqcrjqqmsjvhcbrw7pjnkksr4n84ma6gc3nxb984c";
# date = "2020-07-26T12:24:37+02:00";
};
};
beetcamp
{
beetcamp = version = "unstable-2022-06-07";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
repo = "beetcamp";
owner = "snejus";
rev = "f09dfed68e74ee99474a7e414c9bcf4cf056ee5c";
sha256 = "1217gqd9jv4ip0rcmpq5q84gia891hwgpmdn2ywkcy4dvniwvxxa";
# date = "2023-08-09T10:09:27+01:00";
};
};
Mopidy Bandcamp
-bandcamp = {
mopidyversion = "1.1.5";
src = { python3Packages, ... }: python3Packages.fetchPypi {
version = "1.1.5";
pname = "Mopidy-Bandcamp";
sha256 = "012w2iw09skayskbswp5dak0mp5xf3p0ld90lxhh8rczw9q763y2";
};
};
delve
{
delve = version = "0.9.3";
commit = "9a3e2675ef76865e9ffd95bb49ae1c8307cbfcc1";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "publicimageltd";
repo = "delve";
rev = "f06bd7b1d8759a041601a2b8a870e60151cb750c";
sha256 = "1b9wf45y600vcf9747d36mnb9mrkaqbn6dwsqr5mik41dgxcw13l";
# date = "2023-03-27T09:59:51+02:00";
};
};
jisho-api
-api = {
jishoversion = "0.1.8";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "pedroallenrevez";
repo = "jisho-api";
rev = "d6dc85ca686e6f80b90fdf5ff5d2e76754abbdf2";
sha256 = "0lkkilab5g4mbd8d8cr4wbig4cm2sr9nwpdjv90f3bwpw6klizlf";
# date = "2023-09-05T13:53:44+01:00";
};
};
iNaturalist to Sqlite
-to-sqlite = {
inaturalistversion = "0.2.1";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "dogsheep";
repo = "inaturalist-to-sqlite";
rev = "d888c7c2f02aa0dfb1559603f02357cd0089da11";
sha256 = "0iybdjinlxinsh4fk74k65q39rn1phwg0q9xjay9w90i74dqd0nr";
# date = "2020-10-21T17:08:29-07:00";
};
};
Twitter to Sqlite
-to-sqlite = {
twitterversion = "0.2.1";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "dogsheep";
repo = "twitter-to-sqlite";
rev = "f09d611782a8372cfb002792dfa727325afb4db6";
sha256 = "0nr2s1avb7ah7ygw5p75h0q6qsqvr97k46hi1hsc1j4w6gy2q810";
# date = "2021-12-26T10:08:40-08:00";
};
};
bandcamp-dl
-dl = {
bandcampversion = "0.0.1";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "iliana";
repo = "bandcamp-dl";
rev = "5b434a8401f51397e4cc7c9bce87f6f137d3ec90";
sha256 = "1kqjnsmdpw4mv4f68fxfyclcimn4r6n4fxp5gz838l0dyc7kzqmv";
# date = "2023-04-08T22:16:38+00:00";
};
};
NEXT vsketch and vpype dependencies
NEXT automate fetchFromPyPi or move to GH fetchers
tt-rss plugins
{ pkgs, ... }: pkgs.fetchFromGitHub {
large_apod = owner = "joshp23";
repo = "TTRSS-APOD-Fix";
rev = "d6233f7a9031eaa07649d6b4777525524827f9de";
sha256 = "11vi81vha3sv9nq36ipxisrnrk5y38582f2nk7qg057d6jm9jw0f";
# date = "2017-06-25T13:52:41-04:00";
};
{ pkgs, ... }: pkgs.fetchFromGitHub {
ttrss_wallabag = owner = "joshp23";
repo = "ttrss-to-wallabag-v2";
rev = "49ade5a1a216de74e42c4942ffa9cbf1bf426bec";
sha256 = "09rspawg0by5fk1x5b3b3smzqp4zw93h8c7zdxr63z6wjs41ba0j";
# date = "2021-03-14T01:26:43-05:00";
};
# https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-af-readability
{ pkgs, ... }: pkgs.fetchgit {
ttrss_readability = url= "https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-af-readability";
rev = "cdc97d886cb7085f9c44a1796ee4bbbf57534d06";
sha256 = "sha256-Pbwp+s4G+mOwjseiejb0gbHpInc2lvR+sv85sRP/DVg=";
# date = "2021-03-14T01:26:43-05:00";
};
Unofficial Homestuck Collection in NixOS
rec {
homestuck = pname = "unofficial-homestuck-collection";
version = "2.0.7";
src = { ... }: builtins.fetchurl {
url = "https://github.com/Bambosh/unofficial-homestuck-collection/releases/download/v${version}/The-Unofficial-Homestuck-Collection-${version}.AppImage";
sha256 = "error: unable to download 'https://github.com/Bambosh/unofficial-homestuck-collection/releases/download/v${version}/The-Unofficial-Homestuck-Collection-${version}.AppImage': HTTP error 404";
name = "${pname}-${version}.AppImage";
# date = "2023-09-08T18:40:49-0700";
};
};
This is required because I couldn't get
nix-update-decls
to update the revs of these without also populating asha256
key which will not be valid in abuiltins.fetchGit
invocation. Both nix-community/emacs-overlay and home-manager are loaded in situations where there is no pre-existing nixpkgs to invoke, so they have to use this "impure" invocation.↩︎