Skip to content

Commit

Permalink
Improve root dependency list for Gemfile.lock (#1409)
Browse files Browse the repository at this point in the history
Signed-off-by: Prabhu Subramanian <[email protected]>
  • Loading branch information
prabhu authored Oct 8, 2024
1 parent 49d8e6a commit f546437
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 14 deletions.
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cyclonedx/cdxgen",
"version": "10.10.3",
"version": "10.10.4",
"exports": "./lib/cli/index.js",
"compilerOptions": {
"allowJs": true,
Expand Down
2 changes: 1 addition & 1 deletion jsr.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cyclonedx/cdxgen",
"version": "10.10.3",
"version": "10.10.4",
"exports": "./lib/cli/index.js",
"include": ["*.js", "lib/**", "bin/**", "data/**", "types/**"],
"exclude": [
Expand Down
19 changes: 16 additions & 3 deletions lib/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5517,7 +5517,7 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
const dependenciesMap = {};
const pkgVersionMap = {};
const pkgVersionPlatformMap = {};
const rootList = [];
const pkgNameRef = {};
if (!gemLockData) {
return pkgList;
}
Expand Down Expand Up @@ -5577,6 +5577,9 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
let lastBranch = undefined;
let lastTag = undefined;
let lastParentPlatform = undefined;
// Dependencies block would begin with DEPENDENCIES
let dependenciesBlock = false;
const rootList = [];
// In the second pass, we use the space in the prefix to figure out the dependency tree
gemLockData.split("\n").forEach((l) => {
l = l.replace("\r", "");
Expand All @@ -5596,6 +5599,11 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
lastTag = l.trim().split(" ")[1];
}
if (l.trim() === l.trim().toUpperCase()) {
if (l.trim() === "DEPENDENCIES") {
dependenciesBlock = true;
return;
}
dependenciesBlock = false;
specsFound = false;
lastRemote = undefined;
lastRevision = undefined;
Expand Down Expand Up @@ -5670,7 +5678,6 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
const bomRef = decodeURIComponent(purlString);
if (level === 1) {
lastParent = bomRef;
rootList.push(bomRef);
}
const properties = [
{
Expand Down Expand Up @@ -5737,11 +5744,17 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
if (!dependenciesMap[bomRef]) {
dependenciesMap[bomRef] = new Set();
}
pkgNameRef[name] = bomRef;
// Allow duplicate packages if the version number includes platform
if (!pkgnames[purlString]) {
pkgList.push(apkg);
pkgnames[purlString] = true;
}
} else if (dependenciesBlock) {
const rootDepName = l.trim().split(" ")[0].replace("!", "");
if (pkgNameRef[rootDepName]) {
rootList.push(pkgNameRef[rootDepName]);
}
}
});
for (const k of Object.keys(dependenciesMap)) {
Expand All @@ -5752,7 +5765,7 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
}
if (FETCH_LICENSE) {
pkgList = await getRubyGemsMetadata(pkgList);
return { pkgList, dependenciesList };
return { pkgList, dependenciesList, rootList };
}
return { pkgList, dependenciesList, rootList };
}
Expand Down
6 changes: 6 additions & 0 deletions lib/helpers/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3863,6 +3863,7 @@ test("parseGemfileLockData", async () => {
"./test/data/Gemfile.lock",
);
expect(retMap.pkgList.length).toEqual(140);
expect(retMap.rootList.length).toEqual(42);
expect(retMap.dependenciesList.length).toEqual(140);
expect(retMap.pkgList[0]).toEqual({
name: "actioncable",
Expand Down Expand Up @@ -3895,30 +3896,35 @@ test("parseGemfileLockData", async () => {
"./test/data/Gemfile1.lock",
);
expect(retMap.pkgList.length).toEqual(36);
expect(retMap.rootList.length).toEqual(2);
expect(retMap.dependenciesList.length).toEqual(36);
retMap = await parseGemfileLockData(
readFileSync("./test/data/Gemfile2.lock", { encoding: "utf-8" }),
"./test/data/Gemfile2.lock",
);
expect(retMap.pkgList.length).toEqual(89);
expect(retMap.rootList.length).toEqual(2);
expect(retMap.dependenciesList.length).toEqual(89);
retMap = await parseGemfileLockData(
readFileSync("./test/data/Gemfile4.lock", { encoding: "utf-8" }),
"./test/data/Gemfile4.lock",
);
expect(retMap.pkgList.length).toEqual(182);
expect(retMap.rootList.length).toEqual(78);
expect(retMap.dependenciesList.length).toEqual(182);
retMap = await parseGemfileLockData(
readFileSync("./test/data/Gemfile5.lock", { encoding: "utf-8" }),
"./test/data/Gemfile5.lock",
);
expect(retMap.pkgList.length).toEqual(43);
expect(retMap.rootList.length).toEqual(11);
expect(retMap.dependenciesList.length).toEqual(43);
retMap = await parseGemfileLockData(
readFileSync("./test/data/Gemfile6.lock", { encoding: "utf-8" }),
"./test/data/Gemfile6.lock",
);
expect(retMap.pkgList.length).toEqual(139);
expect(retMap.rootList.length).toEqual(22);
expect(retMap.dependenciesList.length).toEqual(139);
});

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cyclonedx/cdxgen",
"version": "10.10.3",
"version": "10.10.4",
"description": "Creates CycloneDX Software Bill of Materials (SBOM) from source or container image",
"homepage": "http://github.com/cyclonedx/cdxgen",
"author": "Prabhu Subramanian <[email protected]>",
Expand Down
7 changes: 0 additions & 7 deletions types/lib/helpers/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -584,13 +584,6 @@ export function parseGemspecData(gemspecData: string): Promise<any[]>;
* @param {string} lockFile Lock file
*/
export function parseGemfileLockData(gemLockData: object, lockFile: string): Promise<any[] | {
pkgList: any[];
dependenciesList: {
ref: string;
dependsOn: any[];
}[];
rootList?: undefined;
} | {
pkgList: any[];
dependenciesList: {
ref: string;
Expand Down
2 changes: 1 addition & 1 deletion types/lib/helpers/utils.d.ts.map

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

0 comments on commit f546437

Please sign in to comment.