# Copyright 2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import errno import logging from portage import os from portage.util._async.FileCopier import FileCopier from _emerge.CompositeTask import CompositeTask class DeletionTask(CompositeTask): __slots__ = ('distfile', 'config') def _start(self): distfile_path = os.path.join( self.config.options.distfiles, self.distfile) if self.config.options.recycle_dir is not None: distfile_path = os.path.join(self.config.options.distfiles, self.distfile) recycle_path = os.path.join( self.config.options.recycle_dir, self.distfile) if self.config.options.dry_run: logging.info(("dry-run: move '%s' from " "distfiles to recycle") % self.distfile) else: logging.debug(("move '%s' from " "distfiles to recycle") % self.distfile) try: os.rename(distfile_path, recycle_path) except OSError as e: if e.errno != errno.EXDEV: logging.error(("rename %s from distfiles to " "recycle failed: %s") % (self.distfile, e)) else: self.returncode = os.EX_OK self._async_wait() return self._start_task( FileCopier(src_path=distfile_path, dest_path=recycle_path, background=False), self._recycle_copier_exit) return success = True if self.config.options.dry_run: logging.info(("dry-run: delete '%s' from " "distfiles") % self.distfile) else: logging.debug(("delete '%s' from " "distfiles") % self.distfile) try: os.unlink(distfile_path) except OSError as e: if e.errno not in (errno.ENOENT, errno.ESTALE): logging.error("%s unlink failed in distfiles: %s" % (self.distfile, e)) success = False if success: self._success() self.returncode = os.EX_OK else: self.returncode = 1 self._async_wait() def _recycle_copier_exit(self, copier): self._assert_current(copier) if self._was_cancelled(): self.wait() return success = True if copier.returncode == os.EX_OK: try: os.unlink(copier.src_path) except OSError as e: if e.errno not in (errno.ENOENT, errno.ESTALE): logging.error("%s unlink failed in distfiles: %s" % (self.distfile, e)) success = False else: logging.error(("%s copy from distfiles " "to recycle failed: %s") % (self.distfile, e)) success = False if success: self._success() self.returncode = os.EX_OK else: self.returncode = 1 self._current_task = None self.wait() def _success(self): cpv = "unknown" if self.config.distfiles_db is not None: cpv = self.config.distfiles_db.get(self.distfile, cpv) self.config.delete_count += 1 self.config.log_success("%s\t%s\tremoved" % (cpv, self.distfile)) if self.config.distfiles_db is not None: try: del self.config.distfiles_db[self.distfile] except KeyError: pass else: logging.debug(("drop '%s' from " "distfiles db") % self.distfile) if self.config.deletion_db is not None: try: del self.config.deletion_db[self.distfile] except KeyError: pass else: logging.debug(("drop '%s' from " "deletion db") % self.distfile)