Fetch deployment dependencies over localhost SSH with GitHub fallback

This commit is contained in:
TheBadRoger committed 2026-10-15 20:55:25 +08:00
1 parent d4caf05370
commit 959dba988c
7 files changed
+130 -39

No files matched your search

+49 -26
View File
@@ -1,42 +1,65 @@
#!/usr/bin/env python3
"""Initialize pinned external submodules, preferring local repositories over SSH."""
"""Initialize pinned dependencies via localhost SSH, falling back to GitHub."""
import argparse
from pathlib import Path
import subprocess
import sys
ROOT = Path(__file__).resolve().parents[1]
PROJECTS = ['ChuSQL', 'ChuSQL-RustDriver']
PREFIX = 'ChuGit:/srv/git/'
def git(*args, **kwargs):
return subprocess.run(['git', *args], cwd=ROOT, **kwargs)
def initialize(name, override):
path = f'external/{name}'
checkout = ROOT / path
pin = git('ls-files', '--stage', '--', path, text=True, capture_output=True, check=True).stdout.split()
if len(pin) != 4 or pin[0] != '160000':
raise RuntimeError(f'{path} is missing its committed submodule pin')
if (checkout / '.git').exists():
dirty = git('-C', str(checkout), 'status', '--porcelain', text=True, capture_output=True, check=True).stdout
if dirty:
raise RuntimeError(f'{path} has local changes; refusing to overwrite them')
current = git('-C', str(checkout), 'rev-parse', '--verify', 'HEAD', text=True, capture_output=True, check=False)
if current.returncode == 0 and current.stdout.strip() == pin[1]:
print(f'{name}: pinned checkout already available', flush=True)
return
if override:
source = override.resolve()
if not source.is_dir():
raise RuntimeError(f'Local repository does not exist: {source}')
sources = [source.as_uri()]
else:
sources = [f'ssh://git@localhost/srv/git/{name}.git', f'git@github.com:TheBadRoger/{name}.git']
for url in sources:
print(f'{name}: trying {url}', flush=True)
git('config', '--local', f'submodule.{path}.url', url, check=True)
options = ['-c', 'protocol.file.allow=always'] if override else []
options += ['-c', 'core.sshCommand=ssh -o BatchMode=yes -o ConnectTimeout=10 -o ConnectionAttempts=1']
if (checkout / '.git').exists():
git('-C', str(checkout), 'remote', 'set-url', 'origin', url, check=True)
result = git(*options, '-C', str(checkout), 'fetch', '--no-tags', 'origin', pin[1], check=False)
if result.returncode == 0:
git('-C', str(checkout), 'checkout', '--detach', pin[1], check=True)
return
else:
result = git(*options, 'submodule', 'update', '--init', '--checkout', '--', path, check=False)
if result.returncode == 0:
return
print(f'{name}: source failed; trying next configured source', file=sys.stderr, flush=True)
raise RuntimeError(f'No source contains the pinned {name} commit {pin[1]}')
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--database-repo', type=Path, help='local clone/bare repository of ChuSQL')
parser.add_argument('--driver-repo', type=Path, help='local clone/bare repository of ChuSQL-RustDriver')
parser.add_argument('--database-repo', type=Path, help='explicit local development source for ChuSQL')
parser.add_argument('--driver-repo', type=Path, help='explicit local development source for the driver')
args = parser.parse_args()
git_args = []
local_config = ROOT / 'config/git-local.config'
if not args.database_repo and not args.driver_repo and all((Path('/srv/git') / f'{name}.git').is_dir() for name in PROJECTS):
current = subprocess.run(['git', 'config', '--local', '--get-all', 'include.path'], cwd=ROOT, text=True, capture_output=True, check=False)
if str(local_config) not in current.stdout.splitlines():
subprocess.run(['git', 'config', '--local', '--add', 'include.path', str(local_config)], cwd=ROOT, check=True)
git_args.extend(['-c', f'include.path={local_config}'])
for name, override in zip(PROJECTS, [args.database_repo, args.driver_repo]):
source = override or Path('/srv/git') / f'{name}.git'
if override and not source.is_dir():
parser.error(f'Local repository does not exist: {source}')
if source.is_dir():
source = source.resolve()
subprocess.run(['git', '-C', str(source), 'rev-parse', '--git-dir'], check=True, capture_output=True)
key = f'url.{source.as_uri()}.insteadOf'
url = f'{PREFIX}{name}.git'
subprocess.run(['git', 'config', '--local', '--replace-all', key, url], cwd=ROOT, check=True)
git_args.extend(['-c', f'{key}={url}'])
print(f'{name}: using local repository {source}', flush=True)
# The file protocol is enabled only for this explicit, fixed set of dependencies.
if git_args:
git_args.extend(['-c', 'protocol.file.allow=always'])
subprocess.run(['git', *git_args, 'submodule', 'update', '--init', '--', *[f'external/{name}' for name in PROJECTS]], cwd=ROOT, check=True)
initialize(name, override)
if __name__ == '__main__':