def _read_config(self): """read the config file""" self.conf = Cfg(self.confpath, self.profile, debug=self.debug) # transform the config settings to self attribute for k, v in self.conf.get_settings().items(): if self.debug: self.log.dbg('new setting: {}={}'.format(k, v)) setattr(self, k, v)
def _read_config(self): """read the config file""" self.conf = Cfg(self.confpath, self.profile, debug=self.debug, dry=self.dry) # transform the config settings to self attribute self._debug_dict('effective settings', self.conf.get_settings()) for k, v in self.conf.get_settings().items(): setattr(self, k, v)
class Options(AttrMonitor): def __init__(self, args=None): """constructor @args: argument dictionary (if None use sys) """ self.args = {} if not args: self.args = docopt(USAGE, version=VERSION) if args: self.args = args.copy() self.log = Logger() self.debug = self.args['--verbose'] or ENV_DEBUG in os.environ self.dry = self.args['--dry'] if ENV_NODEBUG in os.environ: # force disabling debugs self.debug = False self.profile = self.args['--profile'] self.confpath = self._get_config_path() if self.debug: self.log.dbg('version: {}'.format(VERSION)) self.log.dbg('command: {}'.format(' '.join(sys.argv))) self.log.dbg('config file: {}'.format(self.confpath)) self._read_config() self._apply_args() self._fill_attr() if ENV_NOBANNER not in os.environ \ and self.banner \ and not self.args['--no-banner']: self._header() self._debug_attr() # start monitoring for bad attribute self._set_attr_err = True def _get_config_path(self): """get the config path""" # cli provided if self.args['--cfg']: return os.path.expanduser(self.args['--cfg']) # environment variable provided if ENV_CONFIG in os.environ: return os.path.expanduser(os.environ[ENV_CONFIG]) # look in current directory if os.path.exists(CONFIG): return CONFIG # look in XDG_CONFIG_HOME if ENV_XDG in os.environ: cfg = os.path.expanduser(os.environ[ENV_XDG]) path = os.path.join(cfg, NAME, CONFIG) if os.path.exists(path): return path # look in ~/.config/dotdrop cfg = os.path.expanduser(HOMECFG) path = os.path.join(cfg, CONFIG) if os.path.exists(path): return path # look in /etc/xdg/dotdrop path = os.path.join(ETCXDGCFG, CONFIG) if os.path.exists(path): return path # look in /etc/dotdrop path = os.path.join(ETCCFG, CONFIG) if os.path.exists(path): return path return '' def _header(self): """display the header""" self.log.log(BANNER) self.log.log('') def _read_config(self): """read the config file""" self.conf = Cfg(self.confpath, self.profile, debug=self.debug, dry=self.dry) # transform the config settings to self attribute self._debug_dict('effective settings', self.conf.get_settings()) for k, v in self.conf.get_settings().items(): setattr(self, k, v) def _apply_args(self): """apply cli args as attribute""" # the commands self.cmd_profiles = self.args['profiles'] self.cmd_files = self.args['files'] self.cmd_install = self.args['install'] self.cmd_compare = self.args['compare'] self.cmd_import = self.args['import'] self.cmd_update = self.args['update'] self.cmd_detail = self.args['detail'] self.cmd_remove = self.args['remove'] # adapt attributes based on arguments self.safe = not self.args['--force'] # import link default value self.import_link = self.link_on_import if self.args['--link']: # overwrite default import link with cli switch link = self.args['--link'] if link not in OPT_LINK.keys(): self.log.err('bad option for --link: {}'.format(link)) sys.exit(USAGE) self.import_link = OPT_LINK[link] # "files" specifics self.files_templateonly = self.args['--template'] self.files_grepable = self.args['--grepable'] # "profiles" specifics self.profiles_grepable = self.args['--grepable'] # "install" specifics self.install_force_action = self.args['--force-actions'] self.install_temporary = self.args['--temp'] self.install_keys = self.args['<key>'] self.install_diff = not self.args['--nodiff'] self.install_showdiff = self.showdiff or self.args['--showdiff'] self.install_backup_suffix = BACKUP_SUFFIX self.install_default_actions_pre = [ a for a in self.default_actions if a.kind == Action.pre ] self.install_default_actions_post = [ a for a in self.default_actions if a.kind == Action.post ] self.install_ignore = self.instignore # "compare" specifics self.compare_focus = self.args['--file'] self.compare_ignore = self.args['--ignore'] self.compare_ignore.extend(self.cmpignore) self.compare_ignore.append('*{}'.format(self.install_backup_suffix)) self.compare_ignore = uniq_list(self.compare_ignore) # "import" specifics self.import_path = self.args['<path>'] self.import_as = self.args['--as'] # "update" specifics self.update_path = self.args['<path>'] self.update_iskey = self.args['--key'] self.update_ignore = self.args['--ignore'] self.update_ignore.extend(self.upignore) self.update_ignore.append('*{}'.format(self.install_backup_suffix)) self.update_ignore = uniq_list(self.update_ignore) self.update_showpatch = self.args['--show-patch'] # "detail" specifics self.detail_keys = self.args['<key>'] # "remove" specifics self.remove_path = self.args['<path>'] self.remove_iskey = self.args['--key'] def _fill_attr(self): """create attributes from conf""" # variables self.variables = self.conf.get_variables() # the dotfiles self.dotfiles = self.conf.get_dotfiles() # the profiles self.profiles = self.conf.get_profiles() def _debug_attr(self): """debug display all of this class attributes""" if not self.debug: return self.log.dbg('effective options:') for att in dir(self): if att.startswith('_'): continue val = getattr(self, att) if callable(val): continue if type(val) is list: self._debug_list('-> {}'.format(att), val) elif type(val) is dict: self._debug_dict('-> {}'.format(att), val) else: self.log.dbg('-> {}: {}'.format(att, val)) def _attr_set(self, attr): """error when some inexistent attr is set""" raise Exception('bad option: {}'.format(attr)) def _debug_list(self, title, elems): """pretty print list""" if not self.debug: return self.log.dbg('{}:'.format(title)) for e in elems: self.log.dbg('\t- {}'.format(e)) def _debug_dict(self, title, elems): """pretty print dict""" if not self.debug: return self.log.dbg('{}:'.format(title)) for k, v in elems.items(): if type(v) is list: self.log.dbg('\t- \"{}\":'.format(k)) for i in v: self.log.dbg('\t\t- {}'.format(i)) else: self.log.dbg('\t- \"{}\": {}'.format(k, v))
class Options(AttrMonitor): """dotdrop options manager""" def __init__(self, args=None): """constructor @args: argument dictionary (if None use sys) """ # attributes gotten from self.conf.get_settings() self.banner = None self.showdiff = None self.default_actions = [] self.instignore = None self.force_chmod = None self.cmpignore = None self.impignore = None self.upignore = None self.link_on_import = None self.chmod_on_import = None self.check_version = None self.clear_workdir = None self.key_prefix = None self.key_separator = None # args parsing self.args = {} if not args: self.args = docopt(USAGE, version=VERSION) if args: self.args = args.copy() self.debug = self.args['--verbose'] or ENV_DEBUG in os.environ self.log = Logger(debug=self.debug) self.dry = self.args['--dry'] if ENV_NODEBUG in os.environ: # force disabling debugs self.debug = False self.profile = self.args['--profile'] self.confpath = self._get_config_path() if not self.confpath: raise YamlException('no config file found') self.log.dbg('#################################################') self.log.dbg('#################### DOTDROP ####################') self.log.dbg('#################################################') self.log.dbg('version: {}'.format(VERSION)) self.log.dbg('command: {}'.format(' '.join(sys.argv))) self.log.dbg('config file: {}'.format(self.confpath)) self._read_config() self._apply_args() self._fill_attr() if ENV_NOBANNER not in os.environ \ and self.banner \ and not self.args['--no-banner']: self._header() self._debug_attr() # start monitoring for bad attribute self._set_attr_err = True @classmethod def _get_config_from_fs(cls): """get config from filesystem""" # look in ~/.config/dotdrop cfg = os.path.expanduser(HOMECFG) path = os.path.join(cfg, CONFIG) if os.path.exists(path): return path # look in /etc/xdg/dotdrop path = os.path.join(ETCXDGCFG, CONFIG) if os.path.exists(path): return path # look in /etc/dotdrop path = os.path.join(ETCCFG, CONFIG) if os.path.exists(path): return path return '' def _get_config_path(self): """get the config path""" # cli provided if self.args['--cfg']: return os.path.expanduser(self.args['--cfg']) # environment variable provided if ENV_CONFIG in os.environ: return os.path.expanduser(os.environ[ENV_CONFIG]) # look in current directory if os.path.exists(CONFIG): return CONFIG # look in XDG_CONFIG_HOME if ENV_XDG in os.environ: cfg = os.path.expanduser(os.environ[ENV_XDG]) path = os.path.join(cfg, NAME, CONFIG) if os.path.exists(path): return path return self._get_config_from_fs() def _header(self): """display the header""" self.log.log(BANNER) self.log.log('') def _read_config(self): """read the config file""" self.conf = Cfg(self.confpath, self.profile, debug=self.debug, dry=self.dry) # transform the config settings to self attribute settings = self.conf.get_settings() debug_dict('effective settings', settings, self.debug) for k, val in settings.items(): setattr(self, k, val) def _apply_args_files(self): """files specifics""" self.files_templateonly = self.args['--template'] self.files_grepable = self.args['--grepable'] def _apply_args_install(self): """install specifics""" self.install_force_action = self.args['--force-actions'] self.install_temporary = self.args['--temp'] self.install_keys = self.args['<key>'] self.install_diff = not self.args['--nodiff'] self.install_showdiff = self.showdiff or self.args['--showdiff'] self.install_backup_suffix = BACKUP_SUFFIX self.install_default_actions_pre = [a for a in self.default_actions if a.kind == Action.pre] self.install_default_actions_post = [a for a in self.default_actions if a.kind == Action.post] self.install_ignore = self.instignore self.install_force_chmod = self.force_chmod self.install_clear_workdir = self.args['--workdir-clear'] or \ self.clear_workdir def _apply_args_compare(self): """compare specifics""" self.compare_focus = self.args['--file'] self.compare_ignore = self.args['--ignore'] self.compare_ignore.extend(self.cmpignore) self.compare_ignore.append('*{}'.format(self.install_backup_suffix)) self.compare_ignore = uniq_list(self.compare_ignore) self.compare_fileonly = self.args['--file-only'] self.ignore_missing_in_dotdrop = self.ignore_missing_in_dotdrop or \ self.args['--ignore-missing'] def _apply_args_import(self): """import specifics""" self.import_path = self.args['<path>'] self.import_as = self.args['--as'] self.import_mode = self.args['--preserve-mode'] or self.chmod_on_import self.import_ignore = self.args['--ignore'] self.import_ignore.extend(self.impignore) self.import_ignore.append('*{}'.format(self.install_backup_suffix)) self.import_ignore = uniq_list(self.import_ignore) def _apply_args_update(self): """update specifics""" self.update_path = self.args['<path>'] self.update_iskey = self.args['--key'] self.update_ignore = self.args['--ignore'] self.update_ignore.extend(self.upignore) self.update_ignore.append('*{}'.format(self.install_backup_suffix)) self.update_ignore = uniq_list(self.update_ignore) self.update_showpatch = self.args['--show-patch'] def _apply_args_profiles(self): """profiles specifics""" self.profiles_grepable = self.args['--grepable'] def _apply_args_remove(self): """remove specifics""" self.remove_path = self.args['<path>'] self.remove_iskey = self.args['--key'] def _apply_args_detail(self): """detail specifics""" self.detail_keys = self.args['<key>'] def _apply_args(self): """apply cli args as attribute""" # the commands self.cmd_profiles = self.args['profiles'] self.cmd_files = self.args['files'] self.cmd_install = self.args['install'] self.cmd_compare = self.args['compare'] self.cmd_import = self.args['import'] self.cmd_update = self.args['update'] self.cmd_detail = self.args['detail'] self.cmd_remove = self.args['remove'] # adapt attributes based on arguments self.safe = not self.args['--force'] try: if ENV_WORKERS in os.environ: workers = int(os.environ[ENV_WORKERS]) else: workers = int(self.args['--workers']) self.workers = workers except ValueError: self.log.err('bad option for --workers') sys.exit(USAGE) # import link default value self.import_link = self.link_on_import if self.args['--link']: # overwrite default import link with cli switch link = self.args['--link'] if link not in OPT_LINK: self.log.err('bad option for --link: {}'.format(link)) sys.exit(USAGE) self.import_link = OPT_LINK[link] # "files" specifics self._apply_args_files() # "install" specifics self._apply_args_install() # "compare" specifics self._apply_args_compare() # "import" specifics self._apply_args_import() # "update" specifics self._apply_args_update() # "profiles" specifics self._apply_args_profiles() # "detail" specifics self._apply_args_detail() # "remove" specifics self._apply_args_remove() def _fill_attr(self): """create attributes from conf""" # variables self.variables = self.conf.get_variables() # the dotfiles self.dotfiles = self.conf.get_dotfiles() # the profiles self.profiles = self.conf.get_profiles() def _debug_attr(self): """debug display all of this class attributes""" if not self.debug: return self.log.dbg('effective options:') for att in dir(self): if att.startswith('_'): continue val = getattr(self, att) if callable(val): continue if isinstance(val, list): debug_list('-> {}'.format(att), val, self.debug) elif isinstance(val, dict): debug_dict('-> {}'.format(att), val, self.debug) else: self.log.dbg('-> {}: {}'.format(att, val)) def _attr_set(self, attr): """error when some inexistent attr is set""" raise Exception('bad option: {}'.format(attr))