How to run npm sh script on Windows and Unix - node.js

I want to run a sh script that detects my npm version via npm scripts.
I have the following script and it works cool:
if [ $(npm -v | cut -c 1 | awk '{print $1\"<3\"}' | bc -l) != 0 ]; then echo '[ERROR] You need npm version #>=3\n' && false; fi
But this script works only on *NIX when I run the script on windows I got a error:
$(npm was unexpected at this time.
I want to detect if I'm running the script on Windows then don't execute the script, I tried this, but again only works on *NIX:
if [ 'uname -s' != CYGWIN* ]; then if [ $(npm -v | cut -c 1 | awk '{print $1\"<3\"}' | bc -l) != 0 ]; then echo '[ERROR] You need npm version #>=3\n' && false; fi; fi
Then I got:
'uname was unexpected at this time.
I was checking that the equivalent of uname on windows is systeminfo
But if I use systeminfo then I got the undefined on *NIX.
Any ideas of how can I make this script work on Windows && *NIX?

If you want to execute your bash script on a platform that is not Windows you could check the platform with node itself (assuming that node is installed) using os.platform()
scripts: {
checkNpmVersion: "node -e \"process.exit(require('os').platform() === 'win32')\" && ./check-npm.sh"
}
Or even better you could write your little script in node so that it works on any platform (again assuming that node is installed)
// check-npm.js
const exec = require('child_process').exec
exec('npm -v', function (err, stdout, stderr) {
if (err) throw err
if (stdout.match(/^3/)) throw "npm>3 required"
})
And in the scripts field
scripts: {
checkNpmVersion: "node check-npm.js"
}
Tested on Win7 with Node v4.4.5 and npm 2.15.5

Related

How to execute two BASH shell commands from a single test?

Why does this not work?
test $? -eq 1 || $(echo "hello"; echo "hi")
I get the following error:
Command 'hello' not found, but can be installed with:
snap install hello # version 2.10, or
apt install hello # version 2.10-2ubuntu4
apt install hello-traditional # version 2.10-5
See 'snap info hello' for additional versions.
You're looking for 3.2.5.3 Grouping Commands
test $? -eq 1 || { echo "hello"; echo "hi"; }
The spaces around the braces and the trailing semicolon (or newline) are required.
However, don't test the exit status with the $? variable (it's too easy to accidentally insert another command in there)
Use the command directly
some command here && { echo hello; echo hi; }

Problems creating a React-node app with npm

The instructions are as following:
You are about to start creating a React-node app. Create the file
package.json using npm commands.
Make use of the following information:
The name of the app should be npm_package. The start point will be
index.js The project should have the following elements of
dependencies
- Install the latest version of react
- Lodash with major version 4 and minor version 17,
- Redux with Major version 4,
- Mocha for testing in Dev,
- Eslint with major version 6 in Dev.
Here is my virtual environment for reference:
Virtual Environment
I tried the following commands:
npm init -y
npm install react --save
npm install lodash#4.17.0 --save
npm install redux#4.0.0 --save
npm install mocha --save-dev
npm install eslint#6.0.0 --save-dev
Correctness is determined by the test file score.sh:
#!/bin/sh
PASS=0
FAIL=0
TEST_1=$(grep -o -e "\"dependencies\"" -e "react" -e "\"redux\":\s*\"\^4.*\"" -e "\"lodash\":\s*\"\^4.17.*\"" /projects/challenge/package.json| wc -l)
TEST_2=$(grep -o -e "\"devDependencies\":\s*{" -e "\"eslint\":\s*\"^6.*\"" -e "\"mocha\":\s*" /projects/challenge/package.json| wc -l)
TEST_3=$(find /projects/challenge/node_modules | wc -l)
TEST_4=$(grep -o -e "\"name\":\s*\"npm_package\"" /projects/challenge/package.json| wc -l)
if [ "$TEST_1" -eq 4 ]
then ((PASS++))
fi;
if [ "$TEST_2" -eq 3 ]
then ((PASS++))
fi;
if [ "$TEST_3" -ge 1 ]
then ((PASS++))
fi;
if [ "$TEST_4" -eq 1 ]
then ((PASS++))
fi;
FAIL=$(( 4 - $PASS ))
echo "Test cases executed = 4";
echo "PASS = $PASS FAIL=$FAIL"
Here is my console when I run the tests:
user#workspace5zx0357qxb7p4nvt:/projects/challenge$ bash score.sh Test
cases executed = 4 PASS = 3 FAIL=1
user#workspace5zx0357qxb7p4nvt:/projects/challenge$
It does not tell me which test failed (or much of any other information) and therefore I dont know which of my commands I inputted is wrong or am I missing commands
Since no one has decided to reply, let me.
Just go into package.json and change the name to npm_package.

Check if package.json has script with a certain name in shell script without using extra NPM packages

I am testing a larger library of NPM packages, that consists of private packages, altered forks of public packages or downstreams of public packages.
lib
|-package_1
|-package_2
|-package_N
So I am running a shell script through my package lib, that runs in each directory the npm test command.
for D in *; do
if [ -d "${D}" ]; then
echo "================================="
echo "${D}" # PRINT DIRECTORY NAME
echo "================================="
cd $D
npm run tests
cd ../ # LEAVE PACKAGE DIR
fi
done
Unfortunately there is not a unique pattern for naming the tests-script in the package's JSON files. Some package are running under test a script with watch-mode and have a different name for their cli script (mostly named testcli).
What I would like to do is something like the following pseudocode:
if has-testcli-script then
npm run testcli
else
npm run test
I assume for now, that only those two options exist. I am rather interested in the way of knowing if the script exists, without installing an additional global NPM package.
Since npm version 2.11.4 at least, calling npm run with no arguments will list all runable scripts. Using that you can check to see if your script is present. So something like:
has_testcli_script () {
[[ $(npm run | grep "^ testcli" | wc -l) > 0 ]]
}
if has_testcli_script; then
npm run testcli
else
npm test
fi
Or alternatively, just check to see if your script is in the package.json file directly:
has_testcli_script () {
[[ $(cat package.json | grep "^ \"testcli\":" | wc -l) > 0 ]]
}
In my case that approach didn't work and I had to implement something using jq instead.
has_script (script) {
[[ ! -z "$(jq -rc --arg key $script '.scripts | to_entries | .[] | select(.key == \$key)' package.json)" ]]
}
then use it as:
if has_script('testcli'); then
// Do something
else
// Do nothing
fi

Running bash script via Node.js - Illegal option -o pipefail

I am trying to exec a bash script via Node.js using child_process.exec(). However it is blowing up on the second line of the file:
#!/usr/bin/env bash
set -eo pipefail; [[ $TRACE ]] && set -x
echo "we are here"
The error returned is:
/bin/sh: 2: set: Illegal option -o pipefail
Why is this happening? When I run the script manually, not from Node it works fine. Here is the Node.js code:
var child = child_proc.exec(bashScript, {
env: _.extend(process.env, {
'LB_HOST': config.loadBalancers.lb1
}),
timeout: 0
});
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
By default when you invoke child_process.exec() it uses /bin/sh which on Ubuntu is actually a symbolic link pointing to /bin/dash. Dash is a stripped down version of bash and I guess does not support:
set -eo pipefail; [[ $TRACE ]] && set -x
Adding the shell option to the Node.js child_proc.exec() fixes this:
shell: '/bin/bash'

shell script error

I have the following line in a shell script:
if [ -f /etc/init.d/tomcat6 && ps -C java|grep -qs 'java' ]; then
which throws up the following error when I try to run it:
line 12: [: missing `]'
I have a feeling that this is an encoding issue as I've been editing the file in Notepadd++ on a windows xp pc, I've ensured I've set the encoding to encode in UTF-8 without BOM and that all the line endings are linux style yet I still receive this error.
Can anyone help?
Thanks
Try
if [ -f /etc/init.d/tomcat6 ] && ps -C java | grep -qs 'java'; then
...
fi
[ is basically an alias for the test command. test does not know anything about an argument ps. Alternatively you may use test explicitely (just to clarify syntax):
if test -f /etc/init.d/tomcat6 && ps -C java | grep -qs 'java'; then
...
fi
If you use [ instead of test, you are forced to end the expression with ].
The && ends your [ command.
if [ -f /etc/init.d/tomcat6 ] && ps -C java | grep -qs 'java'; then
The syntax for and is -a.
You need to run ps -C java|grep -qs 'java', it is currently evaluated as an expression. Try this:
if [ -f /etc/init.d/tomcat6 -a $(ps -C java|grep -qs 'java') ]; then

Resources