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

Env file cross-platform #24

Closed
Leokuma opened this issue Mar 20, 2022 · 8 comments
Closed

Env file cross-platform #24

Leokuma opened this issue Mar 20, 2022 · 8 comments

Comments

@Leokuma
Copy link

Leokuma commented Mar 20, 2022

How can I load environment variables from an .env file in a way that works cross-platform?

I have too many variables to add to the command line. I could load them manually from inside my app using dotenv, but I wouldn't like to add the --allow-read permission just for that, and also I'd like to keep my script as clean as possible, with as few deps as possible.

@dsherret
Copy link
Member

I think the way to do this would be something like:

{
  "tasks": {
    "some_task": "deno task --quiet with_vars deno eval 'console.log(5);'",
    "with_vars": "deno run -A scripts/with_vars.ts"
  }
}

Then in scripts/with_vars.ts it could do:

import "https://deno.land/[email protected]/dotenv/load.ts";

const p = Deno.run({
  cmd: [...Deno.args],
});

Deno.exit(await p.status());

So essentially, it launches a script that loads the environment variables from .env, then runs the provided command.

@jsejcksn
Copy link

@dsherret Will you consider opening this again?

I think that recommending privilege escalation isn't a great solution… and that proper support for safely supplying environment variables from a file is a great feature for the task shell to provide.

Recently I wanted to use deno serve with CLI argument values defined in a .env file, but I had to resort to platform specific features for it. Here's an example of what I'm describing:

.env

HOSTNAME=localhost
PORT=3000

deno.json

{
  "tasks": {
    "serve": "deno serve --allow-net=localhost:3000 --host=$HOSTNAME --port=$PORT server.ts",
  }
}

I wanted to:

  1. run the declarative server using the values from the .env file
  2. without making the variables available to the current shell after the deno process ends
  3. without granting additional, unnecessary permissions to deno

…so I ended up running the serve task like this in my *nix shell:

eval $(< .env) deno task serve

This met the criteria above, but eval has its own disadvantages:

  • it's not cross-platform
  • it simply shifts the unsafe code execution step: from JS/TS source text to .env source text

I'd like for the task shell to offer a way to support this case natively: safely parsing and loading environment variables from a .env file for use by subsequent commands in the task — without making the variables available to the current shell afterward (no export).

@dsherret
Copy link
Member

I think that recommending privilege escalation isn't a great solution…

The shell in deno task already has full permissions and can execute executables.

I'd like for the task shell to offer a way to support this case natively: safely parsing and loading environment variables from a .env file for use by subsequent commands in the task — without making the variables available to the current shell afterward (no export).

Maybe deno task should support the --env flag? I'm not sure there's a good solution for the shell itself.

@Leokuma
Copy link
Author

Leokuma commented Jul 24, 2024

Doesn't this work on Windows?

export $(cat .env | xargs) && mycommand

@jsejcksn
Copy link

@dsherret

I think that recommending privilege escalation isn't a great solution…

The shell in deno task already has full permissions and can execute executables.

Right, I meant "recommending privilege escalation to the deno process…"

Maybe deno task should support the --env flag? I'm not sure there's a good solution for the shell itself.

It's definitely an abstract operation, and I haven't yet thought about how to solve it, but I still think it's a useful feature to offer: so that the same environment variables can be used by the task itself and by the code that is run by the task (without duplication).

@jsejcksn
Copy link

Doesn't this work on Windows?

export $(cat .env | xargs) && mycommand

@Leokuma No — one of the requirements I listed is to not export the variables to the shell… so that they don't remain available to subsequent processes.

@jsejcksn
Copy link

@dsherret Since you didn't reopen this issue when you replied… it wasn't clear to me from what you wrote: Are you declining this feature request completely, or should I create a new issue instead?

@dsherret
Copy link
Member

dsherret commented Jul 24, 2024

No — one of the requirements I listed is to not export the variables to the shell… so that they don't remain available to subsequent processes.

You can use a subshell for this (just ensure you're using a newish version of Deno that has denoland/deno#24279):

(export $(cat .env | xargs) && mycommand)

Since you didn't reopen this issue when you replied… it wasn't clear to me from what you wrote: Are you declining this feature request completely, or should I create a new issue instead?

I don't see anything actionable at the moment because there's no proposals. If someone has a proposal for how this could work then please open a new issue outlining that.

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

No branches or pull requests

3 participants