import * as color from "colorette" ; import * as observableProcess from "observable-process" ; import * as tr from "text-runner-core" ; import { callArgs } from "textrun-extension" ; import { CurrentCommand } from "../helpers/current-command" ; import { trimDollar } from "../helpers/trim-dollar" ; interface ProcessInput { readonly input : string ; readonly textToWait : string | null ; } /**
 * The "runConsoleCommand" action runs the given commands on the console
 * and waits until the command is finished.
 */ export async function commandWithInput ( action ) { const content = action . region . textInNodeOfTypes ( "fence" , "code" ) ; const commandsToRun = content . split ( "\n" ) . map ( ( command ) => command . trim ( ) ) . filter ( ( e ) => e ) . map ( trimDollar ) . join ( " && " ) ; if ( commandsToRun === "" ) { throw new Error ( `the <${ action . region [ 0 ] . tag } ${ action . configuration . regionMarker }="exec-with-input"> region contains no commands to run` ) ; } action . name ( `running console command: ${ color . cyan ( commandsToRun ) }` ) ; let input = [ ] ; if ( action . region . hasNodeOfType ( "table" ) ) { input = getInput ( action . region ) ; } const processor = observableProcess . start ( callArgs ( commandsToRun , process . platform ) , { cwd : action . configuration . workspace . platformified ( ) , } ) ; for ( const inputLine of input ) { await enter ( processor , inputLine ) ; } const finished = ( await processor . waitForEnd ( ) ) as observableProcess . FinishedProcess ; CurrentCommand . set ( finished ) ; action . log ( processor . output . fullText ( ) ) ; } async function enter ( processor , input ) { processor . stdin . write ( input . input + "\n" ) ; if ( input . textToWait ) { await processor . stdout . waitForText ( input . textToWait ) ; } } function getInput ( nodes ) { const result = [ ] ; if ( ! nodes ) { return result ; } const tbodyNode = nodes . nodeOfTypes ( "tbody_open" ) ; const tbodyContent = nodes . nodesFor ( tbodyNode ) ; const trNodes = tbodyContent . nodesOfTypes ( "tr_open" ) ; for ( const trNode of trNodes ) { const trContent = nodes . nodesFor ( trNode ) ; if ( trContent . length === 0 ) { continue ; } const tdNode = trContent . nodesOfTypes ( "td_open" ) ; if ( tdNode . length === 0 ) { continue ; } if ( tdNode . length === 1 ) { const text = trContent . textInNode ( tdNode [ 0 ] ) ; result . push ( { textToWait : null , input : text } ) ; } else { result . push ( { input : trContent . textInNode ( tdNode [ tdNode . length - 1 ] ) , textToWait : trContent . textInNode ( tdNode [ 0 ] ) , } ) ; } } return result ; }