@soos-io/soos-sbom 1.0.1-pre.1 → 1.0.1-pre.3
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/README.md +2 -0
- package/bin/constants.d.ts +4 -0
- package/bin/constants.js +4 -0
- package/bin/index.js +54 -19
- package/bin/utilities.d.ts +1 -0
- package/bin/utilities.js +5 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -38,4 +38,6 @@ Then run from the same terminal `node ./soos/node_modules/@soos-io/soos-sbom/bin
|
|
|
38
38
|
| `--operatingEnvironment`| | Set Operating environment for information purposes only. |
|
|
39
39
|
| `--otherOptions` | | Other Options to pass to syft. |
|
|
40
40
|
| `--projectName` | | Project Name - this is what will be displayed in the SOOS app. |
|
|
41
|
+
| `--directoriesToExclude` | `**/node_modules/**, "**/bin/**", "**/obj/**", "**/lib/**` | Listing of directories or patterns to exclude from the search for SBOM files. eg: **bin/start/**, **/start/** |
|
|
42
|
+
| `--filesToExclude` | | Listing of files or patterns patterns to exclude from the search for SBOM files. eg: **/int**.cdx.json/, **/internal.cdx.json |
|
|
41
43
|
| `sbomPath` | | The SBOM File to scan, it could be the location of the file or the file itself. When location is specified only the first file found will be scanned. |
|
package/bin/constants.d.ts
CHANGED
package/bin/constants.js
CHANGED
|
@@ -3,4 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SOOS_SBOM_CONSTANTS = void 0;
|
|
4
4
|
exports.SOOS_SBOM_CONSTANTS = {
|
|
5
5
|
FileRegex: /\.(cdx|spdx)\.json$/,
|
|
6
|
+
FileSyncPattern: "**/*.@(cdx.json|spdx.json)",
|
|
7
|
+
MaxSbomsPerScan: 50,
|
|
8
|
+
UploadBatchSize: 10,
|
|
9
|
+
DefaultDirectoriesToExclude: ["**/node_modules/**", "**/bin/**", "**/obj/**", "**/lib/**"],
|
|
6
10
|
};
|
package/bin/index.js
CHANGED
|
@@ -11,6 +11,8 @@ const AnalysisArgumentParser_1 = tslib_1.__importDefault(require("@soos-io/api-c
|
|
|
11
11
|
const package_json_1 = require("../package.json");
|
|
12
12
|
const AnalysisService_1 = tslib_1.__importDefault(require("@soos-io/api-client/dist/services/AnalysisService"));
|
|
13
13
|
const constants_1 = require("./constants");
|
|
14
|
+
const utilities_2 = require("./utilities");
|
|
15
|
+
const Glob = tslib_1.__importStar(require("glob"));
|
|
14
16
|
class SOOSSBOMAnalysis {
|
|
15
17
|
constructor(args) {
|
|
16
18
|
this.args = args;
|
|
@@ -18,6 +20,21 @@ class SOOSSBOMAnalysis {
|
|
|
18
20
|
static parseArgs() {
|
|
19
21
|
const analysisArgumentParser = AnalysisArgumentParser_1.default.create(api_client_1.IntegrationName.SoosSbom, api_client_1.IntegrationType.Script, api_client_1.ScanType.SBOM, package_json_1.version);
|
|
20
22
|
analysisArgumentParser.addBaseScanArguments();
|
|
23
|
+
analysisArgumentParser.argumentParser.add_argument("--directoriesToExclude", {
|
|
24
|
+
help: "Listing of directories or patterns to exclude from the search for SBOM files. eg: **bin/start/**, **/start/**",
|
|
25
|
+
type: (value) => {
|
|
26
|
+
return (0, utilities_2.removeDuplicates)(value.split(",").map((pattern) => pattern.trim()));
|
|
27
|
+
},
|
|
28
|
+
default: constants_1.SOOS_SBOM_CONSTANTS.DefaultDirectoriesToExclude,
|
|
29
|
+
required: false,
|
|
30
|
+
});
|
|
31
|
+
analysisArgumentParser.argumentParser.add_argument("--filesToExclude", {
|
|
32
|
+
help: "Listing of files or patterns patterns to exclude from the search for SBOM files. eg: **/int**.cdx.json/, **/internal.cdx.json",
|
|
33
|
+
type: (value) => {
|
|
34
|
+
return value.split(",").map((pattern) => pattern.trim());
|
|
35
|
+
},
|
|
36
|
+
required: false,
|
|
37
|
+
});
|
|
21
38
|
analysisArgumentParser.argumentParser.add_argument("sbomPath", {
|
|
22
39
|
help: "The SBOM File to scan, it could be the location of the file or the file itself. When location is specified only the first file found will be scanned.",
|
|
23
40
|
});
|
|
@@ -31,7 +48,15 @@ class SOOSSBOMAnalysis {
|
|
|
31
48
|
let branchHash;
|
|
32
49
|
let analysisId;
|
|
33
50
|
let scanStatusUrl;
|
|
34
|
-
|
|
51
|
+
let sbomFilePaths = await this.findSbomFilePaths();
|
|
52
|
+
const hasMoreThanMaximumManifests = sbomFilePaths.length > constants_1.SOOS_SBOM_CONSTANTS.MaxSbomsPerScan;
|
|
53
|
+
if (hasMoreThanMaximumManifests) {
|
|
54
|
+
const filesToSkip = sbomFilePaths.slice(constants_1.SOOS_SBOM_CONSTANTS.MaxSbomsPerScan);
|
|
55
|
+
sbomFilePaths = sbomFilePaths.slice(0, constants_1.SOOS_SBOM_CONSTANTS.MaxSbomsPerScan);
|
|
56
|
+
const filesDetectedString = utilities_1.StringUtilities.pluralizeTemplate(sbomFilePaths.length, "file was", "files were");
|
|
57
|
+
const filesSkippedString = utilities_1.StringUtilities.pluralizeTemplate(filesToSkip.length, "file");
|
|
58
|
+
api_client_1.soosLogger.info(`The maximum number of SBOMs per scan is ${constants_1.SOOS_SBOM_CONSTANTS.MaxSbomsPerScan}. ${filesDetectedString} detected, and ${filesSkippedString} will be not be uploaded. \n`, `The following SBOMs will not be included in the scan: \n`, filesToSkip.map((file) => ` "${Path.parse(file).base}": "${file}"`).join("\n"));
|
|
59
|
+
}
|
|
35
60
|
try {
|
|
36
61
|
const result = await soosAnalysisService.setupScan({
|
|
37
62
|
clientId: this.args.clientId,
|
|
@@ -66,17 +91,22 @@ class SOOSSBOMAnalysis {
|
|
|
66
91
|
analysisId = result.analysisId;
|
|
67
92
|
scanStatusUrl = result.scanStatusUrl;
|
|
68
93
|
api_client_1.soosLogger.logLineSeparator();
|
|
69
|
-
api_client_1.soosLogger.info("Uploading SBOM File...");
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
94
|
+
api_client_1.soosLogger.info("Uploading SBOM File(s)...");
|
|
95
|
+
for (let i = 0; i < sbomFilePaths.length; i += constants_1.SOOS_SBOM_CONSTANTS.UploadBatchSize) {
|
|
96
|
+
const sbomFilePathsBatch = sbomFilePaths.slice(i, i + constants_1.SOOS_SBOM_CONSTANTS.UploadBatchSize);
|
|
97
|
+
const formData = await soosAnalysisService.getAnalysisFilesAsFormData(sbomFilePathsBatch, this.args.sbomPath);
|
|
98
|
+
const manifestUploadResponse = await soosAnalysisService.analysisApiClient.uploadManifestFiles({
|
|
99
|
+
clientId: this.args.clientId,
|
|
100
|
+
projectHash,
|
|
101
|
+
branchHash,
|
|
102
|
+
analysisId,
|
|
103
|
+
manifestFiles: formData,
|
|
104
|
+
hasMoreThanMaximumManifests,
|
|
105
|
+
});
|
|
106
|
+
api_client_1.soosLogger.info(` SBOM Files: \n`, ` ${manifestUploadResponse.message} \n`, manifestUploadResponse.manifests
|
|
107
|
+
?.map((m) => ` ${m.name}: ${m.statusMessage}`)
|
|
108
|
+
.join("\n"));
|
|
109
|
+
}
|
|
80
110
|
api_client_1.soosLogger.logLineSeparator();
|
|
81
111
|
await soosAnalysisService.startScan({
|
|
82
112
|
clientId: this.args.clientId,
|
|
@@ -112,20 +142,25 @@ class SOOSSBOMAnalysis {
|
|
|
112
142
|
(0, process_1.exit)(1);
|
|
113
143
|
}
|
|
114
144
|
}
|
|
115
|
-
async
|
|
145
|
+
async findSbomFilePaths() {
|
|
116
146
|
const sbomPathStat = await FileSystem.statSync(this.args.sbomPath);
|
|
117
147
|
if (sbomPathStat.isDirectory()) {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
148
|
+
const searchPattern = this.args.sbomPath.endsWith("/") || this.args.sbomPath.endsWith("\\")
|
|
149
|
+
? `${this.args.sbomPath}${constants_1.SOOS_SBOM_CONSTANTS.FileSyncPattern}`
|
|
150
|
+
: `${this.args.sbomPath}/${constants_1.SOOS_SBOM_CONSTANTS.FileSyncPattern}`;
|
|
151
|
+
const sbomFiles = Glob.sync(searchPattern, {
|
|
152
|
+
ignore: [...(this.args.filesToExclude || []), ...(this.args.directoriesToExclude || [])],
|
|
153
|
+
nocase: true,
|
|
154
|
+
});
|
|
155
|
+
if (!sbomFiles || sbomFiles.length == 0) {
|
|
156
|
+
throw new Error("No SBOM files found in the directory.");
|
|
122
157
|
}
|
|
123
|
-
return
|
|
158
|
+
return sbomFiles;
|
|
124
159
|
}
|
|
125
160
|
if (!constants_1.SOOS_SBOM_CONSTANTS.FileRegex.test(this.args.sbomPath)) {
|
|
126
161
|
throw new Error("The file does not match the required SBOM pattern.");
|
|
127
162
|
}
|
|
128
|
-
return this.args.sbomPath;
|
|
163
|
+
return [this.args.sbomPath];
|
|
129
164
|
}
|
|
130
165
|
static async createAndRun() {
|
|
131
166
|
api_client_1.soosLogger.info("Starting SOOS SBOM Analysis");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const removeDuplicates: <T>(list: Array<T>) => Array<T>;
|
package/bin/utilities.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soos-io/soos-sbom",
|
|
3
|
-
"version": "1.0.1-pre.
|
|
3
|
+
"version": "1.0.1-pre.3",
|
|
4
4
|
"description": "SOOS wrapper script to upload SBOMs.",
|
|
5
5
|
"main": "bin/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -39,16 +39,16 @@
|
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://github.com/soos-io/soos-sbom#readme",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@soos-io/api-client": "1.0.
|
|
42
|
+
"@soos-io/api-client": "1.0.5",
|
|
43
43
|
"argparse": "^2.0.1",
|
|
44
44
|
"glob": "^11.0.0",
|
|
45
45
|
"tslib": "^2.6.3"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/argparse": "^2.0.
|
|
49
|
-
"@types/node": "^20.16.
|
|
48
|
+
"@types/argparse": "^2.0.16",
|
|
49
|
+
"@types/node": "^20.16.5",
|
|
50
50
|
"prettier": "^3.3.3",
|
|
51
|
-
"typescript": "^5.
|
|
51
|
+
"typescript": "^5.6.2"
|
|
52
52
|
},
|
|
53
53
|
"bin": {
|
|
54
54
|
"soos-sbom": "bin/index.js"
|