Vendor-ize packages.

def vendorize(ctx, PACKAGES=None, dest_dir=None, internal_call=False):
    """Vendor-ize packages."""
    if not internal_call:
        colorama.init()
        text.title("Minchin Vendorize-er for Python Projects v{}".format(__version__))

        print()

    text.subtitle("Configuration")
    extra_keys = ['here',
                  'source',
                  'module_name',
                  'vendor_dest',
                  'vendor_packages',
                  'vendor_override_src',
                 ]
    if not internal_call:
        check_configuration(ctx, 'releaser', extra_keys)
        check_existence(ctx.releaser.here, "base dir", "releaser.here")
    here = Path(ctx.releaser.here).resolve()

    if not internal_call:
        try:
            check_existence(ctx.releaser.source, "source", "releaser.source", here)
        except FileNotFoundError:
            sys.exit(1)

    check_existence(ctx.releaser.vendor_dest, "vendor dir", "releaser.vendor_dest",
                    here, allow_not_existing=True)
    check_existence(ctx.releaser.vendor_override_src, "override dir",
                    "releaser.vendor_override_src", here, True)
    print()


    dest_dir = Path(ctx.releaser.vendor_dest).resolve()
    base_pkg_dir = Path(ctx.releaser.source)
    # remove and recreate base folder
    text.subtitle("Removing existing vendored directory.")
    try:
        shutil.rmtree(str(dest_dir))
    except FileNotFoundError:
        # directory already deleted
        pass
    dest_dir.mkdir(exist_ok=True)
    print()

    my_req = ['# Requirements for {}'.format(ctx.releaser.module_name),
              '#',
              '# This is built by the minchin.releaser.vendorize script. Do not edit it directly.',
              '',
             ]
    my_req_add = []

    PACKAGES = tuple(ctx.releaser.vendor_packages.keys())

    for package in PACKAGES:
        text.subtitle("Vendorizing {}".format(package))
        req_to_add = []
        # copy python code
        root_dir = (here / ctx.releaser.vendor_packages[package].src).resolve()
        pkg_dest_dir = (dest_dir / ctx.releaser.vendor_packages[package].dest).resolve()
        pkg_dest_dir.mkdir(exist_ok=True)
        print("Copying code from {}".format(root_dir))
        copytree(str(root_dir), str(pkg_dest_dir), True, ['__pycache__'])


        # build requirements file
        try:
            pkg_req_override = (here / ctx.releaser.vendor_packages[package].requirements).resolve()
        except AttributeError:
            pkg_req_override = None
        pkg_req = root_dir / 'requirements.in'
        pkg_req_alt = root_dir / 'requirements.txt'
        if pkg_req_override and pkg_req_override.exists():
            print("  Using project override requirements.")
            req_to_add = read_requirements(str(pkg_req_override))
        elif pkg_req.exists():
            req_to_add = read_requirements(str(pkg_req))
        elif pkg_req_alt.exists():
            print("  Using requirements.TXT.")
            req_to_add = read_requirements(str(pkg_req_alt))
        else:
            print("  No requirements found.")
        my_req_add.extend(req_to_add)
        print()

    text.subtitle("Building requirements-vendor.in")
    # remove vendorized items from requirements list
    my_req_add = [i for i in set(my_req_add) if not i.startswith(PACKAGES)]
    my_req_add.sort()
    my_req.extend(my_req_add)

    # write out requirements file
    dst_req = here / 'requirements-vendor.in'
    dst_req.write_text('\n'.join(my_req) + '\n')
    print()

    # copy over project specific override files
    text.subtitle("Copying over project-specific vendorized overrides.")
    root_dir = Path(ctx.releaser.vendor_override_src)
    copytree(str(root_dir), str(dest_dir), overwrite=True,
             ignore_list=['__pycache__'])
    print()

    if not internal_call:
        text.centered("--- FIN ---")