update-nix-fetchgit
This is a command-line utility for updating fetcher calls in
Nix expressions. It has two primary purposes:
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
or url
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 by git ls-remote
so if the expression has rev = _; # tags/v*
it will be updated to the latest tag beginning with v
, sorted by
version.
Usage
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.
From Vim
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>
Examples
Here are some examples of nix expressions which can be updated:
-
Updating src
and version
{ 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
}) { };
}
Mechanism
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
or nix-prefetch-url
(and a call to the GitHub API to get the commit date in
the case of builtins.fetchTarball
) to get information about the latest
version.
- Update the corresponding
rev
, sha256
, url
, and version
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.
Building from source
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
.
Authors
1: Don't deny you do it