Unpack tarpath to outfolder.  Make a guess about the compression based on
    file extension (.gz or .bz2).

    The unpacking of the tarfile is done in a temp directory and moved into
    place atomically at the end (assuming /tmp is on the same filesystem as
    outfolder).

    If 'owners' is provided, it should be a tuple in the form
    (username, groupname), and the contents of the unpacked folder will be set
    with that owner and group.

    If outfolder already exists, and overwrite=True (the default), the existing
    outfolder will be deleted before the new one is put in place. If outfolder
    already exists and overwrite=False, IOError will be raised.

def untar(tarpath, outfolder, owners=None, overwrite=True, fixperms=True):
    """
    Unpack tarpath to outfolder.  Make a guess about the compression based on
    file extension (.gz or .bz2).

    The unpacking of the tarfile is done in a temp directory and moved into
    place atomically at the end (assuming /tmp is on the same filesystem as
    outfolder).

    If 'owners' is provided, it should be a tuple in the form
    (username, groupname), and the contents of the unpacked folder will be set
    with that owner and group.

    If outfolder already exists, and overwrite=True (the default), the existing
    outfolder will be deleted before the new one is put in place. If outfolder
    already exists and overwrite=False, IOError will be raised.
    """

    # We don't use fixperms at all
    _ignored = fixperms  # noqa

    # make a folder to untar to
    with tmpdir():
        _, _, ext = tarpath.rpartition('.')

        if ext not in ('gz', 'bz2', 'xz'):
            raise ValueError('tarpath must point to a .gz, .bz2, or .xz file')

        tf = tarfile.open(tarpath, 'r:' + ext)
        try:
            os.mkdir('contents')
            tf.extractall('contents')
        finally:
            tf.close()

        if owners is not None:
            contents = path.Path('contents')
            for item in contents.walk():
                if item.isdir():
                    # chown user:group
                    item.chown(*owners)
                    # chmod ug+xr
                    item.chmod('ug+xr')
                if item.isfile() and not item.islink():
                    # chown user:group
                    item.chown(*owners)
                    # chmod ug+rw
                    item.chmod('ug+rw')

        if os.path.isdir(outfolder):
            if overwrite:
                shutil.rmtree(outfolder)
            else:
                raise IOError(
                    ('Cannot untar %s because %s already exists and '
                     'overwrite=False') % (tarfile, outfolder))
        shutil.move('contents', outfolder)