• [gentoo-dev] New eclass: eapi9-pipestatus.eclass

    From =?utf-8?Q?Ulrich_M=C3=BCller?=@21:1/5 to All on Sun Nov 24 13:30:01 2024
    --=-=-=
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: quoted-printable

    This implements a pipestatus command, as discussed in bug 566342 [1]
    and on IRC.

    Subject to approval by the council, the command would be added in
    EAPI 9. Its definition in the Package Manager Specification would be
    along the lines of:

    ΓòôΓöÇΓöÇΓöÇΓöÇ
    Γòæ Tests the shell's pipe status array, i.e. the exit status of the
    Γòæ command(s) in the most recently executed foreground pipeline.
    Γòæ Returns shell true (0) if all elements are zero, or the last
    Γòæ non-zero element otherwise. If called with -v as the first argument,
    Γòæ also outputs the pipe status array as a space-separated list. ΓòÖΓöÇΓöÇΓöÇΓöÇ

    The "assert" command could then be banned (either in the same EAPI or
    in the following EAPI), typically to be replaced by "pipestatus || die".

    I would commit the eclass after the next council meeting, and obviously
    only under the condition that the council will pre-approve the command
    for EAPI 9.

    [1] https://bugs.gentoo.org/566342


    --=-=-Content-Type: text/plain; charset=utf-8
    Content-Disposition: inline; filenameΩpi9-pipestatus.eclass Content-Transfer-Encoding: quoted-printable

    # Copyright 2024 Gentoo Authors
    # Distributed under the terms of the GNU General Public License v2

    # @ECLASS: eapi9-pipestatus.eclass
    # @MAINTAINER:
    # Ulrich M├╝ller <ulm@gentoo.org>
    # @AUTHOR:
    # Ulrich M├╝ller <ulm@gentoo.org>
    # @SUPPORTED_EAPIS: 7 8
    # @BLURB: test the PIPESTATUS array
    # @DESCRIPTION:
    # A stand-alone implementation of a possible future pipestatus command
    # (which would be aimed for EAPI 9). It is meant as a replacement for
    # "assert". In its simplest form it can be called like this:
    #
    # @CODE
    # foo | bar
    # pipestatus || die
    # @CODE
    #
    # With the -v option, the command will also echo the pipe status array,
    # so it can be assigned to a variable like in the following example:
    #
    # @CODE
    # local status
    # foo | bar
    # status=$(pipestatus -v) || die "foo | bar failed, status ${status}"
    # @CODE

    case ${EAPI} in
    7|8) ;;
    *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
    esac

    # @FUNCTION: pipestatus
    # @USAGE: [-v]
    # @RETURN: last non-zero element of PIPESTATUS, or zero if all are zero
    # @DESCRIPTION:
    # Test the PIPESTATUS array, i.e. the exit status of the command(s)
    # in the most recently executed foreground pipeline. If called with
    # option -v, also output the PIPESTATUS array.
    pipestatus() {
    local -a status=( "${PIPESTATUS[@]}" )
    local s ret=0

    [[ $# -gt 0 && ${1} != -v || $# -gt 1 ]] \
    && die "${FUNCNAME}: bad arguments: $@"

    [[ ${1} == -v ]] && echo "${status[@]}"

    for s in "${status[@]}"; do
    [[ ${s} -ne 0 ]] && ret=${s}
    done

    return "${ret}"
    }

    --=-=-=--

    --==-=-Content-Type: application/pgp-signature; name="signature.asc"

    -----BEGIN PGP SIGNATURE-----

    iQFDBAEBCAAtFiEEtDnZ1O9xIP68rzDbUYgzUIhBXi4FAmdDGwsPHHVsbUBnZW50 b28ub3JnAAoJEFGIM1CIQV4u3W4H/1kybz6ohbS1NJ40yJJhTiiXUyCwr8aqL7zR 9GsDo8COGBscCeDCAIhYMdxpa8gRL6jwHYhcIDlmnRSyPyTuqeRy0PrYLV2BKi0R Tw+m485DTqvF9wu5hnDymqv2Iiy4xYD3Y7QmTbh0u/gjzVxpoSwwNRlNIu91XYBo u4nw1f6Q9yEkhYPsau61U5Oh+mWAvXmMl+CzVS7ZZlcUrcCDtydTclK4PyN01edg t3SzPnulDwbailxVTqOlUMEa5l1CFZdc6y2RkTUmokHuwP4u5ogOpcM8Onje1Mff LQvodfjOhIekrnRfLmn5faNkhn9h16U5QM+eaVzqXq74sZ5c/OY=0pUl
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Micha=C5=82_G=C3=B3rny?=@21:1/5 to All on Sun Nov 24 14:00:01 2024
    On Sun, 2024-11-24 at 13:24 +0100, Ulrich Müller wrote:
    # Copyright 2024 Gentoo Authors
    # Distributed under the terms of the GNU General Public License v2

    # @ECLASS: eapi9-pipestatus.eclass
    # @MAINTAINER:
    # Ulrich Müller <ulm@gentoo.org>
    # @AUTHOR:
    # Ulrich Müller <ulm@gentoo.org>
    # @SUPPORTED_EAPIS: 7 8
    # @BLURB: test the PIPESTATUS array
    # @DESCRIPTION:
    # A stand-alone implementation of a possible future pipestatus command
    # (which would be aimed for EAPI 9). It is meant as a replacement for
    # "assert". In its simplest form it can be called like this:
    #
    # @CODE
    # foo | bar
    # pipestatus || die
    # @CODE
    #
    # With the -v option, the command will also echo the pipe status array,
    # so it can be assigned to a variable like in the following example:
    #
    # @CODE
    # local status
    # foo | bar
    # status=$(pipestatus -v) || die "foo | bar failed, status ${status}"

    I suppose you may want to put a verbose warning not to put "local"
    on the same line, because people are going to do that as an "obvious" optimization.

    # @CODE

    case ${EAPI} in
    7|8) ;;
    *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
    esac

    # @FUNCTION: pipestatus
    # @USAGE: [-v]
    # @RETURN: last non-zero element of PIPESTATUS, or zero if all are zero
    # @DESCRIPTION:
    # Test the PIPESTATUS array, i.e. the exit status of the command(s)
    # in the most recently executed foreground pipeline. If called with
    # option -v, also output the PIPESTATUS array.
    pipestatus() {
    local -a status=( "${PIPESTATUS[@]}" )
    local s ret=0

    [[ $# -gt 0 && ${1} != -v || $# -gt 1 ]] \

    Please use parentheses when you combine && and ||, if only for the sake
    of readability.

    && die "${FUNCNAME}: bad arguments: $@"

    Replace the '\' with the '&&'.


    [[ ${1} == -v ]] && echo "${status[@]}"

    for s in "${status[@]}"; do
    [[ ${s} -ne 0 ]] && ret=${s}

    I suppose it's just my C-foo talking and completely needless
    optimization here, but it really itches me to iterate the array
    backwards and return on the first match.

    done

    return "${ret}"
    }

    --
    Best regards,
    Michał Górny


    -----BEGIN PGP SIGNATURE-----

    iQFGBAABCgAwFiEEx2qEUJQJjSjMiybFY5ra4jKeJA4FAmdDItwSHG1nb3JueUBn ZW50b28ub3JnAAoJEGOa2uIyniQOqekH/0/0UlpZQq68rD9wjU7n1LjAdE+UXwcw S4kkSHJ0xayowgxjp0KYl45bL5/Y+xoc8qeSd5MN4Frf1XS3tZcPRA9lW7YmgHjw 52V0p16hkWVbj+tby7YYjg2U+gtIUb14dLl+EDmr9pHQemmYX+0crGC4TTRGarQA uqiSMPi77xGE5ILfG00kK6sQLCjPySipdyvT51vpFJLpBePUxVI3MlXPWa0LhM52 90N4u9muNkovltliiekLfBUySh8+WoQXaUIZ2YWs3+OCDChUGS3UtmsaRLTbWgnE 6VPg3pL9yg5ieCK4n9sT2H6LVWUs0mnmRDFQaxUY2kYFw5eHTMbWsSY=
    =Y71a
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?utf-8?Q?Ulrich_M=C3=BCller?=@21:1/5 to All on Sun Nov 24 15:20:01 2024
    On Sun, 24 Nov 2024, Michał Górny wrote:

    # @CODE
    # local status
    # foo | bar
    # status=$(pipestatus -v) || die "foo | bar failed, status ${status}"

    I suppose you may want to put a verbose warning not to put "local"
    on the same line, because people are going to do that as an "obvious" optimization.

    Thank you for the feedback. I have added the following:

    # Caveat: "pipestatus" must be the next command following the pipeline.
    # In particular, the "local" declaration must be before the pipeline,
    # otherwise it will reset the status.

    [[ $# -gt 0 && ${1} != -v || $# -gt 1 ]] \

    Please use parentheses when you combine && and ||, if only for the sake
    of readability.

    I've replaced it by:

    [[ $# -gt 0 && ( ${1} != -v || $# -gt 1 ) ]]

    Note that

    [[ ( $# -gt 0 && ${1} != -v ) || $# -gt 1 ]]

    would also work, i.e. order doesn't matter (the reason is that "-gt 1"
    implies "-gt 0").

    && die "${FUNCNAME}: bad arguments: $@"

    Replace the '\' with the '&&'.

    We don't have any policy on this, and IMHO it is clearer to split the
    line before the operator. (This is also what the GNU coding standards
    say, and what is used in mathematical typesetting.)

    [[ ${1} == -v ]] && echo "${status[@]}"

    for s in "${status[@]}"; do
    [[ ${s} -ne 0 ]] && ret=${s}

    I suppose it's just my C-foo talking and completely needless
    optimization here, but it really itches me to iterate the array
    backwards and return on the first match.

    I had considered this and decided against it, see the last paragraph
    of https://bugs.gentoo.org/566342#c13:

    | Alternatively, one could loop backwards over the array (and return
    | for the first nonzero status) but it would be more complicated.
    | I don't think that would be more efficient because the normal case
    | is that all statūs are zero. Plus, pipelines rarely consist of more
    | than 3 commands.

    Ulrich

    --=-=-Content-Type: application/pgp-signature; name="signature.asc"

    -----BEGIN PGP SIGNATURE-----

    iQFDBAEBCAAtFiEEtDnZ1O9xIP68rzDbUYgzUIhBXi4FAmdDNFQPHHVsbUBnZW50 b28ub3JnAAoJEFGIM1CIQV4uhdkH/RGw66breGhWK9zfHitwudal4WobrWEIGMKR X2KxjWjUlHi4qG2spoSUwAasVx2ebwFbdjJVBrarNWyOBGn+DLyH3GI3xNgT9sa/ 65kuQdvLmYA9fIM4FXC3AzAV2py3xWg7cHIHwBMEF3anpkvseQL+0FjuxfBKXhEX qFrqz/pnTSc/a4lL8jCkGbeJSmQIHMuzlZMO54N7Eu4Rpb9rRNd61R4YUdbsExUm Wcwd6H22BsmcidxdiFdIyB9aCg9wN2l2WDWXvOadmW7ZovE9kisZP9vWPBnjejyh CKdSjs4BlmfDnjBnPLsdqqiZC3Gj2sR0COTPrhZcK9IpqKn4YK4√jP
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?utf-8?Q?Ulrich_M=C3=BCller?=@21:1/5 to All on Tue Nov 26 08:00:01 2024
    --=-=-=
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: quoted-printable

    On Sun, 24 Nov 2024, Ulrich M├╝ller wrote:

    This implements a pipestatus command, as discussed in bug 566342 [1]
    and on IRC.

    ΓòôΓöÇΓöÇΓöÇΓöÇ
    Γòæ Tests the shell's pipe status array, i.e. the exit status of the
    Γòæ command(s) in the most recently executed foreground pipeline.
    Γòæ Returns shell true (0) if all elements are zero, or the last
    Γòæ non-zero element otherwise. If called with -v as the first argument,
    Γòæ also outputs the pipe status array as a space-separated list. ΓòÖΓöÇΓöÇΓöÇΓöÇ

    Updated version:
    - No functional changes
    - Minor style changes
    - Added a comment

    Thanks again for the feedback.


    --=-=-Content-Type: text/plain; charset=utf-8
    Content-Disposition: inline; filenameΩpi9-pipestatus.eclass Content-Transfer-Encoding: quoted-printable

    # Copyright 2024 Gentoo Authors
    # Distributed under the terms of the GNU General Public License v2

    # @ECLASS: eapi9-pipestatus.eclass
    # @MAINTAINER:
    # Ulrich M├╝ller <ulm@gentoo.org>
    # @AUTHOR:
    # Ulrich M├╝ller <ulm@gentoo.org>
    # @SUPPORTED_EAPIS: 7 8
    # @BLURB: test the PIPESTATUS array
    # @DESCRIPTION:
    # A stand-alone implementation of a possible future pipestatus command
    # (which would be aimed for EAPI 9). It is meant as a replacement for
    # "assert". In its simplest form it can be called like this:
    #
    # @CODE
    # foo | bar
    # pipestatus || die
    # @CODE
    #
    # With the -v option, the command will also echo the pipe status array,
    # so it can be assigned to a variable like in the following example:
    #
    # @CODE
    # local status
    # foo | bar
    # status=$(pipestatus -v) || die "foo | bar failed, status ${status}"
    # @CODE
    #
    # Caveat: "pipestatus" must be the next command following the pipeline.
    # In particular, the "local" declaration must be before the pipeline,
    # otherwise it would reset the status.

    case ${EAPI} in
    7|8) ;;
    *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
    esac

    # @FUNCTION: pipestatus
    # @USAGE: [-v]
    # @RETURN: last non-zero element of PIPESTATUS, or zero if all are zero
    # @DESCRIPTION:
    # Test the PIPESTATUS array, i.e. the exit status of the command(s)
    # in the most recently executed foreground pipeline. If called with
    # option -v, also output the PIPESTATUS array.
    pipestatus() {
    local status=( "${PIPESTATUS[@]}" )
    local s ret=0 verbose=""

    [[ ${1} == -v ]] && { verbose=1; shift; }
    [[ $# -ne 0 ]] && die "usage: ${FUNCNAME} [-v]"

    for s in "${status[@]}"; do
    [[ ${s} -ne 0 ]] && ret=${s}
    done

    [[ ${verbose} ]] && echo "${status[@]}"

    return "${ret}"
    }

    --=-=-=--

    --==-=-Content-Type: application/pgp-signature; name="signature.asc"

    -----BEGIN PGP SIGNATURE-----

    iQFDBAEBCAAtFiEEtDnZ1O9xIP68rzDbUYgzUIhBXi4FAmdFcEEPHHVsbUBnZW50 b28ub3JnAAoJEFGIM1CIQV4ul4EH/iU5hlDATQPkRoVlSQWkwlygD6bRYSdsSoQz 7AxmFmEJCP+BzktUPPXXm9vSeEQXcfGFc6Df67I3q3Dvn9S5C0nlmrW+qF+zJ8Sr J/G2tU5zMTcWHbFNLFwbDf0LQDhI1BVMOcfIxf7Nb3AXDcvoVrEKqCZs2IUDnSqS PRmd+Tzpvfx+BB1WdgNosaGJ5C7UxV3xbP1Hth3HvY2s9aSIh6nEdFC6CVsp54CF 0YZ8iAxmPxCKi9p4oZ558CSPfeBVHk174eZQCqC0fzd0QAMJLOSJrWccOFChpeMn PZapk9hn1UecrqUNvhc0PbIyY2OrStmJC5YYT8tOfDg+8+oAzr8┬ov
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Micha=C5=82_G=C3=B3rny?=@21:1/5 to Florian Schmaus on Wed Nov 27 13:00:01 2024
    On Wed, 2024-11-27 at 11:41 +0100, Florian Schmaus wrote:
    I looked forward to use pipestatus() in texlive-modules.eclass [1], but since the pipe includes a 'grep', which is not uncommon, I can not use
    what is currently proposed.

    Use sed instead.

    --
    Best regards,
    Michał Górny


    -----BEGIN PGP SIGNATURE-----

    iQFGBAABCgAwFiEEx2qEUJQJjSjMiybFY5ra4jKeJA4FAmdHB+USHG1nb3JueUBn ZW50b28ub3JnAAoJEGOa2uIyniQOnH8H/1L6wXI7tVhCVZPNL/Ng6Jz0wQKfciyX bi/e4FirQpV28oMLxOdFkdwOrdf+TfB84N8YHp3neQuoaGKihzhrppKVnVR4W25D k3tOxLA16G/55WhPQXlfA2htJJ/IpsycH/ux4r98cR+sLODezqmdt0rNCjRHEX6b A4VKOmsIEoZrjET6SIp0a8oDV6jDs0cY8RDrD3SRQRQKdS1fJVrDcugKzO5zs3NM LrymMHRAxOSQ6iEnP2To7rYFSZP2kSPC9kj1usf3ooI+J8B30+fe+JKmLbv09tXN bFq4zh3oQZNv6xyCgB4fB6FeikUhM5sp2iYgyeOy6LwzEkVQJlvu7gI=
    =aDvF
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?utf-8?Q?Ulrich_M=C3=BCller?=@21:1/5 to All on Wed Nov 27 13:40:02 2024
    On Wed, 27 Nov 2024, Florian Schmaus wrote:

    ╓────
    ║ Tests the shell's pipe status array, i.e. the exit status of the
    ║ command(s) in the most recently executed foreground pipeline.
    ║ Returns shell true (0) if all elements are zero, or the last
    ║ non-zero element otherwise. If called with -v as the first argument,
    ║ also outputs the pipe status array as a space-separated list.
    ╙────

    Thanks again for putting effort into this ulm.

    When this was discussed in #-qa one initial version of pipestatus()
    had support for specifying non-zero exit statues as success indication
    for certain commands in the pipe. The prime example being 'grep'
    returning 1 if no input matched.

    One proposed version had support for this, but it was removed in later version and the discussion in #-qa shifted towards how the value of PIPESTATUS can be preserved to be included in a potential error
    message.

    I agree that we should drop 'assert' and that dropping it requires a
    sensible named alternative. And the proposed version of pipestatus()
    is a functional equivalent alternative.

    However, I am not sure why the proposed pipestatus() does no longer
    include support for specifying non-zero exit statuses as success
    indication.

    I looked forward to use pipestatus() in texlive-modules.eclass [1],
    but since the pipe includes a 'grep', which is not uncommon, I can not
    use what is currently proposed.

    It seems strange to me to go this far, but then drop the ball on the
    last meter.

    Could we please consider re-adding support for this?

    I have dropped the feature because feedback in bug 566342 was very
    negative. The main argument was it would unnecessarily complicate the
    function, in order to account for a corner case.

    In the discussion it was suggested to introduce a wrapper instead;
    this is now bug 945110.

    Ulrich

    --=-=-Content-Type: application/pgp-signature; name="signature.asc"

    -----BEGIN PGP SIGNATURE-----

    iQFDBAEBCAAtFiEEtDnZ1O9xIP68rzDbUYgzUIhBXi4FAmdHEWcPHHVsbUBnZW50 b28ub3JnAAoJEFGIM1CIQV4uJRAIAKeoetZJJ6WwJqtZx/9CzV/MDipWz2hap3A3 ipgomj+MBGCrEHCleIoD/GtWn7CgJT6W4Cc3/jsV9d3W9UJpXkakRlTeFYTFL6PX 2tBgMoBwiNqmnJf2FbG/yOaV88cOhFSc+PPyfgjnhxIOj0UyoAgV0pO4iiQ747L1 2yAFvBtWCF618CvZGp2dK42gCsBhj2+UZ8sqvkq7A6u/Ugxlq+cXXu6TZv/765me pZlcqgDSt39zeBNPSJU0EBDbrcStP57H5rcCEwL8TELSjFjNZPo0QMOtt6CLKeXs fbaZOYfM6jaLpssXC/QpJlqP5fS6hhwdaEF7KhdFJe/jKNiK3LM=OAy7
    -----END PGP SIGNATURE-----

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)