From fbc2ffa22dfab7b9f9ec84644fb4544d2b6b8db0 Mon Sep 17 00:00:00 2001 From: Kyle Lacy Date: Thu, 13 Jun 2024 19:27:31 -0700 Subject: [PATCH 1/2] Update `std.ociContainerImage` to support Docker (#24) * Update `std.ociContainerImage` to add manifest for Docker compatibility * Update README for `rust_backend` example --- examples/rust_backend/README.md | 2 +- packages/std/extra/oci_container_image.bri | 92 +++++++++++++++------- 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/examples/rust_backend/README.md b/examples/rust_backend/README.md index 3a80362..51a0f3a 100644 --- a/examples/rust_backend/README.md +++ b/examples/rust_backend/README.md @@ -9,6 +9,6 @@ See [`project.bri`](./project.bri) for the Brioche build definition. - Start the server by running `brioche run -p ./examples/rust_backend`. listens on `http://localhost:8000` - Make a request to the server using Curl: `curl -v 'http://localhost:8000'` - Build a container: `brioche build -p ./examples/rust_backend -e container -o container.tar` -- Run the container with Podman: +- Run the container with Podman / Docker (example with Podman shown below): 1. Load the container with `podman load -i container.tar`. Podman will print the digest of the image, like `sha256:xxxxx` 2. Run the container with `podman run --rm -p 8000:8000 'sha256:xxxx'` (using the same digest from (1)) diff --git a/packages/std/extra/oci_container_image.bri b/packages/std/extra/oci_container_image.bri index 0b0a467..9a47824 100644 --- a/packages/std/extra/oci_container_image.bri +++ b/packages/std/extra/oci_container_image.bri @@ -15,6 +15,14 @@ interface OciContainerImageOptions { * - `recipe`: The recipe to use as the image layer. * - `entrypoint`: The entrypoint to use for the image. * Defaults to `["/brioche-run"]`. + * + * ## Notes + * + * The returned image matches the [OCI Image Layout Specification][oci-spec], + * and additionally has a manifest file following the [Docker Image Specification][docker-spec]. + * + * [oci-spec]: https://github.com/opencontainers/image-spec/blob/dd33f727e2faea07432ef6f06d6f9afe73f3f519/image-layout.md + * [docker-spec]: https://github.com/moby/docker-image-spec/blob/main/spec.md */ export function ociContainerImage( options: OciContainerImageOptions, @@ -34,35 +42,40 @@ export function ociContainerImage( ); const layerTar = tar(collectReferences(options.recipe)); - const [diffId] = await describeBlob(layerTar); + const { sha256Digest: layerSha256Digest } = await describeBlob(layerTar); + const diffId = `sha256:${layerSha256Digest}`; const layerTarGzip = gzip(layerTar); let layerDigest = ""; let layerSize = 0; - [imageDir, layerDigest, layerSize] = await addBlob(imageDir, layerTarGzip); + let layerPath = ""; + [imageDir, { digest: layerDigest, size: layerSize, path: layerPath }] = + await addBlob(imageDir, layerTarGzip); let configDigest: string = ""; let configSize: number = 0; - [imageDir, configDigest, configSize] = await addBlob( - imageDir, - std.file( - JSON.stringify({ - architecture: "amd64", - os: "linux", - config: { - Entrypoint: entrypoint, - }, - rootfs: { - type: "layers", - diff_ids: [diffId], - }, - }), - ), - ); + let configPath: string = ""; + [imageDir, { digest: configDigest, size: configSize, path: configPath }] = + await addBlob( + imageDir, + std.file( + JSON.stringify({ + architecture: "amd64", + os: "linux", + config: { + Entrypoint: entrypoint, + }, + rootfs: { + type: "layers", + diff_ids: [diffId], + }, + }), + ), + ); let manifestDigest = ""; let manifestSize = 0; - [imageDir, manifestDigest, manifestSize] = await addBlob( + [imageDir, { digest: manifestDigest, size: manifestSize }] = await addBlob( imageDir, std.file( JSON.stringify({ @@ -105,22 +118,47 @@ export function ociContainerImage( ), ); + imageDir = imageDir.insert( + "manifest.json", + std.file( + JSON.stringify([ + { + Config: configPath, + RepoTags: [], + Layers: [layerPath], + }, + ]), + ), + ); + return tar(imageDir); }); } +interface AddBlobResult { + digest: string; + size: number; + path: string; +} + async function addBlob( imageDir: std.Recipe, blob: std.Recipe, -): Promise<[std.Recipe, string, number]> { - const [digest, size] = await describeBlob(blob); - imageDir = imageDir.insert(`blobs/sha256/${digest}`, blob); - return [imageDir, `sha256:${digest}`, size]; +): Promise<[std.Recipe, AddBlobResult]> { + const { sha256Digest, size } = await describeBlob(blob); + const path = `blobs/sha256/${sha256Digest}`; + imageDir = imageDir.insert(path, blob); + return [imageDir, { digest: `sha256:${sha256Digest}`, size, path }]; +} + +interface DescribeBlobResult { + sha256Digest: string; + size: number; } async function describeBlob( file: std.AsyncRecipe, -): Promise<[string, number]> { +): Promise { const description = await runBash` sha256sum < "$file" > "$BRIOCHE_OUTPUT" wc -c < "$file" >> "$BRIOCHE_OUTPUT" @@ -133,12 +171,12 @@ async function describeBlob( throw new Error(`Invalid output from commands: ${description}`); } - const [shaHash] = sha256sum.split(" "); - if (shaHash == null || !/^[0-9a-f]{64}$/.test(shaHash)) { + const [sha256Digest] = sha256sum.split(" "); + if (sha256Digest == null || !/^[0-9a-f]{64}$/.test(sha256Digest)) { throw new Error(`Invalid sha256sum: ${sha256sum}`); } - return [shaHash, parseInt(size)]; + return { sha256Digest, size: parseInt(size) }; } // TODO: Remove once Brioche v0.1.0 is no longer supported From 126cfe7bf8b112b7ff3f8661c0a0b0c74e6e4c66 Mon Sep 17 00:00:00 2001 From: Kyle Lacy Date: Sun, 16 Jun 2024 17:48:23 -0700 Subject: [PATCH 2/2] [Breaking] Clean up the `std` package to improve compatibility (w/ other changes) (#25) * Refactor `console` and `Brioche` globals to support declaration merging * Replace `artifactType` symbol field with normal field in `Artifact` classes * Remove `recipeMarker` from `std.Recipe` type definition * Avoid unique symbols for process template components * Refactor casting utilities in `std` * Update `ProcessTemplate` serialization to avoid `instanceof` check * Clean up call to `.peel()` in `jq` package * Remove Python from `std.toolchain()` * Fix shebang scripts in `std.toolchain()` * Add new OpenSSL package * Remove OpenSSL from `std.toolchain()` in favor of separate package * Set `$CPATH` in `std.toolchain()` --- examples/nodejs_frontend/project.bri | 2 +- packages/curl/project.bri | 8 +- packages/go/project.bri | 7 +- packages/jq/project.bri | 5 +- packages/miniserve/project.bri | 3 +- packages/nodejs/project.bri | 5 +- packages/openssl/brioche.lock | 3 + packages/openssl/project.bri | 44 ++++++ packages/rust/project.bri | 12 +- packages/std/core/console.bri | 19 ++- packages/std/core/global.bri | 147 +++++++++--------- packages/std/core/recipes/artifact_type.bri | 1 - packages/std/core/recipes/cast.bri | 82 ++++++++++ packages/std/core/recipes/directory.bri | 4 +- packages/std/core/recipes/file.bri | 4 +- packages/std/core/recipes/index.bri | 1 + packages/std/core/recipes/process.bri | 113 ++++++++++++-- packages/std/core/recipes/recipe.bri | 90 +++-------- packages/std/core/recipes/symlink.bri | 7 +- packages/std/extra/autowrap.bri | 2 +- packages/std/extra/oci_container_image.bri | 8 +- packages/std/project.bri | 5 - packages/std/runnable_tools.bri | 2 +- packages/std/toolchain/native/acl.bri | 2 +- packages/std/toolchain/native/attr.bri | 2 +- packages/std/toolchain/native/autoconf.bri | 2 +- packages/std/toolchain/native/automake.bri | 2 +- packages/std/toolchain/native/bash.bri | 2 +- packages/std/toolchain/native/bc.bri | 2 +- packages/std/toolchain/native/binutils.bri | 2 +- packages/std/toolchain/native/bison.bri | 2 +- packages/std/toolchain/native/bzip2.bri | 2 +- packages/std/toolchain/native/coreutils.bri | 2 +- packages/std/toolchain/native/diffutils.bri | 2 +- packages/std/toolchain/native/expat.bri | 2 +- packages/std/toolchain/native/file.bri | 2 +- packages/std/toolchain/native/findutils.bri | 2 +- packages/std/toolchain/native/flex.bri | 2 +- packages/std/toolchain/native/gawk.bri | 2 +- packages/std/toolchain/native/gcc.bri | 2 +- packages/std/toolchain/native/gdbm.bri | 2 +- packages/std/toolchain/native/gettext.bri | 2 +- packages/std/toolchain/native/glibc.bri | 2 +- packages/std/toolchain/native/gmp.bri | 2 +- packages/std/toolchain/native/gperf.bri | 2 +- packages/std/toolchain/native/grep.bri | 2 +- packages/std/toolchain/native/groff.bri | 2 +- packages/std/toolchain/native/gzip.bri | 2 +- packages/std/toolchain/native/index.bri | 77 +++++++-- packages/std/toolchain/native/inetutils.bri | 2 +- packages/std/toolchain/native/intltool.bri | 2 +- packages/std/toolchain/native/less.bri | 2 +- packages/std/toolchain/native/libelf.bri | 2 +- packages/std/toolchain/native/libffi.bri | 36 ----- packages/std/toolchain/native/libpipeline.bri | 2 +- packages/std/toolchain/native/libtool.bri | 2 +- packages/std/toolchain/native/libxcrypt.bri | 2 +- .../std/toolchain/native/linux_headers.bri | 2 +- packages/std/toolchain/native/m4.bri | 2 +- packages/std/toolchain/native/make.bri | 2 +- packages/std/toolchain/native/man_db.bri | 2 +- packages/std/toolchain/native/mpc.bri | 2 +- packages/std/toolchain/native/mpfr.bri | 4 +- packages/std/toolchain/native/ncurses.bri | 2 +- packages/std/toolchain/native/ninja.bri | 60 ------- packages/std/toolchain/native/openssl.bri | 46 ------ packages/std/toolchain/native/patch.bri | 2 +- packages/std/toolchain/native/patchelf.bri | 2 +- packages/std/toolchain/native/perl.bri | 2 +- .../std/toolchain/native/perl_xml_parser.bri | 2 +- packages/std/toolchain/native/pkgconf.bri | 2 +- packages/std/toolchain/native/procps_ng.bri | 2 +- packages/std/toolchain/native/psmisc.bri | 2 +- packages/std/toolchain/native/python.bri | 65 -------- .../std/toolchain/native/python_flit_core.bri | 69 -------- .../std/toolchain/native/python_wheel.bri | 71 --------- packages/std/toolchain/native/readline.bri | 2 +- packages/std/toolchain/native/sed.bri | 2 +- packages/std/toolchain/native/tar.bri | 2 +- packages/std/toolchain/native/texinfo.bri | 2 +- packages/std/toolchain/native/util_linux.bri | 2 +- packages/std/toolchain/native/which.bri | 2 +- packages/std/toolchain/native/xz.bri | 2 +- packages/std/toolchain/native/zlib.bri | 2 +- packages/std/toolchain/native/zstd.bri | 2 +- packages/std/toolchain/stage0/index.bri | 2 +- packages/std/toolchain/stage2/2_17_gcc.bri | 4 - .../std/toolchain/stage2/2_19_gettext.bri | 2 +- packages/std/toolchain/stage2/2_20_bison.bri | 2 +- packages/std/toolchain/stage2/2_21_perl.bri | 8 +- packages/std/toolchain/stage2/2_22_python.bri | 2 +- .../std/toolchain/stage2/2_23_texinfo.bri | 2 +- .../std/toolchain/stage2/2_24_util_linux.bri | 2 +- packages/std/toolchain/stage2/index.bri | 2 +- 94 files changed, 489 insertions(+), 647 deletions(-) create mode 100644 packages/openssl/brioche.lock create mode 100644 packages/openssl/project.bri delete mode 100644 packages/std/core/recipes/artifact_type.bri create mode 100644 packages/std/core/recipes/cast.bri delete mode 100644 packages/std/toolchain/native/libffi.bri delete mode 100644 packages/std/toolchain/native/ninja.bri delete mode 100644 packages/std/toolchain/native/openssl.bri delete mode 100644 packages/std/toolchain/native/python.bri delete mode 100644 packages/std/toolchain/native/python_flit_core.bri delete mode 100644 packages/std/toolchain/native/python_wheel.bri diff --git a/examples/nodejs_frontend/project.bri b/examples/nodejs_frontend/project.bri index 63ae6f4..d1c089f 100644 --- a/examples/nodejs_frontend/project.bri +++ b/examples/nodejs_frontend/project.bri @@ -30,7 +30,7 @@ export function staticSite(): std.Recipe { // Setting `$LD_LIBRARY_PATH` allows Node.js to find this library. LD_LIBRARY_PATH: std.tpl`${std.toolchain()}/lib`, }) - .cast("directory"); + .toDirectory(); } // Build the static site and serve it diff --git a/packages/curl/project.bri b/packages/curl/project.bri index a518f3b..f404b86 100644 --- a/packages/curl/project.bri +++ b/packages/curl/project.bri @@ -1,4 +1,5 @@ import * as std from "std"; +import openssl from "openssl"; export const project = { name: "curl", @@ -13,8 +14,7 @@ const source = std ), }) .unarchive("tar", "gzip") - .peel() - .cast("directory"); + .peel(); export default (): std.Recipe => { const curl = std.runBash` @@ -28,8 +28,8 @@ export default (): std.Recipe => { make install DESTDIR="$BRIOCHE_OUTPUT" ` .workDir(source) - .dependencies(std.toolchain()) - .cast("directory"); + .dependencies(std.toolchain(), openssl()) + .toDirectory(); return std.withRunnableLink(curl, "bin/curl"); }; diff --git a/packages/go/project.bri b/packages/go/project.bri index ca597c8..13812a7 100644 --- a/packages/go/project.bri +++ b/packages/go/project.bri @@ -27,8 +27,7 @@ export function go(): std.Recipe { ), }) .unarchive("tar", "gzip") - .peel() - .cast("directory"); + .peel(); let go = std.directory({ go: goRoot, @@ -89,7 +88,7 @@ export async function goInstall( GOMODCACHE: modules, GOBIN: std.tpl`${std.outputPath}/bin`, }) - .cast("directory"); + .toDirectory(); if (options.runnable != null) { buildResult = std.withRunnableLink(buildResult, options.runnable); @@ -125,5 +124,5 @@ async function goModDownload( .dependencies(go(), caCertificates()) .env({ GOMODCACHE: std.outputPath }) .unsafe({ networking: true }) - .cast("directory"); + .toDirectory(); } diff --git a/packages/jq/project.bri b/packages/jq/project.bri index 24a435f..e6fbe58 100644 --- a/packages/jq/project.bri +++ b/packages/jq/project.bri @@ -13,8 +13,7 @@ const source = std ), }) .unarchive("tar", "gzip") - .peel(1) - .cast("directory"); + .peel(); export default function (): std.Recipe { const jq = std.runBash` @@ -27,7 +26,7 @@ export default function (): std.Recipe { .workDir(source) .dependencies(std.toolchain()) .env(autotoolsEnv()) - .cast("directory"); + .toDirectory(); return std.withRunnableLink(jq, "bin/jq"); } diff --git a/packages/miniserve/project.bri b/packages/miniserve/project.bri index 481a4e4..90338bb 100644 --- a/packages/miniserve/project.bri +++ b/packages/miniserve/project.bri @@ -14,8 +14,7 @@ const crate = std ), }) .unarchive("tar", "gzip") - .peel() - .cast("directory"); + .peel(); export default () => { return cargoBuild({ diff --git a/packages/nodejs/project.bri b/packages/nodejs/project.bri index 592b2bc..07241d8 100644 --- a/packages/nodejs/project.bri +++ b/packages/nodejs/project.bri @@ -20,8 +20,7 @@ function nodejs(): std.Recipe { ), }) .unarchive("tar", "xz") - .peel() - .cast("directory"); + .peel(); node = std.autowrap(node, { executables: ["bin/node"], @@ -72,5 +71,5 @@ export function npmInstall( .dependencies(nodejs()) .outputScaffold(options.npmPackage) .unsafe({ networking: true }) - .cast("directory"); + .toDirectory(); } diff --git a/packages/openssl/brioche.lock b/packages/openssl/brioche.lock new file mode 100644 index 0000000..18a1e41 --- /dev/null +++ b/packages/openssl/brioche.lock @@ -0,0 +1,3 @@ +{ + "dependencies": {} +} diff --git a/packages/openssl/project.bri b/packages/openssl/project.bri new file mode 100644 index 0000000..43a7e3b --- /dev/null +++ b/packages/openssl/project.bri @@ -0,0 +1,44 @@ +import * as std from "std"; + +export const project = { + name: "openssl", + version: "3.3.1", +}; + +const source = std + .download({ + url: `https://github.com/openssl/openssl/releases/download/openssl-${project.version}/openssl-${project.version}.tar.gz`, + hash: std.sha256Hash( + "777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e", + ), + }) + .unarchive("tar", "gzip") + .peel(); + +export default function (): std.Recipe { + let openssl = std.runBash` + ./config \\ + --prefix=/ \\ + --openssldir=/etc/ssl \\ + --libdir=lib + make + make install DESTDIR="$BRIOCHE_OUTPUT" + ` + .dependencies(std.toolchain()) + .workDir(source) + .toDirectory(); + + openssl = std.withRunnableLink(openssl, "bin/openssl"); + openssl = std.setEnv(openssl, { + LIBRARY_PATH: { path: "lib" }, + CPATH: { path: "include" }, + }); + + return std.withRunnableLink(openssl, "bin/openssl"); +} + +export function test() { + return std.runBash` + openssl version | tee "$BRIOCHE_OUTPUT" + `; +} diff --git a/packages/rust/project.bri b/packages/rust/project.bri index 58c6b9c..40a1afd 100644 --- a/packages/rust/project.bri +++ b/packages/rust/project.bri @@ -80,7 +80,7 @@ async function rust(): Promise> { --disable-ldconfig ` .env({ pkgTargetArchive }) - .cast("directory"); + .toDirectory(); result = std.merge(result, installedPkg); } @@ -89,7 +89,7 @@ async function rust(): Promise> { find lib -type f -name '*.so' -print0 > "$BRIOCHE_OUTPUT" ` .workDir(result) - .cast("file") + .toFile() .read() .then((libs) => libs.split("\0").filter((lib) => lib !== "")); const localLibNames = localLibs @@ -158,7 +158,7 @@ export function cargoBuild(options: CargoBuildOptions) { .dependencies(rust(), caCertificates()) .outputScaffold(skeletonCrate) .unsafe({ networking: true }) - .cast("directory"); + .toDirectory(); // Combine the original crate with the vendored dependencies let crate = std.merge(vendoredSkeletonCrate, options.crate); @@ -179,7 +179,7 @@ export function cargoBuild(options: CargoBuildOptions) { PATH: std.tpl`${std.outputPath}/bin`, }) .workDir(crate) - .cast("directory"); + .toDirectory(); // Add a runnable link if set in the options if (options.runnable != null) { @@ -203,7 +203,7 @@ export function createSkeletonCrate( ` .dependencies(rust(), cargoChef()) .workDir(crate) - .cast("file"); + .toFile(); return std.runBash` cd "$BRIOCHE_OUTPUT" cargo chef cook --recipe-path "$recipe" --no-build @@ -211,7 +211,7 @@ export function createSkeletonCrate( .dependencies(rust(), cargoChef()) .env({ recipe }) .outputScaffold(std.directory()) - .cast("directory"); + .toDirectory(); } function cargoChef(): std.Recipe { diff --git a/packages/std/core/console.bri b/packages/std/core/console.bri index 4f8cc7c..8d753c8 100644 --- a/packages/std/core/console.bri +++ b/packages/std/core/console.bri @@ -1,15 +1,14 @@ const ops = (globalThis as any).Deno.core.ops; declare global { - const console: Console; -} - -interface Console { - log: (...args: unknown[]) => void; - debug: (...args: unknown[]) => void; - info: (...args: unknown[]) => void; - warn: (...args: unknown[]) => void; - error: (...args: unknown[]) => void; + // eslint-disable-next-line + namespace console { + function log(...args: unknown[]): void; + function debug(...args: unknown[]): void; + function info(...args: unknown[]): void; + function warn(...args: unknown[]): void; + function error(...args: unknown[]): void; + } } const console = { @@ -28,7 +27,7 @@ const console = { error(...args: unknown[]) { logLevel("error", ...args); }, -} satisfies Console; +} satisfies typeof globalThis.console; function logLevel(level: string, ...args: unknown[]) { ops.op_brioche_console(level, displayAll(...args).join(" ")); diff --git a/packages/std/core/global.bri b/packages/std/core/global.bri index 5e7e7b4..1efc4da 100644 --- a/packages/std/core/global.bri +++ b/packages/std/core/global.bri @@ -6,80 +6,83 @@ import { } from "./recipes"; import { source } from "./source.bri"; -export interface BriocheGlobal { - /** - * Include a file from the filesystem. The path is relative to the - * current Brioche module, and cannot go outside the project root. - * - * ## Example - * - * ``` - * project/ - * ├── project.bri - * └── file.txt - * ``` - * - * ```typescript - * // project.bri - * - * // Returns a file recipe with the contents of `file.txt` - * const file = Brioche.includeFile("file.txt"); - * ``` - */ - includeFile(path: string): Recipe; +declare global { + // eslint-disable-next-line + namespace Brioche { + /** + * Include a file from the filesystem. The path is relative to the + * current Brioche module, and cannot go outside the project root. + * + * ## Example + * + * ``` + * project/ + * ├── project.bri + * └── file.txt + * ``` + * + * ```typescript + * // project.bri + * + * // Returns a file recipe with the contents of `file.txt` + * const file = Brioche.includeFile("file.txt"); + * ``` + */ + function includeFile(path: string): Recipe; - /** - * Include a directory from the filesystem. The path is relative to the - * current Brioche module, and cannot go outside the project root. - * - * ## Example - * - * ``` - * project/ - * ├── project.bri - * └── src/ - * ├── fizz.txt - * └── buzz.txt - * ``` - * - * ```typescript - * // project.bri - * - * // Returns a directory containing `fizz.txt` and `buzz.txt` - * const file = Brioche.includeDirectory("src"); - * ``` - */ - includeDirectory(path: string): Recipe; + /** + * Include a directory from the filesystem. The path is relative to the + * current Brioche module, and cannot go outside the project root. + * + * ## Example + * + * ``` + * project/ + * ├── project.bri + * └── src/ + * ├── fizz.txt + * └── buzz.txt + * ``` + * + * ```typescript + * // project.bri + * + * // Returns a directory containing `fizz.txt` and `buzz.txt` + * const file = Brioche.includeDirectory("src"); + * ``` + */ + function includeDirectory(path: string): Recipe; - /** - * Include multiple files from the filesystem using a glob pattern. The - * returned directory structure preserves the relative paths of the files, - * relative to the current Brioche module. The glob pattern will not - * match any paths if it tries going outside the current module directory. - * - * ## Example - * - * ``` - * project/ - * ├── project.bri - * ├── hello.txt - * └── src/ - * ├── foo.txt - * └── secretfile.env - * ``` - * - * ```typescript - * // project.bri - * - * // Returns a directory with this structure: - * // . - * // ├── hello.txt - * // └── src/ - * // └── foo.txt - * const file = Brioche.glob("hello.txt, src/*.txt") - * ``` - */ - glob(...patterns: string[]): Recipe; + /** + * Include multiple files from the filesystem using a glob pattern. The + * returned directory structure preserves the relative paths of the files, + * relative to the current Brioche module. The glob pattern will not + * match any paths if it tries going outside the current module directory. + * + * ## Example + * + * ``` + * project/ + * ├── project.bri + * ├── hello.txt + * └── src/ + * ├── foo.txt + * └── secretfile.env + * ``` + * + * ```typescript + * // project.bri + * + * // Returns a directory with this structure: + * // . + * // ├── hello.txt + * // └── src/ + * // └── foo.txt + * const file = Brioche.glob("hello.txt, src/*.txt") + * ``` + */ + function glob(...patterns: string[]): Recipe; + } } (globalThis as any).Brioche ??= {}; diff --git a/packages/std/core/recipes/artifact_type.bri b/packages/std/core/recipes/artifact_type.bri deleted file mode 100644 index 0746695..0000000 --- a/packages/std/core/recipes/artifact_type.bri +++ /dev/null @@ -1 +0,0 @@ -export const artifactType: unique symbol = Symbol("artifactType"); diff --git a/packages/std/core/recipes/cast.bri b/packages/std/core/recipes/cast.bri new file mode 100644 index 0000000..c75fd1f --- /dev/null +++ b/packages/std/core/recipes/cast.bri @@ -0,0 +1,82 @@ +import { + type AsyncRecipe, + type Recipe, + type Artifact, + createRecipe, +} from "./recipe.bri"; +import type { File } from "./file.bri"; +import type { Directory } from "./directory.bri"; +import type { Symlink } from "./symlink.bri"; + +interface CastOptions { + sourceDepth?: number; +} + +/** + * Cast a generic recipe to a file recipe. This is useful for cases like + * `std.process()`, or `.get()`, where the output type is not known until + * runtime. The cast will be validated when the recipe is baked. + */ +export function castToFile( + recipe: AsyncRecipe, + options: CastOptions = {}, +): T extends File ? Recipe : never { + return createRecipe(["file"], { + sourceDepth: (options.sourceDepth ?? 0) + 1, + briocheSerialize: async (meta) => { + const serializedRecipe = await (await recipe).briocheSerialize(); + return { + meta, + type: "cast", + recipe: serializedRecipe, + to: "file", + }; + }, + }) as T extends File ? Recipe : never; +} + +/** + * Cast a generic recipe to a directory recipe. This is useful for cases like + * `std.process()`, or `.get()`, where the output type is not known until + * runtime. The cast will be validated when the recipe is baked. + */ +export function castToDirectory( + recipe: AsyncRecipe, + options: CastOptions = {}, +): T extends Directory ? Recipe : never { + return createRecipe(["directory"], { + sourceDepth: (options.sourceDepth ?? 0) + 1, + briocheSerialize: async (meta) => { + const serializedRecipe = await (await recipe).briocheSerialize(); + return { + meta, + type: "cast", + recipe: serializedRecipe, + to: "directory", + }; + }, + }) as T extends Directory ? Recipe : never; +} + +/** + * Cast a generic recipe to a symlink recipe. This is useful for cases like + * `std.process()`, or `.get()`, where the output type is not known until + * runtime. The cast will be validated when the recipe is baked. + */ +export function castToSymlink( + recipe: AsyncRecipe, + options: CastOptions = {}, +): T extends Symlink ? Recipe : never { + return createRecipe(["symlink"], { + sourceDepth: (options.sourceDepth ?? 0) + 1, + briocheSerialize: async (meta) => { + const serializedRecipe = await (await recipe).briocheSerialize(); + return { + meta, + type: "cast", + recipe: serializedRecipe, + to: "symlink", + }; + }, + }) as T extends Symlink ? Recipe : never; +} diff --git a/packages/std/core/recipes/directory.bri b/packages/std/core/recipes/directory.bri index 005e478..dd4a119 100644 --- a/packages/std/core/recipes/directory.bri +++ b/packages/std/core/recipes/directory.bri @@ -7,7 +7,6 @@ import { createRecipe, directoryRecipeUtils, } from "./recipe.bri"; -import { artifactType } from "./artifact_type.bri"; /** * Constructs a new directory. Takes an object argument, where each key @@ -80,7 +79,7 @@ interface DirectoryCtor { } export class Directory implements Recipe { - [artifactType]: "directory" = "directory"; + artifactType: "directory" = "directory"; entries: Record; source?: runtime.Source; @@ -115,5 +114,4 @@ export class Directory implements Recipe { insert = directoryRecipeUtils.insert; remove = directoryRecipeUtils.remove; peel = directoryRecipeUtils.peel; - cast = directoryRecipeUtils.cast; } diff --git a/packages/std/core/recipes/file.bri b/packages/std/core/recipes/file.bri index 7136329..39535ca 100644 --- a/packages/std/core/recipes/file.bri +++ b/packages/std/core/recipes/file.bri @@ -1,7 +1,6 @@ import * as runtime from "../runtime.bri"; import { assert } from "../utils.bri"; import { type Recipe, createRecipe, fileRecipeUtils } from "./recipe.bri"; -import { artifactType } from "./artifact_type.bri"; /** * Create a new file, which contains the provided content. @@ -43,7 +42,7 @@ export interface FileCtor { } export class File implements Recipe { - [artifactType]: "file" = "file"; + artifactType: "file" = "file"; source?: runtime.Source; contentBlob: runtime.BlobHash; executable: boolean; @@ -85,7 +84,6 @@ export class File implements Recipe { }); } - cast = fileRecipeUtils.cast; withPermissions = fileRecipeUtils.withPermissions; unarchive = fileRecipeUtils.unarchive; readBytes = fileRecipeUtils.readBytes; diff --git a/packages/std/core/recipes/index.bri b/packages/std/core/recipes/index.bri index f7d45be..f6489f9 100644 --- a/packages/std/core/recipes/index.bri +++ b/packages/std/core/recipes/index.bri @@ -1,3 +1,4 @@ +export { castToFile, castToDirectory, castToSymlink } from "./cast.bri"; export { directory, merge, Directory } from "./directory.bri"; export { download, type DownloadOptions } from "./download.bri"; export { File, file } from "./file.bri"; diff --git a/packages/std/core/recipes/process.bri b/packages/std/core/recipes/process.bri index ef3ded0..cb17f60 100644 --- a/packages/std/core/recipes/process.bri +++ b/packages/std/core/recipes/process.bri @@ -1,7 +1,10 @@ import { Awaitable, mixin } from "../utils.bri"; import * as runtime from "../runtime.bri"; +import type { File } from "./file.bri"; import { type Directory, directory } from "./directory.bri"; +import type { Symlink } from "./symlink.bri"; import { type AsyncRecipe, type Recipe, createRecipe } from "./recipe.bri"; +import { castToFile, castToDirectory, castToSymlink } from "./cast.bri"; export type ProcessOptions = { command: ProcessTemplateLike; @@ -48,6 +51,24 @@ export interface ProcessUtils { * Returns a new process with unsafe options set. */ unsafe(unsafeOptions: ProcessUnsafe): Process; + + /** + * Cast the process's output to a file recipe. This will fail to bake if + * the process does not write a file to `$BRIOCHE_OUTPUT`. + */ + toFile(): Recipe; + + /** + * Cast the process's output to a directory recipe. This will fail to bake + * if the process does not write a directory to `$BRIOCHE_OUTPUT`. + */ + toDirectory(): Recipe; + + /** + * Cast the process's output to a symlink recipe. This will fail to bake + * if the process does not write a symlink to `$BRIOCHE_OUTPUT`. + */ + toSymlink(): Recipe; } /** @@ -182,6 +203,15 @@ export function process(options: ProcessOptions): Process { ...unsafeOptions, }); }, + toFile(this: Process): Recipe { + return castToFile(this, { sourceDepth: 1 }); + }, + toDirectory(this: Process): Recipe { + return castToDirectory(this, { sourceDepth: 1 }); + }, + toSymlink(this: Process): Recipe { + return castToSymlink(this, { sourceDepth: 1 }); + }, } satisfies ProcessUtils); } @@ -212,43 +242,88 @@ export function tpl( return new ProcessTemplate(...components); } +// This is a branded type for one of the symbol type of process template +// components. Note that we avoid true symbol/branded types so the types can +// be structurally equivalent across different versions of `std`. +type ProcessTemplateSymbol = { + componentType: K; +} & { + [key in K]: never; +}; + /** * Expands to the path where the process should write its output. Equivalent * to the default environment variable `$BRIOCHE_OUTPUT`. */ -export const outputPath: unique symbol = Symbol("outputPath"); +// eslint-disable-next-line +export const outputPath = { + componentType: "outputPath", +} as OutputPath; +type OutputPath = ProcessTemplateSymbol<"outputPath">; /** * Expands to the directory where the process can write resources to that * can then be referenced by files in the process's output. Equivalent * to the default environment variable `$BRIOCHE_RESOURCE_DIR`. */ -export const resourceDir: unique symbol = Symbol("resourceDir"); +// eslint-disable-next-line +export const resourceDir = { + componentType: "resourceDir", +} as ResourceDir; +type ResourceDir = ProcessTemplateSymbol<"resourceDir">; /** * Expands to a `:`-delimited list of directories where the process can find * resources from its inputs. These directories are normally read-only. * Equivalent to the default environment variable `$BRIOCHE_INPUT_RESOURCE_DIRS`. */ -export const inputResourceDirs: unique symbol = Symbol("inputResourceDirs"); +// eslint-disable-next-line +export const inputResourceDirs = { + componentType: "inputResourceDirs", +} as InputResourceDirs; +type InputResourceDirs = ProcessTemplateSymbol<"inputResourceDirs">; /** * Expands to the home directory when the process runs. Equivalent to the * default environment variable `$HOME`. */ -export const homeDir: unique symbol = Symbol("homeDir"); +// eslint-disable-next-line +export const homeDir = { + componentType: "homeDir", +} as HomeDir; +type HomeDir = ProcessTemplateSymbol<"homeDir">; /** * Expands to the the "work directory" of the process. This is the directory * a process starts in by default (which is usually `$HOME/work`). */ -export const workDir: unique symbol = Symbol("workDir"); +// eslint-disable-next-line +export const workDir = { + componentType: "workDir", +} as WorkDir; +type WorkDir = ProcessTemplateSymbol<"workDir">; /** * Expands to the temporary directory where the process can write temporary * files. Equivalent to the default environment variable `$TMPDIR`. */ -export const tempDir: unique symbol = Symbol("tempDir"); +// eslint-disable-next-line +export const tempDir = { + componentType: "tempDir", +} as TempDir; +type TempDir = ProcessTemplateSymbol<"tempDir">; + +function isProcessTemplateSymbol( + value: unknown, + componentType: K, +): value is ProcessTemplateSymbol { + return ( + typeof value === "object" && + value != null && + "componentType" in value && + value["componentType"] === componentType + ); +} export type ProcessTemplateLike = Awaitable; @@ -265,6 +340,7 @@ export type ProcessTemplateComponent = | undefined; export class ProcessTemplate { + componentType: "processTemplate" = "processTemplate"; components: ProcessTemplateLike[]; constructor(...components: ProcessTemplateLike[]) { @@ -281,19 +357,19 @@ export class ProcessTemplate { return []; } else if (typeof component === "string") { return [{ type: "literal", value: runtime.bstring(component) }]; - } else if (component === outputPath) { + } else if (isProcessTemplateSymbol(component, "outputPath")) { return [{ type: "output_path" }]; - } else if (component === resourceDir) { + } else if (isProcessTemplateSymbol(component, "resourceDir")) { return [{ type: "resource_dir" }]; - } else if (component === inputResourceDirs) { + } else if (isProcessTemplateSymbol(component, "inputResourceDirs")) { return [{ type: "input_resource_dirs" }]; - } else if (component === homeDir) { + } else if (isProcessTemplateSymbol(component, "homeDir")) { return [{ type: "home_dir" }]; - } else if (component === workDir) { + } else if (isProcessTemplateSymbol(component, "workDir")) { return [{ type: "work_dir" }]; - } else if (component === tempDir) { + } else if (isProcessTemplateSymbol(component, "tempDir")) { return [{ type: "temp_dir" }]; - } else if (component instanceof ProcessTemplate) { + } else if (isProcessTemplateInstance(component)) { const serialized = await component.briocheSerialize(); return serialized.components; } else { @@ -310,3 +386,14 @@ export class ProcessTemplate { }; } } + +function isProcessTemplateInstance(value: unknown): value is ProcessTemplate { + return ( + typeof value === "object" && + value != null && + "componentType" in value && + value.componentType === "processTemplate" && + "briocheSerialize" in value && + typeof value.briocheSerialize === "function" + ); +} diff --git a/packages/std/core/recipes/recipe.bri b/packages/std/core/recipes/recipe.bri index a312660..4b18131 100644 --- a/packages/std/core/recipes/recipe.bri +++ b/packages/std/core/recipes/recipe.bri @@ -60,19 +60,13 @@ export type RecipeSerialization = runtime.WithMeta & | runtime.SyncRecipe : never); -// This symbol is used in `Recipe` so that `Recipe` doesn't simplify -// to `RecipeCommon` in TypeScript messages. This is mainly done for the LSP. -const recipeMarker: unique symbol = Symbol("recipeMarker"); - /** * A "recipe" is a type that describes how to create an artifact in Brioche. * When you call `brioche build`, the returned recipe is "baked" to produce * an output artifact. Recipes are lazy and won't do anything until `.bake()` * is called on them. */ -export type Recipe = { - [recipeMarker]?: undefined; -} & RecipeCommon & +export type Recipe = RecipeCommon & ([T] extends [File] ? FileRecipeUtils : [T] extends [Directory] @@ -207,14 +201,13 @@ export function createRecipe( throw new Error("bake or briocheSerialize is required"); } }, - ...recipeUtils, ...(isFile ? fileRecipeUtils : {}), ...(isDirectory ? directoryRecipeUtils : {}), ...(isSymlink ? symlinkRecipeUtils : {}), } as unknown as Recipe; } -interface RecipeCommon extends RecipeUtils { +interface RecipeCommon extends RecipeUtils { /** * Bake a recipe, returning a promise that will contain the resulting * artifact. Normally, you won't need to call this function yourself, as @@ -231,31 +224,9 @@ interface RecipeCommon extends RecipeUtils { briocheSerialize(): Awaitable>; } -interface RecipeUtils { - /** - * Cast a recipe to a more specific type. This is useful for cases like - * `std.process()`, where the output type is not known until runtime. The - * cast will be validated when the recipe is baked. - * - * ## Example - * - * ```typescript - * - * ```typescript - * // We know this Bash scirpt will output a file, so call `.cast("file")` - * // to convert it to a `Recipe`. We can then call file-specific - * // methods on the recipe. - * std.runBash` - * echo "hi" > "$BRIOCHE_OUTPUT" - * `.cast("file"); - * ``` - */ - cast & keyof ArtifactTypes>( - to: To, - ): Recipe; -} +interface RecipeUtils {} -interface FileRecipeUtils extends RecipeUtils { +interface FileRecipeUtils extends RecipeUtils { /** * Returns a new file with the given permissions set. * @@ -297,7 +268,7 @@ interface FileRecipeUtils extends RecipeUtils { read(): Promise; } -interface DirectoryRecipeUtils extends RecipeUtils { +interface DirectoryRecipeUtils extends RecipeUtils { /** * Get a file, directory, or symlink from a directory by path. */ @@ -321,40 +292,16 @@ interface DirectoryRecipeUtils extends RecipeUtils { /** * Peel a directory, which removes an outer layer of the directory. Baking - * will fail if the directory does not contain exactly one item. + * will fail if the directory does not contain exactly one inner directory. * * Passing `depth` will repeat the peeling process multiple times (default: 1) */ - peel(depth?: number): Recipe; + peel(depth?: number): Recipe; } -interface SymlinkRecipeUtils extends RecipeUtils {} - -export const recipeUtils: RecipeUtils = { - cast( - this: Recipe, - to: To, - ): Recipe { - return createRecipe( - [to satisfies ArtifactType as ArtifactType], - { - sourceDepth: 1, - briocheSerialize: async (meta) => { - const recipe = await this.briocheSerialize(); - return { - type: "cast", - recipe, - to, - meta, - } satisfies RecipeSerialization as any; - }, - }, - ); - }, -}; +interface SymlinkRecipeUtils extends RecipeUtils {} export const fileRecipeUtils: FileRecipeUtils = { - ...recipeUtils, withPermissions( this: Recipe, permissions: Partial, @@ -403,7 +350,6 @@ export const fileRecipeUtils: FileRecipeUtils = { }; export const directoryRecipeUtils: DirectoryRecipeUtils = { - ...recipeUtils, get(this: Recipe, path: string): Recipe { return createRecipe(["file", "directory", "symlink"], { sourceDepth: 1, @@ -456,21 +402,23 @@ export const directoryRecipeUtils: DirectoryRecipeUtils = { }, }); }, - peel(this: Recipe, depth: number = 1): Recipe { - return createRecipe(["file", "directory", "symlink"], { + peel(this: Recipe, depth: number = 1): Recipe { + return createRecipe(["directory"], { sourceDepth: 1, briocheSerialize: async (meta) => { return { - type: "peel", - directory: await this.briocheSerialize(), - depth, - meta, + type: "cast", + recipe: { + type: "peel", + directory: await this.briocheSerialize(), + depth, + meta, + }, + to: "directory", }; }, }); }, }; -export const symlinkRecipeUtils: SymlinkRecipeUtils = { - ...recipeUtils, -}; +export const symlinkRecipeUtils: SymlinkRecipeUtils = {}; diff --git a/packages/std/core/recipes/symlink.bri b/packages/std/core/recipes/symlink.bri index 533ef9e..197398e 100644 --- a/packages/std/core/recipes/symlink.bri +++ b/packages/std/core/recipes/symlink.bri @@ -1,8 +1,7 @@ import * as runtime from "../runtime.bri"; import { source as briocheSource } from "../source.bri"; import { assert } from "../utils.bri"; -import { type Recipe, symlinkRecipeUtils } from "./recipe.bri"; -import { artifactType } from "./artifact_type.bri"; +import type { Recipe } from "./recipe.bri"; export interface SymlinkOptions { target: string; @@ -28,7 +27,7 @@ interface SymlinkCtor { } export class Symlink implements Recipe { - [artifactType]: "symlink" = "symlink"; + artifactType: "symlink" = "symlink"; target: runtime.BString; source?: runtime.Source; @@ -55,6 +54,4 @@ export class Symlink implements Recipe { bake(): Symlink { return this; } - - cast = symlinkRecipeUtils.cast; } diff --git a/packages/std/extra/autowrap.bri b/packages/std/extra/autowrap.bri index f16bd4f..dfc676c 100644 --- a/packages/std/extra/autowrap.bri +++ b/packages/std/extra/autowrap.bri @@ -55,7 +55,7 @@ export function autowrap( ], }) .outputScaffold(recipe) - .cast("directory") + .toDirectory() .get(executablePath); result = result.insert(executablePath, wrappedExecutable); } diff --git a/packages/std/extra/oci_container_image.bri b/packages/std/extra/oci_container_image.bri index 9a47824..7bb8f2f 100644 --- a/packages/std/extra/oci_container_image.bri +++ b/packages/std/extra/oci_container_image.bri @@ -164,7 +164,7 @@ async function describeBlob( wc -c < "$file" >> "$BRIOCHE_OUTPUT" ` .env({ file }) - .cast("file") + .toFile() .read(); const [sha256sum, size] = description.split("\n"); if (sha256sum == null || size == null) { @@ -214,7 +214,7 @@ function collectReferences( IFS="$oldifs" ` .outputScaffold(recipe) - .cast("directory"); + .toDirectory(); } function tar(recipe: std.AsyncRecipe): std.Recipe { @@ -222,7 +222,7 @@ function tar(recipe: std.AsyncRecipe): std.Recipe { tar -cf "$BRIOCHE_OUTPUT" -C "$recipe" . ` .env({ recipe }) - .cast("file"); + .toFile(); } function gzip(file: std.AsyncRecipe): std.Recipe { @@ -230,5 +230,5 @@ function gzip(file: std.AsyncRecipe): std.Recipe { gzip -c "$file" > "$BRIOCHE_OUTPUT" ` .env({ file }) - .cast("file"); + .toFile(); } diff --git a/packages/std/project.bri b/packages/std/project.bri index 84b44b1..5904e0f 100644 --- a/packages/std/project.bri +++ b/packages/std/project.bri @@ -23,7 +23,6 @@ * @packageDocumentation */ -import type { BriocheGlobal } from "./core/global.bri"; import { toolchain } from "./toolchain"; export * from "./core"; @@ -34,10 +33,6 @@ export const project = { name: "std", }; -declare global { - const Brioche: BriocheGlobal; -} - // NOTE: This default export is a workaround so that `brioche build -p ./std` // will build the toolchain. This will be removed once we support building // other exports more easily. The `never` type is used to discourage external diff --git a/packages/std/runnable_tools.bri b/packages/std/runnable_tools.bri index 4f04850..af05051 100644 --- a/packages/std/runnable_tools.bri +++ b/packages/std/runnable_tools.bri @@ -33,7 +33,7 @@ export function makeRunnableExecutable( JSON.stringify(data), ], }) - .cast("file"); + .toFile(); } export interface RunnableTemplate { diff --git a/packages/std/toolchain/native/acl.bri b/packages/std/toolchain/native/acl.bri index 20ede4e..3bd28ab 100644 --- a/packages/std/toolchain/native/acl.bri +++ b/packages/std/toolchain/native/acl.bri @@ -34,5 +34,5 @@ export default std.memo((): std.Recipe => { LDFLAGS: std.tpl`-L${attr()}/lib`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/attr.bri b/packages/std/toolchain/native/attr.bri index 877bf79..c2f5578 100644 --- a/packages/std/toolchain/native/attr.bri +++ b/packages/std/toolchain/native/attr.bri @@ -31,5 +31,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/autoconf.bri b/packages/std/toolchain/native/autoconf.bri index 12bde5a..a2be5f5 100644 --- a/packages/std/toolchain/native/autoconf.bri +++ b/packages/std/toolchain/native/autoconf.bri @@ -38,7 +38,7 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); autoconf = wrapWithScript(autoconf, { paths: ["bin/autoupdate", "bin/autom4te"], diff --git a/packages/std/toolchain/native/automake.bri b/packages/std/toolchain/native/automake.bri index f65e248..9d0e940 100644 --- a/packages/std/toolchain/native/automake.bri +++ b/packages/std/toolchain/native/automake.bri @@ -41,5 +41,5 @@ export default std.memo((): std.Recipe => { AC_MACRODIR: std.tpl`${autoconf()}/share/autoconf`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/bash.bri b/packages/std/toolchain/native/bash.bri index 6a9460f..8a52390 100644 --- a/packages/std/toolchain/native/bash.bri +++ b/packages/std/toolchain/native/bash.bri @@ -32,7 +32,7 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); bash = bash.insert("bin/sh", std.symlink({ target: "bash" })); diff --git a/packages/std/toolchain/native/bc.bri b/packages/std/toolchain/native/bc.bri index d39c187..a73d6cb 100644 --- a/packages/std/toolchain/native/bc.bri +++ b/packages/std/toolchain/native/bc.bri @@ -34,5 +34,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/binutils.bri b/packages/std/toolchain/native/binutils.bri index e353759..75fe87b 100644 --- a/packages/std/toolchain/native/binutils.bri +++ b/packages/std/toolchain/native/binutils.bri @@ -46,7 +46,7 @@ export default std.memo((): std.Recipe => { LDFLAGS: std.tpl`-L${zlib()}/lib`, }, }) - .cast("directory"); + .toDirectory(); binutils = useBriocheLd(binutils, { ldPaths: ["bin/ld", "bin/ld.bfd", "bin/ld.gold"], diff --git a/packages/std/toolchain/native/bison.bri b/packages/std/toolchain/native/bison.bri index 8bc73f8..adc7e54 100644 --- a/packages/std/toolchain/native/bison.bri +++ b/packages/std/toolchain/native/bison.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/bzip2.bri b/packages/std/toolchain/native/bzip2.bri index cf4d2c8..c59ace8 100644 --- a/packages/std/toolchain/native/bzip2.bri +++ b/packages/std/toolchain/native/bzip2.bri @@ -46,5 +46,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/coreutils.bri b/packages/std/toolchain/native/coreutils.bri index e571d29..ebc9258 100644 --- a/packages/std/toolchain/native/coreutils.bri +++ b/packages/std/toolchain/native/coreutils.bri @@ -31,5 +31,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/diffutils.bri b/packages/std/toolchain/native/diffutils.bri index 3efdf97..bdf6b86 100644 --- a/packages/std/toolchain/native/diffutils.bri +++ b/packages/std/toolchain/native/diffutils.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/expat.bri b/packages/std/toolchain/native/expat.bri index 63d6a1d..2ff50bc 100644 --- a/packages/std/toolchain/native/expat.bri +++ b/packages/std/toolchain/native/expat.bri @@ -31,5 +31,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/file.bri b/packages/std/toolchain/native/file.bri index 3e2ad8a..56e952e 100644 --- a/packages/std/toolchain/native/file.bri +++ b/packages/std/toolchain/native/file.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/findutils.bri b/packages/std/toolchain/native/findutils.bri index 182922e..0b6dd37 100644 --- a/packages/std/toolchain/native/findutils.bri +++ b/packages/std/toolchain/native/findutils.bri @@ -31,5 +31,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/flex.bri b/packages/std/toolchain/native/flex.bri index 8d1b345..0118235 100644 --- a/packages/std/toolchain/native/flex.bri +++ b/packages/std/toolchain/native/flex.bri @@ -32,5 +32,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/gawk.bri b/packages/std/toolchain/native/gawk.bri index f7a8ca2..6d2b2ab 100644 --- a/packages/std/toolchain/native/gawk.bri +++ b/packages/std/toolchain/native/gawk.bri @@ -31,5 +31,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/gcc.bri b/packages/std/toolchain/native/gcc.bri index 0a65f5f..144d9e6 100644 --- a/packages/std/toolchain/native/gcc.bri +++ b/packages/std/toolchain/native/gcc.bri @@ -89,7 +89,7 @@ export default std.memo((): std.Recipe => { mpc: mpc(), }, }) - .cast("directory"); + .toDirectory(); gcc = wrapWithScript(gcc, { paths: [ diff --git a/packages/std/toolchain/native/gdbm.bri b/packages/std/toolchain/native/gdbm.bri index ae71b5f..68852c2 100644 --- a/packages/std/toolchain/native/gdbm.bri +++ b/packages/std/toolchain/native/gdbm.bri @@ -32,5 +32,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/gettext.bri b/packages/std/toolchain/native/gettext.bri index b43c2d9..bd78f88 100644 --- a/packages/std/toolchain/native/gettext.bri +++ b/packages/std/toolchain/native/gettext.bri @@ -32,5 +32,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/glibc.bri b/packages/std/toolchain/native/glibc.bri index ed7d9f8..1476737 100644 --- a/packages/std/toolchain/native/glibc.bri +++ b/packages/std/toolchain/native/glibc.bri @@ -63,7 +63,7 @@ export default std.memo((): std.Recipe => { stage2: stage2(), }, }) - .cast("directory"); + .toDirectory(); glibc = glibc.insert( "lib64", diff --git a/packages/std/toolchain/native/gmp.bri b/packages/std/toolchain/native/gmp.bri index 589a4d7..90eae82 100644 --- a/packages/std/toolchain/native/gmp.bri +++ b/packages/std/toolchain/native/gmp.bri @@ -33,5 +33,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/gperf.bri b/packages/std/toolchain/native/gperf.bri index bcec4f0..7c5021d 100644 --- a/packages/std/toolchain/native/gperf.bri +++ b/packages/std/toolchain/native/gperf.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/grep.bri b/packages/std/toolchain/native/grep.bri index f3c5c01..e6daf77 100644 --- a/packages/std/toolchain/native/grep.bri +++ b/packages/std/toolchain/native/grep.bri @@ -31,5 +31,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/groff.bri b/packages/std/toolchain/native/groff.bri index 2bba6dd..499f864 100644 --- a/packages/std/toolchain/native/groff.bri +++ b/packages/std/toolchain/native/groff.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/gzip.bri b/packages/std/toolchain/native/gzip.bri index 305af8e..9540f9a 100644 --- a/packages/std/toolchain/native/gzip.bri +++ b/packages/std/toolchain/native/gzip.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/index.bri b/packages/std/toolchain/native/index.bri index 141f21d..680f34a 100644 --- a/packages/std/toolchain/native/index.bri +++ b/packages/std/toolchain/native/index.bri @@ -1,5 +1,6 @@ import * as std from "/core"; import { setEnv } from "/extra"; +import stage2 from "/toolchain/stage2"; import linuxHeaders from "./linux_headers.bri"; import glibc from "./glibc.bri"; import zlib from "./zlib.bri"; @@ -38,13 +39,7 @@ import perlXmlParser from "./perl_xml_parser.bri"; import intltool from "./intltool.bri"; import autoconf from "./autoconf.bri"; import automake from "./automake.bri"; -import openssl from "./openssl.bri"; import libelf from "./libelf.bri"; -import libffi from "./libffi.bri"; -import python from "./python.bri"; -import pythonFlitCore from "./python_flit_core.bri"; -import pythonWheel from "./python_wheel.bri"; -import ninja from "./ninja.bri"; import coreutils from "./coreutils.bri"; import diffutils from "./diffutils.bri"; import gawk from "./gawk.bri"; @@ -89,7 +84,9 @@ export const tools = std.memo(async (): Promise> => { tar(), which(), ); + tools = fixShebangs(tools); tools = setEnv(tools, { + CPATH: { path: "include" }, LIBRARY_PATH: { path: "lib" }, PKG_CONFIG_PATH: { path: "lib/pkgconfig" }, MAGIC: { path: "share/misc/magic.mgc" }, @@ -99,8 +96,7 @@ export const tools = std.memo(async (): Promise> => { }); export default std.memo(async (): Promise> => { - let toolchain = std.merge( - tools(), + let toolchainOnly = std.merge( linuxHeaders(), glibc(), readline(), @@ -129,13 +125,7 @@ export default std.memo(async (): Promise> => { intltool(), autoconf(), automake(), - openssl(), libelf(), - libffi(), - python(), - pythonFlitCore(), - pythonWheel(), - ninja(), groff(), libpipeline(), texinfo(), @@ -144,7 +134,62 @@ export default std.memo(async (): Promise> => { utilLinux(), patchelf(), ); - toolchain = toolchain.insert("bin/cc", std.symlink({ target: "gcc" })); + toolchainOnly = fixShebangs(toolchainOnly); + toolchainOnly = toolchainOnly.insert( + "bin/cc", + std.symlink({ target: "gcc" }), + ); + toolchainOnly = std.sync(toolchainOnly); - return std.sync(toolchain); + return std.merge(tools(), toolchainOnly); }); + +function fixShebangs( + recipe: std.AsyncRecipe, +): std.Recipe { + // TODO: Handle shebangs with wrapper scripts instead of just using + // `/usr/bin/env`. This currently duplicates the fix from stage 2 + return std + .process({ + command: std.tpl`${stage2()}/bin/bash`, + args: [ + "-c", + std.indoc` + set -euo pipefail + + find "$BRIOCHE_OUTPUT"/bin -type f -executable -print0 \ + | while IFS= read -r -d $'\\0' file; do + if [ "$(head -c 2 "$file")" == "#!" ]; then + awk ' + { + if (NR == 1 && $0 ~ /^#!/) { + shebangInvocation = $0 + gsub(/^#! */, "", shebangInvocation) + numShebangWords = split(shebangInvocation, shebangWords, / +/) + if (numShebangWords == 1) { + shebangCommand = shebangWords[1] + numComponents = split(shebangCommand, shebangCommandComponents, "/") + targetCommand = shebangCommandComponents[numComponents] + gsub(" ", "", targetCommand) + print "#!/usr/bin/env " targetCommand + } else { + print $0 + } + } else { + print $0 + } + } + ' "$file" > temp + chmod +x temp + mv temp "$file" + fi + done + `, + ], + env: { + PATH: std.tpl`${stage2()}/bin`, + }, + outputScaffold: recipe, + }) + .toDirectory(); +} diff --git a/packages/std/toolchain/native/inetutils.bri b/packages/std/toolchain/native/inetutils.bri index d923fc1..463de37 100644 --- a/packages/std/toolchain/native/inetutils.bri +++ b/packages/std/toolchain/native/inetutils.bri @@ -42,5 +42,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/intltool.bri b/packages/std/toolchain/native/intltool.bri index 4441281..1ef3e25 100644 --- a/packages/std/toolchain/native/intltool.bri +++ b/packages/std/toolchain/native/intltool.bri @@ -41,5 +41,5 @@ export default std.memo((): std.Recipe => { LD_LIBRARY_PATH: std.tpl`${expat()}/lib`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/less.bri b/packages/std/toolchain/native/less.bri index 5d465aa..6aabb90 100644 --- a/packages/std/toolchain/native/less.bri +++ b/packages/std/toolchain/native/less.bri @@ -31,5 +31,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/libelf.bri b/packages/std/toolchain/native/libelf.bri index 6e448e1..3722aa2 100644 --- a/packages/std/toolchain/native/libelf.bri +++ b/packages/std/toolchain/native/libelf.bri @@ -46,5 +46,5 @@ export default std.memo((): std.Recipe => { CPPFLAGS: std.tpl`-I${zlib()}/include`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/libffi.bri b/packages/std/toolchain/native/libffi.bri deleted file mode 100644 index 76d47c8..0000000 --- a/packages/std/toolchain/native/libffi.bri +++ /dev/null @@ -1,36 +0,0 @@ -import * as std from "/core"; -import stage2 from "/toolchain/stage2"; - -export default std.memo((): std.Recipe => { - const sourceArchive = std.download({ - url: "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/libffi-3.4.4.tar.gz", - hash: std.sha256Hash( - "d66c56ad259a82cf2a9dfc408b32bf5da52371500b84745f7fb8b645712df676", - ), - }); - - return std - .process({ - command: std.tpl`${stage2()}/bin/bash`, - args: [ - "-c", - std.indoc` - set -euo pipefail - - tar -xf "$source" --strip-components=1 --no-same-owner --no-same-permissions - - ./configure \ - --prefix=/ \ - --disable-static \ - --with-gcc-arch=x86-64 - make - make install DESTDIR="$BRIOCHE_OUTPUT" - `, - ], - env: { - source: sourceArchive, - PATH: std.tpl`${stage2()}/bin`, - }, - }) - .cast("directory"); -}); diff --git a/packages/std/toolchain/native/libpipeline.bri b/packages/std/toolchain/native/libpipeline.bri index bfae7e8..6e15932 100644 --- a/packages/std/toolchain/native/libpipeline.bri +++ b/packages/std/toolchain/native/libpipeline.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/libtool.bri b/packages/std/toolchain/native/libtool.bri index dbf46be..463e2a2 100644 --- a/packages/std/toolchain/native/libtool.bri +++ b/packages/std/toolchain/native/libtool.bri @@ -30,5 +30,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/libxcrypt.bri b/packages/std/toolchain/native/libxcrypt.bri index 38efb99..b700fd2 100644 --- a/packages/std/toolchain/native/libxcrypt.bri +++ b/packages/std/toolchain/native/libxcrypt.bri @@ -34,5 +34,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/linux_headers.bri b/packages/std/toolchain/native/linux_headers.bri index ef94a2e..2ba1de4 100644 --- a/packages/std/toolchain/native/linux_headers.bri +++ b/packages/std/toolchain/native/linux_headers.bri @@ -33,5 +33,5 @@ export default std.memo(async (): Promise> => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/m4.bri b/packages/std/toolchain/native/m4.bri index 574ea63..5ff4199 100644 --- a/packages/std/toolchain/native/m4.bri +++ b/packages/std/toolchain/native/m4.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/make.bri b/packages/std/toolchain/native/make.bri index 8be9773..f628b78 100644 --- a/packages/std/toolchain/native/make.bri +++ b/packages/std/toolchain/native/make.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/man_db.bri b/packages/std/toolchain/native/man_db.bri index b09dd2b..b90d266 100644 --- a/packages/std/toolchain/native/man_db.bri +++ b/packages/std/toolchain/native/man_db.bri @@ -44,5 +44,5 @@ export default std.memo((): std.Recipe => { GROFF_TMAC_PATH: std.tpl`${groff()}/share/groff/current/tmac`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/mpc.bri b/packages/std/toolchain/native/mpc.bri index b0881f8..a3cd926 100644 --- a/packages/std/toolchain/native/mpc.bri +++ b/packages/std/toolchain/native/mpc.bri @@ -35,5 +35,5 @@ export default std.memo((): std.Recipe => { LDFLAGS: std.tpl`-L${gmp()}/lib -L${mpfr()}/lib`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/mpfr.bri b/packages/std/toolchain/native/mpfr.bri index 87d1c6e..eddb66e 100644 --- a/packages/std/toolchain/native/mpfr.bri +++ b/packages/std/toolchain/native/mpfr.bri @@ -40,7 +40,7 @@ export default std.memo((): std.Recipe => { LDFLAGS: std.tpl`-L${gmp()}/lib`, }, }) - .cast("directory"); + .toDirectory(); let libtoolArchive = mpfr.get("lib/libmpfr.la"); libtoolArchive = std @@ -58,7 +58,7 @@ export default std.memo((): std.Recipe => { libtoolArchive, }, }) - .cast("file"); + .toFile(); mpfr = mpfr.insert("lib/libmpfr.la", libtoolArchive); diff --git a/packages/std/toolchain/native/ncurses.bri b/packages/std/toolchain/native/ncurses.bri index 08cee83..39f882a 100644 --- a/packages/std/toolchain/native/ncurses.bri +++ b/packages/std/toolchain/native/ncurses.bri @@ -47,5 +47,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/ninja.bri b/packages/std/toolchain/native/ninja.bri deleted file mode 100644 index 26cc690..0000000 --- a/packages/std/toolchain/native/ninja.bri +++ /dev/null @@ -1,60 +0,0 @@ -import * as std from "/core"; -import stage2 from "/toolchain/stage2"; -import glibc from "./glibc.bri"; -import binutils from "./binutils.bri"; -import linuxHeaders from "./linux_headers.bri"; -import gcc from "./gcc.bri"; -import python from "./python.bri"; -import zlib from "./zlib.bri"; -import expat from "./expat.bri"; -import openssl from "./openssl.bri"; -import gdbm from "./gdbm.bri"; -import bzip2 from "./bzip2.bri"; -import libffi from "./libffi.bri"; - -export default std.memo((): std.Recipe => { - const sourceArchive = std.download({ - url: "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/ninja-1.11.1.tar.gz", - hash: std.sha256Hash( - "31747ae633213f1eda3842686f83c2aa1412e0f5691d1c14dbbcc67fe7400cea", - ), - }); - - // TODO: Remove this! - const dependencies = std.merge( - zlib(), - expat(), - openssl(), - gdbm(), - bzip2(), - libffi(), - ); - - const toolchain = std.merge(glibc(), binutils(), gcc(), linuxHeaders()); - - return std - .process({ - command: std.tpl`${stage2()}/bin/bash`, - args: [ - "-c", - std.indoc` - set -euo pipefail - - tar -xf "$source" --strip-components=1 --no-same-owner --no-same-permissions - - python3 configure.py --bootstrap - - mkdir -p "$BRIOCHE_OUTPUT"/bin - install -vm755 ninja "$BRIOCHE_OUTPUT"/bin - `, - ], - env: { - source: sourceArchive, - PATH: std.tpl`${python()}/bin:${toolchain}/bin:${stage2()}/bin`, - PYTHONHOME: python(), - // TODO: Remove this - LD_LIBRARY_PATH: std.tpl`${dependencies}/lib`, - }, - }) - .cast("directory"); -}); diff --git a/packages/std/toolchain/native/openssl.bri b/packages/std/toolchain/native/openssl.bri deleted file mode 100644 index 7344415..0000000 --- a/packages/std/toolchain/native/openssl.bri +++ /dev/null @@ -1,46 +0,0 @@ -import * as std from "/core"; -import stage2 from "/toolchain/stage2"; -import zlib from "./zlib.bri"; - -export default std.memo((): std.Recipe => { - const sourceArchive = std.download({ - url: "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/openssl-3.1.2.tar.gz", - hash: std.sha256Hash( - "a0ce69b8b97ea6a35b96875235aa453b966ba3cba8af2de23657d8b6767d6539", - ), - }); - - // TODO: Fix dynamic linking with zlib (`zlib-dynamic` option instead of `zlib`) - return std - .process({ - command: std.tpl`${stage2()}/bin/bash`, - args: [ - "-c", - std.indoc` - set -euo pipefail - - tar -xf "$source" --strip-components=1 --no-same-owner --no-same-permissions - - ./config \ - --prefix=/ \ - --openssldir=/etc/ssl \ - --libdir=lib \ - -L"$zlib/lib" \ - -I"$zlib/include" \ - shared \ - zlib - - make - - sed -i '/INSTALL_LIBS/s/libcrypto.a libssl.a//' Makefile - make install DESTDIR="$BRIOCHE_OUTPUT" MANSUFFIX=ssl - `, - ], - env: { - source: sourceArchive, - PATH: std.tpl`${stage2()}/bin`, - zlib: zlib(), - }, - }) - .cast("directory"); -}); diff --git a/packages/std/toolchain/native/patch.bri b/packages/std/toolchain/native/patch.bri index ad51184..517a8e6 100644 --- a/packages/std/toolchain/native/patch.bri +++ b/packages/std/toolchain/native/patch.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/patchelf.bri b/packages/std/toolchain/native/patchelf.bri index 7b972a9..2952dc9 100644 --- a/packages/std/toolchain/native/patchelf.bri +++ b/packages/std/toolchain/native/patchelf.bri @@ -44,5 +44,5 @@ export default std.memo((): std.Recipe => { AUTOMAKE_LIBDIR: std.tpl`${automake()}/share/automake-1.16`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/perl.bri b/packages/std/toolchain/native/perl.bri index 1acb369..c41aed7 100644 --- a/packages/std/toolchain/native/perl.bri +++ b/packages/std/toolchain/native/perl.bri @@ -41,5 +41,5 @@ export default std.memo((): std.Recipe => { BUILD_BZIP2: "0", }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/perl_xml_parser.bri b/packages/std/toolchain/native/perl_xml_parser.bri index 19ef459..f98cbe8 100644 --- a/packages/std/toolchain/native/perl_xml_parser.bri +++ b/packages/std/toolchain/native/perl_xml_parser.bri @@ -37,5 +37,5 @@ export default std.memo((): std.Recipe => { WATERMARK: "1", }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/pkgconf.bri b/packages/std/toolchain/native/pkgconf.bri index 7e2d921..8d38fec 100644 --- a/packages/std/toolchain/native/pkgconf.bri +++ b/packages/std/toolchain/native/pkgconf.bri @@ -33,5 +33,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/procps_ng.bri b/packages/std/toolchain/native/procps_ng.bri index 08279fd..aa01526 100644 --- a/packages/std/toolchain/native/procps_ng.bri +++ b/packages/std/toolchain/native/procps_ng.bri @@ -40,5 +40,5 @@ export default std.memo((): std.Recipe => { PKG_CONFIG_PATH: std.tpl`${ncurses()}/lib/pkgconfig`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/psmisc.bri b/packages/std/toolchain/native/psmisc.bri index 474b625..05441be 100644 --- a/packages/std/toolchain/native/psmisc.bri +++ b/packages/std/toolchain/native/psmisc.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/python.bri b/packages/std/toolchain/native/python.bri deleted file mode 100644 index 24a3501..0000000 --- a/packages/std/toolchain/native/python.bri +++ /dev/null @@ -1,65 +0,0 @@ -import * as std from "/core"; -import stage2 from "/toolchain/stage2"; -import zlib from "./zlib.bri"; -import expat from "./expat.bri"; -import openssl from "./openssl.bri"; -import gdbm from "./gdbm.bri"; -import bzip2 from "./bzip2.bri"; -import libffi from "./libffi.bri"; - -export default std.memo((): std.Recipe => { - const sourceArchive = std.download({ - url: "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/Python-3.11.4.tar.xz", - hash: std.sha256Hash( - "2f0e409df2ab57aa9fc4cbddfb976af44e4e55bf6f619eee6bc5c2297264a7f6", - ), - }); - - const dependencies = std.merge( - zlib(), - expat(), - openssl(), - gdbm(), - bzip2(), - libffi(), - ); - - return std - .process({ - command: std.tpl`${stage2()}/bin/bash`, - args: [ - "-c", - std.indoc` - set -euo pipefail - - tar -xf "$source" --strip-components=1 --no-same-owner --no-same-permissions - - ./configure \ - --prefix="$BRIOCHE_OUTPUT" \ - --enable-shared \ - --with-system-expat \ - --with-system-ffi \ - --enable-optimizations - make - make install - `, - ], - env: { - // TODO: Clean up these env vars - source: sourceArchive, - PATH: std.tpl`${stage2()}/bin`, - LDFLAGS: std.tpl`-L${dependencies}/lib -lz`, - CPPFLAGS: std.tpl`-I${dependencies}/include`, - ZLIB_LIBS: std.tpl`-L${dependencies}/lib -lz`, - ZLIB_CFLAGS: std.tpl`-I${dependencies}/include`, - GBDM_LIBS: std.tpl`-L${dependencies}/lib -lgdbm`, - GBDM_CFLAGS: std.tpl`-I${dependencies}/include`, - BZIP2_LIBS: std.tpl`-L${dependencies}/lib -lbz2`, - BZIP2_CFLAGS: std.tpl`-I${dependencies}/include`, - LIBCRYPT_LIBS: std.tpl`-L${dependencies}/lib`, - LIBCRYPT_CFLAGS: std.tpl`-I${dependencies}/include`, - LD_LIBRARY_PATH: std.tpl`${dependencies}/lib`, - }, - }) - .cast("directory"); -}); diff --git a/packages/std/toolchain/native/python_flit_core.bri b/packages/std/toolchain/native/python_flit_core.bri deleted file mode 100644 index a95e949..0000000 --- a/packages/std/toolchain/native/python_flit_core.bri +++ /dev/null @@ -1,69 +0,0 @@ -import * as std from "/core"; -import stage2 from "/toolchain/stage2"; -import python from "./python.bri"; -import zlib from "./zlib.bri"; -import expat from "./expat.bri"; -import openssl from "./openssl.bri"; -import gdbm from "./gdbm.bri"; -import bzip2 from "./bzip2.bri"; -import libffi from "./libffi.bri"; - -export default std.memo((): std.Recipe => { - const sourceArchive = std.download({ - url: "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/flit_core-3.9.0.tar.gz", - hash: std.sha256Hash( - "72ad266176c4a3fcfab5f2930d76896059851240570ce9a98733b658cb786eba", - ), - }); - - // TODO: Remove this! - const dependencies = std.merge( - zlib(), - expat(), - openssl(), - gdbm(), - bzip2(), - libffi(), - ); - - let flitCore = std - .process({ - command: std.tpl`${stage2()}/bin/bash`, - args: [ - "-c", - std.indoc` - set -euo pipefail - - tar -xf "$source" --strip-components=1 --no-same-owner --no-same-permissions - - python3 -m venv "$BRIOCHE_OUTPUT" - - "$BRIOCHE_OUTPUT/bin/pip3" wheel \ - -w dist \ - --no-build-isolation \ - --no-deps \ - "$PWD" - "$BRIOCHE_OUTPUT/bin/pip3" install \ - --no-index \ - --find-links=dist \ - flit_core - `, - ], - env: { - source: sourceArchive, - PATH: std.tpl`${python()}/bin:${stage2()}/bin`, - PYTHONHOME: python(), - // TODO: Remove this - LD_LIBRARY_PATH: std.tpl`${dependencies}/lib`, - }, - }) - .cast("directory"); - - // Remove everything but the `lib/` directory. The rest is - // virtualenv stuff we don't want to keep. - flitCore = std.directory({ - lib: flitCore.get("lib"), - }); - - return flitCore; -}); diff --git a/packages/std/toolchain/native/python_wheel.bri b/packages/std/toolchain/native/python_wheel.bri deleted file mode 100644 index 06fb0bf..0000000 --- a/packages/std/toolchain/native/python_wheel.bri +++ /dev/null @@ -1,71 +0,0 @@ -import * as std from "/core"; -import stage2 from "/toolchain/stage2"; -import python from "./python.bri"; -import zlib from "./zlib.bri"; -import expat from "./expat.bri"; -import openssl from "./openssl.bri"; -import gdbm from "./gdbm.bri"; -import bzip2 from "./bzip2.bri"; -import libffi from "./libffi.bri"; -import pythonFlitCore from "./python_flit_core.bri"; - -export default std.memo((): std.Recipe => { - const sourceArchive = std.download({ - url: "https://development-content.brioche.dev/linuxfromscratch.org/v12.0/packages/wheel-0.41.1.tar.gz", - hash: std.sha256Hash( - "12b911f083e876e10c595779709f8a88a59f45aacc646492a67fe9ef796c1b47", - ), - }); - - // TODO: Remove this! - const dependencies = std.merge( - zlib(), - expat(), - openssl(), - gdbm(), - bzip2(), - libffi(), - ); - - let wheel = std - .process({ - command: std.tpl`${stage2()}/bin/bash`, - args: [ - "-c", - std.indoc` - set -euo pipefail - - tar -xf "$source" --strip-components=1 --no-same-owner --no-same-permissions - - python3 -m venv "$BRIOCHE_OUTPUT" - - "$BRIOCHE_OUTPUT/bin/pip3" wheel \ - -w dist \ - --no-build-isolation \ - --no-deps \ - "$PWD" - "$BRIOCHE_OUTPUT/bin/pip3" install \ - --no-index \ - --find-links=dist \ - wheel - `, - ], - env: { - source: sourceArchive, - PATH: std.tpl`${python()}/bin:${stage2()}/bin`, - PYTHONHOME: python(), - PYTHONPATH: std.tpl`${pythonFlitCore()}/lib/python3.11/site-packages`, - // TODO: Remove this - LD_LIBRARY_PATH: std.tpl`${dependencies}/lib`, - }, - }) - .cast("directory"); - - // Remove everything but the `lib/` directory. The rest is - // virtualenv stuff we don't want to keep. - wheel = std.directory({ - lib: wheel.get("lib"), - }); - - return wheel; -}); diff --git a/packages/std/toolchain/native/readline.bri b/packages/std/toolchain/native/readline.bri index 4b6fb91..cc36c7b 100644 --- a/packages/std/toolchain/native/readline.bri +++ b/packages/std/toolchain/native/readline.bri @@ -43,5 +43,5 @@ export default std.memo((): std.Recipe => { sourcePatch, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/sed.bri b/packages/std/toolchain/native/sed.bri index 525cbb3..24b54dd 100644 --- a/packages/std/toolchain/native/sed.bri +++ b/packages/std/toolchain/native/sed.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/tar.bri b/packages/std/toolchain/native/tar.bri index 038fc2f..fbb797c 100644 --- a/packages/std/toolchain/native/tar.bri +++ b/packages/std/toolchain/native/tar.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/texinfo.bri b/packages/std/toolchain/native/texinfo.bri index 5078df8..9e68afe 100644 --- a/packages/std/toolchain/native/texinfo.bri +++ b/packages/std/toolchain/native/texinfo.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/util_linux.bri b/packages/std/toolchain/native/util_linux.bri index 07159cf..4b4ae03 100644 --- a/packages/std/toolchain/native/util_linux.bri +++ b/packages/std/toolchain/native/util_linux.bri @@ -48,5 +48,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/which.bri b/packages/std/toolchain/native/which.bri index 55e223e..563f853 100644 --- a/packages/std/toolchain/native/which.bri +++ b/packages/std/toolchain/native/which.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/xz.bri b/packages/std/toolchain/native/xz.bri index e550112..65eec39 100644 --- a/packages/std/toolchain/native/xz.bri +++ b/packages/std/toolchain/native/xz.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/zlib.bri b/packages/std/toolchain/native/zlib.bri index ba4f67f..7b6ce34 100644 --- a/packages/std/toolchain/native/zlib.bri +++ b/packages/std/toolchain/native/zlib.bri @@ -29,5 +29,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/native/zstd.bri b/packages/std/toolchain/native/zstd.bri index 70c1842..13c2fb7 100644 --- a/packages/std/toolchain/native/zstd.bri +++ b/packages/std/toolchain/native/zstd.bri @@ -28,5 +28,5 @@ export default std.memo((): std.Recipe => { PATH: std.tpl`${stage2()}/bin`, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/stage0/index.bri b/packages/std/toolchain/stage0/index.bri index cf07f6f..aadaf36 100644 --- a/packages/std/toolchain/stage0/index.bri +++ b/packages/std/toolchain/stage0/index.bri @@ -93,7 +93,7 @@ export function bootstrapRun( ), }), }) - .cast("directory"); + .toDirectory(); } export default async (): Promise => { diff --git a/packages/std/toolchain/stage2/2_17_gcc.bri b/packages/std/toolchain/stage2/2_17_gcc.bri index 07ee5f6..a4b7f07 100644 --- a/packages/std/toolchain/stage2/2_17_gcc.bri +++ b/packages/std/toolchain/stage2/2_17_gcc.bri @@ -85,10 +85,6 @@ export default std.memo(async (): Promise> => { ); } - // stage2 = stage2.insert("usr/x86_64-lfs-linux-gnu/include", brioche.symlink({ target: "../include" })); - // const usrInclude = stage2.get("usr/include").cast("directory"); - // stage2 = stage2.insert("usr/x86_64-lfs-linux-gnu/include", usrInclude); - return bootstrapRun({ script: std.indoc` set -euo pipefail diff --git a/packages/std/toolchain/stage2/2_19_gettext.bri b/packages/std/toolchain/stage2/2_19_gettext.bri index 9172331..9771662 100644 --- a/packages/std/toolchain/stage2/2_19_gettext.bri +++ b/packages/std/toolchain/stage2/2_19_gettext.bri @@ -31,5 +31,5 @@ export default std.memo(async (): Promise> => { source: sourceArchive, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/stage2/2_20_bison.bri b/packages/std/toolchain/stage2/2_20_bison.bri index a97efc9..c210e93 100644 --- a/packages/std/toolchain/stage2/2_20_bison.bri +++ b/packages/std/toolchain/stage2/2_20_bison.bri @@ -32,5 +32,5 @@ export default std.memo(async (): Promise> => { source: sourceArchive, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/stage2/2_21_perl.bri b/packages/std/toolchain/stage2/2_21_perl.bri index 54ae1eb..037c7db 100644 --- a/packages/std/toolchain/stage2/2_21_perl.bri +++ b/packages/std/toolchain/stage2/2_21_perl.bri @@ -32,14 +32,12 @@ export default std.memo(async (): Promise> => { source: sourceArchive, }, }) - .cast("directory"); + .toDirectory(); // Mark the perl binary as executable // TODO: Figure out why Perl isn't executable by default? - const perlBin = perl - .get("usr/bin/perl") - .cast("file") - .withPermissions({ executable: true }); + let perlBin = std.castToFile(perl.get("usr/bin/perl")); + perlBin = perlBin.withPermissions({ executable: true }); perl = perl.insert("usr/bin/perl", perlBin); return perl; diff --git a/packages/std/toolchain/stage2/2_22_python.bri b/packages/std/toolchain/stage2/2_22_python.bri index e10a348..fbc50a1 100644 --- a/packages/std/toolchain/stage2/2_22_python.bri +++ b/packages/std/toolchain/stage2/2_22_python.bri @@ -30,5 +30,5 @@ export default std.memo(async (): Promise> => { source: sourceArchive, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/stage2/2_23_texinfo.bri b/packages/std/toolchain/stage2/2_23_texinfo.bri index 8480266..b8cb81b 100644 --- a/packages/std/toolchain/stage2/2_23_texinfo.bri +++ b/packages/std/toolchain/stage2/2_23_texinfo.bri @@ -30,5 +30,5 @@ export default std.memo(async (): Promise> => { source: sourceArchive, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/stage2/2_24_util_linux.bri b/packages/std/toolchain/stage2/2_24_util_linux.bri index 216b97d..a4b6863 100644 --- a/packages/std/toolchain/stage2/2_24_util_linux.bri +++ b/packages/std/toolchain/stage2/2_24_util_linux.bri @@ -43,5 +43,5 @@ export default std.memo(async (): Promise> => { source: sourceArchive, }, }) - .cast("directory"); + .toDirectory(); }); diff --git a/packages/std/toolchain/stage2/index.bri b/packages/std/toolchain/stage2/index.bri index de0b8a8..56d0d6e 100644 --- a/packages/std/toolchain/stage2/index.bri +++ b/packages/std/toolchain/stage2/index.bri @@ -64,5 +64,5 @@ export default std.memo((): std.Recipe => { stage2, }, }) - .cast("directory"); + .toDirectory(); });