Command-line reference

This is the exhaustive reference for pekit's command line and the environment it exports to the commands it runs. Every flag listed here is a real flag accepted by the parser; there are no others. For a narrative walk-through of the grammar and recipe location, see Invocation and flags; for what each command does, see Commands and targets.

Synopsis #

pekit [global flags] <command> [args and flags]
pekit [global flags] workspace [workspace flags] <command> [args and flags]

<command> is exactly one of build, test, install, package, publish, clean, gen, verify, lock, lint, workspace, help, or version. Flags may appear before or after the command word and are parsed identically on both sides — the sole exception is the workspace tail (see Workspace flags). A bare -- ends flag parsing; every following token is captured verbatim as a positional selector. Positional selectors may not begin with -.

Help and version #

InvocationOutput
pekit help, pekit --help, pekit -hThe overview: every command with a line each, the global flags, and a pointer to this page. Exit 0.
pekit help <command>, pekit <command> --helpThat command's usage line, what its selectors mean, and its flags. Generated from the same tables the parser uses, so it cannot list a flag the command rejects. Exit 0.
pekit (no arguments)The overview on stderr, exit 1 (missing_command): nothing ran.
pekit versionpekit <module version> (<commit>[, modified]), from the binary's build info. --version and -V are the version selector, so the print form is a command.

--help wins over validation: pekit clean --version 1 --help prints help rather than unsupported_flag. help and version accept the global flags and no others; workspace cannot delegate to either.

Flag value forms #

The shape of a flag determines how its value may be written.

ShapeHow a value is written
No-valueNever takes a value. --flag=x errors with unexpected_flag_value.
Required-value--flag value or --flag=value. A missing next token, a next token that is -- or begins with -, or an empty --flag= all error with missing_flag_value.
Optional-valueValue only via --flag=value. The bare --flag is valid and means an empty value; it never consumes the following token.

Global flags #

Accepted by every command, before or after the command word. These are never subject to the capability matrix below.

FlagValue formSemantics
--recipe <path|dir>Required-valueUse this recipe instead of searching upward from the cwd. A directory means <dir>/pekit.toml. An existing local path takes precedence over remote-locator spelling such as a .git suffix.
--workspace <path|dir>Required-valueUse this workspace file/root. Valid only with the workspace command.
--allow-unusedNo-valueDowngrade "command does not support this recognised flag" from a fatal error to a suppressed notice.
--dry-runNo-valueRun the full planning pipeline but stop before any side effect; emit plan events instead.
--quietNo-valueHuman renderer, routine progress suppressed (only warning, artifact, publish, workspace_summary, lock, sign events).
--verboseNo-valueHuman renderer plus extra staging/progress events.
--jsonNo-valueEmit newline-delimited JSON events on stdout instead of the human log.

The renderer is chosen from these flags: --json selects the JSON renderer (with --dry-run it buffers and prints a single plan object); otherwise the human renderer runs, in quiet mode when --quiet is set.

Version, source, and build flags #

These are command-specific: each is only accepted by the commands marked in the capability matrix. Passing one to a command that does not support it is unsupported_flag unless --allow-unused is set.

FlagValue formMeaning
--version <v>, -V <v>Required-valueSelect a single recipe version. -V is an exact alias.
--latestNo-valueSelect only the newest available version.
--all-versionsNo-valueAct on every available version.
--lockedNo-valueMake --latest, --all-versions or a version constraint select from the versions already in the recipe's pekit.lock instead of discovering them upstream. Opt-in; see Selecting from the lock.
--local[=<path>]Optional-valueUse a local source tree instead of resolving source; bare form uses the default, =<path> overrides it.
--prefer-local[=<path>]Optional-valueUse the local source when present, otherwise resolve normally.
--no-build[=<list>]Optional-valueReuse already-staged build targets. Bare form reuses all; =a,b,c reuses only the named build targets. Only affects build-kind targets whose stage already exists, and a stage left behind by a target that did not finish is refused with stage_incomplete rather than reused.
--no-verify[=<list>]Optional-valueSkip the gen drift-check pre-flight. Bare form skips all; =a,b,c skips only the named gen targets (an unknown name errors). On package/publish it passes through to the builds they trigger.
--no-gatesNo-valuepackage/publish only: skip every gate = true test in the recipe and the lint gate, for rapid iteration. Pekit warns with the skipped gate names.
--strictNo-valuebuild/test/package/publish only: require a committed catalogue (other than pekit.lock), a source pinned in pekit.lock, and no bypass flag (strict_bypass, strict_dirty, strict_provenance). On publish, also check every install and upgrade closure of the resulting repository. See Strict mode.
--env <name>Required-valueSelect environment-file layers. main (default) loads optional env.pekit.toml; <name> loads <name>.env.pekit.toml, which must exist at the workspace or recipe root; a recipe file overlays the workspace file. none loads no env files.
--keyring <name|path>Required-valueLoad a keyring file. A bare name resolves to <name>.keyring.pekit.toml searched in the workspace root then recipe root; a path-like value is used directly. Repeatable.
--keyring.<path>=<value>Dotted, = requiredSet a single keyring value inline. Requires a non-empty dotted path and the =; otherwise invalid_keyring_flag. Repeatable.
--refresh-sourceNo-valueForce source re-materialisation, ignoring any source cache. The lockfile is still enforced against the fresh download.
--allow-unanchoredNo-valuePermit publish from source with unanchored provenance — no checksum and no lock entry (otherwise unanchored_provenance).
--allow-unsignedNo-valuePermit publish of peipkg-format packages without a configured signing key (otherwise unsigned_publish).
--replaceNo-valuepublish only: let a peipkg package overwrite an already-published package with the same name, version and architecture, instead of refusing it. Each overwritten package is reported with its old digest. This breaks the repository's promise that a published version never changes, so use it only on a repository nobody consumes yet, such as one being bootstrapped. --strict refuses it.
--repinNo-valuelock only: re-download the selected version and replace its lock entry — the explicit accept-changed-upstream-bytes ceremony. Requires an exact single --version.
--allNo-valuepackage/publish: act on every package definition instead of a selector. gen/verify: act on every gen target.
--output-onlyNo-valueclean: remove managed output only, without running a clean target.
--target-onlyNo-valueclean: run the clean target only, without removing managed output.

--version/-V, --latest, and --all-versions form one mutually-exclusive group ("version selection"); --local and --prefer-local form the "local source flags" group.

Workspace flags #

workspace delegates to another command. Its tail is parsed specially: the two workspace-only flags must appear after workspace and before the delegated command word. Everything after the delegated command is parsed as an ordinary invocation of that command.

FlagValue formMeaning
--jobs <N>, --jobs=<N>Required-value, positive integerMaximum concurrent members. Default 1. A non-integer or value <= 0 errors with invalid_flag_value.
--fail-fastNo-valueAbort the whole workspace run on the first member failure.
--journal <file>, --journal=<file>Required-value, pathRecord each member that succeeds; repeating the same run skips them. Creating <file>.stop stops the run between members (workspace_stopped). A journal from a different run is journal_mismatch. See Resumable runs.

Two member-selection flags follow the delegated command, with its own flags. Outside workspace they are an error (invalid_flags).

FlagValue formMeaning
--tag <tag>Required-value, repeatableRun only members whose recipe tags include any given tag.
--exclude-tag <tag>Required-value, repeatableSkip members whose recipe tags include any given tag. Applied after --tag.

A selection that matches no member fails with empty_workspace.

Global flags (--dry-run, --json, --recipe, …) may also appear in the tail before the delegated command. A version/source/build flag placed there is an error (missing_workspace_command, "workspace command flag … must appear after the delegated command"): those belong after the delegated command. The same code fires when no delegated command follows at all. See Workspaces.

Capability matrix #

Which command accepts which flag group. Global flags and workspace flags are omitted (global flags are accepted everywhere). A blank cell means the flag group is unsupported for that command.

Commandversion selectionlocal source--no-build--no-verify--no-gates--env--keyring--refresh-source--allow-unanchored--allow-unsigned--replace--allclean mode--repin--strict
buildYesYesYesYesYesYesYesYes
testYesYesYesYesYesYesYesYes
installYesYesYesYesYesYesYes
packageYesYesYesYesYesYesYesYesYesYes
publishYesYesYesYesYesYesYesYesYesYesYesYesYes
cleanYesYesYes
genYesYesYes
verifyYesYesYes
lockYesYesYes
lintYesYesYesYes
help
version

"clean mode" is the --output-only / --target-only pair. Plain lint acquires delegated recipe files automatically. Its version-selection and local-source flags make that source choice explicit and additionally select an existing build stage for payload rules; it never builds.

Validation and mutual-exclusion rules #

The parser rejects contradictory or malformed invocations before doing any work.

Rejected conditionDiagnostic
--quiet with --verbose--quiet and --verbose cannot be used together
--quiet with --json--quiet and --json cannot be used together
--recipe with --workspace--recipe and --workspace cannot be used together
--workspace without the workspace command--workspace can only be used with the workspace command
No command wordmissing_command
More than one of --version / --latest / --all-versionsmutually exclusive
--locked without --latest, --all-versions or a version constraint, or on lockinvalid_flags
--local with --prefer-localmutually exclusive
--output-only with --target-onlymutually exclusive
A recognised flag the effective command does not supportunsupported_flag (suppressed under --allow-unused)
clean --output-only with --env or --keyring"clean --output-only does not run a target, so … is unused" (suppressed under --allow-unused)
clean with more than one selectorinvalid_selector (clean accepts at most one)
package/publish with --all and a selector"--all cannot be combined with package selectors"
gen/verify with --all and a selector"--all cannot be combined with gen/verify target selectors"
lock with any selectorinvalid_selector (lock does not accept selectors)
lock --repin without an exact single --versioninvalid_flags (--repin requires exactly one exact --version)
lint with any selectorinvalid_selector (lint checks every package)
lint --allunsupported_flag
help <name> where <name> is not a commandunknown_command
version with any selectorinvalid_selector
workspace help or workspace versionmissing_workspace_command
--no-verify naming an unknown gen targetmissing_target
A positional selector beginning with -invalid_selector (use -- before selector-like values)

--allow-unused relaxes only the "recognised-but-unused" and "clean --output-only unused env/keyring" checks; it never excuses unknown flags, malformed values, the mutual-exclusion rules, or bad selectors.

Exit codes #

CodeMeaning
0Success.
1Any error — bad invocation, missing recipe, failed target, and so on.

There are no other exit codes.

Environment contract #

Before running a target's command, pekit constructs its environment in layers: managed PEKIT_* variables, then keyring exports, then user-declared env (workspace → source → recipe → env-file). The process inherits the parent environment with these overlaid. User env may not define any PEKIT_* variable — doing so is reserved_env. The command runs with its working directory set to the source root (or the recipe root for a clean target).

Always set #

Exported for every target pekit runs.

VariableValue
PEKIT_RECIPE_ROOTDirectory containing the resolved recipe (pekit.toml).
PEKIT_SOURCE_ROOTRoot of the materialised source tree. Equals the recipe root for a non-delegated recipe.
PEKIT_LITERAL_ROOTRoot used to resolve @source: payload references.
PEKIT_ROOTPer-source pekit work base (staging lives beneath it).
PEKIT_OUT_BASEBase directory for this source's managed output.
PEKIT_OUTThis target's own stage directory (where it should write).
PEKIT_COMMANDThe command kind running the target (build, test, install, clean, gen, verify).
PEKIT_TARGETThe target's name.
PEKIT_BUILD_TIMESTAMPRun start time, Unix seconds.
PEKIT_SOURCE_TIMESTAMPThe source's own date, Unix seconds: a Git source's commit time; a URL or PyPI source's newest archive member (fixed by the locked bytes), or the recipe's last commit when the download is not a tar archive; a local tree's, or a sourceless recipe's, last commit touching that directory. 0 when none is available (a local tree outside Git takes the run start instead).
SOURCE_DATE_EPOCHThe same value, under the reproducible-builds name that compilers, documentation generators and archivers read, so they stamp the release rather than the build. Not set when PEKIT_SOURCE_TIMESTAMP is 0. A recipe or workspace [env] may override it.
PEKIT_WORKSPACE_ROOTWorkspace root, or an empty string when not in a workspace (always set).
PEKIT_DEPENDENCIES_FILEPath to the JSON dependency payload pekit writes for this target.
PEKIT_DEPENDENCY_PROVIDERSelected env dependency provider (empty when none).
PEKIT_DEPENDENCIESResolved dependencies as name constraint lines, one per line (empty when none).

Set only in an isolated workspace #

When the workspace enables isolation, the profile's root preparer and the sandboxed target see a few more variables.

VariableSeen byValue
PEKIT_SANDBOX_ROOTRoot preparerThe fresh directory the preparer populates as the target's root.
PEKIT_JOB_STATERoot preparerCoordinator-only storage for the job, never mounted into the sandbox.
PEKIT_NATIVE_ROOTTarget1 when the profile's dependency provider is peipkg and the target has no network access; unset otherwise. A recipe built by more than one provider can use it to tell the composed native root apart.

Set only when a version is selected #

Exported only when the run resolves a non-empty version.

VariableValue
PEKIT_VERSIONFull version string, including fourth and later numeric components.
PEKIT_VERSION_MAJORFirst numeric component.
PEKIT_VERSION_MINORSecond numeric component.
PEKIT_VERSION_PATCHThird numeric component.
PEKIT_VERSION_SUFFIXUnseparated upstream suffix (may be empty).
PEKIT_VERSION_PRERELEASEPre-release component (may be empty).
PEKIT_VERSION_BUILDMETABuild-metadata component (may be empty).

Per-dependency and per-keyring variables #

Variable patternWhen setValue
PEKIT_<NEED>_OUTOne per entry in the target's needsStage directory of that needed build target. <NEED> is the target name upper-cased with - and . replaced by _. Two needs mapping to the same name is env_collision.
PEKIT_KEYRING_<PATH>One per keyring leaf loaded via --keyring / --keyring.<path>=<value>The keyring value. <PATH> is the dotted keyring path upper-cased, with each run of non-alphanumeric characters collapsed to a single _ and trailing _ trimmed. For example --keyring.token=… exports PEKIT_KEYRING_TOKEN, and a nested [registry] token = … exports PEKIT_KEYRING_REGISTRY_TOKEN.

A keyring export that collides with a managed PEKIT_* variable or with a normal env variable is env_collision.

See also #

Edit this page