Skip to content

Commit

Permalink
Merge pull request #858 from johnbatty/rust-license-tests
Browse files Browse the repository at this point in the history
Fix for Rust multi-license declaration, plus new Rust license tests
  • Loading branch information
nellshamrell authored Jun 24, 2021
2 parents 4f8a8d2 + 7edeb6a commit dee0a24
Show file tree
Hide file tree
Showing 11 changed files with 24,040 additions and 5 deletions.
2 changes: 2 additions & 0 deletions providers/summary/fossology.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ class FOSSologySummarizer {

_declareLicense(coordinates, result) {
if (!result.files) return
// For Rust crates, leave the license declaration to the ClearlyDefined summarizer which parses Cargo.toml
if (get(coordinates, 'type') === 'crate') return
// if we know this is a license file by the name of it and it has a license detected in it
// then let's declare the license for the component
const licenses = uniq(
Expand Down
2 changes: 2 additions & 0 deletions providers/summary/licensee.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class LicenseeSummarizer {

_addLicenseFromFiles(result, coordinates) {
if (!result.files) return
// For Rust crates, leave the license declaration to the ClearlyDefined summarizer which parses Cargo.toml
if (get(coordinates, 'type') === 'crate') return
const licenses = result.files
.map(file => (isDeclaredLicense(file.license) && isLicenseFile(file.path, coordinates) ? file.license : null))
.filter(x => x)
Expand Down
9 changes: 6 additions & 3 deletions providers/summary/scancode.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ class ScanCodeSummarizer {
if (!scancodeVersion) throw new Error('Not valid ScanCode data')
const result = {}
this.addDescribedInfo(result, harvested)
const declaredLicense =
this._readDeclaredLicense(harvested) || this._getDeclaredLicense(scancodeVersion, harvested, coordinates)
setIfValue(result, 'licensed.declared', declaredLicense)
// For Rust crates, leave the license declaration to the ClearlyDefined summarizer which parses Cargo.toml
if (get(coordinates, 'type') !== 'crate') {
const declaredLicense =
this._readDeclaredLicense(harvested) || this._getDeclaredLicense(scancodeVersion, harvested, coordinates)
setIfValue(result, 'licensed.declared', declaredLicense)
}
result.files = this._summarizeFileInfo(harvested.content.files, coordinates)
return result
}
Expand Down
66 changes: 66 additions & 0 deletions test/business/definitionServiceTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const sinon = require('sinon')
const validator = require('../../schemas/validator')
const DefinitionService = require('../../business/definitionService')
const AggregatorService = require('../../business/aggregator')
const SummaryService = require('../../business/summarizer')
const EntityCoordinates = require('../../lib/entityCoordinates')
const { setIfValue } = require('../../lib/utils')
const Curation = require('../../lib/curation')
Expand Down Expand Up @@ -319,6 +320,64 @@ describe('Aggregation service', () => {
expect(aggregated.files[1].path).to.eq('bar.txt')
expect(aggregated.files[1].license).to.eq('GPL-2.0')
})

it('handles Rust crates with license choices', async () => {
const testcases = [
{
name: 'slog',
version: '2.7.0',
tools: [['clearlydefined', 'licensee', 'scancode']],
// Ideally this would be declared without any parentheses, but currently
// the SPDX normalization adds them.
expected: 'MPL-2.0 OR (MIT OR Apache-2.0)',
},
{
name: 'quote',
version: '0.6.4',
tools: [['clearlydefined', 'fossology', 'licensee', 'scancode']],
expected: 'MIT OR Apache-2.0',
},
{
name: 'quote',
version: '1.0.9',
tools: [['clearlydefined', 'licensee', 'scancode']],
expected: 'MIT OR Apache-2.0',
},
{
name: 'rand',
version: '0.8.2',
tools: [['clearlydefined', 'licensee', 'scancode']],
expected: 'MIT OR Apache-2.0',
},
{
name: 'regex',
version: '1.5.3',
tools: [['clearlydefined', 'licensee', 'scancode']],
expected: 'MIT OR Apache-2.0',
},
{
name: 'serde',
version: '1.0.123',
tools: [['clearlydefined', 'licensee', 'scancode']],
expected: 'MIT OR Apache-2.0',
},
]

const summary_options = {}
const summaryService = SummaryService(summary_options)

for (let i = 0; i < testcases.length; i++) {
let testcase = testcases[i]
const coordSpec = `crate/cratesio/-/${testcase.name}/${testcase.version}`
const coords = EntityCoordinates.fromString(coordSpec)
const raw = require(`./evidence/crate-${testcase.name}-${testcase.version}.json`)
const tools = testcase.tools
const summaries = summaryService.summarizeAll(coords, raw)
const { service } = setupAggregatorWithParams(coordSpec, tools)
const aggregated = service.process(summaries)
expect(aggregated.licensed.declared, `${testcase.name}-${testcase.version}`).to.eq(testcase.expected)
}
})
})

function validate(definition) {
Expand Down Expand Up @@ -368,3 +427,10 @@ function setupAggregator() {
const service = AggregatorService(config)
return { service, coordinates }
}

function setupAggregatorWithParams(coordSpec, tool_precedence) {
const coordinates = EntityCoordinates.fromString(coordSpec)
const config = { precedence: tool_precedence }
const service = AggregatorService(config)
return { service, coordinates }
}
Loading

0 comments on commit dee0a24

Please sign in to comment.