diff --git a/.appveyor.yml b/.appveyor.yml
index afb3780..1180781 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -22,5 +22,9 @@ branches:
# Build Cache #
#---------------------------------#
cache:
-- Source\packages -> Source\**\packages.config
-- tools -> setup.cake
\ No newline at end of file
+- tools -> setup.cake
+
+#---------------------------------#
+# Build Image #
+#---------------------------------#
+image: Visual Studio 2017
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f1e3d20..4623fec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -250,3 +250,6 @@ paket-files/
# JetBrains Rider
.idea/
*.sln.iml
+
+BuildArtifacts
+tools
diff --git a/nuspec/nuget/Cake.DotEnv.Module.nuspec b/nuspec/nuget/Cake.DotEnv.Module.nuspec
index 0627745..843fcfc 100644
--- a/nuspec/nuget/Cake.DotEnv.Module.nuspec
+++ b/nuspec/nuget/Cake.DotEnv.Module.nuspec
@@ -2,17 +2,24 @@
Cake.DotEnv.Module
- 0.0.0
+ 0.0.1
Jamie Phillips
Jamie Phillips
Cake Module for using the dotenv file for settings local environment variables.
Cake Module for using the dotenv file for settings local environment variables.
https://github.com/cake-contrib/Cake.DotEnv.Module/blob/master/LICENSE
https://github.com/cake-contrib/Cake.DotEnv.Module/Cake.Netlify
+ https://cdn.jsdelivr.net/gh/cake-contrib/graphics/png/cake-contrib-medium.png
false
Copyright (c) Jamie Phillips 2017 - Present
Cake, Script, Build, DotEnv, Module
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/setup.cake b/setup.cake
index 51c1926..a9ea031 100644
--- a/setup.cake
+++ b/setup.cake
@@ -8,7 +8,9 @@ BuildParameters.SetParameters(context: Context,
title: "Cake.DotEnv.Module",
repositoryOwner: "cake-contrib",
repositoryName: "Cake.DotEnv.Module",
- appVeyorAccountName: "cakecontrib");
+ appVeyorAccountName: "cakecontrib",
+ shouldRunDupFinder: false,
+ shouldRunInspectCode: false);
BuildParameters.PrintParameters(Context);
@@ -18,4 +20,4 @@ ToolSettings.SetToolSettings(context: Context,
testCoverageFilter: "+[*]* -[xunit.*]* -[Cake.Core]* -[Cake.Testing]* -[*.Tests]* ",
testCoverageExcludeByAttribute: "*.ExcludeFromCodeCoverage*",
testCoverageExcludeByFile: "*/*Designer.cs;*/*.g.cs;*/*.g.i.cs");
-Build.Run();
+Build.RunDotNetCore();
diff --git a/src/Cake.DotEnv.Module.Tests/Cake.DotEnv.Module.Tests.csproj b/src/Cake.DotEnv.Module.Tests/Cake.DotEnv.Module.Tests.csproj
index e78ecec..f27bb2e 100644
--- a/src/Cake.DotEnv.Module.Tests/Cake.DotEnv.Module.Tests.csproj
+++ b/src/Cake.DotEnv.Module.Tests/Cake.DotEnv.Module.Tests.csproj
@@ -1,13 +1,31 @@
- netstandard1.6
+ netcoreapp2.0
+ false
+ false
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
\ No newline at end of file
diff --git a/src/Cake.DotEnv.Module.Tests/Class1.cs b/src/Cake.DotEnv.Module.Tests/Class1.cs
deleted file mode 100644
index ad688c3..0000000
--- a/src/Cake.DotEnv.Module.Tests/Class1.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-
-namespace Cake.DotEnv.Module.Tests
-{
- public class Class1
- {
- }
-}
diff --git a/src/Cake.DotEnv.Module.Tests/DotEnvTests.cs b/src/Cake.DotEnv.Module.Tests/DotEnvTests.cs
new file mode 100644
index 0000000..30b2df9
--- /dev/null
+++ b/src/Cake.DotEnv.Module.Tests/DotEnvTests.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Linq;
+
+using Xunit;
+
+namespace Cake.DotEnv.Module.Tests
+{
+ public class DotEnvTests : IDisposable
+ {
+ private readonly FakeCakeContext context;
+
+ public DotEnvTests()
+ {
+ context = new FakeCakeContext();
+ }
+
+ public void Dispose()
+ {
+ context.DumpLogs();
+ }
+
+ [Fact]
+ public void ParseEnvString()
+ {
+ var data = @"
+DOTENV_TEST_ENV1=Value 1
+
+DOTENV_TEST_ENV2=Value 2
+ DOTENV_TEST_ENV3 = Value 3
+#DOTENV_TEST_ENV4=Value 4";
+
+ CakeAliases.LoadEnvString(context.CakeContext, data);
+
+ Assert.Equal("Value 1", Environment.GetEnvironmentVariable("DOTENV_TEST_ENV1"));
+ Assert.Equal("Value 2", Environment.GetEnvironmentVariable("DOTENV_TEST_ENV2"));
+ Assert.Equal("Value 3", Environment.GetEnvironmentVariable("DOTENV_TEST_ENV3"));
+ Assert.Null(Environment.GetEnvironmentVariable("DOTENV_TEST_ENV4"));
+
+ var vars = Environment.GetEnvironmentVariables().Keys.OfType().Where(x => x.StartsWith("DOTENV_TEST_")).ToList();
+
+ Assert.Equal(3, vars.Count);
+
+ // Delete test vars
+ foreach (var variable in vars)
+ {
+ Environment.SetEnvironmentVariable(variable, null);
+ }
+ }
+
+ [Fact]
+ public void ParseEnvFile()
+ {
+ Assert.True(CakeAliases.LoadDotEnv(context.CakeContext, "Testdata\\testdata01.env"));
+
+ Assert.Equal(".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW", Environment.GetEnvironmentVariable("DOTENV_TEST_PATHEXT"));
+ Assert.Equal("$P$G", Environment.GetEnvironmentVariable("DOTENV_TEST_PROMPT"));
+ Assert.Equal("-Xms256m -Xmx512m", Environment.GetEnvironmentVariable("DOTENV_TEST_JAVA_OPTS"));
+
+ var vars = Environment.GetEnvironmentVariables().Keys.OfType().Where(x => x.StartsWith("DOTENV_TEST_")).ToList();
+
+ Assert.Equal(17, vars.Count);
+
+ // Delete test vars
+ foreach (var variable in vars)
+ {
+ Environment.SetEnvironmentVariable(variable, null);
+ }
+ }
+ }
+}
diff --git a/src/Cake.DotEnv.Module.Tests/FakeCakeArguments.cs b/src/Cake.DotEnv.Module.Tests/FakeCakeArguments.cs
new file mode 100644
index 0000000..1c33675
--- /dev/null
+++ b/src/Cake.DotEnv.Module.Tests/FakeCakeArguments.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+
+using Cake.Core;
+
+namespace Cake.DotEnv.Module.Tests
+{
+ internal sealed class FakeCakeArguments : ICakeArguments
+ {
+ private readonly Dictionary _arguments;
+
+ ///
+ /// Gets the arguments.
+ ///
+ /// The arguments.
+ public IReadOnlyDictionary Arguments => _arguments;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public FakeCakeArguments()
+ {
+ _arguments = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ }
+
+ ///
+ /// Initializes the argument list.
+ ///
+ /// The arguments.
+ public void SetArguments(IDictionary arguments)
+ {
+ if (arguments == null)
+ {
+ throw new ArgumentNullException(nameof(arguments));
+ }
+
+ _arguments.Clear();
+
+ foreach ((string key, string value) in arguments)
+ {
+ _arguments.Add(key, value);
+ }
+ }
+
+ ///
+ /// Determines whether or not the specified argument exist.
+ ///
+ /// The argument name.
+ ///
+ /// true if the argument exist; otherwise false.
+ ///
+ public bool HasArgument(string name)
+ {
+ return _arguments.ContainsKey(name);
+ }
+
+ ///
+ /// Gets an argument.
+ ///
+ /// The argument name.
+ /// The argument value.
+ public string GetArgument(string name)
+ {
+ return _arguments.ContainsKey(name) ? _arguments[name] : null;
+ }
+ }
+}
diff --git a/src/Cake.DotEnv.Module.Tests/FakeCakeContext.cs b/src/Cake.DotEnv.Module.Tests/FakeCakeContext.cs
new file mode 100644
index 0000000..1b14a48
--- /dev/null
+++ b/src/Cake.DotEnv.Module.Tests/FakeCakeContext.cs
@@ -0,0 +1,55 @@
+using System;
+
+using Cake.Core;
+using Cake.Core.IO;
+using Cake.Core.Tooling;
+using Cake.Testing;
+
+using Path = System.IO.Path;
+using NSubstitute;
+
+namespace Cake.DotEnv.Module.Tests
+{
+
+ public class FakeCakeContext
+ {
+ private readonly ICakeContext context;
+ private readonly FakeLog log;
+ private readonly DirectoryPath testsDir;
+
+ public FakeCakeContext()
+ {
+ testsDir = new DirectoryPath(Path.GetFullPath(AppContext.BaseDirectory));
+
+ var environment = FakeEnvironment.CreateUnixEnvironment(false);
+
+ var fileSystem = new FakeFileSystem(environment);
+ var globber = new Globber(fileSystem, environment);
+ log = new FakeLog();
+ var args = new FakeCakeArguments();
+ var registry = new WindowsRegistry();
+
+ var config = new FakeConfiguration();
+ var tools = new ToolLocator(environment, new ToolRepository(environment), new ToolResolutionStrategy(fileSystem, environment, globber, config));
+ var processRunner = new ProcessRunner(fileSystem, environment, log, tools, config);
+ var data = Substitute.For();
+ context = new CakeContext(fileSystem, environment, globber, log, args, processRunner, registry, tools, data, config);
+ context.Environment.WorkingDirectory = testsDir;
+ }
+
+ public DirectoryPath WorkingDirectory => testsDir;
+
+ public ICakeContext CakeContext => context;
+
+ public string GetLogs()
+ {
+ return string.Join(Environment.NewLine, log.Entries);
+ }
+
+ public void DumpLogs()
+ {
+ foreach (var m in log.Entries)
+ Console.WriteLine(m);
+ }
+ }
+}
diff --git a/src/Cake.DotEnv.Module.Tests/Testdata/testdata01.env b/src/Cake.DotEnv.Module.Tests/Testdata/testdata01.env
new file mode 100644
index 0000000..fe3ed8e
--- /dev/null
+++ b/src/Cake.DotEnv.Module.Tests/Testdata/testdata01.env
@@ -0,0 +1,17 @@
+DOTENV_TEST_ALLUSERSPROFILE=C:\ProgramData
+DOTENV_TEST_ANDROID_SDK_HOME=C:\Android
+DOTENV_TEST_CommonProgramFiles=C:\Program Files\Common Files
+DOTENV_TEST_CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
+DOTENV_TEST_CommonProgramW6432=C:\Program Files\Common Files
+DOTENV_TEST_JAVA_OPTS=-Xms256m -Xmx512m
+DOTENV_TEST_OS=Windows_NT
+DOTENV_TEST_PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW
+DOTENV_TEST_PROCESSOR_ARCHITECTURE=AMD64
+DOTENV_TEST_ProgramData=C:\ProgramData
+DOTENV_TEST_ProgramFiles=C:\Program Files
+DOTENV_TEST_ProgramFiles(x86)=C:\Program Files (x86)
+DOTENV_TEST_ProgramW6432=C:\Program Files
+DOTENV_TEST_PROMPT=$P$G
+DOTENV_TEST_SystemDrive=C:
+DOTENV_TEST_SystemRoot=C:\WINDOWS
+DOTENV_TEST_windir=C:\WINDOWS
diff --git a/src/Cake.DotEnv.Module/Cake.DotEnv.Module.csproj b/src/Cake.DotEnv.Module/Cake.DotEnv.Module.csproj
index e4d67dd..ff0f0d3 100644
--- a/src/Cake.DotEnv.Module/Cake.DotEnv.Module.csproj
+++ b/src/Cake.DotEnv.Module/Cake.DotEnv.Module.csproj
@@ -1,11 +1,25 @@
- netstandard1.6
+ net461;netstandard2.0
+ Cake.DotEnv.Module
+ Cake.DotEnv.Module
+ false
+ true
+ anycpu
+ portable
+
+ bin\$(Configuration)\$(TargetFramework)\Cake.DotEnv.Module.xml
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/src/Cake.DotEnv.Module/CakeAliases.cs b/src/Cake.DotEnv.Module/CakeAliases.cs
new file mode 100644
index 0000000..58eee67
--- /dev/null
+++ b/src/Cake.DotEnv.Module/CakeAliases.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Text;
+
+using Cake.Core;
+using Cake.Core.Annotations;
+using Cake.Core.Diagnostics;
+using Cake.Core.IO;
+
+namespace Cake.DotEnv.Module
+{
+ ///
+ /// Class CakeAliases.
+ ///
+ [CakeAliasCategory("Environment")]
+ [SuppressMessage("ReSharper", "UnusedMember.Global")]
+ public static class CakeAliases
+ {
+ ///
+ /// Loads the dot env.
+ ///
+ /// The context.
+ /// The dot env file. Is null, the filename ".env" is assumed.
+ /// The encoding or the default encoding if null
+ /// true if the dotenv file is found and processed, false otherwise.
+ /// context is null
+ [CakeMethodAlias]
+ [CakeAliasCategory("DotEnv")]
+ public static bool LoadDotEnv(
+ this ICakeContext context,
+ FilePath dotEnvFile = null,
+ Encoding encoding = null
+ )
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ if (dotEnvFile == null)
+ {
+ dotEnvFile = new FilePath(".env");
+ }
+
+ var filename = dotEnvFile.FullPath;
+ if (!File.Exists(filename))
+ {
+ context.Log.Error(".env file \"{0}\" not found", filename);
+ return false;
+ }
+
+ var fileEncoding = encoding ?? Encoding.Default;
+
+ var fileContent = File.ReadAllText(filename, fileEncoding);
+
+ context.LoadEnvString(fileContent);
+
+ return true;
+ }
+
+ ///
+ /// Loads the env string.
+ ///
+ /// The context.
+ /// The env data.
+ /// context or envData is null/empty
+ [CakeMethodAlias]
+ [CakeAliasCategory("DotEnv")]
+ public static void LoadEnvString(
+ this ICakeContext context,
+ string envData
+ )
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ if (string.IsNullOrWhiteSpace(envData))
+ {
+ throw new ArgumentNullException(nameof(envData));
+ }
+
+ var fileContent = envData.SplitLines();
+
+ foreach (var fileContentLine in fileContent)
+ {
+ var line = fileContentLine.Trim();
+
+ // Skip empty or comment lines
+ if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#"))
+ continue;
+
+ // Find first equal char
+ var assignmentIndex = line.IndexOf('=');
+
+ if (assignmentIndex == 0)
+ continue;
+
+ var key = line.Substring(0, assignmentIndex).Trim();
+ var value = line.Substring(assignmentIndex + 1, line.Length - (assignmentIndex + 1)).Trim();
+
+ if (key.Length == 0)
+ continue;
+
+ if (value.Length > 0)
+ {
+ context.Log.Information(Verbosity.Diagnostic, "DotEnv: Setting environment variable \"{0}\" to \"{1}\"", key, value);
+ Environment.SetEnvironmentVariable(key, value);
+ }
+ else
+ {
+ context.Log.Information(Verbosity.Diagnostic, "DotEnv: Unsetting environment variable \"{0}\"", key);
+ Environment.SetEnvironmentVariable(key, null);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Cake.DotEnv.Module/Class1.cs b/src/Cake.DotEnv.Module/Class1.cs
deleted file mode 100644
index e839ceb..0000000
--- a/src/Cake.DotEnv.Module/Class1.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-
-namespace Cake.DotEnv.Module
-{
- public class Class1
- {
- }
-}
diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs
new file mode 100644
index 0000000..0ba7245
--- /dev/null
+++ b/src/SolutionInfo.cs
@@ -0,0 +1,13 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by Cake.
+//
+//------------------------------------------------------------------------------
+using System.Reflection;
+
+[assembly: AssemblyCompany("Cake Contributions")]
+[assembly: AssemblyProduct("Cake.DotEnv")]
+[assembly: AssemblyVersion("0.1.0")]
+[assembly: AssemblyFileVersion("0.1.0")]
+[assembly: AssemblyInformationalVersion("0.1.0")]
+[assembly: AssemblyCopyright("Copyright © Cake Contributions 2017 - Present")]
\ No newline at end of file