ENH: Associated hierarchy node with ChildNode(Added/Removed)Event

It will now be easier to know which node has been added or removed
from a given hierarchy.

Still need to figure out which node to associated with the event
'ChildNodeRemovedEvent' invoked in function 'vtkMRMLHierarchyNode::RemoveHierarchyChildrenNodes'

git-svn-id: http://svn.slicer.org/Slicer4/trunk@22910 3bd1e089-480b-0410-8dfb-8563597acbee
STYLE: Fix spelling error in s4ext template
ENH: Create new slicer "wizard" tool

Create new SlicerWizard.py tool, more or less based on the existing
ModuleWizard.py, with improvements. This one separates the concepts of
extensions and modules, and allows creating an extension containing
several modules, as well as adding modules to an existing extension.

The mechanism for specifying templates is also changed; we now take
named templates which are searched for in a well-known location relative
to the script. (In the future it is expected that users will be able to
add additional template directories, however this has not been
implemented yet.)

Eventually it is hoped that this tool will add other actions, e.g.
publishing extensions.
ENH: Create new templates for wizard

Refactor the ModuleWizard.py templates for use by the new
SlicerWizard.py. The main changes are that the module templates no
longer have extension templates wrapped around them (and the extension
templates no longer contain modules), the directory organization has
been improved, and the placeholders are all now TemplateKey.

This last change in particular was to allow the SuperBuild template to
be named "SuperBuild" (which is easy for users to type and logical given
the new organization), and still contain files named like "SuperBuild"
that should not be renamed.
BUG: Fix argparse assert wrapping arguments

Tweak WizardHelpFormatter in SlicerWizard.py to temporarily replace
'[]'s in option value strings during formatting in order to avoid
argparse splitting these and tripping an assert in its internals.
ENH: Add user templates to SlicerWizard.py

Add support for user-specified template directories and keys to
SlicerWizard.py. This allows users to provide their own templates in
addition to the "built in" templates.
STYLE: Refactor SlicerWizard into Python modules

Replace Scripts/SlicerWizard.py with a very short script that merely
imports the main wizard class, intantiates it, and calls its execute()
method. Move the code into two new Python module files in a
subdirectory.

This will allow for better scaling as we add features, by allowing us to
create additional modules as it makes sense, rather than needing to
encapsulate everything in a single monolithic script file.
STYLE: More refactoring of SlicerWizard

Also move manipulation of extension CMakeLists.txt to its own Python
module, and adjust code style to prefer raising exceptions in modules
rather than calling exit(). (We still do call exit(), but it is moved to
higher up the stack where we now catch the newly raised exceptions.)
STYLE: Improve SlicerWizard.py help

Use action.metavar to simplify our usage customization (some is still
needed to avoid breaking the word splitting). Mention TYPE in
--createExtension usage. Show usage when no action was requested.
STYLE: Fix indentation in SlicerWizard.py
ENH: Add option to list templates to SlicerWizard
STYLE: Change error reporting in SlicerWizard

Create a new utility module for generic helper functions. Create and use
a new die() function to terminate the script with an error message,
rather than calling exit() all over the place.
ENH: Create CMake parser for SlicerWizard

Create a Python implementation of a CMake script parser (of sorts). This
is believed to parse most well-formed CMake script (including CMake 3.0
long brackets for strings and comments), and turns the script into a
parse tree that is well suited to editing and capable of reconstructing
the exact input document without reformatting. Use this, instead of
regular expressions, to perform the CMakeLists.txt manipulation when
adding a module to an extension.

In the long run, this will make it much easier to reliably manipulate
CMake scripts.
ENH: Add publishExtension to SlicerWizard

Add a new 'command' to SlicerWizard to publish (to github) an extension.
This creates a git repository for the extension (if one does not already
exist), creates a github repository for the extension, changes the
extension meta-information to reference the github repository, commits
said changes (or makes an initial commit with the contents of the
extension tree), adds the github repository as a remote, and pushes to
github.
ENH: Add debug option to SlicerWizard.py

Add an undocumented --debug option to SlicerWizard.py. When used,
exceptions are re-raised when caught, rather than showing a fatal error
with just the exception message. This is useful for development to get
the stack trace in case of unexpected exceptions due to incorrect code.
BUG: Don't catch die() in SlicerWizard.py

Separately catch SystemExit and re-raise, so that calls to die() from
within a try-except don't print strange error messages.
ENH: Add wrapped output to SlicerWizard.py

Add a 'printw' helper function to print wrapped text. Use this in die()
and one other appropriate spot.
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.