In this mode, the following restrictions apply:
* The builtins currentTime, currentSystem and storePath throw an
  error.
* $NIX_PATH and -I are ignored.
* fetchGit and fetchMercurial require a revision hash.
* fetchurl and fetchTarball require a sha256 attribute.
* No file system access is allowed outside of the paths returned by
  fetch{Git,Mercurial,url,Tarball}. Thus 'nix build -f ./foo.nix' is
  not allowed.
Thus, the evaluation result is completely reproducible from the
command line arguments. E.g.
  nix build --pure-eval '(
    let
      nix = fetchGit { url = https://github.com/NixOS/nixpkgs.git; rev = "9c927de4b179a6dd210dd88d34bda8af4b575680"; };
      nixpkgs = fetchGit { url = https://github.com/NixOS/nixpkgs.git; ref = "release-17.09"; rev = "66b4de79e3841530e6d9c6baf98702aa1f7124e4"; };
    in (import (nix + "/release.nix") { inherit nix nixpkgs; }).build.x86_64-linux
  )'
The goal is to enable completely reproducible and traceable
evaluation. For example, a NixOS configuration could be fully
described by a single Git commit hash. 'nixos-rebuild' would do
something like
  nix build --pure-eval '(
    (import (fetchGit { url = file:///my-nixos-config; rev = "..."; })).system
  ')
where the Git repository /my-nixos-config would use further fetchGit
calls or Git externals to fetch Nixpkgs and whatever other
dependencies it has. Either way, the commit hash would uniquely
identify the NixOS configuration and allow it to reproduced.
		
	
			
		
			
				
	
	
		
			93 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| source common.sh
 | |
| 
 | |
| if [[ -z $(type -p hg) ]]; then
 | |
|     echo "Mercurial not installed; skipping Mercurial tests"
 | |
|     exit 99
 | |
| fi
 | |
| 
 | |
| clearStore
 | |
| 
 | |
| repo=$TEST_ROOT/hg
 | |
| 
 | |
| rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix/hg
 | |
| 
 | |
| hg init $repo
 | |
| echo '[ui]' >> $repo/.hg/hgrc
 | |
| echo 'username = Foobar <foobar@example.org>' >> $repo/.hg/hgrc
 | |
| 
 | |
| echo utrecht > $repo/hello
 | |
| touch $repo/.hgignore
 | |
| hg add --cwd $repo hello .hgignore
 | |
| hg commit --cwd $repo -m 'Bla1'
 | |
| rev1=$(hg log --cwd $repo -r tip --template '{node}')
 | |
| 
 | |
| echo world > $repo/hello
 | |
| hg commit --cwd $repo -m 'Bla2'
 | |
| rev2=$(hg log --cwd $repo -r tip --template '{node}')
 | |
| 
 | |
| # Fetch the default branch.
 | |
| path=$(nix eval --raw "(builtins.fetchMercurial file://$repo).outPath")
 | |
| [[ $(cat $path/hello) = world ]]
 | |
| 
 | |
| # In pure eval mode, fetchGit without a revision should fail.
 | |
| [[ $(nix eval --raw "(builtins.readFile (fetchMercurial file://$repo + \"/hello\"))") = world ]]
 | |
| (! nix eval --pure-eval --raw "(builtins.readFile (fetchMercurial file://$repo + \"/hello\"))")
 | |
| 
 | |
| # Fetch using an explicit revision hash.
 | |
| path2=$(nix eval --raw "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev2\"; }).outPath")
 | |
| [[ $path = $path2 ]]
 | |
| 
 | |
| # In pure eval mode, fetchGit with a revision should succeed.
 | |
| [[ $(nix eval --pure-eval --raw "(builtins.readFile (fetchMercurial { url = file://$repo; rev = \"$rev2\"; } + \"/hello\"))") = world ]]
 | |
| 
 | |
| # Fetch again. This should be cached.
 | |
| mv $repo ${repo}-tmp
 | |
| path2=$(nix eval --raw "(builtins.fetchMercurial file://$repo).outPath")
 | |
| [[ $path = $path2 ]]
 | |
| 
 | |
| [[ $(nix eval --raw "(builtins.fetchMercurial file://$repo).branch") = default ]]
 | |
| [[ $(nix eval "(builtins.fetchMercurial file://$repo).revCount") = 1 ]]
 | |
| [[ $(nix eval --raw "(builtins.fetchMercurial file://$repo).rev") = $rev2 ]]
 | |
| 
 | |
| # But with TTL 0, it should fail.
 | |
| (! nix eval --tarball-ttl 0 "(builtins.fetchMercurial file://$repo)")
 | |
| 
 | |
| # Fetching with a explicit hash should succeed.
 | |
| path2=$(nix eval --tarball-ttl 0 --raw "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev2\"; }).outPath")
 | |
| [[ $path = $path2 ]]
 | |
| 
 | |
| path2=$(nix eval --tarball-ttl 0 --raw "(builtins.fetchMercurial { url = file://$repo; rev = \"$rev1\"; }).outPath")
 | |
| [[ $(cat $path2/hello) = utrecht ]]
 | |
| 
 | |
| mv ${repo}-tmp $repo
 | |
| 
 | |
| # Using a clean working tree should produce the same result.
 | |
| path2=$(nix eval --raw "(builtins.fetchMercurial $repo).outPath")
 | |
| [[ $path = $path2 ]]
 | |
| 
 | |
| # Using an unclean tree should yield the tracked but uncommitted changes.
 | |
| mkdir $repo/dir1 $repo/dir2
 | |
| echo foo > $repo/dir1/foo
 | |
| echo bar > $repo/bar
 | |
| echo bar > $repo/dir2/bar
 | |
| hg add --cwd $repo dir1/foo
 | |
| hg rm --cwd $repo hello
 | |
| 
 | |
| path2=$(nix eval --raw "(builtins.fetchMercurial $repo).outPath")
 | |
| [ ! -e $path2/hello ]
 | |
| [ ! -e $path2/bar ]
 | |
| [ ! -e $path2/dir2/bar ]
 | |
| [ ! -e $path2/.hg ]
 | |
| [[ $(cat $path2/dir1/foo) = foo ]]
 | |
| 
 | |
| [[ $(nix eval --raw "(builtins.fetchMercurial $repo).rev") = 0000000000000000000000000000000000000000 ]]
 | |
| 
 | |
| # ... unless we're using an explicit rev.
 | |
| path3=$(nix eval --raw "(builtins.fetchMercurial { url = $repo; rev = \"default\"; }).outPath")
 | |
| [[ $path = $path3 ]]
 | |
| 
 | |
| # Committing should not affect the store path.
 | |
| hg commit --cwd $repo -m 'Bla3'
 | |
| 
 | |
| path4=$(nix eval --tarball-ttl 0 --raw "(builtins.fetchMercurial file://$repo).outPath")
 | |
| [[ $path2 = $path4 ]]
 |