From 17a117f1325de7a2c08fa23475b8ddf67ace9a09 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Sun, 22 Mar 2026 15:51:17 -0700 Subject: [PATCH] fix(docker): pack bytelyst consumer closure for prep --- scripts/prep-consumer.sh | 137 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 8 deletions(-) diff --git a/scripts/prep-consumer.sh b/scripts/prep-consumer.sh index 4f6dd91f..2a569579 100755 --- a/scripts/prep-consumer.sh +++ b/scripts/prep-consumer.sh @@ -65,6 +65,8 @@ fi # ── Pack + rewrite ──────────────────────────────────────────── DEPS_DIR="$TARGET_DIR/.docker-deps" +PACK_SRC_DIR="$DEPS_DIR/.pack-src" +PLAN_FILE="$DEPS_DIR/.pack-plan.json" rm -rf "$DEPS_DIR" mkdir -p "$DEPS_DIR" @@ -84,10 +86,75 @@ if [ -z "$PKGS" ]; then exit 0 fi +node - "$TARGET_DIR/package.json" "$COMMON_PLAT" "$PLAN_FILE" <<'NODE' +const fs = require('fs'); +const path = require('path'); + +const consumerPath = process.argv[2]; +const commonPlat = process.argv[3]; +const planPath = process.argv[4]; +const packageRoot = path.join(commonPlat, 'packages'); +const consumer = JSON.parse(fs.readFileSync(consumerPath, 'utf8')); + +const directEntries = []; +for (const depType of ['dependencies', 'devDependencies']) { + for (const [name, version] of Object.entries(consumer[depType] ?? {})) { + if (name.startsWith('@bytelyst/') && typeof version === 'string' && version.startsWith('file:')) { + directEntries.push({ name, depType }); + } + } +} + +const queue = [...new Set(directEntries.map((entry) => entry.name))]; +const closure = new Set(queue); +const versions = {}; + +while (queue.length > 0) { + const scopedName = queue.shift(); + const shortName = scopedName.replace('@bytelyst/', ''); + const pkgPath = path.join(packageRoot, shortName, 'package.json'); + if (!fs.existsSync(pkgPath)) { + throw new Error(`Package ${scopedName} not found at ${pkgPath}`); + } + + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); + versions[scopedName] = pkg.version; + + for (const depField of ['dependencies', 'optionalDependencies', 'peerDependencies']) { + for (const depName of Object.keys(pkg[depField] ?? {})) { + if (!depName.startsWith('@bytelyst/')) { + continue; + } + + if (!closure.has(depName)) { + closure.add(depName); + queue.push(depName); + } + } + } +} + +fs.writeFileSync( + planPath, + JSON.stringify( + { + directEntries, + packages: [...closure], + versions, + }, + null, + 2, + ) + '\n', +); +NODE + +mkdir -p "$PACK_SRC_DIR" + COUNT=0 -for scoped_name in $PKGS; do +while IFS= read -r scoped_name; do pkg_short="${scoped_name#@bytelyst/}" PKG_DIR="$COMMON_PLAT/packages/$pkg_short" + TMP_PKG_DIR="$PACK_SRC_DIR/$pkg_short" if [ ! -d "$PKG_DIR" ]; then echo " ⚠️ Package $pkg_short not found in $COMMON_PLAT/packages/" @@ -99,15 +166,69 @@ for scoped_name in $PKGS; do continue fi - # Pack the package into a tarball - TARBALL=$(cd "$PKG_DIR" && npm pack --pack-destination "$DEPS_DIR" 2>/dev/null | tail -1) - echo " 📦 $pkg_short → $TARBALL" + rm -rf "$TMP_PKG_DIR" + cp -R "$PKG_DIR" "$TMP_PKG_DIR" + rm -rf "$TMP_PKG_DIR/node_modules" - # Rewrite the file: ref in package.json to point to the local tarball - sed -i.tmp "s|\"${scoped_name}\": *\"file:[^\"]*\"|\"${scoped_name}\": \"file:.docker-deps/${TARBALL}\"|" "$TARGET_DIR/package.json" - rm -f "$TARGET_DIR/package.json.tmp" + node - "$TMP_PKG_DIR/package.json" "$PLAN_FILE" <<'NODE' +const fs = require('fs'); + +const packageJsonPath = process.argv[2]; +const planPath = process.argv[3]; +const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +const plan = JSON.parse(fs.readFileSync(planPath, 'utf8')); + +for (const depField of ['dependencies', 'optionalDependencies', 'peerDependencies']) { + for (const [depName, depVersion] of Object.entries(pkg[depField] ?? {})) { + if (!depName.startsWith('@bytelyst/')) { + continue; + } + + if (typeof depVersion === 'string' && depVersion.startsWith('workspace:') && plan.versions[depName]) { + pkg[depField][depName] = plan.versions[depName]; + } + } +} + +fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n'); +NODE + + TARBALL=$(cd "$TMP_PKG_DIR" && npm pack --pack-destination "$DEPS_DIR" 2>/dev/null | tail -1) + echo " 📦 $pkg_short → $TARBALL" COUNT=$((COUNT + 1)) -done +done < <(node -e "const fs=require('fs'); const plan=JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); for (const name of plan.packages) console.log(name);" "$PLAN_FILE") + +node - "$TARGET_DIR/package.json" "$PLAN_FILE" <<'NODE' +const fs = require('fs'); + +const consumerPath = process.argv[2]; +const planPath = process.argv[3]; +const consumer = JSON.parse(fs.readFileSync(consumerPath, 'utf8')); +const plan = JSON.parse(fs.readFileSync(planPath, 'utf8')); + +const tarballRefFor = (scopedName) => `file:.docker-deps/${scopedName.replace('@bytelyst/', 'bytelyst-')}-${plan.versions[scopedName]}.tgz`; + +for (const depType of ['dependencies', 'devDependencies']) { + for (const [name, version] of Object.entries(consumer[depType] ?? {})) { + if (name.startsWith('@bytelyst/') && typeof version === 'string' && version.startsWith('file:') && plan.versions[name]) { + consumer[depType][name] = tarballRefFor(name); + } + } +} + +consumer.dependencies ??= {}; + +for (const scopedName of plan.packages) { + const alreadyDeclared = (consumer.dependencies && consumer.dependencies[scopedName]) || (consumer.devDependencies && consumer.devDependencies[scopedName]); + if (!alreadyDeclared) { + consumer.dependencies[scopedName] = tarballRefFor(scopedName); + } +} + +fs.writeFileSync(consumerPath, JSON.stringify(consumer, null, 2) + '\n'); +NODE + +rm -rf "$PACK_SRC_DIR" "$PLAN_FILE" echo " ✅ $DIRNAME ready ($COUNT tarballs in .docker-deps/)" echo ""