Propagate subcommand exit status to calling process.
util.py: refactored `relative_datetime_string` to be more generic
util.py: added text-based table-formatting utility
command.py: added "show builds" command

This command produces a summary of existing ChaNGa builds.
core.py: simplified name creation for ChaNGa builds
core.py: correct typo(s) introduced in @6977e9a
config.py: allow '-' instead of '_' in hand-written launch configs
{core,job}.py: load git, saga mods. as needed to improve chimi load time
Jobs: major rewrite/restructure of job-launch functions and heuristics

Had I been careful to commit more often, such a "rewrite" commit may not
have been necessary; unfortunately it would have been difficult to
reconcile all the individual changes separately at this point.

In any case, the end result is a moderately cleaner and more-efficient
"job" module.

  * Arbitrary configuration-tree overlays for individual options and
    architectures can now be set in chimi/data/option.yaml and
    chimi/data/architecture.yaml, respectively.

    This data can be used to drive a launch-options configuration
    mechanism implemented in chimi/job.py (see `make_launch_config`);
    its usefulness is limited by the fact that such a system allows
    only simple "if I have this build option, apply this config tree"-type
    logic.

  * A Python extension including Charm's `CmiNumCores` function is now
    created and loaded at run-time to enable better choice of commands
    for running ChaNGa.  To avoid licensing issues [the Charm++ license
    is *not* GPL-compatible], Chimi extracts the function definition
    from the Charm++ source tree and alters it to work as a Python
    callback.

    We use CmiNumCores (charm.cmi.num_cores in Python) to determine
    requested CPU occupancy per node, and thus the number of nodes
    required and whether we can stay within a single node.

  * `net'-architecture-specific options are specified only for that
    architecture, and we avoid "++local" when using ibverbs -- apparently
    it doesn't work in that case.

  * Low-level build-configuration options for build selection have been
    removed from the "job run" command in favor of a `--build=` option;
    this option accepts either the name or the UUID of a ChaNGa build
    that should be used for the run.

  * the "job" command's common callback has been split into several parts;
    the common callback itself now just determines user/hostname and loads
    host configuration.  Job-service creation, which can be slow and
    is not needed until we validate input, hass been moved to
    `create_job_service`.

  * Handling of job-options strings specified to "job run" with "-O" is
    more robust (e.g. it doesn't flail miserably when it sees two
    adjacent commas).
Makefile: added `clean' rule
util.py: Table: don't include ANSI esc. seqs. in column-width calculations
util.py: Table: don't bother padding final column if left-aligned
util.py: Table: change default maximum width to 132 columns
command.py: implement purge-by-uuid; provide feedback on purged builds
command.py: don't skip build if existing build has different branch

This is related to the fact that we don't compare branch settings on
build configurations when testing for equality (and that's because we
don't want to require matching branch names when finding a Charm++ build
to use for a ChaNGa build).
command.py: pass continue, replace, force flags to Package.build by keyword
core.py: fixes to branch handling

These changes ensure that a build's branch is set correctly, and correct
incorrect branch names when loading the package-set file.

Also added is a package property `branches`, which contains the names of
all local branches.  Its value is loaded and cached on-demand once per
instantiation of the Package class.
{core,job}.py: make module-load messages disappear after load on terminals
core.py: CharmArchitecture: added list of refs to child architectures
command.py: show builds: allow to switch package, filter by branch + arch