Deprecate builtin test's one- and zero-argument modes (#10365)

This introduces a feature flag, "test-require-arg", that removes builtin test's zero and one argument special modes.

That means:

- `test -n` returns false
- `test -z` returns true
- `test -x` with any other option errors out with "missing argument"
- `test foo` errors out as expecting an option

`test -n` returning true is a frequent source of confusion, and so we are breaking with posix in this regard.

As always the flag defaults to off and can be turned on. In future it will default to on and then eventually be made read-only.

There is a new FLOG category "deprecated-test", run `fish -d deprecated-test` and it will show any test call that would change in future.
This commit is contained in:
Fabian Boehm
2024-04-21 14:25:54 +02:00
committed by GitHub
parent 18a0b44f0f
commit 2c17d34971
8 changed files with 164 additions and 6 deletions

View File

@@ -25,7 +25,15 @@ The first form (``test``) is preferred. For compatibility with other shells, the
When using a variable or command substitution as an argument with ``test`` you should almost always enclose it in double-quotes, as variables expanding to zero or more than one argument will most likely interact badly with ``test``.
For historical reasons, ``test`` supports the one-argument form (``test foo``), and this will also be triggered by e.g. ``test -n $foo`` if $foo is unset. We recommend you don't use the one-argument form and quote all variables or command substitutions used with ``test``.
.. warning::
For historical reasons, ``test`` supports the one-argument form (``test foo``), and this will also be triggered by e.g. ``test -n $foo`` if $foo is unset. We recommend you don't use the one-argument form and quote all variables or command substitutions used with ``test``.
This confusing misfeature will be removed in future. ``test -n`` without any additional argument will be false, ``test -z`` will be true and any other invocation with exactly one or zero arguments, including ``test -d`` and ``test "foo"`` will be an error.
The same goes for ``[``, e.g. ``[ "foo" ]`` and ``[ -d ]`` will be errors.
This can be turned on already via the ``test-require-arg`` :ref:`feature flag <featureflags>`, and will eventually become the default and then only option.
Operators for files and directories
-----------------------------------
@@ -184,6 +192,8 @@ Be careful with unquoted variables::
echo $MANPATH
end
This will change in a future release of fish, or already with the ``test-require-arg`` :ref:`feature flag <featureflags>` - if $MANPATH is unset, ``if test -n $MANPATH`` will be false.
Parentheses and the ``-o`` and ``-a`` operators can be combined to produce more complicated expressions. In this example, success is printed if there is a ``/foo`` or ``/bar`` file as well as a ``/baz`` or ``/bat`` file.
::
@@ -233,6 +243,7 @@ Standards
Unlike many things in fish, ``test`` implements a subset of the `IEEE Std 1003.1-2008 (POSIX.1) standard <https://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html>`__. The following exceptions apply:
- The ``<`` and ``>`` operators for comparing strings are not implemented.
- With ``test-require-arg``, the zero- and one-argument modes will behave differently.
In cases such as this, one can use ``command`` ``test`` to explicitly use the system's standalone ``test`` rather than this ``builtin`` ``test``.