mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-02-16 23:09:11 +00:00
fix diverse bugs
This commit is contained in:
@@ -253,7 +253,6 @@ class CfgAggregator:
|
|||||||
|
|
||||||
def get_dotfile_by_dst(self, dst):
|
def get_dotfile_by_dst(self, dst):
|
||||||
"""get a dotfile by dst"""
|
"""get a dotfile by dst"""
|
||||||
dst = self.path_to_dotfile_dst(dst)
|
|
||||||
try:
|
try:
|
||||||
return next(d for d in self.dotfiles if d.dst == dst)
|
return next(d for d in self.dotfiles if d.dst == dst)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from dotdrop.logger import Logger
|
|||||||
from dotdrop.templategen import Templategen
|
from dotdrop.templategen import Templategen
|
||||||
from dotdrop.linktypes import LinkTypes
|
from dotdrop.linktypes import LinkTypes
|
||||||
from dotdrop.utils import shell, uniq_list
|
from dotdrop.utils import shell, uniq_list
|
||||||
|
from dotdrop.exceptions import YamlException
|
||||||
|
|
||||||
|
|
||||||
class CfgYaml:
|
class CfgYaml:
|
||||||
@@ -116,7 +117,8 @@ class CfgYaml:
|
|||||||
keys = self.dotfiles.keys()
|
keys = self.dotfiles.keys()
|
||||||
if len(keys) != len(list(set(keys))):
|
if len(keys) != len(list(set(keys))):
|
||||||
dups = [x for x in keys if x not in list(set(keys))]
|
dups = [x for x in keys if x not in list(set(keys))]
|
||||||
raise Exception('duplicate dotfile keys found: {}'.format(dups))
|
err = 'duplicate dotfile keys found: {}'.format(dups)
|
||||||
|
raise YamlException(err)
|
||||||
self.dotfiles = self._norm_dotfiles(self.dotfiles)
|
self.dotfiles = self._norm_dotfiles(self.dotfiles)
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('dotfiles: {}'.format(self.dotfiles))
|
self.log.dbg('dotfiles: {}'.format(self.dotfiles))
|
||||||
@@ -329,7 +331,7 @@ class CfgYaml:
|
|||||||
# inherite profile variables
|
# inherite profile variables
|
||||||
for inherited_profile in pentry.get(self.key_profile_include, []):
|
for inherited_profile in pentry.get(self.key_profile_include, []):
|
||||||
if inherited_profile == profile or inherited_profile in seen:
|
if inherited_profile == profile or inherited_profile in seen:
|
||||||
raise Exception('\"include\" loop')
|
raise YamlException('\"include\" loop')
|
||||||
seen.append(inherited_profile)
|
seen.append(inherited_profile)
|
||||||
new = self._get_variables_dict(inherited_profile, seen, sub=True)
|
new = self._get_variables_dict(inherited_profile, seen, sub=True)
|
||||||
variables.update(new)
|
variables.update(new)
|
||||||
@@ -356,7 +358,7 @@ class CfgYaml:
|
|||||||
# inherite profile dynvariables
|
# inherite profile dynvariables
|
||||||
for inherited_profile in pentry.get(self.key_profile_include, []):
|
for inherited_profile in pentry.get(self.key_profile_include, []):
|
||||||
if inherited_profile == profile or inherited_profile in seen:
|
if inherited_profile == profile or inherited_profile in seen:
|
||||||
raise Exception('\"include loop\"')
|
raise YamlException('\"include loop\"')
|
||||||
seen.append(inherited_profile)
|
seen.append(inherited_profile)
|
||||||
new = self._get_dvariables_dict(inherited_profile, seen, sub=True)
|
new = self._get_dvariables_dict(inherited_profile, seen, sub=True)
|
||||||
variables.update(new)
|
variables.update(new)
|
||||||
@@ -383,7 +385,7 @@ class CfgYaml:
|
|||||||
p = os.path.expanduser(p)
|
p = os.path.expanduser(p)
|
||||||
new = glob.glob(p)
|
new = glob.glob(p)
|
||||||
if not new:
|
if not new:
|
||||||
raise Exception('bad path: {}'.format(p))
|
raise YamlException('bad path: {}'.format(p))
|
||||||
res.extend(glob.glob(p))
|
res.extend(glob.glob(p))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -438,8 +440,7 @@ class CfgYaml:
|
|||||||
current = v.get(self.key_dotfiles, [])
|
current = v.get(self.key_dotfiles, [])
|
||||||
path = self._resolve_path(p)
|
path = self._resolve_path(p)
|
||||||
current = self._import_sub(path, self.key_dotfiles,
|
current = self._import_sub(path, self.key_dotfiles,
|
||||||
current, mandatory=False,
|
current, mandatory=False)
|
||||||
path_func=self._norm_dotfiles)
|
|
||||||
v[self.key_dotfiles] = current
|
v[self.key_dotfiles] = current
|
||||||
|
|
||||||
def _import_configs(self):
|
def _import_configs(self):
|
||||||
@@ -491,7 +492,7 @@ class CfgYaml:
|
|||||||
seen = []
|
seen = []
|
||||||
for i in inc:
|
for i in inc:
|
||||||
if i in seen:
|
if i in seen:
|
||||||
raise Exception('\"include loop\"')
|
raise YamlException('\"include loop\"')
|
||||||
seen.append(i)
|
seen.append(i)
|
||||||
if i not in self.profiles.keys():
|
if i not in self.profiles.keys():
|
||||||
self.log.warn('include unknown profile: {}'.format(i))
|
self.log.warn('include unknown profile: {}'.format(i))
|
||||||
@@ -541,7 +542,7 @@ class CfgYaml:
|
|||||||
elif isinstance(current, list) and isinstance(new, list):
|
elif isinstance(current, list) and isinstance(new, list):
|
||||||
current = current + new
|
current = current + new
|
||||||
else:
|
else:
|
||||||
raise Exception('invalid import {} from {}'.format(key, path))
|
raise YamlException('invalid import {} from {}'.format(key, path))
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('new \"{}\": {}'.format(key, current))
|
self.log.dbg('new \"{}\": {}'.format(key, current))
|
||||||
return current
|
return current
|
||||||
@@ -558,7 +559,7 @@ class CfgYaml:
|
|||||||
"""return entry from yaml dictionary"""
|
"""return entry from yaml dictionary"""
|
||||||
if key not in dic:
|
if key not in dic:
|
||||||
if mandatory:
|
if mandatory:
|
||||||
raise Exception('invalid config: no {} found'.format(key))
|
raise YamlException('invalid config: no {} found'.format(key))
|
||||||
dic[key] = {}
|
dic[key] = {}
|
||||||
return dic[key]
|
return dic[key]
|
||||||
if mandatory and not dic[key]:
|
if mandatory and not dic[key]:
|
||||||
@@ -570,13 +571,13 @@ class CfgYaml:
|
|||||||
"""load a yaml file to a dict"""
|
"""load a yaml file to a dict"""
|
||||||
content = {}
|
content = {}
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
raise Exception('config path not found: {}'.format(path))
|
raise YamlException('config path not found: {}'.format(path))
|
||||||
with open(path, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
try:
|
try:
|
||||||
content = yaml.safe_load(f)
|
content = yaml.safe_load(f)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.err(e)
|
self.log.err(e)
|
||||||
raise Exception('invalid config: {}'.format(path))
|
raise YamlException('invalid config: {}'.format(path))
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def _new_profile(self, key):
|
def _new_profile(self, key):
|
||||||
@@ -718,8 +719,13 @@ class CfgYaml:
|
|||||||
if isinstance(v, dict):
|
if isinstance(v, dict):
|
||||||
newv = self._clear_none(v)
|
newv = self._clear_none(v)
|
||||||
if not newv:
|
if not newv:
|
||||||
|
# no empty dict
|
||||||
continue
|
continue
|
||||||
if newv is None:
|
if newv is None:
|
||||||
|
# no None value
|
||||||
|
continue
|
||||||
|
if isinstance(newv, list) and not newv:
|
||||||
|
# no empty list
|
||||||
continue
|
continue
|
||||||
new[k] = newv
|
new[k] = newv
|
||||||
return new
|
return new
|
||||||
@@ -730,12 +736,27 @@ class CfgYaml:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
content = self._clear_none(self.dump())
|
content = self._clear_none(self.dump())
|
||||||
|
|
||||||
|
# make sure we have the base entries
|
||||||
|
if self.key_settings not in content:
|
||||||
|
content[self.key_settings] = None
|
||||||
|
if self.key_dotfiles not in content:
|
||||||
|
content[self.key_dotfiles] = None
|
||||||
|
if self.key_profiles not in content:
|
||||||
|
content[self.key_profiles] = None
|
||||||
|
|
||||||
|
# ensure no null are displayed
|
||||||
|
data = yaml.safe_dump(content,
|
||||||
|
default_flow_style=False,
|
||||||
|
indent=2)
|
||||||
|
data = data.replace('null', '')
|
||||||
|
|
||||||
|
# save to file
|
||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('saving: {}'.format(content))
|
self.log.dbg('saving: {}'.format(content))
|
||||||
with open(self.path, 'w') as f:
|
with open(self.path, 'w') as f:
|
||||||
yaml.safe_dump(content, f,
|
f.write(data)
|
||||||
default_flow_style=False,
|
|
||||||
indent=2)
|
|
||||||
self.dirty = False
|
self.dirty = False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from dotdrop.updater import Updater
|
|||||||
from dotdrop.comparator import Comparator
|
from dotdrop.comparator import Comparator
|
||||||
from dotdrop.utils import get_tmpdir, remove, strip_home, run, uniq_list
|
from dotdrop.utils import get_tmpdir, remove, strip_home, run, uniq_list
|
||||||
from dotdrop.linktypes import LinkTypes
|
from dotdrop.linktypes import LinkTypes
|
||||||
|
from dotdrop.exceptions import YamlException
|
||||||
|
|
||||||
LOG = Logger()
|
LOG = Logger()
|
||||||
TRANS_SUFFIX = 'trans'
|
TRANS_SUFFIX = 'trans'
|
||||||
@@ -423,7 +424,9 @@ def cmd_remove(o):
|
|||||||
LOG.dbg('removing {}'.format(key))
|
LOG.dbg('removing {}'.format(key))
|
||||||
if not iskey:
|
if not iskey:
|
||||||
# by path
|
# by path
|
||||||
|
print(key)
|
||||||
dotfile = o.conf.get_dotfile_by_dst(key)
|
dotfile = o.conf.get_dotfile_by_dst(key)
|
||||||
|
print(dotfile)
|
||||||
if not dotfile:
|
if not dotfile:
|
||||||
LOG.warn('{} ignored, does not exist'.format(key))
|
LOG.warn('{} ignored, does not exist'.format(key))
|
||||||
continue
|
continue
|
||||||
@@ -441,7 +444,7 @@ def cmd_remove(o):
|
|||||||
if o.dry:
|
if o.dry:
|
||||||
LOG.dry('would remove {} from {}'.format(dotfile, pkeys))
|
LOG.dry('would remove {} from {}'.format(dotfile, pkeys))
|
||||||
continue
|
continue
|
||||||
msg = 'Remove dotfile from all these profiles: {}'.format(pkeys)
|
msg = 'Remove \"{}\" from all these profiles: {}'.format(k, pkeys)
|
||||||
if o.safe and not LOG.ask(msg):
|
if o.safe and not LOG.ask(msg):
|
||||||
return False
|
return False
|
||||||
if o.debug:
|
if o.debug:
|
||||||
@@ -537,8 +540,8 @@ def main():
|
|||||||
"""entry point"""
|
"""entry point"""
|
||||||
try:
|
try:
|
||||||
o = Options()
|
o = Options()
|
||||||
except Exception as e:
|
except YamlException as e:
|
||||||
LOG.err('options error: {}'.format(str(e)))
|
LOG.err('config file error: {}'.format(str(e)))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
ret = True
|
ret = True
|
||||||
|
|||||||
11
dotdrop/exceptions.py
Normal file
11
dotdrop/exceptions.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
"""
|
||||||
|
author: deadc0de6 (https://github.com/deadc0de6)
|
||||||
|
Copyright (c) 2019, deadc0de6
|
||||||
|
|
||||||
|
diverse exceptions
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class YamlException(Exception):
|
||||||
|
"""exception in CfgYaml"""
|
||||||
|
pass
|
||||||
@@ -15,18 +15,21 @@ class Profile(DictParser):
|
|||||||
key_include = 'include'
|
key_include = 'include'
|
||||||
key_import = 'import'
|
key_import = 'import'
|
||||||
|
|
||||||
def __init__(self, key, actions=[], dotfiles=[], variables=[]):
|
def __init__(self, key, actions=[], dotfiles=[],
|
||||||
|
variables=[], dynvariables=[]):
|
||||||
"""
|
"""
|
||||||
constructor
|
constructor
|
||||||
@key: profile key
|
@key: profile key
|
||||||
@actions: list of action keys
|
@actions: list of action keys
|
||||||
@dotfiles: list of dotfile keys
|
@dotfiles: list of dotfile keys
|
||||||
@variables: list of variable keys
|
@variables: list of variable keys
|
||||||
|
@dynvariables: list of interpreted variable keys
|
||||||
"""
|
"""
|
||||||
self.key = key
|
self.key = key
|
||||||
self.actions = actions
|
self.actions = actions
|
||||||
self.dotfiles = dotfiles
|
self.dotfiles = dotfiles
|
||||||
self.variables = variables
|
self.variables = variables
|
||||||
|
self.dynvariables = dynvariables
|
||||||
|
|
||||||
def get_pre_actions(self):
|
def get_pre_actions(self):
|
||||||
"""return all 'pre' actions"""
|
"""return all 'pre' actions"""
|
||||||
|
|||||||
Reference in New Issue
Block a user