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

pep257 refactoring

This commit is contained in:
deadc0de6
2018-06-02 14:46:44 +02:00
parent 6b89c3d5b8
commit 48c465f5f3
7 changed files with 59 additions and 38 deletions

View File

@@ -31,6 +31,7 @@ class Cmd:
class Action(Cmd): class Action(Cmd):
def execute(self): def execute(self):
"""execute the action in the shell"""
ret = 1 ret = 1
self.log.sub('executing \"{}\"'.format(self.action)) self.log.sub('executing \"{}\"'.format(self.action))
try: try:
@@ -43,9 +44,9 @@ class Action(Cmd):
class Transform(Cmd): class Transform(Cmd):
def transform(self, arg0, arg1): def transform(self, arg0, arg1):
'''execute transformation with {0} and {1} """execute transformation with {0} and {1}
where {0} is the file to transform and where {0} is the file to transform and
{1} is the result file''' {1} is the result file"""
if os.path.exists(arg1): if os.path.exists(arg1):
msg = 'transformation destination exists: {}' msg = 'transformation destination exists: {}'
self.log.warn(msg.format(arg1)) self.log.warn(msg.format(arg1))

View File

@@ -71,6 +71,7 @@ class Cfg:
raise ValueError('config is not valid') raise ValueError('config is not valid')
def _load_file(self): def _load_file(self):
"""load the yaml file"""
with open(self.cfgpath, 'r') as f: with open(self.cfgpath, 'r') as f:
self.content = yaml.load(f) self.content = yaml.load(f)
if not self._is_valid(): if not self._is_valid():
@@ -78,6 +79,7 @@ class Cfg:
return self._parse() return self._parse()
def _is_valid(self): def _is_valid(self):
"""test the yaml file (self.content) is valid"""
if self.key_profiles not in self.content: if self.key_profiles not in self.content:
self.log.err('missing \"{}\" in config'.format(self.key_profiles)) self.log.err('missing \"{}\" in config'.format(self.key_profiles))
return False return False
@@ -103,7 +105,9 @@ class Cfg:
return True return True
def _parse_actions(self, actions, entries): def _parse_actions(self, actions, entries):
""" parse actions specified for an element """ """parse actions specified for an element
where actions are all known actions and
entries are the ones defined for this dotfile"""
res = { res = {
self.key_actions_pre: [], self.key_actions_pre: [],
self.key_actions_post: [], self.key_actions_post: [],
@@ -128,7 +132,9 @@ class Cfg:
return res return res
def _parse_trans(self, trans, entries): def _parse_trans(self, trans, entries):
""" parse trans specified for an element """ """parse transformations specified for an element
where trans are all known transformation and
entries are the ones defined for this dotfile"""
res = [] res = []
for entry in entries: for entry in entries:
if entry not in trans.keys(): if entry not in trans.keys():
@@ -138,7 +144,7 @@ class Cfg:
return res return res
def _complete_configs(self): def _complete_configs(self):
""" set config defaults if not present """ """set config defaults if not present"""
if self.key_backup not in self.configs: if self.key_backup not in self.configs:
self.configs[self.key_backup] = self.default_backup self.configs[self.key_backup] = self.default_backup
if self.key_create not in self.configs: if self.key_create not in self.configs:
@@ -147,7 +153,7 @@ class Cfg:
self.configs[self.key_banner] = self.default_banner self.configs[self.key_banner] = self.default_banner
def _parse(self): def _parse(self):
""" parse config file """ """parse config file"""
# parse all actions # parse all actions
if self.key_actions in self.content: if self.key_actions in self.content:
if self.content[self.key_actions] is not None: if self.content[self.key_actions] is not None:
@@ -230,6 +236,7 @@ class Cfg:
return True return True
def _get_included_dotfiles(self, profile): def _get_included_dotfiles(self, profile):
"""find all dotfiles for a specific include keyword"""
included = [] included = []
if self.key_profiles_incl not in self.profiles[profile]: if self.key_profiles_incl not in self.profiles[profile]:
return included return included
@@ -243,7 +250,7 @@ class Cfg:
return included return included
def get_abs_dotpath(self, dotpath): def get_abs_dotpath(self, dotpath):
""" transform dotpath to an absolute path """ """transform dotpath to an absolute path"""
if not dotpath.startswith(os.sep): if not dotpath.startswith(os.sep):
absconf = os.path.join(os.path.dirname( absconf = os.path.join(os.path.dirname(
self.cfgpath), dotpath) self.cfgpath), dotpath)
@@ -251,6 +258,7 @@ class Cfg:
return dotpath return dotpath
def _save(self, content, path): def _save(self, content, path):
"""writes the config to file"""
ret = False ret = False
with open(path, 'w') as f: with open(path, 'w') as f:
ret = yaml.dump(content, f, ret = yaml.dump(content, f,
@@ -258,7 +266,7 @@ class Cfg:
return ret return ret
def _get_unique_key(self, dst): def _get_unique_key(self, dst):
""" return a unique key for an inexistent dotfile """ """return a unique key for an inexistent dotfile"""
allkeys = self.dotfiles.keys() allkeys = self.dotfiles.keys()
idx = -1 idx = -1
while True: while True:
@@ -275,16 +283,15 @@ class Cfg:
return key return key
def _dotfile_exists(self, dotfile): def _dotfile_exists(self, dotfile):
""" returns <bool> and the key if this dotfile exists, """return True and the existing dotfile key
a new unique key otherwise """ if it already exists, False and a new unique key otherwise"""
dsts = [(k, d.dst) for k, d in self.dotfiles.items()] dsts = [(k, d.dst) for k, d in self.dotfiles.items()]
if dotfile.dst in [x[1] for x in dsts]: if dotfile.dst in [x[1] for x in dsts]:
return True, [x[0] for x in dsts if x[1] == dotfile.dst][0] return True, [x[0] for x in dsts if x[1] == dotfile.dst][0]
return False, self._get_unique_key(dotfile.dst) return False, self._get_unique_key(dotfile.dst)
def new(self, dotfile, profile, link=False): def new(self, dotfile, profile, link=False):
""" import new dotfile (key will change) """ """import new dotfile (key will change)"""
# keep it short # keep it short
home = os.path.expanduser('~') home = os.path.expanduser('~')
dotfile.dst = dotfile.dst.replace(home, '~') dotfile.dst = dotfile.dst.replace(home, '~')
@@ -335,22 +342,22 @@ class Cfg:
return True, dotfile return True, dotfile
def get_dotfiles(self, profile): def get_dotfiles(self, profile):
""" returns a list of dotfiles for a specific profile """ """return a list of dotfiles for a specific profile"""
if profile not in self.prodots: if profile not in self.prodots:
return [] return []
return sorted(self.prodots[profile], return sorted(self.prodots[profile],
key=lambda x: str(x.key)) key=lambda x: str(x.key))
def get_profiles(self): def get_profiles(self):
""" returns all defined profiles """ """return all defined profiles"""
return self.profiles.keys() return self.profiles.keys()
def get_configs(self): def get_configs(self):
""" returns all defined configs """ """return all defined configs"""
return self.configs.copy() return self.configs.copy()
def dump(self): def dump(self):
""" dump config file """ """return a dump of the config"""
# temporary reset dotpath # temporary reset dotpath
dotpath = self.configs[self.key_dotpath] dotpath = self.configs[self.key_dotpath]
self.configs[self.key_dotpath] = self.curdotpath self.configs[self.key_dotpath] = self.curdotpath
@@ -367,7 +374,7 @@ class Cfg:
return ret return ret
def save(self): def save(self):
""" save config file to path """ """save the config to file"""
# temporary reset dotpath # temporary reset dotpath
dotpath = self.configs[self.key_dotpath] dotpath = self.configs[self.key_dotpath]
self.configs[self.key_dotpath] = self.curdotpath self.configs[self.key_dotpath] = self.curdotpath

View File

@@ -76,6 +76,7 @@ Options:
def install(opts, conf): def install(opts, conf):
"""install all dotfiles for this profile"""
dotfiles = conf.get_dotfiles(opts['profile']) dotfiles = conf.get_dotfiles(opts['profile'])
if dotfiles == []: if dotfiles == []:
msg = 'no dotfiles defined for this profile (\"{}\")' msg = 'no dotfiles defined for this profile (\"{}\")'
@@ -132,7 +133,7 @@ def install(opts, conf):
def compare(opts, conf, tmp, focus=None): def compare(opts, conf, tmp, focus=None):
'''compare dotfiles and return True if all same''' """compare dotfiles and return True if all identical"""
dotfiles = conf.get_dotfiles(opts['profile']) dotfiles = conf.get_dotfiles(opts['profile'])
if dotfiles == []: if dotfiles == []:
msg = 'no dotfiles defined for this profile (\"{}\")' msg = 'no dotfiles defined for this profile (\"{}\")'
@@ -182,6 +183,7 @@ def compare(opts, conf, tmp, focus=None):
def update(opts, conf, path): def update(opts, conf, path):
"""update the dotfile from path"""
if not os.path.exists(path): if not os.path.exists(path):
LOG.err('\"{}\" does not exist!'.format(path)) LOG.err('\"{}\" does not exist!'.format(path))
return False return False
@@ -225,6 +227,7 @@ def update(opts, conf, path):
def importer(opts, conf, paths): def importer(opts, conf, paths):
"""import dotfile(s) from paths"""
home = os.path.expanduser(TILD) home = os.path.expanduser(TILD)
cnt = 0 cnt = 0
for path in paths: for path in paths:
@@ -274,6 +277,7 @@ def importer(opts, conf, paths):
def list_profiles(conf): def list_profiles(conf):
"""list all profiles"""
LOG.log('Available profile(s):') LOG.log('Available profile(s):')
for p in conf.get_profiles(): for p in conf.get_profiles():
LOG.sub(p) LOG.sub(p)
@@ -281,6 +285,7 @@ def list_profiles(conf):
def list_files(opts, conf): def list_files(opts, conf):
"""list all dotfiles for a specific profile"""
if not opts['profile'] in conf.get_profiles(): if not opts['profile'] in conf.get_profiles():
LOG.warn('unknown profile \"{}\"'.format(opts['profile'])) LOG.warn('unknown profile \"{}\"'.format(opts['profile']))
return return
@@ -293,11 +298,13 @@ def list_files(opts, conf):
def header(): def header():
"""print the header"""
LOG.log(BANNER) LOG.log(BANNER)
LOG.log('') LOG.log('')
def main(): def main():
"""entry point"""
ret = True ret = True
args = docopt(USAGE, version=VERSION) args = docopt(USAGE, version=VERSION)
try: try:

View File

@@ -11,11 +11,11 @@ class Dotfile:
actions={}, trans=[], link=False): actions={}, trans=[], link=False):
# key of dotfile in the config # key of dotfile in the config
self.key = key self.key = key
# where to install this dotfile # path where to install this dotfile
self.dst = dst self.dst = dst
# stored dotfile in dotdrop # path where this dotfile is stored in dotdrop
self.src = src self.src = src
# should be a link # if it is a link
self.link = link self.link = link
# list of actions # list of actions
self.actions = actions self.actions = actions

View File

@@ -28,7 +28,7 @@ class Installer:
self.log = Logger(debug=self.debug) self.log = Logger(debug=self.debug)
def install(self, templater, profile, src, dst): def install(self, templater, profile, src, dst):
'''Install the dotfile for profile "profile"''' """install the src to dst using a template"""
src = os.path.join(self.base, os.path.expanduser(src)) src = os.path.join(self.base, os.path.expanduser(src))
dst = os.path.join(self.base, os.path.expanduser(dst)) dst = os.path.join(self.base, os.path.expanduser(dst))
self.log.dbg('install {} to {}'.format(src, dst)) self.log.dbg('install {} to {}'.format(src, dst))
@@ -37,7 +37,7 @@ class Installer:
return self._handle_file(templater, profile, src, dst) return self._handle_file(templater, profile, src, dst)
def link(self, src, dst): def link(self, src, dst):
'''Sets src as the link target of dst''' """set src as the link target of dst"""
src = os.path.join(self.base, os.path.expanduser(src)) src = os.path.join(self.base, os.path.expanduser(src))
dst = os.path.join(self.base, os.path.expanduser(dst)) dst = os.path.join(self.base, os.path.expanduser(dst))
if os.path.exists(dst): if os.path.exists(dst):
@@ -69,7 +69,7 @@ class Installer:
return [(src, dst)] return [(src, dst)]
def _handle_file(self, templater, profile, src, dst): def _handle_file(self, templater, profile, src, dst):
'''Install a file using templater for "profile"''' """install src to dst when is a file"""
self.log.dbg('generate template for {}'.format(src)) self.log.dbg('generate template for {}'.format(src))
content = templater.generate(src, profile) content = templater.generate(src, profile)
if content is None: if content is None:
@@ -93,7 +93,7 @@ class Installer:
return [] return []
def _handle_dir(self, templater, profile, src, dst): def _handle_dir(self, templater, profile, src, dst):
'''Install a directory using templater for "profile"''' """install src to dst when is a directory"""
ret = [] ret = []
for entry in os.listdir(src): for entry in os.listdir(src):
f = os.path.join(src, entry) f = os.path.join(src, entry)
@@ -108,17 +108,17 @@ class Installer:
return ret return ret
def _fake_diff(self, dst, content): def _fake_diff(self, dst, content):
'''Fake diff by comparing file content with "content"''' """fake diff by comparing file content with content"""
cur = '' cur = ''
with open(dst, 'br') as f: with open(dst, 'br') as f:
cur = f.read() cur = f.read()
return cur == content return cur == content
def _write(self, dst, content, rights): def _write(self, dst, content, rights):
'''Write file """write content to file
returns 0 for success, return 0 for success,
1 when already exists 1 when already exists
-1 when error''' -1 when error"""
if self.dry: if self.dry:
self.log.dry('would install {}'.format(dst)) self.log.dry('would install {}'.format(dst))
return 0 return 0
@@ -147,7 +147,7 @@ class Installer:
return 0 return 0
def _create_dirs(self, directory): def _create_dirs(self, directory):
'''mkdir -p "directory"''' """mkdir -p <directory>"""
if not self.create and not os.path.exists(directory): if not self.create and not os.path.exists(directory):
return False return False
if os.path.exists(directory): if os.path.exists(directory):
@@ -157,7 +157,7 @@ class Installer:
return os.path.exists(directory) return os.path.exists(directory)
def _backup(self, path): def _backup(self, path):
'''Backup the file''' """backup file pointed by path"""
if self.dry: if self.dry:
return return
dst = path.rstrip(os.sep) + self.BACKUP_SUFFIX dst = path.rstrip(os.sep) + self.BACKUP_SUFFIX
@@ -165,7 +165,7 @@ class Installer:
os.rename(path, dst) os.rename(path, dst)
def _install_to_temp(self, templater, profile, src, dst, tmpdir): def _install_to_temp(self, templater, profile, src, dst, tmpdir):
'''Install a dotfile to a tempdir for comparing''' """install a dotfile to a tempdir for comparing"""
sub = dst sub = dst
if dst[0] == os.sep: if dst[0] == os.sep:
sub = dst[1:] sub = dst[1:]
@@ -173,7 +173,7 @@ class Installer:
return self.install(templater, profile, src, tmpdst), tmpdst return self.install(templater, profile, src, tmpdst), tmpdst
def compare(self, templater, tmpdir, profile, src, dst, opts=''): def compare(self, templater, tmpdir, profile, src, dst, opts=''):
'''Compare temporary generated dotfile with local one''' """compare a temporary generated dotfile with the local one"""
self.comparing = True self.comparing = True
retval = False, '' retval = False, ''
drysaved = self.dry drysaved = self.dry

View File

@@ -39,7 +39,7 @@ class Templategen:
return self._handle_file(src, profile) return self._handle_file(src, profile)
def _handle_file(self, src, profile): def _handle_file(self, src, profile):
""" generate the file content from template """ """generate the file content from template"""
filetype = utils.run(['file', '-b', src], raw=False) filetype = utils.run(['file', '-b', src], raw=False)
istext = 'text' in filetype istext = 'text' in filetype
if not istext: if not istext:
@@ -47,6 +47,7 @@ class Templategen:
return self._handle_text_file(src, profile) return self._handle_text_file(src, profile)
def _handle_text_file(self, src, profile): def _handle_text_file(self, src, profile):
"""write text to file"""
template_rel_path = os.path.relpath(src, self.base) template_rel_path = os.path.relpath(src, self.base)
try: try:
template = self.env.get_template(template_rel_path) template = self.env.get_template(template_rel_path)
@@ -60,6 +61,7 @@ class Templategen:
return content return content
def _handle_bin_file(self, src, profile): def _handle_bin_file(self, src, profile):
"""write binary to file"""
# this is dirty # this is dirty
if not src.startswith(self.base): if not src.startswith(self.base):
src = os.path.join(self.base, src) src = os.path.join(self.base, src)
@@ -67,9 +69,11 @@ class Templategen:
return f.read() return f.read()
def _read_bad_encoded_text(self, path): def _read_bad_encoded_text(self, path):
"""decode non utf-8 data"""
with open(path, 'rb') as f: with open(path, 'rb') as f:
data = f.read() data = f.read()
return data.decode('utf-8', 'replace') return data.decode('utf-8', 'replace')
def get_marker(): def get_marker():
"""return identifier for template dotfile"""
return BLOCK_START return BLOCK_START

View File

@@ -15,7 +15,7 @@ from dotdrop.logger import Logger
def run(cmd, raw=True): def run(cmd, raw=True):
''' expects a list ''' """run a command in the shell (expects a list)"""
p = subprocess.Popen(cmd, shell=False, p = subprocess.Popen(cmd, shell=False,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if raw: if raw:
@@ -25,22 +25,24 @@ def run(cmd, raw=True):
def diff(src, dst, raw=True, opts=''): def diff(src, dst, raw=True, opts=''):
''' call diff to compare two files ''' """call unix diff to compare two files"""
cmd = 'diff -r {} \"{}\" \"{}\"'.format(opts, src, dst) cmd = 'diff -r {} \"{}\" \"{}\"'.format(opts, src, dst)
return run(shlex.split(cmd), raw=raw) return run(shlex.split(cmd), raw=raw)
def get_tmpdir(): def get_tmpdir():
"""create a temporary directory"""
return tempfile.mkdtemp(prefix='dotdrop-') return tempfile.mkdtemp(prefix='dotdrop-')
def get_tmpfile(): def get_tmpfile():
"""create a temporary file"""
(fd, path) = tempfile.mkstemp(prefix='dotdrop-') (fd, path) = tempfile.mkstemp(prefix='dotdrop-')
return path return path
def remove(path): def remove(path):
''' Remove a file / directory / symlink ''' """remove a file/directory/symlink"""
if not os.path.exists(path): if not os.path.exists(path):
raise OSError("File not found: {}".format(path)) raise OSError("File not found: {}".format(path))
if os.path.islink(path) or os.path.isfile(path): if os.path.islink(path) or os.path.isfile(path):