11import fs from "node:fs" ;
22import assert from "node:assert" ;
3- import { execa } from "execa" ;
43import { additionalFiles } from "./core/additionalFiles.js" ;
54import { BuildManifest } from "@trigger.dev/core/v3" ;
65import { BuildContext , BuildExtension } from "@trigger.dev/core/v3/build" ;
76import { logger } from "@trigger.dev/sdk/v3" ;
8-
9- import type { VerboseObject } from "execa" ;
7+ import { x , Options as XOptions , Result } from "tinyexec" ;
108
119export type PythonOptions = {
1210 requirements ?: string [ ] ;
@@ -30,8 +28,6 @@ export type PythonOptions = {
3028 scripts ?: string [ ] ;
3129} ;
3230
33- type ExecaOptions = Parameters < typeof execa > [ 1 ] ;
34-
3531const splitAndCleanComments = ( str : string ) =>
3632 str
3733 . split ( "\n" )
@@ -124,26 +120,24 @@ class PythonExtension implements BuildExtension {
124120
125121export const run = async (
126122 scriptArgs : string [ ] = [ ] ,
127- options : ExecaOptions = { }
128- ) : Promise < ReturnType < typeof execa > > => {
123+ options : Partial < XOptions > = { }
124+ ) : Promise < Result > => {
129125 const pythonBin = process . env . PYTHON_BIN_PATH || "python" ;
130126
131- const result = await execa ( {
132- shell : true ,
133- verbose : ( line : string , obj : VerboseObject ) => logger . debug ( obj . message , obj ) ,
127+ const result = await x ( pythonBin , scriptArgs , {
134128 ...options ,
135- } ) ( pythonBin , scriptArgs ) ;
129+ throwOnError : false , // Ensure errors are handled manually
130+ } ) ;
136131
137132 try {
138- assert ( ! result . failed , `Python command failed: ${ result . stderr } \nCommand: ${ result . command } ` ) ;
139133 assert (
140134 result . exitCode === 0 ,
141135 `Python command exited with non-zero code ${ result . exitCode } \nStdout: ${ result . stdout } \nStderr: ${ result . stderr } `
142136 ) ;
143137 } catch ( error ) {
144138 logger . error ( "Python command execution failed" , {
145139 error : error instanceof Error ? error . message : error ,
146- command : result . command ,
140+ command : ` ${ pythonBin } ${ scriptArgs . join ( " " ) } ` ,
147141 stdout : result . stdout ,
148142 stderr : result . stderr ,
149143 exitCode : result . exitCode ,
@@ -157,25 +151,23 @@ export const run = async (
157151export const runScript = (
158152 scriptPath : string ,
159153 scriptArgs : string [ ] = [ ] ,
160- options : ExecaOptions = { }
154+ options : Partial < XOptions > = { }
161155) => {
162156 assert ( scriptPath , "Script path is required" ) ;
163157 assert ( fs . existsSync ( scriptPath ) , `Script does not exist: ${ scriptPath } ` ) ;
164158
165159 return run ( [ scriptPath , ...scriptArgs ] , options ) ;
166160} ;
167161
168- export const runInline = async ( scriptContent : string , options : ExecaOptions = { } ) => {
162+ export const runInline = async ( scriptContent : string , options : Partial < XOptions > = { } ) => {
169163 assert ( scriptContent , "Script content is required" ) ;
170164
171- // Create a temporary file with restricted permissions
172165 const tmpFile = `/tmp/script_${ Date . now ( ) } .py` ;
173166 await fs . promises . writeFile ( tmpFile , scriptContent , { mode : 0o600 } ) ;
174167
175168 try {
176169 return await runScript ( tmpFile , [ ] , options ) ;
177170 } finally {
178- // Clean up temporary file
179171 await fs . promises . unlink ( tmpFile ) ;
180172 }
181173} ;
0 commit comments