-1

Basically I want CI to fail if the dependencies section of the package.json contains any range operator. devDependencies could contain anything thought. Some CLI command would be perfect. Any suggestions?

IAfanasov
  • 4,775
  • 3
  • 27
  • 42

1 Answers1

2

Short answer: Unfortunately, there is no existing built-in npm command/feature to achieve this. However, you can utilize your own custom nodejs script. The nodejs script can then be invoked via a command if you define it in the scripts section of your package.json.

The following describes how to achieve this.


Solution

  1. check-deps.js

    Create a nodejs script as follows. Let's name the script check-deps.js and save it somewhere in your project directory.

    const isSemverRange = require('is-semver-range');
    
    const pkgPath = './path/to/your/package.json';
    const pkgData = require(pkgPath);
    
    function hasSemverRange({ dependencies = {}}) {
      return Object.values(dependencies).some(semver => isSemverRange(semver));
    }
    
    if (hasSemverRange(pkgData)) {
      console.log(`Semver range(s) found in dependencies section of ${pkgPath}`);
      process.exit(1);
    }
    

    Explanation of check-deps.js:

    • Firstly we require the is-semver-range package, which we'll use to help check for any semver ranges. To install this package; cd to your project directory and run the following command:

      npm i -D is-semver-range
      
    • We then define a path to the package.json file (i.e. the file we want to check), and subsequently we require its contents.

      const pkgPath = './path/to/your/package.json'; // <-- Redefine path.
      const pkgData = require(pkgPath);
      

      Note: you'll need to redefine your path to package.json as necessary.

    • The hasSemverRange function parameter definition utilizes object destructuring to unpack the dependencies object, and assigns an empty object as a default value to avoid errors occurring if the dependencies section is missing from package.json.

      In the function body we pass in the dependencies object to the Object.values method, and utilize the Array.some() method to test whether at least one of the values is a semver range.

      This function returns true if the value of any property/key of the dependencies object is as a semver range, otherwise it returns false.

    • Finally, in the if statement condition we invoke the hasSemverRange function, passing to it the parsed contents on package.json. If the condition is truthy we log an error message to the console, and exit the script with a non-zero exit code, i.e. process.exit(1).

  2. package.json

    In the scripts section of your package.json define a script as follows. Let's name the script check-deps:

    "scripts": {
      "check-deps": "node path/to/check-deps.js",
      ...
    }
    

    Note: you'll need to redefine your path to check-deps.js as necessary.

  3. Running the npm script

    Run the following command via your CLI to invoke the check-deps script:

    npm run check-deps
    

    If the value of any property defined in the dependencies section of your package.json is a semver range you'll see something like the following error logged to your console:

    Semver range(s) found in dependencies section of ./path/to/package.json

  4. Integrating the check with your CI tool.

    It's unclear from your question which CI tool you're using. However, typically CI tools provide a feature which allows you to invoke an npm script.

    For example, if your utilizing Travis CI you can define the script to run in your .travis.yml file as follows:

    .travis.yml

    script:
      - npm check-deps
    
  5. Additional Note:

    You could also invoke the npm check-deps script via an existing test script which you may have already defined in your package.json by utilizing the && operator. For instance:

    "scripts": {
      "check-deps": "node path/to/check-deps.js",
      "test": "yourCurrentTestcommands && npm run check-deps"
      ...
    }
    

    Note: In the test script above the yourCurrentTestcommands part should be replaced with any commands that you may currently be running.


RobC
  • 22,977
  • 20
  • 73
  • 80