Ejemplo n.º 1
0
 def _pivot_path(self, path, newdir, striphome=False):
     """change path to be under newdir"""
     if self.debug:
         self.log.dbg('pivot new dir: \"{}\"'.format(newdir))
         self.log.dbg('strip home: {}'.format(striphome))
     if striphome:
         path = utils.strip_home(path)
     sub = path.lstrip(os.sep)
     new = os.path.join(newdir, sub)
     if self.debug:
         self.log.dbg('pivot \"{}\" to \"{}\"'.format(path, new))
     return new
Ejemplo n.º 2
0
 def _split_path_for_key(self, path):
     """return a list of path elements, excluded home path"""
     p = strip_home(path)
     dirs = []
     while True:
         p, f = os.path.split(p)
         dirs.append(f)
         if not p or not f:
             break
     dirs.reverse()
     # remove empty entries
     dirs = filter(None, dirs)
     # normalize entries
     return list(map(self._norm_key_elem, dirs))
Ejemplo n.º 3
0
def cmd_importer(o):
    """import dotfile(s) from paths"""
    ret = True
    cnt = 0
    paths = o.import_path
    for path in paths:
        if o.debug:
            LOG.dbg('trying to import {}'.format(path))
        if not os.path.exists(path):
            LOG.err('\"{}\" does not exist, ignored!'.format(path))
            ret = False
            continue
        dst = path.rstrip(os.sep)
        dst = os.path.abspath(dst)
        src = strip_home(dst)
        strip = '.' + os.sep
        if o.keepdot:
            strip = os.sep
        src = src.lstrip(strip)

        # create a new dotfile
        dotfile = Dotfile('', dst, src)

        linktype = LinkTypes(o.link)

        if o.debug:
            LOG.dbg('new dotfile: {}'.format(dotfile))

        # prepare hierarchy for dotfile
        srcf = os.path.join(o.dotpath, src)
        if not os.path.exists(srcf):
            cmd = ['mkdir', '-p', '{}'.format(os.path.dirname(srcf))]
            if o.dry:
                LOG.dry('would run: {}'.format(' '.join(cmd)))
            else:
                r, _ = run(cmd, raw=False, debug=o.debug, checkerr=True)
                if not r:
                    LOG.err('importing \"{}\" failed!'.format(path))
                    ret = False
                    continue
            cmd = ['cp', '-R', '-L', dst, srcf]
            if o.dry:
                LOG.dry('would run: {}'.format(' '.join(cmd)))
                if linktype == LinkTypes.PARENTS:
                    LOG.dry('would symlink {} to {}'.format(srcf, dst))
            else:
                r, _ = run(cmd, raw=False, debug=o.debug, checkerr=True)
                if not r:
                    LOG.err('importing \"{}\" failed!'.format(path))
                    ret = False
                    continue
                if linktype == LinkTypes.PARENTS:
                    remove(dst)
                    os.symlink(srcf, dst)
        retconf, dotfile = o.conf.new(dotfile,
                                      o.profile,
                                      link=linktype,
                                      debug=o.debug)
        if retconf:
            LOG.sub('\"{}\" imported'.format(path))
            cnt += 1
        else:
            LOG.warn('\"{}\" ignored'.format(path))
    if o.dry:
        LOG.dry('new config file would be:')
        LOG.raw(o.conf.dump())
    else:
        o.conf.save()
    LOG.log('\n{} file(s) imported.'.format(cnt))
    return ret
Ejemplo n.º 4
0
def get_path_strip_version(path):
    """Return the path of a file as stored in yaml config"""
    path = strip_home(path)
    path = path.lstrip('.' + os.sep)
    return path
Ejemplo n.º 5
0
def cmd_importer(o):
    """import dotfile(s) from paths"""
    ret = True
    cnt = 0
    paths = o.import_path
    for path in paths:
        if o.debug:
            LOG.dbg('trying to import {}'.format(path))
        if not os.path.exists(path):
            LOG.err('\"{}\" does not exist, ignored!'.format(path))
            ret = False
            continue
        dst = path.rstrip(os.sep)
        dst = os.path.abspath(dst)

        src = strip_home(dst)
        if o.import_as:
            # handle import as
            src = os.path.expanduser(o.import_as)
            src = src.rstrip(os.sep)
            src = os.path.abspath(src)
            src = strip_home(src)
            if o.debug:
                LOG.dbg('import src for {} as {}'.format(dst, src))

        strip = '.' + os.sep
        if o.keepdot:
            strip = os.sep
        src = src.lstrip(strip)

        # set the link attribute
        linktype = o.import_link
        if linktype == LinkTypes.LINK_CHILDREN and \
                not os.path.isdir(path):
            LOG.err('importing \"{}\" failed!'.format(path))
            ret = False
            continue

        if o.debug:
            LOG.dbg('import dotfile: src:{} dst:{}'.format(src, dst))

        # test no other dotfile exists with same
        # dst for this profile but different src
        dfs = o.conf.get_dotfile_by_dst(dst)
        if dfs:
            invalid = False
            for df in dfs:
                profiles = o.conf.get_profiles_by_dotfile_key(df.key)
                profiles = [x.key for x in profiles]
                if o.profile in profiles and \
                        not o.conf.get_dotfile_by_src_dst(src, dst):
                    # same profile
                    # different src
                    LOG.err('duplicate dotfile for this profile')
                    ret = False
                    invalid = True
                    break
            if invalid:
                continue

        # prepare hierarchy for dotfile
        srcf = os.path.join(o.dotpath, src)
        overwrite = not os.path.exists(srcf)
        if os.path.exists(srcf):
            overwrite = True
            if o.safe:
                c = Comparator(debug=o.debug, diff_cmd=o.diff_command)
                diff = c.compare(srcf, dst)
                if diff != '':
                    # files are different, dunno what to do
                    LOG.log('diff \"{}\" VS \"{}\"'.format(dst, srcf))
                    LOG.emph(diff)
                    # ask user
                    msg = 'Dotfile \"{}\" already exists, overwrite?'
                    overwrite = LOG.ask(msg.format(srcf))

        if o.debug:
            LOG.dbg('will overwrite: {}'.format(overwrite))
        if overwrite:
            cmd = ['mkdir', '-p', '{}'.format(os.path.dirname(srcf))]
            if o.dry:
                LOG.dry('would run: {}'.format(' '.join(cmd)))
            else:
                r, _ = run(cmd, raw=False, debug=o.debug, checkerr=True)
                if not r:
                    LOG.err('importing \"{}\" failed!'.format(path))
                    ret = False
                    continue
            if o.dry:
                LOG.dry('would copy {} to {}'.format(dst, srcf))
            else:
                if os.path.isdir(dst):
                    if os.path.exists(srcf):
                        shutil.rmtree(srcf)
                    shutil.copytree(dst, srcf)
                else:
                    shutil.copy2(dst, srcf)
        retconf = o.conf.new(src, dst, linktype)
        if retconf:
            LOG.sub('\"{}\" imported'.format(path))
            cnt += 1
        else:
            LOG.warn('\"{}\" ignored'.format(path))
    if o.dry:
        LOG.dry('new config file would be:')
        LOG.raw(o.conf.dump())
    else:
        o.conf.save()
    LOG.log('\n{} file(s) imported.'.format(cnt))
    return ret
Ejemplo n.º 6
0
def cmd_importer(o):
    """import dotfile(s) from paths"""
    ret = True
    cnt = 0
    paths = o.import_path
    for path in paths:
        if o.debug:
            LOG.dbg('trying to import {}'.format(path))
        if not os.path.exists(path):
            LOG.err('\"{}\" does not exist, ignored!'.format(path))
            ret = False
            continue
        dst = path.rstrip(os.sep)
        dst = os.path.abspath(dst)
        src = strip_home(dst)
        strip = '.' + os.sep
        if o.keepdot:
            strip = os.sep
        src = src.lstrip(strip)

        # set the link attribute
        linktype = o.import_link
        if linktype == LinkTypes.LINK_CHILDREN and \
                not os.path.isdir(path):
            LOG.err('importing \"{}\" failed!'.format(path))
            ret = False
            continue

        if o.debug:
            LOG.dbg('new dotfile: src:{} dst:{}'.format(src, dst))

        # prepare hierarchy for dotfile
        srcf = os.path.join(o.dotpath, src)
        overwrite = not os.path.exists(srcf)
        if os.path.exists(srcf):
            overwrite = True
            if o.safe:
                c = Comparator(debug=o.debug)
                diff = c.compare(srcf, dst)
                if diff != '':
                    # files are different, dunno what to do
                    LOG.log('diff \"{}\" VS \"{}\"'.format(dst, srcf))
                    LOG.emph(diff)
                    # ask user
                    msg = 'Dotfile \"{}\" already exists, overwrite?'
                    overwrite = LOG.ask(msg.format(srcf))

        if o.debug:
            LOG.dbg('will overwrite: {}'.format(overwrite))
        if overwrite:
            cmd = ['mkdir', '-p', '{}'.format(os.path.dirname(srcf))]
            if o.dry:
                LOG.dry('would run: {}'.format(' '.join(cmd)))
            else:
                r, _ = run(cmd, raw=False, debug=o.debug, checkerr=True)
                if not r:
                    LOG.err('importing \"{}\" failed!'.format(path))
                    ret = False
                    continue
            cmd = ['cp', '-R', '-L', dst, srcf]
            if o.dry:
                LOG.dry('would run: {}'.format(' '.join(cmd)))
            else:
                r, _ = run(cmd, raw=False, debug=o.debug, checkerr=True)
                if not r:
                    LOG.err('importing \"{}\" failed!'.format(path))
                    ret = False
                    continue
        retconf = o.conf.new(src, dst, linktype, o.profile)
        if retconf:
            LOG.sub('\"{}\" imported'.format(path))
            cnt += 1
        else:
            LOG.warn('\"{}\" ignored'.format(path))
    if o.dry:
        LOG.dry('new config file would be:')
        LOG.raw(o.conf.dump())
    else:
        o.conf.save()
    LOG.log('\n{} file(s) imported.'.format(cnt))
    return ret
Ejemplo n.º 7
0
    def _import(self,
                path,
                import_as=None,
                import_link=LinkTypes.NOLINK,
                import_mode=False):
        """
        import path
        returns:
            1: 1 dotfile imported
            0: ignored
            -1: error
        """

        # normalize path
        dst = path.rstrip(os.sep)
        dst = os.path.abspath(dst)

        # test if must be ignored
        if self._ignore(dst):
            return 0

        # ask confirmation for symlinks
        if self.safe:
            realdst = os.path.realpath(dst)
            if dst != realdst:
                msg = '\"{}\" is a symlink, dereference it and continue?'
                if not self.log.ask(msg.format(dst)):
                    return 0

        # create src path
        src = strip_home(dst)
        if import_as:
            # handle import as
            src = os.path.expanduser(import_as)
            src = src.rstrip(os.sep)
            src = os.path.abspath(src)
            src = strip_home(src)
            if self.debug:
                self.log.dbg('import src for {} as {}'.format(dst, src))
        # with or without dot prefix
        strip = '.' + os.sep
        if self.keepdot:
            strip = os.sep
        src = src.lstrip(strip)

        # get the permission
        perm = get_file_perm(dst)

        # get the link attribute
        linktype = import_link
        if linktype == LinkTypes.LINK_CHILDREN and \
                not os.path.isdir(path):
            self.log.err('importing \"{}\" failed!'.format(path))
            return -1

        if self._already_exists(src, dst):
            return -1

        if self.debug:
            self.log.dbg('import dotfile: src:{} dst:{}'.format(src, dst))

        if not self._prepare_hierarchy(src, dst):
            return -1

        # handle file mode
        chmod = None
        dflperm = get_default_file_perms(dst, self.umask)
        if self.debug:
            self.log.dbg('import mode: {}'.format(import_mode))
        if import_mode or perm != dflperm:
            if self.debug:
                msg = 'adopt mode {:o} (umask {:o})'
                self.log.dbg(msg.format(perm, dflperm))
            chmod = perm

        # add file to config file
        retconf = self.conf.new_dotfile(src, dst, linktype, chmod=chmod)
        if not retconf:
            self.log.warn('\"{}\" ignored during import'.format(path))
            return 0

        self.log.sub('\"{}\" imported'.format(path))
        return 1
Ejemplo n.º 8
0
    def _import(self,
                path,
                import_as=None,
                import_link=LinkTypes.NOLINK,
                import_mode=False):
        """
        import path
        returns:
            1: 1 dotfile imported
            0: ignored
            -1: error
        """

        # normalize path
        dst = path.rstrip(os.sep)
        dst = os.path.abspath(dst)

        # test if must be ignored
        if self._ignore(dst):
            return 0

        # ask confirmation for symlinks
        if self.safe:
            realdst = os.path.realpath(dst)
            if dst != realdst:
                msg = '\"{}\" is a symlink, dereference it and continue?'
                if not self.log.ask(msg.format(dst)):
                    return 0

        # create src path
        src = strip_home(dst)
        if import_as:
            # handle import as
            src = os.path.expanduser(import_as)
            src = src.rstrip(os.sep)
            src = os.path.abspath(src)
            src = strip_home(src)
            self.log.dbg('import src for {} as {}'.format(dst, src))
        # with or without dot prefix
        strip = '.' + os.sep
        if self.keepdot:
            strip = os.sep
        src = src.lstrip(strip)

        # get the permission
        perm = get_file_perm(dst)

        # get the link attribute
        linktype = import_link
        if linktype == LinkTypes.LINK_CHILDREN and \
                not os.path.isdir(path):
            self.log.err('importing \"{}\" failed!'.format(path))
            return -1

        if self._already_exists(src, dst):
            return -1

        self.log.dbg('import dotfile: src:{} dst:{}'.format(src, dst))

        if not self._prepare_hierarchy(src, dst):
            return -1

        return self._import_it(path, src, dst, perm, linktype, import_mode)