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

Support NODE_PATH in forked process #531

Closed
wants to merge 17 commits into from
Closed

Support NODE_PATH in forked process #531

wants to merge 17 commits into from

Conversation

ingro
Copy link
Contributor

@ingro ingro commented Feb 9, 2016

This PR tries to fix #515 in a non-destructive way.

Basically it checks for the presence of NODE_PATH env variable before forking the process and creates an absolute path from it, so it could be used in test-worker.js as additional node module path.

That won't work there because process.cwd() points to the forked process test file.

@mention-bot
Copy link

By analyzing the blame information on this pull request, we identified @novemberborn, @ariporad and @sotojuan to be potential reviewers

@novemberborn
Copy link
Member

Rather than modifying process.env.NODE_PATH in api.js you should probably pass a custom value in fork.js: https://github.com/sindresorhus/ava/blob/bdb8b6ebaa05f1dc31cdab7c84aed7d92317b8ed/lib/fork.js#L19:L22

@@ -86,6 +86,9 @@ var oldNodeModulesPaths = module.constructor._nodeModulePaths;
module.constructor._nodeModulePaths = function () {
var ret = oldNodeModulesPaths.apply(this, arguments);
ret.push(nodeModulesDir);
if (process.env.NODE_PATH) {
ret.push(process.env.NODE_PATH);
Copy link
Member

Choose a reason for hiding this comment

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

NODE_PATH can contain multiple values. Not sure if the env var needs to be split and concatenated with ret here. See https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders for more.

@ingro
Copy link
Contributor Author

ingro commented Feb 9, 2016

Thanks for your inputs @novemberborn , I made the following changes:

  • removed the ugly process.env.NODE_PATH override in api.js
  • added an option for the forked process (projectRoot) which contains the original path from where ava was called;
  • cycled through possible multiple values of process.env.NODE_PATH (with a simple OS check) and join their path with the one supplied by projectRoot.

@@ -13,7 +13,8 @@ module.exports = function (file, opts) {
tty: process.stdout.isTTY ? {
columns: process.stdout.columns,
rows: process.stdout.rows
} : false
} : false,
projectRoot: process.cwd()
Copy link
Member

Choose a reason for hiding this comment

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

This isn't necessarily the project root. Perhaps parentWorkingDirectory? Bit verbose though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What about parentCwd?

Copy link
Member

Choose a reason for hiding this comment

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

Sure

@novemberborn
Copy link
Member

Perhaps resolve the additional, absolute NODE_PATHs in the main process, once, and then pass the array through the opts to the test-worker.

You should add a test, probably in test/fork.js. Note that tests are written using node-tap. Maybe use t.spawn to spawn another test file (from the fixtures directory) with a NODE_PATH environment variable, then in that file use the lib/fork module to run an AVA test. You could set up NODE_PATH so the final test can do an import and have it be resolved correctly. I'm in Gitter if that wasn't clear https://gitter.im/sindresorhus/ava

@@ -13,7 +13,8 @@ module.exports = function (file, opts) {
tty: process.stdout.isTTY ? {
columns: process.stdout.columns,
rows: process.stdout.rows
} : false
} : false,
additionalPaths: opts.additionalPaths
Copy link
Member

Choose a reason for hiding this comment

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

Object.assign() already takes care of mixing in the opts.

@ingro
Copy link
Contributor Author

ingro commented Feb 10, 2016

I added the test and it seems like it's green now, but I surely forgot something else, let me know if something is missing!

@@ -93,11 +94,22 @@ if (cli.flags.init) {
return;
}

var nodePaths;
if (process.env.NODE_PATH) {
var osSplitChar = process.platform === 'win32' ? ';' : ':';
Copy link

Choose a reason for hiding this comment

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

Instead you can use path.delimiter. https://nodejs.org/api/path.html#path_path_delimiter

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool! So I can get rid of all the env check stuff!

Copy link

Choose a reason for hiding this comment

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

I should have commented it earlier :)

@novemberborn
Copy link
Member

@ingro I think what @sindresorhus is saying is that you can add an env object in fork.js which sets NODE_PATH to the corrected value. Then you don't need the changes in test-worker.js.

@sindresorhus
Copy link
Member

Yup, and keep in mind that the whole existing process.env needs to be passed to the fork thing to preserve existing behavior, so use object-assign to copy the object and then modify the NODE_PATH key.

@ingro
Copy link
Contributor Author

ingro commented Feb 11, 2016

Well I think that's cleaner, I will look at it as soon as I have time!

@ingro
Copy link
Contributor Author

ingro commented Feb 12, 2016

The commit has some conflicts, what's the procedure in situation like this?

@sindresorhus
Copy link
Member

@ingro You resolve the merge conflict. (No need to open a new PR)

@ingro
Copy link
Contributor Author

ingro commented Feb 15, 2016

It seems we are back to green!

.map(function (p) {
return path.resolve(p);
})
.join(path.delimiter);
Copy link
Member

Choose a reason for hiding this comment

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

Could compute this outside of the function so it can be reused for subsequent forks.


env = objectAssign({
NODE_PATH: nodePath
}, env);
Copy link
Member

Choose a reason for hiding this comment

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

Ugh, discovered this too late. This makes no sense. Here you overwrite the modified NODE_PATH with the original one. This means the tests are also invalid. Tests still pass when the .map is commented out.

// @ingro @novemberborn

sindresorhus added a commit that referenced this pull request Feb 16, 2016
@ingro
Copy link
Contributor Author

ingro commented Feb 16, 2016

Welp sorry, I blindly copied from one of your comment above.
That should fix the wrong assignment:
env = objectAssign(env, { NODE_PATH: nodePath });

Anyway tests still fails, will look into that!

@ingro
Copy link
Contributor Author

ingro commented Feb 16, 2016

I think I found the problem with the test, it was:

var nodePaths = 'node-paths/modules' + path.delimiter + 'node-paths/deep/nested';

while it should have been:

var nodePaths = 'fixture/node-paths/modules' + path.delimiter + 'fixture/node-paths/deep/nested';

That's because NODE_PATH should be relative to the directory from which ava is running, not to the test itself.

I've fixed that in my fork, I should create another pull request?

@novemberborn
Copy link
Member

I should create another pull request?

Yep! 👯

@ingro
Copy link
Contributor Author

ingro commented Feb 16, 2016

Created here #559

@hildjj
Copy link

hildjj commented Feb 11, 2021

@sindresorhus I think this regressed with commit 1f10a7c.

@novemberborn
Copy link
Member

@hildjj that was intentional.

@hildjj
Copy link

hildjj commented Feb 12, 2021

Is this the correct place to discuss whether that was the correct decision? I don't see an issue or pull request associated with that commit, so I'll assume yes, unless you'd like me to open a new issue.

I have an (admittedly crappy) use case where being able to manipulate NODE_PATH is very handy. It involves using the same test suite to test two different builds of the same software that have subtle differences in their dependencies. I can figure out another way around this if I have to, but it was convenient.

@novemberborn
Copy link
Member

You could use an ava.config.cjs file to rewrite the NODE_PATH and configure it as an environment variable for AVA to use for the worker processes. We're not going to bring back specialized handling in AVA itself.

@hildjj
Copy link

hildjj commented Feb 12, 2021

I'm arguing that it's not specialized handling. ava is now modifying the environment being passed to my tests in a surprising way. At the very least I would have expected something in the release notes and something in the docs for a change that breaks existing functionality built in to node. The docs currently say:

"environmentVariables: specifies environment variables to be made available to the tests. The environment variables defined here override the ones from process.env"

which is at least confusing at the moment, since it's not clear that the process.env isn't the same as the environment passed in to ava.

ava.config.cjs might work for me, with some logic to detect which of the cases I'm in, I suppose.

@novemberborn
Copy link
Member

No, AVA 3 no longer modifies anything. But let's continue this in a Discussion.

@hildjj
Copy link

hildjj commented Feb 12, 2021

#2682 for linkage

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.

NODE_PATH does not work
7 participants