using System; using System.Globalization; using System.IO; using System.Text.RegularExpressions; namespace UltraCombos { public static class DotNetEnv { private static readonly Regex lineRegex = new Regex( @"(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*""(?:\\""|[^""])*""|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)", RegexOptions.Multiline | RegexOptions.Compiled); public static void Load(string path = ".env") { if (!File.Exists(path)) { return; } var src = File.ReadAllText(path); src = src.Replace("\r\n", "\n").Replace("\r", "\n"); var keys = new System.Collections.Generic.List(); var matches = lineRegex.Matches(src); foreach (Match match in matches) { var key = match.Groups[1].Value; var value = match.Groups[2].Value.Trim(); if (string.IsNullOrEmpty(key)) { continue; } var maybeQuote = value.Length > 0 ? value[0] : (char?)null; value = Regex.Replace(value, @"^(['""`])([\s\S]*)\1$", "$2"); if (maybeQuote == '"') { value = value.Replace("\\n", "\n").Replace("\\r", "\r"); } Environment.SetEnvironmentVariable(key, value); keys.Add(key); } Log.Info("DotNetEnv", $"Loaded environment variable:\n{string.Join("\n", keys)}"); } public static bool TryGet(string key, out string value) { value = Environment.GetEnvironmentVariable(key); return !string.IsNullOrEmpty(value); } public static bool TryGetAs(string key, out T value) where T : struct { var raw = Environment.GetEnvironmentVariable(key); if (string.IsNullOrEmpty(raw)) { value = default; return false; } try { value = (T)Convert.ChangeType(raw, typeof(T), CultureInfo.InvariantCulture); return true; } catch { value = default; return false; } } } }