Skip to content

Commit

Permalink
Use Sprache for parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
rogusdev committed Nov 29, 2020
1 parent 5c1e3f5 commit 1204d05
Show file tree
Hide file tree
Showing 20 changed files with 1,274 additions and 542 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ You can also pass a `LoadOptions` object arg to all `DotNetEnv.Env.Load` variant

```csharp
new DotNetEnv.Env.LoadOptions(
trimWhitespace: false,
isEmbeddedHashComment: false,
unescapeQuotedValues: false,
clobberExistingVars: false,
parseVariables: false
trimWhitespace: true,
isEmbeddedHashComment: true,
unescapeQuotedValues: true,
clobberExistingVars: true,
parseVariables: true
)
```

Expand Down Expand Up @@ -167,13 +167,23 @@ DotNetEnv.Env.Load(
FIRST_KEY=value1
SECOND_KEY=value2and$FIRST_KEY
THIRD_KEY=$EXISTING_ENVIRONMENT_VARIABLE;andvalue3
FOURTH_KEY=$DNE_VAR;nope
```

Would then be available as
```csharp
"value1" == System.Environment.GetEnvironmentVariable("FIRST_KEY")
"value2andvalue1" == System.Environment.GetEnvironmentVariable("SECOND_KEY")
"value;andvalue3" == System.Environment.GetEnvironmentVariable("THIRD_KEY") //EXISTING_ENVIRONMENT_VARIABLE already set to "value"
";nope" == System.Environment.GetEnvironmentVariable("FOURTH_KEY") //DNE_VAR does not exist (has no value)
```

`false` would mean:
```csharp
"value1" == System.Environment.GetEnvironmentVariable("FIRST_KEY")
"value2and$FIRST_KEY" == System.Environment.GetEnvironmentVariable("SECOND_KEY")
"$EXISTING_ENVIRONMENT_VARIABLE;andvalue3" == System.Environment.GetEnvironmentVariable("THIRD_KEY")
"$DNE_VAR;nope" == System.Environment.GetEnvironmentVariable("FOURTH_KEY")
```

## A Note about Production and the Purpose of this library
Expand Down
3 changes: 3 additions & 0 deletions src/DotNetEnv/AssmblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("DotNetEnv.Tests")]
10 changes: 7 additions & 3 deletions src/DotNetEnv/DotNetEnv.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<Title>DotNetEnv</Title>
<Description>A .NET library to load environment variables from .env files</Description>
<AssemblyTitle>DotNetEnv</AssemblyTitle>
<AssemblyVersion>1.4.0</AssemblyVersion>
<PackageVersion>1.4.0</PackageVersion>
<AssemblyVersion>2.0.0</AssemblyVersion>
<PackageVersion>2.0.0</PackageVersion>
<TargetFramework>netstandard1.3</TargetFramework>
<AssemblyName>DotNetEnv</AssemblyName>
<OutputType>Library</OutputType>
Expand All @@ -17,6 +17,10 @@
</PropertyGroup>

<ItemGroup>
<None Include="../../LICENSE" Pack="true" PackagePath=""/>
<None Include="../../LICENSE" Pack="true" PackagePath="" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Sprache" Version="2.3.1" />
</ItemGroup>
</Project>
69 changes: 31 additions & 38 deletions src/DotNetEnv/Env.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;

namespace DotNetEnv
{
Expand All @@ -11,42 +13,43 @@ public class Env

private static LoadOptions DEFAULT_OPTIONS = new LoadOptions();

public static void Load(string[] lines, LoadOptions options = null)
public static IEnumerable<KeyValuePair<string, string>> LoadLines(string[] lines, LoadOptions options = null)
{
if (options == null) options = DEFAULT_OPTIONS;

Vars envFile = Parser.Parse(
lines,
options.TrimWhitespace,
options.IsEmbeddedHashComment,
options.UnescapeQuotedValues,
options.ParseVariables
);
LoadVars.SetEnvironmentVariables(envFile, options.ClobberExistingVars);
return Load(String.Join("\n", lines), options);
}

public static void Load(string path, LoadOptions options = null)
public static IEnumerable<KeyValuePair<string, string>> LoadFile(string path, LoadOptions options = null)
{
if (!File.Exists(path)) return;
Load(File.ReadAllLines(path), options);
// in production, there should be no .env file, so this should be the common code path
if (!File.Exists(path))
{
return Enumerable.Empty<KeyValuePair<string, string>>();
}
return Load(File.ReadAllText(path), options);
}

public static void Load(Stream file, LoadOptions options = null)
public static IEnumerable<KeyValuePair<string, string>> Load(string contents, LoadOptions options = null)
{
var lines = new List<string>();
var currentLine = "";
using (var reader = new StreamReader(file))
if (options == null) options = DEFAULT_OPTIONS;

if (options.ParseEnvVars)
{
while (currentLine != null)
if (options.ClobberExistingVars)
{
currentLine = reader.ReadLine();
if (currentLine != null) lines.Add(currentLine);
return Parsers.ParseDotenvFile(contents, Parsers.SetEnvVar);
}
else
{
return Parsers.ParseDotenvFile(contents, Parsers.NoClobberSetEnvVar);
}
}
Load(lines.ToArray(), options);
else
{
return Parsers.ParseDotenvFile(contents, Parsers.DoNotSetEnvVar);
}
}

public static void Load(LoadOptions options = null) =>
public static IEnumerable<KeyValuePair<string, string>> Load(LoadOptions options = null) =>
Load(Path.Combine(Directory.GetCurrentDirectory(), DEFAULT_ENVFILENAME), options);

public static string GetString(string key, string fallback = default(string)) =>
Expand All @@ -63,25 +66,15 @@ public static void Load(LoadOptions options = null) =>

public class LoadOptions
{
public bool TrimWhitespace { get; }
public bool IsEmbeddedHashComment { get; }
public bool UnescapeQuotedValues { get; }
public bool ParseEnvVars { get; }
public bool ClobberExistingVars { get; }
public bool ParseVariables { get; }

public LoadOptions(
bool trimWhitespace = true,
bool isEmbeddedHashComment = true,
bool unescapeQuotedValues = true,
bool clobberExistingVars = true,
bool parseVariables = true
)
{
TrimWhitespace = trimWhitespace;
IsEmbeddedHashComment = isEmbeddedHashComment;
UnescapeQuotedValues = unescapeQuotedValues;
bool parseEnvVars = true,
bool clobberExistingVars = true
) {
ParseEnvVars = parseEnvVars;
ClobberExistingVars = clobberExistingVars;
ParseVariables = parseVariables;
}
}
}
Expand Down
58 changes: 58 additions & 0 deletions src/DotNetEnv/IValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Linq;
using System.Collections.Generic;

namespace DotNetEnv
{
public interface IValue
{
string GetValue ();
}

public class ValueInterpolated : IValue
{
private readonly string _id;

public ValueInterpolated (string id)
{
_id = id;
}

public string GetValue ()
{
return Environment.GetEnvironmentVariable(_id) ?? string.Empty;
}
}

public class ValueActual : IValue
{
private readonly string _value;

public ValueActual (IEnumerable<string> strs)
{
_value = string.Join(string.Empty, strs);
}

public string GetValue ()
{
return _value;
}
}

public class ValueCalculator
{
public readonly string Value;

public ValueCalculator (IEnumerable<IValue> values)
{
// note that we do want this lookup / calculation / GetValue calls in the ctor
// because it is the state of the world at the moment that this value is calculated
Value = string.Join(string.Empty, values.Select(val => val.GetValue()));
}

public override string ToString()
{
return Value;
}
}
}
16 changes: 0 additions & 16 deletions src/DotNetEnv/LoadVars.cs

This file was deleted.

Loading

0 comments on commit 1204d05

Please sign in to comment.