Node.js - Call a system command or external command - javascript

I've an issue with Node.js. With Python, if I wanted to execute an external command, I used to do something like this:
import subprocess
subprocess.call("bower init", shell=True)
I've read about child_process.exec and spawn in Node.js but I can't do what I want. And what's I want?
I want to execute an external command (like bower init) and see its output in real time and interact with bower itself. The only thing I can do is receive the final output but that don't allow me to interact with the program.
Regards
Edit: I saw this question but the answer doesn't work here. I want to send input when the external program needs it.

How about this?
var childProcess = require('child_process');
var child = childProcess.spawn('bower', ['init'], {
env: process.env,
stdio: 'inherit'
});
child.on('close', function(code) {
process.exit(code);
});
Seemed to work for me

Related

PYTHON module "requests" not working with packaged electron app

In my electron app I have a python file that has two import statements shown below
import requests
import shutil
The app works fine without an errors in the IDE but after packaging the electron app with
npx electron-packager ./ --platform=darwin --icon=src/img/logo.icns
The app gives me this error
It only gives this error for the 'requests' module but not the 'shutil' module. And yes, 'requests' is installed on my computer. I also use the PythonShell module in the js file to run the python file like below
function version_checker(){
form.classList.toggle('hide');
circle.classList.toggle('show');
let pyshell = new PythonShell(__dirname + '/version_checker.py');
pyshell.on('message', function (message){
console.log(message);
if(message !== "same"){
console.log("updating")
}
else{
if(message !== "restart"){
form.classList.toggle('hide');
circle.classList.toggle('show');
}
else{}
}
})
pyshell.end(function (err,code,signal) {
if (err) throw err;
console.log('The exit code was: ' + code);
console.log('The exit signal was: ' + signal);
console.log('finished');
});
}
I also do not wish to compile the python file into an executable because the python script "talks" to the js file. I am also on a M1 Pro Macbook running macOS Ventrua if that helps
How do I package the app and include the 'requests' module OR How do I make the 'requests' module work with the packaged app
I did find a stackoverflow post that asked a similar question but the owner voluntary took down the question so I wasn't able to view it
I looked at this post but it wasn't helpful because I'm not using 'anaconda' or 'child-process'
PythonShell just calls the system's Python interpreter, so use PIP to install the requests library
Or specify the interpreter as follows:
new PythonShell(__dirname + '/version_checker.py', {
pythonPath: '/path/to/python'
})
Note: For production purposes, it is recommended to include an interpreter in electron and install dependencies
It seems you just want to make a HTTP request, why not try fetch in javascript?
If the error is ModuleNotFoundError, then your python interpreter is struggling to find the requests module. This can happen for a number of reasons:
Module does not exist: We can rule this out if your ide ran program successfully.
2: Module is not where interpreter expects to find it: Most likely.
Almost certainly the python interpreter used by your IDE is different to the one you ran after packaging the electron app.
The solution is to either:
a. make sure the location of requests is visible to the PYTHONPATH by setting that in the proper location (I don't use MAC but I believe you have ~/.bash_profile file to set it in or
b. Explicitly add the request module location via a sys.path.append command in your code eg
import sys
import os
path = 'your path to request module'
sys.path.append(os.path.join(path, 'requests')
import requests
You should be able to find the path location by investigating your IDE and looking where you set the module to be included in your program

Executing Simple Unix Terminal Commands using Node.js

I am trying to execute simple terminal commands through Node.js but so far have only gotten 'ls' to work.. What if I want to change directory etc? Anyone know how to do that?
Here is code that just does the 'ls' command via Node.js.
var exec = require('child_process').exec;
var cmd = 'ls';
exec(cmd,function(error,stdout,stderr){
console.log(stdout);
console.log(stderr);
if(error!=null){
console.log(error);
}
});
Well I'm using a command abtrations for doing thing like that.. You can practically use the cd like in your terminal whit this:
https://www.npmjs.com/package/shelljs
how to use a cd:
var shell = require('shelljs');
shell.cd('../');
and the good thing It's that is an abstraction to the command so It should work on any OS..
First : Try to get the input data from your console
Second : Try to execute it in the node code
Third : Try to get the result and show it in your console
All those steps, you can get the answer from google or docs of nodejs. If you can't find the answer, try to search it in npm.

unti testing in sails js [duplicate]

I'm completely new to sails, node and js in general so I might be missing something obvious.
I'm using sails 0.10.5 and node 0.10.33.
In the sails.js documentation there's a page about tests http://sailsjs.org/#/documentation/concepts/Testing, but it doesn't tell me how to actually run them.
I've set up the directories according to that documentation, added a test called test/unit/controllers/RoomController.test.js and now I'd like it to run.
There's no 'sails test' command or anything similar. I also didn't find any signs on how to add a task so tests are always run before a 'sails lift'.
UPDATE-2: After struggling a lil bit with how much it takes to run unit test this way, i decided to create a module to load the models and turn them into globals just as sails does, but without taking so much. Even when you strip out every hook, but the orm-loader depending on the machine, it can easily take a couple seconds WITHOUT ANY TESTS!, and as you add models it gets slower, so i created this module called waterline-loader so you can load just the basics (Its about 10x faster), the module is not stable and needs test, but you are welcome to use it or modify it to suit your needs, or help me out to improve it here -> https://github.com/Zaggen/waterline-loader
UPDATE-1:
I've added the info related to running your tests with mocha to the docs under Running tests section.
Just to expand on what others have said (specially what Alberto Souza said).
You need two steps in order to make mocha work with sails as you want. First, as stated in the sails.js Docs you need to lift the server before running your test, and to do that, you create a file called bootstrap.test.js (It can be called anything you like) in the root path (optional) of your tests (test/bootstrap.test.js) that will be called first by mocha, and then it'll call your test files.
var Sails = require('sails'),
sails;
before(function(done) {
Sails.lift({
// configuration for testing purposes
}, function(err, server) {
sails = server;
if (err) return done(err);
// here you can load fixtures, etc.
done(err, sails);
});
});
after(function(done) {
// here you can clear fixtures, etc.
sails.lower(done);
});
Now in your package.json, on the scripts key, add this line(Ignore the comments)
// package.json ....
scripts": {
// Some config
"test": "mocha test/bootstrap.test.js test/**/*.test.js"
},
// More config
This will load the bootstrap.test.js file, lift your sails server, and then runs all your test that use the format 'testname.test.js', you can change it to '.spec.js' if you prefer.
Now you can use npm test to run your test.
Note that you could do the same thing without modifying your package.json, and typying mocha test/bootstrap.test.js test/**/*.test.js in your command line
PST: For a more detailed configuration of the bootstrap.test.js check Alberto Souza answer or directly check this file in hist github repo
See my test structure in we.js: https://github.com/wejs/we-example/tree/master/test
You can copy and paste in you sails.js app and remove we.js plugin feature in bootstrap.js
And change you package.json to use set correct mocha command in npm test: https://github.com/wejs/we-example/blob/master/package.json#L10
-- edit --
I created a simple sails.js 0.10.x test example, see in: https://github.com/albertosouza/sails-test-example
Given that they don't give special instructions and that they use Mocha, I'd expect that running mocha from the command line while you are in the parent directory of test would work.
Sails uses mocha as a default testing framework.
But Sails do not handle test execution by itself.
So you have to run it manually using mocha command.
But there is an article how to make all Sails stuff included into tests.
http://sailsjs.org/#/documentation/concepts/Testing

Nodejs library without nodejs

How can I integrate a nodejs library into my non nodejs project?
I am particularly needing this library:
https://github.com/greenify/biojs-io-blast
BioJS uses Browserify CDN to automatically generate a single JS file for usage. Either include
<script src="http://wzrd.in/bundle/biojs-io-blast#latest"></script>
in your html or download the JS file via this link.
We also have a live JS Bin example here.
Yes, you can do it using a Publisher/Subscribe pattern and a Queue library, such as RabbitMQ.
In the example below, the author is communicating a python script with a NodeJS one, using the RabbitMQ clients for each platform.
https://github.com/osharim/Communicate-Python-with-NodeJS-through-RabbitMQ
The code for sending from NodeJS:
var amqp = require('amqp');
var amqp_hacks = require('./amqp-hacks');
var connection = amqp.createConnection({ host: "localhost", port: 5672 });
connection.on('ready', function(){
connection.publish('task_queue', 'Hello World!');
console.log(" [x] Sent from nodeJS 'Hello World!'");
amqp_hacks.safeEndConnection(connection);
});
Then, receiving in python:
#!/usr/bin/env python
import pika
import time
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='task_queue', durable=True)
#our callback
def suscriber(ch,method , properties , body):
print "[Y] received %r " % (body,)
time.sleep( body.count('.') )
print " [x] Done"
ch.basic_ack(delivery_tag = method.delivery_tag)
channel.basic_qos(prefetch_count=1)
channel.basic_consume(suscriber, queue = 'task_queue')
print ' [*] Waiting for messages from Python. To exit press CTRL+C'
channel.start_consuming()
to integrate any node library you use the package manager NPM https://www.npmjs.com/ so to integrate your library do as follow
open terminal
cd path/to/your/project_dir
type this line
npm install biojs-io-blast
This is the more common use case. Some of the node.js libraby, i like them too much i want to use it everywhere. But this library, what i see uses core modules of node.js like fs. I dont think you can use it without node dependency || node binary. But as Code Uniquely or others folks says, if you are using webpack as a build/dev. You can try, browserify or BioJS
The node_module which provided is kind of xml parser. You can't add nodejs library (node_module) to non nodejs programs. You can get xml parser for Blast depending on kind of programming language you are using.
For example :
For PHP phpBlastXmlParser and
For java this might helpfull

How do I start a CoffeeScript repl from within a CoffeeScript script?

If I do
repl = require 'repl'
repl.start {useGlobal: true}
It starts a Node repl. How do I start a CoffeeScript repl instead?
Thanks
Nesh is a project to try and make this a bit easier and extensible:
http://danielgtaylor.github.com/nesh/
It provides a way to embed a REPL with support for multiple languages like CoffeeScript as well as providing an asyncronous plugin architecture, support to execute code in the context of the REPL on startup, etc. For example:
nesh = require 'nesh'
nesh.loadLanguage 'coffee'
nesh.start (err, repl) ->
nesh.log.error err if err
It also supports a bunch of options with the default plugins and exposes some built-in convenience functions as well:
opts =
welcome: 'Welcome to my interpreter!'
prompt: '> '
evalData: CoffeeScript.compile 'hello = (name="world") -> "Hello, #{world}!"', {bare: true}
nesh.start opts, (err, repl) ->
nesh.log.error err if err
I think the coffee-script module does not export the REPL functionality to be used programmatically, like the Node repl module does. But CoffeeScript has a repl.coffee file that can be used, even though it's not exported in the main coffee-script module. Taking a hint from command.coffee (which is the file that's executed when you run the coffee command) we can see that the REPL works just by requiring the repl file. So, running this script should start a CoffeeScript REPL:
require 'coffee-script/lib/coffee-script/repl'
This approach, however, is quite hacky. The most important flaw is that it heavily depends on how the coffee-script module works internally and how it's organized. Nothing prevents the repl.coffee file from being moved from coffee-script/lib/coffee-script, or changing the way it works.
A better approach might be calling the coffee command without arguments, just like one would do from the commandline, from Node:
{spawn} = require 'child_process'
spawn 'coffee', [], stdio: 'inherit'
The stdio: 'inherit' option makes the spawned command to read from stdin and write to the stdout of the current process.

Categories

Resources