@cyclonedx/cdxgen 11.1.5 → 11.1.7
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/bin/cdxgen.js +8 -5
- package/lib/cli/index.js +55 -48
- package/lib/evinser/evinser.js +19 -17
- package/lib/helpers/envcontext.js +12 -12
- package/lib/helpers/envcontext.test.js +1 -1
- package/lib/helpers/utils.js +104 -60
- package/lib/helpers/validator.js +9 -1
- package/lib/managers/binary.js +3 -3
- package/lib/managers/docker.js +26 -22
- package/package.json +2 -2
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/helpers/utils.d.ts +15 -0
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/helpers/validator.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts.map +1 -1
package/bin/cdxgen.js
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
isMac,
|
|
29
29
|
isSecureMode,
|
|
30
30
|
isWin,
|
|
31
|
+
safeExistsSync,
|
|
31
32
|
} from "../lib/helpers/utils.js";
|
|
32
33
|
import { validateBom } from "../lib/helpers/validator.js";
|
|
33
34
|
import { postProcess } from "../lib/stages/postgen/postgen.js";
|
|
@@ -579,7 +580,9 @@ const checkPermissions = (filePath, options) => {
|
|
|
579
580
|
console.log(
|
|
580
581
|
"\x1b[1;35mSecure mode requires permission-related arguments. These can be passed as CLI arguments directly to the node runtime or set the NODE_OPTIONS environment variable as shown below.\x1b[0m",
|
|
581
582
|
);
|
|
582
|
-
const
|
|
583
|
+
const childProcessArgs =
|
|
584
|
+
options?.lifecycle !== "pre-build" ? " --allow-child-process" : "";
|
|
585
|
+
const nodeOptionsVal = `--permission --allow-fs-read="${getTmpDir()}/*" --allow-fs-write="${getTmpDir()}/*" --allow-fs-read="${fullFilePath}/*" --allow-fs-write="${options.output}"${childProcessArgs}`;
|
|
583
586
|
console.log(
|
|
584
587
|
`${isWin ? "$env:" : "export "}NODE_OPTIONS='${nodeOptionsVal}'`,
|
|
585
588
|
);
|
|
@@ -680,11 +683,11 @@ const checkPermissions = (filePath, options) => {
|
|
|
680
683
|
}
|
|
681
684
|
if (!process.permission.has("fs.write", getTmpDir())) {
|
|
682
685
|
console.log(
|
|
683
|
-
`FileSystemWrite permission may be required
|
|
686
|
+
`FileSystemWrite permission may be required for the TEMP directory. Please invoke cdxgen with the argument --allow-fs-write="${join(getTmpDir(), "*")}" in case of any crashes.`,
|
|
684
687
|
);
|
|
685
688
|
if (isMac) {
|
|
686
689
|
console.log(
|
|
687
|
-
"TIP: macOS doesn't use `/tmp` prefix for TEMP directories. Use the argument shown above.",
|
|
690
|
+
"TIP: macOS doesn't use the `/tmp` prefix for TEMP directories. Use the argument shown above.",
|
|
688
691
|
);
|
|
689
692
|
}
|
|
690
693
|
}
|
|
@@ -752,7 +755,7 @@ const checkPermissions = (filePath, options) => {
|
|
|
752
755
|
(process.env.SBOM_SIGN_ALGORITHM &&
|
|
753
756
|
process.env.SBOM_SIGN_ALGORITHM !== "none" &&
|
|
754
757
|
process.env.SBOM_SIGN_PRIVATE_KEY &&
|
|
755
|
-
|
|
758
|
+
safeExistsSync(process.env.SBOM_SIGN_PRIVATE_KEY)))
|
|
756
759
|
) {
|
|
757
760
|
let alg = process.env.SBOM_SIGN_ALGORITHM || "RS512";
|
|
758
761
|
if (alg.includes("none")) {
|
|
@@ -794,7 +797,7 @@ const checkPermissions = (filePath, options) => {
|
|
|
794
797
|
);
|
|
795
798
|
if (
|
|
796
799
|
process.env.SBOM_SIGN_PUBLIC_KEY &&
|
|
797
|
-
|
|
800
|
+
safeExistsSync(process.env.SBOM_SIGN_PUBLIC_KEY)
|
|
798
801
|
) {
|
|
799
802
|
jwkPublicKey = crypto
|
|
800
803
|
.createPublicKey(
|
package/lib/cli/index.js
CHANGED
|
@@ -3,9 +3,7 @@ import { spawnSync } from "node:child_process";
|
|
|
3
3
|
import {
|
|
4
4
|
constants,
|
|
5
5
|
accessSync,
|
|
6
|
-
existsSync,
|
|
7
6
|
lstatSync,
|
|
8
|
-
mkdirSync,
|
|
9
7
|
mkdtempSync,
|
|
10
8
|
readFileSync,
|
|
11
9
|
rmSync,
|
|
@@ -152,6 +150,8 @@ import {
|
|
|
152
150
|
parseYarnLock,
|
|
153
151
|
readZipEntry,
|
|
154
152
|
recomputeScope,
|
|
153
|
+
safeExistsSync,
|
|
154
|
+
safeMkdirSync,
|
|
155
155
|
shouldFetchLicense,
|
|
156
156
|
splitOutputByGradleProjects,
|
|
157
157
|
} from "../helpers/utils.js";
|
|
@@ -242,7 +242,7 @@ const createDefaultParentComponent = (
|
|
|
242
242
|
path = resolve(path);
|
|
243
243
|
// Create a parent component based on the directory name
|
|
244
244
|
let dirNameStr =
|
|
245
|
-
|
|
245
|
+
safeExistsSync(path) && lstatSync(path).isDirectory()
|
|
246
246
|
? basename(path)
|
|
247
247
|
: dirname(path);
|
|
248
248
|
const tmpA = dirNameStr.split(sep);
|
|
@@ -1274,7 +1274,7 @@ export function createBinaryBom(path, options) {
|
|
|
1274
1274
|
const tempDir = mkdtempSync(join(getTmpDir(), "blint-tmp-"));
|
|
1275
1275
|
const binaryBomFile = join(tempDir, "bom.json");
|
|
1276
1276
|
getBinaryBom(path, binaryBomFile, options.deep);
|
|
1277
|
-
if (
|
|
1277
|
+
if (safeExistsSync(binaryBomFile)) {
|
|
1278
1278
|
const binaryBom = JSON.parse(
|
|
1279
1279
|
readFileSync(binaryBomFile, { encoding: "utf-8" }),
|
|
1280
1280
|
);
|
|
@@ -1307,7 +1307,7 @@ export async function createJavaBom(path, options) {
|
|
|
1307
1307
|
// war/ear mode
|
|
1308
1308
|
if (path.endsWith(".war") || path.endsWith(".jar")) {
|
|
1309
1309
|
// Check if the file exists
|
|
1310
|
-
if (
|
|
1310
|
+
if (safeExistsSync(path)) {
|
|
1311
1311
|
if (DEBUG_MODE) {
|
|
1312
1312
|
console.log(`Retrieving packages from ${path}`);
|
|
1313
1313
|
}
|
|
@@ -1416,7 +1416,7 @@ export async function createJavaBom(path, options) {
|
|
|
1416
1416
|
continue;
|
|
1417
1417
|
}
|
|
1418
1418
|
const settingsXml = join(basePath, "settings.xml");
|
|
1419
|
-
if (
|
|
1419
|
+
if (safeExistsSync(settingsXml)) {
|
|
1420
1420
|
console.log(
|
|
1421
1421
|
`maven settings.xml found in ${basePath}. Please set the MVN_ARGS environment variable based on the full mvn build command used for this project.\nExample: MVN_ARGS='--settings ${settingsXml}'`,
|
|
1422
1422
|
);
|
|
@@ -1481,7 +1481,7 @@ export async function createJavaBom(path, options) {
|
|
|
1481
1481
|
mvnTreeArgs = mvnTreeArgs.concat(addArgs);
|
|
1482
1482
|
}
|
|
1483
1483
|
// Automatically use settings.xml to improve the success for fallback
|
|
1484
|
-
if (
|
|
1484
|
+
if (safeExistsSync(settingsXml)) {
|
|
1485
1485
|
mvnTreeArgs.push("-s");
|
|
1486
1486
|
mvnTreeArgs.push(settingsXml);
|
|
1487
1487
|
}
|
|
@@ -1500,7 +1500,7 @@ export async function createJavaBom(path, options) {
|
|
|
1500
1500
|
},
|
|
1501
1501
|
);
|
|
1502
1502
|
if (result.status === 0) {
|
|
1503
|
-
if (
|
|
1503
|
+
if (safeExistsSync(tempMvnParentTree)) {
|
|
1504
1504
|
const mvnTreeString = readFileSync(tempMvnParentTree, {
|
|
1505
1505
|
encoding: "utf-8",
|
|
1506
1506
|
});
|
|
@@ -1582,7 +1582,7 @@ export async function createJavaBom(path, options) {
|
|
|
1582
1582
|
pkgList = pkgList.concat(dlist);
|
|
1583
1583
|
}
|
|
1584
1584
|
} else {
|
|
1585
|
-
if (
|
|
1585
|
+
if (safeExistsSync(tempMvnTree)) {
|
|
1586
1586
|
const mvnTreeString = readFileSync(tempMvnTree, {
|
|
1587
1587
|
encoding: "utf-8",
|
|
1588
1588
|
});
|
|
@@ -1715,10 +1715,10 @@ export async function createJavaBom(path, options) {
|
|
|
1715
1715
|
let gradleRootPath = path;
|
|
1716
1716
|
if (
|
|
1717
1717
|
gradleFiles?.length &&
|
|
1718
|
-
!
|
|
1719
|
-
!
|
|
1720
|
-
!
|
|
1721
|
-
!
|
|
1718
|
+
!safeExistsSync(join(path, "settings.gradle")) &&
|
|
1719
|
+
!safeExistsSync(join(path, "settings.gradle.kts")) &&
|
|
1720
|
+
!safeExistsSync(join(path, "build.gradle")) &&
|
|
1721
|
+
!safeExistsSync(join(path, "build.gradle.kts"))
|
|
1722
1722
|
) {
|
|
1723
1723
|
gradleRootPath = dirname(gradleFiles[0]);
|
|
1724
1724
|
}
|
|
@@ -1964,7 +1964,10 @@ export async function createJavaBom(path, options) {
|
|
|
1964
1964
|
bazelTarget,
|
|
1965
1965
|
];
|
|
1966
1966
|
// Automatically load any bazelrc file
|
|
1967
|
-
if (
|
|
1967
|
+
if (
|
|
1968
|
+
!process.env.BAZEL_ARGS &&
|
|
1969
|
+
safeExistsSync(join(basePath, ".bazelrc"))
|
|
1970
|
+
) {
|
|
1968
1971
|
bArgs = ["--bazelrc=.bazelrc", "build", bazelTarget];
|
|
1969
1972
|
}
|
|
1970
1973
|
console.log("Executing", BAZEL_CMD, bArgs.join(" "), "in", basePath);
|
|
@@ -1988,7 +1991,10 @@ export async function createJavaBom(path, options) {
|
|
|
1988
1991
|
let query = [...(process.env?.BAZEL_ARGS?.split(" ") || [])];
|
|
1989
1992
|
let bazelParser;
|
|
1990
1993
|
// Automatically load any bazelrc file
|
|
1991
|
-
if (
|
|
1994
|
+
if (
|
|
1995
|
+
!process.env.BAZEL_ARGS &&
|
|
1996
|
+
safeExistsSync(join(basePath, ".bazelrc"))
|
|
1997
|
+
) {
|
|
1992
1998
|
query = ["--bazelrc=.bazelrc"];
|
|
1993
1999
|
}
|
|
1994
2000
|
if (["true", "1"].includes(process.env.BAZEL_USE_ACTION_GRAPH)) {
|
|
@@ -2121,7 +2127,7 @@ export async function createJavaBom(path, options) {
|
|
|
2121
2127
|
sbtVersion != null && gte(sbtVersion, "1.4.0");
|
|
2122
2128
|
const tempDir = mkdtempSync(join(getTmpDir(), "cdxsbt-"));
|
|
2123
2129
|
const tempSbtgDir = mkdtempSync(join(getTmpDir(), "cdxsbtg-"));
|
|
2124
|
-
|
|
2130
|
+
safeMkdirSync(tempSbtgDir, { recursive: true });
|
|
2125
2131
|
// Create temporary plugins file
|
|
2126
2132
|
const tempSbtPlugins = join(tempSbtgDir, "dep-plugins.sbt");
|
|
2127
2133
|
|
|
@@ -2191,7 +2197,7 @@ export async function createJavaBom(path, options) {
|
|
|
2191
2197
|
if (!standalonePluginFile) {
|
|
2192
2198
|
cleanupPlugin(basePath, pluginFile);
|
|
2193
2199
|
}
|
|
2194
|
-
if (
|
|
2200
|
+
if (safeExistsSync(dlFile)) {
|
|
2195
2201
|
const retMap = parseSbtTree(dlFile);
|
|
2196
2202
|
if (retMap.pkgList?.length) {
|
|
2197
2203
|
const tmpParentComponent = retMap.pkgList.splice(0, 1)[0];
|
|
@@ -2410,7 +2416,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2410
2416
|
// Projects such as juice-shop prevent lockfile creations using .npmrc files
|
|
2411
2417
|
// Plus, they might require specific npm install args such as --legacy-peer-deps that could lead to strange node_modules structure
|
|
2412
2418
|
// To keep life simple, let's look for any .npmrc file that has package-lock=false to toggle before npm install
|
|
2413
|
-
if (pkgMgr === "npm" &&
|
|
2419
|
+
if (pkgMgr === "npm" && safeExistsSync(join(basePath, ".npmrc"))) {
|
|
2414
2420
|
const npmrcData = readFileSync(join(basePath, ".npmrc"));
|
|
2415
2421
|
if (
|
|
2416
2422
|
npmrcData?.includes("package-lock=false") &&
|
|
@@ -2606,7 +2612,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2606
2612
|
// Determine the parent component
|
|
2607
2613
|
const packageJsonF = join(basePath, "package.json");
|
|
2608
2614
|
if (!Object.keys(parentComponent).length) {
|
|
2609
|
-
if (
|
|
2615
|
+
if (safeExistsSync(packageJsonF)) {
|
|
2610
2616
|
const pcs = await parsePkgJson(packageJsonF, true);
|
|
2611
2617
|
if (pcs.length && Object.keys(pcs[0]).length) {
|
|
2612
2618
|
parentComponent = { ...pcs[0] };
|
|
@@ -2687,7 +2693,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2687
2693
|
if (!Object.keys(parentComponent).length) {
|
|
2688
2694
|
const basePath = dirname(f);
|
|
2689
2695
|
const packageJsonF = join(basePath, "package.json");
|
|
2690
|
-
if (
|
|
2696
|
+
if (safeExistsSync(packageJsonF)) {
|
|
2691
2697
|
const pcs = await parsePkgJson(packageJsonF, true);
|
|
2692
2698
|
if (pcs.length && Object.keys(pcs[0]).length) {
|
|
2693
2699
|
tmpParentComponent = { ...pcs[0] };
|
|
@@ -2727,13 +2733,13 @@ export async function createNodejsBom(path, options) {
|
|
|
2727
2733
|
}
|
|
2728
2734
|
}
|
|
2729
2735
|
if (
|
|
2730
|
-
|
|
2736
|
+
safeExistsSync(join(path, "rush.json")) &&
|
|
2731
2737
|
isPackageManagerAllowed("rush", ["npm", "yarn", "pnpm"], options)
|
|
2732
2738
|
) {
|
|
2733
2739
|
// Rush.js creates node_modules inside common/temp directory
|
|
2734
2740
|
const nmDir = join(path, "common", "temp", "node_modules");
|
|
2735
2741
|
// Do rush install if we don't have node_modules directory
|
|
2736
|
-
if (!
|
|
2742
|
+
if (!safeExistsSync(nmDir)) {
|
|
2737
2743
|
console.log("Executing 'rush install --no-link'", path);
|
|
2738
2744
|
const result = spawnSync(
|
|
2739
2745
|
"rush",
|
|
@@ -2758,7 +2764,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2758
2764
|
"shrinkwrap-deps.json",
|
|
2759
2765
|
);
|
|
2760
2766
|
const pnpmLock = join(path, "common", "config", "rush", "pnpm-lock.yaml");
|
|
2761
|
-
if (
|
|
2767
|
+
if (safeExistsSync(swFile)) {
|
|
2762
2768
|
let pkgList = await parseNodeShrinkwrap(swFile);
|
|
2763
2769
|
if (allImports && Object.keys(allImports).length) {
|
|
2764
2770
|
pkgList = await addEvidenceForImports(
|
|
@@ -2774,7 +2780,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2774
2780
|
filename: "shrinkwrap-deps.json",
|
|
2775
2781
|
});
|
|
2776
2782
|
}
|
|
2777
|
-
if (
|
|
2783
|
+
if (safeExistsSync(pnpmLock)) {
|
|
2778
2784
|
let pkgList = await parsePnpmLock(pnpmLock);
|
|
2779
2785
|
if (allImports && Object.keys(allImports).length) {
|
|
2780
2786
|
pkgList = await addEvidenceForImports(
|
|
@@ -2812,7 +2818,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2812
2818
|
const basePath = dirname(f);
|
|
2813
2819
|
// Determine the parent component
|
|
2814
2820
|
const packageJsonF = join(basePath, "package.json");
|
|
2815
|
-
if (
|
|
2821
|
+
if (safeExistsSync(packageJsonF)) {
|
|
2816
2822
|
const pcs = await parsePkgJson(packageJsonF, true);
|
|
2817
2823
|
if (pcs.length && Object.keys(pcs[0]).length) {
|
|
2818
2824
|
const tmpParentComponent = { ...pcs[0] };
|
|
@@ -2899,7 +2905,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2899
2905
|
}
|
|
2900
2906
|
// We might reach here if the project has no lock files
|
|
2901
2907
|
// Eg: juice-shop
|
|
2902
|
-
if (!pkgList.length &&
|
|
2908
|
+
if (!pkgList.length && safeExistsSync(join(path, "node_modules"))) {
|
|
2903
2909
|
// Collect all package.json files from all node_modules directory
|
|
2904
2910
|
const pkgJsonFiles = getAllFiles(
|
|
2905
2911
|
path,
|
|
@@ -2914,7 +2920,7 @@ export async function createNodejsBom(path, options) {
|
|
|
2914
2920
|
}
|
|
2915
2921
|
}
|
|
2916
2922
|
if (!parentComponent || !Object.keys(parentComponent).length) {
|
|
2917
|
-
if (
|
|
2923
|
+
if (safeExistsSync(join(path, "package.json"))) {
|
|
2918
2924
|
const pcs = await parsePkgJson(join(path, "package.json"), true);
|
|
2919
2925
|
if (pcs.length && Object.keys(pcs[0]).length) {
|
|
2920
2926
|
parentComponent = { ...pcs[0] };
|
|
@@ -2982,7 +2988,7 @@ export function createPixiBom(path, options) {
|
|
|
2982
2988
|
|
|
2983
2989
|
// if pixi.toml file found then we
|
|
2984
2990
|
// Add parentComponent Details
|
|
2985
|
-
const pixiTomlMode =
|
|
2991
|
+
const pixiTomlMode = safeExistsSync(pixiToml);
|
|
2986
2992
|
if (pixiTomlMode) {
|
|
2987
2993
|
parentComponent = parsePixiTomlFile(pixiToml);
|
|
2988
2994
|
parentComponent.type = "application";
|
|
@@ -2999,7 +3005,7 @@ export function createPixiBom(path, options) {
|
|
|
2999
3005
|
}
|
|
3000
3006
|
|
|
3001
3007
|
const pixiLockFile = join(path, "pixi.lock");
|
|
3002
|
-
const pixiFilesMode =
|
|
3008
|
+
const pixiFilesMode = safeExistsSync(pixiLockFile);
|
|
3003
3009
|
if (pixiFilesMode) {
|
|
3004
3010
|
// Instead of what we do in createPythonBOM
|
|
3005
3011
|
// where we install packages and run `getPipFrozenTree`
|
|
@@ -3012,7 +3018,7 @@ export function createPixiBom(path, options) {
|
|
|
3012
3018
|
generatePixiLockFile(path);
|
|
3013
3019
|
|
|
3014
3020
|
const pixiLockFile = join(path, "pixi.lock");
|
|
3015
|
-
if (!
|
|
3021
|
+
if (!safeExistsSync(pixiLockFile) && DEBUG_MODE) {
|
|
3016
3022
|
console.log(
|
|
3017
3023
|
"Unexpected Error tried to generate pixi.lock file but failed.",
|
|
3018
3024
|
);
|
|
@@ -3056,13 +3062,13 @@ export async function createPythonBom(path, options) {
|
|
|
3056
3062
|
const tempDir = mkdtempSync(join(getTmpDir(), "cdxgen-venv-"));
|
|
3057
3063
|
let parentComponent = createDefaultParentComponent(path, "pypi", options);
|
|
3058
3064
|
// We are checking only the root here for pipenv
|
|
3059
|
-
const pipenvMode =
|
|
3065
|
+
const pipenvMode = safeExistsSync(join(path, "Pipfile"));
|
|
3060
3066
|
|
|
3061
3067
|
// If pixi is used then just return that as output instead
|
|
3062
3068
|
const pixiLockFile = join(path, "pixi.lock");
|
|
3063
|
-
const pixiFilesMode =
|
|
3069
|
+
const pixiFilesMode = safeExistsSync(pixiLockFile);
|
|
3064
3070
|
const pixiToml = join(path, "pixi.toml");
|
|
3065
|
-
const pixiTomlMode =
|
|
3071
|
+
const pixiTomlMode = safeExistsSync(pixiToml);
|
|
3066
3072
|
if (pixiTomlMode || pixiFilesMode) {
|
|
3067
3073
|
const BomNSData = createPixiBom(path, options);
|
|
3068
3074
|
if (BomNSData) {
|
|
@@ -3123,7 +3129,7 @@ export async function createPythonBom(path, options) {
|
|
|
3123
3129
|
// Is this a pyproject based project.
|
|
3124
3130
|
// TODO: Support nested directories
|
|
3125
3131
|
const pyProjectFile = join(path, "pyproject.toml");
|
|
3126
|
-
const pyProjectMode =
|
|
3132
|
+
const pyProjectMode = safeExistsSync(pyProjectFile);
|
|
3127
3133
|
if (pyProjectMode) {
|
|
3128
3134
|
const pyProjMap = parsePyProjectTomlFile(pyProjectFile);
|
|
3129
3135
|
const tmpParentComponent = pyProjMap.parentComponent;
|
|
@@ -3156,7 +3162,7 @@ export async function createPythonBom(path, options) {
|
|
|
3156
3162
|
|
|
3157
3163
|
// TODO: Support for nested directories
|
|
3158
3164
|
const setupPy = join(path, "setup.py");
|
|
3159
|
-
const setupPyMode =
|
|
3165
|
+
const setupPyMode = safeExistsSync(setupPy);
|
|
3160
3166
|
// Poetry sets up its own virtual env containing site-packages so
|
|
3161
3167
|
// we give preference to poetry lock file. Issue# 129
|
|
3162
3168
|
if (poetryMode) {
|
|
@@ -3262,7 +3268,7 @@ export async function createPythonBom(path, options) {
|
|
|
3262
3268
|
// TODO: Support for nested directories
|
|
3263
3269
|
spawnSync("pipenv", ["install"], { cwd: path, encoding: "utf-8" });
|
|
3264
3270
|
const piplockFile = join(path, "Pipfile.lock");
|
|
3265
|
-
if (
|
|
3271
|
+
if (safeExistsSync(piplockFile)) {
|
|
3266
3272
|
const lockData = JSON.parse(readFileSync(piplockFile));
|
|
3267
3273
|
const dlist = await parsePiplockData(lockData);
|
|
3268
3274
|
if (dlist?.length) {
|
|
@@ -3967,7 +3973,7 @@ export async function createRustBom(path, options) {
|
|
|
3967
3973
|
if (
|
|
3968
3974
|
options.deep === true ||
|
|
3969
3975
|
(options.installDeps &&
|
|
3970
|
-
!
|
|
3976
|
+
!safeExistsSync(f.replace(".toml", ".lock")) &&
|
|
3971
3977
|
["build", "post-build"].includes(options.lifecycle))
|
|
3972
3978
|
) {
|
|
3973
3979
|
const basePath = dirname(f);
|
|
@@ -5213,7 +5219,7 @@ export function createPHPBom(path, options) {
|
|
|
5213
5219
|
);
|
|
5214
5220
|
if (composerLockFiles.length) {
|
|
5215
5221
|
// Look for any root composer.json to capture the parentComponent
|
|
5216
|
-
if (
|
|
5222
|
+
if (safeExistsSync(join(path, "composer.json"))) {
|
|
5217
5223
|
const { moduleParent } = parseComposerJson(join(path, "composer.json"));
|
|
5218
5224
|
parentComponent = moduleParent;
|
|
5219
5225
|
}
|
|
@@ -5225,7 +5231,7 @@ export function createPHPBom(path, options) {
|
|
|
5225
5231
|
}
|
|
5226
5232
|
let rootRequires = [];
|
|
5227
5233
|
// Is there a composer.json to find the module parent component
|
|
5228
|
-
if (
|
|
5234
|
+
if (safeExistsSync(join(basePath, "composer.json"))) {
|
|
5229
5235
|
const retMap = parseComposerJson(join(basePath, "composer.json"));
|
|
5230
5236
|
moduleParent = retMap.moduleParent;
|
|
5231
5237
|
rootRequires = retMap.rootRequires;
|
|
@@ -5884,7 +5890,7 @@ export async function createCsharpBom(path, options) {
|
|
|
5884
5890
|
join(path, options.depsSlicesFile) || join(getTmpDir(), "dosai.json"),
|
|
5885
5891
|
);
|
|
5886
5892
|
// Create the slices file if it doesn't exist
|
|
5887
|
-
if (!
|
|
5893
|
+
if (!safeExistsSync(slicesFile)) {
|
|
5888
5894
|
const sliceResult = getDotnetSlices(resolve(path), resolve(slicesFile));
|
|
5889
5895
|
if (!sliceResult && DEBUG_MODE) {
|
|
5890
5896
|
console.log(
|
|
@@ -6745,9 +6751,9 @@ export async function createXBom(path, options) {
|
|
|
6745
6751
|
return undefined;
|
|
6746
6752
|
}
|
|
6747
6753
|
if (
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6754
|
+
safeExistsSync(join(path, "package.json")) ||
|
|
6755
|
+
safeExistsSync(join(path, "rush.json")) ||
|
|
6756
|
+
safeExistsSync(join(path, "yarn.lock"))
|
|
6751
6757
|
) {
|
|
6752
6758
|
return await createNodejsBom(path, options);
|
|
6753
6759
|
}
|
|
@@ -6773,10 +6779,11 @@ export async function createXBom(path, options) {
|
|
|
6773
6779
|
return await createJavaBom(path, options);
|
|
6774
6780
|
}
|
|
6775
6781
|
// python
|
|
6776
|
-
const pipenvMode =
|
|
6777
|
-
const poetryMode =
|
|
6778
|
-
const pyProjectMode =
|
|
6779
|
-
|
|
6782
|
+
const pipenvMode = safeExistsSync(join(path, "Pipfile"));
|
|
6783
|
+
const poetryMode = safeExistsSync(join(path, "poetry.lock"));
|
|
6784
|
+
const pyProjectMode =
|
|
6785
|
+
!poetryMode && safeExistsSync(join(path, "pyproject.toml"));
|
|
6786
|
+
const setupPyMode = safeExistsSync(join(path, "setup.py"));
|
|
6780
6787
|
if (pipenvMode || poetryMode || pyProjectMode || setupPyMode) {
|
|
6781
6788
|
return await createPythonBom(path, options);
|
|
6782
6789
|
}
|
|
@@ -7111,7 +7118,7 @@ export async function createBom(path, options) {
|
|
|
7111
7118
|
allLayersDir: path,
|
|
7112
7119
|
allLayersExplodedDir: path,
|
|
7113
7120
|
};
|
|
7114
|
-
if (
|
|
7121
|
+
if (safeExistsSync(join(path, "all-layers"))) {
|
|
7115
7122
|
exportData.allLayersDir = join(path, "all-layers");
|
|
7116
7123
|
}
|
|
7117
7124
|
exportData.pkgPathList = getPkgPathList(exportData, undefined);
|
package/lib/evinser/evinser.js
CHANGED
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
getMavenCommand,
|
|
17
17
|
getTimestamp,
|
|
18
18
|
getTmpDir,
|
|
19
|
+
safeExistsSync,
|
|
20
|
+
safeMkdirSync,
|
|
19
21
|
} from "../helpers/utils.js";
|
|
20
22
|
import { postProcess } from "../stages/postgen/postgen.js";
|
|
21
23
|
import { createSemanticsSlices } from "./swiftsem.js";
|
|
@@ -29,16 +31,16 @@ const typePurlsCache = {};
|
|
|
29
31
|
* @param {Object} options Command line options
|
|
30
32
|
*/
|
|
31
33
|
export async function prepareDB(options) {
|
|
32
|
-
if (!options.dbPath.includes("memory") && !
|
|
34
|
+
if (!options.dbPath.includes("memory") && !safeExistsSync(options.dbPath)) {
|
|
33
35
|
try {
|
|
34
|
-
|
|
36
|
+
safeMkdirSync(options.dbPath, { recursive: true });
|
|
35
37
|
} catch (e) {
|
|
36
38
|
// ignore
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
const dirPath = options._[0] || ".";
|
|
40
42
|
const bomJsonFile = options.input;
|
|
41
|
-
if (!
|
|
43
|
+
if (!safeExistsSync(bomJsonFile)) {
|
|
42
44
|
console.log(
|
|
43
45
|
"Bom file doesn't exist. Check if cdxgen was invoked with the correct type argument.",
|
|
44
46
|
);
|
|
@@ -102,7 +104,7 @@ export async function catalogMavenDeps(
|
|
|
102
104
|
options = {},
|
|
103
105
|
) {
|
|
104
106
|
let jarNSMapping = undefined;
|
|
105
|
-
if (
|
|
107
|
+
if (safeExistsSync(path.join(dirPath, "bom.json.map"))) {
|
|
106
108
|
try {
|
|
107
109
|
const mapData = JSON.parse(
|
|
108
110
|
fs.readFileSync(path.join(dirPath, "bom.json.map"), "utf-8"),
|
|
@@ -190,7 +192,7 @@ export async function createAndStoreSlice(
|
|
|
190
192
|
) {
|
|
191
193
|
const retMap = createSlice(purl, purlsJars[purl], "usages", options);
|
|
192
194
|
let sliceData = undefined;
|
|
193
|
-
if (retMap?.slicesFile &&
|
|
195
|
+
if (retMap?.slicesFile && safeExistsSync(retMap.slicesFile)) {
|
|
194
196
|
sliceData = await Usages.findOrCreate({
|
|
195
197
|
where: { purl },
|
|
196
198
|
defaults: {
|
|
@@ -245,7 +247,7 @@ export async function createSlice(
|
|
|
245
247
|
);
|
|
246
248
|
if (options?.output) {
|
|
247
249
|
sliceOutputDir =
|
|
248
|
-
|
|
250
|
+
safeExistsSync(options.output) &&
|
|
249
251
|
fs.lstatSync(options.output).isDirectory()
|
|
250
252
|
? path.basename(options.output)
|
|
251
253
|
: path.dirname(options.output);
|
|
@@ -290,7 +292,7 @@ export async function createSlice(
|
|
|
290
292
|
|
|
291
293
|
args.push(path.resolve(filePath));
|
|
292
294
|
const result = executeAtom(filePath, args);
|
|
293
|
-
if (!result || !
|
|
295
|
+
if (!result || !safeExistsSync(slicesFile)) {
|
|
294
296
|
console.warn(
|
|
295
297
|
`Unable to generate ${sliceType} slice using atom. Check if this is a supported language.`,
|
|
296
298
|
);
|
|
@@ -378,7 +380,7 @@ export function initFromSbom(components, language) {
|
|
|
378
380
|
}
|
|
379
381
|
|
|
380
382
|
function usableSlicesFile(slicesFile) {
|
|
381
|
-
if (!slicesFile || !
|
|
383
|
+
if (!slicesFile || !safeExistsSync(slicesFile)) {
|
|
382
384
|
return false;
|
|
383
385
|
}
|
|
384
386
|
const stats = fs.statSync(slicesFile);
|
|
@@ -432,7 +434,7 @@ export async function analyzeProject(dbObjMap, options) {
|
|
|
432
434
|
);
|
|
433
435
|
} else {
|
|
434
436
|
retMap = await createSlice(language, dirPath, "reachables", options);
|
|
435
|
-
if (retMap?.slicesFile &&
|
|
437
|
+
if (retMap?.slicesFile && safeExistsSync(retMap.slicesFile)) {
|
|
436
438
|
reachablesSlicesFile = retMap.slicesFile;
|
|
437
439
|
reachablesSlice = JSON.parse(
|
|
438
440
|
fs.readFileSync(retMap.slicesFile, "utf-8"),
|
|
@@ -453,7 +455,7 @@ export async function analyzeProject(dbObjMap, options) {
|
|
|
453
455
|
} else {
|
|
454
456
|
// Generate our own slices
|
|
455
457
|
retMap = await createSlice(language, dirPath, "usages", options);
|
|
456
|
-
if (retMap?.slicesFile &&
|
|
458
|
+
if (retMap?.slicesFile && safeExistsSync(retMap.slicesFile)) {
|
|
457
459
|
usageSlice = JSON.parse(fs.readFileSync(retMap.slicesFile, "utf-8"));
|
|
458
460
|
usagesSlicesFile = retMap.slicesFile;
|
|
459
461
|
}
|
|
@@ -463,7 +465,7 @@ export async function analyzeProject(dbObjMap, options) {
|
|
|
463
465
|
// Reuse existing semantics slices
|
|
464
466
|
if (
|
|
465
467
|
options.semanticsSlicesFile &&
|
|
466
|
-
|
|
468
|
+
safeExistsSync(options.semanticsSlicesFile)
|
|
467
469
|
) {
|
|
468
470
|
semanticsSlice = JSON.parse(
|
|
469
471
|
fs.readFileSync(options.semanticsSlicesFile, "utf-8"),
|
|
@@ -472,7 +474,7 @@ export async function analyzeProject(dbObjMap, options) {
|
|
|
472
474
|
} else {
|
|
473
475
|
// Generate our own slices
|
|
474
476
|
retMap = await createSlice(language, dirPath, "semantics", options);
|
|
475
|
-
if (retMap?.slicesFile &&
|
|
477
|
+
if (retMap?.slicesFile && safeExistsSync(retMap.slicesFile)) {
|
|
476
478
|
semanticsSlice = JSON.parse(
|
|
477
479
|
fs.readFileSync(retMap.slicesFile, "utf-8"),
|
|
478
480
|
);
|
|
@@ -507,7 +509,7 @@ export async function analyzeProject(dbObjMap, options) {
|
|
|
507
509
|
if (options.withDataFlow) {
|
|
508
510
|
if (
|
|
509
511
|
options.dataFlowSlicesFile &&
|
|
510
|
-
|
|
512
|
+
safeExistsSync(options.dataFlowSlicesFile)
|
|
511
513
|
) {
|
|
512
514
|
dataFlowSlicesFile = options.dataFlowSlicesFile;
|
|
513
515
|
dataFlowSlice = JSON.parse(
|
|
@@ -515,7 +517,7 @@ export async function analyzeProject(dbObjMap, options) {
|
|
|
515
517
|
);
|
|
516
518
|
} else {
|
|
517
519
|
retMap = await createSlice(language, dirPath, "data-flow", options);
|
|
518
|
-
if (retMap?.slicesFile &&
|
|
520
|
+
if (retMap?.slicesFile && safeExistsSync(retMap.slicesFile)) {
|
|
519
521
|
dataFlowSlicesFile = retMap.slicesFile;
|
|
520
522
|
dataFlowSlice = JSON.parse(fs.readFileSync(retMap.slicesFile, "utf-8"));
|
|
521
523
|
}
|
|
@@ -1359,7 +1361,7 @@ export function createEvinseFile(sliceArtefacts, options) {
|
|
|
1359
1361
|
bomJson.dependencies = newDependencies;
|
|
1360
1362
|
}
|
|
1361
1363
|
if (options.annotate) {
|
|
1362
|
-
if (usagesSlicesFile &&
|
|
1364
|
+
if (usagesSlicesFile && safeExistsSync(usagesSlicesFile)) {
|
|
1363
1365
|
bomJson.annotations.push({
|
|
1364
1366
|
subjects: [bomJson.serialNumber],
|
|
1365
1367
|
annotator: { component: bomJson.metadata.tools.components[0] },
|
|
@@ -1367,7 +1369,7 @@ export function createEvinseFile(sliceArtefacts, options) {
|
|
|
1367
1369
|
text: fs.readFileSync(usagesSlicesFile, "utf8"),
|
|
1368
1370
|
});
|
|
1369
1371
|
}
|
|
1370
|
-
if (dataFlowSlicesFile &&
|
|
1372
|
+
if (dataFlowSlicesFile && safeExistsSync(dataFlowSlicesFile)) {
|
|
1371
1373
|
bomJson.annotations.push({
|
|
1372
1374
|
subjects: [bomJson.serialNumber],
|
|
1373
1375
|
annotator: { component: bomJson.metadata.tools.components[0] },
|
|
@@ -1375,7 +1377,7 @@ export function createEvinseFile(sliceArtefacts, options) {
|
|
|
1375
1377
|
text: fs.readFileSync(dataFlowSlicesFile, "utf8"),
|
|
1376
1378
|
});
|
|
1377
1379
|
}
|
|
1378
|
-
if (reachablesSlicesFile &&
|
|
1380
|
+
if (reachablesSlicesFile && safeExistsSync(reachablesSlicesFile)) {
|
|
1379
1381
|
bomJson.annotations.push({
|
|
1380
1382
|
subjects: [bomJson.serialNumber],
|
|
1381
1383
|
annotator: { component: bomJson.metadata.tools.components[0] },
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Buffer } from "node:buffer";
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
-
import { existsSync } from "node:fs";
|
|
4
3
|
import { arch, homedir } from "node:os";
|
|
5
4
|
import { delimiter, dirname, join } from "node:path";
|
|
6
5
|
import process from "node:process";
|
|
@@ -23,18 +22,19 @@ import {
|
|
|
23
22
|
getTmpDir,
|
|
24
23
|
isMac,
|
|
25
24
|
isWin,
|
|
25
|
+
safeExistsSync,
|
|
26
26
|
} from "./utils.js";
|
|
27
27
|
|
|
28
28
|
export const GIT_COMMAND = process.env.GIT_CMD || "git";
|
|
29
29
|
|
|
30
30
|
// sdkman tool aliases
|
|
31
31
|
export const SDKMAN_JAVA_TOOL_ALIASES = {
|
|
32
|
-
java8: process.env.JAVA8_TOOL || "8.0.
|
|
32
|
+
java8: process.env.JAVA8_TOOL || "8.0.442-amzn", // Temurin no longer offers java8 :(
|
|
33
33
|
java11: process.env.JAVA11_TOOL || "11.0.25-tem",
|
|
34
34
|
java17: process.env.JAVA17_TOOL || "17.0.14-tem",
|
|
35
35
|
java21: process.env.JAVA21_TOOL || "21.0.6-tem",
|
|
36
36
|
java22: process.env.JAVA22_TOOL || "22.0.2-tem",
|
|
37
|
-
java23: process.env.JAVA23_TOOL || "23.0.
|
|
37
|
+
java23: process.env.JAVA23_TOOL || "23.0.2-tem",
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -421,9 +421,9 @@ const getCommandOutput = (cmd, dir, args) => {
|
|
|
421
421
|
export function isSdkmanAvailable() {
|
|
422
422
|
let isSdkmanSetup =
|
|
423
423
|
["SDKMAN_DIR", "SDKMAN_CANDIDATES_DIR"].filter(
|
|
424
|
-
(v) => process.env[v] &&
|
|
424
|
+
(v) => process.env[v] && safeExistsSync(process.env[v]),
|
|
425
425
|
).length >= 1;
|
|
426
|
-
if (!isSdkmanSetup &&
|
|
426
|
+
if (!isSdkmanSetup && safeExistsSync(join(homedir(), ".sdkman", "bin"))) {
|
|
427
427
|
process.env.SDKMAN_DIR = join(homedir(), ".sdkman");
|
|
428
428
|
process.env.SDKMAN_CANDIDATES_DIR = join(
|
|
429
429
|
homedir(),
|
|
@@ -462,12 +462,12 @@ export function isSdkmanToolAvailable(toolType, toolName) {
|
|
|
462
462
|
toolName = getSdkmanToolFullname(toolName);
|
|
463
463
|
let isToolAvailable =
|
|
464
464
|
process.env.SDKMAN_CANDIDATES_DIR &&
|
|
465
|
-
|
|
465
|
+
safeExistsSync(
|
|
466
466
|
join(process.env.SDKMAN_CANDIDATES_DIR, toolType, toolName, "bin"),
|
|
467
467
|
);
|
|
468
468
|
if (
|
|
469
469
|
!isToolAvailable &&
|
|
470
|
-
|
|
470
|
+
safeExistsSync(
|
|
471
471
|
join(homedir(), ".sdkman", "candidates", toolType, toolName, "bin"),
|
|
472
472
|
)
|
|
473
473
|
) {
|
|
@@ -549,7 +549,7 @@ export function installSdkmanTool(toolType, toolName) {
|
|
|
549
549
|
);
|
|
550
550
|
} else if (
|
|
551
551
|
process.env.SDKMAN_CANDIDATES_DIR &&
|
|
552
|
-
|
|
552
|
+
safeExistsSync(join(process.env.SDKMAN_CANDIDATES_DIR, toolType, toolName))
|
|
553
553
|
) {
|
|
554
554
|
process.env[`${toolUpper}_HOME`] = join(
|
|
555
555
|
process.env.SDKMAN_CANDIDATES_DIR,
|
|
@@ -740,7 +740,7 @@ export function bundleInstallWithDocker(rubyVersion, cdxgenGemHome, filePath) {
|
|
|
740
740
|
if (result.error || result.status !== 0) {
|
|
741
741
|
return false;
|
|
742
742
|
}
|
|
743
|
-
if (
|
|
743
|
+
if (safeExistsSync(join(filePath, "Gemfile.lock"))) {
|
|
744
744
|
console.log(
|
|
745
745
|
"Gemfile.lock was generated successfully. Thank you for trying this feature!",
|
|
746
746
|
);
|
|
@@ -763,7 +763,7 @@ export function installRubyVersion(rubyVersion, filePath) {
|
|
|
763
763
|
return { fullToolBinDir: undefined, status: true };
|
|
764
764
|
}
|
|
765
765
|
const fullToolBinDir = rubyVersionDir(rubyVersion);
|
|
766
|
-
if (
|
|
766
|
+
if (safeExistsSync(fullToolBinDir)) {
|
|
767
767
|
const result = spawnSync(
|
|
768
768
|
process.env.RBENV_CMD || "rbenv",
|
|
769
769
|
["local", rubyVersion],
|
|
@@ -861,7 +861,7 @@ export function installRubyBundler(rubyVersion, bundlerVersion) {
|
|
|
861
861
|
bundlerWarningShown = true;
|
|
862
862
|
}
|
|
863
863
|
const fullToolBinDir = rubyVersionDir(rubyVersion);
|
|
864
|
-
if (
|
|
864
|
+
if (safeExistsSync(fullToolBinDir)) {
|
|
865
865
|
const gemInstallArgs = ["install", "bundler"];
|
|
866
866
|
if (bundlerVersion) {
|
|
867
867
|
gemInstallArgs.push("-v");
|
|
@@ -1038,7 +1038,7 @@ export function performBundleInstall(
|
|
|
1038
1038
|
"This project requires a specific version of RubyGems. To do this, the existing version must be uninstalled followed by installing the required version. `sudo gem uninstall rubygems-update -v <existing version>` and then `sudo gem install rubygems-update -v <required version>`.",
|
|
1039
1039
|
);
|
|
1040
1040
|
rubyVersionWarningShown = true;
|
|
1041
|
-
if (
|
|
1041
|
+
if (safeExistsSync(gemFileLock)) {
|
|
1042
1042
|
console.log("Run `bundle install` command to troubleshoot the build.");
|
|
1043
1043
|
} else {
|
|
1044
1044
|
console.log(
|
|
@@ -41,7 +41,7 @@ test("tools tests", () => {
|
|
|
41
41
|
test("sdkman tests", () => {
|
|
42
42
|
if (process.env?.SDKMAN_VERSION) {
|
|
43
43
|
expect(isSdkmanAvailable()).toBeTruthy();
|
|
44
|
-
expect(isSdkmanToolAvailable("java", "23.0.
|
|
44
|
+
expect(isSdkmanToolAvailable("java", "23.0.2-tem")).toBeTruthy();
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
|