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)