Skip to content

FR: child_process.exec(cmd, { additionalEnv }) #14823

Description

@refack
  • Version: *
  • Platform: *
  • Subsystem: child_process

child_process.exec(cmd, { env: Object.assign({}, process.env, {NEW_VAR:1}) }) is a very common pattern. IMHO adding an { additionalEnv } option that implements this pattern, will make the API more complete, and less error prone.

Activity

  1. added
    child_processIssues and PRs related to the child_process subsystem.
    feature requestIssues requesting new Node.js features.
    help wantedIssues that need assistance from volunteers or PRs that need help to proceed.
    on Aug 14, 2017
  2. vsemozhetbyt commented on Aug 14, 2017

    @vsemozhetbyt
    Contributor

    FWIW, in Node.js 8.3.0 we can do:

    child_process.exec(cmd, { env: { ...process.env, NEW_VAR: 1 } });
    
  3. cjihrig commented on Aug 14, 2017

    @cjihrig
    Contributor

    I've thought about this in the past. It seems like an awkward API to me though. I like @vsemozhetbyt's solution moving forward, and Object.assign() (or similar) for older versions.

  4. refack commented on Aug 14, 2017

    @refack
    ContributorAuthor

    Ack that object spreads make this more succinct.
    IMHO there is still the issue that the current API is too close the the POSIX/WIN32 system call, and is not intuitive at the application level.
    I think that the case of adding vars is much more common than the case of replacing the entire env...
    Maybe a cleaner option would be to add a { envAdditive: true } flag (with a default of false) that will treat env as additions instead of replacement.

  5. bnoordhuis commented on Aug 14, 2017

    @bnoordhuis
    Member

    I think that the case of adding vars is much more common than the case of replacing the entire env...

    C programmers will disagree with you.

    This feature request seems like a solution in search of a problem and as to the syntax, I agree with Colin's choice of words: awkward.

  6. refack commented on Aug 14, 2017

    @refack
    ContributorAuthor

    I think that the case of adding vars is much more common than the case of replacing the entire env...

    C programmers will disagree with you.

    This feature request seems like a solution in search of a problem and as to the syntax, I agree with Colin's choice of words: awkward.

    That's sort of my point that (C programmes) != (node programmers).
    The struggle is real #14822 + #13390, and that's node core code written (or at least reviewed) by node core coders.

    I don't have an elegant solution for syntax. Since the API was designed to mimic the system calls, everything would look awkward 🤷‍♂️ The most elegant solution would have been to change the semantics of { env } but that's out of the question.
    But I am trying to think what a programmer who is node-as-first-language would think...

  7. refack commented on Aug 14, 2017

    @refack
    ContributorAuthor

    🤔 trying to be creative:

    const aes = child_process.addativeEnvSymbol;
    const env = { [aes]: true, NEW_VAR:1 }
    child_process.exec(cmd, { env })
  8. joaolucasl commented on Aug 15, 2017

    @joaolucasl
    Contributor

    The spread operator is a pretty good solution for this, imho, but I like the idea of an option to ease the work of merging too.

    I thought of something like:

    const env = { /* ... */ };
    child_process.exec(cmd, { env, mergeEnvs: true });

    mergeEnvs <boolean> If true, merges the env property with process.env. (Default: false).

    The naming might be tricky to get right, since to be descriptive enough it would have to be longer lol

    Edit: (Happy to PR if this goes forward 😄)

  9. evanlucas commented on Aug 15, 2017

    @evanlucas
    Contributor

    I feel like this is something that could easily be done in an npm package

  10. refack commented on Aug 15, 2017

    @refack
    ContributorAuthor

    After reading some POSIX design stories, I tend to agree that this should stay as is for child_process.spawn but now I'm worried about the mismatch with cluster.fork

  11. gibfahn commented on Aug 15, 2017

    @gibfahn
    Member

    I think a common function that adds something to the existing process.env like:

    child_process.exec(cmd, { env: common.envPlus({NEW_VAR:1}) })

    would make sense, and would hopefully solve the problem we have in tests, which is that adding something to the existing env isn't exactly intuitive.

    Whether this is something that the larger community would need is a different question though, and can probably be dealt with separately.

  12. cjihrig commented on Aug 15, 2017

    @cjihrig
    Contributor

    Would common.envPlus() just be this?

    function envPlus(env) {
      return Object.assign({}, process.env, env);
    }

    If so, we could probably live without it.

  13. 1 remaining item

  14. sindresorhus commented on Aug 15, 2017

    @sindresorhus

    I feel like this is something that could easily be done in an npm package

    Check out execa which already does this by default. (extendEnv option to turn it off)

  15. gibfahn commented on Aug 15, 2017

    @gibfahn
    Member

    Raised a PR for discussion purposed: #14845

    Not 100% sold on having the function, but it's easier to discuss over code.

  16. added a commit that references this issue on Aug 17, 2017
  17. refack commented on Aug 26, 2017

    @refack
    ContributorAuthor

    Closed for no consensus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    child_processIssues and PRs related to the child_process subsystem.feature requestIssues requesting new Node.js features.help wantedIssues that need assistance from volunteers or PRs that need help to proceed.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions