Skip to content

Commit 4f292de

Browse files
authored
fix: remove .csproj support, add packages detection to imporve version, and addd tests for packages folder detection (#27)
1 parent 288756a commit 4f292de

File tree

15 files changed

+221
-114
lines changed

15 files changed

+221
-114
lines changed

lib/dependency.js

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,6 @@ Dependency.from = {
4444
result.versionSpec = manifest.$.version;
4545
return result;
4646
},
47-
csprojEntry: function (referenceItem) {
48-
debug('Extracting by hintPath ' + referenceItem.HintPath[0]);
49-
var sep = (
50-
/\//.exec(referenceItem.HintPath[0]) ||
51-
/\\/.exec(referenceItem.HintPath[0]))[0];
52-
var depLocalPath = referenceItem.HintPath[0]
53-
.split(sep).slice(2,3).join(sep);
54-
var packageInfo = Dependency.extractFromDotVersionNotation(depLocalPath);
55-
var name = packageInfo.name;
56-
var version = packageInfo.version;
57-
var result = new Dependency(
58-
name,
59-
version,
60-
'unknown'
61-
);
62-
return result;
63-
},
6447
};
6548

6649
module.exports = Dependency;

lib/find-folder.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ function findFolder (dir) {
1111
}
1212
return false;
1313
}
14-
};
14+
}
1515

1616
module.exports = findFolder;

lib/index.js

Lines changed: 31 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ function determineManifestType (filename) {
2020
case /packages.config$/.test(filename): {
2121
return 'packages.config';
2222
}
23-
case /.csproj$/.test(filename): {
24-
return '.csproj';
25-
}
2623
default: {
2724
throw new Error('Could not determine manifest type for ' + filename);
2825
}
@@ -117,57 +114,15 @@ module.exports = {
117114
});
118115
resolve(installedPackages);
119116
}
120-
})
121-
break;
122-
}
123-
case '.csproj': {
124-
debug('Trying to parse .csproj manifest');
125-
parseXML(fileContent, function scanCsprojContent(err, result) {
126-
if (err) {
127-
reject(err);
128-
} else {
129-
(result.Project.ItemGroup || []).forEach(function (itemGroup) {
130-
(itemGroup.Reference || []).forEach(function (referenceItem) {
131-
if (referenceItem.HintPath) {
132-
try {
133-
var installedDependency =
134-
Dependecy.from.csprojEntry(referenceItem);
135-
if (installedDependency.name.indexOf('System.') !== 0) {
136-
installedPackages.push(installedDependency);
137-
}
138-
}
139-
catch (err) {
140-
debug('Could not parse package name. Skipping');
141-
// gracefully continue
142-
}
143-
}
144-
});
145-
});
146-
}
147-
resolve(installedPackages);
148117
});
149118
break;
150119
}
151120
}
152121
}).then(function scanInstalled(installedPackages) {
153122
if (manifestType !== 'dotnet-core') {
154123
debug('Located ' + installedPackages.length + ' packages in manifest');
155-
function injectPath(dep) {
156-
dep.path = dep.localPath
157-
? path.resolve(
158-
packagesFolder,
159-
dep.localPath
160-
)
161-
: path.resolve(
162-
packagesFolder,
163-
dep.name + '.' + dep.version
164-
);
165-
if (dep.localPath) {
166-
delete dep.localPath;
167-
}
168-
}
169124
installedPackages.forEach(function (entry) {
170-
injectPath(entry);
125+
injectPath(entry, packagesFolder);
171126
flattendPackageList[entry.name] =
172127
flattendPackageList[entry.name] || entry;
173128
debug('Entry: ' + entry.name + ' -> ' + entry.path);
@@ -178,15 +133,24 @@ module.exports = {
178133
packagesFolder);
179134
fs.readdirSync(packagesFolder)
180135
.filter(function (name) {
181-
return name.slice(0, 7).toLowerCase() !== 'system.'
136+
return name.slice(0, 7).toLowerCase() !== 'system.';
182137
})
183138
.map(function (folderName) {
184139
return Dependecy.from.folderName(folderName);
185140
})
186141
.forEach(function (dep) {
187-
injectPath(dep);
188-
flattendPackageList[dep.name] =
189-
flattendPackageList[dep.name] || dep;
142+
injectPath(dep, packagesFolder);
143+
// only add a package from packages folder if version is different
144+
if (flattendPackageList[dep.name] &&
145+
flattendPackageList[dep.name].version !== dep.version) {
146+
// prefer found from packages folder (dep) over existing
147+
debug('For package ' + dep.name + ' the version ' +
148+
flattendPackageList[dep.name].version +
149+
' was extracted from manifest file.' +
150+
'\nWe are overwriting it with version ' + dep.version +
151+
' from the packages folder');
152+
flattendPackageList[dep.name] = dep;
153+
}
190154
});
191155
}
192156
catch (err) {
@@ -196,7 +160,7 @@ module.exports = {
196160
} else {
197161
debug('Located ' +
198162
Object.keys(tree.dependencies).length + 'packages in manifest');
199-
var sorted = {}
163+
var sorted = {};
200164
Object.keys(flattendPackageList).sort().forEach(function (key) {
201165
sorted[key] = flattendPackageList[key];
202166
});
@@ -245,7 +209,7 @@ module.exports = {
245209
requiredChild.version);
246210
transitiveDependency.versionSpec = requiredChild.version;
247211
}
248-
transitiveDependency.from = node.from.concat()
212+
transitiveDependency.from = node.from.concat();
249213
var transitiveChildren =
250214
(nuspecResolutions[transitiveDependency.name] &&
251215
nuspecResolutions[transitiveDependency.name].children) || [];
@@ -260,23 +224,33 @@ module.exports = {
260224
var _nugtKeyCount = Object.keys(nuspecResolutions).length;
261225
Object.keys(flattendPackageList).forEach(function (packageName) {
262226
tree.dependencies[packageName] =
263-
flattendPackageList[packageName].cloneShallow()
264-
})
227+
flattendPackageList[packageName].cloneShallow();
228+
});
265229
if (_nugtKeyCount > 0) {
266230
// local folders scanned, build list from .nuspec
267231
for (var key in nuspecResolutions) {
268232
var resolution = nuspecResolutions[key];
269233
var node = flattendPackageList[resolution.name].cloneShallow();
270-
node.from = tree.from.concat()
234+
node.from = tree.from.concat();
271235
buildTree(node, resolution.children, flattendPackageList);
272236
tree.dependencies[node.name] = node;
273237
}
274238
}
275239
return packageTree;
276240
})['catch'](function (err) {
277241
throw(err);
278-
})
242+
});
279243

280244
return job;
281245
},
282-
};
246+
};
247+
248+
function injectPath(dep, packagesFolder) {
249+
dep.path =
250+
dep.localPath ?
251+
path.resolve(packagesFolder, dep.localPath)
252+
: path.resolve(packagesFolder, dep.name + '.' + dep.version);
253+
if (dep.localPath) {
254+
delete dep.localPath;
255+
}
256+
}

lib/json-manifest-parser.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ function scanForDependencies(obj, deps) {
1818
version = version.toString();
1919
}
2020
deps[depName] = version;
21-
})
21+
});
2222
} else {
2323
scanForDependencies(obj[key], deps);
2424
}
@@ -32,8 +32,8 @@ module.exports = {
3232
var result = {};
3333
result.dependencies = scanForDependencies(rawContent, {});
3434
if (typeof rawContent.project === 'object') {
35-
var pData = rawContent.project
36-
var name = (pData.restore && pData.restore.projectName)
35+
var pData = rawContent.project;
36+
var name = (pData.restore && pData.restore.projectName);
3737
result.project = {
3838
version: pData.version || '0.0.0',
3939
};

lib/nuspec-parser.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var Dependency = require('./dependency');
88

99
function parseNuspec(library, sep) {
1010
var P = new Promise(function (resolve, reject) {
11-
var pathSep = sep || '.'
11+
var pathSep = sep || '.';
1212
var nuspecPath = path.resolve(
1313
library.path,
1414
library.name + pathSep + library.version + '.nupkg');
@@ -35,18 +35,18 @@ function parseNuspec(library, sep) {
3535
(metadata.dependencies || []).forEach(function (rawDependency) {
3636
(rawDependency.group || []).forEach(function (group) {
3737
(group.dependency || []).forEach(function (dep) {
38-
var transitiveDependency = new Dependency(dep.$.id, dep.$.version) // jscs:ignore
39-
transitiveDependency.versionSpec = dep.$.versionSpec
38+
var transitiveDependency = new Dependency(dep.$.id, dep.$.version); // jscs:ignore
39+
transitiveDependency.versionSpec = dep.$.versionSpec;
4040
ownDependencies.push(transitiveDependency);
41-
})
41+
});
4242
});
4343
(rawDependency.dependency || []).forEach(function (dep) {
4444
var transitiveDependency =
4545
new Dependency(dep.$.id, dep.$.version, null);
4646
transitiveDependency.versionSpec = dep.$.version;
4747
ownDependencies.push(transitiveDependency);
4848
});
49-
})
49+
});
5050
});
5151
resolve({
5252
name: library.name,

test/packages_dir.test.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
var path = require('path');
2+
var test = require('tap').test;
3+
var plugin = require('../lib/index');
4+
var projectPath = './test/stubs/packages_dir';
5+
6+
var app1Path = projectPath + '/only_jquery/';
7+
var app1ManifestFile = 'packages.config';
8+
var app1ExpectedTree = require(path.resolve(app1Path, 'expected.json'));
9+
10+
var app2Path = projectPath + '/only_jquery_but_wrong_version/';
11+
var app2ManifestFile = 'packages.config';
12+
var app2ExpectedTree = require(path.resolve(app2Path, 'expected.json'));
13+
14+
var app3Path = projectPath + '/only_momentjs/';
15+
var app3ManifestFile = 'packages.config';
16+
var app3ExpectedTree = require(path.resolve(app3Path, 'expected.json'));
17+
18+
test('packages contains many deps: only jquery', function (t) {
19+
plugin.inspect(
20+
app1Path,
21+
app1ManifestFile,
22+
{
23+
packagesFolder: projectPath + '/packages',
24+
})
25+
.then(function (result) {
26+
t.ok(result.package.dependencies.jQuery,
27+
'jQuery should be found because specified');
28+
t.notOk(result.package.dependencies['Moment.js'],
29+
'Moment.js should not be found, even though exists in packages');
30+
t.deepEqual(
31+
result,
32+
app1ExpectedTree,
33+
'expects project data to be correct'
34+
);
35+
t.end();
36+
})
37+
.catch(function (error) {
38+
t.fail('Error was thrown: ' + err);
39+
});
40+
});
41+
42+
43+
test('packages contains many deps: only moment', function (t) {
44+
plugin.inspect(
45+
app3Path,
46+
app3ManifestFile,
47+
{
48+
packagesFolder: projectPath + '/packages',
49+
})
50+
.then(function (result) {
51+
t.ok(result.package.dependencies['Moment.js'],
52+
'Moment.js should be found because specified');
53+
t.notOk(result.package.dependencies.jQuery,
54+
'jQuery should not be found, even though exists in packages');
55+
t.deepEqual(
56+
result,
57+
app3ExpectedTree,
58+
'expects project data to be correct'
59+
);
60+
t.end();
61+
})
62+
.catch(function (error) {
63+
t.fail('Error was thrown: ' + err);
64+
});
65+
});
66+
67+
68+
test('packages contains many deps: different jquery version', function (t) {
69+
plugin.inspect(
70+
app2Path,
71+
app2ManifestFile,
72+
{
73+
packagesFolder: projectPath + '/packages',
74+
})
75+
.then(function (result) {
76+
t.ok(result.package.dependencies.jQuery,
77+
'jQuery should be found because specified');
78+
t.ok(result.package.dependencies.jQuery.version == '3.2.1',
79+
'should find version as in packages folder 3.2.1, but found ' +
80+
result.package.dependencies.jQuery.version);
81+
t.deepEqual(
82+
result,
83+
app2ExpectedTree,
84+
'expects project data to be correct'
85+
);
86+
t.end();
87+
})
88+
.catch(function (error) {
89+
t.fail('Error was thrown: ' + err);
90+
});
91+
});

test/parse-with-traverse.test.js

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ var targetPackagesConfigFile =
77
targetProjectJsonFile + 'dummy_project_1/packages.config';
88
var alternatePackagesFolder =
99
targetProjectJsonFile + 'alternate_packages';
10-
var targetCSProjFile =
11-
targetProjectJsonFile + 'dummy_project_1/WebApplication1.csproj';
1210
var targetJSONManifestData =
1311
require('./stubs/_2_project.json');
1412

@@ -44,35 +42,6 @@ test('parse project.assets.json - like and traverse packages', function (t) {
4442
});
4543
});
4644

47-
test('parse .csproj and traverse packages', function (t) {
48-
var expectedTreeFile =
49-
fs.readFileSync(
50-
targetProjectJsonFile + 'dummy_project_1/expected_csproj.json');
51-
var expectedTree = JSON.parse(expectedTreeFile.toString());
52-
53-
plugin.inspect(null, targetCSProjFile, null)
54-
.then(function (result) {
55-
t.test('traversing', function (t) {
56-
t.deepEqual(
57-
result.package.dependencies,
58-
expectedTree.package.dependencies,
59-
'expects dependency tree to be correct');
60-
t.ok(result.plugin, 'plugin details exists in result');
61-
t.equal(result.plugin.name, 'snyk-nuget-plugin',
62-
'plugin\'s name is snyk-nuget-plugin');
63-
t.equal(result.plugin.targetFile, targetCSProjFile,
64-
'plugin shows correct targetFile');
65-
t.end();
66-
});
67-
return result;
68-
})
69-
.then(function (result) {
70-
if (result) {
71-
t.end();
72-
}
73-
});
74-
});
75-
7645
test('parse packages.config and traverse packages', function (t) {
7746
var expectedTreeFile =
7847
fs.readFileSync(

0 commit comments

Comments
 (0)