jackspeak
Advanced tools
Comparing version 1.4.2 to 2.0.0
{ | ||
"name": "jackspeak", | ||
"version": "1.4.2", | ||
"version": "2.0.0", | ||
"description": "A very strict and proper argument parser.", | ||
"main": "index.js", | ||
"main": "./dist/cjs/index.js", | ||
"module": "./dist/mjs/index.js", | ||
"types": "./dist/mjs/index.js", | ||
"exports": { | ||
".": { | ||
"import": { | ||
"types": "./dist/mjs/index.d.ts", | ||
"default": "./dist/mjs/index.js" | ||
}, | ||
"require": { | ||
"types": "./dist/cjs/index.d.ts", | ||
"default": "./dist/cjs/index.js" | ||
} | ||
} | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"scripts": { | ||
"build-examples": "for i in examples/*.js ; do node $i -h > ${i/.js/.txt}; done", | ||
"snap": "TAP_SNAPSHOT=1 tap test/*.js -J && npm run build-examples", | ||
"test": "tap test/*.js --100 -J", | ||
"preversion": "npm test", | ||
"postversion": "npm publish", | ||
"postpublish": "git push origin --all; git push origin --tags" | ||
"prepublishOnly": "git push origin --follow-tags", | ||
"prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh", | ||
"pretest": "npm run prepare", | ||
"presnap": "npm run prepare", | ||
"test": "c8 tap", | ||
"snap": "c8 tap", | ||
"format": "prettier --write . --loglevel warn", | ||
"typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" | ||
}, | ||
"license": "ISC", | ||
"license": "BlueOak-1.0.0", | ||
"prettier": { | ||
"semi": false, | ||
"printWidth": 75, | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"singleQuote": true, | ||
"jsxSingleQuote": false, | ||
"bracketSameLine": true, | ||
"arrowParens": "avoid", | ||
"endOfLine": "lf" | ||
}, | ||
"tap": { | ||
"coverage": false, | ||
"node-arg": [ | ||
"--no-warnings", | ||
"--loader", | ||
"ts-node/esm" | ||
], | ||
"ts": false | ||
}, | ||
"devDependencies": { | ||
"tap": "^16.3.0" | ||
"@types/node": "^18.15.11", | ||
"@types/pkgjs__parseargs": "^0.10.0", | ||
"@types/tap": "^15.0.8", | ||
"c8": "^7.13.0", | ||
"eslint-config-prettier": "^8.8.0", | ||
"prettier": "^2.8.6", | ||
"tap": "^16.3.4", | ||
"ts-node": "^10.9.1", | ||
"typedoc": "^0.23.28", | ||
"typescript": "^5.0.2" | ||
}, | ||
"files": [ | ||
"index.js" | ||
], | ||
"dependencies": { | ||
"cliui": "^7.0.4" | ||
}, | ||
"engines": { | ||
"node": ">=14" | ||
}, | ||
"funding": { | ||
"url": "https://github.com/sponsors/isaacs" | ||
}, | ||
"repository": { | ||
@@ -41,5 +95,5 @@ "type": "git", | ||
"author": "Isaac Z. Schlueter <i@izs.me>", | ||
"engines": { | ||
"node": ">=8" | ||
"optionalDependencies": { | ||
"@pkgjs/parseargs": "^0.11.0" | ||
} | ||
} |
506
README.md
@@ -5,258 +5,202 @@ # jackspeak | ||
## USAGE | ||
Validate string, boolean, and number options, from the command | ||
line and the environment. | ||
Pass one or more objects into the exported `jack(...)` function. Each | ||
object can have the following fields, and would typically represent a | ||
"section" in a usage/help output. | ||
Call the `jack` method with a config object, and then chain | ||
methods off of it. | ||
Using multiple sections allows for using some of the "special" fields | ||
as argument names as well; just put them in different sections. | ||
At the end, call the `.parse()` method, and you'll get an object | ||
with `positionals` and `values` members. | ||
- `main` Function | ||
Any unrecognized configs or invalid values will throw an error. | ||
May only appear once. If provided, will be called with the resulting | ||
parsed object. | ||
As long as you define configs using object literals, types will | ||
be properly inferred and TypeScript will know what kinds of | ||
things you got. | ||
Each of the defined flags and options will be set on the result | ||
object, as well as a special `_` array containing all the positional | ||
arguments. `_` also has the following properties: | ||
If you give it a prefix for environment variables, then defaults | ||
will be read from the environment, and parsed values written back | ||
to it, so you can easily pass configs through to child processes. | ||
- `usage` A function that dumps the help output to stdout. | ||
- `explicit` A `Set` containing the names of all arguments that were | ||
explicitly set. | ||
- `original` The `argv` array before any expansions. | ||
- `parsed` The `argv` array once all aliases have been expanded. | ||
- `reparse` A function that takes a string or array of strings, and | ||
parses it according to the options initially provided. Note that | ||
this does _not_ update the results object, it's just for expanding | ||
aliases and short options. | ||
- `update` A function that takes either a single `--key=val`, an array | ||
of `--key=val` values, or an object (as read from an rc file, for | ||
example), and updates the result data accordingly. This will _not_ | ||
update any options set explicitly in the original argv. | ||
Automatically generates a `usage`/`help` banner by calling the | ||
`.usage()` method. | ||
- `usage` String or Array | ||
Unless otherwise noted, all methods return the object itself. | ||
The `Usage: ...` bits that go at the top of the help output | ||
## USAGE | ||
- `description` String | ||
```js | ||
import { jack } from 'jackspeak' | ||
// this works too: | ||
// const { jack } = require('jackspeak') | ||
A heading for the section. Something like `File Options` to | ||
preface all of the options for working with files. | ||
const { positionals, values } = jack({ envPrefix: 'FOO' }) | ||
.flag({ | ||
asdf: { description: 'sets the asfd flag', short: 'a', default: true }, | ||
'no-asdf': { description: 'unsets the asdf flag', short: 'A' }, | ||
foo: { description: 'another boolean', short: 'f' }, | ||
}) | ||
.optList({ | ||
'ip-addrs': { | ||
description: 'addresses to ip things', | ||
delim: ',', // defaults to '\n' | ||
default: ['127.0.0.1'], | ||
}, | ||
}) | ||
.parse([ | ||
'some', | ||
'positional', | ||
'--ip-addrs', | ||
'192.168.0.1', | ||
'--ip-addrs', | ||
'1.1.1.1', | ||
'args', | ||
'--foo', // sets the foo flag | ||
'-A', // short for --no-asdf, sets asdf flag to false | ||
]) | ||
- `help` String | ||
console.log(process.env.FOO_ASDF) // '0' | ||
console.log(process.env.FOO_FOO) // '1' | ||
console.log(values) // { | ||
// 'ip-addrs': ['192.168.0.1', '1.1.1.1'], | ||
// foo: true, | ||
// asdf: false, | ||
// } | ||
console.log(process.env.FOO_IP_ADDRS) // '192.168.0.1,1.1.1.1' | ||
console.log(positionals) // ['some', 'positional', 'args'] | ||
``` | ||
A longer-form (multi-paragraph) section of text that explains the | ||
stuff in more details. | ||
## `jack(options: JackOptions = {})` | ||
- `argv` Array | ||
Options: | ||
A list of arguments to parse. If not provided, jackspeak will | ||
pull form `process.argv`. It knows how to skip over the node binary | ||
and main script filename. | ||
- `allowPositionals` Defaults to true. Set to `false` to not | ||
allow any positional arguments. | ||
If a section is just an array, then it'll be treated as the argv. | ||
- `envPrefix` Set to a string to write configs to and read | ||
configs from the environment. For example, if set to `MY_APP` | ||
then the `foo-bar` config will default based on the value of | ||
`env.MY_APP_FOO_BAR` and will write back to that when parsed. | ||
- `env` Object | ||
Boolean values are written as `'1'` and `'0'`, and will be | ||
treated as `true` if they're `'1'` or false otherwise. | ||
A set of key-value pairs to pull environment variables from. If | ||
not specified, jackspeak will pull from `process.env`. | ||
Number values are written with their `toString()` | ||
representation. | ||
Note that environs are parsed and loaded right away when they are | ||
defined, so you must put `env` on a jackspeak object before | ||
definint any environent | ||
Strings are just strings. | ||
- One or more argument definition objects. These can be formed using | ||
the functions exported by `require('jackspeak')`. The key is the | ||
full canonical name of the argument as it appears in the parsed | ||
result set. | ||
Any value with `multiple: true` will be represented in the | ||
environment split by a delimiter, which defaults to `\n`. | ||
Note that the `--help` flag with the `-h` shorthand will be added | ||
by default, and that `--` will always stop parsing and treat the | ||
rest of the argv as positional arguments. However, `help` and | ||
`--` _may_ be added to a jack section to customize the usage text. | ||
- `env` The place to read/write environment variables. Defaults | ||
to `process.env`. | ||
All types can have the following options: | ||
- `usage` A short usage string to print at the top of the help | ||
banner. | ||
- `description` - Help text for this option. | ||
- `stopAtPositional` Boolean, default false. Stop parsing opts | ||
and flags at the first positional argument. This is useful if | ||
you want to pass certain options to subcommands, like some | ||
programs do, so you can stop parsing and pass the positionals | ||
to the subcommand to parse. | ||
- `hidden` - Do not show this value in the help output. | ||
### `Jack.heading(text: string)` | ||
- `implies` - JavaScript object of values to set in the result | ||
objet when this flag or option is encountered in the arguments. | ||
This can be used to have one flag enable another by default, for | ||
example. | ||
Define a short string heading, used in the `usage()` output. | ||
The types are: | ||
### `Jack.description(text: string)` | ||
- `flag(options)` - A boolean value which can be set or unset, but | ||
not given a value. | ||
Define a long string description, used in the `usage()` output. | ||
Flags can have the following options: | ||
## Option Definitions | ||
- `default` - Either `true` or `false`. If unspecified, flags | ||
default to `false`. | ||
Configs are defined by calling the appropriate field definition | ||
method with an object where the keys are the long option name, | ||
and the value defines the config. | ||
- `envDefault` - The name of an environment variable which provides | ||
the default value for this flag. The environment variable will | ||
be parsed as an `env(flag(...))` value, with `'1'` for true and | ||
`'0'` for false. | ||
Options: | ||
- `short` - A "short" form of the value which is indicated | ||
with a single dash. If `short` is a single character, then | ||
it can be combined gnu-style with other short flags. | ||
- `type` Only needed for the `addFields` method, as the others | ||
set it implicitly. Can be `'string'`, `'boolean'`, or | ||
`'number'`. | ||
- `multiple` Only needed for the `addFields` method, as the | ||
others set it implicitly. Set to `true` to define an array | ||
type. This means that it can be set on the CLI multiple times, | ||
set as an array in the `values` | ||
and it is represented in the environment as a delimited string. | ||
- `short` A one-character shorthand for the option. | ||
- `description` Some words to describe what this option is and | ||
why you'd set it. | ||
- `hint` (Only relevant for non-boolean types) The thing to show | ||
in the usage output, like `--option=<hint>` | ||
- `validate` A function that returns false (or throws) if an | ||
option value is invalid. | ||
- `default` A default value for the field. Note that this may be | ||
overridden by an environment variable, if present. | ||
- `negate` - An object defining how the `--no-<whatever>` form | ||
of the flag works. It can have any options that would be | ||
passed to a flag, other than `negate`. | ||
### `Jack.flag({ [option: string]: definition, ... })` | ||
For example, it can specify the help text for the negated | ||
form, or provide a different shorthand character. So, for | ||
example, `--color` could have `-c` as a shorthand, and | ||
`--no-color` could be shorthanded to `-C`. | ||
Define one or more boolean fields. | ||
- `alias` - Either a string or array of what this flag expands | ||
to. This means that the flag key won't have a value, but | ||
will instead be expanded to its alias. To expand an alias | ||
to multiple arguments, use an array. For example, in the | ||
`rsync` program, `-m` expands to `-r -N -l inf | ||
--no-remove-listing` | ||
Boolean options may be set to `false` by using a | ||
`--no-${optionName}` argument, which will be implicitly created | ||
if it's not defined to be something else. | ||
- `opt(options)` - An argument which takes a value. | ||
If a boolean option named `no-${optionName}` with the same | ||
`multiple` setting is in the configuration, then that will be | ||
treated as a negating flag. | ||
Opts can have the following options: | ||
### `Jack.flagList({ [option: string]: definition, ... })` | ||
- `default` - A default value. If unspecified, opts default | ||
to `undefined`. | ||
Define one or more boolean array fields. | ||
- `envDefault` - The name of an environment variable which provides | ||
the default value for this opt. | ||
### `Jack.num({ [option: string]: definition, ... })` | ||
- `valid` - An array of valid values. If the user provides a | ||
value outside this set, it will throw an error. | ||
Define one or more number fields. These will be set in the | ||
environment as a stringified number, and included in the `values` | ||
object as a number. | ||
- `alias` - A string or array of options that this option | ||
expands to when used. This works the same as flag aliases, | ||
with the exception that you may include the string | ||
`${value}` in the alias string(s) to substitute in the value | ||
provided to this opt. | ||
### `Jack.numList({ [option: string]: definition, ... })` | ||
For example, `--big=<n>` could be an alias for | ||
`--font-size=<n> --bold` by doing: | ||
Define one or more number list fields. These will be set in the | ||
environment as a delimited set of stringified numbers, and | ||
included in the `values` as a number array. | ||
```js | ||
jack({ | ||
big: opt({ | ||
alias: ['--font-size=${value}', '--bold'] | ||
}) | ||
}) | ||
``` | ||
- `hint` - A string to use in the help output as the value | ||
provided to the opt. For example, if you wanted to print | ||
`--output=<file>`, then you'd set `hint: 'file'` here. | ||
Defaults to the opt name. | ||
### `Jack.opt({ [option: string]: definition, ... })` | ||
- `short` - A "short" form of the opt which is indicated | ||
with a single dash. If `short` is a single character, then | ||
it can be combined gnu-style with short flags, and take a | ||
value without an `=` character. | ||
Define one or more string option fields. | ||
For example, in [tap](https://www.node-tap.org), `-bRspec` | ||
is equivalent to `--bail --reporter=spec`. | ||
### `Jack.optList({ [option: string]: definition, ... })` | ||
- `num(options)` - An `opt` that is a number. This will be | ||
provided in the result as an actual number (rather than a | ||
string) and will raise an error if given a non-numeric value. | ||
Define one or more string list fields. | ||
This is numericized by using the `+` operator, so any | ||
JavaScript number represenation will do. | ||
### `Jack.addFields({ [option: string]: definition, ... })` | ||
All of the `opt()` options are supported, plus these: | ||
Define one or more fields of any type. Note that `type` and | ||
`multiple` must be set explicitly on each definition when using | ||
this method. | ||
- `min` - A number that this value cannot be smaller than. | ||
- `max` - A number that this value cannot be larger than. | ||
## Actions | ||
- `list(options)` - An option which can take multiple values by | ||
being specified multiple times, and is represented in the result | ||
object as an array of values. If the list is not present in the | ||
arguments, then it will be an empty array. | ||
Use these methods on a Jack object that's already had its config | ||
fields defined. | ||
- `count(options)` - A flag which can be set multiple times to | ||
increase a value. Unsetting decrements the value, setting | ||
increments it. This can be useful for things like `-v` to set a | ||
verbosity level, or `-d` to set a debug level. | ||
### `Jack.parse(args: string[] = process.argv): { positionals: string[], values: OptionsResults }` | ||
Counts always default to 0. | ||
Parse the arguments list, write to the environment if `envPrefix` | ||
is set, and returned the parsed values and remaining positional | ||
arguments. | ||
Note that a `count` is actually a flag that can be set | ||
multiple times. Thus, it is a composition of the `list` and | ||
`flag` types. | ||
### `Jack.validate(o: any): asserts o is OptionsResults` | ||
- `env(options)` - An environment variable that the program is | ||
interested in. | ||
Throws an error if the object provided is not a valid result set, | ||
for the configurations defined thusfar. | ||
All environment variables will be present in the result | ||
object. `env()` can be composed with other types to change | ||
how the environment variable is handled. | ||
### `Jack.usage()` | ||
- Compose with `flag()` to define an environment variable that | ||
is set to `'1'` to mean `true`, or `'0'` or `''` to mean | ||
`false`. Presented in the result object as a boolean value. | ||
For example: | ||
Returns the compiled `usage` string, with all option descriptions | ||
and heading/description text, wrapped to the appropriate width | ||
for the terminal. | ||
```js | ||
jack({ | ||
FOO: env(flag({ | ||
description: 'Set to "1" to enable the foo flag' | ||
})) | ||
}) | ||
``` | ||
- Compose with `list()` to define an environment variable that | ||
is set to multiple values separated by a delimiter. For | ||
example: | ||
```js | ||
jack({ | ||
NODE_DEBUG: env(list({ | ||
delimiter: ',', | ||
description: 'Define which bits to debug' | ||
})) | ||
}) | ||
``` | ||
This can be further composed with `num` to pass in a list | ||
of numbers separated by a delimiter. | ||
When composed with `count` (which is the composition of | ||
`list` and `flag`), you would pass in a delimited list of | ||
`1` and `0` characters, and it'd count up the `1` values. | ||
I don't know why you'd ever do this, but it works. | ||
- Compose with `num()` to parse the environ as a numeric | ||
value, and raise an error if it is non-numeric. | ||
### Type Composition | ||
Compose types by applying more than one function to the arg | ||
definition options. For example, for a numeric environment | ||
variable, you can do: | ||
```js | ||
jack({ | ||
HOW_MANY_FOOS: env(num({ | ||
description: 'set to define the number of foos' | ||
max: 10, | ||
min: 2, | ||
default: 5, | ||
})) | ||
}) | ||
``` | ||
The order of composition does not matter in normal cases, but note | ||
that some compositions will contradict one another. For example, | ||
composing `flag` (an argument that does not take a value) with `opt` | ||
(an argument that _does_ take a value) will result in the outermost | ||
function taking precedence. | ||
## Some Example Code | ||
@@ -268,19 +212,6 @@ | ||
```js | ||
const { jack, flag, opt, list, count, num } = require('jackspeak') | ||
import { jack } from 'jackspeak' | ||
jack({ | ||
const j = jack({ | ||
// Optional | ||
// the function to call with the options argument when it's all done | ||
// if not provided, then jack() will return the parsed options | ||
// if any unknown options are passed in, then it'll abort with | ||
// the usage output and an error message | ||
main: myFunction, | ||
// Optional | ||
// defaults to process.argv, and slices off the first item if | ||
// it's process.execPath and the second item if it's | ||
// require.main.filename | ||
argv: process.argv, | ||
// Optional | ||
// This will be auto-generated from the descriptions if not supplied | ||
@@ -290,8 +221,5 @@ // top level usage line, printed by -h | ||
usage: 'foo [options] <files>', | ||
// Optional | ||
// longer-form help text | ||
// will be reformatted and wrapped to terminal column width, | ||
// so go ahead and format it however you like here. | ||
help: ` | ||
}) | ||
.heading('The best Foo that ever Fooed') | ||
.description(` | ||
Executes all the files and interprets their output as | ||
@@ -301,3 +229,3 @@ TAP formatted test result data. | ||
To parse TAP data from stdin, specify "-" as a filename. | ||
` | ||
`) | ||
@@ -307,82 +235,50 @@ // flags don't take a value, they're boolean on or off, and can be | ||
// so this adds support for -b to mean --bail, or -B to mean --no-bail | ||
flag: flag({ | ||
// specify a short value if you like. this must be a single char | ||
short: 'f', | ||
// description is optional as well. | ||
description: `Make the flags wave`, | ||
// you can can always negate a flag with `--no-flag` | ||
// specifying a negate option will let you define a short | ||
// single-char option for negation. | ||
negate: { | ||
.flag({ | ||
flag: { | ||
// specify a short value if you like. this must be a single char | ||
short: 'f', | ||
// description is optional as well. | ||
description: `Make the flags wave`, | ||
// default value for flags is 'false', unless you change it | ||
default: true | ||
}, | ||
'no-flag': { | ||
// you can can always negate a flag with `--no-flag` | ||
// specifying a negate option will let you define a short | ||
// single-char option for negation. | ||
short: 'F', | ||
description: `Do not wave the flags` | ||
}, | ||
// default value for flags is 'false', unless you change it | ||
default: true | ||
}), | ||
}) | ||
// Options that take a value are specified with `opt()` | ||
reporter: opt({ | ||
short: 'R', | ||
description: 'the style of report to display', | ||
.opt({ | ||
reporter: { | ||
short: 'R', | ||
description: 'the style of report to display', | ||
}, | ||
}) | ||
// if you want a number, say so, and jackspeak will enforce it | ||
jobs: num({ | ||
short: 'j', | ||
description: 'how many jobs to run in parallel', | ||
default: 1 | ||
}), | ||
.num({ | ||
jobs: { | ||
short: 'j', | ||
description: 'how many jobs to run in parallel', | ||
default: 1 | ||
}, | ||
}) | ||
// Aliases can be a flag or option that expands to | ||
// some other value when used. | ||
'jobs-auto': flag({ | ||
short: 'J', | ||
alias: '--jobs=' + require('os').cpus().length | ||
}), | ||
// you can also set defaults with an environ of course | ||
timeout: num({ | ||
short: 't', | ||
default: +process.env.TAP_TIMEOUT || 30, | ||
}), | ||
// this makes --no-timeout equivalue to setting timeout to zero | ||
'no-timeout': flag({ | ||
short: 'T', | ||
alias: '--timeout=0' | ||
}), | ||
// A list is an option that can be specified multiple times, | ||
// to expand into an array of all the settings. Normal opts | ||
// will just give you the last value specified. | ||
'node-arg': list(), | ||
.optList({ | ||
'node-arg': {}, | ||
}) | ||
// A counter is a flag that increments or decrements its value | ||
// each time it's specified. | ||
// In this case, `-ddd` would return { debug: 3 } in the result | ||
debug: count({ | ||
short: 'd' | ||
// a flagList is an array of booleans, so `-ddd` is [true, true, true] | ||
// count the `true` values to treat it as a counter. | ||
.flagList({ | ||
debug: { short: 'd' } | ||
}) | ||
// an alias can expand to multiple things, not just one | ||
foo: flag({ | ||
alias: ['--statements=100', '--lines=100', '--branches=100'], | ||
}), | ||
// An option alias can take a value and use it in the expansion. | ||
// use `${value}` in the alias to sub in what the user provides | ||
covlevel: opt({ | ||
alias: [ | ||
'--statements=${value}', | ||
'--lines=${value}', | ||
'--branches=${value}' | ||
] | ||
}), | ||
// aliases can recurse, as well | ||
100: flag({ | ||
alias: '--covlevel=100' | ||
}), | ||
// opts take a value, and is set to the string in the results | ||
@@ -392,9 +288,23 @@ // you can combine multiple short-form flags together, but | ||
// -bofilename would be like --bail --output-file=filename | ||
'output-file': opt({ | ||
short: 'o', | ||
// optional: make it -o<file> in the help output insead of -o<value> | ||
hint: 'file', | ||
description: `Send the raw output to the specified file.` | ||
}), | ||
}) | ||
.opt({ | ||
'output-file': { | ||
short: 'o', | ||
// optional: make it -o<file> in the help output insead of -o<value> | ||
hint: 'file', | ||
description: `Send the raw output to the specified file.` | ||
} | ||
}) | ||
// now we can parse argv like this: | ||
const { values, positionals } = j.parse(process.argv) | ||
// or decide to show the usage banner | ||
console.log(j.usage()) | ||
// or validate an object config we got from somewhere else | ||
try { | ||
j.validate(someConfig) | ||
} catch (er) { | ||
console.error('someConfig is not valid!', er) | ||
} | ||
``` | ||
@@ -405,4 +315,4 @@ | ||
The inspiration for this module is [yargs](http://npm.im/yargs), which | ||
is pirate talk themed. Yargs has all the features, and is infinitely | ||
flexible. "Jackspeak" is the slang of the royal navy. This module | ||
does not have all the features. It is declarative and rigid by design. | ||
is pirate talk themed. Yargs has all the features, and is infinitely | ||
flexible. "Jackspeak" is the slang of the royal navy. This module | ||
does not have all the features. It is declarative and rigid by design. |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
185112
21
1627
2
10
312
3
1