[gentoo-commits] proj/gentoo-functions:master commit in: functions/, /
commit: 6cf0940b8d336eb35a970af2ffc819f55e3ab429 Author: Kerin Millar plushkava net> AuthorDate: Sat Aug 10 05:12:15 2024 + Commit: Sam James gentoo org> CommitDate: Sun Aug 11 10:11:03 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=6cf0940b Use the -nt and -ot test primaries again rather than depend on GNU find As regards the test(1) utility, the POSIX.1-2024 specification defines the -nt and -ot primaries as standard features. Given that the specification in question was only recently published, this would not normally be an adequate reason for using them in gentoo-functions, in and as of itself. However, I was already aware that the these primaries are commonly implemented and have been so for years. So, I decided to evaluate a number of shells and see how things stand now. Here is a list of the ones that I tested: - ash (busybox 1.36.1) - dash 0.5.12 - bash 5.2.26 - ksh 93u+ - loksh 7.5 - mksh 59c - oksh 7.5 - sh (FreeBSD 14.1) - sh (NetBSD 10.0) - sh (OpenBSD 7.5) - yash 2.56.1 Of these, bash, ksh93, loksh, mksh, oksh, OpenBSD sh and yash appear to conform with the POSIX-1.2024 specification. The remaining four fail to conform in one particular respect, which is as follows. $ touch existent $ set -- existent nonexistent $ [ "$1" -nt "$2" ]; echo "$?" # should be 0 1 $ [ "$2" -ot "$1" ]; echo "$?" # should be 0 1 To address this, I discerned a reasonably straightforward workaround that involves testing both whether the file under consideration exists and whether the variable keeping track of the newest/oldest file has yet been assigned to. As far as I am concerned, the coverage is more than adequate for both primaries to be used by gentoo-functions. As such, this commit adjusts the following three functions so as to do exactly that. - is_older_than() - newest() - oldest() It also removes the following functions, since they are no longer used. - _find0() - _select_by_mtime() With this, GNU findutils is no longer a required runtime dependency. Of course, should a newly introduced feature of gentoo-functions benefit from the presence of findutils in the future, there is no reason that it cannot be brought back in that capacity. Signed-off-by: Kerin Millar plushkava.net> Signed-off-by: Sam James gentoo.org> functions.sh| 157 +--- functions/rc.sh | 25 +++-- 2 files changed, 113 insertions(+), 69 deletions(-) diff --git a/functions.sh b/functions.sh index 641deb6..43ea385 100644 --- a/functions.sh +++ b/functions.sh @@ -1,6 +1,6 @@ # Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 -# shellcheck shell=sh disable=2209,3043 +# shellcheck shell=sh disable=2209,3013,3043 # This file contains a series of function declarations followed by some # initialisation code. Functions intended for internal use shall be prefixed @@ -294,17 +294,55 @@ is_anyof() # # Considers one or more pathnames and prints the one having the newest -# modification time. If at least one parameter is provided, all parameters shall -# be considered as pathnames to be compared to one another. Otherwise, the -# pathnames to be compared shall be read from the standard input as -# NUL-delimited records. If no pathnames are given, or those specified do not -# exist, the return value shall be greater than 0. In the case that two or more -# pathnames are candidates, the one having the lexicographically greatest value -# shall be selected. Pathnames containing newline characters shall be ignored. +# modification time. If at least one parameter is provided, all parameters +# shall be considered as pathnames to be compared to one another. Otherwise, +# the pathnames to be compared shall be read from the standard input as +# null-terminated records. In the case that two or more pathnames are +# candidates, whichever was first specified shall take precedence over the +# other. If no pathnames are given, or those specified do not exist, the return +# value shall be greater than 0. +# +# Pathnames containing characters shall be handled correctly if +# conveyed as positional parameters. Otherwise, the behaviour for such +# pathnames is unspecified. Users of the function are duly expected to refrain +# from conveying such pathnames for consumption from the standard input; for +# example, by specifying a predicate of ! -path $'*\n*' to the find utility. +# This constraint is expected to be eliminated by a future amendment to the +# function, once support for read -d becomes sufficiently widespread. +# +# The test utility is required to support the -nt primary, per POSIX-1.2024. +# However, measures are in place to to achieve compatibility with shells that +# implement the primary without yet fully adhering to the specification. # newest() { - _select_by_mtime -r "$@" + local path newest + + newest= + if [ "$#" -gt 0 ]; then +
[gentoo-commits] proj/gentoo-functions:master commit in: /, functions/
commit: 8f708ef54a07f200b308f82fd64c2c87f5e89b11 Author: Kerin Millar plushkava net> AuthorDate: Sat Aug 10 06:57:17 2024 + Commit: Sam James gentoo org> CommitDate: Sun Aug 11 10:11:05 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=8f708ef5 Remedy false positives in categories SC2034 and SC2154 Signed-off-by: Kerin Millar plushkava.net> Signed-off-by: Sam James gentoo.org> functions.sh | 5 - functions/experimental.sh | 1 + functions/rc.sh | 8 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/functions.sh b/functions.sh index eff7f5f..38eef62 100644 --- a/functions.sh +++ b/functions.sh @@ -958,11 +958,6 @@ if [ ! "${genfun_basedir+set}" ]; then genfun_basedir=${genfun_prefix}/lib/gentoo fi -# Assign the LF ('\n') character for later expansion. POSIX-1.2024 permits $'\n' -# but it may take years for it to be commonly implemented. -genfun_newline=' -' - # The GENFUN_MODULES variable acts as a means of selecting modules, which are # merely optional collections of functions. If unset then set it now. if [ ! "${GENFUN_MODULES+set}" ]; then diff --git a/functions/experimental.sh b/functions/experimental.sh index 0ca9904..7c2fb25 100644 --- a/functions/experimental.sh +++ b/functions/experimental.sh @@ -168,6 +168,7 @@ str_between() else set -- "$2" "$1" "$3" i=0 + # shellcheck disable=2034 printf '%s\n' "$@" | sort | while IFS= read -r line; do diff --git a/functions/rc.sh b/functions/rc.sh index 4eff3c8..101b99e 100644 --- a/functions/rc.sh +++ b/functions/rc.sh @@ -347,6 +347,7 @@ _eend() "${efunc}" "${msg}" fi # Generate an indicator for ebegin's unsuccessful conclusion. + # shellcheck disable=2154 if _update_tty_level <&1; [ "${genfun_tty}" -eq 0 ]; then msg="[ !! ]" else @@ -356,6 +357,7 @@ _eend() return "${retval}" else # Generate an indicator for ebegin's successful conclusion. + # shellcheck disable=2154 if _update_tty_level <&1; [ "${genfun_tty}" -eq 0 ]; then msg="[ ok ]" else @@ -367,6 +369,7 @@ _eend() # Save the cursor position with DECSC, move it up by one line # with CUU, position it horizontally with CHA, print the # indicator, then restore the cursor position with DECRC. + # shellcheck disable=2154 col=$(( genfun_cols > 6 ? genfun_cols - 6 : 1 )) printf '\0337\033[1A\033[%dG %s\0338' "$(( col + genfun_offset ))" "${msg}" else @@ -484,5 +487,10 @@ else genfun_offset=0 fi +# Assign the LF ('\n') character for later expansion. POSIX-1.2024 permits $'\n' +# but it may take years for it to be commonly implemented. +genfun_newline=' +' + # shellcheck disable=2034 RC_GOT_FUNCTIONS=yes
[gentoo-commits] proj/gentoo-functions:master commit in: functions/, /
commit: 5a34ca0e2001d70bc2037fc2226ad510e26a3349 Author: Kerin Millar plushkava net> AuthorDate: Thu Aug 8 01:27:52 2024 + Commit: Sam James gentoo org> CommitDate: Sun Aug 11 10:10:58 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=5a34ca0e Avoid unspecified behaviour around simple commands in general As mentioned by the previous commit, the Shell Command Language leaves it unspecified as to whether variable assignments affecting the execution environment of a simple command charged with executing a function (that is not the implementation of a standard utility) shall persist after the completion of the function. It transpires that modifying gentoo-functions so as to steer clear of this pitfall isn't particularly difficult so this commit does exactly that. Most of the changes are in test-functions but functions/rc.sh also required some minor changes regarding the use of the GENFUN_CALLER variable. With this, loksh very nearly passes the test suite. There is one individual test that continues to fail, although it looks as though that may be caused by a genuine bug on the part of the shell. That will require investigating in its own right. Signed-off-by: Kerin Millar plushkava.net> Signed-off-by: Sam James gentoo.org> functions/rc.sh | 16 +++- test-functions | 43 --- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/functions/rc.sh b/functions/rc.sh index 12444d1..0c14035 100644 --- a/functions/rc.sh +++ b/functions/rc.sh @@ -49,7 +49,8 @@ ebegin() # eend() { - GENFUN_CALLER=${GENFUN_CALLER:-eend} _eend eerror "$@" + : "${genfun_caller:=eend}" + _eend eerror "$@" } # @@ -161,7 +162,8 @@ ewarnn() # ewend() { - GENFUN_CALLER=${GENFUN_CALLER:-ewend} _eend ewarn "$@" + : "${genfun_caller:=ewend}" + _eend ewarn "$@" } # @@ -240,7 +242,8 @@ done veend() { if yesno "${EINFO_VERBOSE}"; then - GENFUN_CALLER=veend eend "$@" + genfun_caller=veend + eend "$@" elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then _warn_for_args veend "$1" false @@ -252,7 +255,8 @@ veend() vewend() { if yesno "${EINFO_VERBOSE}"; then - GENFUN_CALLER=vewend ewend "$@" + genfun_caller=vewend + ewend "$@" elif [ "$#" -gt 0 ] && { ! is_int "$1" || [ "$1" -lt 0 ]; }; then _warn_for_args vewend "$1" false @@ -311,7 +315,7 @@ _eend() if [ "$#" -eq 0 ]; then retval=0 elif ! is_int "$1" || [ "$1" -lt 0 ]; then - _warn_for_args "${GENFUN_CALLER}" "$1" + _warn_for_args "${genfun_caller}" "$1" retval=1 msg= else @@ -320,6 +324,8 @@ _eend() msg=$* fi + genfun_caller= + if [ "${retval}" -ne 0 ]; then # If a message was given, print it with the specified function. if _is_visible "${msg}"; then diff --git a/test-functions b/test-functions index afc56eb..0b0e127 100755 --- a/test-functions +++ b/test-functions @@ -46,19 +46,6 @@ test_local() { return "${retval}" } -test_simple_command() { - f() { :; } - LEAKED= - LEAKED=1 f - retval=0 - if [ "${LEAKED}" ]; then - printf 'not ' - retval=1 - fi - printf "ok %d - /bin/sh refrains from leaking environmental changes for simple commands\\n" "$((testnum += 1))" - return "${retval}" -} - test_chdir() { set -- \ ge 1 '' \ @@ -76,13 +63,17 @@ test_chdir() { fi callback() { + local CDPATH var + shift test_description="chdir $(quote_args "$@")" if [ "$BASH" ]; then # shellcheck disable=3044 shopt -s cdable_vars fi - CDPATH=child var=child chdir "$@" \ + CDPATH=child + var=child + chdir "$@" \ && test "$PWD" != "$OLDPWD" \ && cd - >/dev/null } @@ -266,7 +257,7 @@ test_esyslog() { should_log=$2 shift 2 test_description="esyslog $(quote_args "$@")" - logged=$(EINFO_LOG=1 esyslog "$@") + logged=$(EINFO_LOG=1; esyslog "$@") case $? in 0) test "${logged:-0}" -eq "${should_log}" @@ -680,10 +671,22 @@ test_whenceforth() { whenceforth "$@" >/dev/null else test_description="PATH=${path} whenceforth $(quote_args "$@")" - PATH=${path} whenceforth "$@" >/dev/null + ( +
[gentoo-commits] proj/gentoo-functions:master commit in: functions/
commit: fed96ec1da2fad4070a02803ceef4a322a87eb4f Author: Kerin Millar plushkava net> AuthorDate: Sun Aug 4 23:48:04 2024 + Commit: Sam James gentoo org> CommitDate: Sun Aug 4 23:53:22 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=fed96ec1 Do not yet deprecate RC_NOCOLOR It would be sensible to conduct a survey to determine whether - and where - it is being used beforehand. Signed-off-by: Kerin Millar plushkava.net> functions/rc.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/functions/rc.sh b/functions/rc.sh index 9b1fc5d..12444d1 100644 --- a/functions/rc.sh +++ b/functions/rc.sh @@ -426,9 +426,7 @@ _is_visible() #--# # Determine whether the use of color is to be wilfully avoided. -if [ "${RC_NOCOLOR+set}" ]; then - warn "the RC_NOCOLOR variable is deprecated by gentoo-functions; please set NO_COLOR instead" -elif [ -n "${NO_COLOR}" ]; then +if [ "${NO_COLOR}" ]; then # See https://no-color.org/. RC_NOCOLOR=yes else
[gentoo-commits] proj/gentoo-functions:master commit in: functions/
commit: d6e689bc832e4b033f4af9cb6746a99649ecc8d8 Author: Kerin Millar plushkava net> AuthorDate: Wed Jul 31 23:20:10 2024 + Commit: Sam James gentoo org> CommitDate: Wed Jul 31 23:36:10 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=d6e689bc Treat EINFO_LOG as false if equal to RC_SERVICE Consider the value of EINFO_LOG to be false in the event that it is equal to the value of RC_SERVICE. The reason for this is that, as of the time of writing, openrc-run(8) defines and uses EINFO_LOG in a way that is at odds with gentoo-functions. Ideally, the behaviour of OpenRC would be modified so that it becomes possible to jettison this workaround. Fixes: 0dd8364c03c6f8737150ee4f146ddeeec57efee9 Bug: https://bugs.gentoo.org/936613 Signed-off-by: Kerin Millar plushkava.net> functions/rc.sh | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/functions/rc.sh b/functions/rc.sh index 9129b32..9b1fc5d 100644 --- a/functions/rc.sh +++ b/functions/rc.sh @@ -117,7 +117,11 @@ eoutdent() # # Invokes the logger(1) utility, provided that EINFO_LOG is true. The first # parameter shall be taken as a priority level, the second as the message tag, -# and the remaining parameters as the message to be logged. +# and the remaining parameters as the message to be logged. As a special case, +# the value of EINFO_LOG shall be treated as if were false in the event that it +# is equal to the value of RC_SERVICE. The reason for this is that, as of the +# time of writing, openrc-run(8) defines and uses EINFO_LOG in a way that is +# at odds with gentoo-functions. # esyslog() { @@ -126,7 +130,7 @@ esyslog() if [ "$#" -lt 2 ]; then warn "esyslog: too few arguments (got $#, expected at least 2)" return 1 - elif yesno "${EINFO_LOG}" && hash logger 2>/dev/null; then + elif [ "${EINFO_LOG}" != "${RC_SERVICE}" ] && yesno "${EINFO_LOG}"; then pri=$1 tag=$2 shift 2 msg=$*
[gentoo-commits] proj/gentoo-functions:master commit in: /, functions/
commit: 2e8bbd04cb55163b3d18ab407ffd8be24bf82c6e Author: Kerin Millar plushkava net> AuthorDate: Fri Aug 2 14:31:54 2024 + Commit: Sam James gentoo org> CommitDate: Fri Aug 2 16:21:14 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2e8bbd04 Move is_subset() to experimental I'm not yet ready to commit to it being among the core functions for the inaugural API level. Signed-off-by: Kerin Millar plushkava.net> functions.sh | 40 functions/experimental.sh | 40 test-functions| 2 +- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/functions.sh b/functions.sh index a002e54..69b9bf5 100644 --- a/functions.sh +++ b/functions.sh @@ -246,46 +246,6 @@ is_anyof() false } -# -# Collects the intersection of the parameters up to - but not including - a -# sentinel value then determines whether the resulting set is a subset of the -# intersection of the remaining parameters. If the SENTINEL variable is set, it -# shall be taken as the value of the sentinel. Otherwise, the value of the -# sentinel shall be defined as . If the sentinel value -# is not encountered or if either set is empty then the return value shall be -# greater than 1. -# -is_subset() -{ - SENTINEL=${SENTINEL-'--'} awk -f - -- "$@" <<-'EOF' - BEGIN { - argc = ARGC - ARGC = 1 - for (i = 1; i < argc; i++) { - word = ARGV[i] - if (word == ENVIRON["SENTINEL"]) { - break - } else { - set1[word] - } - } - if (i == 1 || argc - i < 2) { - exit 1 - } - for (i++; i < argc; i++) { - word = ARGV[i] - set2[word] - } - for (word in set2) { - delete set1[word] - } - for (word in set1) { - exit 1 - } - } - EOF -} - # # Considers one or more pathnames and prints the one having the newest # modification time. If at least one parameter is provided, all parameters shall diff --git a/functions/experimental.sh b/functions/experimental.sh index bbbf0fa..0ca9904 100644 --- a/functions/experimental.sh +++ b/functions/experimental.sh @@ -82,6 +82,46 @@ is_interactive() test -t 0 && { true 3>&1; } 2>/dev/null } +# +# Collects the intersection of the parameters up to - but not including - a +# sentinel value then determines whether the resulting set is a subset of the +# intersection of the remaining parameters. If the SENTINEL variable is set, it +# shall be taken as the value of the sentinel. Otherwise, the value of the +# sentinel shall be defined as . If the sentinel value +# is not encountered or if either set is empty then the return value shall be +# greater than 1. +# +is_subset() +{ + SENTINEL=${SENTINEL-'--'} awk -f - -- "$@" <<-'EOF' + BEGIN { + argc = ARGC + ARGC = 1 + for (i = 1; i < argc; i++) { + word = ARGV[i] + if (word == ENVIRON["SENTINEL"]) { + break + } else { + set1[word] + } + } + if (i == 1 || argc - i < 2) { + exit 1 + } + for (i++; i < argc; i++) { + word = ARGV[i] + set2[word] + } + for (word in set2) { + delete set1[word] + } + for (word in set1) { + exit 1 + } + } + EOF +} + # # Continuously reads lines from the standard input, prepending each with a # timestamp before printing to the standard output. Timestamps shall be in the diff --git a/test-functions b/test-functions index 8070c8d..43b5320 100755 --- a/test-functions +++ b/test-functions @@ -909,7 +909,7 @@ else test_whenceforth || rc=1 test_parallel_run || rc=1 test_is_anyof || rc=1 - test_is_subset || rc=1 + #test_is_subset || rc=1 test_trueof_all || rc=1 test_trueof_any || rc=1 #test_substr || rc=1
[gentoo-commits] proj/gentoo-functions:master commit in: functions/, /
commit: 4e09cd6073e9f7906081231af7511bc74cd1d1bb Author: Kerin Millar plushkava net> AuthorDate: Mon Jul 8 05:24:32 2024 + Commit: Sam James gentoo org> CommitDate: Mon Jul 8 05:24:32 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=4e09cd60 Add the _find0() helper function The function is a simple wrapper around GNU find(1) which presumes the intent to use the -files0-from option to read NUL-delimited path names from the standard input. The benefit in having it is twofold. Firstly, the _select_by_mtime() and is_older_than() functions are thereby made a little easier to read. Secondly, the genfun_bin_find variable is now initialised lazily. Signed-off-by: Kerin Millar plushkava.net> functions.sh| 33 - functions/rc.sh | 2 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/functions.sh b/functions.sh index 82f59a3..dd4eef8 100644 --- a/functions.sh +++ b/functions.sh @@ -652,6 +652,33 @@ whenceforth() #--# +# +# See the definitions of _select_by_mtime() and is_older_than(). +# +_find0() +{ + # Store the name of the GNU find binary, which may be "gfind". + hash gfind 2>/dev/null && genfun_bin_find=gfind || genfun_bin_find=find + + _find0() + { + local opt + + case $1 in + -[HL]) + opt=$1 + shift + set -- "${opt}" -files0-from - "$@" + ;; + *) + set -- -files0-from - "$@" + esac + "${genfun_bin_find}" "$@" + } + + _find0 "$@" +} + # # Determines whether the terminal is a dumb one. # @@ -660,7 +687,6 @@ _has_dumb_terminal() ! case ${TERM} in *dumb*) false ;; esac } -# # # See the definitions of oldest() and newest(). # @@ -674,7 +700,7 @@ _select_by_mtime() { else cat fi \ - | "${genfun_bin_find}" -files0-from - -maxdepth 0 ! -path "*${genfun_newline}*" -printf '%T+ %p\n' \ + | _find0 -maxdepth 0 ! -path "*${genfun_newline}*" -printf '%T+ %p\n' \ | sort "${sort_opt}" \ | { IFS= read -r line && printf '%s\n' "${line#* }"; } } @@ -841,9 +867,6 @@ if [ ! "${genfun_basedir+set}" ]; then genfun_basedir=${genfun_prefix}/lib/gentoo fi -# Store the name of the GNU find binary. Some platforms may have it as "gfind". -hash gfind 2>/dev/null && genfun_bin_find=gfind || genfun_bin_find=find - # Assign the LF ('\n') character for later expansion. POSIX Issue 8 permits # $'\n' but it may take years for it to be commonly implemented. genfun_newline=' diff --git a/functions/rc.sh b/functions/rc.sh index 2f2dc52..9129b32 100644 --- a/functions/rc.sh +++ b/functions/rc.sh @@ -213,7 +213,7 @@ is_older_than() fi shift { test "$#" -gt 0 && printf '%s\0' "$@"; } \ - | "${genfun_bin_find}" -L -files0-from - ${ref:+-newermm} ${ref:+"${ref}"} -printf '\n' -quit \ + | _find0 -L ${ref:+-newermm} ${ref:+"${ref}"} -printf '\n' -quit \ | read -r _ }
[gentoo-commits] proj/gentoo-functions:master commit in: functions/
commit: b720081b68dfba3ed4ebacb4d7564977708bfa25 Author: Kerin Millar plushkava net> AuthorDate: Thu Jun 27 20:42:23 2024 + Commit: Sam James gentoo org> CommitDate: Fri Jun 28 17:39:33 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b720081b Add the int_between() and str_between() functions to experimental Signed-off-by: Kerin Millar plushkava.net> functions/experimental.sh | 42 ++ 1 file changed, 42 insertions(+) diff --git a/functions/experimental.sh b/functions/experimental.sh index e02923a..1aac078 100644 --- a/functions/experimental.sh +++ b/functions/experimental.sh @@ -12,6 +12,24 @@ warn "sourcing the experimental module from gentoo-functions; no stability guarantee is provided" +# +# Expects three parameters, all of which must be integers, and determines +# whether the first is numerically greater than or equal to the second, and +# numerically lower than or equal to the third. +# +int_between() +{ + if [ "$#" -lt 3 ]; then + warn "int_between: too few arguments (got $#, expected 3)" + false + elif ! is_int "$2" || ! is_int "$3"; then + _warn_for_args int_between "$@" + false + else + is_int "$1" && [ "$1" -ge "$2" ] && [ "$1" -le "$3" ] + fi +} + # # Returns 0 provided that two conditions hold. Firstly, that the standard input # is connected to a tty. Secondly, that the standard output has not been closed. @@ -52,6 +70,30 @@ prepend_ts() prepend_ts } +# +# Expects three parameters and determines whether the first is lexicographically +# greater than or equal to the second, and lexicographically lower than or equal +# to the third. The effective system collation shall affect the results, given +# the involvement of the sort(1) utility. +# +str_between() +{ + local i + + if [ "$#" -ne 3 ]; then + warn "str_between: wrong number of arguments (got $#, expected 3)" + false + else + set -- "$2" "$1" "$3" + i=0 + printf '%s\n' "$@" | + sort | + while IFS= read -r line; do + eval "[ \"\${line}\" = \"\$$(( i += 1 ))\" ]" || ! break + done + fi +} + # # Takes the first parameter as either a relative pathname or an integer # referring to a number of iterations. To be recognised as a pathname, the first
[gentoo-commits] proj/gentoo-functions:master commit in: functions/
commit: 9dc4a6c4a383b1214babe14b4b7091ad56840486 Author: Kerin Millar plushkava net> AuthorDate: Thu Jun 27 20:36:10 2024 + Commit: Sam James gentoo org> CommitDate: Fri Jun 28 17:39:27 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=9dc4a6c4 Add the up() function to experimental As based on the implementation in Maarten Billemont's bashlib library. Signed-off-by: Kerin Millar plushkava.net> functions/experimental.sh | 28 1 file changed, 28 insertions(+) diff --git a/functions/experimental.sh b/functions/experimental.sh index f577fa7..e02923a 100644 --- a/functions/experimental.sh +++ b/functions/experimental.sh @@ -51,3 +51,31 @@ prepend_ts() prepend_ts } + +# +# Takes the first parameter as either a relative pathname or an integer +# referring to a number of iterations. To be recognised as a pathname, the first +# four characters must form the special prefix, ".../". It recurses upwards from +# the current directory until either the relative pathname is found to exist, +# the specified number of iterations has occurred, or the root directory is +# encountered. In the event that the root directory is reached without either of +# the first two conditions being satisfied, the return value shall be 1. +# Otherwise, the value of PWD shall be printed to the standard output. +# +up() +{ + local i + + i=0 + while [ "${PWD}" != / ]; do + chdir ../ + case $1 in + .../*) + test -e "${1#.../}" + ;; + *) + test "$(( i += 1 ))" -eq "$1" + esac \ + && pwd && return + done +}
[gentoo-commits] proj/gentoo-functions:master commit in: /, functions/
commit: 23ce043cfccf6b39caf790464c18f2df1d5b7d1b Author: Kerin Millar plushkava net> AuthorDate: Mon Jul 1 02:29:27 2024 + Commit: Sam James gentoo org> CommitDate: Mon Jul 1 02:32:27 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=23ce043c Move fetch() to experimental I'm not yet ready to commit to it being among the core functions for the inaugural API level. Signed-off-by: Kerin Millar plushkava.net> functions.sh | 42 -- functions/experimental.sh | 42 ++ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/functions.sh b/functions.sh index a4fa946..cfaddc3 100644 --- a/functions.sh +++ b/functions.sh @@ -138,48 +138,6 @@ contains_any() return "${retval}" } -# -# Considers the first parameter as an URL then attempts to fetch it with either -# curl(1) or wget(1). If the URL does not contain a scheme then the https:// -# scheme shall be presumed. Both utilities shall be invoked in a manner that -# suppresses all output unless an error occurs, and whereby HTTP redirections -# are honoured. Upon success, the body of the response shall be printed to the -# standard output. Otherwise, the return value shall be greater than 0. -# -fetch() -{ - if hash curl 2>/dev/null; then - fetch() - { - if [ "$#" -gt 0 ]; then - # Discard any extraneous parameters. - set -- "$1" - fi - curl -f -sS -L --connect-timeout 10 --proto-default https -- "$@" - } - elif hash wget 2>/dev/null; then - fetch() - { - if [ "$#" -gt 0 ]; then - # Discard any extraneous parameters. - case $1 in - ''|ftp://*|ftps://*|https://*) - set -- "$1" - ;; - *) - set -- "https://$1"; - esac - fi - wget -nv -O - --connect-timeout 10 -- "$@" - } - else - warn "fetch: this function requires that curl or wget be installed" - return 127 - fi - - fetch "$@" -} - # # Determines whether the current shell is a subprocess of portage. # diff --git a/functions/experimental.sh b/functions/experimental.sh index 4d56cfa..bbbf0fa 100644 --- a/functions/experimental.sh +++ b/functions/experimental.sh @@ -12,6 +12,48 @@ warn "sourcing the experimental module from gentoo-functions; no stability guarantee is provided" +# +# Considers the first parameter as an URL then attempts to fetch it with either +# curl(1) or wget(1). If the URL does not contain a scheme then the https:// +# scheme shall be presumed. Both utilities shall be invoked in a manner that +# suppresses all output unless an error occurs, and whereby HTTP redirections +# are honoured. Upon success, the body of the response shall be printed to the +# standard output. Otherwise, the return value shall be greater than 0. +# +fetch() +{ + if hash curl 2>/dev/null; then + fetch() + { + if [ "$#" -gt 0 ]; then + # Discard any extraneous parameters. + set -- "$1" + fi + curl -f -sS -L --connect-timeout 10 --proto-default https -- "$@" + } + elif hash wget 2>/dev/null; then + fetch() + { + if [ "$#" -gt 0 ]; then + # Discard any extraneous parameters. + case $1 in + ''|ftp://*|ftps://*|https://*) + set -- "$1" + ;; + *) + set -- "https://$1"; + esac + fi + wget -nv -O - --connect-timeout 10 -- "$@" + } + else + warn "fetch: this function requires that curl or wget be installed" + return 127 + fi + + fetch "$@" +} + # # Expects three parameters, all of which must be integers, and determines # whether the first is numerically greater than or equal to the second, and
[gentoo-commits] proj/gentoo-functions:master commit in: /, functions/
commit: feaa7438ef8c749179bf5fb99f93a3683e6d40fd Author: Kerin Millar plushkava net> AuthorDate: Sun Jun 30 23:15:36 2024 + Commit: Sam James gentoo org> CommitDate: Mon Jul 1 02:31:58 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=feaa7438 Move substr() to experimental Though it works very well, I'm not yet ready to commit to it being among the core functions for the inaugural API level. Signed-off-by: Kerin Millar plushkava.net> functions.sh | 41 - functions/experimental.sh | 41 + test-functions| 2 +- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/functions.sh b/functions.sh index 087b62d..1926c40 100644 --- a/functions.sh +++ b/functions.sh @@ -436,47 +436,6 @@ srandom() srandom } -# -# Takes the first parameter as a string (s), the second parameter as a numerical -# position (m) and, optionally, the third parameter as a numerical length (n). -# It shall then print a terminated substring of s that is at most, n -# characters in length and which begins at position m, numbering from 1. If n is -# omitted, or if n specifies more characters than are left in the string, the -# length of the substring shall be limited by the length of s. The function -# shall return 0 provided that none of the parameters are invalid. -# -substr() -{ - local i str - - if [ "$#" -lt 2 ]; then - warn "substr: too few arguments (got $#, expected at least 2)" - return 1 - elif ! is_int "$2"; then - _warn_for_args substr "$2" - return 1 - elif [ "$#" -ge 3 ]; then - if ! is_int "$3"; then - _warn_for_args substr "$3" - return 1 - elif [ "$3" -lt 0 ]; then - set -- "$1" "$2" 0 - fi - fi - str=$1 - i=0 - while [ "$(( i += 1 ))" -lt "$2" ]; do - str=${str#?} - done - i=0 - while [ "${#str}" -gt "${3-${#str}}" ]; do - str=${str%?} - done - if [ "${#str}" -gt 0 ]; then - printf '%s\n' "${str}" - fi -} - # # Trims leading and trailing whitespace from one or more lines. If at least one # parameter is provided, each positional parameter shall be considered as a line diff --git a/functions/experimental.sh b/functions/experimental.sh index 1aac078..4d56cfa 100644 --- a/functions/experimental.sh +++ b/functions/experimental.sh @@ -94,6 +94,47 @@ str_between() fi } +# +# Takes the first parameter as a string (s), the second parameter as a numerical +# position (m) and, optionally, the third parameter as a numerical length (n). +# It shall then print a terminated substring of s that is at most, n +# characters in length and which begins at position m, numbering from 1. If n is +# omitted, or if n specifies more characters than are left in the string, the +# length of the substring shall be limited by the length of s. The function +# shall return 0 provided that none of the parameters are invalid. +# +substr() +{ + local i str + + if [ "$#" -lt 2 ]; then + warn "substr: too few arguments (got $#, expected at least 2)" + return 1 + elif ! is_int "$2"; then + _warn_for_args substr "$2" + return 1 + elif [ "$#" -ge 3 ]; then + if ! is_int "$3"; then + _warn_for_args substr "$3" + return 1 + elif [ "$3" -lt 0 ]; then + set -- "$1" "$2" 0 + fi + fi + str=$1 + i=0 + while [ "$(( i += 1 ))" -lt "$2" ]; do + str=${str#?} + done + i=0 + while [ "${#str}" -gt "${3-${#str}}" ]; do + str=${str%?} + done + if [ "${#str}" -gt 0 ]; then + printf '%s\n' "${str}" + fi +} + # # Takes the first parameter as either a relative pathname or an integer # referring to a number of iterations. To be recognised as a pathname, the first diff --git a/test-functions b/test-functions index 68e73eb..34ff54a 100755 --- a/test-functions +++ b/test-functions @@ -793,7 +793,7 @@ test_is_anyof || rc=1 test_is_subset || rc=1 test_trueof_all || rc=1 test_trueof_any || rc=1 -test_substr || rc=1 +#test_substr || rc=1 cleanup_tmpdir
[gentoo-commits] proj/gentoo-functions:master commit in: functions/
commit: fd79ab30122474ab5207ea001d92ffac677b5380 Author: Kerin Millar plushkava net> AuthorDate: Thu Jun 27 16:06:38 2024 + Commit: Sam James gentoo org> CommitDate: Fri Jun 28 17:39:01 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=fd79ab30 Add an experimental module for staging new ideas The idea is to be able to write new functions without having to initially commit to their being in the core library or, indeed, any of the other modules. Experimental functions may be promoted or simply dropped without warning if it is decided that they are insufficiently useful to merit incorporation. This initial commit defines the is_interactive() and prepend_ts() functions. Signed-off-by: Kerin Millar plushkava.net> functions/experimental.sh | 53 +++ 1 file changed, 53 insertions(+) diff --git a/functions/experimental.sh b/functions/experimental.sh new file mode 100644 index 000..f577fa7 --- /dev/null +++ b/functions/experimental.sh @@ -0,0 +1,53 @@ +# Copyright 2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 +# shellcheck shell=sh disable=3043 + +# This file contains functions considered experimental in nature. Any functions +# defined here may eventually be promoted to the core library or to a distinct +# module. They may also be dropped without warning, either because they were +# not considered as being sufficiently within the scope of gentoo-functions as +# a project or because they were deemed to be insufficiently useful. As such, it +# serves as a staging ground for new ideas. Note that GENFUN_API_LEVEL must +# never be incremented on account of any changes made to this module. + +warn "sourcing the experimental module from gentoo-functions; no stability guarantee is provided" + +# +# Returns 0 provided that two conditions hold. Firstly, that the standard input +# is connected to a tty. Secondly, that the standard output has not been closed. +# This technique is loosely based on the IO::Interactive::Tiny module from CPAN. +# +is_interactive() +{ + test -t 0 && { true 3>&1; } 2>/dev/null +} + +# +# Continuously reads lines from the standard input, prepending each with a +# timestamp before printing to the standard output. Timestamps shall be in the +# format of "%FT%T%z", per strftime(3). Output buffering shall not be employed. +# +prepend_ts() +{ + if hash gawk 2>/dev/null; then + prepend_ts() + { + gawk '{ print strftime("%FT%T%z"), $0; fflush(); }' + } + elif hash ts 2>/dev/null; then + prepend_ts() + { + ts '%FT%T%z' + } + elif bash -c '(( BASH_VERSINFO >= 4 ))' 2>/dev/null; then + prepend_ts() + { + bash -c 'while read -r; do printf "%(%FT%T%z)T %s\n" -1 "${REPLY}"; done' + } + else + warn "prepend_ts: this function requires that either bash, gawk or moreutils be installed" + return 1 + fi + + prepend_ts +}
[gentoo-commits] proj/gentoo-functions:master commit in: functions/, /
commit: 2a58c0e462538b7fb2d12cd95157a9aaf2b7f7ff Author: Kerin Millar plushkava net> AuthorDate: Wed Jun 12 12:16:37 2024 + Commit: Sam James gentoo org> CommitDate: Sun Jun 23 21:18:36 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2a58c0e4 Render gentoo-functions modular in nature For many years, the implied purpose of gentoo-functions has been to provided parallel implementations of utilities provided by OpenRC, along with a handful of peripheral functions. It is probably also fair to say that it has not seen much in the way of maintenance until comparatively recently. As of the present day, the status quo is not ideal. For one thing, the library has never been particularly useful beyond this definition. It is my hope that some of the recently added functions will be well received by those needing to write effective shell scripts in Gentoo for a number of relevant tasks. Certainly, there remains ample room for improvement in that regard. For another thing, the implementation of gentoo-functions is presently inflexible. For instance, it is impossible to source the functions from an OpenRC runscript without overriding the OpenRC implementations. Nor may one source the functions from an ebuild or eclass without overriding the Portage implementations. Indeed, it is has become something of a mess. Not only does gentoo-functions implement a number of functions that shadow the OpenRC implementations but so does Portage, owing to the existence of its "isolated-functions.sh" unit. What's more, the various implementations are of varying quality and do not necessarily behave in the same manner. This commit aims to address some of these issues by rendering gentoo-functions modular in nature. It establishes the premise of having a core library, with collections of additional functions being optionally declarable. As such, all of the functions that shadow OpenRC have been relocated to a unit named "rc.sh". This first change encompasses the following public functions: - ebegin - eend - eerrorn - eindent - einfon - eoutdent - esyslog - ewarnn - ewend - get_bootparam - is_older_than - veend - vewend - yesno Similarly, all of the functions that exclusively shadow Portage have been relocated to a unit named "portage.sh". This second change encompasses the following public functions: - die - edo - eqatag - eqawarn The functions that remain in the "functions.sh" unit may now be considered as core functions. To accommodate all of this, a new GENFUN_MODULES variable is supported, whose behaviour is described herewith. If GENFUN_MODULES is found to be set at the time of "functions.sh" being sourced, it shall be taken as a list of zero or more blank-separated words. In turn, these words shall be taken as the basenames of potentially available modules - not including the .sh suffix. Presently, the only supported module names are "rc" and "portage". Should either or both of these names be present, their respective units shall be automatically sourced. If neither are present, no additional units shall be sourced. Consequently, it becomes possible for a consumer of gentoo-functions to request that only the core functions be declared by writing: GENFUN_MODULES= . /lib/gentoo/functions.sh If, on the other hand, GENFUN_MODULES is found not to be set then heuristics shall be employed to determine which of the additional units should be sourced. The intent of these heuristics is twofold. Firstly, to maintain an adequate degree of backward-compatibility and, secondly, to act as is appropriate based on the characteristics of the operating environment. The exact behaviour of these heuristics is as follows. If the present shell is neither executing a runscript nor a subprocess of one, the ensuing behaviour shall be as if "rc" had initially been among the names defined by the GENFUN_MODULES variable. If the present shell is not a subprocess of portage, the ensuing behaviour shall be as if "portage" had initially been among the names defined by the GENFUN_MODULES variable. Signed-off-by: Kerin Millar plushkava.net> functions.sh | 633 ++- functions/portage.sh | 136 +++ functions/rc.sh | 462 + meson.build | 5 + test-functions | 6 +- 5 files changed, 683 insertions(+), 559 deletions(-) diff --git a/functions.sh b/functions.sh index 166f184..d80a49c 100644 --- a/functions.sh +++ b/functions.sh @@ -1,4 +1,4 @@ -# Copyright 1999-2023 Gentoo Authors +# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # shellcheck shell=sh disable=2209,3043 @@ -15,20 +15,16 @@ # BASH_VERSINFO: whether bash-specific features may be employed # BASHPID : may be used by _update_columns() to detect subshells # COLUMNS : may be used by _update_columns() to get the column count -# EERROR_
[gentoo-commits] proj/gentoo-functions:master commit in: functions/
commit: 94446b64cc9f9a912184a85fa43070fecbc4ce0f Author: Kerin Millar plushkava net> AuthorDate: Wed Jun 12 12:51:55 2024 + Commit: Sam James gentoo org> CommitDate: Sun Jun 23 21:19:15 2024 + URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=94446b64 Deprecate RC_NOCOLOR and the equivalent use of the positional parameters Firstly, the "." builtin is not specified to support the passing of arguments; such is a bashism. It is rather presumptuous to act as if the present contents of the positional parameters are for the benefit of gentoo-functions at the time of its initialisation. Secondly, there exists a de-facto standard for suppressing colored output, which is to define NO_COLOR as a non-empty string, per https://no-color.org. Signed-off-by: Kerin Millar plushkava.net> functions/rc.sh | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/functions/rc.sh b/functions/rc.sh index 519d847..2f2dc52 100644 --- a/functions/rc.sh +++ b/functions/rc.sh @@ -422,13 +422,16 @@ _is_visible() #--# # Determine whether the use of color is to be wilfully avoided. -if [ -n "${NO_COLOR}" ]; then +if [ "${RC_NOCOLOR+set}" ]; then + warn "the RC_NOCOLOR variable is deprecated by gentoo-functions; please set NO_COLOR instead" +elif [ -n "${NO_COLOR}" ]; then # See https://no-color.org/. RC_NOCOLOR=yes else for _; do case $_ in --nocolor|--nocolour|-C) + warn "the $_ option is deprecated by gentoo-functions; please set NO_COLOR=1 instead" RC_NOCOLOR=yes break esac