clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

discover Git performance fixtures instead of naming them

Dami committed 8a2a593
Select every repository under the source directory, or a --repos subset,
and run fixtures in name order.
commit
8a2a593b1192858eaebf68333fbbe9f7b40ba53a
parent
974ca1d9aef3def7b6a0e2a82d9c05a2d486a105
author
Dami <dami.etoile@gmail.com>
2 files changed, +24 -15
Mscripts/git-performance.mjs3+--
Mscripts/prepare-git-performance.py36+++++++++++++++++++-----------
M scripts/git-performance.mjs +1 -2
M scripts/prepare-git-performance.py +23 -13
@@ -1,15 +1,21 @@
11 #!/usr/bin/env python322 """Prepare immutable bare Git benchmark fixtures and inventory corpus metadata.33 4-Usage: prepare-git-performance.py --source-directory ~/Developer --out /tmp/tinyrelay-corpus5-The output directory must not already exist. Each selected repository is cloned4+Usage: prepare-git-performance.py --source-directory ~/Developer --out /tmp/tinyrelay-corpus [--repos a,b]5+Every Git repository directly under the source directory is selected unless6+--repos names a subset. The output directory must not already exist. Each selected repository is cloned67 with --bare --no-local; the source working trees are never modified.78 """89 from __future__ import annotations910 import argparse, json, os, shutil, subprocess, tempfile1011 from pathlib import Path1112 12-NAMES = ("nzip", "bindws", "diagramzip", "strudel", "doorbearer", "atlas")13+def is_repository(path: Path) -> bool:14+ return (path / ".git").exists() or (path / "HEAD").exists()15+16+def select(source: Path, names: list[str] | None) -> list[str]:17+ if names: return names18+ return sorted(p.name for p in source.iterdir() if p.is_dir() and is_repository(p))1319 1420 def run(*args: str, cwd: Path | None = None, input: str | None = None) -> str:1521 p = subprocess.run(args, cwd=cwd, input=input, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -59,14 +65,16 @@ def inventory(repo: Path, name: str) -> dict:
5965 "blobs_over_10MiB": sum(size > 10 * 1024 * 1024 for size, _ in blob_sizes),6066 }6167 62-def prepare(source: Path, out: Path) -> list[dict]:68+def prepare(source: Path, out: Path, names: list[str] | None = None) -> list[dict]:6369 if out.exists(): raise FileExistsError(f"refusing existing destination: {out}")70+ selected = select(source, names)71+ if not selected: raise FileNotFoundError(f"no repositories under {source}")6472 out.mkdir(parents=True)6573 rows = []6674 try:67- for name in NAMES:75+ for name in selected:6876 src = source / name69- if not (src / ".git").exists() and not (src / "HEAD").exists(): raise FileNotFoundError(f"missing source repository: {src}")77+ if not is_repository(src): raise FileNotFoundError(f"missing source repository: {src}")7078 dest = out / (name + ".git")7179 run("git", "clone", "--bare", "--no-local", str(src), str(dest))7280 rows.append(inventory(dest, name))
@@ -82,24 +90,26 @@ def self_test() -> None:
8290 src.mkdir(); run("git", "init", "-b", "trunk", str(src)); run("git", "-C", str(src), "config", "user.email", "test@example.invalid"); run("git", "-C", str(src), "config", "user.name", "test")8391 (src / "tracked").write_text("tracked\n"); run("git", "-C", str(src), "add", "tracked"); run("git", "-C", str(src), "commit", "-m", "one"); run("git", "-C", str(src), "branch", "feature"); run("git", "-C", str(src), "tag", "v1")8492 (src / "uncommitted").write_text("must not be copied\n")85- # Exercise prepare() itself without copying the real corpus: six source86- # names all point at the same tiny synthetic repository.87- for name in NAMES: os.symlink(src, root / name, target_is_directory=True)88- rows = prepare(root, out)89- assert len(rows) == len(NAMES)93+ # Exercise prepare() itself without copying a real corpus: three94+ # fixture names all point at the same tiny synthetic repository.95+ names = ("alpha", "beta", "gamma")96+ for name in names: os.symlink(src, root / name, target_is_directory=True)97+ rows = prepare(root, out, list(names))98+ assert len(rows) == len(names)9099 row = rows[0]91100 assert row["head_branch"] == "refs/heads/trunk" and row["head"] == run("git", "-C", str(src), "rev-parse", "HEAD")92101 assert row["tags"] == 1 and row["all_commits"] == 193- assert "uncommitted" not in run("git", "--git-dir", str(out / "nzip.git"), "ls-tree", "-r", "--name-only", "HEAD")102+ assert "uncommitted" not in run("git", "--git-dir", str(out / "alpha.git"), "ls-tree", "-r", "--name-only", "HEAD")94103 95104 if __name__ == "__main__":96105 parser = argparse.ArgumentParser(description=__doc__)97106 parser.add_argument("--source-directory", type=Path, default=Path.home() / "Developer")98107 parser.add_argument("--out", type=Path)108+ parser.add_argument("--repos", help="comma-separated repository directory names to select")99109 parser.add_argument("--self-test", action="store_true")100110 args = parser.parse_args()101111 if args.self_test: self_test()102112 else:103113 if args.out is None: parser.error("--out is required unless --self-test is used")104- rows = prepare(args.source_directory.expanduser(), args.out.expanduser())114+ rows = prepare(args.source_directory.expanduser(), args.out.expanduser(), args.repos.split(",") if args.repos else None)105115 print(json.dumps(rows, indent=2))