deno --env-file variable expansion without braces cut off by underscore (_)
Version: Deno 2.0.1
# .env
C_D=value1000
E=$C_D${C_D}
# env.ts
console.log(Deno.env.get("E"));
$ deno run --allow-env --env-file env.ts
Expectation:
value1000value1000
Result:
_Dvalue1000
I've checked and ran@std/dotenv. If deno is using @std/dotenv internally, and @std/dotenv does not have any issues, maybe it's on how deno use it?
https://github.com/denoland/std/blob/8c9b4c6972e7eed0214f810542168ab746a306be/dotenv/parse_test.ts#L189
I've also created a repo with how sh and docker compose handle variable expansion.
https://git.sr.ht/~bentinata/read-env-example/tree/deno-env
I am unable to reproduce it using the least version of Deno on Windows.
PS D:\yad\deno> deno -v
deno 2.0.3
PS D:\yad\deno> $env:C_D = "value1000"
PS D:\yad\deno> $env:E = "$env:C_D$env:C_D"
PS D:\yad\deno>
PS D:\yad\deno> cat .\env.ts
console.log(Deno.env.get("E"));
PS D:\yad\deno>
PS D:\yad\deno> deno run --allow-env --env-file env.ts
Warning The `--env-file` flag was used, but the environment file specified '.env' was not found.
value1000value1000
PS D:\yad\deno>
console.log(Deno.env.get("E"));
Yes, but that issue exists in Linux
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ deno -v
deno 2.0.3
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ cat .env
C_D=value1000
E=$C_D${C_D}
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ cat env.ts
console.log(Deno.env.get("E"));
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ deno run --allow-env --env-file env.ts
_Dvalue1000
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
console.log(Deno.env.get("E"));Yes, but that issue exists in Linux
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ deno -v deno 2.0.3 kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ cat .env C_D=value1000 E=$C_D${C_D} kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ cat env.ts console.log(Deno.env.get("E")); kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ deno run --allow-env --env-file env.ts _Dvalue1000 kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
I think the issue is with how to setup environment variables appropriately; here are some Linux examples that demonstrate this.
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman/test$ export C_D=value1000
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman/test$ export E="$C_D$C_D"
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman/test$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman/test$ deno run --allow-env ../env.ts
value1000value1000
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman/test$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ cat .env
C_D=value1000
E=${C_D}${C_D}
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ deno run --allow-env --env-file env.ts
value1000value1000
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
My conclusion is that it's not a bug.
The variable expansion issue in the.env file is due to the need for proper syntax when referencing variables. When using one variable inside another, it should be formatted as ${VARIABLE_NAME}.
like C_D=value1000 E=${C_D}${C_D}
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ cat .env
C_D=value1000
E=${C_D}${C_D}
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$ deno run --allow-env --env-file env.ts
value1000value1000
kutad@DESKTOP-CFBINQA:/mnt/c/Users/Yazan.Abdalrahman$
Oh, its because of the dotenvy crate, which copied behavior from dotenv crate.
https://github.com/allan2/dotenvy/issues/73
https://github.com/dotenv-rs/dotenv/blob/3c1a77bc95821777e5ceb996c5e0b082f2a3ea38/README.md?plain=1#L93-L95
Used in: https://github.com/denoland/deno/blob/5f0bb3c6f4328003012e98ba70ce18e4e2e842de/cli/args/mod.rs#L1879
# std_dotenv.ts
import "jsr:@std/dotenv/load";
console.log(Deno.env.get("E"));
Would output the correct result. Which means @std/dotenv and deno --env-file differs. Would be nice to have it mentioned in the official docs? https://docs.deno.com/runtime/reference/env_variables/#.env-file
Alternatively, we could use dotenvs crate instead.