Add IFD-free gitignoreSource implementation

This commit is contained in:
Robert Hensing 2019-05-12 13:48:32 +02:00
parent 25093d4d10
commit bcc385e399
8 changed files with 514 additions and 0 deletions

24
tests/default.nix Normal file
View file

@ -0,0 +1,24 @@
{ pkgs ? import <nixpkgs> {} }:
let
testdata = import ./testdata.nix { inherit pkgs; };
runner = import ./runner.nix { inherit pkgs; };
in
{
plain = runner.makeTest { name = "plain"; rootDir = testdata.sourceUnfiltered + "/test-tree"; };
nested = runner.makeTest { name = "nested"; rootDir = testdata.sourceUnfilteredRecursive + "/test-tree"; };
plain-with-testdata-dir = runner.makeTest { name = "plain"; rootDir = testdata.sourceUnfiltered; };
nested-with-testdata-dir = runner.makeTest { name = "nested"; rootDir = testdata.sourceUnfilteredRecursive; };
plain-with-testdata-subdir = runner.makeTest { name = "plain"; rootDir = testdata.sourceUnfiltered; subpath = "test-tree"; };
nested-with-testdata-subdir = runner.makeTest { name = "nested"; rootDir = testdata.sourceUnfilteredRecursive; subpath = "test-tree"; };
subdir-1 = runner.makeTest { name = "subdir-1"; rootDir = testdata.sourceUnfiltered + "/test-tree"; subpath = "1-simpl"; };
subdir-1x = runner.makeTest { name = "subdir-1x"; rootDir = testdata.sourceUnfiltered + "/test-tree"; subpath = "1-xxxxx"; };
subdir-2 = runner.makeTest { name = "subdir-2"; rootDir = testdata.sourceUnfiltered + "/test-tree"; subpath = "2-negation"; };
subdir-3 = runner.makeTest { name = "subdir-3"; rootDir = testdata.sourceUnfiltered + "/test-tree"; subpath = "3-wildcards"; };
subdir-4 = runner.makeTest { name = "subdir-4"; rootDir = testdata.sourceUnfiltered + "/test-tree"; subpath = "4-escapes"; };
subdir-9 = runner.makeTest { name = "subdir-9"; rootDir = testdata.sourceUnfiltered + "/test-tree"; subpath = "9-expected"; };
}

126
tests/runner.nix Normal file
View file

@ -0,0 +1,126 @@
{ pkgs ? import <nixpkgs> {} }:
let
inherit (pkgs) lib;
inherit (import ../. { inherit lib; }) gitignoreFilter gitignoreSource;
inherit (lib) concatMap flip;
inherit (lib.attrsets) mapAttrsToList nameValuePair;
inherit (lib.strings) concatStringsSep;
for = l: f: concatMap f l;
guard = b: if b then [{}] else [];
addPath = p: subp: if subp == "" then p else p + "/${subp}";
/*
Make a test case.
name: Name of the test case.
rootDir: Source for the native git implementation.
This is the root of the git repo; as required
by the native git implementation.
rootDir + "/${subpath}": Source for the Nix implementation, which ought to
discover rootDir by itself.
*/
makeTest = {name ? "source", rootDir, subpath ? ""}:
pkgs.runCommand "test-${name}" {
inherit name;
viaGit = listingViaGit { inherit name rootDir subpath; };
viaNix = listingViaNixGitignore { inherit name rootDir subpath; };
} ''
if diff $viaNix $viaGit; then
touch $out
else
echo
echo "Found a difference between nix-gitignore and native git."
echo "Above diff can be read as a 'fix' to the nix-gitignore output."
echo "< fix by excluding this in nix-gitignore"
echo "> fix by including this in nix-gitignore"
exit 1;
fi
'';
listingViaGit = {name ? "source", rootDir, subpath}:
pkgs.stdenv.mkDerivation {
name = "${name}-listing-via-git";
src = rootDir;
buildInputs = [pkgs.git];
buildPhase = ''
if ! test -d .git; then
rm .git || true
git init mkrepo
mv mkrepo/.git . || true
rm -rf mkrepo
fi
git add .
git config user.email a@b.c
git config user.name abc
git commit -m 'Add everything'
git archive HEAD -- ${subpath} | tar -t --quoting-style=literal | sed -e 's_/$__' -e 's@^${subpath}/*@@' | (grep -v '^$' || true) | sort >$out
'';
preInstall = "";
installPhase = ":";
};
listingViaNixGitignore = {name ? "source", rootDir, subpath}:
pkgs.stdenv.mkDerivation {
name = "${name}-listing-via-nix";
src = rootDir;
buildInputs = [
pkgs.git pkgs.nix pkgs.jq
# optional
pkgs.git-crypt
];
NIX_PATH="nixpkgs=${pkgs.path}";
inherit subpath;
buildPhase = ''
export NIX_LOG_DIR=$TMPDIR
export NIX_STATE_DIR=$TMPDIR
test -n "$subpath" && cd $subpath
nix-instantiate --eval --expr --json \
--readonly-mode --option sandbox false \
'(import ${gitignoreSource ../.}/tests/runner.nix {}).toStringNixGitignore ./.' \
| jq -r . \
| sort \
>$out
'';
preInstall = "";
installPhase = ":";
};
/* Like readDir but returning { name, type }
*/
listDir = dir: mapAttrsToList (name: type: { inherit name type; }) (builtins.readDir dir);
/* Like filtersource but only produces a list of paths instead of a source
*/
traverseDirectory = predicate: dir:
let
recurse = subpath:
for (listDir (dir + "/${subpath}")) ({name, type}:
let
subpath' = "${subpath}${if subpath == "" then "" else "/"}${name}";
in
for (guard (predicate (dir + "/${subpath'}") type)) ({}:
[subpath'] ++
for (guard (type == "directory")) (_:
recurse subpath'
)
)
);
in
recurse ""
;
traverseNixGitignore = dir: traverseDirectory (gitignoreFilter dir) dir;
/* Exposed for use *inside* the nix sandbox, called by listingViaNixGitignore.
*/
toStringNixGitignore = dir: concatStringsSep "\n" (traverseNixGitignore dir);
in
{
inherit makeTest toStringNixGitignore listingViaNixGitignore;
}