-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Summary
I propose that we add a configuration provider for .env files.
They are very popular and convenient in the Linux/Docker/Docker Compose world. It would significantly simplify development environment configuration for services that use ASP.NET Core and require dependencies (supporting services) that run as containers. These application- and supporting services often require shared pieces of configuration, and keeping them in a single .env file is very convenient.
Describe the solution you'd like
A Microsoft-authored file configuration provider, similar to existing file configuration providers like the INI- or JSON ones.
I have a prototype:
class EnvFileConfigurationProvider : FileConfigurationProvider
{
public EnvFileConfigurationProvider(EnvFileConfigurationSource source) : base(source) { }
public override void Load(Stream stream)
{
var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var doubleQuotedValueRegex = new Regex(@"""([^""\\]*(?:\\.[^""\\]*)*)""");
var singleQuotedValueRegex = new Regex(@"'([^'\\]*(?:\\.[^'\\]*)*)'");
using (var reader = new StreamReader(stream))
{
while (reader.Peek() != -1)
{
string line = reader.ReadLine().Trim();
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
if (line.StartsWith("#", StringComparison.Ordinal))
{
continue; // It is a comment
}
int separator = line.IndexOf('=', StringComparison.Ordinal);
if (separator <= 0 || separator == (line.Length-1))
{
continue; // Multi-line values are not supported by this implementation.
}
string key = line.Substring(0, separator).Trim();
if (string.IsNullOrWhiteSpace(key))
{
throw new FormatException("Configuration setting name should not be empty");
}
string value = line.Substring(separator + 1).Trim();
var doubleQuotedValue = doubleQuotedValueRegex.Match(value);
if (doubleQuotedValue.Success)
{
value = doubleQuotedValue.Groups[1].Value;
}
else
{
var singleQuotedValue = singleQuotedValueRegex.Match(value);
if (singleQuotedValue.Success)
{
value = singleQuotedValue.Groups[1].Value;
}
else
{
int commentStart = value.IndexOf(" #", StringComparison.Ordinal);
if (commentStart > 0)
{
value = value.Substring(0, commentStart);
}
}
}
data[key] = value;
}
}
Data = data;
}
}Additional context
In hashicorp/terraform#23906 a user is asking to add support for .env files to Terraform and they also list libraries that allow .env files to be consumed from Node, Python, Ruby, and Go. The Node package has 15M weekly downloads and 13k GH stars.
There is a community NuGet package to parse .env files, but I propose we go a step further and have a Microsoft-authored configuration provider for these files added. It would make it much simpler to take dependency on this configuration provider from project templates for VS/VS Code, and incorporate it in examples.