bashshellnpmnpm-run

How to check if npm script exists?


I am creating a bash script which runs through each of my projects and runs npm run test if the test script exists.

I know that if I get into a project and run npm run it will give me the list of available scripts as follows:

Lifecycle scripts included in www:
  start
    node server.js
  test
    mocha --require @babel/register --require dotenv/config --watch-extensions js **/*.test.js

available via `npm run-script`:
  dev
    node -r dotenv/config server.js
  dev:watch
    nodemon -r dotenv/config server.js
  build
    next build

However, I have no idea how to grab that information, see if test is available and then run it.

Here is my current code:

#!/bin/bash

ROOT_PATH="$(cd "$(dirname "$0")" && pwd)"
BASE_PATH="${ROOT_PATH}/../.."

while read MYAPP; do # reads from a list of projects
  PROJECT="${MYAPP}"
  FOLDER="${BASE_PATH}/${PROJECT}"
  cd "$FOLDER"
  if [ check here if the command exists ]; then
    npm run test
    echo ""
  fi
done < "${ROOT_PATH}/../assets/apps-manifest"

Solution

  • EDIT: As mentioned by Marie and James if you only want to run the command if it exists, npm has an option for that:

    npm run test --if-present
    

    This way you can have a generic script that work with multiple projects (that may or may not have an specific task) without having the risk of receiving an error.

    Source: https://docs.npmjs.com/cli/run-script

    EDIT

    You could do a grep to check for the word test:

    npm run | grep -q test
    

    this return true if the result in npm run contains the word test

    In your script it would look like this:

    #!/bin/bash
    
    ROOT_PATH="$(cd "$(dirname "$0")" && pwd)"
    BASE_PATH="${ROOT_PATH}/../.."
    
    while read MYAPP; do # reads from a list of projects
      PROJECT="${MYAPP}"
      FOLDER="${BASE_PATH}/${PROJECT}"
      cd "$FOLDER"
      if npm run | grep -q test; then
        npm run test
        echo ""
      fi
    done < "${ROOT_PATH}/../assets/apps-manifest"
    

    It just would be a problem if the word test is in there with another meaning Hope it helps