Skip to content

Commit

Permalink
Add dependency tree for paket.lock files (#639)
Browse files Browse the repository at this point in the history
* feat: Dependency tree for paket.lock files

Signed-off-by: Robert Liias <44269772+robaliias@users.noreply.github.com>

* Fix linter errors

Signed-off-by: Robert Liias <44269772+robaliias@users.noreply.github.com>

---------

Signed-off-by: Robert Liias <44269772+robaliias@users.noreply.github.com>
  • Loading branch information
robaliias authored Oct 15, 2023
1 parent 62fcf72 commit 812725a
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
- Gradle
- Scala SBT
- Python (requirements.txt, setup.py, pyproject.toml, poetry.lock)
- csharp (projects.assets.json)
- .NET (project.assets.json, paket.lock)
- Go (go.mod)

## Environment variables
Expand Down
7 changes: 6 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4144,10 +4144,15 @@ export const createCsharpBom = async (
console.log(`Parsing ${f}`);
}
pkgData = readFileSync(f, { encoding: "utf-8" });
const dlist = await parsePaketLockData(pkgData);
const results = await parsePaketLockData(pkgData);
const dlist = results.pkgList;
const deps = results.dependenciesList;
if (dlist && dlist.length) {
pkgList = pkgList.concat(dlist);
}
if (deps && deps.length) {
dependencies = dependencies.concat(deps);
}
}
}
if (!parentComponent) {
Expand Down
94 changes: 80 additions & 14 deletions utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4889,24 +4889,90 @@ export const parseCsPkgLockData = async function (csLockData) {

export const parsePaketLockData = async function (paketLockData) {
const pkgList = [];
const dependenciesList = [];
const dependenciesMap = {};
const pkgNameVersionMap = {};
let group = null;
let pkg = null;
if (!paketLockData) {
return pkgList;
return { pkgList, dependenciesList };
}
const pkgRegex = /\s+([a-zA-Z0-9-.]+) \(((?=.*?\.)[a-zA-Z0-9-.]+)\)/g;
for (const [, name, version] of paketLockData.matchAll(pkgRegex)) {
const purl = decodeURIComponent(
new PackageURL("nuget", "", name, version, null, null).toString()
);
pkg = {
group: "",
name: name,
version: version,
purl: purl
};
pkgList.push(pkg);

const packages = paketLockData.split("\n");
const groupRegex = /^GROUP\s(\S*)$/;
const pkgRegex = /^\s{4}([\w.-]+) \(((?=.*?\.)[\w.-]+)\)/;
const depRegex = /^\s{6}([\w.-]+) \([><= \w.-]+\)/;

// Gather all packages
packages.forEach((l) => {
let match = l.match(groupRegex);
if (match) {
group = match[1];
return;
}

match = l.match(pkgRegex);
if (match) {
const name = match[1];
const version = match[2];
const purl = decodeURIComponent(
new PackageURL("nuget", "", name, version, null, null).toString()
);
pkg = {
group: "",
name: name,
version: version,
purl: purl
};
pkgList.push(pkg);
dependenciesMap[purl] = new Set();
pkgNameVersionMap[name + group] = version;
}
});

let purl = null;
group = null;

// Construct the dependency tree
packages.forEach((l) => {
let match = l.match(groupRegex);
if (match) {
group = match[1];
return;
}

match = l.match(pkgRegex);
if (match) {
const pkgName = match[1];
const pkgVersion = match[2];
purl = decodeURIComponent(
new PackageURL("nuget", "", pkgName, pkgVersion, null, null).toString()
);
return;
}

match = l.match(depRegex);
if (match) {
const depName = match[1];
const depVersion = pkgNameVersionMap[depName + group];
const dpurl = decodeURIComponent(
new PackageURL("nuget", "", depName, depVersion, null, null).toString()
);
dependenciesMap[purl].add(dpurl);
}
});

for (const ref in dependenciesMap) {
dependenciesList.push({
ref: ref,
dependsOn: Array.from(dependenciesMap[ref])
});
}
return pkgList;

return {
pkgList,
dependenciesList
};
};

/**
Expand Down
17 changes: 14 additions & 3 deletions utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1299,17 +1299,28 @@ test("parse packages.lock.json", async () => {
});

test("parse paket.lock", async () => {
expect(await parsePaketLockData(null)).toEqual([]);
expect(await parsePaketLockData(null)).toEqual({
pkgList: [],
dependenciesList: []
});
const dep_list = await parsePaketLockData(
readFileSync("./test/data/paket.lock", { encoding: "utf-8" })
);
expect(dep_list.length).toEqual(13);
expect(dep_list[0]).toEqual({
expect(dep_list.pkgList.length).toEqual(13);
expect(dep_list.pkgList[0]).toEqual({
group: "",
name: "0x53A.ReferenceAssemblies.Paket",
version: "0.2",
purl: "pkg:nuget/0x53A.ReferenceAssemblies.Paket@0.2"
});
expect(dep_list.dependenciesList.length).toEqual(13);
expect(dep_list.dependenciesList[2]).toEqual({
ref: "pkg:nuget/FSharp.Compiler.Service@17.0.1",
dependsOn: [
"pkg:nuget/System.Collections.Immutable@1.4",
"pkg:nuget/System.Reflection.Metadata@1.5"
]
});
});

test("parse .net cs proj", async () => {
Expand Down

0 comments on commit 812725a

Please sign in to comment.