diff --git a/packages/vlt/build.ncl b/packages/vlt/build.ncl new file mode 100644 index 00000000..66ee451e --- /dev/null +++ b/packages/vlt/build.ncl @@ -0,0 +1,140 @@ +# Imported from npm `vlt` by `pkgmgr import npm` (node build). +# +# vlt is a package manager (vlt.sh), shipped as a single dependency-free npm +# tarball: `npm ci` installs exactly ONE package, pinned by version + integrity +# in the committed package-lock.json. No transitive tree, no native addons, no +# compile step — the whole build is an extract. +# +# WHY A REGISTRY ARTIFACT AND NOT A SOURCE BUILD — AGENTS.md requires this be +# called out explicitly, and the reason is not "nobody tried". Source IS +# published (codeload .../vltpkg/tar.gz/refs/tags/v1.0.1, 200, 7.4 MB, 48 real +# TypeScript workspaces). It cannot be built with a toolchain we have: +# +# - The only lockfile in the repo is `vlt-lock.json` — vlt's own format. +# There is no pnpm-lock.yaml and no package-lock.json. +# - Dependency specs use the `catalog:` protocol with the catalog declared in +# `vlt.json`. Measured against the extracted tarball: +# npm → EUNSUPPORTEDPROTOCOL: Unsupported URL Type "catalog:" +# pnpm → ERR_PNPM_CATALOG_ENTRY_NOT_FOUND_FOR_SPEC (pnpm supports +# catalogs, but reads pnpm-workspace.yaml, not vlt.json) +# `package.json` has no `workspaces` key at all, so neither tool can even +# see the monorepo layout. +# - Upstream CI agrees: `uses: vltpkg/setup-vlt@v1` then `vlt install`. +# - The published package (`infra/cli/package.json`) declares `bin: null`, +# `dependencies: {}`, and one script — `prepack: vlt-build-prepack`. The +# npm tarball is generated wholesale by their internal bundler. +# +# So building vlt from source requires vlt: a genuine bootstrap cycle, which is +# the "required toolchain genuinely isn't packaged yet" case AGENTS.md carves +# out. Breaking it would mean a two-stage `vlt-bootstrap` → `vlt` pair in the +# gawk-bootstrap shape; worth doing if vlt becomes load-bearing, not before. +# +# `node-lts`, not `node`, for both build and runtime. Two reasons, and the +# private `usr/libexec/vlt` prefix below is the third leg of the same argument +# (gominimal/pkgs#370: a global `usr/lib/node_modules` install collides with +# whichever node variant the user actually has): +# - vlt's own CI tests Node 22.x only (`node-version: '^22.22.0'`, `[22.x]`) +# and `engines` says `>=22.22.0`. Our node-lts is 24.14.1, node is 25.8.2 — +# neither is 22.x, but LTS is two majors closer to what upstream tests. +# - pnpm, the closest analogue in this repo (also a package manager, also a +# node CLI), is on node-lts for exactly this reason — see #97/#98: the node +# most users and hosting providers run is whatever ships with current LTS. +# +# Deliberately NO `source_provenance`. vlt's vuln identity is its npm package +# name, and minimal-supply-chain routes a node-flavored package with no +# provenance to `pkg:npm/` (scan.rs `npm_purl_for_node_package`) so the +# OSV/GHSA npm advisories resolve. Declaring `GithubRepo vltpkg/vltpkg` would +# take it OFF that arm onto the repo-purl arm, where GHSA's npm advisories — +# which are keyed by package name, not repo — would no longer match. Absent is +# correct here, not an oversight. +let { standaloneTest, Attrs, BuildSpec, Local, Needs, OutputBin, OutputData, Test, .. } = import "minimal.ncl" in +let base = import "../base/build.ncl" in +let node-lts = import "../node-lts/build.ncl" in +let coreutils = import "../coreutils/build.ncl" in +let version = "1.0.1" in +{ + name = "vlt", + build_deps = [ + { file = "build.sh" } | Local, + { file = "package.json" } | Local, + { file = "package-lock.json" } | Local, + base, + node-lts, + ], + runtime_deps = [coreutils, node-lts], + needs = + { + dns = {}, + internet = {}, + } | Needs, + cmd = "./build.sh", + build_args = { + include version, + }, + outputs = { + # Enumerated, not `usr/bin/*`: the checker wants each bin named, and the + # npm registry metadata already lists them exactly, so there is nothing to + # infer. `vlt` is the CLI; the others are the documented shorthands + # (`vlr` = `vlt run`, `vlx` = `vlt exec`, plus their variants). + vlt = { glob = "usr/bin/vlt" } | OutputBin, + vlr = { glob = "usr/bin/vlr" } | OutputBin, + vlrx = { glob = "usr/bin/vlrx" } | OutputBin, + vlx = { glob = "usr/bin/vlx" } | OutputBin, + vlxl = { glob = "usr/bin/vlxl" } | OutputBin, + + libexec = { glob = "usr/libexec/vlt/**", allow_executable = true } | OutputData, + }, + attrs = + { + upstream_version = version, + license_spdx = "BSD-2-Clause-Patent", + } | Attrs, + + tests = { + smoketest = standaloneTest "/bin/vlt --version", + + version_is_exact = + { + class = 'Standalone, + test_deps = [base], + cmds = [ + # Exact equality, NOT `--version | grep '%{version}'`: vlt's usage + # banner also carries the version ("next-gen package management + # v1.0.1"), so a grep would pass on a build where `--version` itself + # is broken and only usage prints. This asserts the artifact's own + # version, independent of the build-time lockfile guard in build.sh. + ["/bin/bash", "-c", "test \"$(/bin/vlt --version)\" = \"%{version}\""], + ], + } + | Test, + + companion_bins_work = + { + class = 'Standalone, + test_deps = [base], + cmds = [ + # Five bins are declared as outputs; they are PATH symlinks into the + # private libexec prefix, so a broken relative link fails here and + # nowhere else. A test that only exercised `vlt` would ship four + # dead entries in usr/bin. + ["/bin/bash", "-c", "for b in vlr vlrx vlx vlxl; do test \"$(/bin/$b --version)\" = \"%{version}\" || { echo \"$b failed\" >&2; exit 1; }; done"], + ], + } + | Test, + + reads_a_manifest = + { + class = 'Standalone, + test_deps = [base], + cmds = [ + # Real work, offline: `vlt pkg get` parses a package.json and returns + # a field. This exercises the bundled JS beyond argv handling — a + # truncated or partially-installed tarball prints `--version` fine + # and fails here. vlt has NO default registry as of 1.0.1, so any + # network-touching command is not a candidate for a sandbox test. + ["/bin/bash", "-c", "d=/tmp/vlt-selftest; mkdir -p \"$d\"; cd \"$d\"; printf '{\"name\":\"vlt-selftest-fixture\",\"version\":\"9.9.9\"}' > package.json; test \"$(/bin/vlt pkg get name)\" = '\"vlt-selftest-fixture\"'"], + ], + } + | Test, + }, +} | BuildSpec diff --git a/packages/vlt/build.sh b/packages/vlt/build.sh new file mode 100755 index 00000000..62cb3421 --- /dev/null +++ b/packages/vlt/build.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# Imported from npm `vlt` (1.0.1, node) by pkgmgr import npm. +set -eu + +# Reproducible install: `npm ci` from the committed package-lock.json pins +# the WHOLE transitive tree by version + integrity (a bare `npm install` +# re-resolves it at build time). Install into a package-PRIVATE libexec +# prefix (NOT the shared usr/lib/node_modules the node runtime owns) and +# expose bins as PATH symlinks; the inner `#!/usr/bin/env node` shebang is +# served by coreutils(env)+node, so no shell wrapper is needed. +# Guard: the committed lock must pin the build.ncl version (the updater +# regenerates it on a bump; this catches a hand-edited version drift). +grep -qF "\"$MINIMAL_ARG_VERSION\"" package.json || + { echo "package.json does not pin $MINIMAL_ARG_VERSION — regenerate the lockfile" >&2; exit 1; } +prefix="$OUTPUT_DIR/usr/libexec/vlt" +mkdir -p "$prefix" +cp package.json package-lock.json "$prefix/" +cd "$prefix" +npm ci --omit=dev + +mkdir -p "$OUTPUT_DIR/usr/bin" +for _bin in node_modules/.bin/*; do + [ -e "$_bin" ] || continue + _tool=${_bin##*/} + ln -s "../libexec/vlt/node_modules/.bin/$_tool" "$OUTPUT_DIR/usr/bin/$_tool" +done diff --git a/packages/vlt/package-lock.json b/packages/vlt/package-lock.json new file mode 100644 index 00000000..8f99dcd0 --- /dev/null +++ b/packages/vlt/package-lock.json @@ -0,0 +1,31 @@ +{ + "name": "pkgmgr-node-import", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pkgmgr-node-import", + "version": "0.0.0", + "dependencies": { + "vlt": "1.0.1" + } + }, + "node_modules/vlt": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vlt/-/vlt-1.0.1.tgz", + "integrity": "sha512-+EVCj7/jfTsotOQjrOvteDQSLgTVYu005eslkaAypPYBUdZ+AN8Y3cHk6F100l9mFrvdN3d99ypmPYSv2++FLA==", + "license": "BSD-2-Clause-Patent", + "bin": { + "vlr": "vlr.js", + "vlrx": "vlrx.js", + "vlt": "vlt.js", + "vlx": "vlx.js", + "vlxl": "vlxl.js" + }, + "engines": { + "node": ">=22.22.0" + } + } + } +} diff --git a/packages/vlt/package.json b/packages/vlt/package.json new file mode 100644 index 00000000..74257484 --- /dev/null +++ b/packages/vlt/package.json @@ -0,0 +1,8 @@ +{ + "name": "pkgmgr-node-import", + "version": "0.0.0", + "private": true, + "dependencies": { + "vlt": "1.0.1" + } +}