Replace OTHER with a LicenseRef
ClearlyDefined uses the string `OTHER` for the declared license when a human has reviewed `NOASSERTION` text and found it to be a valid license, but one without an SPDX identifier. `OTHER`, unlike `NOASSERTION`, is not valid. With this change, when `OTHER` appears in a license string, we'll replace it with `LicenseRef-clearlydefined-OTHER`, which _is_ valid and will allow the expressions to parse.
This commit is contained in:
@@ -55,6 +55,16 @@ describe('satisfiesAny', () => {
|
||||
candidate: 'MIT OR ISC',
|
||||
licenses: ['MiT'],
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
candidate: 'MIT AND OTHER',
|
||||
licenses: ['MIT'],
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
candidate: 'MIT OR OTHER',
|
||||
licenses: ['MIT', 'LicenseRef-clearlydefined-OTHER'],
|
||||
expected: true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -73,6 +83,7 @@ describe('satisfiesAll', () => {
|
||||
licenses: ['MIT'],
|
||||
expected: true
|
||||
},
|
||||
// TODO(dangoor): this does not seem correct to me: the only license is Apache-2.0 and it's on the list
|
||||
{
|
||||
candidate: 'Apache-2.0',
|
||||
licenses: ['MIT', 'ISC', 'Apache-2.0'],
|
||||
@@ -130,6 +141,16 @@ describe('satisfiesAll', () => {
|
||||
candidate: 'MIT OR ISC',
|
||||
licenses: ['MiT'],
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
candidate: 'MIT AND OTHER',
|
||||
licenses: ['MIT'],
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
candidate: 'MIT AND OTHER',
|
||||
licenses: ['MIT', 'LicenseRef-clearlydefined-OTHER'],
|
||||
expected: true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -210,6 +231,11 @@ describe('satisfies', () => {
|
||||
candidate: '',
|
||||
allowList: ['BSD-3-Clause', 'ISC', 'MIT'],
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
candidate: 'MIT OR OTHER',
|
||||
constraint: 'MIT OR LicenseRef-clearlydefined-OTHER',
|
||||
expected: true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -246,6 +272,10 @@ describe('isValid', () => {
|
||||
{
|
||||
candidate: '',
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
candidate: 'MIT AND OTHER',
|
||||
expected: true
|
||||
}
|
||||
]
|
||||
for (const unit of units) {
|
||||
@@ -255,3 +285,38 @@ describe('isValid', () => {
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
describe('removeInvalidSPDX', () => {
|
||||
const units = [
|
||||
{
|
||||
candidate: 'MIT',
|
||||
expected: 'MIT'
|
||||
},
|
||||
{
|
||||
candidate: 'OTHER',
|
||||
expected: 'LicenseRef-clearlydefined-OTHER'
|
||||
},
|
||||
{
|
||||
candidate: 'LicenseRef-clearlydefined-OTHER',
|
||||
expected: 'LicenseRef-clearlydefined-OTHER'
|
||||
},
|
||||
{
|
||||
candidate: 'OTHER AND MIT',
|
||||
expected: 'LicenseRef-clearlydefined-OTHER AND MIT'
|
||||
},
|
||||
{
|
||||
candidate: 'MIT AND OTHER',
|
||||
expected: 'MIT AND LicenseRef-clearlydefined-OTHER'
|
||||
},
|
||||
{
|
||||
candidate: 'MIT AND SomethingElse-OTHER',
|
||||
expected: 'MIT AND SomethingElse-OTHER'
|
||||
}
|
||||
]
|
||||
for (const unit of units) {
|
||||
const got: string = spdx.removeInvalidSPDX(unit.candidate)
|
||||
test(`should return ${unit.expected} for ("${unit.candidate}")`, () => {
|
||||
expect(got).toBe(unit.expected)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
+12
@@ -12,6 +12,7 @@ import parse from 'spdx-expression-parse'
|
||||
// accepts a pair of well-formed SPDX expressions. the
|
||||
// candidate is tested against the constraint
|
||||
export function satisfies(candidateExpr: string, allowList: string[]): boolean {
|
||||
candidateExpr = removeInvalidSPDX(candidateExpr)
|
||||
try {
|
||||
return spdxSatisfies(candidateExpr, allowList)
|
||||
} catch (_) {
|
||||
@@ -24,6 +25,7 @@ export function satisfiesAny(
|
||||
candidateExpr: string,
|
||||
licenses: string[]
|
||||
): boolean {
|
||||
candidateExpr = removeInvalidSPDX(candidateExpr)
|
||||
try {
|
||||
return spdxlib.satisfiesAny(candidateExpr, licenses)
|
||||
} catch (_) {
|
||||
@@ -36,6 +38,7 @@ export function satisfiesAll(
|
||||
candidateExpr: string,
|
||||
licenses: string[]
|
||||
): boolean {
|
||||
candidateExpr = removeInvalidSPDX(candidateExpr)
|
||||
try {
|
||||
return spdxlib.satisfiesAll(candidateExpr, licenses)
|
||||
} catch (_) {
|
||||
@@ -45,6 +48,7 @@ export function satisfiesAll(
|
||||
|
||||
// accepts any SPDX expression
|
||||
export function isValid(spdxExpr: string): boolean {
|
||||
spdxExpr = removeInvalidSPDX(spdxExpr)
|
||||
try {
|
||||
parse(spdxExpr)
|
||||
return true
|
||||
@@ -52,3 +56,11 @@ export function isValid(spdxExpr: string): boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const replaceOtherRegex = /(?<![\w-])OTHER(?![\w-])/
|
||||
|
||||
// adjusts license expressions to not include the invalid `OTHER`
|
||||
// which ClearlyDefined adds to license strings
|
||||
export function removeInvalidSPDX(spdxExpr: string): string {
|
||||
return spdxExpr.replace(replaceOtherRegex, 'LicenseRef-clearlydefined-OTHER')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user