# Perforce Repro Scripts This directory contains a collection of disposable, self-contained repro scripts used to demonstrate, investigate, or document Perforce (Helix Core) behaviors -- bugs, oddities, and the occasional "not a bug, but here's a demo" scenario. Each subdirectory is one repro, typically containing a `repro.sh` script and (once it has been run and reviewed) a `repro.log` capturing a sample run. ## Layout ``` repro/ / repro.sh -- the repro script itself repro.log -- a captured run of the script (stdout+stderr), submitted alongside repro.sh once the repro is confirmed useful *.p4s, *.sh -- occasional supporting fixture files (remote specs, etc.) ai_dev_support/ skills/ p4-repro-script/ -- an AI skill for generating new repro.sh scripts (and their logs) that follow the conventions documented here ``` ## Conventions used by these scripts These conventions are followed fairly strictly across the collection. New repros should match them so the whole set stays consistent and easy to skim. * **Disposable, minimalist micro-repro.** Each script builds a tiny, throwaway Perforce environment from scratch -- almost always a P4-native DVCS personal server created with `p4 init -C0 -n` in a scratch directory (default: `/tmp/repro`). Scripts do not depend on any pre-existing depot, server, or workspace. * **`P4CONFIG`/`P4ENVIRO` isolation.** Scripts set: ```bash export P4CONFIG=.p4config.local # (or .p4config in older scripts) export P4ENVIRO=/dev/null/.p4enviro ``` so the repro never picks up a real user's environment or config. * **`-f` to blast the scratch directory.** Scripts refuse to run if `$ReproDir` (usually `/tmp/repro`) already exists, unless `-f` is passed, in which case the old directory is removed first with `/bin/rm -rf`. * **Small set of "micro functions"** used throughout: * `msg "..."` -- prints an informational/narration line (supports `\n` via `echo -e`). * `errmsg "..."` -- prints an error and increments `$ErrorCount`. * `bail "..."` -- calls `errmsg` then exits with the current error count. * `cmd "some command" ["narration"]` -- prints narration (or an "Executing command: ..." default), then actually runs the command. * `usage` (in newer scripts) -- prints the `##`-prefixed usage/header comment block and exits. * **A running `$ErrorCount`.** Each check that fails calls `errmsg` (or `bail`) instead of just failing silently. The script's own exit code is `$ErrorCount`, so `0` means every expectation about the repro'd behavior held; non-zero means something about the environment or p4d version didn't reproduce as expected. * **A "Result" section at the end** that explains, in plain language, what was observed and why it matters -- written for a human who was not in the room when the bug was found, and who may forward the log to someone else (support, a developer, etc.). * **Numbered `Scenario` sections**, each announced with a big `$H1` banner (`===...===`) and a `msg "\n$H1\nScenario $N: \n"` line, so a log file reads like a narrated walkthrough rather than raw command output. * **Self-logging.** Most scripts redirect their own stdout/stderr to a log file (commonly `${ThisScript%.sh}.log`, i.e. `repro.log`) via `exec > >(tee "$Log"); exec 2>&1`, so simply running `./repro.sh` produces a shareable transcript without the caller needing to pipe through `tee` themselves. * **Once a repro is confirmed useful**, both `repro.sh` and the `repro.log` it produced are added and submitted to the depot together, so the observed behavior is preserved as evidence alongside the script that produced it. ## Generating a new repro See `ai_dev_support/skills/p4-repro-script/` for an AI skill (with templates) that captures these conventions in detail and can be used to scaffold a new `<ReproName>/repro.sh` from a plain-language description of the bug or scenario to repro.