scanoss 0.2.18 → 0.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/main/bin/cli-bin.js +4 -2
- package/build/main/commands/dep.js +19 -7
- package/build/main/commands/helpers.d.ts +1 -0
- package/build/main/commands/helpers.js +22 -0
- package/build/main/commands/scan.js +3 -15
- package/build/main/index.d.ts +2 -1
- package/build/main/index.js +3 -2
- package/build/main/lib/dependencies/DependencyScanner.d.ts +10 -0
- package/build/main/lib/dependencies/DependencyScanner.js +66 -0
- package/build/main/lib/dependencies/DependencyScannerCfg.d.ts +4 -0
- package/build/main/lib/dependencies/DependencyScannerCfg.js +11 -0
- package/build/main/lib/dependencies/DependencyTypes.d.ts +10 -8
- package/build/main/lib/dependencies/LocalDependency/DependencyTypes.d.ts +16 -0
- package/build/main/lib/dependencies/LocalDependency/DependencyTypes.js +3 -0
- package/build/main/lib/dependencies/LocalDependency/LocalDependency.d.ts +6 -0
- package/build/main/lib/dependencies/LocalDependency/LocalDependency.js +51 -0
- package/build/main/lib/dependencies/LocalDependency/parsers/golangParser.d.ts +2 -0
- package/build/main/lib/dependencies/LocalDependency/parsers/golangParser.js +63 -0
- package/build/main/lib/dependencies/LocalDependency/parsers/mavenParser.d.ts +2 -0
- package/build/main/lib/dependencies/LocalDependency/parsers/mavenParser.js +57 -0
- package/build/main/lib/dependencies/{parsers → LocalDependency/parsers}/npmParser.d.ts +3 -3
- package/build/main/lib/dependencies/LocalDependency/parsers/npmParser.js +50 -0
- package/build/main/lib/dependencies/LocalDependency/parsers/pyParser.d.ts +2 -0
- package/build/main/lib/dependencies/LocalDependency/parsers/pyParser.js +61 -0
- package/build/main/lib/dependencies/{parsers → LocalDependency/parsers}/rubyParser.d.ts +3 -3
- package/build/main/lib/dependencies/LocalDependency/parsers/rubyParser.js +133 -0
- package/build/main/lib/dependencies/{parsers → LocalDependency/parsers}/utils.d.ts +0 -0
- package/build/main/lib/dependencies/{parsers → LocalDependency/parsers}/utils.js +1 -1
- package/build/main/lib/grpc/GrpcDependencyService.d.ts +11 -0
- package/build/main/lib/grpc/GrpcDependencyService.js +88 -0
- package/build/main/lib/{dependencies/parsers/golangParser.d.ts → grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.d.ts} +0 -0
- package/build/main/lib/grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.js +2 -0
- package/build/main/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.d.ts +1 -0
- package/build/main/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.js +404 -0
- package/build/main/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.d.ts +42 -0
- package/build/main/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.js +98 -0
- package/build/main/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.d.ts +1 -0
- package/build/main/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.js +1197 -0
- package/build/main/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.d.ts +21 -0
- package/build/main/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.js +66 -0
- package/build/main/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.d.ts +1 -0
- package/build/main/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.js +14 -0
- package/build/main/lib/scanner/Scanner.js +1 -1
- package/build/module/bin/cli-bin.js +4 -2
- package/build/module/commands/dep.js +19 -7
- package/build/module/commands/helpers.d.ts +1 -0
- package/build/module/commands/helpers.js +15 -0
- package/build/module/commands/scan.js +2 -14
- package/build/module/index.d.ts +2 -1
- package/build/module/index.js +3 -2
- package/build/module/lib/dependencies/DependencyScanner.d.ts +10 -0
- package/build/module/lib/dependencies/DependencyScanner.js +64 -0
- package/build/module/lib/dependencies/DependencyScannerCfg.d.ts +4 -0
- package/build/module/lib/dependencies/DependencyScannerCfg.js +5 -0
- package/build/module/lib/dependencies/DependencyTypes.d.ts +10 -8
- package/build/module/lib/dependencies/LocalDependency/DependencyTypes.d.ts +16 -0
- package/build/module/lib/dependencies/LocalDependency/DependencyTypes.js +2 -0
- package/build/module/lib/dependencies/LocalDependency/LocalDependency.d.ts +6 -0
- package/build/module/lib/dependencies/LocalDependency/LocalDependency.js +45 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/golangParser.d.ts +2 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/golangParser.js +55 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/mavenParser.d.ts +2 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/mavenParser.js +50 -0
- package/build/module/lib/dependencies/{parsers → LocalDependency/parsers}/npmParser.d.ts +3 -3
- package/build/module/lib/dependencies/LocalDependency/parsers/npmParser.js +42 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/pyParser.d.ts +2 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/pyParser.js +53 -0
- package/build/module/lib/dependencies/{parsers → LocalDependency/parsers}/rubyParser.d.ts +3 -3
- package/build/module/lib/dependencies/LocalDependency/parsers/rubyParser.js +130 -0
- package/build/module/lib/dependencies/{parsers → LocalDependency/parsers}/utils.d.ts +0 -0
- package/build/module/lib/dependencies/LocalDependency/parsers/utils.js +15 -0
- package/build/module/lib/grpc/GrpcDependencyService.d.ts +11 -0
- package/build/module/lib/grpc/GrpcDependencyService.js +67 -0
- package/build/module/lib/{dependencies/parsers/golangParser.d.ts → grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.d.ts} +0 -0
- package/build/module/lib/grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.js +2 -0
- package/build/module/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.d.ts +1 -0
- package/build/module/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.js +404 -0
- package/build/module/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.d.ts +42 -0
- package/build/module/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.js +98 -0
- package/build/module/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.d.ts +1 -0
- package/build/module/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.js +1197 -0
- package/build/module/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.d.ts +21 -0
- package/build/module/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.js +66 -0
- package/build/module/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.d.ts +1 -0
- package/build/module/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.js +14 -0
- package/build/module/lib/scanner/Scanner.js +1 -1
- package/build/tsconfig.module.tsbuildinfo +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -1
- package/src/bin/cli-bin.ts +4 -1
- package/src/commands/dep.ts +18 -6
- package/src/commands/helpers.ts +14 -0
- package/src/commands/scan.ts +3 -12
- package/src/index.ts +5 -1
- package/src/lib/dependencies/DependencyScanner.ts +77 -0
- package/src/lib/dependencies/DependencyScannerCfg.ts +7 -0
- package/src/lib/dependencies/DependencyTypes.ts +16 -14
- package/src/lib/dependencies/LocalDependency/DependencyTypes.ts +21 -0
- package/src/lib/dependencies/LocalDependency/LocalDependency.ts +48 -0
- package/src/lib/dependencies/LocalDependency/parsers/golangParser.ts +78 -0
- package/src/lib/dependencies/{parsers → LocalDependency/parsers}/mavenParser.ts +10 -6
- package/src/lib/dependencies/{parsers → LocalDependency/parsers}/npmParser.ts +14 -8
- package/src/lib/dependencies/LocalDependency/parsers/pyParser.ts +55 -0
- package/src/lib/dependencies/{parsers → LocalDependency/parsers}/rubyParser.ts +21 -29
- package/src/lib/dependencies/{parsers → LocalDependency/parsers}/utils.ts +0 -1
- package/src/lib/grpc/GrpcDependencyService.ts +73 -0
- package/src/lib/grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.d.ts +1 -0
- package/src/lib/grpc/scanoss/api/common/v2/scanoss-common_grpc_pb.js +1 -0
- package/src/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.d.ts +79 -0
- package/src/lib/grpc/scanoss/api/common/v2/scanoss-common_pb.js +482 -0
- package/src/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.d.ts +30 -0
- package/src/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_grpc_pb.js +109 -0
- package/src/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.d.ts +206 -0
- package/src/lib/grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb.js +1489 -0
- package/src/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.d.ts +25 -0
- package/src/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_grpc_pb.js +73 -0
- package/src/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.d.ts +6 -0
- package/src/lib/grpc/scanoss/api/scanning/v2/scanoss-scanning_pb.js +15 -0
- package/src/lib/scanner/Scanner.ts +2 -1
- package/tsconfig.json +5 -22
- package/yarn.lock +5252 -5213
- package/build/main/lib/dependencies/Dependency.d.ts +0 -9
- package/build/main/lib/dependencies/Dependency.js +0 -52
- package/build/main/lib/dependencies/PurlGenerator.d.ts +0 -2
- package/build/main/lib/dependencies/PurlGenerator.js +0 -44
- package/build/main/lib/dependencies/parsers/golangParser.js +0 -3
- package/build/main/lib/dependencies/parsers/mavenParser.d.ts +0 -2
- package/build/main/lib/dependencies/parsers/mavenParser.js +0 -54
- package/build/main/lib/dependencies/parsers/npmParser.js +0 -46
- package/build/main/lib/dependencies/parsers/pyParser.d.ts +0 -2
- package/build/main/lib/dependencies/parsers/pyParser.js +0 -51
- package/build/main/lib/dependencies/parsers/rubyParser.js +0 -135
- package/build/main/lib/dependencies/parsers/types.d.ts +0 -15
- package/build/main/lib/dependencies/parsers/types.js +0 -33
- package/build/module/lib/dependencies/Dependency.d.ts +0 -9
- package/build/module/lib/dependencies/Dependency.js +0 -47
- package/build/module/lib/dependencies/PurlGenerator.d.ts +0 -2
- package/build/module/lib/dependencies/PurlGenerator.js +0 -37
- package/build/module/lib/dependencies/parsers/golangParser.js +0 -3
- package/build/module/lib/dependencies/parsers/mavenParser.d.ts +0 -2
- package/build/module/lib/dependencies/parsers/mavenParser.js +0 -47
- package/build/module/lib/dependencies/parsers/npmParser.js +0 -38
- package/build/module/lib/dependencies/parsers/pyParser.d.ts +0 -2
- package/build/module/lib/dependencies/parsers/pyParser.js +0 -44
- package/build/module/lib/dependencies/parsers/rubyParser.js +0 -132
- package/build/module/lib/dependencies/parsers/types.d.ts +0 -15
- package/build/module/lib/dependencies/parsers/types.js +0 -32
- package/build/module/lib/dependencies/parsers/utils.js +0 -15
- package/package-lock.json +0 -18589
- package/src/lib/dependencies/Dependency.ts +0 -60
- package/src/lib/dependencies/PurlGenerator.ts +0 -44
- package/src/lib/dependencies/parsers/golangParser.ts +0 -4
- package/src/lib/dependencies/parsers/pyParser.ts +0 -46
- package/src/lib/dependencies/parsers/types.ts +0 -50
package/src/commands/dep.ts
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
|
-
import {
|
|
2
|
+
import { DependencyScanner } from "../lib/dependencies/DependencyScanner";
|
|
3
|
+
import { DependencyScannerCfg } from "../lib/dependencies/DependencyScannerCfg";
|
|
3
4
|
import { Tree } from "../lib/tree/Tree";
|
|
5
|
+
import { isFolder } from "./helpers";
|
|
4
6
|
|
|
5
7
|
export async function depHandler(rootPath: string, options: any): Promise<void> {
|
|
8
|
+
|
|
6
9
|
rootPath = rootPath.replace(/\/$/, ''); // Remove trailing slash if exists
|
|
7
10
|
rootPath = rootPath.replace(/^\./, process.env.PWD); // Convert relative path to absolute path.
|
|
11
|
+
const pathIsFolder = await isFolder(rootPath);
|
|
12
|
+
const dependencyScannerCfg = new DependencyScannerCfg();
|
|
13
|
+
if(options.grpcHost) dependencyScannerCfg.DEFAULT_GRPC_HOST = options.grpcHost;
|
|
14
|
+
if(options.grpcPort) dependencyScannerCfg.DEFAULT_GRPC_PORT = options.grpcPort;
|
|
15
|
+
|
|
16
|
+
const dependencyScanner = new DependencyScanner(dependencyScannerCfg);
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
|
|
18
|
+
let fileList: Array<string> = [];
|
|
19
|
+
fileList.push(rootPath);
|
|
11
20
|
|
|
12
|
-
|
|
21
|
+
if (pathIsFolder) {
|
|
22
|
+
const tree = new Tree(rootPath);
|
|
23
|
+
tree.buildTree();
|
|
24
|
+
fileList = tree.getRootFolder().getFiles().map((path) => {return rootPath+path});
|
|
25
|
+
}
|
|
13
26
|
|
|
14
|
-
const
|
|
15
|
-
const results = await dependency.scan(fileList);
|
|
27
|
+
const results = await dependencyScanner.scan(fileList);
|
|
16
28
|
|
|
17
29
|
if(options.output) {
|
|
18
30
|
fs.promises.writeFile(options.output, JSON.stringify(results, null, 2));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
// Async function that verify if a path is a folder. If the path is not valid the promise will be rejected
|
|
4
|
+
export const isFolder = (path: string): Promise<boolean> => {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
fs.stat(path, (err, stats) => {
|
|
7
|
+
if (err) {
|
|
8
|
+
reject(err);
|
|
9
|
+
} else {
|
|
10
|
+
resolve(stats.isDirectory());
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
}
|
package/src/commands/scan.ts
CHANGED
|
@@ -8,20 +8,11 @@ import { DispatcherResponse } from '../lib/scanner/Dispatcher/DispatcherResponse
|
|
|
8
8
|
import { defaultFilter } from '../lib/filters/defaultFilter';
|
|
9
9
|
import { FilterList } from '../lib/filters/filtering';
|
|
10
10
|
|
|
11
|
+
import { isFolder } from './helpers';
|
|
12
|
+
|
|
11
13
|
import fs from 'fs';
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
const isFolder = (path: string): Promise<boolean> => {
|
|
15
|
-
return new Promise((resolve, reject) => {
|
|
16
|
-
fs.stat(path, (err, stats) => {
|
|
17
|
-
if (err) {
|
|
18
|
-
reject(err);
|
|
19
|
-
} else {
|
|
20
|
-
resolve(stats.isDirectory());
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
}
|
|
15
|
+
|
|
25
16
|
|
|
26
17
|
export async function scanHandler(rootPath: string, options: any): Promise<void> {
|
|
27
18
|
|
package/src/index.ts
CHANGED
|
@@ -2,4 +2,8 @@ export * from './lib/scanner/ScannerTypes';
|
|
|
2
2
|
export * from './lib/scanner/ScannerCfg'
|
|
3
3
|
export * from './lib/scanner/Scanner'
|
|
4
4
|
export * from './lib/dependencies/DependencyTypes';
|
|
5
|
-
export * from './lib/dependencies/
|
|
5
|
+
export * from './lib/dependencies/DependencyScannerCfg';
|
|
6
|
+
export * from './lib/dependencies/DependencyScanner';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { ILocalDependencies } from "./LocalDependency/DependencyTypes";
|
|
2
|
+
import { GrpcDependencyService } from "../grpc/GrpcDependencyService";
|
|
3
|
+
import { DependencyRequest, DependencyResponse } from "../grpc/scanoss/api/dependencies/v2/scanoss-dependencies_pb";
|
|
4
|
+
import { LocalDependencies } from "./LocalDependency/LocalDependency";
|
|
5
|
+
import { DependencyScannerCfg } from "./DependencyScannerCfg";
|
|
6
|
+
import { IDependencyResponse } from "./DependencyTypes";
|
|
7
|
+
|
|
8
|
+
export class DependencyScanner {
|
|
9
|
+
|
|
10
|
+
private localDependency: LocalDependencies;
|
|
11
|
+
|
|
12
|
+
private grpcDependencyService: GrpcDependencyService;
|
|
13
|
+
|
|
14
|
+
constructor(cfg = new DependencyScannerCfg()) {
|
|
15
|
+
this.grpcDependencyService = new GrpcDependencyService(cfg.DEFAULT_GRPC_HOST, cfg.DEFAULT_GRPC_PORT);
|
|
16
|
+
this.localDependency = new LocalDependencies();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
public async scan(files: Array<string>): Promise<IDependencyResponse> {
|
|
21
|
+
const localDependencies = await this.localDependency.search(files);
|
|
22
|
+
if (localDependencies.files.length === 0) return null;
|
|
23
|
+
const request = this.buildRequest(localDependencies);
|
|
24
|
+
const grpcResponse = await this.grpcDependencyService.get(request);
|
|
25
|
+
const response = grpcResponse.toObject();
|
|
26
|
+
|
|
27
|
+
// Extract scope from localDependencies and add it to response
|
|
28
|
+
this.mergeScopeField(localDependencies, response);
|
|
29
|
+
return response;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
private buildRequest(localDependencies: ILocalDependencies): DependencyRequest {
|
|
34
|
+
try {
|
|
35
|
+
const depRequest = new DependencyRequest();
|
|
36
|
+
for (const file of localDependencies.files) {
|
|
37
|
+
const fileMsg = new DependencyRequest.Files();
|
|
38
|
+
fileMsg.setFile(file.file);
|
|
39
|
+
for (const purl of file.purls) {
|
|
40
|
+
const purlMsg = new DependencyRequest.Purls();
|
|
41
|
+
purlMsg.setPurl(purl.purl);
|
|
42
|
+
purlMsg.setRequirement(purl?.requirements);
|
|
43
|
+
fileMsg.addPurls(purlMsg);
|
|
44
|
+
}
|
|
45
|
+
depRequest.addFiles(fileMsg);
|
|
46
|
+
}
|
|
47
|
+
return depRequest;
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.error(e);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private mergeScopeField(localdependency: ILocalDependencies, serverResponse: DependencyResponse.AsObject
|
|
55
|
+
): IDependencyResponse {
|
|
56
|
+
|
|
57
|
+
const scopeHashMap = {};
|
|
58
|
+
|
|
59
|
+
for (const file of localdependency.files) {
|
|
60
|
+
const filename = file.file
|
|
61
|
+
for (const dependency of file.purls) {
|
|
62
|
+
if (dependency?.scope) scopeHashMap[filename + dependency.purl] = dependency.scope;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const file of serverResponse.filesList) {
|
|
67
|
+
const filename = file.file
|
|
68
|
+
for (const dependency of file.dependenciesList) {
|
|
69
|
+
const scope = scopeHashMap[filename + dependency.purl];
|
|
70
|
+
if (scope) dependency['scope'] = scope;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return serverResponse;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export interface LicensesList {
|
|
2
|
+
name: string;
|
|
3
|
+
spdxId: string;
|
|
4
|
+
isSpdxApproved: boolean;
|
|
4
5
|
}
|
|
5
6
|
|
|
6
|
-
export interface
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export interface DependenciesList {
|
|
8
|
+
component: string;
|
|
9
|
+
purl: string;
|
|
10
|
+
version?: string;
|
|
11
|
+
scope?: string;
|
|
12
|
+
licensesList: LicensesList[];
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
export interface
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
export interface FilesList {
|
|
16
|
+
file: string;
|
|
17
|
+
id: string;
|
|
18
|
+
status: string;
|
|
19
|
+
dependenciesList: DependenciesList[];
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export interface IDependencyResponse {
|
|
21
|
-
|
|
23
|
+
filesList: FilesList[];
|
|
22
24
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ILocalPurl {
|
|
2
|
+
purl: string;
|
|
3
|
+
requirements?: string;
|
|
4
|
+
scope?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ILocalDependency {
|
|
8
|
+
file: string;
|
|
9
|
+
purls: Array<ILocalPurl>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ILocalDependencies{
|
|
13
|
+
files: Array<ILocalDependency>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* Parser funcion definition */
|
|
17
|
+
export type ParserFuncType = (fileContent: string, filePath: string) => ILocalDependency;
|
|
18
|
+
|
|
19
|
+
export interface ParserDefinitions {
|
|
20
|
+
[key: string]: ParserFuncType;
|
|
21
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { ParserFuncType, ILocalDependencies } from "./DependencyTypes";
|
|
4
|
+
import { requirementsParser } from "./parsers/pyParser";
|
|
5
|
+
import { pomParser } from "./parsers/mavenParser";
|
|
6
|
+
import { packagelockParser, packageParser } from "./parsers/npmParser";
|
|
7
|
+
import { gemfilelockParser, gemfileParser } from "./parsers/rubyParser";
|
|
8
|
+
import { goModParser } from './parsers/golangParser';
|
|
9
|
+
|
|
10
|
+
export class LocalDependencies {
|
|
11
|
+
|
|
12
|
+
private parserMap: Record<string, ParserFuncType>;
|
|
13
|
+
|
|
14
|
+
constructor() {
|
|
15
|
+
/*
|
|
16
|
+
This is a hash map that connect a filename with it's own parser function
|
|
17
|
+
Any parser function must return a ILocalDependencies object (See DependencyTypes.ts)
|
|
18
|
+
*/
|
|
19
|
+
this.parserMap = {
|
|
20
|
+
'requirements.txt': requirementsParser,
|
|
21
|
+
'pom.xml': pomParser,
|
|
22
|
+
'package.json': packageParser,
|
|
23
|
+
'package-lock.json': packagelockParser,
|
|
24
|
+
'Gemfile': gemfileParser,
|
|
25
|
+
'Gemfile.lock': gemfilelockParser,
|
|
26
|
+
'go.mod': goModParser,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public async search(files: Array<string>): Promise<ILocalDependencies> {
|
|
31
|
+
let results: ILocalDependencies = {files: []};
|
|
32
|
+
for (const filePath of files) {
|
|
33
|
+
const fileName = path.basename(filePath);
|
|
34
|
+
if(this.parserMap[fileName] != null) {
|
|
35
|
+
try{
|
|
36
|
+
const fileContent = await fs.promises.readFile(filePath, 'utf8');
|
|
37
|
+
const dependency = this.parserMap[fileName](fileContent, filePath);
|
|
38
|
+
if(dependency.purls.length != 0)
|
|
39
|
+
results.files.push(dependency);
|
|
40
|
+
} catch(e) {
|
|
41
|
+
console.error(e);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return results;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ILocalDependency } from "../DependencyTypes";
|
|
2
|
+
|
|
3
|
+
import { PackageURL } from "packageurl-js";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
function parseModule (str: string) {
|
|
7
|
+
const res = /(?<type>[^\s]+)(?:\s)+(?<ns_name>[^\s]+)\s?(?<version>(.*))/.exec(str);
|
|
8
|
+
return {
|
|
9
|
+
type: res.groups.type,
|
|
10
|
+
ns_name: res.groups.ns_name,
|
|
11
|
+
version: res.groups.version
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function parseDepLink (str: string) {
|
|
16
|
+
const res = /.*?(?<ns_name>[^\s]+)\s+(?<version>(.*))/.exec(str);
|
|
17
|
+
return {
|
|
18
|
+
ns_name: res?.groups?.ns_name,
|
|
19
|
+
version: res?.groups?.version
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Removes comments and spaces
|
|
24
|
+
function preprocessLine(line: string) {
|
|
25
|
+
if (line.includes("//"))
|
|
26
|
+
line = line.substring(0,line.indexOf("//"));
|
|
27
|
+
return line.trim();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
const PURL_TYPE = 'golang';
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// See reference on: https://go.dev/ref/mod#go-mod-file
|
|
37
|
+
const MANIFEST_FILE = 'go.mod';
|
|
38
|
+
export function goModParser(fileContent: string, filePath: string): ILocalDependency {
|
|
39
|
+
|
|
40
|
+
// If the file is not a go.mod manifest file, return an empty results
|
|
41
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
42
|
+
if(path.basename(filePath) != MANIFEST_FILE)
|
|
43
|
+
return results;
|
|
44
|
+
|
|
45
|
+
const lines = fileContent.split('\n');
|
|
46
|
+
|
|
47
|
+
const require = [];
|
|
48
|
+
const exclude = [];
|
|
49
|
+
|
|
50
|
+
for (let num = 0 ; num < lines.length ; num+=1) {
|
|
51
|
+
|
|
52
|
+
let line = preprocessLine(lines[num]);
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if(line.includes('require') && line.includes('(')) {
|
|
56
|
+
num+=1;
|
|
57
|
+
line = preprocessLine(lines[num]);
|
|
58
|
+
while (num < lines.length && line!==')') {
|
|
59
|
+
|
|
60
|
+
const {ns_name, version} = parseDepLink(line);
|
|
61
|
+
|
|
62
|
+
const index = ns_name.lastIndexOf('/');
|
|
63
|
+
const namespace = ns_name.substring(0, index);
|
|
64
|
+
const name = ns_name.substring(index + 1);
|
|
65
|
+
|
|
66
|
+
const purlString = new PackageURL(PURL_TYPE, namespace, name, version, undefined, undefined).toString();
|
|
67
|
+
results.purls.push({purl: purlString});
|
|
68
|
+
|
|
69
|
+
require.push(line);
|
|
70
|
+
|
|
71
|
+
num+=1;
|
|
72
|
+
line = preprocessLine(lines[num]);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return results;
|
|
78
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { PackageURL } from "packageurl-js";
|
|
3
|
-
import {
|
|
4
|
-
import { isValidPath, isValidUrl } from './utils';
|
|
3
|
+
import { ILocalDependency } from "../DependencyTypes";
|
|
5
4
|
|
|
6
5
|
const PURL_TYPE = 'maven';
|
|
7
6
|
|
|
8
7
|
|
|
8
|
+
|
|
9
9
|
// Parse a pom.txt file from maven manifest file
|
|
10
10
|
// See reference on: https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
|
|
11
11
|
// and https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
|
|
12
12
|
const MANIFEST_FILE = 'pom.xml';
|
|
13
|
-
export function pomParser(fileContent: string, filePath: string):
|
|
13
|
+
export function pomParser(fileContent: string, filePath: string): ILocalDependency {
|
|
14
14
|
|
|
15
15
|
// If the file is not a python manifest file, return an empty results
|
|
16
|
-
const results:
|
|
16
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
17
17
|
if(path.basename(filePath) != MANIFEST_FILE)
|
|
18
18
|
return results;
|
|
19
19
|
|
|
@@ -34,7 +34,7 @@ export function pomParser(fileContent: string, filePath: string): FileDependency
|
|
|
34
34
|
let version = versionReg ? versionReg[1] : '';
|
|
35
35
|
|
|
36
36
|
const ver = version.match(/\${(.*?)}/);
|
|
37
|
-
if(ver && ver.length >= 1)
|
|
37
|
+
if(ver && ver.length >= 1) {
|
|
38
38
|
if(ver[1] === 'project.version') { // TODO: Add support for project.version
|
|
39
39
|
version = undefined;
|
|
40
40
|
} else {
|
|
@@ -50,8 +50,12 @@ export function pomParser(fileContent: string, filePath: string): FileDependency
|
|
|
50
50
|
purlQualifiers['type'] = type[1]
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// Extract scope.
|
|
54
|
+
const scopeRes = dependency.match(/<scope>([^<]*)<\/scope>/);
|
|
55
|
+
const scope = scopeRes ? scopeRes[1] : undefined;
|
|
56
|
+
|
|
53
57
|
const purlString = new PackageURL(PURL_TYPE, namespace, name, version, purlQualifiers, undefined).toString();
|
|
54
|
-
results.purls.push({purl: purlString});
|
|
58
|
+
results.purls.push({purl: purlString, scope: scope});
|
|
55
59
|
});
|
|
56
60
|
}
|
|
57
61
|
return results;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { PackageURL } from "packageurl-js";
|
|
3
|
-
import {
|
|
4
|
-
import { isValidPath, isValidUrl } from './utils';
|
|
3
|
+
import { ILocalDependency } from "../DependencyTypes";
|
|
5
4
|
|
|
6
5
|
const PURL_TYPE = 'npm';
|
|
7
6
|
|
|
@@ -9,19 +8,26 @@ const PURL_TYPE = 'npm';
|
|
|
9
8
|
// Parse a package.json file from node projects
|
|
10
9
|
// See reference on: https://docs.npmjs.com/cli/v8/configuring-npm/package-json
|
|
11
10
|
const MANIFEST_FILE = 'package.json';
|
|
12
|
-
export function packageParser(fileContent: string, filePath: string):
|
|
11
|
+
export function packageParser(fileContent: string, filePath: string): ILocalDependency {
|
|
13
12
|
// If the file is not manifest file, return an empty results
|
|
14
|
-
const results:
|
|
13
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
15
14
|
if(path.basename(filePath) != MANIFEST_FILE)
|
|
16
15
|
return results;
|
|
17
16
|
const o = JSON.parse(fileContent);
|
|
18
17
|
let devDeps = Object.keys(o.devDependencies || {});
|
|
19
18
|
let deps = Object.keys(o.dependencies || {});
|
|
20
19
|
let listDeps = [...deps, ...devDeps];
|
|
21
|
-
|
|
20
|
+
|
|
21
|
+
for(const name of deps){
|
|
22
22
|
const purlString = new PackageURL(PURL_TYPE, undefined, name, undefined, undefined, undefined).toString();
|
|
23
|
-
results.purls.push({purl: purlString});
|
|
23
|
+
results.purls.push({purl: purlString, scope: "dependencies", requirements: o.dependencies[name]});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for(const name of devDeps){
|
|
27
|
+
const purlString = new PackageURL(PURL_TYPE, undefined, name, undefined, undefined, undefined).toString();
|
|
28
|
+
results.purls.push({purl: purlString, scope: "devDependencies", requirements: o.devDependencies[name]});
|
|
24
29
|
}
|
|
30
|
+
|
|
25
31
|
return results;
|
|
26
32
|
}
|
|
27
33
|
|
|
@@ -29,9 +35,9 @@ export function packageParser(fileContent: string, filePath: string): FileDepend
|
|
|
29
35
|
// Parse a package-lock.json file from node projects
|
|
30
36
|
// See reference on: https://docs.npmjs.com/cli/v8/configuring-npm/package-json
|
|
31
37
|
const MANIFEST_FILE_1 = 'package-lock.json';
|
|
32
|
-
export function packagelockParser(fileContent: string, filePath: string):
|
|
38
|
+
export function packagelockParser(fileContent: string, filePath: string): ILocalDependency {
|
|
33
39
|
|
|
34
|
-
const results:
|
|
40
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
35
41
|
if(path.basename(filePath) != MANIFEST_FILE_1)
|
|
36
42
|
return results;
|
|
37
43
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { PackageURL } from "packageurl-js";
|
|
3
|
+
import { ILocalDependency } from "../DependencyTypes";
|
|
4
|
+
import { isValidPath, isValidUrl } from './utils';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
function parseDep (str: string) {
|
|
8
|
+
const res = /^(?<name>[-\w]+)\s*(?<sym>[>=~!]*)\s*(?<version>[\d\.]*)/.exec(str);
|
|
9
|
+
return {
|
|
10
|
+
name: res?.groups?.name,
|
|
11
|
+
sym: res?.groups?.sym,
|
|
12
|
+
version: res?.groups?.version,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const PURL_TYPE = 'pypi';
|
|
17
|
+
|
|
18
|
+
// Parse a requirements.txt file from python projects
|
|
19
|
+
// See reference on: https://pip.pypa.io/en/stable/reference/requirements-file-format/
|
|
20
|
+
const MANIFEST_FILE = 'requirements.txt';
|
|
21
|
+
export function requirementsParser(fileContent: string, filePath: string): ILocalDependency {
|
|
22
|
+
|
|
23
|
+
// If the file is not a python manifest file, return an empty results
|
|
24
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
25
|
+
if(path.basename(filePath) != MANIFEST_FILE)
|
|
26
|
+
return results;
|
|
27
|
+
|
|
28
|
+
const lines: Array<string> = fileContent.split('\n');
|
|
29
|
+
|
|
30
|
+
for (let line of lines) {
|
|
31
|
+
line = line.trim();
|
|
32
|
+
if(line.length == 0) continue;
|
|
33
|
+
if(!line.startsWith('#') && line.length>0) { // Avoid comments and new lines
|
|
34
|
+
if(isValidUrl(line)) {
|
|
35
|
+
// For reference about the regex see https://www.rfc-editor.org/rfc/rfc3986#appendix-B
|
|
36
|
+
const res = line.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
else if(isValidPath(line)) {continue;} // Do not parse local dependencies.
|
|
40
|
+
else if(line.startsWith('-r')) {continue;} // Recursive dependencies (NOT SUPPORTED YET)
|
|
41
|
+
else {
|
|
42
|
+
|
|
43
|
+
const dep = parseDep(line);
|
|
44
|
+
if (dep.sym === '==') {
|
|
45
|
+
const purlString = new PackageURL(PURL_TYPE, undefined, dep.name, dep.version, undefined, undefined).toString();
|
|
46
|
+
results.purls.push({purl: purlString});
|
|
47
|
+
} else {
|
|
48
|
+
const purlString = new PackageURL(PURL_TYPE, undefined, dep.name, undefined, undefined, undefined).toString();
|
|
49
|
+
results.purls.push({purl: purlString, requirements: dep.sym+dep.version});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return results;
|
|
55
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { PackageURL } from "packageurl-js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import { stringify } from "querystring";
|
|
3
|
+
import { ILocalDependency } from "../DependencyTypes";
|
|
4
|
+
|
|
6
5
|
|
|
7
6
|
const PURL_TYPE = 'gem';
|
|
8
7
|
|
|
@@ -11,10 +10,10 @@ const PURL_TYPE = 'gem';
|
|
|
11
10
|
// See reference on: https://bundler.io/gemfile.html
|
|
12
11
|
// and https://bundler.io/man/gemfile.5.html
|
|
13
12
|
const MANIFEST_FILE = 'Gemfile';
|
|
14
|
-
export function gemfileParser(fileContent: string, filePath: string):
|
|
15
|
-
|
|
13
|
+
export function gemfileParser(fileContent: string, filePath: string): ILocalDependency {
|
|
14
|
+
|
|
16
15
|
// If the file is not a manifest file, return an empty results
|
|
17
|
-
const results:
|
|
16
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
18
17
|
if(path.basename(filePath) != MANIFEST_FILE)
|
|
19
18
|
return results;
|
|
20
19
|
|
|
@@ -32,7 +31,7 @@ export function gemfileParser(fileContent: string, filePath: string): FileDepend
|
|
|
32
31
|
compName = compName.replace(/['"]/g, '');
|
|
33
32
|
const purlString = new PackageURL(PURL_TYPE, undefined, compName, undefined, undefined, undefined).toString();
|
|
34
33
|
results.purls.push({purl: purlString});
|
|
35
|
-
}
|
|
34
|
+
}
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
return results;
|
|
@@ -40,10 +39,10 @@ export function gemfileParser(fileContent: string, filePath: string): FileDepend
|
|
|
40
39
|
|
|
41
40
|
|
|
42
41
|
const MANIFEST_FILE_1 = 'Gemfile.lock';
|
|
43
|
-
export function gemfilelockParser(fileContent: string, filePath: string):
|
|
44
|
-
|
|
42
|
+
export function gemfilelockParser(fileContent: string, filePath: string): ILocalDependency {
|
|
43
|
+
|
|
45
44
|
// If the file is not a manifest file, return an empty results
|
|
46
|
-
const results:
|
|
45
|
+
const results: ILocalDependency = {file: filePath, purls: []};
|
|
47
46
|
if(path.basename(filePath) != MANIFEST_FILE_1)
|
|
48
47
|
return results;
|
|
49
48
|
|
|
@@ -80,13 +79,13 @@ const firstDepLevelRegex = /^ {4}(?! )/;
|
|
|
80
79
|
class GemfileLockParser {
|
|
81
80
|
|
|
82
81
|
private statesMap;
|
|
83
|
-
|
|
84
|
-
private state;
|
|
85
|
-
|
|
86
|
-
private current_options: Record<string, string>;
|
|
87
|
-
|
|
88
|
-
private current_gem;
|
|
89
|
-
|
|
82
|
+
|
|
83
|
+
private state;
|
|
84
|
+
|
|
85
|
+
private current_options: Record<string, string>;
|
|
86
|
+
|
|
87
|
+
private current_gem;
|
|
88
|
+
|
|
90
89
|
private purlList;
|
|
91
90
|
|
|
92
91
|
constructor () {
|
|
@@ -127,7 +126,6 @@ class GemfileLockParser {
|
|
|
127
126
|
// process the line
|
|
128
127
|
if (this.state) this.state(line);
|
|
129
128
|
}
|
|
130
|
-
this.refine();
|
|
131
129
|
return this.purlList;
|
|
132
130
|
}
|
|
133
131
|
|
|
@@ -141,21 +139,21 @@ class GemfileLockParser {
|
|
|
141
139
|
const key = match.length>=1 ? match[1] : null;
|
|
142
140
|
const value = match.length>=2 ? match[2] : null;
|
|
143
141
|
if(key) this.current_options[key] = value;
|
|
144
|
-
}
|
|
142
|
+
}
|
|
145
143
|
|
|
146
144
|
private parseDependency(line: string) {}
|
|
147
145
|
private parsePlatform(line: string){}
|
|
148
|
-
|
|
146
|
+
|
|
149
147
|
|
|
150
148
|
private parseSpec(line: string) {
|
|
151
|
-
|
|
149
|
+
|
|
152
150
|
if(this.current_gem == GEM) {
|
|
153
|
-
if(firstDepLevelRegex.test(line)) {
|
|
151
|
+
if(firstDepLevelRegex.test(line)) {
|
|
154
152
|
line = line.trimStart();
|
|
155
153
|
const match = line.match(specRegex);
|
|
156
154
|
|
|
157
155
|
const purl = new PackageURL( PURL_TYPE,
|
|
158
|
-
undefined,
|
|
156
|
+
undefined,
|
|
159
157
|
match.groups.name,
|
|
160
158
|
match.groups.version,
|
|
161
159
|
undefined,
|
|
@@ -171,11 +169,5 @@ class GemfileLockParser {
|
|
|
171
169
|
|
|
172
170
|
// Purl from local dependencies are not generated
|
|
173
171
|
if(this.current_gem == PATH){}
|
|
174
|
-
|
|
175
172
|
}
|
|
176
|
-
|
|
177
|
-
private refine() {}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
173
|
}
|