This is a command-line utility for updating fetcher calls in Nix expressions. It has two primary purposes:
-
Automating the process of keeping such expressions up-to-date with the latest sources
-
Filling hashes automatically instead of copying from the error message1.
The following fetchers are supported:
fetchgit
fetchgitPrivate
fetchFromGitHub
fetchFromGitLab
builtins.fetchGit
builtins.fetchTarball
(Only updates the url when this is a archive fetch from GitHub)pkgs.haskellPackages.callHackageDirect
(Only updates the hash)fetchurl
(Only updates the hash)
The options deepClone
, leaveDotGit
, fetchSubmodules
are also supported.
Additionally if the rev
(for git fetches) or url
attribute has a comment:
pin
: the revision or URL will not be updated, only the hash will be changed- Anything else: the
rev
orurl
parameter will be updated to point to the revision pointed to by the branch or tag named in the comment. This is in the format expected bygit ls-remote
so if the expression hasrev = _; # tags/v*
it will be updated to the latest tag beginning withv
, sorted by version.
Pass the name of the files to be updated in place or pass no files to read and
write to stdin
and stdout
(useful as a filter in an editor).
update-nix-fetchgit file1.nix file2.nix
update-nix-fetchgit <file1.nix >file1-updated.nix
It will update fetchers anywhere in the files, note that it is a purely syntactic match so complicated invocations of the fetchers may not be picked up; see ./src/Update/Nix/Updater.hs to look at the shapes of Nix expressions which are matched.
If you pass --only-commented
only expressions which have a comment on the
rev
or url
attribute will be updated. This can be useful for updating files
en-mass with some control over which expressions are modified with a command
like: fd .nix --exec update-nix-fetchgit --only-commented
Please open an issue if update-nix-fetchgit
doesn't recognize a fetcher and
you think it could.
This VimScript will bind <leader>u
to update the fetcher under the cursor.
The mnemonic is u
for "it's unUsual to update things in this way"
" A helper to preserve the cursor location with filters
function! Preserve(command)
let w = winsaveview()
execute a:command
call winrestview(w)
endfunction
" Update fetcher under cursor, note that this might take a little while if the
" fetched path is large.
autocmd FileType nix map <nowait> <leader>u :call Preserve("%!update-nix-fetchgit --location=" . line(".") . ":" . col("."))<CR>
Here are some examples of nix expressions which can be updated:
-
Updating
src
andversion
{ stdenv, fetchgit }: stdenv.mkDerivation rec { name = "foo-${version}"; version = "2016-07-13"; # ^ version will be updated to the date of the new revision src = fetchgit { url = "git://midipix.org/slibtool"; rev = "4f56fd184ef6020626492a6f954a486d54f8b7ba"; # ^ rev will be updated to the revision of HEAD sha256 = "0nmyp5yrzl9dbq85wyiimsj9fklb8637a1936nw7zzvlnzkgh28n"; # ^ sha256 will be updated to the correct hash }; }
-
Following a branch fetched with
builtins.fetchTarball
{ pkgs ? import (builtins.fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/foobar.tar.gz"; # nixos-unstable # ^ 'foobar' will be replaced with the revision pointed to by 'refs/heads/nixos-unstable' sha256 = ""; # ^ sha256 will be updated to the correct hash }) { } }: myExpression
-
Updating the hash (instead of trying to build and copying the hash from the error message)
{ upfind = import (pkgs.fetchFromGitHub { owner = "expipiplus1"; repo = "upfind"; rev = "cb451254f5b112f839aa36e5b6fd83b60cf9b9ae"; # pin # ^ This will not change because of the '# pin' comment sha256 = _; # ^ This will be updated }) { }; }
When you run update-nix-fetchgit
on a file, it will:
- Read the file and parse it as a Nix expression.
- Find all calls to fetchers.
- Run
nix-prefetch-git
ornix-prefetch-url
(and a call to the GitHub API to get the commit date in the case ofbuiltins.fetchTarball
) to get information about the latest version. - Update the corresponding
rev
,sha256
,url
, andversion
attributes for each repository. - Overwrite the original input file or print to
stdout
Any version
attribute found in the file will be updated if it is in a set
that contains (directly or indirectly) a Git fetch. The version attribute will
be updated to the commit date of the latest HEAD commit in the Git repository,
in the time zone of the committer, in "YYYY-MM-DD" format. If the set contains
multiple Git fetches, the latest such date is used.
The recommended way to build this program from source for development purposes
is to download and run nix-shell
in the top-level source directory and then
run cabal build
.
- expipiplus1 - I'm
jophish
on Freenode; say hi! - DavidEGrayson
1: Don't deny you do it