Skip to content

Commit 4b83b52

Browse files
committed
DT-1094 Converts table LicenseObligation to new data layer
1 parent 9f9b07d commit 4b83b52

File tree

11 files changed

+200
-110
lines changed

11 files changed

+200
-110
lines changed

Diff for: assets/ReportHTMLTemplate/index.html

+74-59
Large diffs are not rendered by default.

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "scanoss",
3-
"version": "0.9.3",
3+
"version": "0.10.0",
44
"description": "The SCANOSS JS package provides a simple, easy to consume module for interacting with SCANOSS APIs/Engine.",
55
"main": "build/main/index.js",
66
"typings": "build/main/index.d.ts",

Diff for: src/cli/commands/scan.ts

+8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { SummaryDataProvider } from '../../sdk/Report/DataLayer/DataProviders/Su
2828
import { DecompressionFilter } from '../../sdk/tree/Filters/DecompressionFilter';
2929
import { DecompressionManager } from '../../sdk/Decompress/DecompressionManager';
3030
import path from 'path';
31+
import { LicenseObligationDataProvider } from '../../sdk/Report/DataLayer/DataProviders/LicenseObligationDataProvider';
3132

3233
export async function scanHandler(
3334
rootPath: string,
@@ -184,6 +185,13 @@ export async function scanHandler(
184185
dataProviderManager.addDataProvider(
185186
new SummaryDataProvider(projectName, new Date(), scannersResults.scanner)
186187
);
188+
189+
dataProviderManager.addDataProvider(
190+
new LicenseObligationDataProvider(
191+
scannersResults.scanner,
192+
scannersResults.dependencies
193+
)
194+
);
187195
const report = new Report(dataProviderManager);
188196
scannerResultsString = await report.getHTML();
189197
}

Diff for: src/sdk/Report/DataLayer/DataLayerTypes.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@ export interface LicenseDataLayer {
8787
label: string;
8888
value: number; //Number of licenses found
8989
components: Array<LicenseComponent>;
90-
incompatibleWith: Array<string>;
91-
hasIncompatibles: Array<string>;
92-
copyleft: boolean;
9390
}
9491

9592
export interface LicenseComponent {
@@ -101,7 +98,17 @@ export interface LicenseComponent {
10198
}
10299
/************* License interface definition *************/
103100

101+
/************* License Obligation interface definition *************/
102+
export interface LicenseObligation {
103+
label: string; //spdxid
104+
incompatibleWith: Array<string>;
105+
hasIncompatibles: Array<string>;
106+
copyleft: boolean;
107+
}
108+
/************* License Obligation interface definition *************/
109+
104110
export interface SummaryDataLayer {
111+
reportTitle: string;
105112
projectName: string;
106113
timestamp: Date;
107114
matchedFiles: number;
@@ -112,6 +119,7 @@ export interface SummaryDataLayer {
112119
// Each layer is created to group by differents criteria.
113120
export interface IDataLayers {
114121
licenses: LicenseDataLayer[];
122+
licensesObligations: LicenseObligation[];
115123
component: ComponentDataLayer[];
116124
dependencies: DependencyDataLayer[];
117125
vulnerabilities: VulnerabilityDataLayer[];

Diff for: src/sdk/Report/DataLayer/DataProviderManager.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class DataProviderManager {
1818
vulnerabilities: null,
1919
summary: null,
2020
licenses: null,
21+
licensesObligations: null,
2122
};
2223

2324
for (const layer of this.dataLayersProviders)

Diff for: src/sdk/Report/DataLayer/DataProviders/LicenseDataProvider.ts

-41
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ export class LicenseDataProvider implements DataProvider {
4747
this.updateLicenseStorageFromDependencies();
4848

4949
this.licenseLayer = Object.values(this.licenseStorage);
50-
if (this.licenseLayer.length > 0) this.updateIncompatibilities();
5150

5251
this.licenseLayer.sort((itemA, itemB) => {
5352
if (itemA.value > itemB.value) return -1;
@@ -74,12 +73,6 @@ export class LicenseDataProvider implements DataProvider {
7473
const newLicense: LicenseDataLayer = <LicenseDataLayer>{};
7574
newLicense.value = 1;
7675
newLicense.label = license.name;
77-
newLicense.copyleft = license.copyleft === 'yes' ? true : false;
78-
newLicense.hasIncompatibles = [];
79-
newLicense.incompatibleWith =
80-
license.incompatible_with !== undefined
81-
? license.incompatible_with.split(',').map((il) => il.trim())
82-
: [];
8376
newLicense.components = [newLicenseComponent];
8477
this.licenseStorage[license.name] = newLicense;
8578
} else {
@@ -111,9 +104,6 @@ export class LicenseDataProvider implements DataProvider {
111104
const newLicense: LicenseDataLayer = <LicenseDataLayer>{};
112105
newLicense.value = 1;
113106
newLicense.label = license_name;
114-
newLicense.copyleft = false;
115-
newLicense.hasIncompatibles = [];
116-
newLicense.incompatibleWith = [];
117107
newLicense.components = [newLicenseComponent];
118108
this.licenseStorage[license_name] = newLicense;
119109
} else {
@@ -131,9 +121,6 @@ export class LicenseDataProvider implements DataProvider {
131121
const newLicense: LicenseDataLayer = <LicenseDataLayer>{};
132122
newLicense.value = 1;
133123
newLicense.label = 'unknown';
134-
newLicense.copyleft = false;
135-
newLicense.hasIncompatibles = [];
136-
newLicense.incompatibleWith = [];
137124
newLicense.components = [newLicenseComponent];
138125
this.licenseStorage['unknown'] = newLicense;
139126
} else {
@@ -148,21 +135,6 @@ export class LicenseDataProvider implements DataProvider {
148135
});
149136
}
150137

151-
private updateIncompatibilities() {
152-
for (let l = 0; l < this.licenseLayer.length; l += 1) {
153-
const license = this.licenseLayer[l];
154-
if (license.incompatibleWith !== undefined)
155-
for (let i = 0; i < license.incompatibleWith.length; i += 1) {
156-
if (
157-
this.licenseLayer.some(
158-
(lic) => lic.label === license.incompatibleWith[i]
159-
)
160-
)
161-
license.hasIncompatibles.push(license.incompatibleWith[i]);
162-
}
163-
}
164-
}
165-
166138
private insertComponentIntoLicense(
167139
license: LicenseDataLayer,
168140
newComponent: LicenseComponent
@@ -187,17 +159,4 @@ export class LicenseDataProvider implements DataProvider {
187159
}
188160
return license;
189161
}
190-
191-
private unknownLicensesToEnd() {
192-
// let unknownLicenses = null;
193-
// if(this.licenseMapper['unknown']){
194-
// unknownLicenses = this.licenseMapper['unknown'];
195-
// delete this.licenseMapper['unknown'];
196-
// }
197-
//
198-
// this.licenses = Object.values((this.licenseMapper));
199-
// if(unknownLicenses){
200-
// this.licenses.push(unknownLicenses);
201-
// }
202-
}
203162
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import {
2+
DataProvider,
3+
IDataLayers,
4+
LicenseComponent,
5+
LicenseDataLayer,
6+
LicenseObligation,
7+
} from '../DataLayerTypes';
8+
import {
9+
ScannerComponent,
10+
ScannerResults,
11+
} from '../../../scanner/ScannerTypes';
12+
import { IDependencyResponse } from '../../../Dependencies/DependencyTypes';
13+
14+
export class LicenseObligationDataProvider implements DataProvider {
15+
private scanResults: ScannerResults;
16+
17+
private dependencies: IDependencyResponse;
18+
private licenseLayer: LicenseObligation[];
19+
private componentList: ScannerComponent[];
20+
21+
private licenseSet: Record<string, LicenseObligation>;
22+
constructor(scanResults: ScannerResults, dependencies?: IDependencyResponse) {
23+
this.scanResults = scanResults;
24+
this.dependencies = dependencies;
25+
26+
//Maps a license name to its own data
27+
this.licenseSet = {};
28+
this.licenseLayer = [];
29+
}
30+
31+
public getLayerName(): string {
32+
return 'License Obligation Layer';
33+
}
34+
35+
public async getData(): Promise<IDataLayers> {
36+
/* Get licenses from Scan Results */
37+
this.componentList = Object.values(this.scanResults).flat();
38+
this.componentList = this.componentList.filter(
39+
(component) => component.id !== 'none'
40+
);
41+
42+
if (this.componentList.length > 0) {
43+
this.componentList.forEach((component) => {
44+
component.licenses.forEach((license) => {
45+
if (!this.licenseSet[license.name]) {
46+
this.licenseSet[license.name] = {
47+
copyleft:
48+
license.copyleft?.toLowerCase() === 'yes' ? true : false,
49+
label: license.name,
50+
hasIncompatibles: [],
51+
incompatibleWith: license.incompatible_with
52+
? license.incompatible_with.split('')
53+
: [],
54+
};
55+
}
56+
});
57+
});
58+
}
59+
60+
/* Get licenses from Dependencies Results */
61+
if (this.dependencies && this.dependencies.filesList.length > 0) {
62+
this.dependencies.filesList.forEach((file) => {
63+
file.dependenciesList.forEach((dependency) => {
64+
dependency.licensesList.forEach((license) => {
65+
license.spdxId?.split(/;|\//g).forEach((spdxid) => {
66+
if (spdxid !== '' && !this.licenseSet[spdxid]) {
67+
this.licenseSet[spdxid] = {
68+
copyleft: false,
69+
label: spdxid,
70+
hasIncompatibles: [],
71+
incompatibleWith: [],
72+
};
73+
}
74+
});
75+
});
76+
});
77+
});
78+
}
79+
80+
const allSpdxid = Object.keys(this.licenseSet);
81+
const allLicenses = Object.values(this.licenseSet);
82+
83+
const licensesObligations = allLicenses.map((l) => {
84+
l.incompatibleWith = l.incompatibleWith.filter((spdxid) =>
85+
allSpdxid.includes(spdxid)
86+
);
87+
return l;
88+
});
89+
90+
return { licensesObligations } as IDataLayers;
91+
}
92+
}

Diff for: src/sdk/Report/DataLayer/DataProviders/SummaryDataProvider.ts

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export class SummaryDataProvider implements DataProvider {
1414

1515
private projectCreateAt: Date;
1616

17+
private reportTitle: string = 'Detected Report';
1718
constructor(
1819
projectName: string,
1920
projectCreatedAt: Date,
@@ -35,6 +36,7 @@ export class SummaryDataProvider implements DataProvider {
3536
this.summary.totalFiles = 0;
3637
this.summary.noMatchFiles = 0;
3738
this.summary.matchedFiles = 0;
39+
this.summary.reportTitle = this.getReportTitle();
3840

3941
for (const [file, components] of Object.entries(this.scannerResults)) {
4042
components.forEach((component) => {
@@ -47,4 +49,8 @@ export class SummaryDataProvider implements DataProvider {
4749

4850
return <IDataLayers>{ summary: this.summary };
4951
}
52+
53+
public getReportTitle(): string {
54+
return this.reportTitle;
55+
}
5056
}

Diff for: tests/sdk/DataLayer/DataProviders/ComponentDataProvider.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ chai.use(deepEqualInAnyOrder);
1010
const { expect } = chai;
1111

1212
describe('Suit test for DataProvider', () => {
13-
it('Test ComponentDataLayer', function () {
13+
it('Test ComponentDataLayer', async function () {
1414
const result = JSON.parse(
1515
fs.readFileSync(
1616
path.join(__dirname, '/samples/results-with-dep.json'),
@@ -21,7 +21,7 @@ describe('Suit test for DataProvider', () => {
2121
result.scanner,
2222
result.dependencies
2323
);
24-
const componentData = componentDataProvider.getData();
24+
const componentData = await componentDataProvider.getData();
2525

2626
const expectedOutput: ComponentDataLayer[] = [
2727
//First component

Diff for: tests/sdk/DataLayer/DataProviders/DependencyDataProvider.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { DependencyDataProvider } from '../../../../src/sdk/Report/DataLayer/Dat
66
import { DependencyDataLayer } from '../../../../src/sdk/Report/DataLayer/DataLayerTypes';
77

88
describe('Suit test for Dependency Data Provider', () => {
9-
it('Test Simple case Dependency Data provider', function () {
9+
it('Test Simple case Dependency Data provider', async function () {
1010
const result = JSON.parse(
1111
fs.readFileSync(
1212
path.join(__dirname, '/samples/results-with-dep.json'),
@@ -16,7 +16,7 @@ describe('Suit test for Dependency Data Provider', () => {
1616
const dependencyDataProvider = new DependencyDataProvider(
1717
result.dependencies
1818
);
19-
const dependencyData = dependencyDataProvider.getData();
19+
const dependencyData = await dependencyDataProvider.getData();
2020

2121
const expectedOutput: DependencyDataLayer[] = [
2222
{

Diff for: tests/sdk/DataLayer/DataProviders/SummaryDataProvider.spec.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { SummaryDataLayer } from '../../../../src/sdk/Report/DataLayer/DataLayer
66
import { SummaryDataProvider } from '../../../../src/sdk/Report/DataLayer/DataProviders/SummaryDataProvider';
77

88
describe('Suit test for SummaryDataProvider', () => {
9-
it('Simple test SummaryDataProvider', function () {
9+
it('Simple test SummaryDataProvider', async function () {
1010
const result = JSON.parse(
1111
fs.readFileSync(
1212
path.join(__dirname, '/samples/results-with-dep.json'),
@@ -21,14 +21,15 @@ describe('Suit test for SummaryDataProvider', () => {
2121
date,
2222
result.scanner
2323
);
24-
const summaryData = summaryDataProvider.getData();
24+
const summaryData = await summaryDataProvider.getData();
2525

2626
const expectedOutput: SummaryDataLayer = {
2727
projectName: 'Test project',
2828
timestamp: date,
2929
totalFiles: 4,
3030
noMatchFiles: 0,
3131
matchedFiles: 4,
32+
reportTitle: summaryDataProvider.getReportTitle(),
3233
};
3334

3435
expect(summaryData.summary).to.deep.equal(expectedOutput);

0 commit comments

Comments
 (0)