Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/lockfile parser lib #188

Merged
merged 14 commits into from
Aug 16, 2018
Merged

Feat/lockfile parser lib #188

merged 14 commits into from
Aug 16, 2018

Conversation

miiila
Copy link
Contributor

@miiila miiila commented Aug 9, 2018

Moved from https://github.com/snyk/snyk-internal/pull/417

  • Ready for review
  • Follows CONTRIBUTING rules
  • Reviewed by Snyk internal team

What does this PR do?

  • Adds in a fork for opt-in lockfile testing
  • Includes the new lockfile parser lib
  • Splits up some functionality for re-use

Assuming the https://github.com/snyk/nodejs-lockfile-parser/pull/5/files returns a tree the way we expect, i hope this is enough code to be able to get back a tree in the same format and carry on the test in the same way as before.

  • We are missing tests for this, need to get 1 in at least!

Where should the reviewer start?

Look in snyk-test/npm/index.js

How should this be manually tested?

snyk-dev test -d => will test using the old flow by looking at your node_modules
snyk-dev test -d --file=package-lock.json will go down the new flow and use the new lib

Any background context you want to provide?

What are the relevant tickets?

SC-5873

@CLAassistant
Copy link

CLAassistant commented Aug 9, 2018

CLA assistant check
All committers have signed the CLA.

@miiila miiila force-pushed the feat/lockfile-parser-lib branch from c651996 to c16e64d Compare August 9, 2018 11:58
@miiila miiila force-pushed the feat/lockfile-parser-lib branch from c16e64d to 9d4035b Compare August 11, 2018 13:22
@miiila miiila force-pushed the feat/lockfile-parser-lib branch 7 times, most recently from 408390b to f2fc748 Compare August 13, 2018 14:01
@miiila miiila self-assigned this Aug 13, 2018
@miiila miiila force-pushed the feat/lockfile-parser-lib branch from f2fc748 to f275033 Compare August 13, 2018 14:16
Copy link
Contributor

@michael-go michael-go left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make sure this branch works also with snyk monitor

var shrinkwrapFullPath = path.resolve(root, 'npm-shrinkwrap.json');

if (!fileSystem.existsSync(targetFileFullPath)) {
throw new Error('LockFile package.json not found at location: ' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a typo - package.json is not a lock


function generateDependenciesFromLockfile(root, options) {
debug('Lockfile detected, generating dependency tree from lockfile');
var targetFileFullPath = path.resolve(root, 'package.json');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's think about the case of monorepo and make sure it behaves as we expect, in example what about a case where user runs:

snyk test --file=node-subproject/package-lock.json

in this case the pacakge.json should be picked from the same location of the lock, but maybe it's ok as the user can also run:

snyk test node-project --file=package-lock.json

Copy link
Contributor

@gjvis gjvis Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defo need to make sure that the correct lockfile is always used (according to NPM rules)

var targetFile = fileSystem.readFileSync(targetFileFullPath);
var lockFile = fileSystem.readFileSync(lockFileFullPath);

analytics.add('local', true);
Copy link
Contributor

@michael-go michael-go Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we'er at it, maybe also add analytics metadata for the fact a lockfile is used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you - I had it in mind, but then I forgot :-)

analytics.add('local', true);

var resolveModuleSpinnerLabel = 'Analyzing npm dependencies for ' +
lockFileFullPath;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an indentation is needed here

var resolveModuleSpinnerLabel = 'Analyzing npm dependencies for ' +
lockFileFullPath;
debug(resolveModuleSpinnerLabel);
var payload = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it necessary to clone the payload creation (and this is not only the payload, but parameters for the http request) and policy collection into generateDependenciesFromLockfile() ? Would expect this function to just generate a tree and continue with the flow that already exists

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We agreed with @lili2311 that refactoring to better shape will happen later (will be planned properly) and with upcoming work around yarn.lock.

Copy link
Contributor

@michael-go michael-go Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can try and help refactor this, don't think we should merge a PR with a code that is not in good shape - unless there's a really good reason for it to be

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michael-go 👋 We had this chat already with Mila yesterday, please see https://snyk.slack.com/archives/CBXBQHN6A/p1534157719000072 We will be refactoring this but in the next few PRs

Copy link
Contributor

@lili2311 lili2311 Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are happy with out decision to hold off the refactoring for this PR, this way we gain more knowledge over the next few PRs & features like supporting different use cases and yarn.lock to help us understand how we should restructure this file to make the best of it.

package.json Outdated
@@ -48,6 +48,7 @@
"snyk-gradle-plugin": "1.3.0",
"snyk-module": "1.8.2",
"snyk-mvn-plugin": "1.2.0",
"snyk-nodejs-lockfile-parser": "^1.2.2",
Copy link
Contributor

@michael-go michael-go Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note we always pin our own dependencies to an exact version - maybe we shouldn't, but easier to stick to what we already do 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I am not sure I am happy with this approach, however I can see the reasons... Will do it for now.

Copy link
Contributor

@gjvis gjvis Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miiila It means that the version of the main CLI library tells us the exact state of the Snyk modules on a user's machine. Very useful for debugging and support.

Copy link
Contributor Author

@miiila miiila Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gjvis And for those situations, when you break the flow by fixing the bug 😇

var pkg = req.body;
t.equal(req.method, 'POST', 'makes POST request');
t.match(req.url, '/vuln/npm', 'posts to correct url');
t.ok(pkg.dependencies['to-array'], 'dependency');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would check a transitive dependency too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no transitive dependecny right now :-(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so lets use a better fixture ...

t.includes(e.message, '--file=npm-shrinkwrap.json', 'Contains enough info about error');
});
});

test('`test` on a yarn package does work and displays appropriate text',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe also add a test that if lockfile exists but not given via --file it's not used?


if (options.file.endsWith('package-lock.json') && fileSystem.existsSync(shrinkwrapFullPath)) {
throw new Error('`npm-shrinkwrap.json` was found while using package-lock.json.\n'
+ 'Please use `--file=npm-shrinkwrap.json` flag instead.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and we support that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't and we will not => changing the message.

var shrinkwrapFullPath = path.resolve(root, 'npm-shrinkwrap.json');

if (!fileSystem.existsSync(targetFileFullPath)) {
throw new Error('LockFile package.json not found at location: ' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LockFile => Lockfile

return lockFileParser.buildDepTree(manifestFile, lockFile, options);
})
.then(function (pkg) {
modules = pkg;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my comment here became outdated with some recent changes - but still, this needs refactoring. Why duplicate the http requests params creation & policy file collection code?

Copy link
Contributor

@michael-go michael-go Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and also the name getDependenciesFrom... is misleading as the functions also query for vulns.

@miiila miiila force-pushed the feat/lockfile-parser-lib branch from caa01df to 407f471 Compare August 14, 2018 11:59
@@ -11,20 +11,124 @@ var isCI = require('../../is-ci');
var _ = require('lodash');
var analytics = require('../../analytics');
var common = require('../common');
var fileSystem = require('fs');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason you're not calling the var fs like we always do?

options.root = root;

// if the file exists, let's read the package file and post
// that up to the server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment is misleading, as we'll upload the fully resolved dependency tree, not the package file

if (error) {
return reject(error);
}
return queryForVulns(p, modules, options);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it will be nicer to do:

return p.then(function(payload) {
  return queryForVulns(payload, modules, options);
})

or even add it to he promise chain above,
instead of passing a promise as a parameter to queryVulns

Copy link
Contributor Author

@miiila miiila Aug 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree (and will address), however, this exactly the thin ice, when you are refactoring and suddenly realise, you are changing behaviour :-D

});
}

function queryForVulns(p, modules, options) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that in the lockfile case - modules is just the pkgTree, but in the node_modules case it's an object with methods and such .. and in this function .pluck() is called on it and .numDependencies is checked

},
};
options.hasDevDependencies = false;
options.root = root;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't look right - if we do this to pass data down to queryForVulns(), lets instead just use extra parameters for it, and not "abuse" the options object

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, not sure if I agree - what is the options object for then? I am not a big fan of methods like queryForVulns(data, modules, hasDevDependencies, root, options).

@miiila miiila force-pushed the feat/lockfile-parser-lib branch from a63bd8d to f6f360a Compare August 15, 2018 16:26
@miiila miiila force-pushed the feat/lockfile-parser-lib branch from f6f360a to 5cf157c Compare August 15, 2018 16:37
Copy link
Contributor

@michael-go michael-go left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving but not happily - would prefer us to wait for a fixed lockfile-parser lib that doesn't hang on cycles

@miiila miiila merged commit 88905df into master Aug 16, 2018
@miiila miiila deleted the feat/lockfile-parser-lib branch August 16, 2018 16:02
@snyksec
Copy link

snyksec commented Aug 16, 2018

🎉 This PR is included in version 1.91.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@miiila miiila mentioned this pull request Sep 21, 2018
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants