def load(self, select_prefix=None): """ Load the actual configuration. We put this outside the ctor so we can reload on the same object. In that case, anything unsaved is reset! """ ## Get command line args: parser = argparse.ArgumentParser(add_help=False) self.setup_parser(parser) args = parser.parse_known_args()[0] cfg_files = [] ## Set verbosity level: verb_offset = args.verbose - args.quiet verb_level = pb_logging.default_log_level - 10 * verb_offset if verb_level < pb_logging.OBNOXIOUS: verb_level = pb_logging.OBNOXIOUS pb_logging.logger.setLevel(verb_level) self.yes = args.yes ## Set up logger: self.log = pb_logging.logger.getChild("ConfigManager") ## Setup cfg_cascade: # self.cfg_cascade is a list of dicts. The higher the index, # the more important the dict. # Zeroth layer: The default values. self.cfg_cascade = [{k: v[0] for k, v in iteritems(self.defaults)},] # Global defaults global_cfg = os.path.join(self.global_base_dir, self.cfg_file_name) if self._append_cfg_from_file(global_cfg): cfg_files.insert(0, global_cfg) # Home directory: self.local_cfg_dir = self.get_pybombs_dir() if not os.path.isdir(self.local_cfg_dir): try: self.log.debug("Creating local config dir {0}".format(self.local_cfg_dir)) os.mkdir(self.local_cfg_dir) except (IOError, OSError): self.log.debug("Failed.") self.local_cfg = os.path.join(self.local_cfg_dir, self.cfg_file_name) if self._append_cfg_from_file(self.local_cfg): cfg_files.insert(0, self.local_cfg) # Current prefix (don't know that yet -- so skip for now) self.cfg_cascade.append({}) # Config file specified on command line: if args.config_file is not None: self._append_cfg_from_file(npath(args.config_file)) cfg_files.insert(0, npath(args.config_file)) else: self.cfg_cascade.append({}) # Config args specified on command line: cmd_line_opts = {} for opt in args.config: k, v = opt.split('=', 1) cmd_line_opts[k] = v self.cfg_cascade.append(cmd_line_opts) # Append an empty one. This is what we use when set() is called # to change settings at runtime. self.cfg_cascade.append({}) # After this, no more dicts should be appended to cfg_cascade. assert len(self.cfg_cascade) == self.LAYER_VOLATILE + 1 # Find recipe templates: self._template_dir = os.path.join(self.module_dir, 'templates') self.log.debug("Template directory: {0}".format(self._template_dir)) ## Init prefix: self._prefix_info = PrefixInfo(args, cfg_files, select_prefix) # Add the prefix config file (if it exists) prefix_config = self._prefix_info.cfg_file if prefix_config is not None and os.path.exists(prefix_config): cfg_files.insert(0, prefix_config) self._append_cfg_from_file(prefix_config, self.LAYER_PREFIX) ## Init recipe-lists: # Go through cfg files, then env variable, then command line args self._recipe_locations = [] self._named_recipe_dirs = {} self._named_recipe_sources = {} self._named_recipe_cfg_files = {} # From command line: for r_loc in args.recipes: if r_loc: self._recipe_locations.append(npath(r_loc)) # From environment variable: if len(os.environ.get("PYBOMBS_RECIPE_DIR", "").strip()): self._recipe_locations += [ npath(x) \ for x in os.environ.get("PYBOMBS_RECIPE_DIR").split(os.pathsep) \ if len(x.strip()) ] # From prefix info: if self._prefix_info.recipe_dir is not None: self._recipe_locations.append(self._prefix_info.recipe_dir) # From config files (from here, recipe locations are named): for cfg_file in cfg_files: recipe_locations = PBConfigFile(cfg_file).get('recipes') for name, uri in reversed(recipe_locations.items()): local_recipe_dir = self.resolve_recipe_uri( uri, name, os.path.join(os.path.split(cfg_file)[0], 'recipes') ) self._recipe_locations.append(local_recipe_dir) self._named_recipe_dirs[name] = local_recipe_dir self._named_recipe_sources[name] = uri self._named_recipe_cfg_files[name] = cfg_file # Internal recipe list: self._recipe_locations.append(os.path.join(self.module_dir, 'recipes')) self.log.debug("Full list of recipe locations: {0}".format(self._recipe_locations)) self.log.debug("Named recipe locations: {0}".format(self._named_recipe_sources))
def load(self, select_prefix=None): """ Load the actual configuration. We put this outside the ctor so we can reload on the same object. In that case, anything unsaved is reset! """ ## Get command line args: parser = argparse.ArgumentParser(add_help=False) self.setup_parser(parser) args = parser.parse_known_args()[0] cfg_files = [] ## Set verbosity level: verb_offset = args.verbose - args.quiet verb_level = pb_logging.default_log_level - 10 * verb_offset if verb_level < pb_logging.TRACE: verb_level = pb_logging.TRACE pb_logging.logger.setLevel(verb_level) self.yes = args.yes ## Set up logger: self.log = pb_logging.logger.getChild("ConfigManager") ## Setup cfg_cascade: # self.cfg_cascade is a list of dicts. The higher the index, # the more important the dict. # Zeroth layer: The default values. self.cfg_cascade = [{k: v[0] for k, v in iteritems(self.defaults)},] # Global defaults global_cfg = os.path.join(self.global_base_dir, self.cfg_file_name) if self._append_cfg_from_file(global_cfg): cfg_files.insert(0, global_cfg) # Home directory: self.local_cfg_dir = self.get_pybombs_dir() if not os.path.isdir(self.local_cfg_dir): try: self.log.debug("Creating local config dir {0}".format(self.local_cfg_dir)) os.mkdir(self.local_cfg_dir) except (IOError, OSError): self.log.debug("Failed.") self.local_cfg = os.path.join(self.local_cfg_dir, self.cfg_file_name) if self._append_cfg_from_file(self.local_cfg): cfg_files.insert(0, self.local_cfg) # Current prefix (don't know that yet -- so skip for now) self.cfg_cascade.append({}) # Config file specified on command line: if args.config_file is not None: self._append_cfg_from_file(npath(args.config_file)) cfg_files.insert(0, npath(args.config_file)) else: self.cfg_cascade.append({}) # Config args specified on command line: cmd_line_opts = {} for opt in args.config: k, v = opt.split('=', 1) cmd_line_opts[k] = v self.cfg_cascade.append(cmd_line_opts) # Append an empty one. This is what we use when set() is called # to change settings at runtime. self.cfg_cascade.append({}) # After this, no more dicts should be appended to cfg_cascade. assert len(self.cfg_cascade) == self.LAYER_VOLATILE + 1 # Find recipe templates: self._template_dir = os.path.join(self.module_dir, 'templates') self.log.debug("Template directory: {0}".format(self._template_dir)) ## Init prefix: self._prefix_info = PrefixInfo(args, cfg_files, select_prefix) self._config_reference = 'prefix' # Add the prefix config file (if it exists) prefix_config = self._prefix_info.cfg_file if prefix_config is not None and os.path.exists(prefix_config): cfg_files.insert(0, prefix_config) self._append_cfg_from_file(prefix_config, self.LAYER_PREFIX) ## Init recipe-lists: # Go through cfg files, then env variable, then command line args self._recipe_locations = [] self._named_recipe_dirs = {} self._named_recipe_sources = {} self._named_recipe_cfg_files = {} # From command line: for r_loc in args.recipes: if r_loc: self._recipe_locations.append(npath(r_loc)) # From environment variable: if len(os.environ.get("PYBOMBS_RECIPE_DIR", "").strip()): self._recipe_locations += [ npath(x) \ for x in os.environ.get("PYBOMBS_RECIPE_DIR").split(os.pathsep) \ if len(x.strip()) ] # From prefix info: if self._prefix_info.recipe_dir is not None: self._recipe_locations.append(self._prefix_info.recipe_dir) # From config files (from here, recipe locations are named): for cfg_file in cfg_files: recipe_locations = PBConfigFile(cfg_file).get('recipes') for name, uri in reversed(recipe_locations.items()): local_recipe_dir = self.resolve_recipe_uri( uri, name, os.path.join(os.path.split(cfg_file)[0], 'recipes') ) self._recipe_locations.append(local_recipe_dir) self._named_recipe_dirs[name] = local_recipe_dir self._named_recipe_sources[name] = uri self._named_recipe_cfg_files[name] = cfg_file # Internal recipe list: self._recipe_locations.append(os.path.join(self.module_dir, 'recipes')) self.log.debug("Full list of recipe locations: {0}".format(self._recipe_locations)) self.log.debug("Named recipe locations: {0}".format(self._named_recipe_sources)) # Detect Python version of the prefix (this is *not* necessarily # the Python version that is used for executing this script! The # prefix could be, for example, a virtualenv with its custom Python # version.) self._detect_python_version() self.log.info("Prefix Python version is: {}" .format(self.get('python_ver')))