blob: 574a83559d065c014c37ea6af7c1179c5fe8fd92 [file] [log] [blame]
# Copyright 2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import copy
import io
import logging
import shelve
import sys
import time
import portage
from portage import os
from portage.util import grabdict, grablines
from portage.util._ShelveUnicodeWrapper import ShelveUnicodeWrapper
class Config(object):
def __init__(self, options, portdb, event_loop):
self.options = options
self.portdb = portdb
self.event_loop = event_loop
self.added_byte_count = 0
self.added_file_count = 0
self.scheduled_deletion_count = 0
self.delete_count = 0
self.file_owners = {}
self.file_failures = {}
self.start_time = time.time()
self._open_files = []
self.log_success = self._open_log('success', options.success_log, 'a')
self.log_failure = self._open_log('failure', options.failure_log, 'a')
self.distfiles = None
if options.distfiles is not None:
self.distfiles = options.distfiles
self.mirrors = copy.copy(portdb.settings.thirdpartymirrors())
if options.mirror_overrides is not None:
if options.mirror_skip is not None:
for x in options.mirror_skip.split(","):
self.mirrors[x] = []
self.whitelist = None
if options.whitelist_from is not None:
self.whitelist = set()
for filename in options.whitelist_from:
for line in grablines(filename):
line = line.strip()
if line and not line.startswith("#"):
self.restrict_mirror_exemptions = None
if options.restrict_mirror_exemptions is not None:
self.restrict_mirror_exemptions = frozenset(
self.recycle_db = None
if options.recycle_db is not None:
self.recycle_db = self._open_shelve(
options.recycle_db, 'recycle')
self.distfiles_db = None
if options.distfiles_db is not None:
self.distfiles_db = self._open_shelve(
options.distfiles_db, 'distfiles')
self.deletion_db = None
if options.deletion_db is not None:
self.deletion_db = self._open_shelve(
options.deletion_db, 'deletion')
def _open_log(self, log_desc, log_path, mode):
if log_path is None or self.options.dry_run:
log_func =
line_format = "%s: %%s" % log_desc
add_newline = False
if log_path is not None:
logging.warning("dry-run: %s log "
"redirected to" % log_desc)
self._open_files.append(, mode=mode,
line_format = "%s\n"
log_func = self._open_files[-1].write
return self._LogFormatter(line_format, log_func)
class _LogFormatter(object):
__slots__ = ('_line_format', '_log_func')
def __init__(self, line_format, log_func):
self._line_format = line_format
self._log_func = log_func
def __call__(self, msg):
self._log_func(self._line_format % (msg,))
def _open_shelve(self, db_file, db_desc):
if self.options.dry_run:
open_flag = "r"
open_flag = "c"
if self.options.dry_run and not os.path.exists(db_file):
db = {}
db =, flag=open_flag)
except ImportError as e:
# ImportError has different attributes for python2 vs. python3
if (getattr(e, 'name', None) == 'bsddb' or
getattr(e, 'message', None) == 'No module named bsddb'):
from bsddb3 import dbshelve
db =, flags=open_flag)
if sys.hexversion < 0x3000000:
db = ShelveUnicodeWrapper(db)
if self.options.dry_run:
logging.warning("dry-run: %s db opened in readonly mode" % db_desc)
if not isinstance(db, dict):
volatile_db = dict((k, db[k]) for k in db)
db = volatile_db
return db
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
while self._open_files: