Skip to content

Commit

Permalink
SCP-138 Adds policy report: copyleft
Browse files Browse the repository at this point in the history
  • Loading branch information
francostramana committed Feb 26, 2024
1 parent 89dbf68 commit e15c5a9
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 22 deletions.
18 changes: 17 additions & 1 deletion __tests__/result-service.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ScannerResults } from '../src/services/result.interfaces';
import { getLicenses, License } from '../src/services/result.service';
import { getComponents, getLicenses, License } from '../src/services/result.service';

const licenseTableTest: { name: string; description: string; content: string; licenses: License[] }[] = [
{
Expand Down Expand Up @@ -60,3 +60,19 @@ describe('Test Results service', () => {
});
}
});

describe('Test components service', () => {
const t = licenseTableTest[3];
it(`test c`, () => {

Check warning on line 66 in __tests__/result-service.test.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Test has no assertions

Check warning on line 66 in __tests__/result-service.test.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Test has no assertions
const scannerResults = JSON.parse(t.content) as ScannerResults;
const components = getComponents(scannerResults);
const util = require('util');

Check failure on line 69 in __tests__/result-service.test.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

A `require()` style import is forbidden

Check failure on line 69 in __tests__/result-service.test.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Require statement not part of import statement

Check failure on line 69 in __tests__/result-service.test.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

A `require()` style import is forbidden

Check failure on line 69 in __tests__/result-service.test.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Require statement not part of import statement
// console.log(util.inspect(compoments, {showHidden: false, depth: null, colors: true}))

const componentsWithCopyleft = components.filter(component =>
component.licenses.some(license => !!license.copyleft)
);

console.log(util.inspect(componentsWithCopyleft, { showHidden: false, depth: null, colors: true }));
});
});
76 changes: 66 additions & 10 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 36 additions & 6 deletions src/policies/copyleft-policy-check.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ScannerResults } from '../services/result.interfaces';
import { CHECK_NAME } from '../app.config';
import { PolicyCheck } from './policy-check';
import { getLicenses } from '../services/result.service';
import { Component, getComponents, getLicenses } from '../services/result.service';

Check warning on line 4 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

'getLicenses' is defined but never used

Check warning on line 4 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

'getLicenses' is defined but never used
import { generateTable } from 'src/utils/markdown.util';

Check failure on line 5 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Unexpected use of file extension "util" for "src/utils/markdown.util"

Check failure on line 5 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Unable to resolve path to module 'src/utils/markdown.util'

Check failure on line 5 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Unexpected use of file extension "util" for "src/utils/markdown.util"

Check failure on line 5 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Unable to resolve path to module 'src/utils/markdown.util'

export class CopyleftPolicyCheck extends PolicyCheck {
constructor() {
Expand All @@ -10,13 +11,42 @@ export class CopyleftPolicyCheck extends PolicyCheck {

async run(scannerResults: ScannerResults): Promise<void> {
super.run(scannerResults);
const licenses = getLicenses(scannerResults);
const components = getComponents(scannerResults);

const hasCopyleft = licenses.some(license => !!license.copyleft);
if (!hasCopyleft) {
this.success('Completed succesfully', 'Not copyleft licenses were found');
// Filter copyleft components
const componentsWithCopyleft = components.filter(component =>
component.licenses.some(license => !!license.copyleft)
);

const summary = this.getSummary(componentsWithCopyleft);
const details = this.getDetails(componentsWithCopyleft);

if (componentsWithCopyleft.length === 0) {
return this.success(summary, details);
} else {
this.reject('Completed failure', 'Copyleft licenses were found:'); // TODO: create a table with copyleft licenses
return this.reject(summary, details);
}
}

private getSummary(components: Component[]): string {
return components.length === 0
? '### :white_check_mark: Policy Pass \n ' + '#### ' + 'Not copyleft components were found'

Check failure on line 33 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Unexpected string concatenation of literals

Check failure on line 33 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Unexpected string concatenation of literals

Check failure on line 33 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Unexpected string concatenation of literals

Check failure on line 33 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Unexpected string concatenation of literals
: '### :x: Policy Fail \n' + '#### ' + components.length + ' component(s) with copyleft licenses were found';

Check failure on line 34 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Unexpected string concatenation

Check failure on line 34 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / Lint Codebase

Unexpected string concatenation of literals

Check failure on line 34 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Unexpected string concatenation

Check failure on line 34 in src/policies/copyleft-policy-check.ts

View workflow job for this annotation

GitHub Actions / TypeScript Tests

Unexpected string concatenation of literals
}

private getDetails(components: Component[]): string {
if (components.length === 0) return '';

const headers = ['Component', 'Version', 'License', 'URL', 'Copyleft'];
const rows: string[][] = [];

components.forEach(component => {
component.licenses.forEach(license => {
const copyleftIcon = license.copyleft ? ':x:' : ' ';
rows.push([component.purl, component.version, license.spdxid, `${license.url || ''}`, copyleftIcon]);
});
});

return generateTable(headers, rows);
}
}
4 changes: 2 additions & 2 deletions src/policies/policy-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ export abstract class PolicyCheck {
}

protected async success(summary: string, text: string): Promise<void> {
await this.finish(CONCLUSION.Success, summary, text);
return await this.finish(CONCLUSION.Success, summary, text);
}

protected async reject(summary: string, text: string): Promise<void> {
await this.finish(inputs.POLICIES_HALT_ON_FAILURE ? CONCLUSION.Failure : CONCLUSION.Neutral, summary, text);
return await this.finish(inputs.POLICIES_HALT_ON_FAILURE ? CONCLUSION.Failure : CONCLUSION.Neutral, summary, text);
}

protected async finish(conclusion: CONCLUSION | undefined, summary: string, text: string): Promise<void> {
Expand Down
22 changes: 19 additions & 3 deletions src/services/result.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,44 @@ export interface License {

export interface Component {
purl: string;
version: string;
licenses: License[];
}

export function getComponents(results: ScannerResults): Component[] {
const components = new Array<Component>();

for (const component of Object.values(results)) {
for (const c of component) {
if (c.id === ComponentID.FILE || c.id === ComponentID.SNIPPET) {
components.push({
purl: (c as ScannerComponent).purl[0]
purl: (c as ScannerComponent).purl[0],
version: (c as ScannerComponent).version,
licenses: (c as ScannerComponent).licenses.map(l => ({
spdxid: l.name,
copyleft: !l.copyleft ? null : l.copyleft === 'yes' ? true : false,
url: l?.url ? l.url : null,
count: 1
}))
});
}

if (c.id === ComponentID.DEPENDENCY) {
const dependencies = (c as DependencyComponent).dependencies;
for (const d of dependencies) {
components.push({ purl: d.purl });
components.push({
purl: d.purl,
version: d.version,
licenses: d.licenses.map(l => ({ spdxid: l.spdx_id, copyleft: null, url: null, count: 1 }))
});
}
}
}
}

return Array.from(new Set(components)); //Remove duplicated
//Merge duplicates purls

return components;
}

export function getLicenses(results: ScannerResults): License[] {
Expand Down
13 changes: 13 additions & 0 deletions src/utils/markdown.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const generateTable = (headers: string[], rows: string[][]): string => {
const COL_SEP = ' | ';
const LINE_BREAK = ' \n ';

let md = COL_SEP + headers.join(COL_SEP) + COL_SEP + LINE_BREAK;
md += COL_SEP + new Array(headers.length).fill('-').join(COL_SEP) + COL_SEP + LINE_BREAK;

rows.forEach(row => {
md += COL_SEP + row.join(COL_SEP) + COL_SEP + LINE_BREAK;
});

return md;
};

0 comments on commit e15c5a9

Please sign in to comment.