Merge pull request #224834 from tweag/pathType-and-co
Improvements to pathType, pathIsDirectory and pathIsRegularFile
This commit is contained in:
commit
a344acdc7f
@ -117,10 +117,11 @@ let
|
||||
inherit (self.meta) addMetaAttrs dontDistribute setName updateName
|
||||
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
|
||||
hiPrioSet getLicenseFromSpdxId getExe;
|
||||
inherit (self.sources) pathType pathIsDirectory cleanSourceFilter
|
||||
inherit (self.filesystem) pathType pathIsDirectory pathIsRegularFile;
|
||||
inherit (self.sources) cleanSourceFilter
|
||||
cleanSource sourceByRegex sourceFilesBySuffices
|
||||
commitIdFromGitRepo cleanSourceWith pathHasContext
|
||||
canCleanSource pathIsRegularFile pathIsGitRepo;
|
||||
canCleanSource pathIsGitRepo;
|
||||
inherit (self.modules) evalModules setDefaultModuleLocation
|
||||
unifyModuleSyntax applyModuleArgsIfFunction mergeModules
|
||||
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
|
||||
|
@ -1,13 +1,93 @@
|
||||
# Functions for copying sources to the Nix store.
|
||||
# Functions for querying information about the filesystem
|
||||
# without copying any files to the Nix store.
|
||||
{ lib }:
|
||||
|
||||
# Tested in lib/tests/filesystem.sh
|
||||
let
|
||||
inherit (builtins)
|
||||
readDir
|
||||
pathExists
|
||||
;
|
||||
|
||||
inherit (lib.strings)
|
||||
hasPrefix
|
||||
;
|
||||
|
||||
inherit (lib.filesystem)
|
||||
pathType
|
||||
;
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
/*
|
||||
The type of a path. The path needs to exist and be accessible.
|
||||
The result is either "directory" for a directory, "regular" for a regular file, "symlink" for a symlink, or "unknown" for anything else.
|
||||
|
||||
Type:
|
||||
pathType :: Path -> String
|
||||
|
||||
Example:
|
||||
pathType /.
|
||||
=> "directory"
|
||||
|
||||
pathType /some/file.nix
|
||||
=> "regular"
|
||||
*/
|
||||
pathType =
|
||||
builtins.readFileType or
|
||||
# Nix <2.14 compatibility shim
|
||||
(path:
|
||||
if ! pathExists path
|
||||
# Fail irrecoverably to mimic the historic behavior of this function and
|
||||
# the new builtins.readFileType
|
||||
then abort "lib.filesystem.pathType: Path ${toString path} does not exist."
|
||||
# The filesystem root is the only path where `dirOf / == /` and
|
||||
# `baseNameOf /` is not valid. We can detect this and directly return
|
||||
# "directory", since we know the filesystem root can't be anything else.
|
||||
else if dirOf path == path
|
||||
then "directory"
|
||||
else (readDir (dirOf path)).${baseNameOf path}
|
||||
);
|
||||
|
||||
/*
|
||||
Whether a path exists and is a directory.
|
||||
|
||||
Type:
|
||||
pathIsDirectory :: Path -> Bool
|
||||
|
||||
Example:
|
||||
pathIsDirectory /.
|
||||
=> true
|
||||
|
||||
pathIsDirectory /this/does/not/exist
|
||||
=> false
|
||||
|
||||
pathIsDirectory /some/file.nix
|
||||
=> false
|
||||
*/
|
||||
pathIsDirectory = path:
|
||||
pathExists path && pathType path == "directory";
|
||||
|
||||
/*
|
||||
Whether a path exists and is a regular file, meaning not a symlink or any other special file type.
|
||||
|
||||
Type:
|
||||
pathIsRegularFile :: Path -> Bool
|
||||
|
||||
Example:
|
||||
pathIsRegularFile /.
|
||||
=> false
|
||||
|
||||
pathIsRegularFile /this/does/not/exist
|
||||
=> false
|
||||
|
||||
pathIsRegularFile /some/file.nix
|
||||
=> true
|
||||
*/
|
||||
pathIsRegularFile = path:
|
||||
pathExists path && pathType path == "regular";
|
||||
|
||||
/*
|
||||
A map of all haskell packages defined in the given path,
|
||||
identified by having a cabal file with the same name as the
|
||||
|
@ -18,21 +18,11 @@ let
|
||||
pathExists
|
||||
readFile
|
||||
;
|
||||
|
||||
/*
|
||||
Returns the type of a path: regular (for file), symlink, or directory.
|
||||
*/
|
||||
pathType = path: getAttr (baseNameOf path) (readDir (dirOf path));
|
||||
|
||||
/*
|
||||
Returns true if the path exists and is a directory, false otherwise.
|
||||
*/
|
||||
pathIsDirectory = path: if pathExists path then (pathType path) == "directory" else false;
|
||||
|
||||
/*
|
||||
Returns true if the path exists and is a regular file, false otherwise.
|
||||
*/
|
||||
pathIsRegularFile = path: if pathExists path then (pathType path) == "regular" else false;
|
||||
inherit (lib.filesystem)
|
||||
pathType
|
||||
pathIsDirectory
|
||||
pathIsRegularFile
|
||||
;
|
||||
|
||||
/*
|
||||
A basic filter for `cleanSourceWith` that removes
|
||||
@ -271,11 +261,20 @@ let
|
||||
};
|
||||
|
||||
in {
|
||||
inherit
|
||||
pathType
|
||||
pathIsDirectory
|
||||
pathIsRegularFile
|
||||
|
||||
pathType = lib.warnIf (lib.isInOldestRelease 2305)
|
||||
"lib.sources.pathType has been moved to lib.filesystem.pathType."
|
||||
lib.filesystem.pathType;
|
||||
|
||||
pathIsDirectory = lib.warnIf (lib.isInOldestRelease 2305)
|
||||
"lib.sources.pathIsDirectory has been moved to lib.filesystem.pathIsDirectory."
|
||||
lib.filesystem.pathIsDirectory;
|
||||
|
||||
pathIsRegularFile = lib.warnIf (lib.isInOldestRelease 2305)
|
||||
"lib.sources.pathIsRegularFile has been moved to lib.filesystem.pathIsRegularFile."
|
||||
lib.filesystem.pathIsRegularFile;
|
||||
|
||||
inherit
|
||||
pathIsGitRepo
|
||||
commitIdFromGitRepo
|
||||
|
||||
|
92
lib/tests/filesystem.sh
Executable file
92
lib/tests/filesystem.sh
Executable file
@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Tests lib/filesystem.nix
|
||||
# Run:
|
||||
# [nixpkgs]$ lib/tests/filesystem.sh
|
||||
# or:
|
||||
# [nixpkgs]$ nix-build lib/tests/release.nix
|
||||
|
||||
set -euo pipefail
|
||||
shopt -s inherit_errexit
|
||||
|
||||
# Use
|
||||
# || die
|
||||
die() {
|
||||
echo >&2 "test case failed: " "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if test -n "${TEST_LIB:-}"; then
|
||||
NIX_PATH=nixpkgs="$(dirname "$TEST_LIB")"
|
||||
else
|
||||
NIX_PATH=nixpkgs="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.."; pwd)"
|
||||
fi
|
||||
export NIX_PATH
|
||||
|
||||
work="$(mktemp -d)"
|
||||
clean_up() {
|
||||
rm -rf "$work"
|
||||
}
|
||||
trap clean_up EXIT
|
||||
cd "$work"
|
||||
|
||||
mkdir directory
|
||||
touch regular
|
||||
ln -s target symlink
|
||||
mkfifo fifo
|
||||
|
||||
checkPathType() {
|
||||
local path=$1
|
||||
local expectedPathType=$2
|
||||
local actualPathType=$(nix-instantiate --eval --strict --json 2>&1 \
|
||||
-E '{ path }: let lib = import <nixpkgs/lib>; in lib.filesystem.pathType path' \
|
||||
--argstr path "$path")
|
||||
if [[ "$actualPathType" != "$expectedPathType" ]]; then
|
||||
die "lib.filesystem.pathType \"$path\" == $actualPathType, but $expectedPathType was expected"
|
||||
fi
|
||||
}
|
||||
|
||||
checkPathType "/" '"directory"'
|
||||
checkPathType "$PWD/directory" '"directory"'
|
||||
checkPathType "$PWD/regular" '"regular"'
|
||||
checkPathType "$PWD/symlink" '"symlink"'
|
||||
checkPathType "$PWD/fifo" '"unknown"'
|
||||
checkPathType "$PWD/non-existent" "error: evaluation aborted with the following error message: 'lib.filesystem.pathType: Path $PWD/non-existent does not exist.'"
|
||||
|
||||
checkPathIsDirectory() {
|
||||
local path=$1
|
||||
local expectedIsDirectory=$2
|
||||
local actualIsDirectory=$(nix-instantiate --eval --strict --json 2>&1 \
|
||||
-E '{ path }: let lib = import <nixpkgs/lib>; in lib.filesystem.pathIsDirectory path' \
|
||||
--argstr path "$path")
|
||||
if [[ "$actualIsDirectory" != "$expectedIsDirectory" ]]; then
|
||||
die "lib.filesystem.pathIsDirectory \"$path\" == $actualIsDirectory, but $expectedIsDirectory was expected"
|
||||
fi
|
||||
}
|
||||
|
||||
checkPathIsDirectory "/" "true"
|
||||
checkPathIsDirectory "$PWD/directory" "true"
|
||||
checkPathIsDirectory "$PWD/regular" "false"
|
||||
checkPathIsDirectory "$PWD/symlink" "false"
|
||||
checkPathIsDirectory "$PWD/fifo" "false"
|
||||
checkPathIsDirectory "$PWD/non-existent" "false"
|
||||
|
||||
checkPathIsRegularFile() {
|
||||
local path=$1
|
||||
local expectedIsRegularFile=$2
|
||||
local actualIsRegularFile=$(nix-instantiate --eval --strict --json 2>&1 \
|
||||
-E '{ path }: let lib = import <nixpkgs/lib>; in lib.filesystem.pathIsRegularFile path' \
|
||||
--argstr path "$path")
|
||||
if [[ "$actualIsRegularFile" != "$expectedIsRegularFile" ]]; then
|
||||
die "lib.filesystem.pathIsRegularFile \"$path\" == $actualIsRegularFile, but $expectedIsRegularFile was expected"
|
||||
fi
|
||||
}
|
||||
|
||||
checkPathIsRegularFile "/" "false"
|
||||
checkPathIsRegularFile "$PWD/directory" "false"
|
||||
checkPathIsRegularFile "$PWD/regular" "true"
|
||||
checkPathIsRegularFile "$PWD/symlink" "false"
|
||||
checkPathIsRegularFile "$PWD/fifo" "false"
|
||||
checkPathIsRegularFile "$PWD/non-existent" "false"
|
||||
|
||||
echo >&2 tests ok
|
@ -44,6 +44,9 @@ pkgs.runCommand "nixpkgs-lib-tests" {
|
||||
echo "Running lib/tests/modules.sh"
|
||||
bash lib/tests/modules.sh
|
||||
|
||||
echo "Running lib/tests/filesystem.sh"
|
||||
TEST_LIB=$PWD/lib bash lib/tests/filesystem.sh
|
||||
|
||||
echo "Running lib/tests/sources.sh"
|
||||
TEST_LIB=$PWD/lib bash lib/tests/sources.sh
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user