def _parse(paths, prepos, local_config, default_opts): """Parse files in paths to load config""" parser = SafeConfigParser(defaults=default_opts) recursive_paths = [] for p in paths: if isinstance(p, basestring): recursive_paths.extend(_recursive_file_list(p)) else: recursive_paths.append(p) read_configs(parser, recursive_paths) prepos['DEFAULT'] = RepoConfig("DEFAULT", parser.defaults(), local_config=local_config) for sname in parser.sections(): optdict = {} for oname in parser.options(sname): optdict[oname] = parser.get(sname, oname) repo = RepoConfig(sname, optdict, local_config=local_config) for o in portage.sync.module_specific_options(repo): if parser.has_option(sname, o): repo.set_module_specific_opt(o, parser.get(sname, o)) # Perform repos.conf sync variable validation portage.sync.validate_config(repo, logging) # For backward compatibility with locations set via PORTDIR and # PORTDIR_OVERLAY, delay validation of the location and repo.name # until after PORTDIR and PORTDIR_OVERLAY have been processed. prepos[sname] = repo
def __init__(self, settings, logger): self.settings = settings self.logger = logger # Similar to emerge, sync needs a default umask so that created # files have sane permissions. os.umask(0o22) self.module_controller = portage.sync.module_controller self.module_names = self.module_controller.module_names self.hooks = {} for _dir in ["repo.postsync.d", "postsync.d"]: postsync_dir = os.path.join(self.settings["PORTAGE_CONFIGROOT"], portage.USER_CONFIG_PATH, _dir) hooks = OrderedDict() for filepath in util._recursive_file_list(postsync_dir): name = filepath.split(postsync_dir)[1].lstrip(os.sep) if os.access(filepath, os.X_OK): hooks[filepath] = name else: writemsg_level(" %s %s hook: '%s' is not executable\n" % ( warn("*"), _dir, _unicode_decode(name), ), level=logging.WARN, noiselevel=2) self.hooks[_dir] = hooks
def _parse(paths, defaults): parser = SafeConfigParser(defaults=defaults) recursive_paths = [] for p in paths: if isinstance(p, str): recursive_paths.extend(_recursive_file_list(p)) else: recursive_paths.append(p) read_configs(parser, recursive_paths) return parser
def get_hooks_from_dir(rel_directory, prefix="/"): directory = os.path.join(prefix, portage.USER_CONFIG_PATH, rel_directory) hooks = OrderedDict() for filepath in _recursive_file_list(directory): name = filepath.split(directory)[1].lstrip(portage.os.sep) if portage.os.access(filepath, portage.os.X_OK): hooks[filepath] = name else: writemsg_level( " %s %s hook: '%s' is not executable\n" % ( warn("*"), directory, portage._unicode_decode(name), ), level=logging.WARN, noiselevel=2, ) return hooks
def __init__(self, settings, logger): self.settings = settings self.logger = logger # Similar to emerge, sync needs a default umask so that created # files have sane permissions. os.umask(0o22) self.module_controller = portage.sync.module_controller self.module_names = self.module_controller.module_names self.hooks = {} for _dir in ["repo.postsync.d", "postsync.d"]: postsync_dir = os.path.join(self.settings["PORTAGE_CONFIGROOT"], portage.USER_CONFIG_PATH, _dir) hooks = OrderedDict() for filepath in util._recursive_file_list(postsync_dir): name = filepath.split(postsync_dir)[1].lstrip(os.sep) if os.access(filepath, os.X_OK): hooks[filepath] = name else: writemsg_level(" %s %s hook: '%s' is not executable\n" % (warn("*"), _dir, _unicode_decode(name),), level=logging.WARN, noiselevel=2) self.hooks[_dir] = hooks
def emirrordist_main(args): # The calling environment is ignored, so the program is # completely controlled by commandline arguments. env = {} if not sys.stdout.isatty(): portage.output.nocolor() env['NOCOLOR'] = 'true' parser, options, args = parse_args(args) if options.version: sys.stdout.write("Portage %s\n" % portage.VERSION) return os.EX_OK config_root = options.config_root if options.repositories_configuration is not None: env['PORTAGE_REPOSITORIES'] = options.repositories_configuration settings = portage.config(config_root=config_root, local_config=False, env=env) default_opts = None if not options.ignore_default_opts: default_opts = settings.get('EMIRRORDIST_DEFAULT_OPTS', '').split() if default_opts: parser, options, args = parse_args(default_opts + args) settings = portage.config(config_root=config_root, local_config=False, env=env) if options.repo is None: if len(settings.repositories.prepos) == 2: for repo in settings.repositories: if repo.name != "DEFAULT": options.repo = repo.name break if options.repo is None: parser.error("--repo option is required") repo_path = settings.repositories.treemap.get(options.repo) if repo_path is None: parser.error("Unable to locate repository named '%s'" % (options.repo,)) if options.jobs is not None: options.jobs = int(options.jobs) if options.load_average is not None: options.load_average = float(options.load_average) if options.failure_log is not None: options.failure_log = normalize_path( os.path.abspath(options.failure_log)) parent_dir = os.path.dirname(options.failure_log) if not (os.path.isdir(parent_dir) and os.access(parent_dir, os.W_OK|os.X_OK)): parser.error(("--failure-log '%s' parent is not a " "writable directory") % options.failure_log) if options.success_log is not None: options.success_log = normalize_path( os.path.abspath(options.success_log)) parent_dir = os.path.dirname(options.success_log) if not (os.path.isdir(parent_dir) and os.access(parent_dir, os.W_OK|os.X_OK)): parser.error(("--success-log '%s' parent is not a " "writable directory") % options.success_log) if options.scheduled_deletion_log is not None: options.scheduled_deletion_log = normalize_path( os.path.abspath(options.scheduled_deletion_log)) parent_dir = os.path.dirname(options.scheduled_deletion_log) if not (os.path.isdir(parent_dir) and os.access(parent_dir, os.W_OK|os.X_OK)): parser.error(("--scheduled-deletion-log '%s' parent is not a " "writable directory") % options.scheduled_deletion_log) if options.deletion_db is None: parser.error("--scheduled-deletion-log requires --deletion-db") if options.deletion_delay is not None: options.deletion_delay = long(options.deletion_delay) if options.deletion_db is None: parser.error("--deletion-delay requires --deletion-db") if options.deletion_db is not None: if options.deletion_delay is None: parser.error("--deletion-db requires --deletion-delay") options.deletion_db = normalize_path( os.path.abspath(options.deletion_db)) if options.temp_dir is not None: options.temp_dir = normalize_path( os.path.abspath(options.temp_dir)) if not (os.path.isdir(options.temp_dir) and os.access(options.temp_dir, os.W_OK|os.X_OK)): parser.error(("--temp-dir '%s' is not a " "writable directory") % options.temp_dir) if options.distfiles is not None: options.distfiles = normalize_path( os.path.abspath(options.distfiles)) if not (os.path.isdir(options.distfiles) and os.access(options.distfiles, os.W_OK|os.X_OK)): parser.error(("--distfiles '%s' is not a " "writable directory") % options.distfiles) else: parser.error("missing required --distfiles parameter") if options.mirror_overrides is not None: options.mirror_overrides = normalize_path( os.path.abspath(options.mirror_overrides)) if not (os.access(options.mirror_overrides, os.R_OK) and os.path.isfile(options.mirror_overrides)): parser.error( "--mirror-overrides-file '%s' is not a readable file" % options.mirror_overrides) if options.distfiles_local is not None: options.distfiles_local = normalize_path( os.path.abspath(options.distfiles_local)) if not (os.path.isdir(options.distfiles_local) and os.access(options.distfiles_local, os.W_OK|os.X_OK)): parser.error(("--distfiles-local '%s' is not a " "writable directory") % options.distfiles_local) if options.distfiles_db is not None: options.distfiles_db = normalize_path( os.path.abspath(options.distfiles_db)) if options.tries is not None: options.tries = int(options.tries) if options.recycle_dir is not None: options.recycle_dir = normalize_path( os.path.abspath(options.recycle_dir)) if not (os.path.isdir(options.recycle_dir) and os.access(options.recycle_dir, os.W_OK|os.X_OK)): parser.error(("--recycle-dir '%s' is not a " "writable directory") % options.recycle_dir) if options.recycle_db is not None: if options.recycle_dir is None: parser.error("--recycle-db requires " "--recycle-dir to be specified") options.recycle_db = normalize_path( os.path.abspath(options.recycle_db)) if options.recycle_deletion_delay is not None: options.recycle_deletion_delay = \ long(options.recycle_deletion_delay) if options.fetch_log_dir is not None: options.fetch_log_dir = normalize_path( os.path.abspath(options.fetch_log_dir)) if not (os.path.isdir(options.fetch_log_dir) and os.access(options.fetch_log_dir, os.W_OK|os.X_OK)): parser.error(("--fetch-log-dir '%s' is not a " "writable directory") % options.fetch_log_dir) if options.whitelist_from: normalized_paths = [] for x in options.whitelist_from: path = normalize_path(os.path.abspath(x)) if not os.access(path, os.R_OK): parser.error("--whitelist-from '%s' is not readable" % x) if os.path.isfile(path): normalized_paths.append(path) elif os.path.isdir(path): for file in _recursive_file_list(path): if not os.access(file, os.R_OK): parser.error("--whitelist-from '%s' directory contains not readable file '%s'" % (x, file)) normalized_paths.append(file) else: parser.error("--whitelist-from '%s' is not a regular file or a directory" % x) options.whitelist_from = normalized_paths if options.strict_manifests is not None: if options.strict_manifests == "y": settings.features.add("strict") else: settings.features.discard("strict") settings.lock() portdb = portage.portdbapi(mysettings=settings) # Limit ebuilds to the specified repo. portdb.porttrees = [repo_path] portage.util.initialize_logger() if options.verbose > 0: l = logging.getLogger() l.setLevel(l.getEffectiveLevel() - 10 * options.verbose) with Config(options, portdb, SchedulerInterface(global_event_loop())) as config: if not options.mirror: parser.error('No action specified') returncode = os.EX_OK if options.mirror: signum = run_main_scheduler(MirrorDistTask(config)) if signum is not None: sys.exit(128 + signum) return returncode
def _parse(paths, prepos, ignored_map, ignored_location_map, local_config, portdir): """Parse files in paths to load config""" parser = SafeConfigParser() # use read_file/readfp in order to control decoding of unicode try: # Python >=3.2 read_file = parser.read_file source_kwarg = 'source' except AttributeError: read_file = parser.readfp source_kwarg = 'filename' recursive_paths = [] for p in paths: if isinstance(p, basestring): recursive_paths.extend(_recursive_file_list(p)) else: recursive_paths.append(p) for p in recursive_paths: if isinstance(p, basestring): f = None try: f = io.open(_unicode_encode(p, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['repo.content'], errors='replace') except EnvironmentError: pass else: # The 'source' keyword argument is needed since otherwise # ConfigParser in Python <3.3.3 may throw a TypeError # because it assumes that f.name is a native string rather # than binary when constructing error messages. kwargs = {source_kwarg: p} read_file(f, **portage._native_kwargs(kwargs)) finally: if f is not None: f.close() elif isinstance(p, io.StringIO): kwargs = {source_kwarg: "<io.StringIO>"} read_file(p, **portage._native_kwargs(kwargs)) else: raise TypeError("Unsupported type %r of element %r of 'paths' argument" % (type(p), p)) prepos['DEFAULT'] = RepoConfig("DEFAULT", parser.defaults(), local_config=local_config) for sname in parser.sections(): optdict = {} for oname in parser.options(sname): optdict[oname] = parser.get(sname, oname) repo = RepoConfig(sname, optdict, local_config=local_config) # Perform repos.conf sync variable validation portage.sync.validate_config(repo, logging) # For backward compatibility with locations set via PORTDIR and # PORTDIR_OVERLAY, delay validation of the location and repo.name # until after PORTDIR and PORTDIR_OVERLAY have been processed. prepos[sname] = repo
def _parse(paths, prepos, ignored_map, ignored_location_map, local_config, portdir): """Parse files in paths to load config""" parser = SafeConfigParser() # use read_file/readfp in order to control decoding of unicode try: # Python >=3.2 read_file = parser.read_file source_kwarg = 'source' except AttributeError: read_file = parser.readfp source_kwarg = 'filename' recursive_paths = [] for p in paths: if isinstance(p, basestring): recursive_paths.extend(_recursive_file_list(p)) else: recursive_paths.append(p) for p in recursive_paths: if isinstance(p, basestring): f = None try: f = io.open(_unicode_encode(p, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['repo.content'], errors='replace') except EnvironmentError: pass else: # The 'source' keyword argument is needed since otherwise # ConfigParser in Python <3.3.3 may throw a TypeError # because it assumes that f.name is a native string rather # than binary when constructing error messages. kwargs = {source_kwarg: p} read_file(f, **portage._native_kwargs(kwargs)) finally: if f is not None: f.close() elif isinstance(p, io.StringIO): kwargs = {source_kwarg: "<io.StringIO>"} read_file(p, **portage._native_kwargs(kwargs)) else: raise TypeError("Unsupported type %r of element %r of 'paths' argument" % (type(p), p)) prepos['DEFAULT'] = RepoConfig("DEFAULT", parser.defaults(), local_config=local_config) for sname in parser.sections(): optdict = {} for oname in parser.options(sname): optdict[oname] = parser.get(sname, oname) repo = RepoConfig(sname, optdict, local_config=local_config) if repo.sync_type is not None and repo.sync_uri is None: writemsg_level("!!! %s\n" % _("Repository '%s' has sync-type attribute, but is missing sync-uri attribute") % sname, level=logging.ERROR, noiselevel=-1) continue if repo.sync_uri is not None and repo.sync_type is None: writemsg_level("!!! %s\n" % _("Repository '%s' has sync-uri attribute, but is missing sync-type attribute") % sname, level=logging.ERROR, noiselevel=-1) continue if repo.sync_type not in (None, "cvs", "git", "rsync"): writemsg_level("!!! %s\n" % _("Repository '%s' has sync-type attribute set to unsupported value: '%s'") % (sname, repo.sync_type), level=logging.ERROR, noiselevel=-1) continue if repo.sync_type == "cvs" and repo.sync_cvs_repo is None: writemsg_level("!!! %s\n" % _("Repository '%s' has sync-type=cvs, but is missing sync-cvs-repo attribute") % sname, level=logging.ERROR, noiselevel=-1) continue # For backward compatibility with locations set via PORTDIR and # PORTDIR_OVERLAY, delay validation of the location and repo.name # until after PORTDIR and PORTDIR_OVERLAY have been processed. prepos[sname] = repo
def _parse(paths, prepos, ignored_map, ignored_location_map, local_config, portdir, default_opts): """Parse files in paths to load config""" parser = SafeConfigParser(defaults=default_opts) # use read_file/readfp in order to control decoding of unicode try: # Python >=3.2 read_file = parser.read_file source_kwarg = 'source' except AttributeError: read_file = parser.readfp source_kwarg = 'filename' recursive_paths = [] for p in paths: if isinstance(p, basestring): recursive_paths.extend(_recursive_file_list(p)) else: recursive_paths.append(p) for p in recursive_paths: if isinstance(p, basestring): f = None try: f = io.open(_unicode_encode(p, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['repo.content'], errors='replace') except EnvironmentError: pass else: # The 'source' keyword argument is needed since otherwise # ConfigParser in Python <3.3.3 may throw a TypeError # because it assumes that f.name is a native string rather # than binary when constructing error messages. kwargs = {source_kwarg: p} read_file(f, **portage._native_kwargs(kwargs)) finally: if f is not None: f.close() elif isinstance(p, io.StringIO): kwargs = {source_kwarg: "<io.StringIO>"} read_file(p, **portage._native_kwargs(kwargs)) else: raise TypeError("Unsupported type %r of element %r of 'paths' argument" % (type(p), p)) prepos['DEFAULT'] = RepoConfig("DEFAULT", parser.defaults(), local_config=local_config) for sname in parser.sections(): optdict = {} for oname in parser.options(sname): optdict[oname] = parser.get(sname, oname) repo = RepoConfig(sname, optdict, local_config=local_config) for o in portage.sync.module_specific_options(repo): repo.set_module_specific_opt(o, parser.get(sname, o)) # Perform repos.conf sync variable validation portage.sync.validate_config(repo, logging) # For backward compatibility with locations set via PORTDIR and # PORTDIR_OVERLAY, delay validation of the location and repo.name # until after PORTDIR and PORTDIR_OVERLAY have been processed. prepos[sname] = repo
def _parse(paths, prepos, ignored_map, ignored_location_map, local_config, portdir): """Parse files in paths to load config""" parser = SafeConfigParser() # use read_file/readfp in order to control decoding of unicode try: # Python >=3.2 read_file = parser.read_file source_kwarg = 'source' except AttributeError: read_file = parser.readfp source_kwarg = 'filename' recursive_paths = [] for p in paths: if isinstance(p, basestring): recursive_paths.extend(_recursive_file_list(p)) else: recursive_paths.append(p) for p in recursive_paths: if isinstance(p, basestring): f = None try: f = io.open(_unicode_encode(p, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['repo.content'], errors='replace') except EnvironmentError: pass else: # The 'source' keyword argument is needed since otherwise # ConfigParser in Python <3.3.3 may throw a TypeError # because it assumes that f.name is a native string rather # than binary when constructing error messages. kwargs = {source_kwarg: p} read_file(f, **portage._native_kwargs(kwargs)) finally: if f is not None: f.close() elif isinstance(p, io.StringIO): kwargs = {source_kwarg: "<io.StringIO>"} read_file(p, **portage._native_kwargs(kwargs)) else: raise TypeError( "Unsupported type %r of element %r of 'paths' argument" % (type(p), p)) prepos['DEFAULT'] = RepoConfig("DEFAULT", parser.defaults(), local_config=local_config) for sname in parser.sections(): optdict = {} for oname in parser.options(sname): optdict[oname] = parser.get(sname, oname) repo = RepoConfig(sname, optdict, local_config=local_config) if repo.sync_type is not None and repo.sync_uri is None: writemsg_level("!!! %s\n" % _( "Repository '%s' has sync-type attribute, but is missing sync-uri attribute" ) % sname, level=logging.ERROR, noiselevel=-1) continue if repo.sync_uri is not None and repo.sync_type is None: writemsg_level("!!! %s\n" % _( "Repository '%s' has sync-uri attribute, but is missing sync-type attribute" ) % sname, level=logging.ERROR, noiselevel=-1) continue if repo.sync_type not in (None, "cvs", "git", "rsync"): writemsg_level("!!! %s\n" % _( "Repository '%s' has sync-type attribute set to unsupported value: '%s'" ) % (sname, repo.sync_type), level=logging.ERROR, noiselevel=-1) continue if repo.sync_type == "cvs" and repo.sync_cvs_repo is None: writemsg_level("!!! %s\n" % _( "Repository '%s' has sync-type=cvs, but is missing sync-cvs-repo attribute" ) % sname, level=logging.ERROR, noiselevel=-1) continue # For backward compatibility with locations set via PORTDIR and # PORTDIR_OVERLAY, delay validation of the location and repo.name # until after PORTDIR and PORTDIR_OVERLAY have been processed. prepos[sname] = repo
def emirrordist_main(args): # The calling environment is ignored, so the program is # completely controlled by commandline arguments. env = {} if not sys.stdout.isatty(): portage.output.nocolor() env['NOCOLOR'] = 'true' parser, options, args = parse_args(args) if options.version: sys.stdout.write("Portage[mgorny] %s\n" % portage.VERSION) return os.EX_OK config_root = options.config_root if options.repositories_configuration is not None: env['PORTAGE_REPOSITORIES'] = options.repositories_configuration settings = portage.config(config_root=config_root, local_config=False, env=env) default_opts = None if not options.ignore_default_opts: default_opts = settings.get('EMIRRORDIST_DEFAULT_OPTS', '').split() if default_opts: parser, options, args = parse_args(default_opts + args) settings = portage.config(config_root=config_root, local_config=False, env=env) if options.repo is None: if len(settings.repositories.prepos) == 2: for repo in settings.repositories: if repo.name != "DEFAULT": options.repo = repo.name break if options.repo is None: parser.error("--repo option is required") repo_path = settings.repositories.treemap.get(options.repo) if repo_path is None: parser.error("Unable to locate repository named '%s'" % (options.repo,)) if options.jobs is not None: options.jobs = int(options.jobs) if options.load_average is not None: options.load_average = float(options.load_average) if options.failure_log is not None: options.failure_log = normalize_path( os.path.abspath(options.failure_log)) parent_dir = os.path.dirname(options.failure_log) if not (os.path.isdir(parent_dir) and os.access(parent_dir, os.W_OK|os.X_OK)): parser.error(("--failure-log '%s' parent is not a " "writable directory") % options.failure_log) if options.success_log is not None: options.success_log = normalize_path( os.path.abspath(options.success_log)) parent_dir = os.path.dirname(options.success_log) if not (os.path.isdir(parent_dir) and os.access(parent_dir, os.W_OK|os.X_OK)): parser.error(("--success-log '%s' parent is not a " "writable directory") % options.success_log) if options.scheduled_deletion_log is not None: options.scheduled_deletion_log = normalize_path( os.path.abspath(options.scheduled_deletion_log)) parent_dir = os.path.dirname(options.scheduled_deletion_log) if not (os.path.isdir(parent_dir) and os.access(parent_dir, os.W_OK|os.X_OK)): parser.error(("--scheduled-deletion-log '%s' parent is not a " "writable directory") % options.scheduled_deletion_log) if options.deletion_db is None: parser.error("--scheduled-deletion-log requires --deletion-db") if options.deletion_delay is not None: options.deletion_delay = long(options.deletion_delay) if options.deletion_db is None: parser.error("--deletion-delay requires --deletion-db") if options.deletion_db is not None: if options.deletion_delay is None: parser.error("--deletion-db requires --deletion-delay") options.deletion_db = normalize_path( os.path.abspath(options.deletion_db)) if options.temp_dir is not None: options.temp_dir = normalize_path( os.path.abspath(options.temp_dir)) if not (os.path.isdir(options.temp_dir) and os.access(options.temp_dir, os.W_OK|os.X_OK)): parser.error(("--temp-dir '%s' is not a " "writable directory") % options.temp_dir) if options.distfiles is not None: options.distfiles = normalize_path( os.path.abspath(options.distfiles)) if not (os.path.isdir(options.distfiles) and os.access(options.distfiles, os.W_OK|os.X_OK)): parser.error(("--distfiles '%s' is not a " "writable directory") % options.distfiles) else: parser.error("missing required --distfiles parameter") if options.mirror_overrides is not None: options.mirror_overrides = normalize_path( os.path.abspath(options.mirror_overrides)) if not (os.access(options.mirror_overrides, os.R_OK) and os.path.isfile(options.mirror_overrides)): parser.error( "--mirror-overrides-file '%s' is not a readable file" % options.mirror_overrides) if options.distfiles_local is not None: options.distfiles_local = normalize_path( os.path.abspath(options.distfiles_local)) if not (os.path.isdir(options.distfiles_local) and os.access(options.distfiles_local, os.W_OK|os.X_OK)): parser.error(("--distfiles-local '%s' is not a " "writable directory") % options.distfiles_local) if options.distfiles_db is not None: options.distfiles_db = normalize_path( os.path.abspath(options.distfiles_db)) if options.tries is not None: options.tries = int(options.tries) if options.recycle_dir is not None: options.recycle_dir = normalize_path( os.path.abspath(options.recycle_dir)) if not (os.path.isdir(options.recycle_dir) and os.access(options.recycle_dir, os.W_OK|os.X_OK)): parser.error(("--recycle-dir '%s' is not a " "writable directory") % options.recycle_dir) if options.recycle_db is not None: if options.recycle_dir is None: parser.error("--recycle-db requires " "--recycle-dir to be specified") options.recycle_db = normalize_path( os.path.abspath(options.recycle_db)) if options.recycle_deletion_delay is not None: options.recycle_deletion_delay = \ long(options.recycle_deletion_delay) if options.fetch_log_dir is not None: options.fetch_log_dir = normalize_path( os.path.abspath(options.fetch_log_dir)) if not (os.path.isdir(options.fetch_log_dir) and os.access(options.fetch_log_dir, os.W_OK|os.X_OK)): parser.error(("--fetch-log-dir '%s' is not a " "writable directory") % options.fetch_log_dir) if options.whitelist_from: normalized_paths = [] for x in options.whitelist_from: path = normalize_path(os.path.abspath(x)) if not os.access(path, os.R_OK): parser.error("--whitelist-from '%s' is not readable" % x) if os.path.isfile(path): normalized_paths.append(path) elif os.path.isdir(path): for file in _recursive_file_list(path): if not os.access(file, os.R_OK): parser.error("--whitelist-from '%s' directory contains not readable file '%s'" % (x, file)) normalized_paths.append(file) else: parser.error("--whitelist-from '%s' is not a regular file or a directory" % x) options.whitelist_from = normalized_paths if options.strict_manifests is not None: if options.strict_manifests == "y": settings.features.add("strict") else: settings.features.discard("strict") settings.lock() portdb = portage.portdbapi(mysettings=settings) # Limit ebuilds to the specified repo. portdb.porttrees = [repo_path] portage.util.initialize_logger() if options.verbose > 0: l = logging.getLogger() l.setLevel(l.getEffectiveLevel() - 10 * options.verbose) with Config(options, portdb, SchedulerInterface(global_event_loop())) as config: if not options.mirror: parser.error('No action specified') returncode = os.EX_OK if options.mirror: signum = run_main_scheduler(MirrorDistTask(config)) if signum is not None: sys.exit(128 + signum) return returncode