mirror of
https://github.com/openai/codex.git
synced 2026-10-19 16:17:49 +00:00
## What changed Remove the patched `zsh` resource from package assembly and macOS signing, along with the `--zsh-bin` and `--zsh-manifest` packaging options. Delete the standalone `codex-zsh` release workflow, build scripts, and DotSlash manifests. Update package documentation and layout and signing tests to match the remaining resources. GitOrigin-RevId: 429a8db55048fed7facec89957910206523b6013
271 lines
8.9 KiB
Python
271 lines
8.9 KiB
Python
"""Command-line interface for building Codex package directories."""
|
|
|
|
import argparse
|
|
import re
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
from .archive import write_archive
|
|
from .cargo import build_source_binaries
|
|
from .layout import build_package_dir
|
|
from .layout import prepare_package_dir
|
|
from .layout import validate_package_dir
|
|
from .ripgrep import resolve_rg_bin
|
|
from .symbols import strip_binary
|
|
from .targets import PACKAGE_VARIANTS
|
|
from .targets import TARGET_SPECS
|
|
from .targets import PackageInputs
|
|
from .targets import default_target
|
|
from .targets import resolve_input_path
|
|
from .version import read_workspace_version
|
|
|
|
|
|
# Release pipelines run this builder with system Python, so avoid new dependencies.
|
|
SEMVER_PATTERN = re.compile(
|
|
r"(?P<major>0|[1-9][0-9]*)\."
|
|
r"(?P<minor>0|[1-9][0-9]*)\."
|
|
r"(?P<patch>0|[1-9][0-9]*)"
|
|
r"(?:-(?P<prerelease>[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?"
|
|
r"(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?"
|
|
)
|
|
|
|
|
|
def parse_package_version(value: str) -> str:
|
|
match = SEMVER_PATTERN.fullmatch(value)
|
|
if match is not None:
|
|
components = (match.group(name) for name in ("major", "minor", "patch"))
|
|
prerelease = match.group("prerelease") or ""
|
|
if all(int(component) <= 2**64 - 1 for component in components) and all(
|
|
not (part.isdigit() and len(part) > 1 and part.startswith("0"))
|
|
for part in prerelease.split(".")
|
|
):
|
|
return value
|
|
|
|
raise argparse.ArgumentTypeError(f"invalid semantic version: {value!r}")
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
return create_parser().parse_args()
|
|
|
|
|
|
def create_parser() -> argparse.ArgumentParser:
|
|
parser = argparse.ArgumentParser(
|
|
description="Build a canonical Codex package directory and optional archive.",
|
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
)
|
|
parser.add_argument(
|
|
"--target",
|
|
default=argparse.SUPPRESS,
|
|
choices=sorted(TARGET_SPECS),
|
|
help=(
|
|
"Rust target triple for the package. Defaults to the release target "
|
|
"for this host platform."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--variant",
|
|
choices=sorted(PACKAGE_VARIANTS),
|
|
default="codex",
|
|
help="Package variant to build.",
|
|
)
|
|
parser.add_argument(
|
|
"--package-version",
|
|
type=parse_package_version,
|
|
default=read_workspace_version(),
|
|
help="Semantic version to record in codex-package.json.",
|
|
)
|
|
parser.add_argument(
|
|
"--package-dir",
|
|
type=Path,
|
|
default=argparse.SUPPRESS,
|
|
help=(
|
|
"Output directory to create as the package root. Defaults to a new temporary directory."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--archive-output",
|
|
type=Path,
|
|
action="append",
|
|
default=[],
|
|
help=(
|
|
"Optional archive output path. May be repeated. Supported suffixes: "
|
|
".tar.gz, .tgz, .tar.zst, .zip."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--force",
|
|
action="store_true",
|
|
help="Replace an existing package directory or archive output.",
|
|
)
|
|
parser.add_argument(
|
|
"--cargo",
|
|
default="cargo",
|
|
help="Cargo executable to use for source-built package artifacts.",
|
|
)
|
|
parser.add_argument(
|
|
"--cargo-profile",
|
|
default="dev-small",
|
|
help=(
|
|
"Cargo profile for source-built package artifacts. Use release for release packages."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--strip",
|
|
choices=("auto", "all", "none"),
|
|
default="auto",
|
|
help=(
|
|
"Strip Unix first-party package binaries: auto strips source-built "
|
|
"release-profile inputs, all also strips other profiles and prebuilt "
|
|
"inputs, none preserves symbols. "
|
|
"Original inputs and third-party resources are never modified."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--strip-tool",
|
|
help="Target-compatible strip executable override, for example llvm-strip.",
|
|
)
|
|
parser.add_argument(
|
|
"--entrypoint-bin",
|
|
type=Path,
|
|
help=(
|
|
"Optional prebuilt entrypoint executable for the selected package "
|
|
"variant. If omitted, the entrypoint is built with Cargo."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--code-mode-host-bin",
|
|
type=Path,
|
|
help=(
|
|
"Optional prebuilt codex-code-mode-host executable. If omitted, "
|
|
"the host is built with Cargo."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--bwrap-bin",
|
|
type=Path,
|
|
help=(
|
|
"Optional prebuilt Linux bwrap executable. If omitted for Linux "
|
|
"targets, bwrap is built with Cargo."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--codex-command-runner-bin",
|
|
type=Path,
|
|
help=(
|
|
"Optional prebuilt Windows codex-command-runner.exe executable. "
|
|
"If omitted for Windows targets, codex-command-runner is built "
|
|
"with Cargo."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--codex-windows-sandbox-setup-bin",
|
|
type=Path,
|
|
help=(
|
|
"Optional prebuilt Windows codex-windows-sandbox-setup.exe "
|
|
"executable. If omitted for Windows targets, "
|
|
"codex-windows-sandbox-setup is built with Cargo."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--rg-bin",
|
|
type=Path,
|
|
help=(
|
|
"Optional local ripgrep executable override instead of fetching from "
|
|
"scripts/codex_package/rg."
|
|
),
|
|
)
|
|
return parser
|
|
|
|
|
|
def main() -> int:
|
|
args = parse_args()
|
|
package_dir = assemble_package(args)
|
|
archive_package(package_dir, args)
|
|
return 0
|
|
|
|
|
|
def assemble_package(args: argparse.Namespace) -> Path:
|
|
"""Build the directory before optional downstream additions and archiving."""
|
|
spec = TARGET_SPECS[getattr(args, "target", None) or default_target()]
|
|
variant = PACKAGE_VARIANTS[args.variant]
|
|
package_dir_arg = getattr(args, "package_dir", None)
|
|
package_dir = (
|
|
package_dir_arg.resolve()
|
|
if package_dir_arg is not None
|
|
else Path(tempfile.mkdtemp(prefix="codex-package-")).resolve()
|
|
)
|
|
|
|
source_outputs = build_source_binaries(
|
|
spec,
|
|
variant,
|
|
cargo=args.cargo,
|
|
profile=args.cargo_profile,
|
|
entrypoint_bin=resolve_optional_input_path(
|
|
args.entrypoint_bin,
|
|
"prebuilt entrypoint executable",
|
|
"--entrypoint-bin",
|
|
),
|
|
code_mode_host_bin=resolve_optional_input_path(
|
|
args.code_mode_host_bin,
|
|
"prebuilt code-mode host executable",
|
|
"--code-mode-host-bin",
|
|
),
|
|
bwrap_bin=resolve_optional_input_path(
|
|
args.bwrap_bin,
|
|
"prebuilt Linux bwrap executable",
|
|
"--bwrap-bin",
|
|
),
|
|
codex_command_runner_bin=resolve_optional_input_path(
|
|
args.codex_command_runner_bin,
|
|
"prebuilt Windows codex-command-runner.exe executable",
|
|
"--codex-command-runner-bin",
|
|
),
|
|
codex_windows_sandbox_setup_bin=resolve_optional_input_path(
|
|
args.codex_windows_sandbox_setup_bin,
|
|
"prebuilt Windows codex-windows-sandbox-setup.exe executable",
|
|
"--codex-windows-sandbox-setup-bin",
|
|
),
|
|
)
|
|
inputs = PackageInputs(
|
|
entrypoint_bin=source_outputs.entrypoint_bin,
|
|
code_mode_host_bin=source_outputs.code_mode_host_bin,
|
|
rg_bin=resolve_rg_bin(spec, args.rg_bin),
|
|
bwrap_bin=source_outputs.bwrap_bin,
|
|
codex_command_runner_bin=source_outputs.codex_command_runner_bin,
|
|
codex_windows_sandbox_setup_bin=source_outputs.codex_windows_sandbox_setup_bin,
|
|
)
|
|
prepare_package_dir(package_dir, force=args.force)
|
|
build_package_dir(package_dir, args.package_version, variant, spec, inputs)
|
|
for filename, prebuilt in (
|
|
(variant.entrypoint_name(spec), args.entrypoint_bin),
|
|
(f"codex-code-mode-host{spec.exe_suffix}", args.code_mode_host_bin),
|
|
):
|
|
if args.strip == "all" or (
|
|
args.strip == "auto"
|
|
and args.cargo_profile == "release"
|
|
and prebuilt is None
|
|
):
|
|
strip_binary(package_dir / "bin" / filename, spec, tool=args.strip_tool)
|
|
validate_package_dir(package_dir, variant, spec)
|
|
return package_dir
|
|
|
|
|
|
def archive_package(package_dir: Path, args: argparse.Namespace) -> None:
|
|
for archive_output in args.archive_output:
|
|
archive_path = archive_output.resolve()
|
|
write_archive(package_dir, archive_path, force=args.force)
|
|
print(f"Built Codex package archive at {archive_path}")
|
|
|
|
print(f"Built Codex package directory at {package_dir}")
|
|
|
|
|
|
def resolve_optional_input_path(
|
|
explicit_path: Path | None,
|
|
description: str,
|
|
flag_name: str,
|
|
) -> Path | None:
|
|
if explicit_path is None:
|
|
return None
|
|
|
|
return resolve_input_path(explicit_path, description, flag_name)
|