build.cmds.CmdListRepos: Add module

Add the command list-repos to jw-projects.py. It is meant to do the
same thing as "git-srv-adm.sh list-personal-projects", i.e. enumerate
remote Git repositories, but also support additional servers and
protocols.  As of this commit, support for https://github.com and for
forgejo installations over HTTPS is implemented.

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2025-11-18 12:56:14 +01:00
commit 9b85b3e8a6

View file

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
import re
from argparse import Namespace, ArgumentParser
from ..Cmd import Cmd
from ..lib import SSHClientCmd, get_username, get_password, run_curl
class CmdListRepos(Cmd): # export
def __init__(self) -> None:
super().__init__('list-repos', help='Query a remote GIT server for repositories')
def add_arguments(self, parser: ArgumentParser) -> None:
super().add_arguments(parser)
parser.add_argument('base_url', help='Base URL of all Git repositories')
parser.add_argument('--name-only', help='Only list names of repos, not URLs')
parser.add_argument('--username', help='Username for SSH or HTTP authentication, don\'t specify for unauthenticated', default=None)
parser.add_argument('--askpass', help='Program to echo password for SSH or HTTP authentication, don\'t specify for unauthenticated', default=None)
parser.add_argument('--from-user', help='List from-user\'s projects', default='janware')
def _run(self, args: Namespace) -> None:
from urllib.parse import urlparse
url = urlparse(args.base_url)
username = get_username(args=args, url=args.base_url)
match url.scheme:
case 'ssh':
password = get_password(args=args, url=args.base_url, askpass_env=['GIT_ASKPASS', 'SSH_ASKPASS'])
if re.match(r'ssh://.*git\.janware\.com/', args.base_url):
from jw.build.lib import SSHClientCmd as SSHClient
ssh = SSHClient(hostname=url.hostname)
if username is not None:
ssh.set_username(username)
if password is not None:
ssh.set_password(password)
cmd = f'/opt/jw-build/bin/git-srv-admin.sh -u {args.from_user} -j list-personal-projects'
out = ssh.run_cmd(cmd)
print(out)
return
case 'https':
if re.match(r'https://github.com', args.base_url):
curl_args = [
'-H',
'Accept: application/vnd.github+json',
'-H',
'X-GitHub-Api-Version: 2022-11-28',
f'https://api.github.com/users/{args.from_user}/repos'
]
repos = run_curl(curl_args)
for repo in repos:
print(repo['name'])
return
if re.match(r'https://', args.base_url):
# assume Forgejo Backend
curl_args = []
if re.match(r'https://janware.test', args.base_url):
curl_args.append('--insecure')
curl_args.extend([
f'https://{url.hostname}/code/api/v1/orgs/{args.from_user}/repos'
])
repos = run_curl(curl_args)
for repo in repos:
print(repo['name'])
return
raise Exception(f'Don\'t know how to enumerate Git repos at base url {args.base_url}')