summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* Correct the implementation of contains_all()Kerin Millar2024-07-081-32/+94
| | | | | | | It was not translating IFS to FS correctly. Have it do so and extend the test suite accordingly. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the contains_all() and contains_any() functionsKerin Millar2024-07-011-0/+80
| | | | | | | | | | | | | | | | | | Here are some examples which presume the default value of IFS. contains_all " cat mat " cat dog # returns 1 contains_all " cat mat " mat cat # returns 0 contains_any " cat mat " cat dog # returns 0 contains_any " cat mat " dog # returns 1 Here are some examples showing that IFS is taken into account. IFS=, contains_all "cat,mat" cat dog # returns 1 IFS=, contains_all "cat,mat" mat cat # returns 0 IFS=, contains_any "cat,mat" cat dog # returns 0 IFS=, contains_any "cat,mat" dog # returns 1 Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Move substr() to experimentalKerin Millar2024-07-011-1/+1
| | | | | | | 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 <kfm@plushkava.net>
* Have whenceforce() require the -x option to check the execute bitKerin Millar2024-06-281-20/+37
| | | | | | | | This renders the behaviour of whenceforth() almost equivalent to type -P in the absence of the -x option, the exception being that whenceforth() never consults the hash table. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the substr() functionKerin Millar2024-06-281-0/+39
| | | | | | | POSIX sh does not support substring expansion so it may come in handy. The implementation is based on the awk function of the same name. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the trueof_all() and trueof_any() functionsKerin Millar2024-06-251-0/+44
| | | | | | | | | | | | | | These functions allow for it to be determined whether an arbitrary simple command yields true for either all of an arbitrary list of parameters or at least one of them. The simple command shall be given each parameter, one at a time. Some examples are shown below. trueof_all test -d -- / /var/empty # returns 0 trueof_all test -d -- / /dev/null # returns 1 trueof_any test -d -- / /dev/null # returns 0 trueof_any test -d -- /etc/fstab /dev/null # returns 1 Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Render gentoo-functions modular in natureKerin Millar2024-06-231-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 <kfm@plushkava.net>
* Add the is_anyof() and is_subset() functionsKerin Millar2024-06-141-0/+49
| | | | | | | | | | | | Examples follow. is_anyof y x y z # returns 0 is_anoyf y x w z # returns 1 is_subset x y -- x y z # returns 0 is_subset x y z -- z y x # returns 0 is_subset x y -- x w z # returns 1 Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Promote _print_args() to the public function, quote_args()Kerin Millar2024-06-121-14/+14
| | | | Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the parallel_run() functionKerin Millar2024-06-121-1/+20
| | | | | | | | | | | | | | Here is an example of how to use it. $ parallel_run 0 sha256sum dir/* Simple commands of a greater level of sophistication can easily be composed with the aid of functions. $ sm3sum() { cksum -a sm3 "$@"; } $ parallel_run 0 sm3sum dir/* Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the get_nprocs() functionKerin Millar2024-06-121-0/+12
| | | | | | | It stands a good chance of printing a useful value, even in the case that nproc(1) from coreutils is unavailable. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the whenceforth() function as a type -P alternativeKerin Millar2024-06-121-0/+39
| | | | | | | It acts much as type -P does in bash. I would have liked to name it whence but ksh and zsh already have builtins by that name. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the hr() function to print a horizontal ruleKerin Millar2024-06-121-0/+24
| | | | | | As based on the implementation in Maarten Billemont's bashlib library. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the trim() functionKerin Millar2024-06-121-0/+29
| | | | | | As based on the implementation in Maarten Billemont's bashlib library. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the oldest() and newest() functionsKerin Millar2024-06-121-0/+39
| | | | | | | | | | | | | | | | | | It compares potentially existing pathnames, printing the oldest and newest among them by modification time, respectively. $ . /lib/gentoo/functions.sh $ newest /etc/* /etc/environment.d $ printf '%s\0' /etc/* | newest /etc/environment.d Support for pathnames containing <newline> characters may be added once read -d becomes broadly supported. https://austingroupbugs.net/view.php?id=245 Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add the srandom() functionKerin Millar2024-06-121-0/+22
| | | | | | | | | | | This is based on the behaviour of the special SRANDOM variable in bash. It should be noted that sh is capable of bitwise arithmetic. For instance, it is possible to clamp the number in such a way that it does not exceed the minimum possible value of RAND_MAX (32767). n=$(srandom) && : $(( n >>= 17 )) Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Clean up the indentationKerin Millar2024-06-111-26/+26
| | | | Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Remove an unused variableKerin Millar2024-06-111-1/+0
| | | | Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Relax parameter validation for various functionsKerin Millar2024-06-111-11/+2
| | | | | | | | | | | | | | | | | | | Following some deliberation over the matter, I have concluded that calling die() for the handling of invalid parameters ought not to be considered as a matter of course. As such, this commit retains the existing diagnostics for the functions listed below, while modifying them so as to no longer attempt to exit the shell. - eend - eqatag - esyslog - ewend - is_older than - veend - vewend - yesno Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Minor ebegin() test refactoringKerin Millar2024-05-211-3/+3
| | | | Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Render tests somewhat fast againKerin Millar2024-05-211-4/+13
| | | | | | | Do so by having the tests for is_older_than() and yesno() employ subshells only where necessary. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Render argument checking more stringent; standardise diagnosticsKerin Millar2024-05-201-6/+5
| | | | | | | | | | | | | | | | | | | | | | | Have esyslog(), is_older_than(), veend(), vewend() and yesno() die for invalid arguments rather than issue a warning. Have yesno() die if given no arguments, just as several other functions already do. Introduce a helper function named _throw_invalid_args() to assist. It calls upon _print_args() to safely display any offending argument(s) while also helping to standardise the diagnostics. To that end, the diagnostic messages concerning wrong argument counts have been adjusted to follow suit. Below are some examples. test-functions: is_older_than: too few arguments (got 0, expected at least 2) test-functions: is_older_than: too few arguments (got 1, expected at least 2) test-functions: esyslog: too few arguments (got 0, expected at least 2) test-functions: esyslog: too few arguments (got 1, expected at least 2) test-functions: yesno: invalid argument: 'not-a-valid-nameref' test-functions: yesno: invalid argument: '_"; set -- yes # code injection' Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Include /opt/pkg/bin in PATHKerin Millar2024-05-201-1/+1
| | | | | | | This helps where testing on platforms having utilities that were installed by pkgsrc. In particular, gfind. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Actually remove print_args()Kerin Millar2024-05-191-17/+0
| | | | | | | This was supposed to be staged for the last commit that touched test-functions but was harmlessly omitted. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Separate some edo() code into a _print_args() helper functionKerin Millar2024-05-181-9/+9
| | | | | | | | Further, make test-functions use _print_args() and jettison the inferior print_args() function that it was previously using. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Fix spurious edo() test failuresKerin Millar2024-05-181-5/+7
| | | | | | | | | | | | Portage amends PATH in such a way that "ebuild-helper" utilities can be found. One of those is a die utility. What purpose that can serve is presently unclear to me. In any case, it was impeding the declaration of the die() function provided by gentoo-functions. Address it by setting PATH to a sane, generic value prior to sourcing the functions for testing. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Fix invalid TAP outputKerin Millar2024-05-181-1/+1
| | | | | | | | | Quite rightly, meson complains about the output of the edo tests constituting invalid TAP. Since only the exit status matters, mute STDOUT for these particular tests. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* Add an edo() functionKerin Millar2024-05-181-0/+15
| | | | | | | Its implementation is similar to that of the edo eclass. Signed-off-by: Kerin Millar <kfm@plushkava.net> Bug: https://bugs.gentoo.org/878505
* test-functions: Use test rather than [ to placate shellcheckKerin Millar2024-05-181-2/+2
| | | | | | Also, fix an accidental - though ultimately harmless - case of SC2027. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Fix a spurious test failureKerin Millar2024-05-181-185/+188
| | | | | | | | | | | | | | | The second-to-last commit added a test case for the die() function but also made it so that the exit status of each test is always compared to the expected value with the -eq operator. This turns out be insufficiently inflexible. For example, cd may return 2 in bash but 1 in another shell. Address this by requiring for each operand slice defined by a callback function to begin with an operator name, and by having the iterate_tests() function use the operator at the time of invoking the test utility. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add a die() functionKerin Millar2024-05-171-14/+25
| | | | | | | | | | | | | | | | | | | For now, it will only be defined if no utility, function or alias already exists by that name. Like the exit builtin, it is able to preserve the value of $? but will never exit with a status of 0. For example, the following will preserve the exit status of failing_command. failing_command || die "gadzooks" Whereas the following will ignore the value of $? - being that it is 0 - and instead exit with a status of 1. if prevailing_command; then die "fiddlesticks" fi Signed-off-by: Kerin Millar <kfm@plushkava.net> Bug: https://bugs.gentoo.org/878505
* Simplify _eprint() and _eend() behaviour markedlyKerin Millar2024-05-141-34/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Following almost a year of usage and testing, I now consider my experiments in smart terminal handling to be both a success and a failure by equal measure. I deem them to be a successful in so far as the code functions as intended, and that there have been several positive reports from those intrepid enough to unmask gentoo-functions-1.0. However, I also deem them to be a failure in so far as there is a noticeable impact upon performance. In particular, repeated calls to ebegin() and eend() are handled rather slowly. As such, this commit greatly simplifies the code whilst retaining the most compelling traits of the work that has been performed. The exact changes are described herewith. The _eprint() function shall now only check whether STDOUT refers to a tty. In the event that it does, the message may be printed in a colourised fashion. Otherwise, it shall be printed plainly. No longer will the terminal be asked to remember the position of the cursor (using DECSC), nor shall any variables be used for the purpose of keeping state. The _eend() function shall no longer attempt to restore the prior position of the cursor (using DECRC), nor attempt to determine the present position of the cursor (using ecma48-cpr). Instead, the behaviour is reduced to that of checking whether STDOUT refers to a smart terminal. In the event that it does, the success/failure identifier shall always be printed on the preceding line, right-aligned. Otherwise, it shall be printed plainly on the present line. It remains the case that the terminal will be asked to report its dimensions, so that _eend() can adapt to any adjustments made to the width of the terminal emulator. As a consequence of these changes, the _update_cursor_coords() and _ecma48_cpr() functions are rendered obsolete and have been removed. Additionally, the "genfun_cols", "genfun_y" and "genfun_is_pending_lf" variables are rendered obsolete and have been removed. Finally, the _update_winsize() function has been renamed to _update_columns(). Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Add a test for the ebegin() functionKerin Millar2023-06-101-0/+20
| | | | | | | The test determines whether ebegin() appends at least one <newline> character to the message (following the ASCII ellipsis). Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Really fix non-conforming TAP outputKerin Millar2023-06-101-10/+11
| | | | | | | | | | | | | | | | | | | | | | The previous "fix" was an experimental patch that was not yet intended for inclusion. This supplemental commit does as little as is necessary to render the test suite properly functional under meson, given that meson.build has been configured to expect the use of the TAP protocol. It also configures meson to be verbose while executing the test suite. As far as I can gather, the TAP support in meson is weak. Subtests do not appear to be supported. For that reason, I have dropped the TAP version from 14 to 13. While meson recognises "# SKIP" as a directive, it does not report the reason that may follow the text. Another issue is that no controlling terminal is present under meson. Therefore, test_update_cursor_coords() is rendered useless, for it will always be skipped. I have left the test in for the time being, in the hope that there may yet be a solution. In any case, this should be enough to render the -9999 ebuild both testable and usable. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Fix non-conforming TAP 14 outputKerin Millar2023-06-101-11/+18
| | | | | | | | Given that there are no subtests, it isn't permissible to duplicate any of the test numbers. Also, the test_update_cursor_coords() function was not correctly conveying the case where the test is skipped. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Address a slew of shellcheck warningsKerin Millar2023-06-091-8/+10
| | | | | | | | | False-positives galore. It's getting out of hand for test-functions, so I disabled several more tests in its global scope. It was correct to point out that "${PWD}" should be quoted, however. Bash doesn't mind but other sh implementations might. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Add a test for the _update_cursor_coords() functionKerin Millar2023-06-091-0/+22
| | | | Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Do not silence ewarn() while testing is_older_than()Kerin Millar2023-06-091-1/+1
| | | | | | | | I changed my mind about this. It's probable that more diagnostic messages will be added in the future and it may then be useful to observe them in the case that the test suite fails. Signed-off-by: Kerin Millar <kfm@plushkava.net>
* test-functions: Ensure that ecma48-cpr can be resolved during src_test()Kerin Millar2023-06-091-0/+8
| | | | | | | | The test phase is run prior to the install phase. Compensate for this by wrapping ecma48-cpr with a shim function and redeclaring said function where the value of EBUILD_PHASE is equal to "test". Signed-off-by: Kerin Millar <kfm@plushkava.net>
* Add a chdir() function to act as a safer alternative to the cd builtinKerin Millar2023-06-091-3/+60
| | | | | | | | | | | | | | | To run cd "$dir" is problematic because: 1) it may consider its operand as an option 2) it will search CDPATH for an operand not beginning with ./, ../ or / 3) it will switch to OLDPWD if the operand is - 4) cdable_vars causes bash to treat the operand as a potential varname This commit introduces a chdir() function that addresses all of these pitfalls. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Add a test for the _is_visible() functionKerin Millar2023-06-071-0/+21
| | | | | Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Silence ewarn() while testing is_older_than()Kerin Millar2023-06-071-1/+1
| | | | | | | | | The is_older_than() function now calls ewarn() if given invalid arguments. For the purposes of the test suite, the resulting diagnostic messages aren't particularly interesting. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Add a test for the is_identifier() functionKerin Millar2023-06-071-0/+56
| | | | | Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Also test is_older_than with just one argumentKerin Millar2023-02-141-0/+4
| | | | | Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Add a test for the yesno() functionKerin Millar2023-02-121-0/+39
| | | | | Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Add a test for the is_int() functionKerin Millar2023-02-101-5/+33
| | | | Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Add a test for the esyslog() functionKerin Millar2023-02-091-37/+83
| | | | | | | | | | | | | | | | | In order to facilitate the appropriate tests, the test suite was adjusted slightly. Now, iterate_tests() will compose the code to be evaluated for each test being conducted. Consequently, it is able to recognise "N/A" as a special word to indicate that no further parameters should be specified. In turn, that means that the callback() function no longer needs to assume responsibility for recognising said word and can instead work with the positional parameters it receives in a natural fashion. Further, a print_args() function has been added that is used to compose the test descriptions. Also, further clarify the runtime requirements in the opening comment. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Reduce the boilerplate required for new testsKerin Millar2023-02-081-26/+31
| | | | | | | | | | Test functions may now define a callback() function before calling iterate_tests() to iterate over the tests defined by the positional parameters. The callback() function is responsible for performing a single given test, and for setting the description variable. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* Mention that the busybox builtins work with the test scriptKerin Millar2023-02-081-1/+2
| | | | | | | | Busybox provides builtins for mktemp(1) and touch(1), both of which are now known to be compatible with the test suite. Mention so in a comment. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>
* test-functions: Don't imply that coreutils is requiredKerin Millar2023-02-081-4/+3
| | | | | | | | The runtime requirements are made clear by the opening comment, but there was still a reference to coreutils made in another comment. Remove the latter. Signed-off-by: Kerin Millar <kfm@plushkava.net> Signed-off-by: Sam James <sam@gentoo.org>