Skip to content
This repository has been archived by the owner on Jan 6, 2021. It is now read-only.

fix: Resolve value of env variables before invoking cross-spawn #95

Merged
merged 2 commits into from
Mar 27, 2017

Conversation

DanReyLop
Copy link
Contributor

Since this was the only blocker for releasing the next major version, I decided to give it a try.

Before:
cross-env FOO=$NODE_ENV echo $FOO
Output (before this PR): "$NODE_ENV" on UNIX, "%NODE_ENV%" on Windows.
Output (after this PR): "development" (or whatever value NODE_ENV has)

I've added some logic in the part of the parser that processes the right-hand side of variable assignments (in this example, the $NODE_ENV in the FOO=$NODE_ENV expression). It will find all occurences of UNIX-style env variables and replace them with their value.

I've also had to change the program logic a little bit so commandConvert only operates on the real command and its arguments, not on the variable assignments.

Fixes #90

Copy link
Collaborator

@hgwood hgwood 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 looking into this.

src/index.js Outdated
return [command, commandArgs, envVars]
const commandArgs = args.slice()
const command = commandConvert(getCommand(commandArgs, envVars))
return [commandConvert(command), commandArgs.map(commandConvert), envVars]
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • map does not mutate its argument so no need to slice first
  • So the command is converted twice? Is that on purpose?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So the command is converted twice? Is that on purpose?

No, that was a mistake. Fixed. Good catch!

map does not mutate its argument so no need to slice first

getCommand mutates its first argument (commandArgs), so the .slice is necessary.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, I see. You are leveraging the fact that getCommand will strip env setters and the command from commandArgs. And you are making a copy so that getCommandArgsAndEnvVars does not itself mutate its argument. Am I correct? I think this is not very clear from the code. I understand it is done like this to minimize impact on existing code. It might still be a good idea to rename getCommand to something more revealing. However, the more I think about a name for this, the more I realize it does too much to have a good name:

  • it strips env setters and the command from its first argument
  • it sets env vars on its second argument
  • it returns the command

A possible improvement would be to replace it with 2 functions:

  • args -> [env setters, command, commandArgs] (simple to use using destructuring)
  • env setters -> map of env vars (to be merged with process.env to form the env for the new process)

What do you think? Is it worth the work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are leveraging the fact that getCommand will strip env setters and the command from commandArgs. And you are making a copy so that getCommandArgsAndEnvVars does not itself mutate its argument. Am I correct?

Correct. If I didn't make a copy, a call to crossEnv would get its arguments mutated, and I don't think we want that :)

A possible improvement would be to replace it with 2 functions...

That sound good, this part was the most confusing when I started looking at this repo, so I think it's totally worth it to refactor a bit.

Copy link
Owner

Choose a reason for hiding this comment

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

In addition, we could probably refactor out the whole loop to simplify the code a bit and remove the mutation. 😀

Copy link
Owner

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

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

This looks great! I think that it could be improved by doing what @hgwood suggests here though. Thanks! Once this is merged, I'll make a beta release for us all to try out! Wahoo!

@DanReyLop
Copy link
Contributor Author

What do you folks think about it now? 53776d3

I believe it's a bit cleaner now but I've written it 5 minutes ago so I may be a bit biased :)

Copy link
Collaborator

@hgwood hgwood left a comment

Choose a reason for hiding this comment

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

lgtm

Copy link
Owner

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks so much!

@kentcdodds kentcdodds merged commit 63352c2 into kentcdodds:next Mar 27, 2017
@kentcdodds
Copy link
Owner

Hey @danielo515, thanks so much for your help! I've added you as a collaborator on the project. Please make sure that you review the CONTRIBUTING.md file (specifically the bit about the commit messages and the git hooks) and familiarize yourself with the code of conduct (we're using the contributor covenant). You might also want to watch the repo to be notified when someone files an issue/PR. Please continue to make PRs as you feel the need (you can make your branches directly on the repo rather than your fork if you want). Thanks! And welcome to the team :)

@danielo515
Copy link
Contributor

Dear @kentcdodds

Thank you very much. I'm not sure why are no notifying me on this pull request (convenience I guess), but I'm glad to become a collaborator.

Regards

@DanReyLop
Copy link
Contributor Author

@danielo515 I think he mispelled my name haha

@kentcdodds
Copy link
Owner

😅 whoops! Yeah, sorry about that @danielo515, I appreciate your contributions as well! I have a fairly open contributors policy so if anything comes up, feel free to jump in with a PR. I generally give contrib rights to anyone who's contributed non-trivial code changes :)

kentcdodds pushed a commit that referenced this pull request Mar 31, 2017
* fix: Resolve value of env variables before invoking cross-spawn

#90

* Refactored the main parsing loop

BREAKING CHANGE: This is unlikely to break anyone, but now if you assign a variable to a variable (like `FOO=$BAR` with the value `$BAR` being assigned to `hello`, the command will be converted to `FOO=hello` whereas before it was `FOO=$BAR`).
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants