ENH: Add 'submit extension' to SlicerWizard.py

Add a utility to manipulate slicer extension description files, which
can read an existing description file or create a description from an
extension git repository, and also write a description file (without
comments). Add helpers to get a named repository from github, or a
user's fork of a github repository. Add a git helper to find or create a
remote matching a specified fetch url. Modify git 'get repository'
helper to take a callable as the 'create' parameter in order to allow
enforcing that a newly-created repository is created in an empty (or
previously non-existing) directory.

Use all of the above to start implementing a 'submit extension' command,
which takes an extension repository and creates a pull request to add
the extension to the extensions index. So far this does everything but
create the actual pull request (i.e. handles the user's fork of the
index repository, and creating and pushing the commit against the index
repository to add or update the extension).
BUG: Avoid trailing whitespace in description file

Change ExtensionDescription.py to strip whitespace from output lines
when writing the description file, in order to avoid writing trailing
space in case a value is not set.
ENH: Update user's fork when submitting extension

When submitting an extension, also push the current upstream branch to
the user's fork, so that the branch does not seem to include extraneous
history due to the target branch on the user's fork being behind
upstream.
BUG: Include target in submit branch name

Include the target branch in the extension index branch created to
submit an extension. This is required to concurrently submit to multiple
target branches (which would otherwise be impossible due to branch name
collision).
ENH: Refactor SlicerWizard logging

Convert SlicerWizard reporting to use Python's built-in logging
facility, and add additional debug messages (newly controlled by the
--debug option).

This gives us additional features and better control over logging, e.g.
we now implicitly use logging levels, with WARNING and higher going to
stderr, and INFO/DEBUG going to stdout, as well as applying text
wrapping to everything.
STYLE: Move exception logging to die()

Change die() in SlicerWizard/Utilities.py to log the current exception,
if there is one, and --debug has been given. This allows us to remove
the code to re-raise the exception (in order to produce the traceback)
any time we would otherwise call die() after catching an exception.
STYLE: Move wrapping width to formatter

Move the variable holding the text wrap width from a global in
SlicerWizard/Utilities.py to a member of the log formatter class, now
that it is only used from there, and not from a freestanding function.
ENH: Create pull request when submitting extension

Finish implementing the base logic to crate the github pull request via
SlicerWizard when submitting an extension. This seems to be working for
additions. For updates, we still also want to generate a compare URL for
the extension repository to add to the pull request message.
ENH: Allow looking up github repository by URL

Change GithubHelper.getRepo to take either a name or clone URL, adding
the ability to look up a repository by a clone URL. This is needed to
find the github repository for an extension that has already been
published.
ENH: Improve ExtensionDescription API

Add ability to directly construct an ExtensionDescription from a file
path. Note that unlike read() this takes the path to a description file,
not a directory containing a (single) extension description. This is
intended to be used to read extension descriptions from the index
repository.
ENH: Add compare URL when updating extension

Change SlicerWizard.py to load the old extension description when
submitting an update to an extension, and to use this to generate and
include a compare URL in the pull request message with the changes in
the extension from the currently available (indexed) version.
ENH: Add 'describe extension' to SlicerWizard.py

Add an action to "describe" an extension (i.e. dump its generated
description content to stdout). This is useful both as a user check
before publishing, and potentially can be used by CMake as an alternate
means of generating the s4ext file for the build.

Note that at the moment the extension must have a git repository.
Eventually we want to support subversion repositories and also
extensions that don't yet have a repository, but a number of places will
need to change for that (e.g. publishing should also support svn).
STYLE: Rename Slicer(Wizard.py) -> Extension

Given its current functionality, SlicerWizard.py is more appropriately
the Extension Wizard; rename it accordingly. This also allows us to
shorten the actions (by dropping 'extension' from the end).

Also, the 'submit' action has been renamed to 'contribute'.

Note that the module code has NOT been moved, as it conceivably could be
used by some other script. (Although the SlicerWizard class is renamed.)
Thus, the driver script now says 'from SlicerWizard import
ExtensionWizard'.
ENH: Sort ExtensionWizard.py --listTemplates

Change TemplateManager.listTemplates method to sort the list of
templates per category, rather than outputting in the semi-arbitrary
order of dict. (The categories come from a list, which retains the
declaration order - which is likely to be a meaningful, semantic
ordering that is at least as good as a lexical sorting - and so do not
need to be sorted.)
ENH: Use 'git credentials' in GithubHelper.py

Change GithubHelper.py to use 'git credentials' to get the login
information for github. This way we are not only handling this
information in the same manner as git, but we leverage its credentials
storage system as well. (The downside is that the user name is no longer
automatically stored permanently if the user is not using a password
manager.)
STYLE: Remove silly shebangs

Remove shebangs ("#!/usr/bin/env python") from Python module code. These
are not meant to be executed directly, so shebangs are not appropriate.
(Their presence is almost certainly accidental.)
STYLE: Document SlicerWizard/Utilities.py

Add documentation for the public API of SlicerWizard.Utilities. Also,
fix some minor code issues revealed in the course of writing the same:

- Use sys.exit instead of exit
- Remove unused 'clone' parameter from getRepo
STYLE: Document SlicerWizard/GithubHelper.py

Add documentation for the public API of SlicerWizard.GithubHelper. Also,
fix some code issues revealed in the course of writing the same:

- CredentialToken class is private; name should start with '_'
- CredentialToken did not output values added from text input
- logIn() function doesn't need a repository; it can be optional
- logIn() was not failing as expected in case of authentication failure
- getPullRequest() should accept additional criteria
STYLE: Document SlicerWizard/CMakeParser.py

Add documentation of SlicerWizard.CMakeParser. Tweak an exception
message that I noticed in the process could be improved.
STYLE: Make ExtensionProject.project a property

Change the project() method of ExtensionProject to a property, and
update uses accordingly.