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