def _update(self, path, dotfile): """update dotfile from file pointed by path""" ret = False new_path = None ignores = list(set(self.ignore + dotfile.upignore)) self.ignores = patch_ignores(ignores, dotfile.dst, debug=self.debug) if self.debug: self.log.dbg('ignore pattern(s): {}'.format(self.ignores)) path = os.path.expanduser(path) dtpath = os.path.join(self.dotpath, dotfile.src) dtpath = os.path.expanduser(dtpath) if self._ignore([path, dtpath]): self.log.sub('\"{}\" ignored'.format(dotfile.key)) return True # apply write transformation if any new_path = self._apply_trans_w(path, dotfile) if not new_path: return False if os.path.isdir(new_path): ret = self._handle_dir(new_path, dtpath) else: ret = self._handle_file(new_path, dtpath) # clean temporary files if new_path != path and os.path.exists(new_path): remove(new_path) return ret
def _update(self, path, dotfile): """update dotfile from file pointed by path""" ret = False new_path = None ignores = list(set(self.ignore + dotfile.upignore)) self.ignores = patch_ignores(ignores, dotfile.dst, debug=self.debug) if self.debug: self.log.dbg('ignore pattern(s): {}'.format(self.ignores)) deployed_path = os.path.expanduser(path) local_path = os.path.join(self.dotpath, dotfile.src) local_path = os.path.expanduser(local_path) if not os.path.exists(deployed_path): msg = '\"{}\" does not exist' self.log.err(msg.format(deployed_path)) return False if not os.path.exists(local_path): msg = '\"{}\" does not exist, import it first' self.log.err(msg.format(local_path)) return False ignore_missing_in_dotdrop = self.ignore_missing_in_dotdrop or \ dotfile.ignore_missing_in_dotdrop if (ignore_missing_in_dotdrop and not os.path.exists(local_path)) or \ self._ignore([deployed_path, local_path]): self.log.sub('\"{}\" ignored'.format(dotfile.key)) return True # apply write transformation if any new_path = self._apply_trans_w(deployed_path, dotfile) if not new_path: return False # save current rights deployed_mode = get_file_perm(deployed_path) local_mode = get_file_perm(local_path) # handle the pointed file if os.path.isdir(new_path): ret = self._handle_dir(new_path, local_path, dotfile) else: ret = self._handle_file(new_path, local_path, dotfile) if deployed_mode != local_mode: # mirror rights if self.debug: m = 'adopt mode {:o} for {}' self.log.dbg(m.format(deployed_mode, dotfile.key)) r = self.conf.update_dotfile(dotfile.key, deployed_mode) if r: ret = True # clean temporary files if new_path != deployed_path and os.path.exists(new_path): removepath(new_path, logger=self.log) return ret
def _update(self, path, dotfile): """update dotfile from file pointed by path""" ret = False new_path = None ignores = list(set(self.ignore + dotfile.upignore)) self.ignores = patch_ignores(ignores, dotfile.dst, debug=self.debug) if self.debug: self.log.dbg('ignore pattern(s): {}'.format(self.ignores)) path = os.path.expanduser(path) dtpath = os.path.join(self.dotpath, dotfile.src) dtpath = os.path.expanduser(dtpath) if self._ignore([path, dtpath]): self.log.sub('\"{}\" ignored'.format(dotfile.key)) return True # apply write transformation if any new_path = self._apply_trans_w(path, dotfile) if not new_path: return False # save current rights fsmode = get_file_perm(path) dfmode = get_file_perm(dtpath) # handle the pointed file if os.path.isdir(new_path): ret = self._handle_dir(new_path, dtpath) else: ret = self._handle_file(new_path, dtpath) if fsmode != dfmode: # mirror rights if self.debug: m = 'adopt mode {:o} for {}' self.log.dbg(m.format(fsmode, dotfile.key)) r = self.conf.update_dotfile(dotfile.key, fsmode) if r: ret = True # clean temporary files if new_path != path and os.path.exists(new_path): removepath(new_path, logger=self.log) return ret
def _dotfile_compare(o, dotfile, tmp): """ compare a dotfile returns True if same """ t = _get_templater(o) inst = Installer(create=o.create, backup=o.backup, dry=o.dry, base=o.dotpath, workdir=o.workdir, debug=o.debug, backup_suffix=o.install_backup_suffix, diff_cmd=o.diff_command) comp = Comparator(diff_cmd=o.diff_command, debug=o.debug) # add dotfile variables newvars = dotfile.get_dotfile_variables() t.add_tmp_vars(newvars=newvars) # dotfiles does not exist / not installed if o.debug: LOG.dbg('comparing {}'.format(dotfile)) src = dotfile.src if not os.path.lexists(os.path.expanduser(dotfile.dst)): line = '=> compare {}: \"{}\" does not exist on destination' LOG.log(line.format(dotfile.key, dotfile.dst)) return False # apply transformation tmpsrc = None if dotfile.trans_r: if o.debug: LOG.dbg('applying transformation before comparing') tmpsrc = apply_trans(o.dotpath, dotfile, t, debug=o.debug) if not tmpsrc: # could not apply trans return False src = tmpsrc # is a symlink pointing to itself asrc = os.path.join(o.dotpath, os.path.expanduser(src)) adst = os.path.expanduser(dotfile.dst) if os.path.samefile(asrc, adst): if o.debug: line = '=> compare {}: diffing with \"{}\"' LOG.dbg(line.format(dotfile.key, dotfile.dst)) LOG.dbg('points to itself') return True ignores = list(set(o.compare_ignore + dotfile.cmpignore)) ignores = patch_ignores(ignores, dotfile.dst, debug=o.debug) insttmp = None if dotfile.template and Templategen.is_template(src, ignore=ignores): # install dotfile to temporary dir for compare ret, err, insttmp = inst.install_to_temp(t, tmp, src, dotfile.dst, is_template=True, chmod=dotfile.chmod) if not ret: # failed to install to tmp line = '=> compare {} error: {}' LOG.log(line.format(dotfile.key, err)) LOG.err(err) return False src = insttmp # compare diff = comp.compare(src, dotfile.dst, ignore=ignores) # clean tmp transformed dotfile if any if tmpsrc: tmpsrc = os.path.join(o.dotpath, tmpsrc) if os.path.exists(tmpsrc): removepath(tmpsrc, LOG) # clean tmp template dotfile if any if insttmp: if os.path.exists(insttmp): removepath(insttmp, LOG) if diff != '': # print diff results line = '=> compare {}: diffing with \"{}\"' LOG.log(line.format(dotfile.key, dotfile.dst)) if o.compare_fileonly: LOG.raw('<files are different>') else: LOG.emph(diff) return False # no difference if o.debug: line = '=> compare {}: diffing with \"{}\"' LOG.dbg(line.format(dotfile.key, dotfile.dst)) LOG.dbg('same file') return True
def _dotfile_install(o, dotfile, tmpdir=None): """ install a dotfile returns <success, dotfile key, err> """ # installer inst = _get_install_installer(o, tmpdir=tmpdir) # templater t = _get_templater(o) # add dotfile variables newvars = dotfile.get_dotfile_variables() t.add_tmp_vars(newvars=newvars) preactions = [] if not o.install_temporary: preactions.extend(dotfile.get_pre_actions()) defactions = o.install_default_actions_pre pre_actions_exec = action_executor(o, preactions, defactions, t, post=False) if o.debug: LOG.dbg('installing dotfile: \"{}\"'.format(dotfile.key)) LOG.dbg(dotfile.prt()) ignores = list(set(o.install_ignore + dotfile.instignore)) ignores = patch_ignores(ignores, dotfile.dst, debug=o.debug) is_template = dotfile.template and Templategen.is_template( dotfile.src, ignore=ignores, ) if hasattr(dotfile, 'link') and dotfile.link == LinkTypes.LINK: # link r, err = inst.install(t, dotfile.src, dotfile.dst, dotfile.link, actionexec=pre_actions_exec, is_template=is_template, ignore=ignores, chmod=dotfile.chmod) elif hasattr(dotfile, 'link') and \ dotfile.link == LinkTypes.LINK_CHILDREN: # link_children r, err = inst.install(t, dotfile.src, dotfile.dst, dotfile.link, actionexec=pre_actions_exec, is_template=is_template, chmod=dotfile.chmod, ignore=ignores) else: # nolink src = dotfile.src tmp = None if dotfile.trans_r: tmp = apply_trans(o.dotpath, dotfile, t, debug=o.debug) if not tmp: return False, dotfile.key, None src = tmp r, err = inst.install(t, src, dotfile.dst, LinkTypes.NOLINK, actionexec=pre_actions_exec, noempty=dotfile.noempty, ignore=ignores, is_template=is_template, chmod=dotfile.chmod) if tmp: tmp = os.path.join(o.dotpath, tmp) if os.path.exists(tmp): removepath(tmp, LOG) # check result of installation if r: # dotfile was installed if not o.install_temporary: defactions = o.install_default_actions_post postactions = dotfile.get_post_actions() post_actions_exec = action_executor(o, postactions, defactions, t, post=True) post_actions_exec() else: # dotfile was NOT installed if o.install_force_action: # pre-actions if o.debug: LOG.dbg('force pre action execution ...') pre_actions_exec() # post-actions if o.debug: LOG.dbg('force post action execution ...') defactions = o.install_default_actions_post postactions = dotfile.get_post_actions() post_actions_exec = action_executor(o, postactions, defactions, t, post=True) post_actions_exec() return r, dotfile.key, err
def cmd_install(o): """install dotfiles for this profile""" dotfiles = o.dotfiles prof = o.conf.get_profile() pro_pre_actions = prof.get_pre_actions() if prof else [] pro_post_actions = prof.get_post_actions() if prof else [] if o.install_keys: # filtered dotfiles to install uniq = uniq_list(o.install_keys) dotfiles = [d for d in dotfiles if d.key in uniq] if not dotfiles: msg = 'no dotfile to install for this profile (\"{}\")' LOG.warn(msg.format(o.profile)) return False t = Templategen(base=o.dotpath, variables=o.variables, func_file=o.func_file, filter_file=o.filter_file, debug=o.debug) tmpdir = None if o.install_temporary: tmpdir = get_tmpdir() inst = Installer(create=o.create, backup=o.backup, dry=o.dry, safe=o.safe, base=o.dotpath, workdir=o.workdir, diff=o.install_diff, debug=o.debug, totemp=tmpdir, showdiff=o.install_showdiff, backup_suffix=o.install_backup_suffix, diff_cmd=o.diff_command) installed = 0 tvars = t.add_tmp_vars() # execute profile pre-action if o.debug: LOG.dbg('run {} profile pre actions'.format(len(pro_pre_actions))) ret, err = action_executor(o, pro_pre_actions, [], t, post=False)() if not ret: return False # install each dotfile for dotfile in dotfiles: # add dotfile variables t.restore_vars(tvars) newvars = dotfile.get_dotfile_variables() t.add_tmp_vars(newvars=newvars) preactions = [] if not o.install_temporary: preactions.extend(dotfile.get_pre_actions()) defactions = o.install_default_actions_pre pre_actions_exec = action_executor(o, preactions, defactions, t, post=False) if o.debug: LOG.dbg('installing dotfile: \"{}\"'.format(dotfile.key)) LOG.dbg(dotfile.prt()) if hasattr(dotfile, 'link') and dotfile.link == LinkTypes.LINK: r, err = inst.link(t, dotfile.src, dotfile.dst, actionexec=pre_actions_exec) elif hasattr(dotfile, 'link') and \ dotfile.link == LinkTypes.LINK_CHILDREN: r, err = inst.link_children(t, dotfile.src, dotfile.dst, actionexec=pre_actions_exec) else: src = dotfile.src tmp = None if dotfile.trans_r: tmp = apply_trans(o.dotpath, dotfile, t, debug=o.debug) if not tmp: continue src = tmp ignores = list(set(o.install_ignore + dotfile.instignore)) ignores = patch_ignores(ignores, dotfile.dst, debug=o.debug) r, err = inst.install(t, src, dotfile.dst, actionexec=pre_actions_exec, noempty=dotfile.noempty, ignore=ignores) if tmp: tmp = os.path.join(o.dotpath, tmp) if os.path.exists(tmp): remove(tmp) if r: # dotfile was installed if not o.install_temporary: defactions = o.install_default_actions_post postactions = dotfile.get_post_actions() post_actions_exec = action_executor(o, postactions, defactions, t, post=True) post_actions_exec() installed += 1 elif not r: # dotfile was NOT installed if o.install_force_action: # pre-actions if o.debug: LOG.dbg('force pre action execution ...') pre_actions_exec() # post-actions if o.debug: LOG.dbg('force post action execution ...') postactions = dotfile.get_post_actions() post_actions_exec = action_executor(o, postactions, defactions, t, post=True) post_actions_exec() if err: LOG.err('installing \"{}\" failed: {}'.format( dotfile.key, err)) # execute profile post-action if installed > 0 or o.install_force_action: if o.debug: msg = 'run {} profile post actions' LOG.dbg(msg.format(len(pro_post_actions))) ret, err = action_executor(o, pro_post_actions, [], t, post=False)() if not ret: return False if o.debug: LOG.dbg('install done') if o.install_temporary: LOG.log('\ninstalled to tmp \"{}\".'.format(tmpdir)) LOG.log('\n{} dotfile(s) installed.'.format(installed)) return True
def cmd_compare(o, tmp): """compare dotfiles and return True if all identical""" dotfiles = o.dotfiles if not dotfiles: msg = 'no dotfile defined for this profile (\"{}\")' LOG.warn(msg.format(o.profile)) return True # compare only specific files same = True selected = dotfiles if o.compare_focus: selected = _select(o.compare_focus, dotfiles) if len(selected) < 1: return False t = Templategen(base=o.dotpath, variables=o.variables, func_file=o.func_file, filter_file=o.filter_file, debug=o.debug) tvars = t.add_tmp_vars() inst = Installer(create=o.create, backup=o.backup, dry=o.dry, base=o.dotpath, workdir=o.workdir, debug=o.debug, backup_suffix=o.install_backup_suffix, diff_cmd=o.diff_command) comp = Comparator(diff_cmd=o.diff_command, debug=o.debug) for dotfile in selected: # add dotfile variables t.restore_vars(tvars) newvars = dotfile.get_dotfile_variables() t.add_tmp_vars(newvars=newvars) if o.debug: LOG.dbg('comparing {}'.format(dotfile)) src = dotfile.src if not os.path.lexists(os.path.expanduser(dotfile.dst)): line = '=> compare {}: \"{}\" does not exist on destination' LOG.log(line.format(dotfile.key, dotfile.dst)) same = False continue tmpsrc = None if dotfile.trans_r: # apply transformation if o.debug: LOG.dbg('applying transformation before comparing') tmpsrc = apply_trans(o.dotpath, dotfile, t, debug=o.debug) if not tmpsrc: # could not apply trans same = False continue src = tmpsrc # is a symlink pointing to itself asrc = os.path.join(o.dotpath, os.path.expanduser(src)) adst = os.path.expanduser(dotfile.dst) if os.path.samefile(asrc, adst): if o.debug: line = '=> compare {}: diffing with \"{}\"' LOG.dbg(line.format(dotfile.key, dotfile.dst)) LOG.dbg('points to itself') continue # install dotfile to temporary dir ret, insttmp = inst.install_to_temp(t, tmp, src, dotfile.dst) if not ret: # failed to install to tmp same = False continue ignores = list(set(o.compare_ignore + dotfile.cmpignore)) ignores = patch_ignores(ignores, dotfile.dst, debug=o.debug) diff = comp.compare(insttmp, dotfile.dst, ignore=ignores) if tmpsrc: # clean tmp transformed dotfile if any tmpsrc = os.path.join(o.dotpath, tmpsrc) if os.path.exists(tmpsrc): remove(tmpsrc) if diff == '': if o.debug: line = '=> compare {}: diffing with \"{}\"' LOG.dbg(line.format(dotfile.key, dotfile.dst)) LOG.dbg('same file') else: line = '=> compare {}: diffing with \"{}\"' LOG.log(line.format(dotfile.key, dotfile.dst)) LOG.emph(diff) same = False return same
def cmd_compare(o, tmp): """compare dotfiles and return True if all identical""" dotfiles = o.dotfiles if not dotfiles: msg = 'no dotfile defined for this profile (\"{}\")' LOG.warn(msg.format(o.profile)) return True # compare only specific files same = True selected = dotfiles if o.compare_focus: selected = _select(o.compare_focus, dotfiles) if len(selected) < 1: return False t = Templategen(base=o.dotpath, variables=o.variables, func_file=o.func_file, filter_file=o.filter_file, debug=o.debug) tvars = t.add_tmp_vars() inst = Installer(create=o.create, backup=o.backup, dry=o.dry, base=o.dotpath, workdir=o.workdir, debug=o.debug, backup_suffix=o.install_backup_suffix, diff_cmd=o.diff_command) comp = Comparator(diff_cmd=o.diff_command, debug=o.debug) for dotfile in selected: if not dotfile.src and not dotfile.dst: # ignore fake dotfile continue # add dotfile variables t.restore_vars(tvars) newvars = dotfile.get_dotfile_variables() t.add_tmp_vars(newvars=newvars) # dotfiles does not exist / not installed if o.debug: LOG.dbg('comparing {}'.format(dotfile)) src = dotfile.src if not os.path.lexists(os.path.expanduser(dotfile.dst)): line = '=> compare {}: \"{}\" does not exist on destination' LOG.log(line.format(dotfile.key, dotfile.dst)) same = False continue # apply transformation tmpsrc = None if dotfile.trans_r: if o.debug: LOG.dbg('applying transformation before comparing') tmpsrc = apply_trans(o.dotpath, dotfile, t, debug=o.debug) if not tmpsrc: # could not apply trans same = False continue src = tmpsrc # is a symlink pointing to itself asrc = os.path.join(o.dotpath, os.path.expanduser(src)) adst = os.path.expanduser(dotfile.dst) if os.path.samefile(asrc, adst): if o.debug: line = '=> compare {}: diffing with \"{}\"' LOG.dbg(line.format(dotfile.key, dotfile.dst)) LOG.dbg('points to itself') continue log_dst = dotfile.dst if log_dst.startswith(os.path.expanduser('~')): log_dst = log_dst.replace(os.path.expanduser('~'), '~', 1) # install dotfile to temporary dir and compare ret, err, insttmp = inst.install_to_temp(t, tmp, src, dotfile.dst, template=dotfile.template) if not ret: # failed to install to tmp line = '=> compare {}: error' LOG.log(line.format(dotfile.key, err)) LOG.err(err) same = False continue ignores = list(set(o.compare_ignore + dotfile.cmpignore)) ignores = patch_ignores(ignores, dotfile.dst, debug=o.debug) src_newer = os.path.getmtime(asrc) > os.path.getmtime(adst) if o.debug: LOG.dbg('src newer: {}'.format(src_newer)) diff = '' if o.compare_target == 'local' \ or (o.compare_target == 'smart' and not src_newer): diff = comp.compare(dotfile.dst, insttmp, ignore=ignores) diff_target = dotfile.dst else: diff = comp.compare(insttmp, dotfile.dst, ignore=ignores) diff_target = insttmp # clean tmp transformed dotfile if any if tmpsrc: tmpsrc = os.path.join(o.dotpath, tmpsrc) if os.path.exists(tmpsrc): remove(tmpsrc, LOG) if diff == '': # no difference if o.debug: line = '=> compare {}: diffing with \"{}\"' LOG.dbg(line.format(dotfile.src_key, log_dst)) LOG.dbg('same file') else: # print diff results line = '=> compare {}: diffing with \"{}\"' if diff_target == dotfile.dst: line = line.format(log_dst, dotfile.src_key) else: line = line.format(dotfile.src_key, log_dst) LOG.log(line) if o.compare_target == 'smart': if src_newer: LOG.sub('{} is newer'.format(dotfile.src_key)) else: LOG.sub('{} is newer'.format(log_dst)) if not o.compare_fileonly: LOG.emph(diff) same = False return same