diff --git a/dotdrop/config.py b/dotdrop/config.py index 88ed2b5..ff0ff04 100644 --- a/dotdrop/config.py +++ b/dotdrop/config.py @@ -142,7 +142,7 @@ class Cfg: # make sure we have an absolute dotpath self.curdotpath = self.configs[self.key_dotpath] - self.configs[self.key_dotpath] = self._get_abs_dotpath(self.curdotpath) + self.configs[self.key_dotpath] = self.get_abs_dotpath(self.curdotpath) return True def _get_included_dotfiles(self, profile): @@ -158,7 +158,7 @@ class Cfg: included.extend(self.prodots[other]) return included - def _get_abs_dotpath(self, dotpath): + def get_abs_dotpath(self, dotpath): """ transform dotpath to an absolute path """ if not dotpath.startswith(os.sep): absconf = os.path.join(os.path.dirname( diff --git a/dotdrop/dotdrop.py b/dotdrop/dotdrop.py index cc62ed9..eb96ae8 100644 --- a/dotdrop/dotdrop.py +++ b/dotdrop/dotdrop.py @@ -44,6 +44,7 @@ from .utils import * CUR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) LOG = Logger() HOSTNAME = os.uname()[1] +TILD = '~' BANNER = """ _ _ _ __| | ___ | |_ __| |_ __ ___ _ __ @@ -59,6 +60,7 @@ Usage: dotdrop import [-ldV] [-c ] [-p ] ... dotdrop compare [-V] [-c ] [-p ] [-o ] [--files=] + dotdrop update [-dV] [-c ] dotdrop listfiles [-V] [-c ] [-p ] dotdrop list [-V] [-c ] dotdrop --help @@ -147,8 +149,43 @@ def compare(opts, conf, tmp, focus=None): return len(selected) > 0 +def update(opts, conf, path): + if not os.path.exists(path): + LOG.err('\"%s\" does not exist!' % (path)) + return False + home = os.path.expanduser(TILD) + path = os.path.expanduser(path) + path = os.path.expandvars(path) + # normalize the path + if path.startswith(home): + path = path.lstrip(home) + path = os.path.join(TILD, path) + dotfiles = conf.get_dotfiles(opts['profile']) + l = [d for d in dotfiles if d.dst == path] + if not l: + LOG.err('\"%s\" is not managed!' % (path)) + return False + if len(l) > 1: + found = ','.join([d.src for d in dotfiles]) + LOG.err('multiple dotfiles found: %s' % (found)) + return False + dotfile = l[0] + src = os.path.join(conf.get_abs_dotpath(opts['dotpath']), dotfile.src) + if Templategen.get_marker() in open(src, 'r').read(): + LOG.warn('\"%s\" uses template, please update manually' % (src)) + return False + cmd = ['cp', '-R', '-L', os.path.expanduser(path), src] + if opts['dry']: + LOG.dry('would run: %s' % (' '.join(cmd))) + else: + if LOG.ask('Overwrite \"%s\" with \"%s\"?' % (src, path)): + run(cmd, raw=False, log=False) + LOG.log('\"%s\" updated from \"%s\".' % (src, path)) + return True + + def importer(opts, conf, paths): - home = os.path.expanduser('~') + home = os.path.expanduser(TILD) cnt = 0 for path in paths: if not os.path.exists(path): @@ -220,7 +257,7 @@ def list_files(opts, conf): def header(): LOG.log(BANNER) - LOG.log("") + LOG.log('') def main(): @@ -269,6 +306,10 @@ def main(): # import dotfile(s) importer(opts, conf, args['']) + elif args['update']: + # update a dotfile + update(opts, conf, args['']) + except KeyboardInterrupt: LOG.err('interrupted') ret = False diff --git a/dotdrop/templategen.py b/dotdrop/templategen.py index 010ecba..a556b59 100644 --- a/dotdrop/templategen.py +++ b/dotdrop/templategen.py @@ -70,3 +70,6 @@ class Templategen: with open(path, 'rb') as f: data = f.read() return data.decode('utf-8', 'replace') + + def get_marker(): + return BLOCK_START