Skip to content

Commit

Permalink
Merge pull request #85 from nosarthur/refactor
Browse files Browse the repository at this point in the history
change group.yml format
  • Loading branch information
nosarthur authored May 24, 2020
2 parents a4c7217 + dbe28c4 commit a2f4e7e
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 24 deletions.
19 changes: 10 additions & 9 deletions gita/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def f_ll(args: argparse.Namespace):
"""
repos = utils.get_repos()
if args.group: # only display repos in this group
group_repos = utils.get_groups()[args.group].split()
group_repos = utils.get_groups()[args.group]
repos = {k: repos[k] for k in group_repos if k in repos}
for line in utils.describe(repos):
print(line)
Expand All @@ -66,25 +66,25 @@ def f_group(args: argparse.Namespace):
if args.to_group:
gname = input('group name? ')
if gname in groups:
gname_repos = set(groups[gname].split())
gname_repos = set(groups[gname])
gname_repos.update(args.to_group)
groups[gname] = ' '.join(sorted(gname_repos))
groups[gname] = sorted(gname_repos)
utils.write_to_groups_file(groups, 'w')
else:
utils.write_to_groups_file({gname: ' '.join(sorted(args.to_group))}, 'a+')
utils.write_to_groups_file({gname: sorted(args.to_group)}, 'a+')
else:
for group, repos in groups.items():
print(f"{group}: {repos}")
print(f"{group}: {', '.join(repos)}")


def f_ungroup(args: argparse.Namespace):
groups = utils.get_groups()
to_ungroup = set(args.to_ungroup)
to_del = []
for name, repos in groups.items():
remaining = set(repos.split()) - to_ungroup
remaining = set(repos) - to_ungroup
if remaining:
groups[name] = ''.join(remaining)
groups[name] = list(sorted(remaining))
else:
to_del.append(name)
for name in to_del:
Expand Down Expand Up @@ -117,7 +117,7 @@ def f_git_cmd(args: argparse.Namespace):
if k in repos:
chosen[k] = repos[k]
if k in groups:
for r in groups[k].split():
for r in groups[k]:
chosen[r] = repos[r]
repos = chosen
cmds = ['git'] + args.cmd
Expand Down Expand Up @@ -232,7 +232,8 @@ def main(argv=None):
p_group.set_defaults(func=f_group)

p_ungroup = subparsers.add_parser(
'ungroup', help='remove group information for repos')
'ungroup', help='remove group information for repos',
description="Remove group information on repos")
p_ungroup.add_argument('to_ungroup',
nargs='+',
choices=utils.get_repos(),
Expand Down
8 changes: 3 additions & 5 deletions gita/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def get_repos() -> Dict[str, str]:


@lru_cache()
def get_groups() -> Dict[str, str]:
def get_groups() -> Dict[str, List[str]]:
"""
Return a `dict` of group name to repo names.
"""
Expand Down Expand Up @@ -98,7 +98,6 @@ def rename_repo(repos: Dict[str, str], repo: str, new_name: str):
write_to_repo_file(repos, 'w')


# TODO: combine these 2 write apis
def write_to_repo_file(repos: Dict[str, str], mode: str):
"""
"""
Expand All @@ -109,15 +108,14 @@ def write_to_repo_file(repos: Dict[str, str], mode: str):
f.write(data)


def write_to_groups_file(groups: Dict[str, str], mode: str):
def write_to_groups_file(groups: Dict[str, List[str]], mode: str):
"""
"""
data = ''.join(f'{group}: {repos}\n' for group, repos in groups.items())
fname = get_config_fname('groups.yml')
os.makedirs(os.path.dirname(fname), exist_ok=True)
with open(fname, mode) as f:
f.write(data)
yaml.dump(groups, f, default_flow_style=None)


def add_repos(repos: Dict[str, str], new_paths: List[str]):
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
setup(
name='gita',
packages=['gita'],
version='0.10.8',
version='0.10.9',
license='MIT',
description='Manage multiple git repos',
long_description=long_description,
Expand All @@ -32,6 +32,7 @@
"Topic :: Utilities",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
],
include_package_data=True,
)
16 changes: 11 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import os
from pathlib import Path
from unittest.mock import MagicMock

TEST_DIR = os.path.abspath(os.path.dirname(__file__))
PATH_FNAME = os.path.join(TEST_DIR, 'mock_path_file')
PATH_FNAME_EMPTY = os.path.join(TEST_DIR, 'empty_path_file')
PATH_FNAME_CLASH = os.path.join(TEST_DIR, 'clash_path_file')
TEST_DIR = Path(__file__).parents[0]


def fullpath(fname: str):
return str(TEST_DIR / fname)


PATH_FNAME = fullpath('mock_path_file')
PATH_FNAME_EMPTY = fullpath('empty_path_file')
PATH_FNAME_CLASH = fullpath('clash_path_file')
GROUP_FNAME = fullpath('mock_group_file')

def async_mock():
"""
Mock an async function. The calling arguments are saved in a MagicMock.
Expand Down
2 changes: 2 additions & 0 deletions tests/mock_group_file
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
xx: [a, b]
yy: [a, c, d]
33 changes: 32 additions & 1 deletion tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

from gita import __main__
from gita import utils
from conftest import PATH_FNAME, PATH_FNAME_EMPTY, PATH_FNAME_CLASH, async_mock
from conftest import (
PATH_FNAME, PATH_FNAME_EMPTY, PATH_FNAME_CLASH, GROUP_FNAME,
async_mock
)


class TestLsLl:
Expand Down Expand Up @@ -128,6 +131,34 @@ def test_superman(mock_run, _, input):
mock_run.assert_called_once_with(expected_cmds, cwd='path7')


@pytest.mark.parametrize('input, expected', [
('a', {'xx': ['b'], 'yy': ['c', 'd']}),
("c", {'xx': ['a', 'b'], 'yy': ['a', 'd']}),
("a b", {'yy': ['c', 'd']}),
])
@patch('gita.utils.get_repos', return_value={'a': '', 'b': '', 'c': '', 'd': ''})
@patch('gita.utils.get_config_fname', return_value=GROUP_FNAME)
@patch('gita.utils.write_to_groups_file')
def test_ungroup(mock_write, _, __, input, expected):
utils.get_groups.cache_clear()
args = ['ungroup'] + shlex.split(input)
__main__.main(args)
mock_write.assert_called_once_with(expected, 'w')


@patch('gita.utils.is_git', return_value=True)
@patch('gita.utils.get_config_fname', return_value=PATH_FNAME)
@patch('gita.utils.rename_repo')
def test_rename(mock_rename, _, __):
utils.get_repos.cache_clear()
args = ['rename', 'repo1', 'abc']
__main__.main(args)
mock_rename.assert_called_once_with(
{'repo1': '/a/bcd/repo1', 'repo2': '/e/fgh/repo2',
'xxx': '/a/b/c/repo3'},
'repo1', 'abc')


@patch('os.path.isfile', return_value=False)
def test_info(mock_isfile, capfd):
__main__.f_info(None)
Expand Down
17 changes: 14 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from unittest.mock import patch, mock_open

from gita import utils, info
from conftest import PATH_FNAME, PATH_FNAME_EMPTY, PATH_FNAME_CLASH
from conftest import (
PATH_FNAME, PATH_FNAME_EMPTY, PATH_FNAME_CLASH, GROUP_FNAME,
)


@pytest.mark.parametrize('test_input, diff_return, expected', [
Expand Down Expand Up @@ -43,8 +45,17 @@ def test_describe(test_input, diff_return, expected, monkeypatch):
def test_get_repos(mock_path_fname, _, path_fname, expected):
mock_path_fname.return_value = path_fname
utils.get_repos.cache_clear()
repos = utils.get_repos()
assert repos == expected
assert utils.get_repos() == expected


@pytest.mark.parametrize('group_fname, expected', [
(GROUP_FNAME, {'xx': ['a', 'b'], 'yy': ['a', 'c', 'd']}),
])
@patch('gita.utils.get_config_fname')
def test_get_groups(mock_group_fname, group_fname, expected):
mock_group_fname.return_value = group_fname
utils.get_groups.cache_clear()
assert utils.get_groups() == expected


@patch('os.path.isfile', return_value=True)
Expand Down

0 comments on commit a2f4e7e

Please sign in to comment.