I am trying to run a golang application in interactive mode (so that it will prompt users for information it needs) from nodejs, like so:
childprocess.execFileSync(pulumiExecutable, ["stack", "select"], { encoding: "utf-8", shell: true, stdio: "inherit" });
However it uses this function to automatically disable interactive mode, if it thinks that it is not run from a terminal. Presumably because IsTerminal() is returning false.
Given that I am telling nodejs to inherit IO streams from the parent process, I am wondering what else I can try to do in order to stay in interactive mode when invoking pulumi from within nodejs.
Turns out that there were two reasons why it was not running in interactive mode:
Running the nodejs program as WebStorm Run Configuration makes it non-interactive.
Running the child-process in shell mode makes it non-interactive too.
This works when the nodejs program is run from a terminal:
childprocess.execFileSync(pulumiExecutable, ["stack", "select"], { encoding: "utf-8", stdio: "inherit" });
Related
How can i mimic the action of double-clicking the application (.exe) on the desktop with nodejs, knowing the path to the exe. I want to launch the application and it remain open even after i close the the Nodejs application that launched it.
I've tried a bunch of options but they all seem to have issues not showing the applications native popup window. Which makes me believe it's an issue with the way im launching it from nodejs.
export function testExecute() {
const command =
"C:/Program Files/Side Effects Software/Houdini 18.5.633/bin/happrentice.exe";
const cmd = `"${command}"`;
// OPTION 1: Applications built in console doesn't show when launching
exec(cmd).unref();
// OPTION 2: Applications built in console doesn't show when launching either
spawn(cmd, [], {
detached: true,
shell: true,
stdio: ["ignore", "ignore", "ignore"],
});
}
I'm working on a CLI tool to add an extra layer of automation and utilities to our workflow and I'm wrapping the webpack development command with an alternative in my CLI (here's a demonstration):-
function runDev(){
this.doSomePreAutomationAndPreperations();
this.runWebpackDevCommand();
}
I'm using NodeJs child_proecess.exec and I'm trying to figure out a way to execute the webpack dev command and attach it to the terminal (like -it in docker if you're familiar with it) or transferring the control to the child process(so output will be directly emitted to the console).
Is there away to do that?
It turns out that I can achieve this but just making the child process inherit the stdio. ex:-
const { spawn } = require('child_process')
const shell = spawn('sh',[], { stdio: 'inherit' })
shell.on('close',(code)=>{console.log('[shell] terminated :',code)})
With Intern, how can I run some setup code in Node prior to running browser tests, but not when running Node tests? I know that I could do that outside of Intern completely, but is there anything that's a part of Intern that could handle that?
For a more concrete example: I'm running tests for an HTTP library that communicates with a Python server. When running in Node, I can run spawn("python", ["app.py"]) to start the server. However, in the browser, I would need to run that command before the browser begins running the tests.
Phrased another way: is there a built-in way with Intern to run some code in the Node process prior to launching the browser tests?
By default, Intern will run the plugins configured for node regardless of which environment you're running in.
So, you could create a plugin that hooks into the runStart and runEnd events like this:
intern.on("runStart", () => {
console.log("Starting...");
// Setup code here
});
intern.on("runEnd", () => {
console.log("Ending...");
// Teardown code here
});
These handlers will run inside the Node process, and thus have access to all the available Node APIs.
Additionally, you can detect which environments are being tested by looking at intern.config.environments:
{
environments: [
{
browserName: 'chrome',
browserVersion: undefined,
version: undefined
}
]
}
By looking at the environments, you can determine whether or not you need to run your setup code.
I'm building an Electron application (Node.js) which needs to spawn gcloud app deploy from the application with realtime feedback (stdin/stdout/stderr).
I rapidly switched from child_process to execa because I had some issues on Mac OS X with the child_process buffer which is limited to 200kb (and gcloud app deploy sends some big chunk of string > 200kb which crash the command).
Now, with execa everything seems to work normally on OSX but not on Windows.
The code looks something like this:
let bin = `gcloud${/^win/.test(process.platform) ? '.cmd' : ''}`
//which: https://github.com/npm/node-which
which(bin, (err, fullpath) => {
let proc = execa(fullpath, ['app', 'deploy'], {
cwd: appPath
})
proc.stdout.on('data', data => {
parseDeploy(data.toString())
})
proc.stderr.on('data', data => {
parseDeploy(data.toString())
})
proc.then(() => {
...
}).catch(e => {
...
})
})
This code works perfectly on Mac OS X while I haven't the same result on Windows
I have tried lots of thing:
execa()
execa.shell()
options shell:true
I tried maxBuffer to 1GB (just in case)
It works with detached:true BUT I can't read stdout / stderr in realtime in the application as it prompts a new cmd.exe without interaction with the Node.js application
Lots of child_process variant.
I have made a GIST to show the responses I get for some tests I have done on Windows with basic Child Process scripts:
https://gist.github.com/thyb/9b53b65c25cd964bbe962d8a9754e31f
I also opened an issue on execa repository: https://github.com/sindresorhus/execa/issues/97
Does someone already got this issue ? I've searched around and found nothing promising except this reddit thread which doesn't solve this issue.
Behind the scene, gcloud.cmd is running a python script. After reading tons of Node.js issue with ChildProcess / Python and Windows, I fell on this thread: https://github.com/nodejs/node-v0.x-archive/issues/8298
There is some known issue about running Python scripts from a Node.js Child Process.
They talk in this comment about an unbuffered option for python. After updating the shell script in gcloud.cmd by adding the -u option, I noticed everything was working as expected
This comment explains how to set this option as an environment variable (to not modify the windows shell script directly): https://docs.python.org/2/using/cmdline.html#envvar-PYTHONUNBUFFERED
So adding PYTHONUNBUFFERED to the environment variable fix this issue !
execa(fullpath, ['app', 'deploy'], {
cwd: appPath,
env: Object.assign({}, process.env, {
PYTHONUNBUFFERED: true
})
})
I'm working on a Visual Studio Code extension in which I hope to create a terminal which gives access to a custom shell. I have a Node.js script (.js file) which implements this shell. Now, I'm trying to use Code's createTerminal method from my extension to launch a terminal that uses my Node.js script as its shell.
I can't directly set the shellPath to be my js file, because I have no guarantee that the user has Node.js installed, that the system will run such files with Node.js, nor what version of Node is installed. I need to be able to point at a universally-understood binary which can handle the file. Roughly speaking, I want to do this:
let terminal = vscode.window.createTerminal({
name: "My terminal",
shellPath: 'node', // Use the Node.js executable as the target
shellArgs: [path.join(__dirname, 'my-shell-wrapper.js')] // Tell Node to run my shell
});
terminal.show();
How can I accomplish this? Is there an executable that ships with Code that I can point to which runs Node scripts? Or is there another mechanism which I'm missing?
VSCode now (as of the past year or so) has the option of specifying custom behaviors for terminals aside from just the underlying shell executable. createTerminal has an overload which takes ExtensionTerminalOptions; this has a pty property which allows you to specify custom handlers for reading from and writing to the terminal. From their Pseudoterminal documentation:
const writeEmitter = new vscode.EventEmitter<string>();
const pty: vscode.Pseudoterminal = {
onDidWrite: writeEmitter.event,
open: () => {},
close: () => {},
handleInput: data => writeEmitter.fire(data === '\r' ? '\r\n' : data)
};
vscode.window.createTerminal({ name: 'Local echo', pty });
This can be used to implement arbitrary terminal interactions.