Archives a specific tag in a specific SVN repository.
    :param root_url: This is the root url of the repo and should end in the
        repo name.
    :param archive_path: Where the archive will be stored - Must end in a
        valid extension that matches the archive_mode type. Default requires
        'tar.gz'
    :param tag: This is the tag you want to harvest, None=HEAD
    :param archive_mode: See 'tarfile.open' modes default w:gz > tar.gz

def harvest_repo(root_url, archive_path, tag=None, archive_mode='w:gz'):
    """
    Archives a specific tag in a specific SVN repository.
    :param root_url: This is the root url of the repo and should end in the
        repo name.
    :param archive_path: Where the archive will be stored - Must end in a
        valid extension that matches the archive_mode type. Default requires
        'tar.gz'
    :param tag: This is the tag you want to harvest, None=HEAD
    :param archive_mode: See 'tarfile.open' modes default w:gz > tar.gz
    """

    if not svn_exists():
        raise Exception("SVN not found. It probably needs installing.")

    clone_path = mkdtemp(dir=cfg['CFG_TMPDIR'])

    svn = get_which_svn()

    if tag:
        call([svn, 'co', root_url + '/tags/' + tag, clone_path])
    else:
        call([svn, 'co', root_url + '/trunk/', clone_path])

    chdir(cfg['CFG_TMPDIR'])
    tar = tarfile.open(name=archive_path, mode=archive_mode)
    tar.add(clone_path, arcname=root_url.split('/').pop())
    tar.close()

    try:
        rmtree(clone_path)
    except OSError as e:
        # Reraise unless ENOENT: No such file or directory
        # (ok if directory has already been deleted)
        if e.errno != errno.ENOENT:
            raise