update licenses pkg and tests
This commit is contained in:
+29
-30
@@ -1,7 +1,6 @@
|
|||||||
import {expect, jest, test} from '@jest/globals'
|
import {expect, jest, test} from '@jest/globals'
|
||||||
import {Change, Changes} from '../src/schemas'
|
import {Change, Changes} from '../src/schemas'
|
||||||
|
import {getInvalidLicenseChanges} from '../src/licenses'
|
||||||
let getInvalidLicenseChanges: Function
|
|
||||||
|
|
||||||
const npmChange: Change = {
|
const npmChange: Change = {
|
||||||
manifest: 'package.json',
|
manifest: 'package.json',
|
||||||
@@ -30,7 +29,7 @@ const rubyChange: Change = {
|
|||||||
name: 'actionsomething',
|
name: 'actionsomething',
|
||||||
version: '3.2.0',
|
version: '3.2.0',
|
||||||
package_url: 'pkg:gem/[email protected]',
|
package_url: 'pkg:gem/[email protected]',
|
||||||
license: 'BSD',
|
license: 'BSD-3-Clause',
|
||||||
source_repository_url: 'github.com/some-repo',
|
source_repository_url: 'github.com/some-repo',
|
||||||
scope: 'runtime',
|
scope: 'runtime',
|
||||||
vulnerabilities: [
|
vulnerabilities: [
|
||||||
@@ -100,29 +99,32 @@ jest.mock('octokit', () => {
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
jest.resetModules()
|
jest.resetModules()
|
||||||
jest.doMock('spdx-satisfies', () => {
|
|
||||||
// mock spdx-satisfies return value
|
|
||||||
// true for BSD, false for all others
|
|
||||||
return jest.fn((license: string, _: string): boolean => license === 'BSD')
|
|
||||||
})
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
||||||
;({getInvalidLicenseChanges} = require('../src/licenses'))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('it adds license outside the allow list to forbidden changes', async () => {
|
test('it adds license outside the allow list to forbidden changes', async () => {
|
||||||
const changes: Changes = [npmChange, rubyChange]
|
const changes: Changes = [
|
||||||
|
npmChange, // MIT license
|
||||||
|
rubyChange // BSD license
|
||||||
|
]
|
||||||
|
|
||||||
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
||||||
allow: ['BSD']
|
allow: ['BSD-3-Clause']
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(forbidden[0]).toBe(npmChange)
|
expect(forbidden[0]).toBe(npmChange)
|
||||||
expect(forbidden.length).toEqual(1)
|
expect(forbidden.length).toEqual(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('it adds license inside the deny list to forbidden changes', async () => {
|
test('it adds license inside the deny list to forbidden changes', async () => {
|
||||||
const changes: Changes = [npmChange, rubyChange]
|
const changes: Changes = [
|
||||||
|
npmChange, // MIT license
|
||||||
|
rubyChange // BSD license
|
||||||
|
]
|
||||||
|
|
||||||
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
||||||
deny: ['BSD']
|
deny: ['BSD-3-Clause']
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(forbidden[0]).toBe(rubyChange)
|
expect(forbidden[0]).toBe(rubyChange)
|
||||||
expect(forbidden.length).toEqual(1)
|
expect(forbidden.length).toEqual(1)
|
||||||
})
|
})
|
||||||
@@ -133,7 +135,7 @@ test('it does not add license outside the allow list to forbidden changes if it
|
|||||||
{...rubyChange, change_type: 'removed'}
|
{...rubyChange, change_type: 'removed'}
|
||||||
]
|
]
|
||||||
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
||||||
allow: ['BSD']
|
allow: ['BSD-3-Clause']
|
||||||
})
|
})
|
||||||
expect(forbidden).toStrictEqual([])
|
expect(forbidden).toStrictEqual([])
|
||||||
})
|
})
|
||||||
@@ -144,7 +146,7 @@ test('it does not add license inside the deny list to forbidden changes if it is
|
|||||||
{...rubyChange, change_type: 'removed'}
|
{...rubyChange, change_type: 'removed'}
|
||||||
]
|
]
|
||||||
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
||||||
deny: ['BSD']
|
deny: ['BSD-3-Clause']
|
||||||
})
|
})
|
||||||
expect(forbidden).toStrictEqual([])
|
expect(forbidden).toStrictEqual([])
|
||||||
})
|
})
|
||||||
@@ -156,23 +158,18 @@ test('it adds license outside the allow list to forbidden changes if it is in bo
|
|||||||
{...rubyChange, change_type: 'removed'}
|
{...rubyChange, change_type: 'removed'}
|
||||||
]
|
]
|
||||||
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
const {forbidden} = await getInvalidLicenseChanges(changes, {
|
||||||
allow: ['BSD']
|
allow: ['BSD-3-Clause']
|
||||||
})
|
})
|
||||||
expect(forbidden).toStrictEqual([npmChange])
|
expect(forbidden).toStrictEqual([npmChange])
|
||||||
})
|
})
|
||||||
|
|
||||||
test('it adds all licenses to unresolved if it is unable to determine the validity', async () => {
|
test('it adds all licenses to unresolved if it is unable to determine the validity', async () => {
|
||||||
jest.resetModules() // reset module set in before
|
const changes: Changes = [
|
||||||
jest.doMock('spdx-satisfies', () => {
|
{...npmChange, license: 'Foo'},
|
||||||
return jest.fn((_first: string, _second: string) => {
|
{...rubyChange, license: 'Bar'}
|
||||||
throw new Error('Some Error')
|
]
|
||||||
})
|
|
||||||
})
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
||||||
;({getInvalidLicenseChanges} = require('../src/licenses'))
|
|
||||||
const changes: Changes = [npmChange, rubyChange]
|
|
||||||
const invalidLicenses = await getInvalidLicenseChanges(changes, {
|
const invalidLicenses = await getInvalidLicenseChanges(changes, {
|
||||||
allow: ['BSD']
|
allow: ['Apache-2.0']
|
||||||
})
|
})
|
||||||
expect(invalidLicenses.forbidden.length).toEqual(0)
|
expect(invalidLicenses.forbidden.length).toEqual(0)
|
||||||
expect(invalidLicenses.unlicensed.length).toEqual(0)
|
expect(invalidLicenses.unlicensed.length).toEqual(0)
|
||||||
@@ -182,7 +179,7 @@ test('it adds all licenses to unresolved if it is unable to determine the validi
|
|||||||
test('it does not filter out changes that are on the exclusions list', async () => {
|
test('it does not filter out changes that are on the exclusions list', async () => {
|
||||||
const changes: Changes = [pipChange, npmChange, rubyChange]
|
const changes: Changes = [pipChange, npmChange, rubyChange]
|
||||||
const licensesConfig = {
|
const licensesConfig = {
|
||||||
allow: ['BSD'],
|
allow: ['BSD-3-Clause'],
|
||||||
licenseExclusions: ['pkg:pypi/[email protected]', 'pkg:npm/[email protected]']
|
licenseExclusions: ['pkg:pypi/[email protected]', 'pkg:npm/[email protected]']
|
||||||
}
|
}
|
||||||
const invalidLicenses = await getInvalidLicenseChanges(
|
const invalidLicenses = await getInvalidLicenseChanges(
|
||||||
@@ -198,7 +195,7 @@ test('it does not fail when the packages dont have a valid PURL', async () => {
|
|||||||
|
|
||||||
const changes: Changes = [emptyPurlChange, npmChange, rubyChange]
|
const changes: Changes = [emptyPurlChange, npmChange, rubyChange]
|
||||||
const licensesConfig = {
|
const licensesConfig = {
|
||||||
allow: ['BSD'],
|
allow: ['BSD-3-Clause'],
|
||||||
licenseExclusions: ['pkg:pypi/[email protected]', 'pkg:npm/[email protected]']
|
licenseExclusions: ['pkg:pypi/[email protected]', 'pkg:npm/[email protected]']
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,16 +209,18 @@ test('it does not fail when the packages dont have a valid PURL', async () => {
|
|||||||
test('it does filters out changes if they are not on the exclusions list', async () => {
|
test('it does filters out changes if they are not on the exclusions list', async () => {
|
||||||
const changes: Changes = [pipChange, npmChange, rubyChange]
|
const changes: Changes = [pipChange, npmChange, rubyChange]
|
||||||
const licensesConfig = {
|
const licensesConfig = {
|
||||||
allow: ['BSD'],
|
allow: ['BSD-3-Clause'],
|
||||||
licenseExclusions: [
|
licenseExclusions: [
|
||||||
'pkg:pypi/[email protected]',
|
'pkg:pypi/[email protected]',
|
||||||
'pkg:npm/[email protected]'
|
'pkg:npm/[email protected]'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const invalidLicenses = await getInvalidLicenseChanges(
|
const invalidLicenses = await getInvalidLicenseChanges(
|
||||||
changes,
|
changes,
|
||||||
licensesConfig
|
licensesConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(invalidLicenses.forbidden.length).toEqual(2)
|
expect(invalidLicenses.forbidden.length).toEqual(2)
|
||||||
expect(invalidLicenses.forbidden[0]).toBe(pipChange)
|
expect(invalidLicenses.forbidden[0]).toBe(pipChange)
|
||||||
expect(invalidLicenses.forbidden[1]).toBe(npmChange)
|
expect(invalidLicenses.forbidden[1]).toBe(npmChange)
|
||||||
|
|||||||
+7
-12
@@ -1,8 +1,7 @@
|
|||||||
import spdxSatisfies from 'spdx-satisfies'
|
|
||||||
import {Change, Changes} from './schemas'
|
import {Change, Changes} from './schemas'
|
||||||
import {octokitClient} from './utils'
|
import {octokitClient} from './utils'
|
||||||
import {parsePURL} from './purl'
|
import {parsePURL} from './purl'
|
||||||
import {isValid} from './spdx'
|
import * as spdx from './spdx'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loops through a list of changes, filtering and returning the
|
* Loops through a list of changes, filtering and returning the
|
||||||
@@ -48,7 +47,7 @@ export async function getInvalidLicenseChanges(
|
|||||||
|
|
||||||
const changeAsPackageURL = parsePURL(encodeURI(change.package_url))
|
const changeAsPackageURL = parsePURL(encodeURI(change.package_url))
|
||||||
|
|
||||||
// We want to find if the licenseExclussion list contains the PackageURL of the Change
|
// We want to find if the licenseExclusion list contains the PackageURL of the Change
|
||||||
// If it does, we want to filter it out and therefore return false
|
// If it does, we want to filter it out and therefore return false
|
||||||
// If it doesn't, we want to keep it and therefore return true
|
// If it doesn't, we want to keep it and therefore return true
|
||||||
if (
|
if (
|
||||||
@@ -88,15 +87,11 @@ export async function getInvalidLicenseChanges(
|
|||||||
} else if (validityCache.get(license) === undefined) {
|
} else if (validityCache.get(license) === undefined) {
|
||||||
try {
|
try {
|
||||||
if (allow !== undefined) {
|
if (allow !== undefined) {
|
||||||
const found = allow.find(spdxExpression =>
|
const found = spdx.satisfiesAny(license, allow)
|
||||||
spdxSatisfies(license, spdxExpression)
|
validityCache.set(license, found)
|
||||||
)
|
|
||||||
validityCache.set(license, found !== undefined)
|
|
||||||
} else if (deny !== undefined) {
|
} else if (deny !== undefined) {
|
||||||
const found = deny.find(spdxExpression =>
|
const found = spdx.satisfiesAny(license, deny)
|
||||||
spdxSatisfies(license, spdxExpression)
|
validityCache.set(license, !found)
|
||||||
)
|
|
||||||
validityCache.set(license, found === undefined)
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
invalidLicenseChanges.unresolved.push(change)
|
invalidLicenseChanges.unresolved.push(change)
|
||||||
@@ -166,7 +161,7 @@ const setGHLicenses = async (changes: Change[]): Promise<Change[]> => {
|
|||||||
// Currently Dependency Graph licenses are truncated to 255 characters
|
// Currently Dependency Graph licenses are truncated to 255 characters
|
||||||
// This possibly makes them invalid spdx ids
|
// This possibly makes them invalid spdx ids
|
||||||
const truncatedDGLicense = (license: string): boolean =>
|
const truncatedDGLicense = (license: string): boolean =>
|
||||||
license.length === 255 && !isValid(license)
|
license.length === 255 && !spdx.isValid(license)
|
||||||
|
|
||||||
async function groupChanges(
|
async function groupChanges(
|
||||||
changes: Changes
|
changes: Changes
|
||||||
|
|||||||
+14
@@ -8,6 +8,20 @@ export function satisfies(
|
|||||||
return spdx.satisfies(candidateExpr, constraintExpr)
|
return spdx.satisfies(candidateExpr, constraintExpr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function satisfiesAny(
|
||||||
|
candidateExpr: string,
|
||||||
|
licenses: string[]
|
||||||
|
): boolean {
|
||||||
|
return spdx.satisfiesAny(candidateExpr, licenses)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function satisfiesAll(
|
||||||
|
candidateExpr: string,
|
||||||
|
licenses: string[]
|
||||||
|
): boolean {
|
||||||
|
return spdx.satisfiesAll(candidateExpr, licenses)
|
||||||
|
}
|
||||||
|
|
||||||
// can be a single license or an SPDX expression
|
// can be a single license or an SPDX expression
|
||||||
export function isValid(spdxExpr: string): boolean {
|
export function isValid(spdxExpr: string): boolean {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Vendored
+12
@@ -3,4 +3,16 @@ declare module '@onebeyond/spdx-license-satisfies' {
|
|||||||
candidateExpr: string,
|
candidateExpr: string,
|
||||||
constraintExpr: string
|
constraintExpr: string
|
||||||
): boolean
|
): boolean
|
||||||
|
|
||||||
|
export function satisfiesAny(
|
||||||
|
candidateExpr: string,
|
||||||
|
licenses: string[]
|
||||||
|
): boolean
|
||||||
|
|
||||||
|
export function satisfiesAll(
|
||||||
|
candidateExpr: string,
|
||||||
|
licenses: string[]
|
||||||
|
): boolean
|
||||||
|
|
||||||
|
export function isValid(candidateExpr: string): boolean
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user