import argparse
from pathlib import Path
import shutil
import subprocess
import tempfile
REPOS = ("rustclamp", "core", "kernel", "runtime", "http", "postgres", "messaging", "worker", "scheduler")
MANIFEST = '''# Generated by rustclamp/tools/workspace.py; local coordination only.
[workspace]
resolver = "3"
members = ["rustclamp", "core", "kernel", "runtime", "http", "postgres", "messaging", "worker", "scheduler"]
exclude = ["experiments", "playground"]
# rustclamp depends on core through git (#86); the coordinated checkout uses the member.
[patch."https://github.com/rustclamp/core"]
rustclamp-core = { path = "core" }
[profile.release]
opt-level = 3
debug = false
strip = "none"
lto = false
codegen-units = 16
panic = "unwind"
'''
_WITHOUT_PATCH = MANIFEST.replace(
'\n# rustclamp depends on core through git (#86); the coordinated checkout uses the member.\n'
'[patch."https://github.com/rustclamp/core"]\nrustclamp-core = { path = "core" }\n',
'',
)
PREVIOUS_MANIFESTS = (
_WITHOUT_PATCH,
_WITHOUT_PATCH.replace(
'members = ["rustclamp", "core", "kernel", "runtime", "http", "postgres", "messaging", "worker", "scheduler"]',
'members = ["rustclamp", "core", "kernel", "runtime", "http", "postgres", "messaging", "worker"]',
),
)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--root", type=Path, default=Path(__file__).resolve().parents[2])
args = parser.parse_args()
root = args.root.resolve()
for repo in REPOS:
if not (root / repo / "Cargo.toml").is_file():
parser.error(f"missing sibling package: {root / repo}")
outputs = {
root / "Cargo.toml": MANIFEST,
root / "rust-toolchain.toml": (root / "rustclamp/rust-toolchain.toml").read_text(),
}
for path, content in outputs.items():
if path.exists() and path.read_text() != content and not (
path == root / "Cargo.toml" and path.read_text() in PREVIOUS_MANIFESTS
):
parser.error(f"refusing to replace differing file: {path}")
for path, content in outputs.items():
path.write_text(content)
(root / "workspace").mkdir(exist_ok=True)
for repo in REPOS:
lock = root / repo / "Cargo.lock"
if not lock.exists():
with tempfile.TemporaryDirectory(prefix="clamp-lock-") as tmp:
temp_root = Path(tmp)
for sibling in REPOS:
shutil.copytree(
root / sibling,
temp_root / sibling,
ignore=shutil.ignore_patterns(".git", "target", "Cargo.lock"),
)
dest = temp_root / repo
subprocess.run(["cargo", "generate-lockfile", "--offline"], cwd=dest, check=True)
shutil.copyfile(dest / "Cargo.lock", lock)
print(f"Coordination manifest: {root / 'Cargo.toml'}")
if __name__ == "__main__":
main()