Node.js child_process module with git command - node.js

First, Please understand that it's not smooth because I use a translator.
I want to create an API server using the child_process module in node.js to send git command.
ex) git clone ..., git pull, git push , ...
And i succeeded!
But there's a big problem here. ;(
execSync(cmd, {stdio: 'inherit', cwd: cwd});
This is my code.
'npm start' And use this API.
Logs are displayed in the cmd window.
It is displayed in the log like this, but I can't allocate it as a variable in my node code. Like stdout, stderr.
If you don't use '{stdio: 'inherit'}' this option, you're successfully assigned to the variable.
But I want to show the log of the server and assign it to the variables.
How can we catch two rabbits?

This would print the log (stdout), and the log is assigned to data.
const childProcess = require("child_process");
const git = childProcess.exec("git pull");
git.stdout.on("data", data => {
console.log(`Git replied: ${data}`);
});
// Git replied: Already up to date.

Related

Unable to read a continuous data stream from a node child process in Node.js

First things first. The goal I want to achieve:
I have two processes:
the first one is webpack that just watches for file changes and pushes the bundled files into the dist/ directory
the second process (Shopify CLI) watches for any file changes in the dist/ directory and pushes them to a remote destination
My goal is to have only one command (like npm run start) which simultaneously runs both processes without printing anything to the terminal so I can print custom messages. And that's where the problem starts:
How can I continuously read child process terminal output?
Printing custom messages for webpack events at the right time is pretty easy, since webpack has a Node API for that. But the Shopify CLI only gives me the ability to capture their output and process it.
Normally, the Shopify CLI prints something like "Finished Upload" as soon as the changed file has been pushed. It works perfectly fine for the first time but after that, nothing is printed to the terminal anymore.
Here is a minimal representation of what my current setup looks like:
const spawn = require('spawn');
const childProcess = spawn('shopify', ['theme', 'serve'], {
stdio: 'pipe',
});
childProcess.stdout.on('data', (data) => {
console.log(data);
});
childProcess.stderr.on('data', (data) => {
// Just to make sure there are no errors
console.log(data);
});

Executing Command in Nodejs and Attaching the output to the console

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)})

Installing NPM Modules via the Frontend

I am working on an app wherein I would like to be able to install NPM modules via the frontend. I have no idea, though, how to do so. That is, I know how to do CRUD actions via the front end, but I don't know how to either interact with the command line or run command line functions via the front end.
Are there packages that can help with this or is this built into Node.js somehow?
In short, how can I connect my front-end to my backend in such a way that I can install an NPM package?
What you want is the child_process module. It's built-in so you don't need to install any additional module.
Mostly what you're looking for is either spawn() or exec().
For example, if you want to run npm install some_module you can do:
const { exec } = require('child_process');
let command = 'npm install some_module';
let options = { cwd: '/path/to/node/project' };
exec(command, options, (error, stdout, stderr) => {
// Do anything you want with program output here:
console.log('output:', stdout, stderr);
});
You may check the documentation for child_process in Node JS:
Child Process
const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
The key difference between exec() and spawn() is how they return the data. As exec() stores all the output in a buffer, it is more memory intensive than spawn(), which streams the output as it comes.
Generally, if you are not expecting large amounts of data to be returned, you can use exec() for simplicity. Good examples of use-cases are creating a folder or getting the status of a file. However, if you are expecting a large amount of output from your command, then you should use spawn()
The easiest way to install an npm package via "the front end" is to have node spawn npm as a child process based off of the package name that the client provides.
var child = require('child_process').exec(`npm i ${package_name}`);
child.on('exit',function(){
//npm finished
});
This should install the module given that package_name is the name of the npm package, in the same directory that the script is running in. In terms of getting the package name from the front end to the back end, there are several different ways to do that.
You cannot run the your backend application without NPM modules installed, one thing that I think you can do is to make a plain nodejs file without any modules, which will receive the args when invoked, and you can use that args to the required modules, because that file will run with just core modules

Node JS: How to check if a dependent application is installed on target machine?

I would like to implement an external dependency validation logic in my Node JS console application. For example, git. In the terminal "git --version" would respond with current version of the git installed. I might use child_process module in Node and invoke shell commands but is there a better way to do it? It should work regardless of the host operating system.
Why Am I having such requirement?
My application should create a git like merge conflict if 2 or 3 versions (Modified, Original, Remote) of the file having conflicting changes. I wish I could use some node modules to achieve. But it turns that there is none. So I decided to use 'git merge-file'. But before executing the command, I would want to check if git is installed or not. This might seem odd but your suggestions are valuable. Thanks in advance.
Child process is the solution you should go for, as you have already figured it out. It's the only way to interact with other processes from Node.js application.
You can have something like:
const { exec } = require('child_process');
exec('git --version', error => {
if (error) {
// Git doesn't exist
// Add your handler code here
}
else {
// Git exists
// Add remaining of code here
}
});

Run tortoise SVN from Node.js

Is it possible to run some simple commands for Tortoise SVN via a Node.js server? Essentially an update and commit on a repository.
You could use the child_process module to execute whatever shell script you want. Just figure out the svn commands you need to execute and refer to the node js child_process docs. You will need svn to be installed on the server your node process is running on.
Here is a simplified example:
const spawn = require('child_process').spawn;
const pathToRepo = findPathToRepoSomehow();
const svnUpdate = spawn('svn', ['update', pathToRepo]);
svnUpdate.on('close', (code) => {
console.log('update successful!');
});
You would want to handle error conditions as well.

Resources