def __init__(self, dotpath, dotfiles, variables, dry=False, safe=True, debug=False, ignore=[], showpatch=False): """constructor @dotpath: path where dotfiles are stored @dotfiles: dotfiles for this profile @variables: dictionary of variables for the templates @dry: simulate @safe: ask for overwrite if True @debug: enable debug @ignore: pattern to ignore when updating @showpatch: show patch if dotfile to update is a template """ self.dotpath = dotpath self.dotfiles = dotfiles self.variables = variables self.dry = dry self.safe = safe self.debug = debug self.ignore = ignore self.showpatch = showpatch self.log = Logger()
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 __init__(self, args=None): """constructor @args: argument dictionary (if None use sys) """ self.args = args if not args: self.args = docopt(USAGE, version=VERSION) self.log = Logger() self.debug = self.args['--verbose'] if not self.debug and ENV_DEBUG in os.environ: self.debug = True if ENV_NODEBUG in os.environ: self.debug = False self.profile = self.args['--profile'] self.confpath = os.path.expanduser(self.args['--cfg']) if self.debug: self.log.dbg('config file: {}'.format(self.confpath)) self._read_config(self.profile) 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._print_attr() # start monitoring for bad attribute self._set_attr_err = True
def __init__(self, profile, conf, dotpath, diff_cmd, dry=False, safe=True, debug=False, keepdot=True, ignore=[]): """constructor @profile: the selected profile @conf: configuration manager @dotpath: dotfiles dotpath @diff_cmd: diff command to use @dry: simulate @safe: ask for overwrite if True @debug: enable debug @keepdot: keep dot prefix @ignore: patterns to ignore when importing """ self.profile = profile self.conf = conf self.dotpath = dotpath self.diff_cmd = diff_cmd self.dry = dry self.safe = safe self.debug = debug self.keepdot = keepdot self.ignore = ignore self.umask = get_umask() self.log = Logger()
def __init__(self, base='.', create=True, backup=True, dry=False, safe=False, workdir='~/.config/dotdrop', debug=False, diff=True, totemp=None, showdiff=False, backup_suffix='.dotdropbak', diff_cmd=''): """constructor @base: directory path where to search for templates @create: create directory hierarchy if missing when installing @backup: backup existing dotfile when installing @dry: just simulate @safe: ask for any overwrite @workdir: where to install template before symlinking @debug: enable debug @diff: diff when installing if True @totemp: deploy to this path instead of dotfile dst if not None @showdiff: show the diff before overwriting (or asking for) @backup_suffix: suffix for dotfile backup file @diff_cmd: diff command to use """ self.create = create self.backup = backup self.dry = dry self.safe = safe self.workdir = os.path.expanduser(workdir) self.base = base self.debug = debug self.diff = diff self.totemp = totemp self.showdiff = showdiff self.backup_suffix = backup_suffix self.diff_cmd = diff_cmd self.comparing = False self.action_executed = False self.log = Logger()
def __init__(self, dotpath, variables, conf, dry=False, safe=True, debug=False, ignore=[], showpatch=False): """constructor @dotpath: path where dotfiles are stored @variables: dictionary of variables for the templates @conf: configuration manager @dry: simulate @safe: ask for overwrite if True @debug: enable debug @ignore: pattern to ignore when updating @showpatch: show patch if dotfile to update is a template """ self.dotpath = dotpath self.variables = variables self.conf = conf self.dry = dry self.safe = safe self.debug = debug self.ignore = ignore self.showpatch = showpatch self.templater = Templategen(variables=self.variables, base=self.dotpath, debug=self.debug) # save template vars self.tvars = self.templater.add_tmp_vars() self.log = Logger()
def __init__(self, base='.', variables={}, debug=False): """constructor @base: directory path where to search for templates @variables: dictionary of variables for templates @debug: enable debug """ self.base = base.rstrip(os.sep) self.debug = debug self.log = Logger() loader = FileSystemLoader(self.base) self.env = Environment(loader=loader, trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True, block_start_string=BLOCK_START, block_end_string=BLOCK_END, variable_start_string=VAR_START, variable_end_string=VAR_END, comment_start_string=COMMENT_START, comment_end_string=COMMENT_END) # adding variables self.env.globals['env'] = os.environ if variables: self.env.globals.update(variables) # adding header method self.env.globals['header'] = self._header # adding helper methods self.env.globals['exists'] = jhelpers.exists self.env.globals['exists_in_path'] = jhelpers.exists_in_path self.env.globals['basename'] = jhelpers.basename self.env.globals['dirname'] = jhelpers.dirname if self.debug: self.log.dbg('template additional variables: {}'.format(variables))
def __init__(self, conf, dotpath, profile, variables, dry, safe, iskey=False, debug=False, ignore=[], showpatch=False): """constructor @conf: configuration @dotpath: path where dotfiles are stored @profile: profile selected @variables: dictionary of variables for the templates @dry: simulate @safe: ask for overwrite if True @iskey: will the update be called on keys or path @debug: enable debug @ignore: pattern to ignore when updating @showpatch: show patch if dotfile to update is a template """ self.conf = conf self.dotpath = dotpath self.profile = profile self.variables = variables self.dry = dry self.safe = safe self.iskey = iskey self.debug = debug self.ignore = ignore self.showpatch = showpatch self.log = Logger()
class DictParser: log = Logger() @classmethod def _adjust_yaml_keys(cls, value): """adjust value for object 'cls'""" return value @classmethod def parse(cls, key, value): """parse (key,value) and construct object 'cls'""" tmp = value try: tmp = value.copy() except AttributeError: pass newv = cls._adjust_yaml_keys(tmp) if not key: return cls(**newv) return cls(key=key, **newv) @classmethod def parse_dict(cls, items): """parse a dictionary and construct object 'cls'""" if not items: return [] return [cls.parse(k, v) for k, v in items.items()]
def __init__(self, dotpath, variables, dotfile_key_getter, dotfile_dst_getter, dotfile_path_normalizer, dry=False, safe=True, debug=False, ignore=[], showpatch=False): """constructor @dotpath: path where dotfiles are stored @variables: dictionary of variables for the templates @dotfile_key_getter: func to get a dotfile by key @dotfile_dst_getter: func to get a dotfile by dst @dotfile_path_normalizer: func to normalize dotfile dst @dry: simulate @safe: ask for overwrite if True @debug: enable debug @ignore: pattern to ignore when updating @showpatch: show patch if dotfile to update is a template """ self.dotpath = dotpath self.variables = variables self.dotfile_key_getter = dotfile_key_getter self.dotfile_dst_getter = dotfile_dst_getter self.dotfile_path_normalizer = dotfile_path_normalizer self.dry = dry self.safe = safe self.debug = debug self.ignore = ignore self.showpatch = showpatch self.log = Logger()
def __init__(self, cfgpath): if not os.path.exists(cfgpath): raise ValueError('config file does not exist: {}'.format(cfgpath)) # make sure to have an absolute path to config file self.cfgpath = os.path.abspath(cfgpath) # init the logger self.log = Logger() # represents all entries under "config" # linked inside the yaml dict (self.content) self.lnk_settings = {} # represents all entries under "profiles" # linked inside the yaml dict (self.content) self.lnk_profiles = {} # represents all dotfiles # NOT linked inside the yaml dict (self.content) self.dotfiles = {} # dict of all action objects by action key # NOT linked inside the yaml dict (self.content) self.actions = {} # dict of all transformation objects by trans key # NOT linked inside the yaml dict (self.content) self.trans = {} # represents all dotfiles per profile by profile key # NOT linked inside the yaml dict (self.content) self.prodots = {} if not self._load_file(): raise ValueError('config is not valid')
def __init__(self, conf, dotpath, dry, safe, debug): self.home = os.path.expanduser(TILD) self.conf = conf self.dotpath = dotpath self.dry = dry self.safe = safe self.debug = debug self.log = Logger()
def __init__(self, diffopts='', debug=False): """constructor @diffopts: cli switches to pass to unix diff @debug: enable debug """ self.diffopts = diffopts self.debug = debug self.log = Logger()
def __init__(self, key, action): """constructor @key: action key @action: action string """ self.key = key self.action = action self.log = Logger()
def __init__(self, diff_cmd='', debug=False): """constructor @diff_cmd: diff command to use @debug: enable debug """ self.diff_cmd = diff_cmd self.debug = debug self.log = Logger()
def __init__(self, base='.', variables={}, func_file=[], filter_file=[], debug=False): """constructor @base: directory path where to search for templates @variables: dictionary of variables for templates @func_file: file path to load functions from @filter_file: file path to load filters from @debug: enable debug """ self.base = base.rstrip(os.sep) self.debug = debug self.log = Logger() self.variables = {} loader1 = FileSystemLoader(self.base) loader2 = FunctionLoader(self._template_loader) loader = ChoiceLoader([loader1, loader2]) self.env = Environment(loader=loader, trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True, block_start_string=BLOCK_START, block_end_string=BLOCK_END, variable_start_string=VAR_START, variable_end_string=VAR_END, comment_start_string=COMMENT_START, comment_end_string=COMMENT_END, undefined=StrictUndefined) # adding variables self.variables['env'] = os.environ if variables: self.variables.update(variables) # adding header method self.env.globals['header'] = self._header # adding helper methods if self.debug: self.log.dbg('load global functions:') self._load_funcs_to_dic(jhelpers, self.env.globals) if func_file: for f in func_file: if self.debug: self.log.dbg('load custom functions from {}'.format(f)) self._load_path_to_dic(f, self.env.globals) if filter_file: for f in filter_file: if self.debug: self.log.dbg('load custom filters from {}'.format(f)) self._load_path_to_dic(f, self.env.filters) if self.debug: self._debug_dict('template additional variables', variables)
def __init__(self, base='.', create=True, backup=True, dry=False, safe=False, debug=False, diff=True): self.create = create self.backup = backup self.dry = dry self.safe = safe self.base = base self.debug = debug self.diff = diff self.comparing = False self.log = Logger()
def __init__(self, path, profile=None, debug=False): """ config parser @path: config file path @profile: the selected profile @debug: debug flag """ self.path = os.path.abspath(path) self.profile = profile self.debug = debug self.log = Logger() # config needs to be written self.dirty = False # indicates the config has been updated self.dirty_deprecated = False if not os.path.exists(path): err = 'invalid config path: \"{}\"'.format(path) if self.debug: self.log.dbg(err) raise YamlException(err) self.yaml_dict = self._load_yaml(self.path) # live patch deprecated entries self._fix_deprecated(self.yaml_dict) # parse to self variables self._parse_main_yaml(self.yaml_dict) if self.debug: self.log.dbg('before normalization: {}'.format(self.yaml_dict)) # resolve variables self.variables, self.prokeys = self._merge_variables() # apply variables self._apply_variables() # process imported variables (import_variables) self._import_variables() # process imported actions (import_actions) self._import_actions() # process imported profile dotfiles (import) self._import_profiles_dotfiles() # process imported configs (import_configs) self._import_configs() # process profile include self._resolve_profile_includes() # process profile ALL self._resolve_profile_all() # patch dotfiles paths self._resolve_dotfile_paths() if self.debug: self.log.dbg('after normalization: {}'.format(self.yaml_dict))
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
def __init__(self, path, profile_key, debug=False): """ high level config parser @path: path to the config file @profile_key: profile key @debug: debug flag """ self.path = path self.profile_key = profile_key self.debug = debug self.log = Logger() self._load()
def __init__(self, path, profile=None, debug=False): """ high level config parser @path: path to the config file @profile: selected profile @debug: debug flag """ self.path = path self.profile = profile self.debug = debug self.log = Logger() self._load()
def __init__(self, diff_cmd='', debug=False, ignore_missing_in_dotdrop=False): """constructor @diff_cmd: diff command to use @debug: enable debug """ self.diff_cmd = diff_cmd self.debug = debug self.log = Logger() self.ignore_missing_in_dotdrop = ignore_missing_in_dotdrop
def __init__(self, base='.', debug=False): self.base = base.rstrip(os.sep) loader = FileSystemLoader(self.base) self.env = Environment(loader=loader, trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True, block_start_string=BLOCK_START, block_end_string=BLOCK_END, variable_start_string=VAR_START, variable_end_string=VAR_END, comment_start_string=COMMENT_START, comment_end_string=COMMENT_END) self.log = Logger(debug=debug)
def __init__(self, cfgpath, profile=None, debug=False): """constructor @cfgpath: path to the config file @profile: chosen profile @debug: enable debug """ if not os.path.exists(cfgpath): raise ValueError('config file does not exist: {}'.format(cfgpath)) # make sure to have an absolute path to config file self.cfgpath = os.path.abspath(cfgpath) self.debug = debug # init the logger self.log = Logger() # represents all entries under "config" # linked inside the yaml dict (self.content) self.lnk_settings = {} # represents all entries under "profiles" # linked inside the yaml dict (self.content) self.lnk_profiles = {} # represents all dotfiles # NOT linked inside the yaml dict (self.content) self.dotfiles = {} # dict of all action objects by action key # NOT linked inside the yaml dict (self.content) self.actions = {} # dict of all read transformation objects by trans key # NOT linked inside the yaml dict (self.content) self.trans_r = {} # dict of all write transformation objects by trans key # NOT linked inside the yaml dict (self.content) self.trans_w = {} # represents all dotfiles per profile by profile key # NOT linked inside the yaml dict (self.content) self.prodots = {} # represents all variables from external files self.ext_variables = {} self.ext_dynvariables = {} if not self._load_config(profile=profile): raise ValueError('config is not valid')
def __init__(self, cfgpath): if not os.path.exists(cfgpath): raise ValueError('config file does not exist') self.cfgpath = cfgpath self.log = Logger() # link inside content self.configs = {} # link inside content self.profiles = {} # not linked to content self.dotfiles = {} # not linked to content self.actions = {} # not linked to content self.prodots = {} if not self._load_file(): raise ValueError('config is not valid')
def __init__(self, base='.', create=True, backup=True, dry=False, safe=False, workdir='~/.config/dotdrop', debug=False, diff=True, totemp=None, showdiff=False): self.create = create self.backup = backup self.dry = dry self.safe = safe self.workdir = os.path.expanduser(workdir) self.base = base self.debug = debug self.diff = diff self.totemp = totemp self.showdiff = showdiff self.comparing = False self.action_executed = False self.log = Logger()
def __init__(self, profile='', base='.', variables={}, debug=False): self.base = base.rstrip(os.sep) self.debug = debug self.log = Logger() loader = FileSystemLoader(self.base) self.env = Environment(loader=loader, trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True, block_start_string=BLOCK_START, block_end_string=BLOCK_END, variable_start_string=VAR_START, variable_end_string=VAR_END, comment_start_string=COMMENT_START, comment_end_string=COMMENT_END) # adding variables self.env.globals['env'] = os.environ if profile: self.env.globals['profile'] = profile self.env.globals.update(variables) # adding header method self.env.globals['header'] = self._header # adding helper methods self.env.globals['exists'] = jhelpers.exists
import os import sys # local imports from dotdrop.options import Options from dotdrop.logger import Logger from dotdrop.templategen import Templategen from dotdrop.installer import Installer from dotdrop.updater import Updater from dotdrop.comparator import Comparator from dotdrop.dotfile import Dotfile from dotdrop.config import Cfg from dotdrop.utils import get_tmpdir, remove, strip_home, run from dotdrop.linktypes import LinkTypes LOG = Logger() TRANS_SUFFIX = 'trans' ########################################################### # entry point ########################################################### def cmd_install(o): """install dotfiles for this profile""" dotfiles = o.dotfiles if o.install_keys: # filtered dotfiles to install dotfiles = [d for d in dotfiles if d.key in set(o.install_keys)] if not dotfiles: msg = 'no dotfile to install for this profile (\"{}\")'
def __init__(self, path, profile=None, addprofiles=[], debug=False): """ config parser @path: config file path @profile: the selected profile @addprofiles: included profiles @debug: debug flag """ self._path = os.path.abspath(path) self._profile = profile self._debug = debug self._log = Logger() # config needs to be written self._dirty = False # indicates the config has been updated self._dirty_deprecated = False # profile variables self._profilevarskeys = [] # included profiles self._inc_profiles = addprofiles # init the dictionaries self.settings = {} self.dotfiles = {} self.profiles = {} self.actions = {} self.trans_r = {} self.trans_w = {} self.variables = {} if not os.path.exists(self._path): err = 'invalid config path: \"{}\"'.format(path) if self._debug: self._dbg(err) raise YamlException(err) self._yaml_dict = self._load_yaml(self._path) # live patch deprecated entries self._fix_deprecated(self._yaml_dict) ################################################## # parse the config and variables ################################################## # parse the "config" block self.settings = self._parse_blk_settings(self._yaml_dict) # base templater (when no vars/dvars exist) self.variables = self._enrich_vars(self.variables, self._profile) self._redefine_templater() # variables and dynvariables need to be first merged # before being templated in order to allow cyclic # references between them # parse the "variables" block var = self._parse_blk_variables(self._yaml_dict) self._add_variables(var, template=False) # parse the "dynvariables" block dvariables = self._parse_blk_dynvariables(self._yaml_dict) self._add_variables(dvariables, template=False) # now template variables and dynvariables from the same pool self._rec_resolve_variables(self.variables) # and execute dvariables # since this is done after recursively resolving variables # and dynvariables this means that variables referencing # dynvariables will result with the not executed value if dvariables.keys(): self._shell_exec_dvars(self.variables, keys=dvariables.keys()) # finally redefine the template self._redefine_templater() if self._debug: self._debug_dict('current variables defined', self.variables) # parse the "profiles" block self.profiles = self._parse_blk_profiles(self._yaml_dict) # include the profile's variables/dynvariables last # as it overwrites existing ones self._inc_profiles, pv, pvd = self._get_profile_included_vars() self._add_variables(pv, prio=True) self._add_variables(pvd, shell=True, prio=True) self._profilevarskeys.extend(pv.keys()) self._profilevarskeys.extend(pvd.keys()) # template variables self.variables = self._template_dict(self.variables) if self._debug: self._debug_dict('current variables defined', self.variables) ################################################## # template the "include" entries ################################################## self._template_include_entry() if self._debug: self._debug_dict('current variables defined', self.variables) ################################################## # parse the other blocks ################################################## # parse the "dotfiles" block self.dotfiles = self._parse_blk_dotfiles(self._yaml_dict) # parse the "actions" block self.actions = self._parse_blk_actions(self._yaml_dict) # parse the "trans_r" block self.trans_r = self._parse_blk_trans_r(self._yaml_dict) # parse the "trans_w" block self.trans_w = self._parse_blk_trans_w(self._yaml_dict) ################################################## # import elements ################################################## # process imported variables (import_variables) newvars = self._import_variables() self._clear_profile_vars(newvars) self._add_variables(newvars) # process imported actions (import_actions) self._import_actions() # process imported profile dotfiles (import) self._import_profiles_dotfiles() # process imported configs (import_configs) self._import_configs() # process profile include self._resolve_profile_includes() # add the current profile variables _, pv, pvd = self._get_profile_included_vars() self._add_variables(pv, prio=True) self._add_variables(pvd, shell=True, prio=True) self._profilevarskeys.extend(pv.keys()) self._profilevarskeys.extend(pvd.keys()) # resolve variables self._clear_profile_vars(newvars) self._add_variables(newvars) # process profile ALL self._resolve_profile_all() # patch dotfiles paths self._template_dotfiles_paths() if self._debug: self._dbg('########### {} ###########'.format('final config')) self._debug_entries()
def __init__(self, key, action): self.key = key self.action = action self.log = Logger()