예제 #1
0
파일: fsops.py 프로젝트: Byron/bcore
class MoveFSItemOperation(FSOperationBase):

    """Move a file or directory to the given name"""
    __slots__ = ("_source_path", "_destination_path", "_actual_destination_path")

    name = "FSItemMove"

    def __init__(self, transaction, source_path, destination_path):
        super(MoveFSItemOperation, self).__init__(transaction)
        self._source_path = Path(source_path).expandvars()
        self._destination_path = self._actual_destination_path = Path(destination_path).expandvars()

        # if we move into a directory, the filename will just be appended
        if self._destination_path.isdir():
            self._actual_destination_path = self._destination_path / source_path.basename()
        # END handle actual destination

    def apply(self):
        if self._actual_destination_path.exists():
            raise AssertionError("Cannot move item %s onto existing one at %s" %
                                 (self._source_path, self._actual_destination_path))
        # END handle existing dsetination

        if self._dry_run():
            return

        self.log.info("moving %s to %s", self._source_path, self._destination_path)
        self._source_path.move(self._destination_path)
        self._operation_performed = True

    def rollback(self):
        try:
            if not self._operation_performed or not self._actual_destination_path.exists():
                return

            # fail gracefully
            if self._source_path.exists():
                raise AssertionError("Cannot move destination %s into existing source %s, source directory should not exist" % (
                    self._actual_destination_path, self._source_path))
            self.log.info("moving %s to %s", self._actual_destination_path, self._source_path)
            self._actual_destination_path.move(self._source_path)
        finally:
            self._reset_state()
        # END assure state reset

    #{ Interface

    def actual_destination(self):
        """:return: path to the final destination"""
        return self._actual_destination_path