11import { exec , spawn } from 'node:child_process' ;
2+ import events from 'node:events' ;
3+ import fs from 'node:fs' ;
24import os from 'node:os' ;
35import path from 'node:path' ;
4- import { Binary } from 'binary-install' ;
6+ import { pipeline } from 'node:stream/promises' ;
7+ import { fileURLToPath } from 'node:url' ;
58import { filesystem , patching , print , system } from 'gluegun' ;
69import yaml from 'js-yaml' ;
710import semver from 'semver' ;
811import { Args , Command , Flags } from '@oclif/core' ;
912import { GRAPH_CLI_SHARED_HEADERS } from '../constants.js' ;
10- import fetch from '../fetch.js' ;
1113
1214export default class TestCommand extends Command {
1315 static description = 'Runs rust binary for subgraph testing.' ;
@@ -144,32 +146,52 @@ async function runBinary(
144146 } ,
145147) {
146148 const coverageOpt = opts . coverage ;
147- const forceOpt = opts . force ;
148149 const logsOpt = opts . logs ;
149150 const versionOpt = opts . version ;
150151 const latestVersion = opts . latestVersion ;
151152 const recompileOpt = opts . recompile ;
153+ let binPath = '' ;
152154
153- const platform = await getPlatform . bind ( this ) ( versionOpt || latestVersion , logsOpt ) ;
155+ try {
156+ const platform = await getPlatform . bind ( this ) ( versionOpt || latestVersion , logsOpt ) ;
154157
155- const url = `https://github.com/LimeChain/matchstick/releases/download/${
156- versionOpt || latestVersion
157- } / ${ platform } `;
158+ const url = `https://github.com/LimeChain/matchstick/releases/download/${ versionOpt || latestVersion } / ${ platform } ` ;
159+ const binDir = path . join ( path . dirname ( fileURLToPath ( import . meta . url ) ) , 'node_modules' , '.bin' ) ;
160+ binPath = path . join ( binDir , `matchstick- ${ platform } `) ;
158161
159- if ( logsOpt ) {
160- this . log ( `Download link: ${ url } ` ) ;
162+ if ( logsOpt ) {
163+ this . log ( `Download link: ${ url } ` ) ;
164+ this . log ( `Binary path: ${ binPath } ` ) ;
165+ }
166+
167+ if ( ! fs . existsSync ( binPath ) ) {
168+ this . log ( `Downloading matchstick binary: ${ url } ` ) ;
169+ await fs . promises . mkdir ( binDir , { recursive : true } ) ;
170+ const response = await fetch ( url ) ;
171+ if ( ! response . ok ) throw new Error ( `Status: ${ response . statusText } ` ) ;
172+ if ( ! response . body ) throw new Error ( 'No response body received' ) ;
173+
174+ const fileStream = fs . createWriteStream ( binPath ) ;
175+ await pipeline ( response . body , fileStream ) ;
176+ await fs . promises . chmod ( binPath , '755' ) ;
177+ }
178+ } catch ( e ) {
179+ this . error (
180+ `Failed to get matchstick binary: ${ e . message } \nConsider using -d flag to run it in Docker instead:\n graph test -d` ,
181+ { exit : 1 } ,
182+ ) ;
161183 }
162184
163- const binary = new Binary ( platform , url , versionOpt || latestVersion ) ;
164- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
165- forceOpt ? await binary . install ( true ) : await binary . install ( false ) ;
166185 const args = [ ] ;
167-
168186 if ( coverageOpt ) args . push ( '-c' ) ;
169187 if ( recompileOpt ) args . push ( '-r' ) ;
170188 if ( datasource ) args . push ( datasource ) ;
171- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
172- args . length > 0 ? binary . run ( ...args ) : binary . run ( ) ;
189+
190+ const child = spawn ( binPath , args , { stdio : 'inherit' } ) ;
191+ const [ code ] = await events . once ( child , 'exit' ) ;
192+ if ( code !== 0 ) {
193+ this . error ( 'Matchstick failed' , { exit : 1 } ) ;
194+ }
173195}
174196
175197async function getPlatform (
@@ -180,7 +202,7 @@ async function getPlatform(
180202 const type = os . type ( ) ;
181203 const arch = os . arch ( ) ;
182204 const cpuCore = os . cpus ( ) [ 0 ] ;
183- const isAppleSilicon = arch === 'arm64' && / A p p l e ( M 1 | M 2 | M 3 | M 4 | p r o c e s s o r ) / . test ( cpuCore . model ) ;
205+ const isAppleSilicon = arch === 'arm64' && / A p p l e ( M [ 0 - 9 ] | p r o c e s s o r ) / . test ( cpuCore . model ) ;
184206 const linuxInfo = type === 'Linux' ? await getLinuxInfo . bind ( this ) ( ) : { } ;
185207 const linuxDistro = linuxInfo . name ;
186208 const release = linuxInfo . version || os . release ( ) ;
@@ -204,7 +226,7 @@ async function getPlatform(
204226 }
205227 return 'binary-macos-12' ;
206228 }
207- if ( type === 'Linux' && majorVersion === 22 ) {
229+ if ( type === 'Linux' && ( majorVersion === 22 || majorVersion === 24 ) ) {
208230 return 'binary-linux-22' ;
209231 }
210232 } else {
@@ -283,10 +305,6 @@ async function runDocker(
283305 const latestVersion = opts . latestVersion ;
284306 const recompileOpt = opts . recompile ;
285307
286- // Remove binary-install binaries, because docker has permission issues
287- // when building the docker images
288- filesystem . remove ( './node_modules/binary-install/bin' ) ;
289-
290308 // Get current working directory
291309 const current_folder = filesystem . cwd ( ) ;
292310
0 commit comments