aboutsummaryrefslogtreecommitdiff
path: root/src/env_loader.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/env_loader.zig')
-rw-r--r--src/env_loader.zig89
1 files changed, 59 insertions, 30 deletions
diff --git a/src/env_loader.zig b/src/env_loader.zig
index 7c2c38a99..7f0be98a7 100644
--- a/src/env_loader.zig
+++ b/src/env_loader.zig
@@ -231,7 +231,7 @@ pub const Loader = struct {
if (behavior == .prefix) {
while (iter.next()) |entry| {
- const value: string = entry.value_ptr.*;
+ const value: string = entry.value_ptr.value;
if (strings.startsWith(entry.key_ptr.*, prefix)) {
const key_str = std.fmt.allocPrint(key_allocator, "process.env.{s}", .{entry.key_ptr.*}) catch unreachable;
@@ -282,12 +282,12 @@ pub const Loader = struct {
}
} else {
while (iter.next()) |entry| {
- const value: string = if (entry.value_ptr.*.len == 0) empty_string_value else entry.value_ptr.*;
+ const value: string = if (entry.value_ptr.value.len == 0) empty_string_value else entry.value_ptr.value;
const key = std.fmt.allocPrint(key_allocator, "process.env.{s}", .{entry.key_ptr.*}) catch unreachable;
e_strings[0] = js_ast.E.String{
- .data = if (entry.value_ptr.*.len > 0)
- @as([*]u8, @ptrFromInt(@intFromPtr(entry.value_ptr.*.ptr)))[0..value.len]
+ .data = if (entry.value_ptr.value.len > 0)
+ @as([*]u8, @ptrFromInt(@intFromPtr(entry.value_ptr.value.ptr)))[0..value.len]
else
&[_]u8{},
};
@@ -370,7 +370,6 @@ pub const Loader = struct {
// .env goes last
pub fn load(
this: *Loader,
- fs: *Fs.FileSystem.RealFS,
dir: *Fs.FileSystem.DirEntry,
comptime suffix: enum { development, production, @"test" },
) !void {
@@ -380,19 +379,19 @@ pub const Loader = struct {
switch (comptime suffix) {
.development => {
if (dir.hasComptimeQuery(".env.development.local")) {
- try this.loadEnvFile(fs, dir_handle, ".env.development.local", false);
+ try this.loadEnvFile(dir_handle, ".env.development.local", false, true);
Analytics.Features.dotenv = true;
}
},
.production => {
if (dir.hasComptimeQuery(".env.production.local")) {
- try this.loadEnvFile(fs, dir_handle, ".env.production.local", false);
+ try this.loadEnvFile(dir_handle, ".env.production.local", false, true);
Analytics.Features.dotenv = true;
}
},
.@"test" => {
if (dir.hasComptimeQuery(".env.test.local")) {
- try this.loadEnvFile(fs, dir_handle, ".env.test.local", false);
+ try this.loadEnvFile(dir_handle, ".env.test.local", false, true);
Analytics.Features.dotenv = true;
}
},
@@ -400,7 +399,7 @@ pub const Loader = struct {
if (comptime suffix != .@"test") {
if (dir.hasComptimeQuery(".env.local")) {
- try this.loadEnvFile(fs, dir_handle, ".env.local", false);
+ try this.loadEnvFile(dir_handle, ".env.local", false, false);
Analytics.Features.dotenv = true;
}
}
@@ -408,26 +407,26 @@ pub const Loader = struct {
switch (comptime suffix) {
.development => {
if (dir.hasComptimeQuery(".env.development")) {
- try this.loadEnvFile(fs, dir_handle, ".env.development", false);
+ try this.loadEnvFile(dir_handle, ".env.development", false, true);
Analytics.Features.dotenv = true;
}
},
.production => {
if (dir.hasComptimeQuery(".env.production")) {
- try this.loadEnvFile(fs, dir_handle, ".env.production", false);
+ try this.loadEnvFile(dir_handle, ".env.production", false, true);
Analytics.Features.dotenv = true;
}
},
.@"test" => {
if (dir.hasComptimeQuery(".env.test")) {
- try this.loadEnvFile(fs, dir_handle, ".env.test", false);
+ try this.loadEnvFile(dir_handle, ".env.test", false, true);
Analytics.Features.dotenv = true;
}
},
}
if (dir.hasComptimeQuery(".env")) {
- try this.loadEnvFile(fs, dir_handle, ".env", false);
+ try this.loadEnvFile(dir_handle, ".env", false, false);
Analytics.Features.dotenv = true;
}
@@ -487,8 +486,13 @@ pub const Loader = struct {
Output.flush();
}
- pub fn loadEnvFile(this: *Loader, fs: *Fs.FileSystem.RealFS, dir: std.fs.Dir, comptime base: string, comptime override: bool) !void {
- _ = fs;
+ pub fn loadEnvFile(
+ this: *Loader,
+ dir: std.fs.Dir,
+ comptime base: string,
+ comptime override: bool,
+ comptime conditional: bool,
+ ) !void {
if (@field(this, base) != null) {
return;
}
@@ -565,6 +569,7 @@ pub const Loader = struct {
this.map,
override,
false,
+ conditional,
);
@field(this, base) = source;
@@ -789,6 +794,7 @@ const Parser = struct {
map: *Map,
comptime override: bool,
comptime is_process: bool,
+ comptime conditional: bool,
) void {
var count = map.map.count();
while (this.pos < this.src.len) {
@@ -804,19 +810,25 @@ const Parser = struct {
// https://github.com/oven-sh/bun/issues/1262
if (comptime !override) continue;
} else {
- allocator.free(entry.value_ptr.*);
+ allocator.free(entry.value_ptr.value);
}
}
- entry.value_ptr.* = allocator.dupe(u8, value) catch unreachable;
+ entry.value_ptr.* = .{
+ .value = allocator.dupe(u8, value) catch unreachable,
+ .conditional = conditional,
+ };
}
if (comptime !is_process) {
var it = map.iter();
while (it.next()) |entry| {
if (count > 0) {
count -= 1;
- } else if (expandValue(map, entry.value_ptr.*)) |value| {
- allocator.free(entry.value_ptr.*);
- entry.value_ptr.* = allocator.dupe(u8, value) catch unreachable;
+ } else if (expandValue(map, entry.value_ptr.value)) |value| {
+ allocator.free(entry.value_ptr.value);
+ entry.value_ptr.* = .{
+ .value = allocator.dupe(u8, value) catch unreachable,
+ .conditional = conditional,
+ };
}
}
}
@@ -828,14 +840,19 @@ const Parser = struct {
map: *Map,
comptime override: bool,
comptime is_process: bool,
+ comptime conditional: bool,
) void {
var parser = Parser{ .src = source.contents };
- parser._parse(allocator, map, override, is_process);
+ parser._parse(allocator, map, override, is_process, conditional);
}
};
pub const Map = struct {
- const HashTable = bun.StringArrayHashMap(string);
+ const HashTableValue = struct {
+ value: string,
+ conditional: bool,
+ };
+ const HashTable = bun.StringArrayHashMap(HashTableValue);
map: HashTable,
@@ -848,10 +865,10 @@ pub const Map = struct {
var it = env_map.iterator();
var i: usize = 0;
while (it.next()) |pair| : (i += 1) {
- const env_buf = try arena.allocSentinel(u8, pair.key_ptr.len + pair.value_ptr.len + 1, 0);
+ const env_buf = try arena.allocSentinel(u8, pair.key_ptr.len + pair.value_ptr.value.len + 1, 0);
bun.copy(u8, env_buf, pair.key_ptr.*);
env_buf[pair.key_ptr.len] = '=';
- bun.copy(u8, env_buf[pair.key_ptr.len + 1 ..], pair.value_ptr.*);
+ bun.copy(u8, env_buf[pair.key_ptr.len + 1 ..], pair.value_ptr.value);
envp_buf[i] = env_buf.ptr;
}
std.debug.assert(i == envp_count);
@@ -864,7 +881,10 @@ pub const Map = struct {
var iter_ = this.map.iterator();
while (iter_.next()) |entry| {
- try env_map.putMove(bun.constStrToU8(entry.key_ptr.*), bun.constStrToU8(entry.value_ptr.*));
+ // Allow var from .env.development or .env.production to be loaded again. Also don't clone empty vars.
+ if (!entry.value_ptr.conditional and entry.value_ptr.value.len > 0) {
+ try env_map.putMove(bun.constStrToU8(entry.key_ptr.*), bun.constStrToU8(entry.value_ptr.value));
+ }
}
return env_map;
@@ -879,7 +899,10 @@ pub const Map = struct {
}
pub inline fn put(this: *Map, key: string, value: string) !void {
- try this.map.put(key, value);
+ try this.map.put(key, .{
+ .value = value,
+ .conditional = false,
+ });
}
pub fn jsonStringify(self: *const @This(), writer: anytype) !void {
@@ -907,22 +930,28 @@ pub const Map = struct {
this: *const Map,
key: string,
) ?string {
- return this.map.get(key);
+ return if (this.map.get(key)) |entry| entry.value else null;
}
pub fn get_(
this: *const Map,
key: string,
) ?string {
- return this.map.get(key);
+ return if (this.map.get(key)) |entry| entry.value else null;
}
pub inline fn putDefault(this: *Map, key: string, value: string) !void {
- _ = try this.map.getOrPutValue(key, value);
+ _ = try this.map.getOrPutValue(key, .{
+ .value = value,
+ .conditional = false,
+ });
}
pub inline fn getOrPut(this: *Map, key: string, value: string) !void {
- _ = try this.map.getOrPutValue(key, value);
+ _ = try this.map.getOrPutValue(key, .{
+ .value = value,
+ .conditional = false,
+ });
}
};