Create a release of a MicroDrop plugin source directory in the target
    directory path.

    Skip the following patterns:

     - ``bld.bat``
     - ``.conda-recipe/*``
     - ``.git/*``

    .. versionchanged:: 0.24.1
        Remove temporary archive after extraction.

        Change directory into source directory before running ``git archive``.

    .. versionchanged:: 0.25
        Add optional :data:`version_number` argument.

    Parameters
    ----------
    source_dir : str
        Source directory.
    target_dir : str
        Target directory.
    package_name : str, optional
        Name of plugin Conda package (defaults to name of :data:`target_dir`).
    version_number : str, optional
        Package version number.

        If not specified, assume version package exposes version using
        `versioneer <https://github.com/warner/python-versioneer>`_.

def build(source_dir, target_dir, package_name=None, version_number=None):
    '''
    Create a release of a MicroDrop plugin source directory in the target
    directory path.

    Skip the following patterns:

     - ``bld.bat``
     - ``.conda-recipe/*``
     - ``.git/*``

    .. versionchanged:: 0.24.1
        Remove temporary archive after extraction.

        Change directory into source directory before running ``git archive``.

    .. versionchanged:: 0.25
        Add optional :data:`version_number` argument.

    Parameters
    ----------
    source_dir : str
        Source directory.
    target_dir : str
        Target directory.
    package_name : str, optional
        Name of plugin Conda package (defaults to name of :data:`target_dir`).
    version_number : str, optional
        Package version number.

        If not specified, assume version package exposes version using
        `versioneer <https://github.com/warner/python-versioneer>`_.
    '''
    source_dir = ph.path(source_dir).realpath()
    target_dir = ph.path(target_dir).realpath()
    target_dir.makedirs_p()
    source_archive = source_dir.joinpath(source_dir.name + '.zip')
    if package_name is None:
        package_name = str(target_dir.name)
    logger.info('Source directory: %s', source_dir)
    logger.info('Source archive: %s', source_archive)
    logger.info('Target directory: %s', target_dir)
    logger.info('Package name: %s', package_name)

    # Export git archive, which substitutes version expressions in
    # `_version.py` to reflect the state (i.e., revision and tag info) of the
    # git repository.
    original_dir = ph.path(os.getcwd())
    try:
        os.chdir(source_dir)
        sp.check_call(['git', 'archive', '-o', source_archive, 'HEAD'],
                      shell=True)
    finally:
        os.chdir(original_dir)

    # Extract exported git archive to Conda MicroDrop plugins directory.
    with zipfile.ZipFile(source_archive, 'r') as zip_ref:
        zip_ref.extractall(target_dir)
    # Extraction is complete.  Remove temporary archive.
    source_archive.remove()

    # Delete Conda build recipe from installed package.
    target_dir.joinpath('.conda-recipe').rmtree()
    # Delete Conda build recipe from installed package.
    for p in target_dir.files('.git*'):
        p.remove()

    # Write package information to (legacy) `properties.yml` file.
    original_dir = ph.path(os.getcwd())
    try:
        os.chdir(source_dir)
        if version_number is None:
            # Assume versioneer is being used for managing version.
            import _version as v

            version_info = {'version': v.get_versions()['version'],
                            'versioneer': v.get_versions()}
        else:
            # Version number was specified explicitly.
            version_info = {'version': version_number}
    finally:
        os.chdir(original_dir)

    # Create properties dictionary object (cast types, e.g., `ph.path`, to
    # strings for cleaner YAML dump).
    properties = {'package_name': package_name,
                  'plugin_name': str(target_dir.name)}
    properties.update(version_info)

    with target_dir.joinpath('properties.yml').open('w') as properties_yml:
        # Dump properties to YAML-formatted file.
        # Setting `default_flow_style=False` writes each property on a separate
        # line (cosmetic change only).
        yaml.dump(properties, properties_yml, default_flow_style=False)