aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Kit PANG <pangkit888@gmail.com> 2022-09-18 13:11:16 +0800
committerGravatar GitHub <noreply@github.com> 2022-09-17 22:11:16 -0700
commit184230058a5ce9782a30dfd52955c2e201064ea0 (patch)
tree7c386edc05ef8cb12722ac9caef2b7a1cc602655 /src
parenta08b323e617c6e2db6c6bc2e1731f447b43ccb50 (diff)
downloadbun-184230058a5ce9782a30dfd52955c2e201064ea0.tar.gz
bun-184230058a5ce9782a30dfd52955c2e201064ea0.tar.zst
bun-184230058a5ce9782a30dfd52955c2e201064ea0.zip
feat: env loader nested values with curly braces (#1246)
* [env loader] Add support for nested value with curly braces does not support default values for nested values, e.g., ${undefined:default}, ${undefined:-default}, or ${undefined-default} * fix: minor fix and add more test * [env loader] Improve nested value parsing performance remove unnecessary branching Co-authored-by: Like <like@ekil.sh>
Diffstat (limited to 'src')
-rw-r--r--src/env_loader.zig47
1 files changed, 46 insertions, 1 deletions
diff --git a/src/env_loader.zig b/src/env_loader.zig
index 72efce55f..be2bce933 100644
--- a/src/env_loader.zig
+++ b/src/env_loader.zig
@@ -72,11 +72,18 @@ pub const Lexer = struct {
i += 1;
const start = i;
+ const curly_braces_offset: usize = if (variable.value[i] == '{') 1 else 0;
+ i += curly_braces_offset;
+
while (i < variable.value.len) {
switch (variable.value[i]) {
'a'...'z', 'A'...'Z', '0'...'9', '-', '_' => {
i += 1;
},
+ '}' => {
+ i += curly_braces_offset;
+ break;
+ },
else => {
break;
},
@@ -85,7 +92,7 @@ pub const Lexer = struct {
try writer.writeAll(variable.value[last_flush .. start - 1]);
last_flush = i;
- const name = variable.value[start..i];
+ const name = variable.value[start + curly_braces_offset .. i - curly_braces_offset];
if (@call(.{ .modifier = .always_inline }, getter, .{ ctx, name })) |new_value| {
if (new_value.len > 0) {
@@ -1089,10 +1096,17 @@ test "DotEnv Loader - basic" {
\\
\\NESTED_VALUE='$API_KEY'
\\
+ \\NESTED_VALUE_WITH_CURLY_BRACES='${API_KEY}'
+ \\NESTED_VALUE_WITHOUT_OPENING_CURLY_BRACE='$API_KEY}'
+ \\
\\RECURSIVE_NESTED_VALUE=$NESTED_VALUE:$API_KEY
\\
+ \\RECURSIVE_NESTED_VALUE_WITH_CURLY_BRACES=${NESTED_VALUE}:${API_KEY}
+ \\
\\NESTED_VALUES_RESPECT_ESCAPING='\$API_KEY'
\\
+ \\NESTED_VALUES_WITH_CURLY_BRACES_RESPECT_ESCAPING='\${API_KEY}'
+ \\
\\EMPTY_SINGLE_QUOTED_VALUE_IS_EMPTY_STRING=''
\\
\\EMPTY_DOUBLE_QUOTED_VALUE_IS_EMPTY_STRING=""
@@ -1108,9 +1122,13 @@ test "DotEnv Loader - basic" {
false,
);
try expectString(map.get("NESTED_VALUES_RESPECT_ESCAPING").?, "\\$API_KEY");
+ try expectString(map.get("NESTED_VALUES_WITH_CURLY_BRACES_RESPECT_ESCAPING").?, "\\${API_KEY}");
try expectString(map.get("NESTED_VALUE").?, "verysecure");
+ try expectString(map.get("NESTED_VALUE_WITH_CURLY_BRACES").?, "verysecure");
+ try expectString(map.get("NESTED_VALUE_WITHOUT_OPENING_CURLY_BRACE").?, "verysecure}");
try expectString(map.get("RECURSIVE_NESTED_VALUE").?, "verysecure:verysecure");
+ try expectString(map.get("RECURSIVE_NESTED_VALUE_WITH_CURLY_BRACES").?, "verysecure:verysecure");
try expectString(map.get("API_KEY").?, "verysecure");
try expectString(map.get("process.env.WAT").?, "ABCDEFGHIJKLMNOPQRSTUVWXYZZ10239457123");
@@ -1128,6 +1146,33 @@ test "DotEnv Loader - basic" {
try expectString(map.get("EMPTY_DOUBLE_QUOTED_VALUE_IS_EMPTY_STRING").?, "");
}
+test "DotEnv Loader - Nested values with curly braces" {
+ const VALID_ENV =
+ \\DB_USER=postgres
+ \\DB_PASS=xyz
+ \\DB_HOST=localhost
+ \\DB_PORT=5432
+ \\DB_NAME=db
+ \\
+ \\DB_USER2=${DB_USER}
+ \\
+ \\DATABASE_URL="postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}?pool_timeout=30&connection_limit=22"
+ \\
+ ;
+ const source = logger.Source.initPathString(".env", VALID_ENV);
+ var map = Map.init(default_allocator);
+ Parser.parse(
+ &source,
+ default_allocator,
+ &map,
+ true,
+ false,
+ );
+ try expectString(map.get("DB_USER").?, "postgres");
+ try expectString(map.get("DB_USER2").?, "postgres");
+ try expectString(map.get("DATABASE_URL").?, "postgresql://postgres:xyz@localhost:5432/db?pool_timeout=30&connection_limit=22");
+}
+
test "DotEnv Process" {
var map = Map.init(default_allocator);
var process = try std.process.getEnvMap(default_allocator);