diff --git a/src/Microsoft.DotNet.Watcher.Tools/Program.cs b/src/Microsoft.DotNet.Watcher.Tools/Program.cs index 16a7a17288..45b4721b62 100644 --- a/src/Microsoft.DotNet.Watcher.Tools/Program.cs +++ b/src/Microsoft.DotNet.Watcher.Tools/Program.cs @@ -30,7 +30,7 @@ namespace Microsoft.DotNet.Watcher public static int Main(string[] args) { - HandleDebugSwitch(ref args); + DebugHelper.HandleDebugSwitch(ref args); return new Program(PhysicalConsole.Singleton, Directory.GetCurrentDirectory()) .RunAsync(args) .GetAwaiter() @@ -141,17 +141,5 @@ namespace Microsoft.DotNet.Watcher return LogLevel.Information; } - - [Conditional("DEBUG")] - private static void HandleDebugSwitch(ref string[] args) - { - if (args.Length > 0 && string.Equals("--debug", args[0], StringComparison.OrdinalIgnoreCase)) - { - args = args.Skip(1).ToArray(); - Console.WriteLine("Waiting for debugger to attach. Press ENTER to continue"); - Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}"); - Console.ReadLine(); - } - } } } diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/CommandLineOptions.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/CommandLineOptions.cs index 2284b2ed25..9a397eee59 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/CommandLineOptions.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/CommandLineOptions.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Reflection; -using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.Tools.Internal; @@ -37,7 +36,7 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal var optionProject = app.Option("-p|--project ", "Path to project, default is current directory", CommandOptionType.SingleValue, inherited: true); - var optionConfig = app.Option("-c|--configuration ", $"The project configuration to use. Defaults to {Constants.DefaultConfiguration}", + var optionConfig = app.Option("-c|--configuration ", $"The project configuration to use. Defaults to 'Debug'", CommandOptionType.SingleValue, inherited: true); // the escape hatch if project evaluation fails, or if users want to alter a secret store other than the one @@ -47,8 +46,8 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal var options = new CommandLineOptions(); - app.Command("set", c => SetCommand.Configure(c, options)); - app.Command("remove", c => RemoveCommand.Configure(c, options)); + app.Command("set", c => SetCommand.Configure(c, options, console)); + app.Command("remove", c => RemoveCommand.Configure(c, options, console)); app.Command("list", c => ListCommand.Configure(c, options)); app.Command("clear", c => ClearCommand.Configure(c, options)); diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/MsBuildProjectFinder.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/MsBuildProjectFinder.cs index ed37e7ad87..a24843b04d 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/MsBuildProjectFinder.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/MsBuildProjectFinder.cs @@ -1,10 +1,9 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.IO; using System.Linq; -using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.Tools.Internal; namespace Microsoft.Extensions.SecretManager.Tools.Internal @@ -37,12 +36,12 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal if (projects.Count > 1) { - throw new GracefulException(Resources.FormatError_MultipleProjectsFound(projectPath)); + throw new FileNotFoundException(Resources.FormatError_MultipleProjectsFound(projectPath)); } if (projects.Count == 0) { - throw new GracefulException(Resources.FormatError_NoProjectsFound(projectPath)); + throw new FileNotFoundException(Resources.FormatError_NoProjectsFound(projectPath)); } return projects[0]; @@ -50,7 +49,7 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal if (!File.Exists(projectPath)) { - throw new GracefulException(Resources.FormatError_ProjectPath_NotFound(projectPath)); + throw new FileNotFoundException(Resources.FormatError_ProjectPath_NotFound(projectPath)); } return projectPath; diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs index 683f412c83..40d3dc52b9 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs @@ -3,11 +3,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; -using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Tools.Internal; namespace Microsoft.Extensions.SecretManager.Tools.Internal { @@ -24,7 +25,7 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal _logger = logger; } - public string Resolve(string project, string configuration = Constants.DefaultConfiguration) + public string Resolve(string project, string configuration = "Debug") { var finder = new MsBuildProjectFinder(_workingDirectory); var projectFile = finder.FindMsBuildProject(project); @@ -35,32 +36,37 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal var outputFile = Path.GetTempFileName(); _tempFiles.Add(outputFile); - var commandOutput = new List(); - var commandResult = Command.CreateDotNet("msbuild", - new[] { - targetFile, - "/nologo", - "/t:_FindUserSecretsProperty", - $"/p:Project={projectFile}", - $"/p:OutputFile={outputFile}", - $"/p:Configuration={configuration}" - }) - .CaptureStdErr() - .CaptureStdOut() - .OnErrorLine(l => commandOutput.Add(l)) - .OnOutputLine(l => commandOutput.Add(l)) - .Execute(); - - if (commandResult.ExitCode != 0) + var args = new[] { - _logger.LogDebug(string.Join(Environment.NewLine, commandOutput)); - throw new GracefulException(Resources.FormatError_ProjectFailedToLoad(projectFile)); + "msbuild", + targetFile, + "/nologo", + "/t:_FindUserSecretsProperty", + $"/p:Project={projectFile}", + $"/p:OutputFile={outputFile}", + $"/p:Configuration={configuration}" + }; + var psi = new ProcessStartInfo + { + FileName = DotNetMuxer.MuxerPathOrDefault(), + Arguments = ArgumentEscaper.EscapeAndConcatenate(args), + RedirectStandardOutput = true, + RedirectStandardError = true + }; + var process = Process.Start(psi); + process.WaitForExit(); + + if (process.ExitCode != 0) + { + _logger.LogDebug(process.StandardOutput.ReadToEnd()); + _logger.LogDebug(process.StandardError.ReadToEnd()); + throw new InvalidOperationException(Resources.FormatError_ProjectFailedToLoad(projectFile)); } var id = File.ReadAllText(outputFile)?.Trim(); if (string.IsNullOrEmpty(id)) { - throw new GracefulException(Resources.FormatError_ProjectMissingId(projectFile)); + throw new InvalidOperationException(Resources.FormatError_ProjectMissingId(projectFile)); } return id; diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/RemoveCommand.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/RemoveCommand.cs index 6e6e5af027..d896c31a87 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/RemoveCommand.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/RemoveCommand.cs @@ -1,9 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.DotNet.Cli.Utils; +using System; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Tools.Internal; namespace Microsoft.Extensions.SecretManager.Tools.Internal { @@ -11,7 +12,7 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal { private readonly string _keyName; - public static void Configure(CommandLineApplication command, CommandLineOptions options) + public static void Configure(CommandLineApplication command, CommandLineOptions options, IConsole console) { command.Description = "Removes the specified user secret"; command.HelpOption(); @@ -21,10 +22,12 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal { if (keyArg.Value == null) { - throw new GracefulException("Missing parameter value for 'name'.\nUse the '--help' flag to see info."); + console.Error.WriteLine(Resources.FormatError_MissingArgument("name").Red()); + return 1; } options.Command = new RemoveCommand(keyArg.Value); + return 0; }); } diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/SetCommand.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/SetCommand.cs index e8c3855961..013777210e 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/SetCommand.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/SetCommand.cs @@ -1,21 +1,18 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Diagnostics; +using System; using System.IO; using System.Text; -using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Tools.Internal; namespace Microsoft.Extensions.SecretManager.Tools.Internal { - public class SetCommand : ICommand + public class SetCommand { - private readonly string _keyName; - private readonly string _keyValue; - - public static void Configure(CommandLineApplication command, CommandLineOptions options) + public static void Configure(CommandLineApplication command, CommandLineOptions options, IConsole console) { command.Description = "Sets the user secret to the specified value"; command.ExtendedHelpText = @" @@ -34,72 +31,74 @@ Examples: command.OnExecute(() => { - options.Command = new SetCommand(nameArg.Value, valueArg.Value); + if (console.IsInputRedirected && nameArg.Value == null) + { + options.Command = new FromStdInStrategy(); + return 0; + } + + if (string.IsNullOrEmpty(nameArg.Value)) + { + console.Error.WriteLine(Resources.FormatError_MissingArgument("name").Red()); + return 1; + } + + if (valueArg.Value == null) + { + console.Error.WriteLine(Resources.FormatError_MissingArgument("value").Red()); + return 1; + } + + options.Command = new ForOneValueStrategy(nameArg.Value, valueArg.Value); + return 0; }); } - internal SetCommand(string keyName, string keyValue) + public class FromStdInStrategy : ICommand { - Debug.Assert(keyName != null || keyValue == null, "Inconsistent state. keyValue must not be null if keyName is null."); - _keyName = keyName; - _keyValue = keyValue; - } - - internal SetCommand() - { } - - public void Execute(CommandContext context) - { - if (context.Console.IsInputRedirected && _keyName == null) + public void Execute(CommandContext context) { - ReadFromInput(context); - } - else - { - SetFromArguments(context); - } - } - - private void ReadFromInput(CommandContext context) - { - // parses stdin with the same parser that Microsoft.Extensions.Configuration.Json would use - var provider = new ReadableJsonConfigurationProvider(); - using (var stream = new MemoryStream()) - { - using (var writer = new StreamWriter(stream, Encoding.Unicode, 1024, true)) + // parses stdin with the same parser that Microsoft.Extensions.Configuration.Json would use + var provider = new ReadableJsonConfigurationProvider(); + using (var stream = new MemoryStream()) { - writer.Write(context.Console.In.ReadToEnd()); // TODO buffer? + using (var writer = new StreamWriter(stream, Encoding.Unicode, 1024, true)) + { + writer.Write(context.Console.In.ReadToEnd()); // TODO buffer? + } + + stream.Seek(0, SeekOrigin.Begin); + provider.Load(stream); } - stream.Seek(0, SeekOrigin.Begin); - provider.Load(stream); + foreach (var k in provider.CurrentData) + { + context.SecretStore.Set(k.Key, k.Value); + } + + context.Logger.LogInformation(Resources.Message_Saved_Secrets, provider.CurrentData.Count); + + context.SecretStore.Save(); } - - foreach (var k in provider.CurrentData) - { - context.SecretStore.Set(k.Key, k.Value); - } - - context.Logger.LogInformation(Resources.Message_Saved_Secrets, provider.CurrentData.Count); - - context.SecretStore.Save(); } - private void SetFromArguments(CommandContext context) + public class ForOneValueStrategy : ICommand { - if (_keyName == null) + private readonly string _keyName; + private readonly string _keyValue; + + public ForOneValueStrategy(string keyName, string keyValue) { - throw new GracefulException(Resources.FormatError_MissingArgument("name")); + _keyName = keyName; + _keyValue = keyValue; } - if (_keyValue == null) + public void Execute(CommandContext context) { - throw new GracefulException((Resources.FormatError_MissingArgument("value"))); + context.SecretStore.Set(_keyName, _keyValue); + context.SecretStore.Save(); + context.Logger.LogInformation(Resources.Message_Saved_Secret, _keyName, _keyValue); } - - context.SecretStore.Set(_keyName, _keyValue); - context.SecretStore.Save(); - context.Logger.LogInformation(Resources.Message_Saved_Secret, _keyName, _keyValue); } } } \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec b/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec index f8c596e5e9..c9f2903331 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec +++ b/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec @@ -16,10 +16,9 @@ - - - - + + + diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Program.cs b/src/Microsoft.Extensions.SecretManager.Tools/Program.cs index 810c0a043d..656b0d9c05 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Program.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Program.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.Logging; using Microsoft.Extensions.SecretManager.Tools.Internal; using Microsoft.Extensions.Tools.Internal; @@ -58,20 +57,8 @@ namespace Microsoft.Extensions.SecretManager.Tools } catch (Exception exception) { - if (exception is GracefulException) - { - if (exception.InnerException != null) - { - Logger.LogInformation(exception.InnerException.Message); - } - - Logger.LogError(exception.Message); - } - else - { - Logger.LogDebug(exception.ToString()); - Logger.LogCritical(Resources.Error_Command_Failed, exception.Message); - } + Logger.LogDebug(exception.ToString()); + Logger.LogCritical(Resources.Error_Command_Failed, exception.Message); returnCode = 1; return false; } @@ -96,7 +83,17 @@ namespace Microsoft.Extensions.SecretManager.Tools CommandOutputProvider.LogLevel = LogLevel.Debug; } - var userSecretsId = ResolveId(options); + string userSecretsId; + try + { + userSecretsId = ResolveId(options); + } + catch (Exception ex) when (ex is InvalidOperationException || ex is FileNotFoundException) + { + _logger.LogError(ex.Message); + return 1; + } + var store = new SecretsStore(userSecretsId, Logger); var context = new Internal.CommandContext(store, Logger, _console); options.Command.Execute(context); diff --git a/src/Microsoft.Extensions.SecretManager.Tools/project.json b/src/Microsoft.Extensions.SecretManager.Tools/project.json index 2c2e801dd2..f4731bc33d 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/project.json +++ b/src/Microsoft.Extensions.SecretManager.Tools/project.json @@ -38,7 +38,6 @@ ] }, "dependencies": { - "Microsoft.DotNet.Cli.Utils": "1.0.0-preview3-004056", "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.NETCore.App": { diff --git a/src/Shared/DebugHelper.cs b/src/Shared/DebugHelper.cs new file mode 100644 index 0000000000..bb7f966d65 --- /dev/null +++ b/src/Shared/DebugHelper.cs @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Diagnostics; +using System.Linq; + +namespace Microsoft.Extensions.Tools.Internal +{ + public static class DebugHelper + { + [Conditional("DEBUG")] + public static void HandleDebugSwitch(ref string[] args) + { + if (args.Length > 0 && string.Equals("--debug", args[0], StringComparison.OrdinalIgnoreCase)) + { + args = args.Skip(1).ToArray(); + Console.WriteLine("Waiting for debugger to attach. Press ENTER to continue"); + Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}"); + Console.ReadLine(); + } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/MsBuildProjectFinderTest.cs b/test/Microsoft.Extensions.SecretManager.Tools.Tests/MsBuildProjectFinderTest.cs index fad1808677..ec79f8ef4a 100644 --- a/test/Microsoft.Extensions.SecretManager.Tools.Tests/MsBuildProjectFinderTest.cs +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/MsBuildProjectFinderTest.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.IO; -using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.SecretManager.Tools.Internal; using Xunit; @@ -34,7 +33,7 @@ namespace Microsoft.Extensions.SecretsManager.Tools.Tests { var finder = new MsBuildProjectFinder(files.Root); - Assert.Throws(() => finder.FindMsBuildProject(null)); + Assert.Throws(() => finder.FindMsBuildProject(null)); } } @@ -46,7 +45,7 @@ namespace Microsoft.Extensions.SecretsManager.Tools.Tests var finder = new MsBuildProjectFinder(files.Root); files.Add("test.xproj", ""); - Assert.Throws(() => finder.FindMsBuildProject(null)); + Assert.Throws(() => finder.FindMsBuildProject(null)); } } @@ -59,7 +58,7 @@ namespace Microsoft.Extensions.SecretsManager.Tools.Tests files.Add("Test2.csproj", ""); var finder = new MsBuildProjectFinder(files.Root); - Assert.Throws(() => finder.FindMsBuildProject(null)); + Assert.Throws(() => finder.FindMsBuildProject(null)); } } @@ -70,7 +69,7 @@ namespace Microsoft.Extensions.SecretsManager.Tools.Tests { var finder = new MsBuildProjectFinder(files.Root); - Assert.Throws(() => finder.FindMsBuildProject("test.csproj")); + Assert.Throws(() => finder.FindMsBuildProject("test.csproj")); } } @@ -80,7 +79,7 @@ namespace Microsoft.Extensions.SecretsManager.Tools.Tests var files = new TemporaryFileProvider(); var finder = new MsBuildProjectFinder(files.Root); files.Dispose(); - Assert.Throws(() => finder.FindMsBuildProject(null)); + Assert.Throws(() => finder.FindMsBuildProject(null)); } } } diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/SecretManagerTests.cs b/test/Microsoft.Extensions.SecretManager.Tools.Tests/SecretManagerTests.cs index fba4b6e25b..d003c12234 100644 --- a/test/Microsoft.Extensions.SecretManager.Tools.Tests/SecretManagerTests.cs +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/SecretManagerTests.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; -using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.Configuration.UserSecrets; using Microsoft.Extensions.Configuration.UserSecrets.Tests; using Microsoft.Extensions.Logging; @@ -44,8 +43,8 @@ namespace Microsoft.Extensions.SecretManager.Tools.Tests var project = Path.Combine(_fixture.CreateProject(id), "TestProject.csproj"); var secretManager = CreateProgram(); - var ex = Assert.Throws(() => secretManager.RunInternal("list", "-p", project)); - Assert.Equal(Resources.FormatError_ProjectMissingId(project), ex.Message); + secretManager.RunInternal("list", "-p", project); + Assert.Contains(Resources.FormatError_ProjectMissingId(project), _logger.Messages); } [Fact] @@ -54,8 +53,8 @@ namespace Microsoft.Extensions.SecretManager.Tools.Tests var project = Path.Combine(_fixture.CreateProject("<"), "TestProject.csproj"); var secretManager = CreateProgram(); - var ex = Assert.Throws(() => secretManager.RunInternal("list", "-p", project)); - Assert.Equal(Resources.FormatError_ProjectFailedToLoad(project), ex.Message); + secretManager.RunInternal("list", "-p", project); + Assert.Contains(Resources.FormatError_ProjectFailedToLoad(project), _logger.Messages); } [Fact] @@ -64,8 +63,8 @@ namespace Microsoft.Extensions.SecretManager.Tools.Tests var projectPath = Path.Combine(_fixture.GetTempSecretProject(), "does_not_exist", "TestProject.csproj"); var secretManager = CreateProgram(); - var ex = Assert.Throws(() => secretManager.RunInternal("list", "--project", projectPath)); - Assert.Equal(Resources.FormatError_ProjectPath_NotFound(projectPath), ex.Message); + secretManager.RunInternal("list", "--project", projectPath); + Assert.Contains(Resources.FormatError_ProjectPath_NotFound(projectPath), _logger.Messages); } [Fact] diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/SetCommandTest.cs b/test/Microsoft.Extensions.SecretManager.Tools.Tests/SetCommandTest.cs index 90952ff5bd..4a3a94c716 100644 --- a/test/Microsoft.Extensions.SecretManager.Tools.Tests/SetCommandTest.cs +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/SetCommandTest.cs @@ -37,7 +37,7 @@ namespace Microsoft.Extensions.SecretManager.Tools.Tests In = new StringReader(input) }; var secretStore = new TestSecretsStore(); - var command = new SetCommand(); + var command = new SetCommand.FromStdInStrategy(); command.Execute(new CommandContext(secretStore, NullLogger.Instance, testConsole)); @@ -64,7 +64,7 @@ namespace Microsoft.Extensions.SecretManager.Tools.Tests In = new StringReader(input) }; var secretStore = new TestSecretsStore(); - var command = new SetCommand(); + var command = new SetCommand.FromStdInStrategy(); command.Execute(new CommandContext(secretStore, NullLogger.Instance, testConsole)); @@ -83,12 +83,8 @@ namespace Microsoft.Extensions.SecretManager.Tools.Tests IsInputRedirected = true, In = new StringReader("") }; - var secretStore = new TestSecretsStore(); - var command = new SetCommand("key", null); - - var ex = Assert.Throws( - () => command.Execute(new CommandContext(secretStore, NullLogger.Instance, testConsole))); - Assert.Equal(Resources.FormatError_MissingArgument("value"), ex.Message); + var options = CommandLineOptions.Parse(new [] { "set", "key", "value" }, testConsole); + Assert.IsType(options.Command); } private class TestSecretsStore : SecretsStore diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/test.sh b/test/Microsoft.Extensions.SecretManager.Tools.Tests/test.sh new file mode 100755 index 0000000000..31eb5fd320 --- /dev/null +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/test.sh @@ -0,0 +1,10 @@ +set -e + +~/.dotnet/dotnet build + +../../.build/dotnet/dotnet exec \ +--depsfile bin/Debug/netcoreapp1.0/Microsoft.Extensions.SecretManager.Tools.Tests.deps.json \ +--runtimeconfig bin/Debug/netcoreapp1.0/Microsoft.Extensions.SecretManager.Tools.Tests.runtimeconfig.json \ +../../.build/dotnet-test-xunit/2.2.0-preview2-build1029/lib/netcoreapp1.0/dotnet-test-xunit.dll \ +bin/Debug/netcoreapp1.0/Microsoft.Extensions.SecretManager.Tools.Tests.dll \ +$@ \ No newline at end of file