Home > Software engineering >  How does dotenv cli with "--" (double-dash) running commands?
How does dotenv cli with "--" (double-dash) running commands?

Time:02-14

Im my project i am trying to use dotenv-cli with pnpm. I am using PowerShell 7.2.1 on windows. I have monorepo with package api with script dev in package.json. First what I tried was:

dotenv -e .\.env -- pnpm dev --filter api

And it did not work:

 ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL  not found: dev

But when I tried:

dotenv -e .\.env -- pnpm -- dev --filter api

It worked well.

As I had read -- signifies the end of command options, after which only positional arguments are accepted. So why do I need to use it twice for my command to work? Why is it working like that?

CodePudding user response:

The problem is that when you call from PowerShell (unlike from cmd.exe), the command name dotenv resolves to a PowerShell script, namely dotenv.ps1, as you report.

When PowerShell calls a PowerShell-native command - including .ps1 files - its own parameter binder interprets the (first) -- argument and removes it; that is, the target command never sees it. (The semantics of -- is analogous to that of Unix utilities: -- tells the parameter binder to treat subsequent arguments as positional ones, even if they look like parameter (option) names, such as -foo.)

Thus, unfortunately, you need to specify -- twice in order to pass a single -- instance through to the .ps1 script itself:

# The first '--' is removed by PowerShell's parameter binder.
# The second one is then received as an actual, positional argument by
# dotenv.ps1
dotenv -e .\.env -- -- pnpm dev --filter api

Alternatively, assuming that dotenv.cmd, i.e. a batch file version of the CLI exists too (and is also in a directory listed in $env:PATH), you can bypass this problem by calling it explicitly, instead of the .ps1; when calling external programs (including scripts interpreted by other shells / scripting engines, such as cmd.exe), PowerShell does not remove --:

# Calling the batch-file form of the command doesn't require
# passing '--' twice.
dotenv.cmd -e .\.env -- pnpm dev --filter api

Caveat: While it will typically not matter, the way a batch file parses its arguments differs from how PowerShell does it for its native commands.

  • Related