Code Monkey home page Code Monkey logo

licensee.js's Introduction

licensee

Check npm package dependency license metadata against rules.

Configuration

Licensee accepts two kinds of configuration:

  1. a rule about permitted licenses
  2. a package allowlist of name-and-range pairs

You can set configuration with command flags or a .licensee.json file at the root of your package, like so:

{
  "licenses": {
    "spdx": [
      "MIT",
      "BSD-2-Clause",
      "BSD-3-Clause",
      "Apache-2.0"
    ]
  },
  "packages": {
    "optimist": "<=0.6.1"
  },
  "corrections": false,
  "ignore": [
    {"scope": "kemitchell"},
    {"prefix": "commonform-"},
    {"author": "Kyle E. Mitchell"}
  ]
}

The licenses object adds licenses to an allowlist. Any package with standard license metadata that satisfies that allowlist according to spdx-whitelisted will not cause an error.

Instead of allowlisting each license by SPDX identifier, you can allowlist categories of licenses.

For example, you can specify a minimum Blue Oak Council license rating---lead, bronze, silver, or gold---like so:

{
  "licenses": {
    "blueOak": "bronze"
  }
}

You can combine categories and specific license identifiers, too:

{
  "licenses": {
    "spdx": ["CC-BY-4.0"],
    "blueOak": "gold"
  }
}

The packages property is a map from package name to a node-semver Semantic Versioning range. Packages whose license metadata don't match the SPDX license expression in licenses but have a name and version described in packages will not cause an error.

The corrections flag toggles community corrections to npm package license metadata. When enabled, licensee will check against license values from npm-license-corrections when available, and also use correct-license-metadata to try to correct old-style licenses arrays and other unambiguous, but invalid, metadata.

The optional ignore array instructs licensee to approve packages without considering their license metadata. Ignore rules can take one of three forms:

  1. {"scope":"x"} ignores all packages in scope x, like @x/y.

  2. {"prefix":"x"} ignores all packages whose names start with x, but not scoped packages whose scopes do not match, like @y/x.

  3. {"author":"x"} ignores all packages whose authors' names, e-mail addresses, or URLs contain x.

All ignore rules are case-insensitive.

Use

To install and use licensee globally:

npm install --global licensee
cd your-package
licensee --init
licensee

The licensee script prints a report about dependencies and their license terms to standard output. It exits with status 0 when all packages in ./node_modules meet the configured licensing criteria and 1 when one or more do not.

To install it as a development dependency of your package:

cd your-package
npm install --save-dev licensee

Consider adding licensee to your npm scripts:

{
  "scripts": {
    "posttest": "licensee"
  }
}

To check only production dependencies, ignoring development dependencies, use --production flag:

{
  "scripts": {
    "posttest": "licensee --production"
  }
}

For output as newline-delimited JSON objects, for further processing:

{
  "scripts": {
    "posttest": "licensee --ndjson"
  }
}

To skip the readout of license information:

{
  "scripts": {
    "posttest": "licensee --quiet"
  }
}

If you want a readout of dependency information, but don't want your continuous integration going red, you can ignore licensee's exit code:

{
  "scripts": {
    "posttest": "licensee || true"
  }
}

To save the readout of license information to a file:

{
  "scripts": {
    "posttest": "licensee | tee LICENSES || true"
  }
}

Alternatively, for a readout of just packages without approved licenses:

{
  "scripts": {
    "posttest": "licensee --errors-only"
  }
}

JavaScript Module

The package exports an asynchronous function of three arguments:

  1. A configuration object in the same form as .licensee.json.

  2. The path of the package to check.

  3. An error-first callback that yields an array of objects, one per dependency.

licensee.js's People

Contributors

kemitchell avatar ljharb avatar brettz9 avatar ericcornelissen avatar bnb avatar janl avatar lencioni avatar amonks avatar sonicdoe avatar plampila avatar

Stargazers

Ray Patterson avatar Eleanor Mozley avatar Romain GAGNAIRE avatar Jacob Hummer avatar 平江 avatar Toby Smith avatar Alexandre Nicastro avatar Mark Tiedemann avatar juspky avatar  avatar Ronaldo Sc avatar Bomin Chuang avatar Al-Khawarizmi avatar Jeffrey Paul avatar Hunter avatar Andrew Nesbitt avatar TED Vortex (Teodor-Eugen Duțulescu) avatar Hunter Tunnicliff avatar Denis Dorotenko avatar Ronan Harris Sujito avatar Leonardo avatar Jaromil avatar Brian Faust avatar Oskar Gewalli avatar Frederik Bosch avatar Pelle Wessman avatar Thomas.G avatar Gregory Daynes avatar Momen avatar Gustavo Porto avatar Mikey Battiston avatar Welkson Ramos avatar Tenvi avatar Darcy Clarke avatar Yasin ATEŞ avatar Eduardo Rabelo avatar Glenn 'devalias' Grant avatar Thomas Deinhamer avatar  avatar Muhammad Farid Zia avatar savi2w avatar Daiki Ihara avatar Sora Morimoto avatar Maximilian Zauner avatar Andrey Goncharov avatar Dheeraj V avatar Ifiok Jr. avatar Matt Travi avatar Rhys Arkins avatar Jeremy Kohn avatar Jannis R avatar Tyler Richards avatar Tomer Aberbach avatar Yoshiya Hinosawa avatar Eduardo Dias avatar Klaus Hartl avatar Robert McGuinness avatar Konstantin Pauk avatar Simone Sanfratello avatar Charlie Robbins avatar Romulo Cintra avatar w96k avatar Ben Briggs avatar  avatar Leo Dutra avatar  avatar  avatar Henri Tanskanen avatar Douglas Duteil avatar Joe Esposito avatar Alexander Akait avatar Luke Hedger avatar Christian Murphy avatar Dennis Torres avatar Michael Danilov avatar Dan Rubins avatar Alan Plum avatar Ryan Bogle avatar Waldir Pimenta avatar Gosha Spark avatar Benedict Juretko avatar Òscar Casajuana avatar deepskyblue avatar James Benner avatar pixelistik avatar Antoine Motet avatar Marcel Eichner avatar Nico Lindemann avatar Jonathan Cremin avatar Arwed Mett avatar Philipp Andreychev avatar Ruslan Kazakov avatar Ali Torki avatar Jerzerak avatar Biko Tushinde avatar Antoine Leblanc avatar Alexander Clausen avatar Moore avatar 爱可可-爱生活 avatar Jonas Hermsmeier avatar

Watchers

 avatar  avatar Benjamin E. Coe avatar  avatar Ron Korving avatar James Cloos avatar shinnn avatar Daijiro Wachi avatar Antoine Motet avatar

licensee.js's Issues

Allow missing `whitelist` property

Currently, the following .licensee.json file is treated as an invalid configuration.

{
  "license": "(MIT OR BSD-2-Clause OR BSD-3-Clause OR Apache-2.0)"
}

I think it would be fine to allow a missing whitelist property.

License blacklist

From the README and looking at https://npmjs.com/packages/spdx-expression-parse it's not clear whether we can have a license blacklist, e.g. NOT GPL.

This could be useful, especially for existing projects where creating and conforming to a whitelist could take some time. It could be simpler to start with "no GPL" (for example) and go from there.

Specify supported Node.js version in the manifest

Relates to #55


Suggestion to add the "engines" field to the project's package.json to make the supported Node.js versions explicit. This would allow users of licensee to be informed about (potential) incompatibility with their current Node.js version if they use the engine-strict option.

Not sure what the preferred approach would be, but based on the list of Node.js version tests some options include:

  • Minimum only:
    • "node": ">=12"
    • "node": "^12 | ^13 | ^14 | ^15 | ^16 | ^17 | >=18"
  • Minimum and maximum (would require a patch update to add support for a new Node.js version):
    • "node": ">=12 <19"
    • "node": "^12 | ^13 | ^14 | ^15 | ^16 | ^17 | ^18"

FR: Flexibility with the SPDX License List

Hello and thank you for this neat module.
I'm not sure this is a good idea but consider being more flexible with the SPDX License Identifiers "parsing".
For instance, some modules have their license set as MIT/X11, meaning to allow for a dual license. In such case licensee could allow the module if the configuration specifies either MIT or X11.
As I said above, not sure this is a good idea as it doesn't follow the "general practices" but it could be made as an option in the licensee.json configuration file.
One more question, Does licensee only scan modules defined under "dependencies" in package.json or does it also scan modules defined under devDependencies ?
Maybe the configuration should allow for specifying which alternative to go with.

Support conjunction

I see parsed SPDX expressions with conjunction are excluded. I'd like to request support for expressions exclusively limited to or conjunctions. It would be nice to optionally support AND conjunctions as well if all of the AND items are present.

Shareable Config

Related to #2 are there any plans to include an extends type property to support shareable configs?

Comments in the .license.json file

Hey :)

Would you be open to the idea of parsing the .licensee.json file using something like json5 so that the file can contain comments?

After having a brief look over the repository, it seems that it could perhaps be a drop-in replacement on line 105 of /licensee with the only changes being:

  • Adding an require statement const JSON5 = require('json5');
  • Changing JSON.parse(data) to JSON5.parse(data).

Thanks for your consideration

Add a "quiet" mode which only shows issues

Thanks for the amazing new module. Immentiately added it to one of our boilerplates. It would be nice though to have a new mode where we can just output the problematic packages in a compact format (no contributors, etc.).

Do you have something like this in mind, too?

Incoming: Arborist

Isaac was kind enough to confirm that read-package-tree will probably be deprecated in favor of Arborist. Arborist will expose a promise API.

I have watched release on the Arborist repo. When the time comes, licensee will want to switch. But I'd strongly recommend that we hold off doing any substantial development until that decision is taken.

Allow ".licensee.js" configuration file

For sharing configuration files between projects as NPM modules it is useful to use dynamic JavaScript files as configuration, in addition to JSON files.

ESLint Config Docs or Commitlint Config Docs can be used as reference.

The .licensee.js configuration file could look like this:

module.exports = {
  licenses: {
    spdx: ['CC-BY-3.0'],
    blueOak: 'bronze',
  },
  packages: {
    'deep-is': '0.1.3',
    diff: '1.4.0',
    doctrine: '1.5.0',
    esutils: '2.0.2',
    'json-schema': '0.2.3',
    wordwrap: '0.0.2',
    longest: '1.0.1',
    'repeat-element': '1.1.2',
  },
  corrections: true,
};

Fails to run on Windows when using --production flag

Running on Windows fails when using the --production flag because spawning an npm process fails.

This is because spawn does not use the PATHEXT env var on Windows and does not find the npm command that is actually called npm.cmd. See: nodejs/node-v0.x-archive#2318

Not sure what is the best way to deal with this issue. There is a cross-spawn package. Using shell option for spawn seems to be an option etc.

Wildcards?

We have lots of internal packages under either a scope, or a common name prefix. It would be great to be able to whitelist "airbnb-*", for example, without having to manually add each new one to the list.

Option to ignore missing peer dependencies

Hello!

We've recently updated to Angular 8 and we've come across a scenario where a dependency has not updated its dependency list to support the new version and is thus raising an expected peer dependency error. This causes a problem with licensee when npm ls is used to retrieve the production dependency list. As a result, our license check is failing in our build pipeline. We've disabled the license check as a temporary workaround.

This is the underlying error being raised by npm ls --production:

peer dep missing: @angular/core@>=6.0.0 <8.0.0, required by [email protected]

We have confirmed that, for our purposes, this is a safe upgrade as we await the PR but were wondering if it would be possible to add a flag to ignore peer dependency errors. Right now, we are unable to get a list of actual license errors --errors-only --production since the task fails on the peer dependency errors and exits before parsing the json.

Something like:

licensee --production --errors-only --ignorePeerDepsErrors

There doesn't appear to be a flag on npm ls to ignore those errors, unfortunately. That would have been an easier fix.

I'm willing to attempt a PR if this sounds ok. Thoughts?

Thank you!

Using "ignore" lead to UnhandledPromiseRejection

I've got an error "UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'toLowerCase' of undefined" trying to use "ignore" filter. (licensee\index.js:327:17)

It caused by package node_modules\\@svgr\\webpack\\node_modules\\@babel\\plugin-proposal-private-methods. This package results in empty object inside tree.package in resultForPackage func.

Option to skip dev dependencies

I'm primarily concerned with the licenses I distribute, not the licenses of the dev tools I use.

Could there be an option like --production that skipped devDeps (but checked deps, peerDeps, bundledDeps, etc)?

blacklist option

Are there any plans to introduce a blacklist option, for both licenses and packages?

Time to drop fs-access dependency?

I assume everybody is getting the same warning as I am:

npm WARN deprecated [email protected]: This package is no longer relevant as Node.js 0.12 is unmaintained.

Node.js 0.12 is ancient, so maybe it's time to drop this dependency?

Support for `licenses` property

Ran into this on with corsify.

{"licenses": [
    {
      "type": "MIT",
      "url": "http://github.com/Raynos/corsify/raw/master/LICENSE"
    }
  ]
}

I didn't even know about this property and style of format but apparently it's in use :/

[email protected] (Invalid license metadata)

Use "allowlist" and "blocklist" rather than "whitelist"

The terminology "whitelist" and "blacklist" are used in a way that mean "good, blessed, permitted, positive" and "bad, forsaken, forbidden, negative" respectively. These are problematic in our society for reasons that are relatively obvious.

Instead, it would be preferable to use "allowlist" and "blocklist" or "allowlist" and "denylist" where the terminology is present.

I'm happy to submit a PR to make changes where relevant. I wanted to get a +1 from the maintainers via an Issue first, however, so as not to be particularly intrusive with a PR that is focusing on a negative.

If the use of spdx-whitelist is a blocker, I'm also happy to help do work there and in its upstream dependencies to update its terminology or help rename and republish it to spdx-allowlist or whatever other terminology that is preferred.

References on others doing this same thing/discussing the subject:

deduping

I'm seeing multiple entries in the list - presumably when a dependency is duplicated in the graph.

It'd be ideal if when the package name and license data are the same, they could all be collapsed to a single entry (with a semver range covering the ones that are the same).

When misspelling the blueOak category name, it doesn't warn me

I think missconfiguration should be rather fatal, as it can be hard to validate (especially on small projects with few dependencies) that the test that is running is actually correct. It may give false positives. It would be nice if, when passing a blueOak value of foo, it would throw an error saying that is not an existing category.

List location of dependency

[email protected]
  NOT APPROVED
  Terms: Invalid license metadata
  Repository: git://github.com/jashkenas/underscore.git
  Homepage: http://underscorejs.org
  Author: Jeremy Ashkenas <[email protected]>
  Contributors: None listed

It would be great to know where [email protected] is being called - it is not the most recent version, and I suspect that many packages use the old style for declaring licenses in package.jsons:

// Not valid metadata
{ "license" :
  { "type" : "ISC"
  , "url" : "https://opensource.org/licenses/ISC"
  }
}

While note SPDX approved, this shouldn't be flagging the same error as the others, because there is a license, at least. Alternatively to declaring where the dep is being called, this module could check for older license checks.

This may be out of scope for this module.

Whitelist of packages to include

Would it be in scope for you to support giving a list of package names/ranges to include for checking (and not check anything else)?

In order to display content on the likes of raw.githack.com for browser scripts, I have a routine to copy dependencies out of node_modules and reference the copies instead and to only add them in devDependencies. However, I'm not interested in licenses for all of the other (many) devDependencies, so I'd like to whitelist my own list for checking rather than being forced to explicitly ignore the ones that are not of interest.

Cannot run without .licensee.json file

~/random-project $ licensee
Cannot read ~/random-project/.licensee.json

Would be ideal to automatically create this file with licensee --init, or to specify in usage that it must be manually created first.

Idea: give 'packages' a more descriptive name

Firstly thanks for the useful tool! One small piece of feedback - a colleague messages me last week with:

should i trust https://github.com/myco/myapp/blob/master/frontend/.licensee.json as the full list of packages/licenses?
i would have thought there should be a lot more

This is despite me mentioning previously that packages is a list of exceptions, rather than a list of all packages.

I suspect my colleague (and I, when I first started using licensee) are not the only one confused by the key name packages. Giving it a more descriptive name might help eliminate the confusion!

Some better names might be:

  • ignorePackages
  • ignore
  • exceptions

etc. Anyway thanks for listening to the suggestion!

Licenses key

Hi
Licensee currently only checks the license key and ignores the old npm format licenses key - can you update licensee so that it at least makes any information under a licenses key available to anyone using licensee - you don't need to do anything with it but if its available it avoids me having to re-read package.json files to check if that key exists
many thanks

Support 'LicenseRef' license name when initializing the package.json with 'npm init' command

Why cannot use 'LicenseRef' license name when initializing the package.json with 'npm init' command?

image

If users wants to add the proprietary license name in package.json, they may also want to add the license name to match the spdx license expression. Because it is easier to manage the license name of their package than using 'SEE LICENSE IN '.

What about changing to accept 'LicenseRef-' spdx license expression?

I can't whitelist invalid SPDX identifiers

Whether or not a package is using a valid identifier or not, I'd like to be able to whitelist it's license type. I have multiple packages with "MIT/X11", and since that's basically MIT, i'd like to allow those - but licensee errors out.

fs-access deprecated (but also unnecessary)

For starters: I will make a PR for this later.

This was briefly discussed in #42, but since #55 dropped support for unmaintained versions of Node, we can progress with this issue now too.

I realized that this is not just an issue of replacing fs-access with fs.access (the Node built-in not present in older versions of Node), but actually, the only place where it's used, fs.access is not actually needed. The more robust way to check for file non-existence is to check for error.code === 'ENOENT' when reading fails.

Monorepository (lerna) issue

Currently I am working on a mono-repository using lerna and its feature of hoisting dependencies (quoting from https://github.com/lerna/lerna/blob/master/doc/hoist.md):

When an overall project is divided into more than one NPM package, this organizational improvement generally comes with a cost: the various packages often have many duplicate dependencies in their package.json files, and as a result hundreds or thousands of duplicated files in various node_modules directories. By making it easier to manage a project comprised of many NPM packages, Lerna can inadvertently exacerbate this problem.

Fortunately, Lerna also offers a feature to improve the situation - Lerna can reduce the time and space requirements for numerous copies of packages in development and build environments, by "hoisting" dependencies up to the topmost, Lerna-project-level node_modules directory instead.

As per my understanding, licensee.js is using the read-package-tree library (by which it will look at the node_modules folder structure only) from npm to understand which dependencies to check and basically - in combination with the previous described behaviour - in my case is checking also the licenses of transitive dependencies.

This in principles can be good but it should be configurable from my point of view with a flag/option (depth?) and the process should also relay not only on the node_modules structure but also - probably - on the lockfiles (both npm-shrinkwrap and package-lock) where the details about a dependency are more precise.

Am I wrong?

Support third-party assessments of package license?

I've been thinking a bit about allowing licensee to use external "mappings" from package@version to SPDX ID, for those packages that have an SPDX-identified license, but haven't coded it correctly in package.json.

I find myself copying the same whitelist mappings from project to project. This could solve.

update dependencies

Hi @kemitchell can you update your dependencies - im currently getting

├─┬ [email protected]
│ └─┬ [email protected]
│ └─┬ [email protected]
│ └─┬ [email protected]
│ └─┬ [email protected]
│ └─┬ [email protected]
│ └── [email protected]
└─┬ [email protected]
└── [email protected]

licensee is using the old spdx-license-ids - a few of the module dependencies in the tree need updating to fix this - can you also bump the licensee version when you've updated this.

thanks

Documenting `--production`/`productionOnly`

I figure the README should include documentation with at least one example of either the flag --production or API productionOnly. I can prepare a PR, but wanted to see if there were opinions on how.

Parse license object(s)

As well as licenses, license has allowed an albeit now deprecated object per https://docs.npmjs.com/files/package.json#license

{ "license" :
  { "type" : "ISC"
  , "url" : "https://opensource.org/licenses/ISC"
  }
}

(While a comment states, "Not valid metadata", it goes on to say "Those styles are now deprecated", i.e., they are not entirely rejected yet.)

Some packages still use this format, so weren't being found for approval. I think this format, and the array format, should be supported.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.