deno icon indicating copy to clipboard operation
deno copied to clipboard

deno --env-file variable expansion without braces cut off by underscore (_)

Open bentinata opened this issue 1 year ago • 5 comments

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

bentinata avatar Oct 27 '24 13:10 bentinata

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> 

yazan-abdalrahman avatar Oct 27 '24 14:10 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$

yazan-abdalrahman avatar Oct 27 '24 14:10 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$

yazan-abdalrahman avatar Oct 27 '24 14:10 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$

yazan-abdalrahman avatar Oct 27 '24 14:10 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.

bentinata avatar Oct 28 '24 02:10 bentinata