From 049f8df9573753ad05814e7f642a2a98fef47e3e Mon Sep 17 00:00:00 2001 From: Adam Patridge Date: Fri, 25 Aug 2017 16:28:43 -0600 Subject: [PATCH] Add ArgumentOrEnvironmentVariable overload for strings. --- ...ntOrEnvironmentVariableAlias_BoolTests.cs} | 2 +- ...tOrEnvironmentVariableAlias_StringTests.cs | 136 ++++++++++++++++++ .../Cake.ArgumentHelpers.Tests.csproj | 8 +- Cake.ArgumentHelpers.sln | 83 ++++++----- .../ArgumentOrEnvironmentVariableAlias.cs | 29 ++++ README.md | 24 +++- 6 files changed, 237 insertions(+), 45 deletions(-) rename Cake.ArgumentHelpers.Tests/{ArgumentOrEnvironmentVariableAliasTests.cs => ArgumentOrEnvironmentVariableAlias_BoolTests.cs} (99%) create mode 100644 Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAlias_StringTests.cs diff --git a/Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAliasTests.cs b/Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAlias_BoolTests.cs similarity index 99% rename from Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAliasTests.cs rename to Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAlias_BoolTests.cs index a54aeae..89c8baa 100644 --- a/Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAliasTests.cs +++ b/Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAlias_BoolTests.cs @@ -4,7 +4,7 @@ using Moq; namespace Cake.ArgumentHelpers.Tests { [TestFixture()] - public class ArgumentOrEnvironmentVariableAliasTests { + public class ArgumentOrEnvironmentVariableAlias_BoolTests { Mock cakeContextMock; Mock cakeArgumentsMock; Mock cakeEnvironmentMock; diff --git a/Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAlias_StringTests.cs b/Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAlias_StringTests.cs new file mode 100644 index 0000000..6b751fa --- /dev/null +++ b/Cake.ArgumentHelpers.Tests/ArgumentOrEnvironmentVariableAlias_StringTests.cs @@ -0,0 +1,136 @@ +using NUnit.Framework; +using Cake.Core; +using Moq; + +namespace Cake.ArgumentHelpers.Tests { + [TestFixture()] + public class ArgumentOrEnvironmentVariableAlias_StringTests { + Mock cakeContextMock; + Mock cakeArgumentsMock; + Mock cakeEnvironmentMock; + + [SetUp] + public void Setup() { + cakeContextMock = new Mock(); + cakeArgumentsMock = new Mock(); + cakeEnvironmentMock = new Mock(); + cakeContextMock.Setup(cakeContext => cakeContext.Arguments).Returns(cakeArgumentsMock.Object); + cakeContextMock.Setup(cakeContext => cakeContext.Environment).Returns(cakeEnvironmentMock.Object); + } + + void SetupVariables(string key, string environmentPrefix, string argumentValue, string environmentValue) { + bool hasArgument = argumentValue != null; + cakeArgumentsMock.Setup(x => x.HasArgument(key)).Returns(hasArgument); + if (hasArgument) { + cakeArgumentsMock.Setup(x => x.GetArgument(key)).Returns(argumentValue.ToString()); + } + bool hasEnvironmentVariable = environmentValue != null; + if (hasEnvironmentVariable) + { + cakeEnvironmentMock.Setup(x => x.GetEnvironmentVariable(environmentPrefix + key)).Returns(environmentValue); + } + } + + [Test] + public void SomeArgumentAndNullEnvironment_ReturnsSome() { + var testKey = "someVariable"; + var testKeyEnvironmentPrefix = "somePrefix_"; + string testArgumentValue = "Some"; + string testEnvironmentValue = null; + + SetupVariables(testKey, testKeyEnvironmentPrefix, testArgumentValue, testEnvironmentValue); + + var expected = testArgumentValue; + var actual = cakeContextMock.Object.ArgumentOrEnvironmentVariable(testKey, testKeyEnvironmentPrefix, (string)null); + + Assert.AreEqual(expected, actual, "Didn't find Argument variable."); + } + [Test] + public void NullArgumentAndNullEnvironmentAndNullDefault_ReturnsNull() { + var testKey = "someVariable"; + var testKeyEnvironmentPrefix = "somePrefix_"; + string testArgumentValue = null; + string testEnvironmentValue = null; + + SetupVariables(testKey, testKeyEnvironmentPrefix, testArgumentValue, testEnvironmentValue); + + var expected = (string)null; + var actual = cakeContextMock.Object.ArgumentOrEnvironmentVariable(testKey, testKeyEnvironmentPrefix, (string)null); + + Assert.AreEqual(expected, actual, "Found unexpected variable value."); + } + [Test] + public void NullArgumentAndSomeEnvironment_ReturnsSome() { + var testKey = "someVariable"; + var testKeyEnvironmentPrefix = "somePrefix_"; + string testArgumentValue = null; + string testEnvironmentValue = "Some"; + + SetupVariables(testKey, testKeyEnvironmentPrefix, testArgumentValue, testEnvironmentValue); + + var expected = testEnvironmentValue; + var actual = cakeContextMock.Object.ArgumentOrEnvironmentVariable(testKey, testKeyEnvironmentPrefix, (string)null); + + Assert.AreEqual(expected, actual, "Didn't find Environment variable."); + } + [Test] + public void NullArgumentAndSomeEnvironmentWithoutPrefix_ReturnsSome() { + var testKey = "someVariable"; + var testKeyEnvironmentPrefix = (string)null; + string testArgumentValue = null; + string testEnvironmentValue = "Some"; + + SetupVariables(testKey, testKeyEnvironmentPrefix, testArgumentValue, testEnvironmentValue); + + var expected = testEnvironmentValue; + var actual = cakeContextMock.Object.ArgumentOrEnvironmentVariable(testKey, testKeyEnvironmentPrefix, (string)null); + + Assert.AreEqual(expected, actual, "Didn't find Environment variable without prefix."); + } + [Test] + public void SomeArgumentAndOtherEnvironment_ReturnsSome() { + var testKey = "someVariable"; + var testKeyEnvironmentPrefix = "somePrefix_"; + string testArgumentValue = "Some"; + string testEnvironmentValue = "Other"; + + SetupVariables(testKey, testKeyEnvironmentPrefix, testArgumentValue, testEnvironmentValue); + + var expected = testArgumentValue; + var actual = cakeContextMock.Object.ArgumentOrEnvironmentVariable(testKey, testKeyEnvironmentPrefix, (string)null); + + Assert.AreEqual(expected, actual, "Didn't find correct variable value from Argument source."); + } + [Test] + public void NullArgumentAndNullEnvironment_ReturnsDefault() + { + var testKey = "someVariable"; + var testKeyEnvironmentPrefix = "somePrefix_"; + var defaultValue = "Default"; + string testArgumentValue = null; + string testEnvironmentValue = null; + + SetupVariables(testKey, testKeyEnvironmentPrefix, testArgumentValue, testEnvironmentValue); + + var expected = defaultValue; + var actual = cakeContextMock.Object.ArgumentOrEnvironmentVariable(testKey, testKeyEnvironmentPrefix, defaultValue); + + Assert.AreEqual(expected, actual, "Didn't fall back on default value."); + } + [Test] + public void NullArgumentAndNullEnvironmentWithoutDefault_ReturnsNull() + { + var testKey = "someVariable"; + var testKeyEnvironmentPrefix = "somePrefix_"; + string testArgumentValue = null; + string testEnvironmentValue = null; + + SetupVariables(testKey, testKeyEnvironmentPrefix, testArgumentValue, testEnvironmentValue); + + var expected = (string)null; + var actual = cakeContextMock.Object.ArgumentOrEnvironmentVariable(testKey, testKeyEnvironmentPrefix); + + Assert.AreEqual(expected, actual, "Didn't fail to a null value."); + } + } +} diff --git a/Cake.ArgumentHelpers.Tests/Cake.ArgumentHelpers.Tests.csproj b/Cake.ArgumentHelpers.Tests/Cake.ArgumentHelpers.Tests.csproj index f01a60f..bbce4f6 100644 --- a/Cake.ArgumentHelpers.Tests/Cake.ArgumentHelpers.Tests.csproj +++ b/Cake.ArgumentHelpers.Tests/Cake.ArgumentHelpers.Tests.csproj @@ -1,4 +1,4 @@ - + Debug @@ -43,7 +43,8 @@ - + + @@ -54,5 +55,8 @@ Cake.ArgumentHelpers + + + \ No newline at end of file diff --git a/Cake.ArgumentHelpers.sln b/Cake.ArgumentHelpers.sln index 742caf1..0a7131b 100644 --- a/Cake.ArgumentHelpers.sln +++ b/Cake.ArgumentHelpers.sln @@ -1,13 +1,15 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.13 +VisualStudioVersion = 15.0.26730.10 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.ArgumentHelpers", "Cake.ArgumentHelpers\Cake.ArgumentHelpers.csproj", "{9C50A7C4-E00D-4851-8311-81135D062C77}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EA17B50A-988B-47C1-9840-DC7347D88259}" ProjectSection(SolutionItems) = preProject + LICENSE = LICENSE Package.nuspec = Package.nuspec + README.md = README.md EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.ArgumentHelpers.Tests", "Cake.ArgumentHelpers.Tests\Cake.ArgumentHelpers.Tests.csproj", "{1297E243-9A95-45A5-A5C6-AAAC94ECEE22}" @@ -30,42 +32,45 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - Policies = $0 - $0.TextStylePolicy = $1 - $1.NoTabsAfterNonTabs = True - $1.inheritsSet = VisualStudio - $1.inheritsScope = text/plain - $1.scope = text/x-csharp - $0.CSharpFormattingPolicy = $2 - $2.NamespaceBraceStyle = EndOfLine - $2.ClassBraceStyle = EndOfLine - $2.InterfaceBraceStyle = EndOfLine - $2.StructBraceStyle = EndOfLine - $2.EnumBraceStyle = EndOfLine - $2.MethodBraceStyle = EndOfLine - $2.ConstructorBraceStyle = EndOfLine - $2.DestructorBraceStyle = EndOfLine - $2.ElseNewLinePlacement = NewLine - $2.BeforeMethodDeclarationParentheses = False - $2.BeforeMethodCallParentheses = False - $2.BeforeConstructorDeclarationParentheses = False - $2.BeforeIndexerDeclarationBracket = False - $2.BeforeDelegateDeclarationParentheses = False - $2.AfterDelegateDeclarationParameterComma = True - $2.NewParentheses = False - $2.SpacesBeforeBrackets = False - $2.inheritsSet = Mono - $2.inheritsScope = text/x-csharp - $2.scope = text/x-csharp - $2.NewLinesForBracesInTypes = False - $2.NewLinesForBracesInMethods = False - $2.SpacingAfterMethodDeclarationName = False - $2.SpaceAfterMethodCallName = False - $2.SpaceBeforeOpenSquareBracket = False - $0.DotNetNamingPolicy = $3 - $3.DirectoryNamespaceAssociation = None - $3.ResourceNamePolicy = FileFormatDefault - StartupItem = Smudges.iOS\Smudges.iOS.csproj - EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E1B5DAA9-DAD7-4FEA-8B04-2E4A112C196F} + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + Policies = $0 + $0.TextStylePolicy = $1 + $1.NoTabsAfterNonTabs = True + $1.inheritsSet = VisualStudio + $1.inheritsScope = text/plain + $1.scope = text/x-csharp + $0.CSharpFormattingPolicy = $2 + $2.NamespaceBraceStyle = EndOfLine + $2.ClassBraceStyle = EndOfLine + $2.InterfaceBraceStyle = EndOfLine + $2.StructBraceStyle = EndOfLine + $2.EnumBraceStyle = EndOfLine + $2.MethodBraceStyle = EndOfLine + $2.ConstructorBraceStyle = EndOfLine + $2.DestructorBraceStyle = EndOfLine + $2.ElseNewLinePlacement = NewLine + $2.BeforeMethodDeclarationParentheses = False + $2.BeforeMethodCallParentheses = False + $2.BeforeConstructorDeclarationParentheses = False + $2.BeforeIndexerDeclarationBracket = False + $2.BeforeDelegateDeclarationParentheses = False + $2.AfterDelegateDeclarationParameterComma = True + $2.NewParentheses = False + $2.SpacesBeforeBrackets = False + $2.inheritsSet = Mono + $2.inheritsScope = text/x-csharp + $2.scope = text/x-csharp + $2.NewLinesForBracesInTypes = False + $2.NewLinesForBracesInMethods = False + $2.SpacingAfterMethodDeclarationName = False + $2.SpaceAfterMethodCallName = False + $2.SpaceBeforeOpenSquareBracket = False + $0.DotNetNamingPolicy = $3 + $3.DirectoryNamespaceAssociation = None + $3.ResourceNamePolicy = FileFormatDefault + StartupItem = Smudges.iOS\Smudges.iOS.csproj + EndGlobalSection EndGlobal diff --git a/Cake.ArgumentHelpers/ArgumentOrEnvironmentVariableAlias.cs b/Cake.ArgumentHelpers/ArgumentOrEnvironmentVariableAlias.cs index 23b5185..f2ae0f9 100644 --- a/Cake.ArgumentHelpers/ArgumentOrEnvironmentVariableAlias.cs +++ b/Cake.ArgumentHelpers/ArgumentOrEnvironmentVariableAlias.cs @@ -13,6 +13,7 @@ namespace Cake.ArgumentHelpers { /// /// Get a bool variable from various script inputs: first via Argument, then falling back on EnvironmentVariable, finally falling back on a default. /// + /// The argument name to attempt to find in the command line parameters, prefixing with to attempt to find in environment variables. /// An optional prefix used to qualify the same variable name when present in EnvironmentVariable form (e.g., "MySetting" command-line argument vs. "MyTool_MySetting" environment variable). /// Value found or default, first checked in command-line argument, then environment variable. [CakeMethodAlias] @@ -25,6 +26,7 @@ namespace Cake.ArgumentHelpers { /// /// Get a bool variable from various script inputs: first via Argument, then falling back on EnvironmentVariable, finally falling back on a default. /// + /// The argument name to attempt to find in either the command line parameters or environment variables. /// Value found or default, first checked in command-line argument, then environment variable. [CakeMethodAlias] [CakeAliasCategory("Argument")] @@ -32,5 +34,32 @@ namespace Cake.ArgumentHelpers { public static bool ArgumentOrEnvironmentVariable(this ICakeContext context, string name, bool defaultValue) { return context.ArgumentOrEnvironmentVariable(name, null, defaultValue); } + + /// + /// Get a string variable from various script inputs: first via Argument, then falling back on EnvironmentVariable, finally falling back on a default. + /// + /// The argument name to attempt to find in the command line parameters, prefixing with to attempt to find in environment variables. + /// An optional prefix used to qualify the same variable name when present in EnvironmentVariable form (e.g., "MySetting" command-line argument vs. "MyTool_MySetting" environment variable). + /// Value found or default, first checked in command-line argument, then environment variable. + [CakeMethodAlias] + [CakeAliasCategory("Argument")] + [CakeAliasCategory("Environment")] + public static string ArgumentOrEnvironmentVariable(this ICakeContext context, string name, string environmentNamePrefix, string defaultValue) { + return ArgumentAliases.Argument(context, name, EnvironmentAliases.EnvironmentVariable(context, environmentNamePrefix + name)) ?? defaultValue; + } + + /// + /// Get a string variable from various script inputs: first via Argument, then falling back on EnvironmentVariable, finally falling back on a default. + /// + /// The argument name to attempt to find in the command line parameters, prefixing with to attempt to find in environment variables. + /// An optional prefix used to qualify the same variable name when present in EnvironmentVariable form (e.g., "MySetting" command-line argument vs. "MyTool_MySetting" environment variable). + /// Value found or default, first checked in command-line argument, then environment variable. + [CakeMethodAlias] + [CakeAliasCategory("Argument")] + [CakeAliasCategory("Environment")] + public static string ArgumentOrEnvironmentVariable(this ICakeContext context, string name, string environmentNamePrefix) + { + return ArgumentOrEnvironmentVariable(context, name, environmentNamePrefix, null); + } } } diff --git a/README.md b/README.md index 1e984fa..aaf399b 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Just reference the Cake.ArgumentHelpers NuGet package directly in your build scr ## Available Aliases -Yep, just one so far... +Yep, just two so far... -### ArgumentOrEnvironmentVariable +### ArgumentOrEnvironmentVariable (for boolean values) `bool ArgumentOrEnvironmentVariable(..., string name, string environmentNamePrefix, bool defaultValue)` @@ -32,4 +32,22 @@ Given a potential command line argument of `SomeSetting` that could also be set var isSomethingTrue = ArgumentOrEnvironmentVariable("SomeSetting", "SomeProject_", false); ``` -## \ No newline at end of file +### ArgumentOrEnvironmentVariable (for string values) + +`string ArgumentOrEnvironmentVariable(..., string name, string environmentNamePrefix[, string defaultValue])` + +This is a helper method that simply wraps around nested calls to Arugment and EnvironmentVariable (and offering a fallback default). + +It works by getting a string value with multiple fallbacks: + +1. Try to get it from `Argument` (e.g., command line: `-SomeSetting="SomeValue"`) +2. Try to get it from `EnvironmentVariable` (e.g., `$env:SomeProject_SomeSetting = "SomeOtherValue";`) +3. Use a `defaultValue` if we don't find it elsewhere + +#### Example + +Given a potential command line argument of `SomeSetting` that could also be set via an environment variable prefixed with a project name, get the boolean value or `false` if it isn't found: + +```csharp +var someVariableValue = ArgumentOrEnvironmentVariable("SomeSetting", "SomeProject_", "SomeFallbackValue"); +```