snyk-mvn-plugin
Version:
Snyk CLI Maven plugin
152 lines • 6.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createDepGraphFromArchive = createDepGraphFromArchive;
exports.createDepGraphFromArchives = createDepGraphFromArchives;
exports.isArchive = isArchive;
exports.findArchives = findArchives;
const dep_graph_1 = require("@snyk/dep-graph");
const path = require("path");
const crypto = require("crypto");
const fs = require("fs");
const glob = require("glob");
const debugLib = require("debug");
const search_1 = require("./search");
const fingerprint_1 = require("./fingerprint");
const debug = debugLib('snyk-mvn-plugin');
const ALGORITHM = 'sha1';
const DIGEST = 'hex';
function getSha1(buf) {
return crypto.createHash(ALGORITHM).update(buf).digest(DIGEST);
}
function getHash(buf, algorithm) {
return crypto.createHash(algorithm).update(buf).digest(DIGEST);
}
async function getMavenPackages(targetPath, snykHttpClient) {
const contents = fs.readFileSync(targetPath);
const sha1 = getSha1(contents);
return (0, search_1.getMavenPackageInfo)(sha1, targetPath, snykHttpClient);
}
async function getDependenciesWithPaths(paths, snykHttpClient) {
let dependencies = [];
for (const p of paths) {
try {
const mavenPackages = await getMavenPackages(p, snykHttpClient);
const packagesWithPaths = mavenPackages.map((pkg) => ({
...pkg,
archivePath: p,
}));
dependencies = dependencies.concat(packagesWithPaths);
}
catch (err) {
// log error and continue with other paths
if (err instanceof Error) {
console.error(`Failed to get maven dependency for '${p}'.`, err.message);
}
}
}
return dependencies;
}
async function createDepGraphFromArchive(root, targetPath, snykHttpClient, fingerprintOptions) {
try {
return await createDepGraphFromArchives(root, [targetPath], snykHttpClient, fingerprintOptions);
}
catch (err) {
const msg = `There was a problem generating a dep-graph for '${targetPath}'.`;
debug(msg, err);
if (err instanceof Error) {
throw new Error(msg + ' ' + err.message);
}
throw new Error(msg);
}
}
async function createDepGraphFromArchives(root, archivePaths, snykHttpClient, fingerprintOptions) {
if (!snykHttpClient) {
throw new Error('No HTTP client provided!');
}
try {
const dependencies = await getDependenciesWithPaths(archivePaths, snykHttpClient);
if (!dependencies.length) {
throw new Error(`No Maven artifacts found!`);
}
debug(`Creating dep-graph from ${JSON.stringify(dependencies)}`);
const rootDependency = getRootDependency(root);
const rootPkg = {
name: `${rootDependency.groupId}:${rootDependency.artifactId}`,
version: rootDependency.version,
};
const builder = new dep_graph_1.DepGraphBuilder({ name: 'maven' }, rootPkg);
for (const dependency of dependencies) {
const nodeId = `${dependency.groupId}:${dependency.artifactId}@${dependency.version}`;
// Create package info
const pkgInfo = {
name: `${dependency.groupId}:${dependency.artifactId}`,
version: dependency.version,
};
// Generate fingerprint data if fingerprinting is enabled
if (fingerprintOptions?.enabled) {
try {
const archiveContents = fs.readFileSync(dependency.archivePath);
const hash = getHash(archiveContents, fingerprintOptions.algorithm);
const fingerprintData = {
hash,
algorithm: fingerprintOptions.algorithm,
filePath: dependency.archivePath,
fileSize: archiveContents.length,
processingTime: 0, // Not tracking timing for archive files
};
debug(`Generated fingerprint for ${dependency.archivePath}: ${hash}`);
pkgInfo.purl = (0, fingerprint_1.createMavenPurlWithChecksum)(dependency.groupId, dependency.artifactId, dependency.version, fingerprintData);
}
catch (err) {
debug(`Failed to generate fingerprint for ${dependency.archivePath}:`, err);
}
}
builder.addPkgNode(pkgInfo, nodeId);
builder.connectDep(builder.rootNodeId, nodeId);
}
const depGraph = builder.build();
debug(`Created dep-graph ${JSON.stringify(depGraph.toJSON())}`);
return depGraph;
}
catch (err) {
const msg = `Detected supported file(s) in '${root}', but there was a problem generating a dep-graph.`;
debug(msg, err);
if (err instanceof Error) {
throw new Error(msg + ' ' + err.message);
}
throw new Error(msg);
}
}
function isArchive(file) {
return !!file.match(/\.(([jwa]ar)|(zip))$/);
}
function findArchives(targetPath) {
const stats = fs.statSync(targetPath);
const dir = stats.isFile() ? path.dirname(targetPath) : targetPath;
return glob.sync(`${dir}/**/*.@(jar|war|aar|zip)`);
}
function getRootDependency(root, targetFile) {
let groupId;
if (targetFile) {
groupId = path.dirname(targetFile);
if (groupId === '.') {
// we are in directory of the jar
groupId = path.basename(path.resolve(root));
}
}
else {
// take root's parent directory base name
groupId = path.basename(path.dirname(path.resolve(root)));
}
// replace path separators with dots
groupId = groupId
.replace(/\//g, '.') // *inx
.replace(/\\/g, '.') // windows
.replace(/^\./, ''); // remove any leading '.'
return {
groupId: groupId || 'root',
artifactId: path.basename(targetFile || root) || 'root',
version: '1.0.0',
};
}
//# sourceMappingURL=archive.js.map