1
0
Fork 0

Merging upstream version 0.15.8.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-11 18:45:20 +01:00
parent b0e635dff4
commit 461ccdc618
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
6 changed files with 91 additions and 72 deletions

View file

@ -186,9 +186,9 @@ def f_ll(args: argparse.Namespace):
for line in utils.describe(repos, no_colors=args.no_colors):
print(' ', line)
else:
for g, g_repos in utils.get_groups().items():
for g, prop in utils.get_groups().items():
print(f'{g}:')
g_repos = {k: repos[k] for k in g_repos if k in repos}
g_repos = {k: repos[k] for k in prop['repos'] if k in repos}
for line in utils.describe(g_repos, no_colors=args.no_colors):
print(' ', line)
else:
@ -286,26 +286,16 @@ def f_rm(args: argparse.Namespace):
path_file = common.get_config_fname('repos.csv')
if os.path.isfile(path_file):
repos = utils.get_repos()
main_paths = [prop['path'] for prop in repos.values() if prop['type'] == 'm']
# TODO: add test case to delete main repo from main repo
# only local setting should be affected instead of the global one
group_updated = False
groups = utils.get_groups()
for repo in args.repo:
del repos[repo]
groups = utils.get_groups()
group_updated = group_updated or utils.delete_repo_from_groups(repo, groups)
up = utils.delete_repo_from_groups(repo, groups)
group_updated = group_updated or up
if group_updated:
utils.write_to_groups_file(groups, 'w')
# If cwd is relative to any main repo, write to local config
cwd = os.getcwd()
# TODO: delete main path mechanism
for p in main_paths:
if utils.get_relative_path(cwd, p) is not None:
utils.write_to_repo_file(repos, 'w', p)
break
else: # global config
utils.write_to_repo_file(repos, 'w')
utils.write_to_repo_file(repos, 'w')
def f_git_cmd(args: argparse.Namespace):
@ -313,20 +303,11 @@ def f_git_cmd(args: argparse.Namespace):
Delegate git command/alias defined in `args.cmd`. Asynchronous execution is
disabled for commands in the `args.async_blacklist`.
"""
repos = utils.get_repos()
groups = utils.get_groups()
ctx = utils.get_context()
if not args.repo and ctx:
args.repo = [ctx.stem]
if args.repo: # with user specified repo(s) or group(s)
chosen = {}
for k in args.repo:
if k in repos:
chosen[k] = repos[k]
if k in groups:
for r in groups[k]['repos']:
chosen[r] = repos[r]
repos = chosen
if '_parsed_repos' in args:
repos = args._parsed_repos
else:
repos, _ = utils.parse_repos_and_rest(args.repo)
per_repo_cmds = []
for prop in repos.values():
cmds = args.cmd.copy()
@ -361,29 +342,12 @@ def f_shell(args):
Delegate shell command defined in `args.man`, which may or may not
contain repo names.
"""
names = []
repos = utils.get_repos()
groups = utils.get_groups()
ctx = utils.get_context()
for i, word in enumerate(args.man):
if word in repos or word in groups:
names.append(word)
else:
break
args.repo = names
# TODO: redundant with f_git_cmd
if not args.repo and ctx:
args.repo = [ctx.stem]
if args.repo: # with user specified repo(s) or group(s)
chosen = {}
for k in args.repo:
if k in repos:
chosen[k] = repos[k]
if k in groups:
for r in groups[k]:
chosen[r] = repos[r]
repos = chosen
cmds = ' '.join(args.man[i:]) # join the shell command into a single string
repos, cmds = utils.parse_repos_and_rest(args.man)
if not cmds:
print('Missing commands')
sys.exit(2)
cmds = ' '.join(cmds) # join the shell command into a single string
for name, prop in repos.items():
# TODO: pull this out as a function
got = subprocess.run(cmds, cwd=prop['path'], shell=True,
@ -397,16 +361,13 @@ def f_super(args):
Delegate git command/alias defined in `args.man`, which may or may not
contain repo names.
"""
names = []
repos = utils.get_repos()
groups = utils.get_groups()
for i, word in enumerate(args.man):
if word in repos or word in groups:
names.append(word)
else:
break
args.cmd = ['git'] + args.man[i:]
args.repo = names
repos, cmds = utils.parse_repos_and_rest(args.man)
if not cmds:
print('Missing commands')
sys.exit(2)
args.cmd = ['git'] + cmds
args._parsed_repos = repos
args.shell = False
f_git_cmd(args)
@ -625,15 +586,15 @@ def main(argv=None):
p_super = subparsers.add_parser(
'super',
help='run any git command/alias',
description='Superman mode: delegate any git command/alias in specified or '
description='Superman mode: delegate any git command/alias in specified repo(s), group(s), or '
'all repo(s).\n'
'Examples:\n \t gita super myrepo1 commit -am "fix a bug"\n'
'\t gita super repo1 repo2 repo3 checkout new-feature')
p_super.add_argument(
'man',
nargs=argparse.REMAINDER,
help="execute arbitrary git command/alias for specified or all repos\n"
"Example: gita super myrepo1 diff --name-only --staged "
help="execute arbitrary git command/alias for specified repo(s), group(s), or all repos.\n"
"Example: gita super myrepo1 diff --name-only --staged\n"
"Another: gita super checkout master ")
p_super.set_defaults(func=f_super)
@ -641,15 +602,15 @@ def main(argv=None):
p_shell = subparsers.add_parser(
'shell',
help='run any shell command',
description='shell mode: delegate any shell command in specified or '
description='shell mode: delegate any shell command in specified repo(s), group(s), or '
'all repo(s).\n'
'Examples:\n \t gita shell pwd\n'
'Examples:\n \t gita shell pwd; \n'
'\t gita shell repo1 repo2 repo3 touch xx')
p_shell.add_argument(
'man',
nargs=argparse.REMAINDER,
help="execute arbitrary shell command for specified or all repos "
"Example: gita shell myrepo1 ls"
help="execute arbitrary shell command for specified repo(s), group(s), or all repos.\n"
"Example: gita shell myrepo1 ls\n"
"Another: gita shell git checkout master ")
p_shell.set_defaults(func=f_shell)

View file

@ -256,6 +256,10 @@ def write_to_groups_file(groups: Dict[str, Dict], mode: str):
if not groups: # all groups are deleted
open(fname, 'w').close()
else:
# delete the group if there are no repos
for name in list(groups):
if not groups[name]['repos']:
del groups[name]
with open(fname, mode, newline='') as f:
data = [
(group, ' '.join(prop['repos']), prop['path'])
@ -475,3 +479,38 @@ def get_cmds_from_files() -> Dict[str, Dict[str, str]]:
# custom commands shadow default ones
cmds.update(custom_cmds)
return cmds
def parse_repos_and_rest(input: List[str]
) -> Tuple[Dict[str, Dict[str, str]], List[str]]:
"""
Parse gita input arguments
@return: repos and the rest (e.g., gita shell and super commands)
"""
i = None
names = []
repos = get_repos()
groups = get_groups()
ctx = get_context()
for i, word in enumerate(input):
if word in repos or word in groups:
names.append(word)
else:
break
else: # all input is repos and groups, shift the index once more
if i is not None:
i += 1
if not names and ctx:
names = [ctx.stem]
if names:
chosen = {}
for k in names:
if k in repos:
chosen[k] = repos[k]
if k in groups:
for r in groups[k]['repos']:
chosen[r] = repos[r]
# if not set here, all repos are chosen
repos = chosen
return repos, input[i:]