From 526e3b37e380e41e0c165ef2f4e40139ae5936b9 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 22 Nov 2019 22:53:43 +0100 Subject: [PATCH 1/6] Polish --- find-files.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/find-files.nix b/find-files.nix index 1e788d3..cd72229 100644 --- a/find-files.nix +++ b/find-files.nix @@ -4,7 +4,7 @@ let parse-gitignore = import ./rules.nix { inherit lib; }; in rec { - inherit (builtins) dirOf baseNameOf abort split hasAttr readFile readDir; + inherit (builtins) dirOf baseNameOf abort split hasAttr readFile readDir pathExists; inherit (lib.lists) filter length head tail concatMap take; inherit (lib.attrsets) filterAttrs mapAttrs attrNames; inherit (lib.strings) hasPrefix removePrefix splitString; @@ -27,7 +27,7 @@ rec { localDirPathElements = splitString "/" localDirPath; patternResult = parse-gitignore.runFilterPattern (getPatterns patternsBelowP localDirPathElements)."/patterns" path type; nonempty = any (nodeName: gitignoreFilter (basePath + "/${nodeName}") != false) - (attrNames (builtins.readDir path)); + (attrNames (readDir path)); in patternResult && (type == "directory" -> nonempty); getPatterns = @@ -162,7 +162,7 @@ rec { # TODO: only readDir lazily for the .git type. Rest can be done efficiently with pathExists inspectDir = dirPath: - let + let d = readDir dirPath; dotGitType = d.".git" or null; isWorkTreeRoot = dotGitType != null; @@ -280,7 +280,7 @@ rec { */ safeGetNodeType = path: if toString path == "/" then nodeTypes.directory - else if builtins.pathExists path + else if pathExists path then let parentDir = readDir (dirOf path); in parentDir."${baseNameOf path}" or null else null; From de0767e90eb7f4a062e84756551badadf3f4c6eb Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 22 Nov 2019 22:55:00 +0100 Subject: [PATCH 2/6] Prevent a readDir via pathExists --- find-files.nix | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/find-files.nix b/find-files.nix index cd72229..3f0bf2e 100644 --- a/find-files.nix +++ b/find-files.nix @@ -160,16 +160,19 @@ rec { isForbiddenDir = p: p == builtins.storeDir || p == "/"; - # TODO: only readDir lazily for the .git type. Rest can be done efficiently with pathExists inspectDir = dirPath: let d = readDir dirPath; dotGitType = d.".git" or null; - isWorkTreeRoot = dotGitType != null; + isWorkTreeRoot = pathExists (dirPath + "/.git"); gitDir = if dotGitType == nodeTypes.directory then dirPath + "/.git" else if dotGitType == nodeTypes.regular then readDotGitFile (dirPath + "/.git") - else dotGitType; - hasGitignore = (d.".gitignore" or null) == nodeTypes.regular; + else throw ".git is a symlink. Teach me what that means."; + + # directory should probably be ignored here, but to figure out the node type, we + # currently don't have a builtin to do it directly and readDir is expensive, + # particularly for a tool like lorri. + hasGitignore = pathExists (dirPath + "/.gitignore"); in { inherit isWorkTreeRoot hasGitignore gitDir dirPath; }; /* .git file path -> GIT_DIR From a422a9797ac2657da8cf25eee4599d79b457208a Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 22 Nov 2019 23:03:22 +0100 Subject: [PATCH 3/6] Elaborate null vs unknown .git node type --- find-files.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/find-files.nix b/find-files.nix index 3f0bf2e..63a5b53 100644 --- a/find-files.nix +++ b/find-files.nix @@ -167,7 +167,9 @@ rec { isWorkTreeRoot = pathExists (dirPath + "/.git"); gitDir = if dotGitType == nodeTypes.directory then dirPath + "/.git" else if dotGitType == nodeTypes.regular then readDotGitFile (dirPath + "/.git") - else throw ".git is a symlink. Teach me what that means."; + else if dotGitType == nodeTypes.symlink then throw "gitignore.nix: ${toString dirPath}/.git is a symlink. This is not supported (yet?)." + else if dotGitType == null then null + else throw "gitignore.nix: ${toString dirPath}/.git is of unknown node type ${dotGitType}"; # directory should probably be ignored here, but to figure out the node type, we # currently don't have a builtin to do it directly and readDir is expensive, From bf4d43602f495c80973a9aa81244f9f937f3a2d4 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 22 Nov 2019 23:19:16 +0100 Subject: [PATCH 4/6] Fix XDG_ env var handling --- find-files.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/find-files.nix b/find-files.nix index 63a5b53..3ae76fe 100644 --- a/find-files.nix +++ b/find-files.nix @@ -203,9 +203,9 @@ rec { maybeXdgGitConfigFile = for - (guardNonEmptyString (/. + builtins.getEnv "XDG_CONFIG_HOME")) + (guardNonEmptyString (builtins.getEnv "XDG_CONFIG_HOME")) (xdgConfigHome: - guardFile (xdgConfigHome + "/git/config") + guardFile (/. + xdgConfigHome + "/git/config") ); maybeGlobalConfig = take 1 (guardFile ~/.gitconfig ++ maybeXdgGitConfigFile @@ -226,9 +226,9 @@ rec { ) ); xdgExcludesFile = for - (guardNonEmptyString (/. + builtins.getEnv "XDG_CONFIG_HOME")) + (guardNonEmptyString (builtins.getEnv "XDG_CONFIG_HOME")) (xdgConfigHome: - guardFile (xdgConfigHome + "/git/ignore") + guardFile (/. + xdgConfigHome + "/git/ignore") ); maybeGlobalIgnoresFile = take 1 ( globalConfiguredExcludesFile From f4c201667ce43608a994ed22e3dbc9074c7adc80 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 22 Nov 2019 23:21:12 +0100 Subject: [PATCH 5/6] Hope for sane setups when checking files --- find-files.nix | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/find-files.nix b/find-files.nix index 3ae76fe..963e9e7 100644 --- a/find-files.nix +++ b/find-files.nix @@ -257,7 +257,14 @@ rec { nullableToList = x: if x == null then [] else [x]; for = l: f: concatMap f l; guard = b: if b then [{}] else []; - guardFile = p: if nodeTypes.isFile (safeGetNodeType p) then [p] else []; + guardProperFile = p: if nodeTypes.isFile (safeGetNodeType p) then [p] else []; + + # guardFile + # Like guardProperFile but avoid reading a directory. This can't check whether + # it's actually a file, rather than something else, but that's worth it for + # (lorri) performance. + # TODO: get something like builtins.pathType or builtins.stat into Nix + guardFile = p: if pathExists p then [p] else []; guardNonEmptyString = s: if s == "" then [s] else []; guardNonNull = a: if a != null then a else []; From 5196a460309edc852ff9827955ab386f473d94fe Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 28 Nov 2019 16:21:51 +0100 Subject: [PATCH 6/6] Remove guardProperFile and doc the readDir problem --- README.md | 2 ++ find-files.nix | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 30323bf..5c03bbf 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ mkDerivation { } ``` +If you need something more specific, that can not be achieved with Nixpkgs' `cleanSourceWith` function, you may want to use [gitignoreFilter](docs/gitignoreFilter.md). + # Features - Reads parent gitignores even if only pointed at a subdirectory diff --git a/find-files.nix b/find-files.nix index 963e9e7..a5ff411 100644 --- a/find-files.nix +++ b/find-files.nix @@ -257,12 +257,16 @@ rec { nullableToList = x: if x == null then [] else [x]; for = l: f: concatMap f l; guard = b: if b then [{}] else []; - guardProperFile = p: if nodeTypes.isFile (safeGetNodeType p) then [p] else []; - # guardFile - # Like guardProperFile but avoid reading a directory. This can't check whether - # it's actually a file, rather than something else, but that's worth it for - # (lorri) performance. + /* + Check whether a path exists; if it does, return it as a singleton list. + + Currently it checks whether a path exists, but we'd like to check the + node type, so we don't try to readFile for example a directory if we don't + have to. + It can be done with readDir but this causes lorri to watch everything, + which is really bad when reading for example ~/.gitconfig. + */ # TODO: get something like builtins.pathType or builtins.stat into Nix guardFile = p: if pathExists p then [p] else []; guardNonEmptyString = s: if s == "" then [s] else [];