Пример #1
0
    def test_comments_and_empty(self, tmp_path):
        fname = self.write_flist(tmp_path, '# test comment\n    '+
                '\n  # spaced comment\n')

        flist = Filelist(fname)
        assert flist.groups == {}
        assert flist.files == {}
Пример #2
0
    def test_activate_normal(self, tmp_path):
        fname = self.write_flist(tmp_path, 'file:cat1,cat2\nfile2:cat3\n')

        flist = Filelist(fname)
        assert flist.activate(['cat2']) == {
            'file': {
                'categories': ['cat1', 'cat2'],
                'plugin': 'plain',
            }}
Пример #3
0
    def test_activate_groups(self, tmp_path):
        fname = self.write_flist(tmp_path, 'group=cat1,cat2\nfile:cat1')

        flist = Filelist(fname)
        assert flist.activate(['group']) == {
            'file': {
                'categories': ['cat1'],
                'plugin': 'plain'
            }}
Пример #4
0
    def test_nocat_plugin(self, tmp_path):
        fname = self.write_flist(tmp_path, 'file|encrypt')

        flist = Filelist(fname)
        assert flist.files == {
            'file': [{
                'categories': ['common'],
                'plugin': 'encrypt'
            }]}
Пример #5
0
    def test_common_file(self, tmp_path):
        fname = self.write_flist(tmp_path, 'common_file/with/path')

        flist = Filelist(fname)
        assert flist.groups == {}
        assert flist.files == {'common_file/with/path': [{
            'categories': ['common'],
            'plugin': 'plain'
        }]}
Пример #6
0
    def test_group(self, tmp_path):
        # Test where group name != hostname
        fname = self.write_flist(tmp_path, 'group=cat1,cat2,cat3')

        flist = Filelist(fname)
        assert flist.groups == {'group': ['cat1', 'cat2', 'cat3']}
        assert flist.files == {}

        # Test where group name == hostname
        fname = self.write_flist(tmp_path,
                                 socket.gethostname() + '=cat1,cat2,cat3')

        flist = Filelist(fname)
        assert flist.groups == {
            socket.gethostname():
            ['cat1', 'cat2', 'cat3',
             socket.gethostname()]
        }
        assert flist.files == {}
Пример #7
0
    def test_file(self, tmp_path):
        fname = self.write_flist(tmp_path, 'file:cat1,cat2\nfile:cat3\n')

        flist = Filelist(fname)
        assert flist.groups == {}
        assert flist.files == {
            'file': [{
                'categories': ['cat1', 'cat2'],
                'plugin': 'plain'
            }, {
                'categories': ['cat3'],
                'plugin': 'plain'
            }]}
Пример #8
0
    def test_mix(self, tmp_path):
        fname = self.write_flist(tmp_path,
                'group=cat1,cat2\ncfile\n#comment\nnfile:cat1,cat2\n')

        flist = Filelist(fname)
        assert flist.groups == {'group': ['cat1', 'cat2']}
        assert flist.files == {
            'cfile': [{
                'categories': ['common'],
                'plugin': 'plain'
            }],
            'nfile': [{
                'categories': ['cat1', 'cat2'],
                'plugin': 'plain'
            }]}
Пример #9
0
    def test_manifest(self, tmp_path):
        fname = self.write_flist(tmp_path,
                                 'group=cat1,cat2\ncfile\nnfile:cat1,cat2\n'
                                 'gfile:group\npfile:cat1,cat2|encrypt')

        flist = Filelist(fname)
        manifest = flist.manifest()

        assert type(manifest) is dict
        assert sorted(manifest) == sorted(['plain', 'encrypt'])

        assert sorted(manifest['plain']) == sorted(['common/cfile',
                                                    'cat1/nfile', 'cat2/nfile',
                                                    'cat1/gfile',
                                                    'cat2/gfile'])

        assert sorted(manifest['encrypt']) == sorted(['cat1/pfile',
                                                      'cat2/pfile'])
Пример #10
0
    def test_group(self, tmp_path):
        fname = self.write_flist(tmp_path, 'group=cat1,cat2,cat3')

        flist = Filelist(fname)
        assert flist.groups == {'group': ['cat1', 'cat2', 'cat3']}
        assert flist.files == {}
Пример #11
0
    def test_activate_duplicate(self, tmp_path):
        fname = self.write_flist(tmp_path, 'file:cat1,cat2\nfile:cat2\n')

        flist = Filelist(fname)
        with pytest.raises(RuntimeError):
            flist.activate(['cat2'])
Пример #12
0
def main(args=None, cwd=os.getcwd(), home=info.home):
    if args is None:
        args = sys.argv[1:]

    # parse cmd arguments
    args = Arguments(args)
    logging.basicConfig(format='%(message)s ', level=args.verbose_level)
    logging.debug(f'ran with arguments {args}')

    repo = cwd
    flist_fname = os.path.join(repo, 'filelist')

    # run safety checks
    if not safety_checks(repo, home, args.action == Actions.INIT):
        logging.error(f'safety checks failed for {os.getcwd()}, exiting')
        return 1

    # check for init
    if args.action == Actions.INIT:
        init_repo(repo, flist_fname)
        return 0

    # parse filelist
    filelist = Filelist(flist_fname)
    # generate manifest for later cleaning
    manifest = filelist.manifest()
    # activate categories on filelist
    try:
        filelist = filelist.activate(args.categories)
    except RuntimeError:
        return 1

    # set up git interface
    git = Git(repo)

    # set the dotfiles repo
    dotfiles = os.path.join(repo, 'dotfiles')
    logging.debug(f'dotfiles path is {dotfiles}')

    # init plugins
    plugins_data_dir = os.path.join(repo, '.plugins')
    plugins = {
        'plain': PlainPlugin(
            data_dir=os.path.join(plugins_data_dir, 'plain'),
            repo_dir=os.path.join(dotfiles, 'plain'),
            hard=args.hard_mode),
        'encrypt': EncryptPlugin(
            data_dir=os.path.join(plugins_data_dir, 'encrypt'),
            repo_dir=os.path.join(dotfiles, 'encrypt'))
    }

    plugin_dirs = {plugin: os.path.join(dotfiles, plugin) for plugin in
                   plugins}

    if args.action in [Actions.UPDATE, Actions.RESTORE, Actions.CLEAN]:
        clean_ops = []

        # calculate and apply file operations
        for plugin in plugins:
            # filter out filelist paths that use current plugin
            flist = {path: filelist[path]['categories'] for path in filelist if
                     filelist[path]['plugin'] == plugin}
            if not flist:
                continue
            logging.debug(f'active filelist for plugin {plugin}: {flist}')

            plugin_dir = plugin_dirs[plugin]
            calc_ops = CalcOps(plugin_dir, home, plugins[plugin])

            if args.action == Actions.UPDATE:
                calc_ops.update(flist).apply(args.dry_run)
                calc_ops.restore(flist).apply(args.dry_run)
            elif args.action == Actions.RESTORE:
                calc_ops.restore(flist).apply(args.dry_run)
            elif args.action == Actions.CLEAN:
                calc_ops.clean(flist).apply(args.dry_run)

            clean_ops.append(calc_ops.clean_repo(manifest[plugin]))
            plugins[plugin].clean_data(manifest[plugin])

        # execute cleaning ops after everything else
        for clean_op in clean_ops:
            clean_op.apply(args.dry_run)

    elif args.action in [Actions.DIFF, Actions.COMMIT]:
        # calculate and apply git operations
        if args.action == Actions.DIFF:
            print('\n'.join(git.diff(ignore=['.plugins/'])))

            for plugin in plugins:
                calc_ops = CalcOps(plugin_dirs[plugin], home, plugins[plugin])
                diff = calc_ops.diff(args.categories)

                if diff:
                    print(f'\n{plugin}-plugin updates not yet in repo:')
                    print('\n'.join(diff))

        elif args.action == Actions.COMMIT:
            if not git.has_changes():
                logging.warning('no changes detected in repo, not creating '
                                'commit')
                return 0
            git.add()
            msg = git.gen_commit_message(ignore=['.plugins/'])
            git.commit(msg)

            if git.has_remote():
                ans = input('remote for repo detected, push to remote? [Yn] ')
                ans = ans if ans else 'y'
                if ans.lower() == 'y':
                    git.push()
                    logging.info('successfully pushed to git remote')

    elif args.action == Actions.PASSWD:
        logging.debug('attempting to change encryption password')
        repo = os.path.join(dotfiles, 'encrypt')
        if os.path.exists(repo):
            plugins['encrypt'].init_password()
            plugins['encrypt'].change_password(repo=repo)
        else:
            plugins['encrypt'].change_password()

    return 0