Make and install a package.

    Example:

        >>> def make_root(variant, path):
        >>>     os.symlink("/foo_payload/misc/python27", "ext")
        >>>
        >>> with make_package('foo', '/packages', make_root=make_root) as pkg:
        >>>     pkg.version = '1.0.0'
        >>>     pkg.description = 'does foo things'
        >>>     pkg.requires = ['python-2.7']

    Args:
        name (str): Package name.
        path (str): Package repository path to install package into.
        make_base (callable): Function that is used to create the package
            payload, if applicable.
        make_root (callable): Function that is used to create the package
            variant payloads, if applicable.
        skip_existing (bool): If True, detect if a variant already exists, and
            skip with a warning message if so.
        warn_on_skip (bool): If True, print warning when a variant is skipped.

    Yields:
        `PackageMaker` object.

    Note:
        Both `make_base` and `make_root` are called once per variant install,
        and have the signature (variant, path).

    Note:
        The 'installed_variants' attribute on the `PackageMaker` instance will
        be appended with variant(s) created by this function, if any.

def make_package(name, path, make_base=None, make_root=None, skip_existing=True,
                 warn_on_skip=True):
    """Make and install a package.

    Example:

        >>> def make_root(variant, path):
        >>>     os.symlink("/foo_payload/misc/python27", "ext")
        >>>
        >>> with make_package('foo', '/packages', make_root=make_root) as pkg:
        >>>     pkg.version = '1.0.0'
        >>>     pkg.description = 'does foo things'
        >>>     pkg.requires = ['python-2.7']

    Args:
        name (str): Package name.
        path (str): Package repository path to install package into.
        make_base (callable): Function that is used to create the package
            payload, if applicable.
        make_root (callable): Function that is used to create the package
            variant payloads, if applicable.
        skip_existing (bool): If True, detect if a variant already exists, and
            skip with a warning message if so.
        warn_on_skip (bool): If True, print warning when a variant is skipped.

    Yields:
        `PackageMaker` object.

    Note:
        Both `make_base` and `make_root` are called once per variant install,
        and have the signature (variant, path).

    Note:
        The 'installed_variants' attribute on the `PackageMaker` instance will
        be appended with variant(s) created by this function, if any.
    """
    maker = PackageMaker(name)
    yield maker

    # post-with-block:
    #

    package = maker.get_package()
    cwd = os.getcwd()
    src_variants = []

    # skip those variants that already exist
    if skip_existing:
        for variant in package.iter_variants():
            variant_ = variant.install(path, dry_run=True)
            if variant_ is None:
                src_variants.append(variant)
            else:
                maker.skipped_variants.append(variant_)
                if warn_on_skip:
                    print_warning("Skipping installation: Package variant already "
                                  "exists: %s" % variant_.uri)
    else:
        src_variants = package.iter_variants()

    with retain_cwd():
        # install the package variant(s) into the filesystem package repo at `path`
        for variant in src_variants:
            variant_ = variant.install(path)

            base = variant_.base
            if make_base and base:
                if not os.path.exists(base):
                    os.makedirs(base)
                os.chdir(base)
                make_base(variant_, base)

            root = variant_.root
            if make_root and root:
                if not os.path.exists(root):
                    os.makedirs(root)
                os.chdir(root)
                make_root(variant_, root)

            maker.installed_variants.append(variant_)