1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-10 23:44:16 +00:00

Refactoring config parser

This commit is contained in:
Davide Laezza
2019-04-19 19:24:24 +02:00
parent 0fcefe98f1
commit f84920e2e6

View File

@@ -34,6 +34,8 @@ class Cfg:
key_imp_link = 'link_on_import' key_imp_link = 'link_on_import'
key_dotfile_link = 'link_dotfile_default' key_dotfile_link = 'link_dotfile_default'
key_workdir = 'workdir' key_workdir = 'workdir'
# import keys
key_import_vars = 'import_variables' key_import_vars = 'import_variables'
key_import_actions = 'import_actions' key_import_actions = 'import_actions'
key_cmpignore = 'cmpignore' key_cmpignore = 'cmpignore'
@@ -100,6 +102,7 @@ class Cfg:
raise ValueError('config file path undefined') raise ValueError('config file path undefined')
if not os.path.exists(cfgpath): if not os.path.exists(cfgpath):
raise ValueError('config file does not exist: {}'.format(cfgpath)) raise ValueError('config file does not exist: {}'.format(cfgpath))
# make sure to have an absolute path to config file # make sure to have an absolute path to config file
self.cfgpath = os.path.abspath(cfgpath) self.cfgpath = os.path.abspath(cfgpath)
self.debug = debug self.debug = debug
@@ -220,29 +223,25 @@ class Cfg:
return False return False
# parse the profiles # parse the profiles
self.lnk_profiles = self.content[self.key_profiles] # ensures self.lnk_profiles is a dict
if self.lnk_profiles is None: if not isinstance(self.content[self.key_profiles], dict):
# ensures self.lnk_profiles is a dict
self.content[self.key_profiles] = {} self.content[self.key_profiles] = {}
self.lnk_profiles = self.content[self.key_profiles]
for k, v in self.lnk_profiles.items(): self.lnk_profiles = self.content[self.key_profiles]
if not v: for p in filter(bool, self.lnk_profiles.values()):
continue # Ensures that the dotfiles entry is an empty list when not given
if self.key_profiles_dots in v and \ # or none
v[self.key_profiles_dots] is None: p.setdefault(self.key_profiles_dots, [])
# if has the dotfiles entry but is empty if p[self.key_profiles_dots] is None:
# ensures it's an empty list p[self.key_profiles_dots] = []
v[self.key_profiles_dots] = []
# make sure we have an absolute dotpath # make sure we have an absolute dotpath
self.curdotpath = self.lnk_settings[self.key_dotpath] self.curdotpath = self.lnk_settings[self.key_dotpath]
self.lnk_settings[self.key_dotpath] = \ self.lnk_settings[self.key_dotpath] = self._abs_path(self.curdotpath)
self._abs_path(self.curdotpath)
# make sure we have an absolute workdir # make sure we have an absolute workdir
self.curworkdir = self.lnk_settings[self.key_workdir] self.curworkdir = self.lnk_settings[self.key_workdir]
self.lnk_settings[self.key_workdir] = \ self.lnk_settings[self.key_workdir] = self._abs_path(self.curworkdir)
self._abs_path(self.curworkdir)
# load external variables/dynvariables # load external variables/dynvariables
if self.key_import_vars in self.lnk_settings: if self.key_import_vars in self.lnk_settings:
@@ -258,7 +257,7 @@ class Cfg:
self.cmpignores = self.lnk_settings[self.key_cmpignore] or [] self.cmpignores = self.lnk_settings[self.key_cmpignore] or []
# parse external actions # parse external actions
if self.key_import_actions in self.lnk_settings: try:
for path in self.lnk_settings[self.key_import_actions]: for path in self.lnk_settings[self.key_import_actions]:
path = self._abs_path(path) path = self._abs_path(path)
if self.debug: if self.debug:
@@ -267,6 +266,8 @@ class Cfg:
if self.key_actions in content and \ if self.key_actions in content and \
content[self.key_actions] is not None: content[self.key_actions] is not None:
self._load_actions(content[self.key_actions]) self._load_actions(content[self.key_actions])
except KeyError:
pass
# parse local actions # parse local actions
if self.key_actions in self.content and \ if self.key_actions in self.content and \
@@ -285,14 +286,14 @@ class Cfg:
for k, v in self.content[self.key_trans_w].items(): for k, v in self.content[self.key_trans_w].items():
self.trans_w[k] = Transform(k, v) self.trans_w[k] = Transform(k, v)
# parse the dotfiles # parse the dotfiles and construct the dict of objects per dotfile key
# and construct the dict of objects per dotfile key # ensures the dotfiles entry is a dict
if not self.content[self.key_dotfiles]: if not isinstance(self.content[self.key_dotfiles], dict):
# ensures the dotfiles entry is a dict
self.content[self.key_dotfiles] = {} self.content[self.key_dotfiles] = {}
for k in self.content[self.key_dotfiles].keys(): dotfiles = self.content[self.key_dotfiles]
v = self.content[self.key_dotfiles][k] noempty_default = self.lnk_settings[self.key_ignoreempty]
for k, v in dotfiles.items():
src = os.path.normpath(v[self.key_dotfiles_src]) src = os.path.normpath(v[self.key_dotfiles_src])
dst = os.path.normpath(v[self.key_dotfiles_dst]) dst = os.path.normpath(v[self.key_dotfiles_dst])
@@ -306,7 +307,7 @@ class Cfg:
# fix it # fix it
v = self._fix_dotfile_link(k, v) v = self._fix_dotfile_link(k, v)
self.content[self.key_dotfiles][k] = v dotfiles[k] = v
# get link type # get link type
link = self._get_def_link() link = self._get_def_link()
@@ -314,13 +315,10 @@ class Cfg:
link = self._string_to_linktype(v[self.key_dotfiles_link]) link = self._string_to_linktype(v[self.key_dotfiles_link])
# get ignore empty # get ignore empty
noempty = v[self.key_dotfiles_noempty] if \ noempty = v.get(self.key_dotfiles_noempty, noempty_default)
self.key_dotfiles_noempty \
in v else self.lnk_settings[self.key_ignoreempty]
# parse actions # parse actions
itsactions = v[self.key_dotfiles_actions] if \ itsactions = v.get(self.key_dotfiles_actions, [])
self.key_dotfiles_actions in v else []
actions = self._parse_actions(itsactions, profile=profile) actions = self._parse_actions(itsactions, profile=profile)
if self.debug: if self.debug:
self.log.dbg('action for {}'.format(k)) self.log.dbg('action for {}'.format(k))
@@ -329,8 +327,7 @@ class Cfg:
self.log.dbg('- {}: {}'.format(t, action)) self.log.dbg('- {}: {}'.format(t, action))
# parse read transformation # parse read transformation
itstrans_r = v[self.key_dotfiles_trans_r] if \ itstrans_r = v.get(self.key_dotfiles_trans_r)
self.key_dotfiles_trans_r in v else None
trans_r = None trans_r = None
if itstrans_r: if itstrans_r:
if type(itstrans_r) is list: if type(itstrans_r) is list:
@@ -347,8 +344,7 @@ class Cfg:
return False return False
# parse write transformation # parse write transformation
itstrans_w = v[self.key_dotfiles_trans_w] if \ itstrans_w = v.get(self.key_dotfiles_trans_w)
self.key_dotfiles_trans_w in v else None
trans_w = None trans_w = None
if itstrans_w: if itstrans_w:
if type(itstrans_w) is list: if type(itstrans_w) is list:
@@ -373,13 +369,11 @@ class Cfg:
trans_w = None trans_w = None
# parse cmpignore pattern # parse cmpignore pattern
cmpignores = v[self.key_dotfiles_cmpignore] if \ cmpignores = v.get(self.key_dotfiles_cmpignore, [])
self.key_dotfiles_cmpignore in v else []
cmpignores.extend(self.cmpignores) cmpignores.extend(self.cmpignores)
# parse upignore pattern # parse upignore pattern
upignores = v[self.key_dotfiles_upignore] if \ upignores = v.get(self.key_dotfiles_upignore, [])
self.key_dotfiles_upignore in v else []
upignores.extend(self.upignores) upignores.extend(self.upignores)
# create new dotfile # create new dotfile
@@ -390,16 +384,14 @@ class Cfg:
upignore=upignores) upignore=upignores)
# assign dotfiles to each profile # assign dotfiles to each profile
for k, v in self.lnk_profiles.items(): self.prodots = {k: [] for k in self.lnk_profiles.keys()}
self.prodots[k] = [] for name, profile in self.lnk_profiles.items():
if not v: if not profile:
continue continue
if self.key_profiles_dots not in v: dots = profile[self.key_profiles_dots]
# ensures is a list if not dots:
v[self.key_profiles_dots] = []
if not v[self.key_profiles_dots]:
continue continue
dots = v[self.key_profiles_dots]
if self.key_all in dots: if self.key_all in dots:
# add all if key ALL is used # add all if key ALL is used
self.prodots[k] = list(self.dotfiles.values()) self.prodots[k] = list(self.dotfiles.values())
@@ -410,10 +402,11 @@ class Cfg:
msg = 'unknown dotfile \"{}\" for {}'.format(d, k) msg = 'unknown dotfile \"{}\" for {}'.format(d, k)
self.log.err(msg) self.log.err(msg)
continue continue
self.prodots[k].append(self.dotfiles[d]) self.prodots[name].append(self.dotfiles[d])
profile_names = self.lnk_profiles.keys()
# handle "import" (from file) for each profile # handle "import" (from file) for each profile
for k in self.lnk_profiles.keys(): for k in profile_names:
dots = self._get_imported_dotfiles_keys(k) dots = self._get_imported_dotfiles_keys(k)
for d in dots: for d in dots:
if d not in self.dotfiles: if d not in self.dotfiles:
@@ -423,20 +416,19 @@ class Cfg:
self.prodots[k].append(self.dotfiles[d]) self.prodots[k].append(self.dotfiles[d])
# handle "include" (from other profile) for each profile # handle "include" (from other profile) for each profile
for k in self.lnk_profiles.keys(): for k in profile_names:
ret, dots = self._get_included_dotfiles(k) ret, dots = self._get_included_dotfiles(k)
if not ret: if not ret:
return False return False
self.prodots[k].extend(dots) self.prodots[k].extend(dots)
# remove duplicates if any # remove duplicates if any
for k in self.lnk_profiles.keys(): self.prodots = {k: list(set(v)) for k, v in self.prodots.items()}
self.prodots[k] = list(set(self.prodots[k]))
# print dotfiles for each profile # print dotfiles for each profile
if self.debug: if self.debug:
for k in self.lnk_profiles.keys(): for k in self.lnk_profiles.keys():
df = ','.join([d.key for d in self.prodots[k]]) df = ','.join(d.key for d in self.prodots[k])
self.log.dbg('dotfiles for \"{}\": {}'.format(k, df)) self.log.dbg('dotfiles for \"{}\": {}'.format(k, df))
return True return True