# -*- coding: utf-8 -*- from __future__ import annotations from typing import TYPE_CHECKING from argparse import Namespace, ArgumentParser from ...lib.log import * from ...lib.base import InputMode from ..Cmd import Cmd from ..CmdProjects import CmdProjects from ...App import Scope if TYPE_CHECKING: from ...lib.base import Result class CmdCanonicalizeRemotes(Cmd): # export def __rewrite_url(self, url: str) -> str: return url.replace('/srv/git', '') def __init__(self, parent: CmdProjects) -> None: super().__init__(parent, 'canonicalize-remotes', help='Streamline janware Git remotes') def add_arguments(self, parser: ArgumentParser) -> None: super().add_arguments(parser) parser.add_argument('-n', '--dry-run', default=False, action='store_true', help='Only log what would be done') async def _run(self, args: Namespace) -> None: async def git(cmd: list[str], ro=False, throw=True) -> Result: cmd = ['/usr/bin/git', *cmd] log(NOTICE, f'-- {" ".join(cmd)}') if ro or not args.dry_run: return await self.app.exec_context.run(cmd, cmd_input=InputMode.NonInteractive, throw=throw) remotes: dict[str, dict[str, str]] = {} stdout, stderr, status = await git(['remote', '-v'], ro=True) for line in stdout.decode().splitlines(): name, url, fp = line.split() remote = remotes.setdefault(name, {}) key = 'url' if fp == '(fetch)' else 'pushurl' fpurls = remote.setdefault(key, []) fpurls.append(url) for remote, config in remotes.items(): dirty_keys: set[str] = set() for key, urls in config.items(): for url in urls: if url != self.__rewrite_url(url): dirty_keys.add(key) for key in dirty_keys: urls = config[key] await git(['config', '--unset-all', f'remote.{remote}.{key}'], throw=False) for url in urls: await git(['config', '--add', f'remote.{remote}.{key}', self.__rewrite_url(url)])