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

Allow Node arguments to be configured #2272

Merged
merged 33 commits into from
Jan 18, 2020

Conversation

maximelkin
Copy link
Contributor

@maximelkin maximelkin commented Oct 17, 2019

Fixes #2090


IssueHunt Summary

Referenced issues

This pull request has been submitted to:


IssueHunt has been backed by the following sponsors. Become a sponsor

@maximelkin maximelkin changed the title add node-arguments flag [WIP]: add node-arguments flag Oct 17, 2019
@maximelkin maximelkin force-pushed the node-arguments branch 2 times, most recently from ec5304d to 1f81b2f Compare October 17, 2019 00:34
@maximelkin maximelkin changed the title [WIP]: add node-arguments flag add node-arguments flag Oct 17, 2019
@novemberborn
Copy link
Member

Hey @maximelkin sorry about the delay in reviewing. At first glance this looks great, though I'd like to play with it a little first.

Copy link
Member

@novemberborn novemberborn left a comment

Choose a reason for hiding this comment

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

This is really nice @maximelkin! I kept writing comments and then looking at other code and realizing I got things wrong… by which I mean to say you really did think through all the angles here.

I've pushed some small tweaks, and left some other comments as well. Let me know what you think.

lib/api.js Outdated Show resolved Hide resolved
lib/node-arguments.js Outdated Show resolved Hide resolved
lib/node-arguments.js Outdated Show resolved Hide resolved
lib/node-arguments.js Outdated Show resolved Hide resolved
docs/05-command-line.md Outdated Show resolved Hide resolved
@maximelkin
Copy link
Contributor Author

Not sure, why tests getting SIGKILL on local machine

Copy link
Member

@novemberborn novemberborn left a comment

Choose a reason for hiding this comment

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

Thanks for your continuing work on this @maximelkin. I think it's nearly there.

Hopefully I've figured out how to make the CI run on pull requests as well.

lib/api.js Outdated
@@ -15,6 +16,8 @@ const makeDir = require('make-dir');
const ms = require('ms');
const chunkd = require('chunkd');
const Emittery = require('emittery');
const minimist = require('minimist');
Copy link
Member

Choose a reason for hiding this comment

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

Could we use https://www.npmjs.com/package/yargs-parser instead? It's already in our dependency tree as part of meow.

(Though it looks like so is minimist, because Node.js modules, but for less apparent reasons.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I choose minimist, because it has reverse package, maybe there is another package for it?

Copy link
Member

Choose a reason for hiding this comment

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

I reckon dargs may work with yargs-parser too, assuming it also outputs straight-forward objects.

lib/api.js Outdated
const hasInspect = args.inspect || args['inspect-brk'];
if (hasInspect) {
if (args.inspect && args['inspect-brk']) {
throw new Error('Flags inspect and inspect-brk provided simultaneously');
Copy link
Member

Choose a reason for hiding this comment

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

Note to self: check how this ends up being reported.

lib/cli.js Outdated
@@ -115,6 +116,10 @@ exports.run = async () => { // eslint-disable-line complexity
type: 'boolean',
default: false
},
'node-arguments': {
type: 'string',
default: ''
Copy link
Member

Choose a reason for hiding this comment

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

Can we remove this default? See my comment for normalizeNodeArguments().

* @param {string} cliParams
* @return {object}
*/
function normalizeNodeArguments(confParams, cliParams) {
Copy link
Member

Choose a reason for hiding this comment

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

If we can assume the arguments may be undefined, we can use default parameter values:

Suggested change
function normalizeNodeArguments(confParams, cliParams) {
function normalizeNodeArguments(confParams = [], cliParams = '') {

And we can get rid of the JSDoc comment too.

We do need to enforce confParams is an array.

function normalizeNodeArguments(confParams, cliParams) {
return omit({
...minimist(confParams || []),
...minimist(cliParams.split(' '))
Copy link
Member

Choose a reason for hiding this comment

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

Are there Node.js arguments that take strings? Cause then splitting on the empty string won't work.

return omit({
...minimist(confParams || []),
...minimist(cliParams.split(' '))
}, '_');
Copy link
Member

Choose a reason for hiding this comment

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

Is the _ returned by minimist? I'd prefer rest-spread for this:

const { _, ...normalized } = { ...minimist(), ...minimist() };
return normalized;

lib/api.js Outdated
if (inspectArgIndex === -1) {
return Promise.resolve(execArgv);
}
const mainProcessArgs = minimist(process.execArgv);
Copy link
Member

Choose a reason for hiding this comment

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

Could we cache this? This function runs for every test file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure, what I correctly understand you, check please

@niftylettuce
Copy link
Contributor

Great work! Will be so nice to have since Node v12 changed TLS min version and we need --tls-min-v1 flag as a Node arg for a project of mine.

@novemberborn
Copy link
Member

Hi @maximelkin, I did not have time to look at your changes yet, sorry.

@maximelkin
Copy link
Contributor Author

About passing arguments via cli
Maybe it's better to pass as --node-arguments "a b c"?
As I see this is supported by yargs-parser (and meow) now

@novemberborn
Copy link
Member

About passing arguments via cli
Maybe it's better to pass as --node-arguments "a b c"?
As I see this is supported by yargs-parser (and meow) now

@maximelkin what do you mean by this?


I spotted the change of -r to --require in the CLI helper. This led me of on a chase as to why -r wasn't working. It's because with the default configuration, dargs outputs -r=foo.js which Node.js does not support.

This then led me to think about how we're combining the arguments. I think we should simplify it a little:

  • Take process.execArgv
  • Concatenate with the nodeArguments array from the AVA config
  • Concatenate with the value of --node-arguments passed to AVA on the CLI
  • Provide this combined array as the execArgv option when forking the child process

This without parsing into objects, though we do need to parse the value to the --node-arguments option into the proper array.

I guess what may complicate this is the dynamic port assignment when we see --inspect flags. I'm hoping to do a bunch of work on AVA over the next two weeks, so maybe I can get rid of that too.

@novemberborn
Copy link
Member

I've switched the CLI flag parser to yargs (#2315) which will cause some conflicts here. But, #2316 adds a built-in debug command, which simplifies the execArgv stuff in api.js.

@novemberborn
Copy link
Member

@maximelkin I've been making a lot of changes over the past few weeks which has caused a lot of merge conflicts here. Sorry about that. I can try and resolve them when I get some time.

With regards to parsing --node-arguments, I was thinking we could maybe launch a script as a child process which outputs console.log(JSON.stringify(process.execArgv)). That way we can use Node.js own argument parsing logic.

* Combine values without overwriting duplicates
* Use Node.js to parse the argv string

Also add a bit more context in the documentation.
@novemberborn
Copy link
Member

@maximelkin I've fixed the merge conflicts and simplified the implementation as per #2272 (comment). Please let me know what you think!

@novemberborn
Copy link
Member

I was afraid this wouldn't work on Windows though 😢

@maximelkin
Copy link
Contributor Author

Hello, sorry for long inactivity
All is ok, very interesting hack with calling node for parsing
Also, maybe ask nodejs to expose algorithm of doing this? (for better implementation in future)

@maximelkin
Copy link
Contributor Author

maximelkin commented Jan 14, 2020

So adding shell: true to spawn test make it works, but break watcher test
Watcher breaking seems to be suspicious for me, I will research this

@novemberborn
Copy link
Member

All is ok, very interesting hack with calling node for parsing
Also, maybe ask nodejs to expose algorithm of doing this? (for better implementation in future)

I found https://github.com/astur/arrgv which claims to work just like Node.js does. Looking at the implementation in Node.js itself it also does a bunch of validation, which could lead to unexpected errors. So a simple parser is better. And this one gives us arrays which is what we want. Plus, it's tested using AVA 😄

Let's see if CI passes and then let's ship this!

@novemberborn novemberborn changed the title add node-arguments flag Allow Node arguments to be configured Jan 18, 2020
@novemberborn novemberborn merged commit 7b20f6c into avajs:master Jan 18, 2020
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.

Add a --node-arguments flags
3 participants