NPM script problems - javascript

I have a nodejs file runner.node.js.
If I run node runner.node.js it works
But if I try tu run it with npm test (it's referenced in package.json):
"test": "node ./spec/runner.node.js"
or
"test": "spec/runner.node.js"
It says that the file isn't executable:
sh: 1: spec/runner.node.js: Permission denied
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
If I set the file as executable it then says:
spec/runner.node.js: 1: spec/runner.node.js: Syntax error: word unexpected (expecting ")")
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
while it still runs correctly with "node spec/runner.node.js"
The file is this:
console.log("Running Knockout tests in Node.js");
var fs = require('fs');
var jasmine = require('./lib/jasmine-1.2.0/jasmine');
// export jasmine globals
for (var key in jasmine) {
global[key] = jasmine[key];
}
// add our jasmine extensions to the exported globals
require('./lib/jasmine.extensions');
// export ko globals
if (process.argv.length > 2 && process.argv[2] == '--source') {
// equivalent of ../build/knockout-raw.js
global.DEBUG = true;
global.ko = global.koExports = {};
global.knockoutDebugCallback = function(sources) {
sources.unshift('build/fragments/extern-pre.js');
sources.push('build/fragments/extern-post.js');
eval(sources.reduce(function(all, source) {
return all + '\n' + fs.readFileSync(source);
}, ''));
};
require('../build/fragments/source-references');
} else {
global.ko = require('../build/output/knockout-latest.js');
}
// reference behaviors that should work out of browser
require('./arrayEditDetectionBehaviors');
require('./asyncBehaviors');
require('./dependentObservableBehaviors');
require('./expressionRewritingBehaviors');
require('./extenderBehaviors');
require('./mappingHelperBehaviors');
require('./observableArrayBehaviors');
require('./observableBehaviors');
require('./subscribableBehaviors');
// get reference to jasmine runtime
var env = jasmine.jasmine.getEnv();
// create reporter to return results
function failureFilter(item) {
return !item.passed();
}
env.addReporter({
reportRunnerResults:function (runner) {
var results = runner.results();
runner.suites().map(function (suite) {
// hack around suite results not having a description
var suiteResults = suite.results();
suiteResults.description = suite.description;
return suiteResults;
}).filter(failureFilter).forEach(function (suite) {
console.error(suite.description);
suite.getItems().filter(failureFilter).forEach(function (spec) {
console.error('\t' + spec.description);
spec.getItems().filter(failureFilter).forEach(function (expectation) {
console.error('\t\t' + expectation.message);
});
});
});
console.log("Total:" + results.totalCount + " Passed:" + results.passedCount + " Failed:" + results.failedCount);
process.exit(results.failedCount);
}
});
// good to go
env.execute();

Add
#/usr/bin/env node
as the first line in your file. This way, when run as an executable your OS will know that it shall use Node.js to run it (to be exactly: your OS will know that it shall use the first application called node to execute your script).

Related

Getting a blank cmd prompt on running a bat file in nodejs

I am trying to run a .bat file by passing arguments to it in nodejs. However, I get an empty command prompt. How to get the command pasted on the path.
code -
server.js
var bat = require.resolve('E:/API_Gateway_through_Swagger/New_Project/aws-bat-file-3.bat');
var num = "123"
var state_desc = "abc";
var ls = spawn(bat, [num, state_desc ]);
ls.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
ls.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
ls.on('exit', function (code) {
console.log('child process exited with code ' + code);
});
Bat file -
aws-bat-file-3.bat
echo off
echo "Batch Started"
set arg1=%1
set arg2=%2
START "Task Options" cmd.exe /b " cd C:\Users\myfolder & aws apigateway create deployment --rest-api-id %arg1% --stage-name dev --stage-description %arg2%"
output img file is -
NodeJS documented the problem of spawning batch files on Windows thoroughly in this section.
Excerpt:
When running on Windows, .bat and .cmd files can be invoked using child_process.spawn() with the shell option set, with child_process.exec(), or by spawning cmd.exe and passing the .bat or .cmd file as an argument (which is what the shell option and child_process.exec() do).
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });

How to have cli-spinner run during ShellJS command exec?

I'm currently trying to make a simple command-line node program that allows for me to easily create a boilerplate for a lot of the React/Redux applications that I make. I'm using ShellJS to execute console commands (I've tried using Node's child_process, too.) The problem is getting cli-spinner to work with executing terminal commands. Here's my code:
#! /usr/bin/env node
var shell = require('shelljs');
var userArgs = process.argv.slice(2);
var folderName = userArgs[0];
var Spinner = require('cli-spinner').Spinner;
var depSpin = new Spinner('Installing dependencies.. %s');
depSpin.setSpinnerString(10);
shell.mkdir(folderName);
shell.cd(folderName);
depSpin.start();
// I expect for the spinner to start here (before the execution of the commands.)
shell.exec('npm init -y', {silent: true});
shell.exec('npm install --save babel-core babel-loader babel-preset-es2015 babel-preset-react react-dom react-redux redux webpack', {silent: true});
shell.exec('npm install --save-dev babel-preset-env webpack-dev-server', {silent: true});
depSpin.stop();
// Since ShellJS should run synchronously,
// the spinner should stop right after the last command finishes.
shell.touch('webpack.config.js');
shell.mkdir(['build', 'frontend']);
shell.cd('frontend');
shell.mkdir(['components', 'containers', 'reducers', 'store']);
shell.touch('app.js');
But when running the program, it just hangs without displaying anything while it installs the dependencies. It's the same as when the spinner code wasn't even in there. I've also tried removing the depSpin.stop(), which just makes the program hang forever on the spinner. I have a feeling that this issue is caused by a conflict between cli-spinner and ShellJS both using the terminal.
I was able to accomplish this effect by using child_process's spawn. I had to create a child_process.spawn and run all of the commands concatenated with &&. That freed up the console output to be exclusively the cli-spinner output. I then did an event handler for when the child process exited to stop the spinner.
#! /usr/bin/env node
var shell = require('shelljs');
var userArgs = process.argv.slice(2);
var folderName = userArgs[0];
var Spinner = require('cli-spinner').Spinner;
var depSpin = new Spinner('Installing dependencies.. %s');
var spawn = require('child_process').spawn;
var commandsDep = [
'cd ' + folderName,
'npm init -y',
'npm install --save babel-core babel-loader babel-preset-es2015 babel-preset-react react-dom react-redux redux webpack',
'npm install --save-dev babel-preset-env webpack-dev-server'
];
var depChild = spawn(commandsDep.join(' && '), {
shell: true
});
depSpin.setSpinnerString(18);
shell.mkdir(folderName);
shell.cd(folderName);
depSpin.start();
depChild.on('exit', () => {
depSpin.stop();
shell.exec('clear');
console.log('Installing dependencies.. ✓');
})
shell.touch('webpack.config.js');
shell.mkdir(['build', 'frontend']);
shell.cd('frontend');
shell.mkdir(['components', 'containers', 'reducers', 'store']);
shell.touch('app.js');
shell.cd('containers');
shell.touch(['AppContainer.js', 'Root.js']);
shell.cd('../reducers');
shell.touch('index.js');
shell.cd('../store');
shell.touch('configureStore.js');
Based on Owens' answer I made a helper method myself to run long commands with a spinner inline with normal shelljs commands;
const Spinner = require('cli-spinner').Spinner;
const spinner = new Spinner('installing.. %s');
spinner.setSpinnerString('|/-\\');
var spawn = require('child_process').spawn;
const longCommand = (command, onSuccess) => {
return new Promise((resolve, reject) => {
var process = spawn(command, { shell: true });
spinner.start();
process.on('exit', () => {
spinner.stop();
onSuccess();
resolve();
})
})
}
const npmInstall = async () => {
await longCommand("npm install", () => console.log(`NPM modules installed! 👍`))
// Other stuff
shell.mkdir('new')
}
npmInstall()

how to create simple nodejs script to wrap an binary/executable?

I want to create a nodejs file, that simple runs/wraps an executable binary file with all inputs and outputs.
For now at least on windows.
Why:
wanted to install an executable tool over npm install -g, to have it in console, without PATH changes. (npm global packages are included in PATH)
i used such solution:
const path = require("path");
const spawnSync = require('child_process').spawnSync;
const pathToMyExe = path.join(__dirname, 'bin', 'myfile.exe'); //just path to exe
const input = process.argv.slice(2); //minus "node" and "this js" arguments
spawnSync(pathToMyExe, input, {stdio: 'inherit'});
but for ".exe to PATH" problem, there is a simplier way (if you want windows only).
just set bin property in package.json to pathToExe.
https://docs.npmjs.com/files/package.json#bin
You can use the bin-wrapper npm package.
EDIT:
There's a better alternative called bin-manager.
Installation:
$ npm install --save bin-manager
Usage
const bmanager = require('bin-manager');
const base = 'https://github.com/imagemin/gifsicle-bin/raw/master/vendor';
const bin = bmanager('bin', 'gifsicle')
.src(base + '/macos/gifsicle', 'darwin')
.src(base + '/linux/x64/gifsicle', 'linux', 'x64')
.src(base + '/win/x64/gifsicle.exe', 'win32', 'x64')
.use(process.platform === 'win32' ? 'gifsicle.exe' : 'gifsicle');
bin.run(['--version'], (err, out) => {
if (err) {
console.log(error);
return;
}
console.log(out.stdout);
});

Node.js - Cannot read property 'toString' of null when running package on Windows

I am using the gulp and hercule package on node.js to transclude some plain text files. On Unix, everything seems to work fine. However, some coworkers are having issues running it on Windows. They are getting the following error message only when running on Windows:
[13:02:01] TypeError: Cannot read property 'toString' of null at Object.transcludeStringSync (D:\project\node_modules\hercule\lib\hercule.js:136:36)
I have tried the above with hercule#3.0.5 as well as hercule#2.0.5, and both packages give the above error. However, given that this occurs only on Windows and across many versions of the package, I suspect this issue has something to due with the Node.js installation or path.
The code that is using the hercule package:
var fs = require('fs');
var path = require('path');
var gulp = require('gulp');
var drakov = require('drakov');
var hercule = require('hercule');
gulp.task('mock', ['i18n','build_minify_no_tests'], function() {
var mockSpecificationTemplate= fs.readFileSync('test/mock/mock-template.apib','utf8');
var transcludedMockSpecification = hercule.transcludeStringSync(mockSpecificationTemplate, {
relativePath: path.resolve('../../../')
});
fs.writeFileSync('test/mock/mock.apib', transcludedMockSpecification, 'utf-8');
// Running mock server
var drakovArgv = {
sourceFiles: 'test/mock/mock.apib',
serverPort: 9000,
staticPaths: [
'../../'
],
discover: true,
watch: true
};
drakov.run(drakovArgv);
});
node and npm version information:
$ node -v
v6.3.0
$ npm -v
3.10.3
hercule.transcludeStringSync simply runs another hercule process and sends input to it:
const result = childProcess.spawnSync('../bin/hercule', syncArgs, syncOptions);
with the script ../bin/hercule:
#!/usr/bin/env node
"use strict";
require('../lib/main.js');
...obviously doesn't work on Windows
If that task must be synchronized, you may use the following function instead:
function transcludeStringSync(input, options) {
const {dirname, join} = require('path')
const hercule = join(dirname(require.resolve('hercule')), 'main')
const args = [hercule, '--reporter', 'json-err']
for (let name in options) {
args.push(`--${name}`, `--${options[name]}`)
}
const result = require('child_process').spawnSync('node', args, {input})
const err = result.stderr.toString()
if (err) throw new Error('Could not transclude input')
return result.stdout.toString()
}

How to extract global variable __coverage__ value afterEach hook for Istanbul coverage?

I have this code in my unit test case file test.js
browser.driver.executeScript('if (typeof __coverage__ !== "undefined") { return __coverage__; }').then(function(val) {
if(val){
var now = new Date();
var destFile = process.env.TEST_DIR + "/output/code-coverage/istanbul/" + "protractor-" + now.getTime().toString() + "-collected-coverage.json";
console.log("Collecting code coverage and save it to " + destFile + ".");
fs.writeFileSync(destFile , JSON.stringify(val));
} else {
console.log("No code coverage found.");
} });
};
module.exports.writeCoverage = writeCoverage;
That is supposed to extract the js object value from global variable __coverage__ and write it to a JSON file. It works for protractor test cases but with mocha unit tests, I am hitting this error:
mocha test.js
"after each" hook for "Get Complete Module List":
ReferenceError: browser is not defined
at Object.writeCoverage (/home/../src/writeCoverage.js:4:3)
at Context. (test.js:7:11)
I appreciate the help.
Thanks!

Categories

Resources