mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Add warn-short-path-literals setting
Add a new setting to warn about path literals that don't start with "." or "/". When enabled, expressions like `foo/bar` will emit a warning suggesting to use `./foo/bar` instead. A functional test is included. The setting defaults to false for backward compatibility but could eventually default to true in the future. Closes: #13374 Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
parent
47f5e5fbef
commit
6d46dc9f6a
4 changed files with 80 additions and 0 deletions
|
|
@ -327,6 +327,21 @@ struct EvalSettings : Config
|
|||
|
||||
This option can be enabled by setting `NIX_ABORT_ON_WARN=1` in the environment.
|
||||
)"};
|
||||
|
||||
Setting<bool> warnShortPathLiterals{
|
||||
this,
|
||||
false,
|
||||
"warn-short-path-literals",
|
||||
R"(
|
||||
If set to true, the Nix evaluator will warn when encountering relative path literals
|
||||
that don't start with `./` or `../`.
|
||||
|
||||
For example, with this setting enabled, `foo/bar` would emit a warning
|
||||
suggesting to use `./foo/bar` instead.
|
||||
|
||||
This is useful for improving code readability and making path literals
|
||||
more explicit.
|
||||
)"};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -365,6 +365,15 @@ string_parts_interpolated
|
|||
path_start
|
||||
: PATH {
|
||||
std::string_view literal({$1.p, $1.l});
|
||||
|
||||
/* check for short path literals */
|
||||
if (state->settings.warnShortPathLiterals && literal.front() != '/' && literal.front() != '.') {
|
||||
logWarning({
|
||||
.msg = HintFmt("relative path literal '%s' should be prefixed with '.' for clarity: './%s'. (" ANSI_BOLD "warn-short-path-literals" ANSI_NORMAL " = true)", literal, literal),
|
||||
.pos = state->positions[CUR_POS]
|
||||
});
|
||||
}
|
||||
|
||||
Path path(absPath(literal, state->basePath.path.abs()));
|
||||
/* add back in the trailing '/' to the first segment */
|
||||
if (literal.size() > 1 && literal.back() == '/')
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ suites = [
|
|||
'impure-eval.sh',
|
||||
'pure-eval.sh',
|
||||
'eval.sh',
|
||||
'short-path-literals.sh',
|
||||
'repl.sh',
|
||||
'binary-cache-build-remote.sh',
|
||||
'search.sh',
|
||||
|
|
|
|||
55
tests/functional/short-path-literals.sh
Normal file
55
tests/functional/short-path-literals.sh
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source common.sh
|
||||
|
||||
clearStoreIfPossible
|
||||
|
||||
# Test 1: Without the setting (default), no warnings should be produced
|
||||
nix eval --expr 'test/subdir' 2>"$TEST_ROOT"/stderr
|
||||
grepQuietInverse < "$TEST_ROOT/stderr" -E "relative path|path literal" || fail "Should not produce warnings by default"
|
||||
|
||||
# Test 2: With the setting enabled, warnings should be produced for short path literals
|
||||
nix eval --warn-short-path-literals --expr 'test/subdir' 2>"$TEST_ROOT"/stderr
|
||||
grepQuiet "relative path literal 'test/subdir' should be prefixed with '.' for clarity: './test/subdir'" "$TEST_ROOT/stderr"
|
||||
|
||||
# Test 3: Different short path literals should all produce warnings
|
||||
nix eval --warn-short-path-literals --expr 'foo/bar' 2>"$TEST_ROOT"/stderr
|
||||
grepQuiet "relative path literal 'foo/bar' should be prefixed with '.' for clarity: './foo/bar'" "$TEST_ROOT/stderr"
|
||||
|
||||
nix eval --warn-short-path-literals --expr 'a/b/c/d' 2>"$TEST_ROOT"/stderr
|
||||
grepQuiet "relative path literal 'a/b/c/d' should be prefixed with '.' for clarity: './a/b/c/d'" "$TEST_ROOT/stderr"
|
||||
|
||||
# Test 4: Paths starting with ./ should NOT produce warnings
|
||||
nix eval --warn-short-path-literals --expr './test/subdir' 2>"$TEST_ROOT"/stderr
|
||||
grepQuietInverse "relative path literal" "$TEST_ROOT/stderr"
|
||||
|
||||
# Test 5: Paths starting with ../ should NOT produce warnings
|
||||
nix eval --warn-short-path-literals --expr '../test/subdir' 2>"$TEST_ROOT"/stderr
|
||||
grepQuietInverse "relative path literal" "$TEST_ROOT/stderr"
|
||||
|
||||
# Test 6: Absolute paths should NOT produce warnings
|
||||
nix eval --warn-short-path-literals --expr '/absolute/path' 2>"$TEST_ROOT"/stderr
|
||||
grepQuietInverse "relative path literal" "$TEST_ROOT/stderr"
|
||||
|
||||
# Test 7: Test that the warning is at the correct position
|
||||
nix eval --warn-short-path-literals --expr 'foo/bar' 2>"$TEST_ROOT"/stderr
|
||||
grepQuiet "at «string»:1:1:" "$TEST_ROOT/stderr"
|
||||
|
||||
# Test 8: Test that evaluation still works correctly despite the warning
|
||||
result=$(nix eval --warn-short-path-literals --expr 'test/subdir' 2>/dev/null)
|
||||
expected="$PWD/test/subdir"
|
||||
[[ "$result" == "$expected" ]] || fail "Evaluation result should be correct despite warning"
|
||||
|
||||
# Test 9: Test with nix-instantiate as well
|
||||
nix-instantiate --warn-short-path-literals --eval -E 'foo/bar' 2>"$TEST_ROOT"/stderr
|
||||
grepQuiet "relative path literal 'foo/bar' should be prefixed" "$TEST_ROOT/stderr"
|
||||
|
||||
# Test 10: Test that the setting can be set via configuration
|
||||
NIX_CONFIG='warn-short-path-literals = true' nix eval --expr 'test/file' 2>"$TEST_ROOT"/stderr
|
||||
grepQuiet "relative path literal 'test/file' should be prefixed" "$TEST_ROOT/stderr"
|
||||
|
||||
# Test 11: Test that command line flag overrides config
|
||||
NIX_CONFIG='warn-short-path-literals = true' nix eval --no-warn-short-path-literals --expr 'test/file' 2>"$TEST_ROOT"/stderr
|
||||
grepQuietInverse "relative path literal" "$TEST_ROOT/stderr"
|
||||
|
||||
echo "short-path-literals test passed!"
|
||||
Loading…
Add table
Add a link
Reference in a new issue