コード例 #1
0
def copy(source: str,
         destination: str,
         *,
         follow_symlinks: bool = False) -> None:
    """Copy source and destination files.

    This function overwrites the destination if it already exists, and also
    tries to copy ownership information.

    :param str source: The source to be copied to destination.
    :param str destination: Where to put the copy.
    :param bool follow_symlinks: Whether or not symlinks should be followed.

    :raises SnapcraftCopyFileNotFoundError: If source doesn't exist.
    """
    # If os.link raised an I/O error, it may have left a file behind. Skip on
    # OSError in case it doesn't exist or is a directory.
    with suppress(OSError):
        os.unlink(destination)

    try:
        shutil.copy2(source, destination, follow_symlinks=follow_symlinks)
    except FileNotFoundError:
        raise SnapcraftCopyFileNotFoundError(source)
    uid = os.stat(source, follow_symlinks=follow_symlinks).st_uid
    gid = os.stat(source, follow_symlinks=follow_symlinks).st_gid
    try:
        os.chown(destination, uid, gid, follow_symlinks=follow_symlinks)
    except PermissionError as e:
        logger.debug("Unable to chown {destination}: {error}".format(
            destination=destination, error=e))
コード例 #2
0
def link(source: str,
         destination: str,
         *,
         follow_symlinks: bool = False) -> None:
    """Hard-link source and destination files.

    :param str source: The source to which destination will be linked.
    :param str destination: The destination to be linked to source.
    :param bool follow_symlinks: Whether or not symlinks should be followed.

    :raises SnapcraftCopyFileNotFoundError: If source doesn't exist.
    """
    # Note that follow_symlinks doesn't seem to work for os.link, so we'll
    # implement this logic ourselves using realpath.
    source_path = source
    if follow_symlinks:
        source_path = os.path.realpath(source)

    if not os.path.exists(os.path.dirname(destination)):
        create_similar_directory(os.path.dirname(source_path),
                                 os.path.dirname(destination))
    # Setting follow_symlinks=False in case this bug is ever fixed
    # upstream-- we want this function to continue supporting NOT following
    # symlinks.
    try:
        os.link(source_path, destination, follow_symlinks=False)
    except FileNotFoundError:
        raise SnapcraftCopyFileNotFoundError(source)
コード例 #3
0
def _copy(source: str, destination: str, follow_symlinks: bool=False) -> None:
    # If os.link raised an I/O error, it may have left a file behind. Skip on
    # OSError in case it doesn't exist or is a directory.
    with suppress(OSError):
        os.unlink(destination)

    try:
        shutil.copy2(
            source, destination, follow_symlinks=follow_symlinks)
    except FileNotFoundError:
        raise SnapcraftCopyFileNotFoundError(source)
    uid = os.stat(source, follow_symlinks=follow_symlinks).st_uid
    gid = os.stat(source, follow_symlinks=follow_symlinks).st_gid
    try:
        os.chown(destination, uid, gid, follow_symlinks=follow_symlinks)
    except PermissionError as e:
        logger.debug('Unable to chown {destination}: {error}'.format(
            destination=destination, error=e))
コード例 #4
0
def _link(source: str, destination: str, follow_symlinks: bool=False) -> None:
    # Note that follow_symlinks doesn't seem to work for os.link, so we'll
    # implement this logic ourselves using realpath.
    source_path = source
    if follow_symlinks:
        source_path = os.path.realpath(source)

    if not os.path.exists(os.path.dirname(destination)):
        create_similar_directory(
            os.path.dirname(source_path),
            os.path.dirname(destination))
    # Setting follow_symlinks=False in case this bug is ever fixed
    # upstream-- we want this function to continue supporting NOT following
    # symlinks.
    try:
        os.link(source_path, destination, follow_symlinks=False)
    except FileNotFoundError:
        raise SnapcraftCopyFileNotFoundError(source)