diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Makefile | 25 | ||||
l--------- | src/lib/blacklist.sh.3.ronn | 1 | ||||
-rw-r--r-- | src/lib/common.sh.3.ronn | 16 | ||||
-rw-r--r-- | src/lib/common.sh.top | 10 | ||||
-rw-r--r-- | src/lib/conf.sh | 49 | ||||
-rw-r--r-- | src/lib/conf.sh.3.ronn | 128 | ||||
-rwxr-xr-x | src/lib/libreblacklist | 12 | ||||
-rw-r--r-- | src/lib/libreblacklist.1.ronn | 23 | ||||
-rwxr-xr-x | src/lib/librelib | 39 | ||||
-rw-r--r-- | src/lib/librelib.1.ronn | 55 | ||||
-rw-r--r-- | src/lib/librelib.7.ronn | 50 | ||||
-rwxr-xr-x | src/lib/libremessages | 43 | ||||
-rw-r--r-- | src/lib/libremessages.1.ronn | 220 | ||||
l--------- | src/lib/messages.sh.3.ronn | 1 |
14 files changed, 612 insertions, 60 deletions
diff --git a/src/lib/Makefile b/src/lib/Makefile index 45fd330..495abb1 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -1,8 +1,10 @@ copy_files = common.sh.in -libexecs = $(filter-out librelib,$(wildcard libre*)) +libexecs = $(filter-out librelib,$(progs)) # include common.sh in libs explicitly, because it might not exist yet # when the wildcard is performed libs = $(sort $(wildcard *.sh) common.sh) + +pots = $(libs) include ../../common.mk # Build ############################################################## @@ -12,19 +14,24 @@ common.sh: %: %.in %.top Makefile @{ \ cat '$*.top' && \ echo && \ - sed -r -e '/encoding problem/d;/LANG=/d' -e 's/mesg=\$$(.)/mesg="$$(_ "$$\1")"/' '$*.in' && \ + sed -r \ + -e '/encoding problem/d;/LANG=/d' \ + -e 's/mesg=\$$(.)/mesg="$$(_ "$$\1")"/' \ + -e 's/gettext /_l _ /g' \ + -e "s/^(\s+)(msg|error) '/\1_l \2 '/" \ + -e 's|lock\(\)\s*\{|lock()\n{|' \ + '$*.in' && \ echo && \ cat '$*.bottom' && \ :; } > '$@' # Translate ########################################################## -pot: libreblacklist.pot common.sh.pot librelib.pot - libreblacklist.pot: libreblacklist { \ - sed -n '/^# Usage:/,/()/{ /^#/ { =; p; } }' $< | sed -r -e 's/^# (.*)/msgid "\1"/' -e 's/^[0-9]*$$/#. embedded usage text\n#: $<:&/'; \ - sed -rn '/print /{ =; s/\s*print "([^"]*)".*/msgid "\1"/p; }' $< | sed 's/^[0-9]*$$/#. print\n#: $<:&/' ; \ - } | sed 's/^msgid .*/&\nmsgstr ""\n/' > $@ -common.sh.pot: common.sh - xgettext --omit-header -i --from-code=UTF-8 -L shell -o $@ $< + sed -n '/^# Usage:/,/()/{ /^#/ { =; p; } }' $< | \ + sed -r -e 's/^# (.*)/msgid "\1"\nmsgstr ""\n/' \ + -e 's/^[0-9]*$$/#. embedded usage text\n#: $<:&/'; \ + $(xgettext-sh-prose); \ + $(xgettext-sh-std); \ + } | $(pofmt) > $@ diff --git a/src/lib/blacklist.sh.3.ronn b/src/lib/blacklist.sh.3.ronn new file mode 120000 index 0000000..9001445 --- /dev/null +++ b/src/lib/blacklist.sh.3.ronn @@ -0,0 +1 @@ +libreblacklist.1.ronn
\ No newline at end of file diff --git a/src/lib/common.sh.3.ronn b/src/lib/common.sh.3.ronn new file mode 100644 index 0000000..2ec113c --- /dev/null +++ b/src/lib/common.sh.3.ronn @@ -0,0 +1,16 @@ +common.sh -- common Bash routines from devtools +=============================================== + +## SYNPOSIS + +`. $(librelib common)` + +## DESCRIPTION + +In short, don't use this. Use `libremessages`(1) instead. +`libremessages` uses this internally. + +## SEE ALSO + + * librelib(7) + * libremessages(1)/messages.sh(3) diff --git a/src/lib/common.sh.top b/src/lib/common.sh.top index 054301b..9c4ba2e 100644 --- a/src/lib/common.sh.top +++ b/src/lib/common.sh.top @@ -13,14 +13,20 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. +shopt -s extglob + if [[ -z ${_INCLUDE_COMMON_SH:-} ]]; then _INCLUDE_COMMON_SH=true -export TEXTDOMAIN='libretools' -export TEXTDOMAINDIR='/usr/share/locale' +[[ -n ${TEXTDOMAIN:-} ]] || export TEXTDOMAIN='libretools' +[[ -n ${TEXTDOMAINDIR:-} ]] || export TEXTDOMAINDIR='/usr/share/locale' if type gettext &>/dev/null; then _() { gettext "$@"; } else _() { echo "$@"; } fi + +_l() { + TEXTDOMAIN='librelib' TEXTDOMAINDIR='/usr/share/locale' "$@" +} diff --git a/src/lib/conf.sh b/src/lib/conf.sh index f96af26..ee52f6f 100644 --- a/src/lib/conf.sh +++ b/src/lib/conf.sh @@ -1,7 +1,7 @@ #!/bin/bash # non-executable, but put this there as a hint to text editors # This may be included with or without `set -euE` -# Copyright (c) 2012-2013 by Luke Shumaker <lukeshu@sbcglobal.net> +# Copyright (C) 2012-2014 by Luke Shumaker <lukeshu@sbcglobal.net> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -29,7 +29,7 @@ if [[ -z ${XDG_CACHE_HOME:-} ]]; then export XDG_CACHE_HOME="${LIBREHOME}/.cache" fi -# Generic functions ############################################################ +# Low-level generic functions ################################################## # Usage: list_files $slug # Lists the configuration files to be considered for $slug. @@ -61,7 +61,7 @@ list_files() { } # Usage: list_envvars $slug -# Lists the environmental variables that take precidence over the configuration +# Lists the environmental variables that take precedence over the configuration # files for $slug. list_envvars() { local slug=$1 @@ -73,10 +73,16 @@ list_envvars() { PKGEXT SRCEXT \ GPGKEY PACKAGER ;; + libretools) + printf '%s\n' \ + DIFFPROG + ;; *) :;; esac } +# High-level generic functions ################################################# + # Usage: load_files $slug # Loads the configuration files for $slug in the proper order. load_files() { @@ -106,7 +112,7 @@ load_files() { # Check whether the variables listed are properly set. # If not, it prints a message saying to set them in the configuration file(s) # for $slug. -check_vars() { +check_vars() ( local slug=$1; shift local ret=0 @@ -116,10 +122,10 @@ check_vars() { if [[ -z ${!VAR:-} ]]; then type print &>/dev/null || . libremessages if [[ $(list_files $slug|wc -l) -gt 1 ]]; then - print "Configure '%s' in one of:" "$VAR" + _l print "Configure '%s' in one of:" "$VAR" list_files $slug | sed 's/./ -> &/' else - print "Configure '%s' in '%s'" "$VAR" "$(list_files $slug)" + _l print "Configure '%s' in '%s'" "$VAR" "$(list_files $slug)" fi ret=1 fi @@ -128,24 +134,27 @@ check_vars() { if [[ $ret != 0 ]]; then return 1 fi -} - -# makepkg configuration ######################################################## +) -# Usage: get_conf_makepkg <var_name> <default_value> -get_conf_makepkg() ( +# Usage: get_var <slug> <var_name> <default_value> +# Does not work with arrays +get_var() ( set +euE - local setting=$1 - local default=$2 - load_files makepkg - printf '%s\n' "${!setting:-${default}}" + local slug=$1 + local setting=$2 + local default=$3 + load_files "$slug" + printf '%s' "${!setting:-${default}}" ) -set_conf_makepkg() { - local key=$1 - local val=$2 +# Usage: set_var <slug> <var_name> <value> +# Does not work with arrays +set_var() { + local slug=$1 + local key=$2 + local val=$3 local file - for file in $(list_files makepkg|tac); do + for file in $(list_files "$slug"|tac); do if [[ -w $file ]]; then sed -i "/^\s*$key=/d" "$file" printf '%s=%q\n' "$key" "$val" >> "$file" @@ -185,6 +194,6 @@ unset_PKGBUILD() { load_PKGBUILD() { local file=${1:-./PKGBUILD} unset_PKGBUILD - CARCH="$(get_conf_makepkg CARCH "`uname -m`")" + CARCH="$(get_var makepkg CARCH "`uname -m`")" . "$file" } diff --git a/src/lib/conf.sh.3.ronn b/src/lib/conf.sh.3.ronn new file mode 100644 index 0000000..4108f9a --- /dev/null +++ b/src/lib/conf.sh.3.ronn @@ -0,0 +1,128 @@ +conf.sh(3) -- easy loading of configuration files +============================================== + +## SYNOPSIS + +`. $(librelib conf)` + +## DESCRIPTION + +`conf.sh` is a Bash(1) library to easily load various configuration +files related to Arch Linux/Parabola(7) and libretools(7). + +I recommend reading the source yourself--it is mostly +self-explanatory, and is shorter than this document. + +### VARIABLES + +When loading configuration files in a program run with `sudo`(8), it +is often desirable to load the configuration files from the home +directory of the user who called `sudo`, instead of from /root. + +To accommodate this, instead of using the usual $<USER> and $<HOME>, +`conf.sh` sets $<LIBREUSER> and $<LIBREHOME>, which it then uses. + + * <LIBREUSER>: + If $<SUDO_USER> is set, then $<LIBREUSER> is set to + that. Otherwise, $<LIBREUSER> is set to the value of $<USER>. + * <LIBREHOME>: + If $<LIBREUSER> == $<USER>, then $<LIBREHOME> is set to the value + of $<HOME>. Otherwise, it is set to the default home directory + of the user $<LIBREUSER>. + +Further, `conf.sh` works with XDG; it sets and uses +$<XDG_CONFIG_HOME> and $<XDG_CACHE_HOME> with the following values: + + * <XDG_CONFIG_HOME>: + If it isn't already set, it is set to "$<LIBREHOME>/.config" and + exported. + * <XDG_CACHE_HOME>: + If it isn't already set, it is set to "$<LIBREHOME>/.cache" and + exported. + +Note that only the XDG_* variables are exported. + +### GENERIC ROUTINES + +The following routines take a "slug" to refer to a group of +configuration files; that is the basename of the files. For example, +<SLUG>='abs' will identify `/etc/abs.conf` and `$<LIBREHOME>/.abs.conf`. + +The routines you will likely actually use are: + + * `load_files` <SLUG>: + Loads the configuration files for <SLUG>, loading the files in + the correct order, and checking the appropriate environmental + variables. + * `check_vars` <SLUG> <VARS>...: + Checks to see if all of <VARS> are defined. If any of them + aren't, it prints a message to configure them in the + configuration files for <SLUG>, and returns with a non-zero + status. + * `get_var` <SLUG> <VAR> <DEFAULT>: + If <VAR> is set in the configuration for <SLUG>, print it's + value, considering environmental variables. If it is not set, + return <DEFAULT>. This does NOT work for array variables. + * `set_var` <SLUG> <VAR> <VALUE>: + Set the variable <VAR> equal to <VALUE> in the configuration file + for <SLUG> of highest precedence that already exists, and is + writable. If no files fit this description, the routine does + nothing and returns a non-zero exit status. This does NOT work + for array variables. + +There are two more routines the above routines use internally that are +used internally by . You are unlikely to use them directly, but they +might be useful for debugging, or at least describing behavior. + + * `list_files` <SLUG>: + Lists (newline-separated) the configuration files that must be + considered for <SLUG>. Files listed later take precedence over + files listed earlier. + * `list_envvars` <SLUG>: + Lists (newline-separated) the environmental variables that take + precedence over the settings in the configuration files for + <SLUG>. For example, in `makepkg.conf`(8) (<SLUG>=makepkg), if the + <PACKAGER> environmental variable is set, the value in the + configuration file is ignored. + +### PKGBUILD ROUTINES + +These two routines deal with loading `PKGBUILD`(5) files. + + * `unset_PKGBUILD`: + Unsets all variables and functions that might be set in a + `PKGBUILD`(5) file, including those specific to `librefetch`(8). + * `load_PKGBUILD` [<FILE>]: + "Safely" loads a PKGBUILD. Everything that it would normally set + is unset first, $<CARCH> is set according to `makepkg.conf`(5), + then the file is loaded. The file to be loaded is <FILE>, or + "./PKGBUILD" by default. This isn't safe, security wise, in that + the PKGBUILD is free to execute code. + +### SLUGS + +The differences in behavior for anything that takes a slug comes down +to the differences in the output for `list_files` and `list_envvars`. + +The "known" slugs are "abs", "makepkg", and "libretools". If anything +else is given, then: + + * `list_files` will give back "/etc/libretools.d/<SLUG>.conf" and + "$<XDG_CONFIG_HOME>/libretools/<SLUG>.conf" + * `list_envvars` will give back an empty list. + +The rules for <SLUG>=(abs|makepkg|libretools) are more easily +expressed in code than prose, so it is recommended that you look at +that. + +## BUGS + +`get_var` and `set_var` do not work with arrays. + +## SEE ALSO + +librelib(7) + +abs.conf(5), makepkg.conf(5), libretools.conf(5), PKGBUILD(5) + +chroot.conf(5), librefetch.conf(5) diff --git a/src/lib/libreblacklist b/src/lib/libreblacklist index 5db1a3f..5525098 100755 --- a/src/lib/libreblacklist +++ b/src/lib/libreblacklist @@ -2,7 +2,7 @@ # This may be included with or without `set -euE` # When run directly, it does `set -euE` -# Copyright (c) 2013 by Luke Shumaker <lukeshu@sbcglobal.net> +# Copyright (C) 2013-2014 by Luke Shumaker <lukeshu@sbcglobal.net> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -48,7 +48,7 @@ blacklist-update() ( local remote_blacklist="$BLACKLIST" local local_blacklist="$XDG_CACHE_HOME/libretools/blacklist.txt" - stat_busy "Downloading blacklist of proprietary software packages" + _l stat_busy "Downloading blacklist of proprietary software packages" mkdir -p "${local_blacklist%/*}" if wget -N -q -O "${local_blacklist}.part" "$remote_blacklist" 2>/dev/null; then @@ -58,9 +58,9 @@ blacklist-update() ( stat_done rm "${local_blacklist}.part" if [[ -e "$local_blacklist" ]]; then - warning "Using local copy of blacklist" + _l warning "Using local copy of blacklist" else - error "Download failed, exiting" + _l error "Download failed, exiting" return 1 fi @@ -109,6 +109,8 @@ if [[ "${0##*/}" == libreblacklist ]]; then sed 's/\r/\n/g'<<<"$1"|sed -e '/^$/d' -e 's/^# //' } usage() { + export TEXTDOMAIN='librelib' + export TEXTDOMAINDIR='/usr/share/locale' . $(librelib messages) if [[ $# -eq 0 ]]; then print "Usage: %s [-h] COMMAND [ARGUMENTS]" "${0##*/}" @@ -135,7 +137,7 @@ if [[ "${0##*/}" == libreblacklist ]]; then } if [[ $# -eq 0 ]]; then - usage >/dev/stderr + usage >&2 exit 1 fi _blacklist_cmd=$1 diff --git a/src/lib/libreblacklist.1.ronn b/src/lib/libreblacklist.1.ronn new file mode 100644 index 0000000..e44aa8d --- /dev/null +++ b/src/lib/libreblacklist.1.ronn @@ -0,0 +1,23 @@ +libreblacklist(1) -- Tools for working with the your-freedom blacklist +====================================================================== + +## SYNPOSIS + +`. $(librelib blacklist)`<br> +`. libreblacklist`<br> +`libremessages` [-h] <COMMAND> [<ARGS>...] + +## DESCRIPTION + +`libreblacklist` is a set of tools for working with the your-freedom +blacklist. + +It may be included into a `Bash`(1) program as a library, which will +expose it's routines as "blacklist-<COMMAND>", or it may be invoked on +the command line as "libreblacklist <COMMAND>". + +See `libremessages -h` for more information. + +## SEE ALSO + +librelib(7) diff --git a/src/lib/librelib b/src/lib/librelib index 2dc9314..d0a06e5 100755 --- a/src/lib/librelib +++ b/src/lib/librelib @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2013 by Luke Shumaker <lukeshu@sbcglobal.net> +# Copyright (C) 2013-2014 by Luke Shumaker <lukeshu@sbcglobal.net> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,25 +16,39 @@ default_libdir=/usr/lib/libretools -if ! type gettext &>/dev/null; then - gettext() { echo "$@"; } +if type gettext &>/dev/null; then + _() { gettext "$@"; } +else + _() { echo "$@"; } fi +_l() { + TEXTDOMAIN='librelib' TEXTDOMAINDIR='/usr/share/locale' "$@" +} + print() { - mesg=$1 + local mesg="$(_ "$1")" shift - printf -- "$(gettext "$mesg")\n" "$@" + printf -- "$mesg\n" "$@" +} + +_html_whitespace_collapse() { + [[ $# == 0 ]] || panic + tr '\n' ' ' | sed -r -e 's/\t/ /g' -e 's/ +/ /g' } prose() { - print "$@" | fmt -su + [[ $# -ge 1 ]] || panic + local mesg="$(_ "$(_html_whitespace_collapse <<<"$1")")"; shift + printf -- "$mesg" "$@" | fmt -u } cmd=${0##*/} usage() { . libremessages print 'Usage: . $(%s LIBRARY)' "$cmd" - print "Finds a shell library file" + print 'Usage: %s -h' "$cmd" + print "Finds a Bash library file" echo prose "While some libraries can be sourced just by their name because they are installed in PATH (like libremessages), some are not @@ -45,16 +59,19 @@ usage() { changed with the environmental variable LIBRETOOLS_LIBDIR.' "$default_libdir" echo print "Example usage:" - printf ' . $(%s conf.sh)\n' "$cmd" + printf ' . $(%s conf)\n' "$cmd" + echo + print "Options:" + flag '-h' 'Show this message' } main() { if [[ $# != 1 ]]; then - usage >&2 + _l usage >&2 return 2 fi if [[ $1 == '-h' ]]; then - usage + _l usage return 0; fi @@ -72,7 +89,7 @@ main() { return 0; fi done - print '%s: could not find library: %s' "$cmd" "$lib" >> /dev/stderr + _l print '%s: could not find library: %s' "$cmd" "$lib" >&2 return 1 } diff --git a/src/lib/librelib.1.ronn b/src/lib/librelib.1.ronn new file mode 100644 index 0000000..42d8f15 --- /dev/null +++ b/src/lib/librelib.1.ronn @@ -0,0 +1,55 @@ +librelib(1) -- finds a Bash library file +======================================== + +## SYNOPSIS + +`. $(librelib LIBRARY)`<br> +`librelib -h` + +## DESRIPTION + +`librelib` is a program to find a Bash(1) library file at run-time. +This way, the path does not need to be hard-coded into the +application; think of it as a sort of dynamic-linker for shell +programs. + +There are several reasons for doing this, instead of hard-coding the +path: + + * The install path can change in the future without having to change + programs that use them. + * The install directory can be configured at runtime, by setting + `LIBRETOOLS_LIBDIR`, similar to `LD_PRELOAD` (this is used when + running the test suite). + * The naming scheme of a library can change (such as between + `libreNAME` and `NAME.sh` without changing programs that use it. + +By default, `librelib` looks in `/usr/lib/libretools`, but that can be +changed by setting the `LIBRETOOLS_LIBDIR` environmental variable to +the directory it should look in. + +When searching for a library, `librelib` first strips `libre` from the +beginning of the name, and `.sh` from the end. This means that all of +the following are equivalent: + + . $(librelib messages) + . $(librelib messages.sh) + . $(librelib libremessages) + . $(librelib libremessages.sh) + +Once it has the 'base' name of the library it is looking for, it looks +for a file with that 'base' name (allowing for, but not requiring +`libre` to be prepended, or `.sh` to be appended) in whichever +directory it is looking in. + +If it cannot find a suitable library file, it will print an error +message to standard error, and exit with a code of 1. + +## Examples + + . $(librelib messages) + . $(librelib conf) + +## SEE ALSO + +librelib(7) diff --git a/src/lib/librelib.7.ronn b/src/lib/librelib.7.ronn new file mode 100644 index 0000000..e030f6a --- /dev/null +++ b/src/lib/librelib.7.ronn @@ -0,0 +1,50 @@ +librelib(7) -- Suite of Bash libraries +====================================== + +## SYNOPSIS + +Overview ot the librelib Bash library suite. + +## DESCRIPTION + +There are three parts to librelib: + + 1. The `librelib`(1) executable. + 2. The non-executable libraries installed in `/usr/lib/libretools` + 3. The executable libraries installed in both `/usr/bin` and + `/usr/lib/libretools`. + +The `librelib` executable isn't very exciting, it just finds the +libraries installed in `/usr/lib/libretools`. Think of it as a sort +of dynamic-linker. + +The 'core' of librelib are the libraries installed in +`/usr/lib/libretools`. These are `Bash`(1) libaries that may be sourced in +Bash programs. + +Some of these libraries also make sense as stand-alone programs, where +if they are invoked directly, the first argument is the library +routine to be executed. For example, the `messages` library may be +included, or executed: + + . $(librelib messages) + msg2 "Foo was found: %s" "$foo" + # or + libremessages msg2 "Foo was found: %s" "$foo" + +The `blacklist` library is similar: + + . $(librelib blacklist) + blacklist-update + # or + libreblacklist update + + + +## SEE ALSO + + * librelib(1) + * libremessages(1)/messages.sh(3) + * libreblacklist(1)/blacklist.sh(3) + * conf.sh(3) + * common.sh(3) diff --git a/src/lib/libremessages b/src/lib/libremessages index c6d08e2..e5b7157 100755 --- a/src/lib/libremessages +++ b/src/lib/libremessages @@ -2,15 +2,15 @@ # This may be included with or without `set -euE` # When run directly, it does `set -euE` -# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> -# Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> -# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> -# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> -# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> -# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> -# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> -# Copyright (c) 2011 by Joshua Haase <hahj87@gmail.com> -# Copyright (c) 2012-2013 by Luke Shumaker <lukeshu@sbcglobal.net> +# Copyright (C) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> +# Copyright (C) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (C) 2005 by Aurelien Foret <orelien@chez.com> +# Copyright (C) 2005 by Christian Hamar <krics@linuxforum.hu> +# Copyright (C) 2006 by Alex Smith <alex@alex-smith.me.uk> +# Copyright (C) 2006 by Andras Voroskoi <voroskoi@frugalware.org> +# Copyright (C) 2006 by Miklos Vajna <vmiklos@frugalware.org> +# Copyright (C) 2011 by Joshua Haase <hahj87@gmail.com> +# Copyright (C) 2012-2014 by Luke Shumaker <lukeshu@sbcglobal.net> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -36,7 +36,7 @@ ################################################################################ panic() { - echo "$(_ 'panic: malformed call to internal function')" >&2 + echo "$(_l _ 'panic: malformed call to internal function')" >&2 exit 1 } @@ -88,8 +88,6 @@ bullet() { # bullet. flag() { [[ $# == 2 ]] || panic - local n=' -' local flag=$1 local desc="$(_ "$(_html_whitespace_collapse <<<"$2")")" @@ -99,7 +97,7 @@ flag() { done local lines - IFS=$n lines=($(fmt -u -w $((73-indent)) <<<"$desc")) + IFS=$'\n' lines=($(fmt -u -w $((73-indent)) <<<"$desc")) local line for line in "${lines[@]}"; do printf " %-${indent}s %s\n" "$flag" "$line" @@ -119,6 +117,25 @@ term_title() { printf "$fmt" "$*" } +# Usage: setup_traps +# Sets up traps on TERM, HUP, QUIT and INT signals, as well as the ERR event, +# similar to makepkg +setup_traps() { + _libremessages_trap_exit() { + local signal=$1; shift + echo + error "$@" + trap -- "$signal" + kill "-$signal" "$$" + } + set -E + for signal in TERM HUP QUIT; do + trap "_libremessages_trap_exit $signal '%s signal caught. Exiting...' $signal" $signal + done + trap '_libremessages_trap_exit INT "Aborted by user! Exiting..."' INT + trap '_libremessages_trap_exit USR1 "An unknown error has occurred. Exiting..."' ERR +} + ################################################################################ # Run one of the defined functions if invoked directly # ################################################################################ diff --git a/src/lib/libremessages.1.ronn b/src/lib/libremessages.1.ronn new file mode 100644 index 0000000..d4c35fc --- /dev/null +++ b/src/lib/libremessages.1.ronn @@ -0,0 +1,220 @@ +libremessages(1) -- common Bash routines +======================================== + +## SYNOPSIS + +`. $(librelib messages)`<br> +`. libremessages`<br> +`libremessages` <COMMAND> + +## DESCRIPTION + +`libremessages` is a shell library containing many common routines. +The name is a bit of a misnomer, it mostly deals with printing +messages, but also has other things. + +`libremessages` uses `common.sh`(3) internally for a large portion of +it's functionality. The authors make no promises that functionality +that is implemented in `libremessages` won't move into `common.sh` or +vice-versa. So, it is recommended that you use `libremessages`, not +`common.sh`. + +### STAND ALONE USAGE + +The "normal" way to use libremessages is to source it, then call the +provided routines. + +However, if you call libremessages directly, the first argument is +taken as a the function to call, and the remaining arguments are +passed to it. The only cases where this doesn't work are the lockfile +routines (`lock`, `slock`, and `lock_close`), because lockfiles are +managed as file descriptors. + +### VARIABLES + +The following variables for printing terminal color codes are set: +`ALL_OFF`, `BOLD`, `BLUE`, `GREEN`, `RED`, `YELLOW`. If standard +error is not a terminal (see `isatty`(3)), they are set, but empty. +They are marked as readonly, so it is an error to try to set them +afterwords. + +### MESSAGE FORMAT + +All routines feed the message/format string through `gettext`(1), if +it is available. + +The descriptions will frequently reference `printf`(1)--this isn't +really that `printf`. The program described by the manual page +`printf`(1) is probably the version from GNU coreutils, every time it +is used here, it is `bash`(1)'s internal implementation; try running +the command `help printf` from a Bash shell for more information. + +### GENERAL ROUTINES + +Unless otherwise noted, these do not implicitly call `gettext`. + + * `_` <MESSAGE>: + If `gettext` is available, calls `gettext`, otherwise just prints + the arguments given. + + * `in_array` <NEEDLE> <HAYSTACK>...: + Evaluates whether <HAYSTACK> includes <NEEDLE>; returns 0 if it + does, non-zero if it doesn't. + + * `panic`: + For the times when you can't reasonably continue, similar to + "assert" in some programming languages. + + * `term_title` <MESSAGE>...: + Joins all arguments with whitespace, and sets the terminal title + to that. + + * `setup_traps`: + Sets traps on TERM, HUP, QUIT and INT signals, as sell as the ERR + event, similar to makepkg. + +### PROSE ROUTINES + +These routines print to standard output, ande are useful for printing +word-wrapped prose. + +For each of these, <MESSAGE> is fed through `gettext` automatically. + + * `print` <MESSAGE> [<ARGS>...]: + Like `printf`(1), but `gettext`-aware, and automatically prints a + trailing newline. + + * `prose` <MESSAGE> [<ARGS>...]: + Takes a `printf`(1)-formatted string, collapses whitespace + (HTML-style), and then word-wraps it. + + * `bullet` <MESSAGE> [<ARGS>...]: + Similar to `prose`, but prints a bullet point before the first + line, and indents the remaining lines. + + * `flag` <FLAG> <DESCRIPTION>: + Print a flag and description formatted for `--help` text. For + example:<br> + `flag '-N' 'Disable networking in the chroot'`<br> + The description is fed through `gettext`, the flag is not, so if + part of the flag needs to be translated, you must do that + yourself:<br> + `flag "-C <$(_ FILE)>" 'Use this file instead of pacman.conf'`<br> + Newlines in the description are ignored; it is + whitespace-collapsed (so newlines are stripped), then it is + re-word-wrapped, in the same way as `prose` and `bullet`. + +### NOTIFICATION ROUTINES + +These routines print to standard error, and all take arguments in the +same format as `printf`(1), except for `stat_done`, which doesn't take +any arguments. Each of these print to stderr, not stdout. + +For each of these, <MESSAGE> is fed through `gettext` automatically. + + * `plain` <MESSAGE> [<ARGS>...]: + Prints "plain" message in bold, indented with 4 spaces. + + * `msg` <MESSAGE> [<ARGS>...]: + Prints a top-level priority notification. + + * `msg2` <MESSAGE> [<ARGS>...]: + Prints a secondary notification. + + * `warning` <MESSAGE> [<ARGS>...]: + Prints a warning. + + * `error` <MESSAGE> [<ARGS>...]: + Prints an error message. + + * `stat_busy` <MESSAGE> [<ARGS>...]: + Prints a "working..." type message without a trailing newline. + + * `stat_done`: + Prints a "done" type message to terminate `stat_busy`. + +### TEMPORARY DIRECTORY MANAGEMENT + +These are used by devtools, and not used within the rest of +libretools. + +They work by creating and removing the directory referred to by the +variable $<WORKDIR>; `libretools.conf`(5) uses the same variable to +where the user saves all their work. If you aren't careful with +these, you could end up deleting a lot of someone's work. + + * `setup_workdir`: + Creates a temporary directory, and sets the environmental + variable $<WORKDIR> to it. Also sets traps for the signals INT, + QUIT, TERM and HUP to run `abort`; and EXIT to run `cleanup` + (see `signal`(7)). + + * `cleanup` [<EXIT_STATUS>]: + *If* `setup_workdir` has been run, `rm -rf "$WORKDIR"`. If given + a numeric argument, it will then call `exit`(1) with that argument. + + * `abort`: + Calls `msg` with the message "Aborting...", then calls + `cleanup 0`. + + * `die` <MESSAGE> [<ARGS>...]: + Exactly like `error`, but calls `cleanup` and calls `exit`(1) + with a status of 1. + +### LOCKFILE ROUTINES + + * `lock` <FD> <LOCKFILE> <MESSAGE> [<MSG_ARGS>...]: + Opens (creating if nescessary) the file <LOCKFILE> with file + descriptor <FD> in the current process, and gets an exclusive + lock on it. If another program already has a lock on the file, + and this program needs to wait for the lock to be release, then + it uses `stat_busy`/`stat_done` to print <MESSAGE>. + + * `slock` <FD> <LOCKFILE> <MESSAGE> [<MSG_ARGS>...]: + Identical like `lock`, but opens a shared lock. This is also + known as a "read lock". Many programs can have a shared lock at + the same time, as long as no one has an exclusive lock on it. + + * `lock_close` <FD>: + Closes file descriptor <FD>, releasing the lock opened on it. + +### MAKEPKG ROUTINES + +These routines relate to `makepkg`(8). + + * `find_cached_package` <PKGNAME> <PKGVER>[-<PKGREL] <ARCH>: + Searches for a localy built copy of the specified package, in + <PKGDEST> and the current working directory. If <PKGREL> is not + specified, any value will match. If multiple matching files are + found (not counting duplicate links), then an error is printed to + stderr and nothing is prented to stdout. + + * `get_full_version` [<PKGNAME>]: + Inspects variables that are set, and prints the full version + spec, including <epoch> if necessary, <pkgver>, and <pkgrel>. By + default, it will print the information for <pkgbase>, following + the normal rules for finding <pkgbase>. If <PKGNAME> is given, + it will print the information for that sub-package. The versions + for different parts of a split package don't have to be the same! + +## BUGS + +Generating `.pot` files for the prose functions is a pain. The +libretools Makefiles have rules to do it, but it might make sense to +pull it into a separate program. + +`term_title` currently only knows about the terminals screen, tmux, +xterm and rxvt (and their various <TERM> values; +"rxvt-unicode-256color" is still rxvt). + +Also, I think `abort` calling `cleanup 1` would make more sense than +`cleanup 0`. + +## SEE ALSO + +librelib(7), gettext(1), common.sh(3) + +Things that were mentioned: + +bash(1), exit(1), isatty(3), libretools.conf(5), makepkg(8), +printf(1), signal(7) diff --git a/src/lib/messages.sh.3.ronn b/src/lib/messages.sh.3.ronn new file mode 120000 index 0000000..391ecbd --- /dev/null +++ b/src/lib/messages.sh.3.ronn @@ -0,0 +1 @@ +libremessages.1.ronn
\ No newline at end of file |