snyk-nuget-plugin
Advanced tools
Comparing version 1.5.0 to 1.5.1
@@ -0,6 +1,23 @@ | ||
'use strict'; | ||
var Dependency = require('../dependency'); | ||
var debug = require('debug')('snyk'); | ||
var _ = require('lodash'); | ||
// TODO: any convention for global vars? (gFreqDeps) | ||
let 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; | ||
freqDeps.dependencies = {}; | ||
} | ||
function convertFromPathSyntax(path) { | ||
var name = path.split('/').join('@'); // posix | ||
let name = path.split('/').join('@'); // posix | ||
name = name.split('\\').join('@'); // windows | ||
@@ -11,71 +28,131 @@ return name; | ||
function collectFlatList(targetObj) { | ||
var names = Object.keys(targetObj); | ||
var libs = names.map(function (name) { | ||
const names = Object.keys(targetObj); | ||
return names.map(function (name) { | ||
name = convertFromPathSyntax(name); | ||
return name; | ||
}); | ||
return libs; | ||
} | ||
function registerDependency(packageTree, resolvedName) { | ||
var name = resolvedName.split('@')[0]; | ||
var version = resolvedName.split('@')[1]; | ||
packageTree.dependencies[name] = | ||
packageTree.dependencies[name] || new Dependency(name, version); | ||
debug(resolvedName); | ||
function buildTreeRecursive(targetDeps, depName, parent, treeDepth) { | ||
const MAX_TREE_DEPTH = 40; | ||
if (treeDepth > MAX_TREE_DEPTH) { | ||
throw new Error('The depth of the tree is too big.'); | ||
} | ||
let depResolvedName = ''; | ||
let originalDepKey = ''; | ||
debug(`${treeDepth}: Looking for '${depName}'`); | ||
const depNameLowerCase = depName.toLowerCase(); | ||
const exists = Object.keys(targetDeps).some(function (currentDep) { | ||
let currentResolvedName = convertFromPathSyntax(currentDep); | ||
if (currentResolvedName.split('@')[0].toLowerCase() === depNameLowerCase) { | ||
depResolvedName = currentResolvedName; | ||
originalDepKey = currentDep; | ||
debug(`${treeDepth}: Found '${currentDep}'`); | ||
return true; | ||
} | ||
}); | ||
if (!exists) { | ||
debug(`Failed to find '${depName}'`); | ||
return; | ||
} | ||
const depVersion = depResolvedName.split('@')[1]; | ||
parent.dependencies[depName] = | ||
parent.dependencies[depName] || new Dependency(depName, depVersion); | ||
Object.keys(targetDeps[originalDepKey].dependencies || {}).forEach( | ||
function (currentDep) { | ||
if (currentDep in freqDeps) { | ||
if (freqDeps[currentDep] != false) { | ||
return; | ||
} | ||
buildTreeRecursive(targetDeps, | ||
currentDep, | ||
freqDeps, | ||
0); | ||
freqDeps[currentDep] = true; | ||
}else { | ||
buildTreeRecursive(targetDeps, | ||
currentDep, | ||
parent.dependencies[depName], | ||
treeDepth + 1); | ||
} | ||
}); | ||
} | ||
function getFrameworkObjToRun(manifest) { | ||
const frameworks = _.get(manifest, 'project.frameworks') | ||
if (!frameworks) { | ||
throw new Error('No frameworks were found in project.assets.json'); | ||
} | ||
if (_.isEmpty(frameworks)) { | ||
throw new Error('0 frameworks were found in project.assets.json'); | ||
} | ||
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 frameworks[selectedFrameworkKey]; | ||
} | ||
function getTargetObjToRun(manifest) { | ||
if (!manifest.targets) { | ||
throw new Error('No targets were found in project.assets.json'); | ||
} | ||
if (_.isEmpty(manifest.targets)) { | ||
throw new Error('0 targets were found in project.assets.json'); | ||
} | ||
debug(`Available targets: '${Object.keys(manifest.targets)}'`); | ||
let 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 parse(fileContent, packageTree) { | ||
var libraries = {}; | ||
var manifest = JSON.parse(fileContent); | ||
if (manifest.project) { | ||
const manifest = JSON.parse(fileContent); | ||
if (!manifest.project) { | ||
throw new Error('Project field was not found in project.assets.json'); | ||
} | ||
if (manifest.project.version) { | ||
packageTree.version = manifest.project.version; | ||
} | ||
var targets = Object | ||
.keys(manifest.targets) | ||
.map(function (key) { | ||
return manifest.targets[key]; | ||
}); | ||
collectFlatList(manifest.libraries).forEach(function (rawName) { | ||
registerDependency(packageTree, rawName); | ||
}); | ||
const selectedFrameworkObj = getFrameworkObjToRun(manifest); | ||
const selectedTargetObj = getTargetObjToRun(manifest); | ||
targets.forEach(function (targetObj) { | ||
collectFlatList(targetObj).forEach(function (rawName) { | ||
registerDependency(packageTree, rawName); | ||
}); | ||
initFreqDepsDict(); | ||
Object.keys(targetObj).forEach(function (key) { | ||
var resolvedName = convertFromPathSyntax(key); | ||
var depName = resolvedName.split('@')[0]; | ||
var dependency = packageTree.dependencies[depName]; | ||
var depManifest = targetObj[key]; | ||
Object.keys(depManifest.dependencies || {}).forEach(function (key) { | ||
try { | ||
var version = depManifest.dependencies[key]; | ||
var lookup = key + '@' + version; | ||
if (lookup.toLowerCase().indexOf('system.') === 0) { | ||
// skip system packages in tree | ||
return; | ||
} | ||
// a sub-dependency should never take priority over a regular one | ||
// even within the subtree | ||
if (packageTree.dependencies[key]) { | ||
dependency.dependencies[key] = | ||
new Dependency(key, packageTree.dependencies[key].version); | ||
} else { | ||
dependency.dependencies[key] = new Dependency(key, version); | ||
} | ||
} | ||
catch (err) { | ||
console.log(err); | ||
} | ||
}) | ||
}) | ||
const directDependencies = collectFlatList(selectedFrameworkObj.dependencies); | ||
debug(`directDependencies: '${directDependencies}'`); | ||
directDependencies.forEach(function (directDep) { | ||
debug(`First order dep: '${directDep}'`); | ||
buildTreeRecursive(selectedTargetObj, directDep, packageTree, 0); | ||
}); | ||
if (!_.isEmpty(freqDeps.dependencies)) { | ||
packageTree.dependencies['freqSystemDependencies'] = freqDeps.dependencies; | ||
} | ||
// to disconnect the object references inside the tree | ||
// JSON parse/stringify is used | ||
var pathedTree = JSON.parse(JSON.stringify(packageTree.dependencies)); | ||
let pathedTree = JSON.parse(JSON.stringify(packageTree.dependencies)); | ||
packageTree.dependencies = pathedTree; | ||
@@ -82,0 +159,0 @@ } |
@@ -10,3 +10,3 @@ var fs = require('fs'); | ||
var projectJsonFormatParser = require('./formats/dotnet-core-parser'); | ||
var determineDotnetVersion = require('./proj-parser'); | ||
var determineDotnetVersions = require('./proj-parser'); | ||
@@ -41,3 +41,3 @@ function determineManifestType (filename) { | ||
var fileContent; | ||
var dotnetVersion; | ||
var dotnetVersions; | ||
var fileContentPath = path.resolve(root || '.', targetFile || '.'); | ||
@@ -53,6 +53,6 @@ var projectRootFolder = path.resolve(fileContentPath, '../../'); | ||
if (manifestType === 'dotnet-core') { | ||
dotnetVersion = determineDotnetVersion(projectRootFolder); | ||
dotnetVersions = determineDotnetVersions(projectRootFolder); | ||
} else { | ||
// .csproj is in the same directory as packages.config or project.json | ||
dotnetVersion = determineDotnetVersion( | ||
dotnetVersions = determineDotnetVersions( | ||
path.resolve(fileContentPath, '../')); | ||
@@ -62,3 +62,3 @@ } | ||
debug('Loaded ' + targetFile + ' with manifest type ' | ||
+ manifestType + ' for .NET version ' + dotnetVersion); | ||
+ manifestType + ' for .NET version ' + dotnetVersions); | ||
} | ||
@@ -181,4 +181,3 @@ catch (error) { | ||
} | ||
}) | ||
.then(function fetchNugetInformationFromPackages() { | ||
}).then(function fetchNugetInformationFromPackages() { | ||
var nuspecParserChain = []; | ||
@@ -191,3 +190,3 @@ if (manifestType !== 'dotnet-core') { | ||
debug('...' + name); | ||
nuspecParserChain.push(parseNuspec(dep)); | ||
nuspecParserChain.push(parseNuspec(dep, dotnetVersions)); | ||
} | ||
@@ -194,0 +193,0 @@ } |
@@ -8,9 +8,12 @@ var zip = require('zip'); | ||
var Dependency = require('./dependency'); | ||
var _ = require('lodash'); | ||
function parseNuspec(library, sep) { | ||
const targetFrameworkRegex = /([.a-zA-Z]+)([.0-9]+)/; | ||
function parseNuspec(dep, targetFrameworks, sep) { | ||
var P = new Promise(function (resolve, reject) { | ||
var pathSep = sep || '.'; | ||
var nuspecPath = path.resolve( | ||
library.path, | ||
library.name + pathSep + library.version + '.nupkg'); | ||
dep.path, | ||
dep.name + pathSep + dep.version + '.nupkg'); | ||
var rawZipped; | ||
@@ -34,21 +37,39 @@ | ||
} else { | ||
var ownDependencies = []; | ||
(result.package.metadata || []).forEach(function (metadata) { | ||
(metadata.dependencies || []).forEach(function (rawDependency) { | ||
(rawDependency.group || []).forEach(function (group) { | ||
(group.dependency || []).forEach(function (dep) { | ||
var transitiveDependency = new Dependency(dep.$.id, dep.$.version); // jscs:ignore | ||
ownDependencies.push(transitiveDependency); | ||
}); | ||
}); | ||
(rawDependency.dependency || []).forEach(function (dep) { | ||
var transitiveDependency = | ||
new Dependency(dep.$.id, dep.$.version, null); | ||
ownDependencies.push(transitiveDependency); | ||
}); | ||
var ownDeps = []; | ||
// We are only going to check the first targetFramework we encounter | ||
// in the future we may want to support multiple, but only once | ||
// we have dependency version conflict resolution implemented | ||
// _(targetFrameworks).forEach(function (targetFramework) { | ||
_(result.package.metadata).forEach(function (metadata) { | ||
_(metadata.dependencies).forEach(function (rawDependency) { | ||
// Find and add target framework version specific dependencies | ||
const depsForTargetFramework = _(rawDependency.group) | ||
.filter(function (group) { | ||
return targetFrameworkRegex.test(group.$.targetFramework); | ||
}).map(function (group) { | ||
const parts = _.split(group.$.targetFramework, targetFrameworkRegex); // jscs:ignore | ||
return { | ||
framework: parts [1], | ||
version: parts[2], | ||
group: group, | ||
} | ||
}).orderBy(['framework', 'version'], ['asc', 'desc']) | ||
.find(function (group) { | ||
return targetFrameworks[0].framework === group.framework && | ||
targetFrameworks[0].version >= group.version; | ||
});// jscs:ignore validateIndentation | ||
if (depsForTargetFramework) { | ||
ownDeps = _.concat(ownDeps, | ||
extractDepsFromRaw(depsForTargetFramework.group.dependency)); | ||
} | ||
// Add the default dependencies | ||
ownDeps = _.concat(ownDeps, extractDepsFromRaw(rawDependency.dependency)); // jscs:ignore | ||
}); | ||
}); | ||
resolve({ | ||
name: library.name, | ||
children: ownDependencies.filter(function (dep) { | ||
name: dep.name, | ||
children: ownDeps.filter(function (dep) { | ||
return dep.name.indexOf('System.') !== 0; | ||
@@ -63,2 +84,11 @@ }), | ||
function extractDepsFromRaw(rawDependencies) { | ||
var deps = []; | ||
_.forEach(rawDependencies, function (dependency) { | ||
var dep = new Dependency(dependency.$.id, dependency.$.version); | ||
deps.push(dep); | ||
}); | ||
return deps; | ||
} | ||
module.exports = parseNuspec; |
@@ -7,3 +7,3 @@ const fs = require('fs'); | ||
function determineDotnetVersion(rootDir) { | ||
function determineDotnetVersions(rootDir) { | ||
debug('Looking for your .csproj file in ' + rootDir); | ||
@@ -53,3 +53,6 @@ const csprojPath = findFile(rootDir, /.*\.csproj$/); | ||
if (new RegExp(type + /\d.?\d(.?\d)?$/.source).test(version)) { | ||
return typeMapping[type] + version.split(type)[1]; | ||
return { | ||
framework: typeMapping[type], | ||
version: version.split(type)[1], | ||
}; | ||
} | ||
@@ -73,2 +76,2 @@ } | ||
module.exports = determineDotnetVersion; | ||
module.exports = determineDotnetVersions; |
@@ -1,1 +0,1 @@ | ||
{"name":"snyk-nuget-plugin","description":"![logo](https://res.cloudinary.com/snyk/image/upload/v1468845259/logo/snyk-dog.svg) ## Snyk: NuGet Plugin ***","main":"lib/index.js","scripts":{"lint":"jscs `find ./lib -name '*.js'` -v && jscs `find ./test -name '*.js'` -v","test":"npm run unit-test","test-windows":"tap -R spec test/*.test.js --timeout=120","unit-test":"tap `ls ./test/*.test.js` -R=spec","dev":"nodemon -x 'npm run unit-test'","semantic-release":"semantic-release pre && npm publish && semantic-release post"},"repository":{"type":"git","url":"https://github.com/snyk/snyk-nuget-plugin.git"},"keywords":["snyk","nuget"],"author":"snyk.io","license":"Apache-2.0","bugs":{"url":"https://github.com/snyk/snyk-nuget-plugin/issues"},"homepage":"https://github.com/snyk/snyk-nuget-plugin#readme","dependencies":{"debug":"^3.1.0","es6-promise":"^4.1.1","xml2js":"^0.4.17","zip":"^1.2.0","lodash":"^4.17.10"},"devDependencies":{"jscs":"^3.0.7","nodemon":"^1.12.1","semantic-release":"^8.2.0","tap":"^10.7.0","tap-only":"0.0.5"},"version":"1.5.0"} | ||
{"name":"snyk-nuget-plugin","description":"![logo](https://res.cloudinary.com/snyk/image/upload/v1468845259/logo/snyk-dog.svg) ## Snyk: NuGet Plugin ***","main":"lib/index.js","scripts":{"lint":"jscs `find ./lib -name '*.js'` -v && jscs `find ./test -name '*.js'` -v","test":"npm run unit-test","test-windows":"tap -R spec test/*.test.js --timeout=120","unit-test":"tap `ls ./test/*.test.js` -R=spec --timeout=120","dev":"nodemon -x 'npm run unit-test'","semantic-release":"semantic-release pre && npm publish && semantic-release post"},"repository":{"type":"git","url":"https://github.com/snyk/snyk-nuget-plugin.git"},"keywords":["snyk","nuget"],"author":"snyk.io","license":"Apache-2.0","bugs":{"url":"https://github.com/snyk/snyk-nuget-plugin/issues"},"homepage":"https://github.com/snyk/snyk-nuget-plugin#readme","dependencies":{"debug":"^3.1.0","es6-promise":"^4.1.1","xml2js":"^0.4.17","zip":"^1.2.0","lodash":"^4.17.10"},"devDependencies":{"jscs":"^3.0.7","nodemon":"^1.12.1","semantic-release":"^8.2.0","tap":"^10.7.0","tap-only":"0.0.5"},"version":"1.5.1"} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25507
633