1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-04 20:54:51 +00:00
This commit is contained in:
deadc0de6
2021-04-29 15:27:22 +02:00
parent 3ca863c9dd
commit 2654458c6e
9 changed files with 70 additions and 48 deletions

View File

@@ -312,7 +312,8 @@ class CfgAggregator:
return self._get_long_key(path, existing_keys)
return self._get_short_key(path, existing_keys)
def _norm_key_elem(self, elem):
@classmethod
def _norm_key_elem(cls, elem):
"""normalize path element for sanity"""
elem = elem.lstrip('.')
elem = elem.replace(' ', '-')
@@ -369,7 +370,8 @@ class CfgAggregator:
self._load()
self.debug = olddebug
def _norm_path(self, path):
@classmethod
def _norm_path(cls, path):
if not path:
return path
path = os.path.expanduser(path)

View File

@@ -15,6 +15,7 @@ from dotdrop.utils import must_ignore, uniq_list, diff, \
class Comparator:
"""compare dotfiles helper"""
def __init__(self, diff_cmd='', debug=False,
ignore_missing_in_dotdrop=False):
@@ -27,9 +28,11 @@ class Comparator:
self.log = Logger(debug=self.debug)
self.ignore_missing_in_dotdrop = ignore_missing_in_dotdrop
def compare(self, local_path, deployed_path, ignore=[]):
def compare(self, local_path, deployed_path, ignore=None):
"""diff local_path (dotdrop dotfile) and
deployed_path (destination file)"""
if not ignore:
ignore = []
local_path = os.path.expanduser(local_path)
deployed_path = os.path.expanduser(deployed_path)
self.log.dbg('comparing {} and {}'.format(
@@ -113,15 +116,19 @@ class Comparator:
return ''
if not os.path.isdir(deployed_path):
return '\"{}\" is a file\n'.format(deployed_path)
return self._compare_dirs(local_path, deployed_path, ignore)
def _compare_dirs(self, local_path, deployed_path, ignore):
"""compare directories"""
self.log.dbg('compare {} and {}'.format(local_path, deployed_path))
ret = []
comp = filecmp.dircmp(local_path, deployed_path)
# handle files only in deployed dir
for i in comp.left_only:
if self.ignore_missing_in_dotdrop:
continue
if must_ignore([os.path.join(local_path, i)],
if self.ignore_missing_in_dotdrop or \
must_ignore([os.path.join(local_path, i)],
ignore, debug=self.debug):
continue
ret.append('=> \"{}\" does not exist on destination\n'.format(i))

View File

@@ -9,6 +9,7 @@ from dotdrop.logger import Logger
class DictParser:
"""a dict parser"""
log = Logger()

View File

@@ -19,10 +19,10 @@ class Dotfile(DictParser):
key_template = 'template'
def __init__(self, key, dst, src,
actions=[], trans_r=None, trans_w=None,
actions=None, trans_r=None, trans_w=None,
link=LinkTypes.NOLINK, noempty=False,
cmpignore=[], upignore=[],
instignore=[], template=True, chmod=None,
cmpignore=None, upignore=None,
instignore=None, template=True, chmod=None,
ignore_missing_in_dotdrop=False):
"""
constructor
@@ -40,7 +40,7 @@ class Dotfile(DictParser):
@template: template this dotfile
@chmod: file permission
"""
self.actions = actions
self.actions = actions or []
self.dst = dst
self.key = key
self.link = LinkTypes.get(link)
@@ -48,9 +48,9 @@ class Dotfile(DictParser):
self.src = src
self.trans_r = trans_r
self.trans_w = trans_w
self.upignore = upignore
self.cmpignore = cmpignore
self.instignore = instignore
self.upignore = upignore or []
self.cmpignore = cmpignore or []
self.instignore = instignore or []
self.template = template
self.chmod = chmod
self.ignore_missing_in_dotdrop = ignore_missing_in_dotdrop
@@ -135,14 +135,14 @@ class Dotfile(DictParser):
out += '\n{}pre-action:'.format(indent)
some = self.get_pre_actions()
if some:
for a in some:
out += '\n{}- {}'.format(2 * indent, a)
for act in some:
out += '\n{}- {}'.format(2 * indent, act)
out += '\n{}post-action:'.format(indent)
some = self.get_post_actions()
if some:
for a in some:
out += '\n{}- {}'.format(2 * indent, a)
for act in some:
out += '\n{}- {}'.format(2 * indent, act)
out += '\n{}trans_r:'.format(indent)
some = self.get_trans_r()

View File

@@ -8,9 +8,7 @@ diverse exceptions
class YamlException(Exception):
"""exception in CfgYaml"""
pass
class UndefinedException(Exception):
"""exception in templating"""
pass

View File

@@ -41,9 +41,7 @@ class Importer:
self.safe = safe
self.debug = debug
self.keepdot = keepdot
if not ignore:
ignore = []
self.ignore = ignore
self.ignore = ignore or []
self.umask = get_umask()
self.log = Logger(debug=self.debug)

View File

@@ -1,19 +1,33 @@
"""
author: deadc0de6 (https://github.com/deadc0de6)
Copyright (c) 2020, deadc0de6
represents a type of link in dotdrop
"""
# https://github.com/PyCQA/pylint/issues/2062
# pylint: disable=E1101
from enum import IntEnum
class LinkTypes(IntEnum):
"""a type of link"""
NOLINK = 0
LINK = 1
LINK_CHILDREN = 2
@classmethod
def get(cls, key, default=None):
"""get the linktype"""
try:
return key if isinstance(key, cls) else cls[key.upper()]
except KeyError:
except KeyError as exc:
if default:
return default
raise ValueError('bad {} value: "{}"'.format(cls.__name__, key))
err = 'bad {} value: "{}"'.format(cls.__name__, key)
raise ValueError(err) from exc
def __str__(self):
"""linktype to string"""
return self.name.lower()

View File

@@ -10,13 +10,14 @@ from dotdrop.action import Action
class Profile(DictParser):
"""dotdrop profile"""
# profile keys
key_include = 'include'
key_import = 'import'
def __init__(self, key, actions=[], dotfiles=[],
variables=[], dynvariables=[]):
def __init__(self, key, actions=None, dotfiles=None,
variables=None, dynvariables=None):
"""
constructor
@key: profile key
@@ -26,10 +27,10 @@ class Profile(DictParser):
@dynvariables: list of interpreted variable keys
"""
self.key = key
self.actions = actions
self.dotfiles = dotfiles
self.variables = variables
self.dynvariables = dynvariables
self.actions = actions or []
self.dotfiles = dotfiles or []
self.variables = variables or []
self.dynvariables = dynvariables or []
def get_pre_actions(self):
"""return all 'pre' actions"""
@@ -51,8 +52,7 @@ class Profile(DictParser):
def __hash__(self):
return (hash(self.key) ^
hash(tuple(self.dotfiles)) ^
hash(tuple(self.included_profiles)))
hash(tuple(self.dotfiles)))
def __str__(self):
msg = 'key:"{}"'

View File

@@ -16,6 +16,7 @@ ENV_WORKDIR = 'DOTDROP_WORKDIR'
class Settings(DictParser):
"""Settings block in config"""
# key in yaml file
key_yaml = 'config'
@@ -50,14 +51,15 @@ class Settings(DictParser):
key_import_variables = 'import_variables'
def __init__(self, backup=True, banner=True,
create=True, default_actions=[], dotpath='dotfiles',
ignoreempty=False, import_actions=[], import_configs=[],
import_variables=[], keepdot=False,
create=True, default_actions=None, dotpath='dotfiles',
ignoreempty=False, import_actions=None, import_configs=None,
import_variables=None, keepdot=False,
link_dotfile_default=LinkTypes.NOLINK,
link_on_import=LinkTypes.NOLINK, longkey=False,
upignore=[], cmpignore=[], instignore=[], impignore=[],
workdir='~/.config/dotdrop', showdiff=False,
minversion=None, func_file=[], filter_file=[],
upignore=None, cmpignore=None, instignore=None,
impignore=None, workdir='~/.config/dotdrop',
showdiff=False, minversion=None,
func_file=None, filter_file=None,
diff_command='diff -r -u {0} {1}',
template_dotfile_default=True,
ignore_missing_in_dotdrop=False,
@@ -65,27 +67,27 @@ class Settings(DictParser):
self.backup = backup
self.banner = banner
self.create = create
self.default_actions = default_actions
self.default_actions = default_actions or []
self.dotpath = dotpath
self.ignoreempty = ignoreempty
self.import_actions = import_actions
self.import_configs = import_configs
self.import_variables = import_variables
self.import_actions = import_actions or []
self.import_configs = import_configs or []
self.import_variables = import_variables or []
self.keepdot = keepdot
self.longkey = longkey
self.showdiff = showdiff
self.upignore = upignore
self.cmpignore = cmpignore
self.instignore = instignore
self.impignore = impignore
self.upignore = upignore or []
self.cmpignore = cmpignore or []
self.instignore = instignore or []
self.impignore = impignore or []
self.workdir = workdir
if ENV_WORKDIR in os.environ:
self.workdir = os.environ[ENV_WORKDIR]
self.link_dotfile_default = LinkTypes.get(link_dotfile_default)
self.link_on_import = LinkTypes.get(link_on_import)
self.minversion = minversion
self.func_file = func_file
self.filter_file = filter_file
self.func_file = func_file or []
self.filter_file = filter_file or []
self.diff_command = diff_command
self.template_dotfile_default = template_dotfile_default
self.ignore_missing_in_dotdrop = ignore_missing_in_dotdrop