UNPKG

snyk-nuget-plugin

Version:
183 lines 7.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parse = parse; const errors_1 = require("../../errors"); const debugModule = require("debug"); const _ = require("lodash"); const debug = debugModule('snyk'); const PACKAGE_DELIMITER = '@'; const freqDeps = {}; function initFreqDepsDict() { freqDeps['Microsoft.NETCore.Platforms'] = false; freqDeps['Microsoft.NETCore.Targets'] = false; freqDeps['System.Runtime'] = false; freqDeps['System.IO'] = false; freqDeps['System.Text.Encoding'] = false; freqDeps['System.Threading.Tasks'] = false; freqDeps['System.Reflection'] = false; freqDeps['System.Globalization'] = false; } function isScanned(nodes, pkg) { const node = nodes.find((elem) => elem.name === pkg.name && elem.version === pkg.version); return !!node; } function isFreqDep(packageName) { return packageName in freqDeps; } function pick(obj, keys) { const pickedObj = {}; Object.keys(obj).forEach((k) => { if (keys.includes(k)) { pickedObj[k] = obj[k]; } }); return pickedObj; } function convertFromPathSyntax(path) { let name = path.split('/').join('@'); // posix name = name.split('\\').join('@'); // windows return name; } function findPackage(targetDeps, depName) { debug(`Looking for ${depName}`); const depNameLowerCase = depName.toLowerCase(); for (const currentDep of Object.keys(targetDeps)) { const currentResolvedName = convertFromPathSyntax(currentDep); const [currentDepName, currentDepVersion] = currentResolvedName.split(PACKAGE_DELIMITER); if (currentDepName.toLowerCase() === depNameLowerCase) { return { name: depName, version: currentDepVersion, dependencies: targetDeps[currentDep].dependencies, }; } } debug(`Failed to find ${depName}`); return undefined; } function constructTree(roots, nodes, links) { const treeMap = {}; for (const node of nodes) { const { name, version } = node; const treeNode = { name, version, dependencies: {} }; treeMap[name] = treeNode; } for (const link of links) { const parentName = link.from.name; const childName = link.to.name; const parentNode = treeMap[parentName]; const childNode = treeMap[childName]; if (!isFreqDep(childName)) { parentNode.dependencies[childName] = { ...childNode, }; } } const tree = pick(treeMap, roots); const freqSysDeps = pick(treeMap, Object.keys(freqDeps)); if (Object.keys(freqSysDeps).length > 0) { tree['freqSystemDependencies'] = { name: 'freqSystemDependencies', version: '0.0.0', dependencies: freqSysDeps, }; } return tree; } function collectFlatList(targetObj) { const names = Object.keys(targetObj); return names.map((name) => { name = convertFromPathSyntax(name); return name; }); } function addPackageDepLinks(links, pkg) { if (pkg && pkg.dependencies) { const from = { name: pkg.name, version: pkg.version }; for (const name of Object.keys(pkg.dependencies)) { const to = { name, version: pkg.dependencies[name] }; links.push({ from, to }); } } } function buildBfsTree(targetDeps, roots) { let queue = [...roots]; const nodes = []; const links = []; while (queue.length > 0) { const dep = queue.shift(); const foundPackage = findPackage(targetDeps, dep); if (foundPackage && !isScanned(nodes, foundPackage)) { nodes.push(foundPackage); if (foundPackage.dependencies) { addPackageDepLinks(links, foundPackage); queue = queue.concat(Object.keys(foundPackage.dependencies)); } } } return constructTree(roots, nodes, links); } function getFrameworkToRun(manifest) { const frameworks = manifest?.project?.frameworks; debug(`Available frameworks: '${Object.keys(frameworks)}'`); // not yet supporting multiple frameworks in the same assets file -> // taking only the first 1 const selectedFrameworkKey = Object.keys(frameworks)[0]; debug(`Selected framework: '${selectedFrameworkKey}'`); return selectedFrameworkKey; } function getTargetObjToRun(manifest) { debug(`Available targets: '${Object.keys(manifest.targets)}'`); const selectedTargetKey = Object.keys(manifest.targets)[0]; debug(`Selected target: '${selectedTargetKey}'`); // not yet supporting multiple targets in the same assets file -> // taking only the first 1 return manifest.targets[selectedTargetKey]; } function validateManifest(manifest) { if (!manifest.project) { throw new errors_1.InvalidManifestError('Project field was not found in project.assets.json'); } if (!manifest.project.frameworks) { throw new errors_1.InvalidManifestError('No frameworks were found in project.assets.json'); } if (!manifest.project.frameworks || Object.keys(manifest.project.frameworks).length === 0) { throw new errors_1.InvalidManifestError('0 frameworks were found in project.assets.json'); } if (!manifest.targets) { throw new errors_1.InvalidManifestError('No targets were found in project.assets.json'); } if (!manifest.targets || Object.keys(manifest.targets).length === 0) { throw new errors_1.InvalidManifestError('0 targets were found in project.assets.json'); } } function parse(tree, manifest) { debug('Trying to parse dot-net-cli manifest'); validateManifest(manifest); if (manifest.project.version) { tree.version = manifest.project.version; } // If a targetFramework was not found in the proj file, we will extract it from the lock file // OR // If the targetFramework is undefined, extract it from the lock file // Fix for https://github.com/snyk/snyk-nuget-plugin/issues/75 if (!tree.meta.targetFramework || manifest.project.frameworks[tree.meta.targetFramework] === undefined) { tree.meta.targetFramework = getFrameworkToRun(manifest); } const selectedFrameworkObj = manifest.project.frameworks[tree.meta.targetFramework]; // We currently ignore the found targetFramework when looking for target dependencies const selectedTargetObj = getTargetObjToRun(manifest); initFreqDepsDict(); const directDependencies = selectedFrameworkObj.dependencies ? collectFlatList(selectedFrameworkObj.dependencies) : []; debug(`directDependencies: '${directDependencies}'`); tree.dependencies = buildBfsTree(selectedTargetObj, directDependencies); // to disconnect the object references inside the tree // cloneDeep is used here tree.dependencies = _.cloneDeep(tree.dependencies); return tree; } //# sourceMappingURL=dotnet-core-parser.js.map