11#!/usr/bin/env bun
22
3- import { mkdtempSync , mkdirSync , rmSync } from "node:fs" ;
3+ import {
4+ cpSync ,
5+ mkdtempSync ,
6+ mkdirSync ,
7+ readFileSync ,
8+ rmSync ,
9+ statSync ,
10+ writeFileSync ,
11+ } from "node:fs" ;
412import path from "node:path" ;
5- import { getHostPlatformPackageSpec , releaseNpmDir } from "./prebuilt-package-helpers" ;
13+ import {
14+ binaryFilenameForSpec ,
15+ getHostPlatformPackageSpec ,
16+ releaseNpmDir ,
17+ } from "./prebuilt-package-helpers" ;
618
719function run ( command : string [ ] , options ?: { cwd ?: string ; env ?: NodeJS . ProcessEnv } ) {
820 const proc = Bun . spawnSync ( command , {
@@ -34,6 +46,7 @@ const tempRoot = path.join(repoRoot, "tmp");
3446mkdirSync ( tempRoot , { recursive : true } ) ;
3547const packageDir = mkdtempSync ( path . join ( tempRoot , "hunk-prebuilt-pack-" ) ) ;
3648const installDir = mkdtempSync ( path . join ( tempRoot , "hunk-prebuilt-install-" ) ) ;
49+ const smokeMetaDir = mkdtempSync ( path . join ( tempRoot , "hunk-prebuilt-meta-" ) ) ;
3750const nodeBinary = Bun . spawnSync ( [ "bash" , "-lc" , "command -v node" ] , {
3851 stdin : "ignore" ,
3952 stdout : "pipe" ,
@@ -44,28 +57,73 @@ const resolvedNode = Buffer.from(nodeBinary.stdout).toString("utf8").trim();
4457if ( nodeBinary . exitCode !== 0 || resolvedNode . length === 0 ) {
4558 throw new Error ( "Could not resolve node on PATH for the prebuilt install smoke test." ) ;
4659}
60+ const bashBinary = Bun . spawnSync ( [ "bash" , "-lc" , "command -v bash" ] , {
61+ stdin : "ignore" ,
62+ stdout : "pipe" ,
63+ stderr : "pipe" ,
64+ env : process . env ,
65+ } ) ;
66+ const resolvedBash = Buffer . from ( bashBinary . stdout ) . toString ( "utf8" ) . trim ( ) ;
67+ if ( bashBinary . exitCode !== 0 || resolvedBash . length === 0 ) {
68+ throw new Error ( "Could not resolve bash on PATH for the prebuilt install smoke test." ) ;
69+ }
4770const nodeDir = path . dirname ( resolvedNode ) ;
71+ const bashDir = path . dirname ( resolvedBash ) ;
4872
4973try {
5074 run ( [ "npm" , "pack" , "--pack-destination" , packageDir ] , {
5175 cwd : path . join ( releaseRoot , hostSpec . packageName ) ,
5276 } ) ;
53- run ( [ "npm" , "pack" , "--pack-destination" , packageDir ] , {
54- cwd : path . join ( releaseRoot , "hunkdiff" ) ,
55- } ) ;
5677
5778 const platformTarball = path . join ( packageDir , `${ hostSpec . packageName } -${ packageVersion } .tgz` ) ;
79+
80+ // Point a temp copy of the staged meta package at the local platform tarball.
81+ // The real manifest uses semver ranges, but this smoke test runs before publish.
82+ const smokePackageDir = path . join ( smokeMetaDir , "hunkdiff" ) ;
83+ cpSync ( path . join ( releaseRoot , "hunkdiff" ) , smokePackageDir , { recursive : true } ) ;
84+ const smokeManifestPath = path . join ( smokePackageDir , "package.json" ) ;
85+ const smokeManifest = JSON . parse ( readFileSync ( smokeManifestPath , "utf8" ) ) as {
86+ optionalDependencies ?: Record < string , string > ;
87+ } ;
88+ smokeManifest . optionalDependencies = {
89+ ...smokeManifest . optionalDependencies ,
90+ [ hostSpec . packageName ] : `file:${ platformTarball } ` ,
91+ } ;
92+ writeFileSync ( smokeManifestPath , `${ JSON . stringify ( smokeManifest , null , 2 ) } \n` ) ;
93+
94+ run ( [ "npm" , "pack" , "--pack-destination" , packageDir ] , {
95+ cwd : smokePackageDir ,
96+ } ) ;
5897 const metaTarball = path . join ( packageDir , `hunkdiff-${ packageVersion } .tgz` ) ;
5998
60- run ( [ "npm" , "install" , "-g" , "--prefix" , installDir , platformTarball ] ) ;
6199 run ( [ "npm" , "install" , "-g" , "--prefix" , installDir , metaTarball ] ) ;
62100
63- const sanitizedPath = ` ${ path . join ( installDir , "bin" ) } : ${ nodeDir } ` ;
101+ const sanitizedPath = [ path . join ( installDir , "bin" ) , nodeDir , bashDir ] . join ( ":" ) ;
64102 const installedHunk = path . join ( installDir , "bin" , "hunk" ) ;
103+ const installedPlatformBinary = path . join (
104+ installDir ,
105+ "lib" ,
106+ "node_modules" ,
107+ "hunkdiff" ,
108+ "node_modules" ,
109+ hostSpec . packageName ,
110+ "bin" ,
111+ binaryFilenameForSpec ( hostSpec ) ,
112+ ) ;
65113 const commandEnv = {
66114 ...process . env ,
67115 PATH : sanitizedPath ,
68116 } ;
117+
118+ if ( process . platform !== "win32" ) {
119+ const installedBinaryMode = statSync ( installedPlatformBinary ) . mode & 0o777 ;
120+ if ( ( installedBinaryMode & 0o111 ) === 0 ) {
121+ throw new Error (
122+ `Expected installed platform binary to keep execute bits, got mode ${ installedBinaryMode . toString ( 8 ) } at ${ installedPlatformBinary } ` ,
123+ ) ;
124+ }
125+ }
126+
69127 const help = run ( [ installedHunk , "--help" ] , {
70128 env : commandEnv ,
71129 } ) ;
@@ -102,4 +160,5 @@ try {
102160} finally {
103161 rmSync ( packageDir , { recursive : true , force : true } ) ;
104162 rmSync ( installDir , { recursive : true , force : true } ) ;
163+ rmSync ( smokeMetaDir , { recursive : true , force : true } ) ;
105164}
0 commit comments