From 704f39c8399968da28ce290d1b994042ba8bde24 Mon Sep 17 00:00:00 2001 From: Scott Beddall <45376673+scbedd@users.noreply.github.com> Date: Fri, 21 Apr 2023 13:13:09 -0700 Subject: [PATCH] Swap `Test-Proxy` to `System.CommandLine`, implement `config` subcommands (#6010) * Swap Test-Proxy to utilize System.CommandLine instead of CommandLineParser for argument parsing * Add new 'config' verb that can be used to interact in various ways with an assets.json * Add tests for new argument parsing --- .../InvocationTests.cs | 260 ++++++++++++++++++ .../Azure.Sdk.Tools.TestProxy.csproj | 2 +- .../CommandOptions/CLICommandOptions.cs | 35 +++ .../Config/ConfigCreateOptions.cs | 34 +++ .../Config/ConfigLocateOptions.cs | 34 +++ .../Config/ConfigShowOptions.cs | 34 +++ .../CommandOptions/ConfigOptions.cs | 34 +++ .../CommandOptions/DefaultOptions.cs | 31 +++ .../CommandOptions/OptionsGenerator.cs | 126 +++++++++ .../CommandOptions/PushOptions.cs | 34 +++ .../CommandOptions/ResetOptions.cs | 38 +++ .../CommandOptions/RestoreOptions.cs | 34 +++ .../CommandOptions/StartOptions.cs | 46 ++++ .../CommandParserOptions/CLICommandOptions.cs | 13 - .../CommandParserOptions/DefaultOptions.cs | 16 -- .../CommandParserOptions/PushOptions.cs | 13 - .../CommandParserOptions/ResetOptions.cs | 15 - .../CommandParserOptions/RestoreOptions.cs | 12 - .../CommandParserOptions/StartOptions.cs | 24 -- .../Azure.Sdk.Tools.TestProxy/Startup.cs | 126 +++------ .../Store/GitStore.cs | 8 +- .../Store/IAssetsStore.cs | 3 +- .../Store/NullStore.cs | 3 +- 23 files changed, 794 insertions(+), 181 deletions(-) create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/InvocationTests.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/CLICommandOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigCreateOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigLocateOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigShowOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/ConfigOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/DefaultOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/PushOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/ResetOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/RestoreOptions.cs create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/StartOptions.cs delete mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/CLICommandOptions.cs delete mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/DefaultOptions.cs delete mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/PushOptions.cs delete mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/ResetOptions.cs delete mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/RestoreOptions.cs delete mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/StartOptions.cs diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/InvocationTests.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/InvocationTests.cs new file mode 100644 index 00000000000..051d2a55832 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/InvocationTests.cs @@ -0,0 +1,260 @@ +using System; +using System.CommandLine; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Azure.Sdk.Tools.TestProxy.CommandOptions; +using Xunit; + +namespace Azure.Sdk.Tools.TestProxy.Tests +{ + public class InvocationTests + { + + + [Theory] + [InlineData("start", "-i", "-d")] + [InlineData("start")] + [InlineData("start", "--insecure", "-d")] + [InlineData("start", "--dump")] + [InlineData("start", "--dump", "--", "--urls", "https://localhost:8002")] + public async Task TestBasicServerInvocations(params string[] input) + { + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.True(obj is StartOptions); + Assert.Equal(0, exitCode); + + if (input.Contains("-i")|| input.Contains("--insecure")) + { + Assert.True(((StartOptions)obj).Insecure); + } + else + { + Assert.False(((StartOptions)obj).Insecure); + } + + if (input.Contains("--dump") || input.Contains("-d")) + { + Assert.True(((StartOptions)obj).Dump); + } + else + { + Assert.False(((StartOptions)obj).Dump); + } + } + + [Fact] + public async Task TestServerInvocationsHonorUnmatched() + { + string[] input = new string[] { "start", "--dump", "--", "--urls", "https://localhost:8002" }; + + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.True(obj is StartOptions); + Assert.Equal(new string[] { "--urls", "https://localhost:8002" }, ((StartOptions)obj).AdditionalArgs); + Assert.Equal(0, exitCode); + } + + [Fact] + public async Task TestConfig() + { + string[] input = new string[] { "config" }; + + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.True(obj is ConfigOptions); + Assert.Equal(0, exitCode); + } + + [Fact] + public async Task TestConfigShow() + { + string[] input = new string[] { "config", "show", "-a", "path/to/assets.json" }; + + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.True(obj is ConfigShowOptions); + Assert.Equal("path/to/assets.json", ((ConfigShowOptions)obj).AssetsJsonPath); + Assert.Equal(0, exitCode); + } + + [Fact] + public async Task TestConfigCreate() + { + string[] input = new string[] { "config", "create", "-a", "path/to/assets.json" }; + + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.True(obj is ConfigCreateOptions); + Assert.Equal("path/to/assets.json", ((ConfigCreateOptions)obj).AssetsJsonPath); + Assert.Equal(0, exitCode); + } + + [Fact] + public async Task TestConfigLocate() + { + string[] input = new string[] { "config", "locate", "-a", "path/to/assets.json" }; + + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.True(obj is ConfigLocateOptions); + Assert.Equal("path/to/assets.json", ((ConfigLocateOptions)obj).AssetsJsonPath); + Assert.Equal(0, exitCode); + } + + [Theory] + [InlineData("config", "invalid-verb")] + [InlineData("totally-invalid-verb")] + + public async Task TestInvalidVerbCombinations(params string[] input) + { + var output = new StringWriter(); + System.Console.SetOut(output); + var obj = string.Empty; + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = "Invoked"; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.NotEqual("Invoked", obj); + Assert.Equal(1, exitCode); + } + + [Theory] + [InlineData("push", "-a", "path/to/assets.json")] + + public async Task TestPushOptions(params string[] input) + { + var output = new StringWriter(); + System.Console.SetOut(output); + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.True(obj is PushOptions); + Assert.Equal("path/to/assets.json", ((PushOptions)obj).AssetsJsonPath); + Assert.Equal(0, exitCode); + } + + [Theory] + [InlineData("restore", "-a", "path/to/assets.json")] + + public async Task TestRestoreOptions(params string[] input) + { + var output = new StringWriter(); + System.Console.SetOut(output); + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + Assert.True(obj is RestoreOptions); + Assert.Equal("path/to/assets.json", ((RestoreOptions)obj).AssetsJsonPath); + Assert.Equal(0, exitCode); + } + + [Theory] + [InlineData("reset", "-a", "path/to/assets.json")] + [InlineData("reset", "-y", "-a", "path/to/assets.json")] + public async Task TestResetOptions(params string[] input) + { + var output = new StringWriter(); + System.Console.SetOut(output); + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + + if (input.Contains("--yes") || input.Contains("-y")) + { + Assert.True(((ResetOptions)obj).ConfirmReset); + } + else + { + Assert.False(((ResetOptions)obj).ConfirmReset); + } + + Assert.True(obj is ResetOptions); + Assert.Equal("path/to/assets.json", ((ResetOptions)obj).AssetsJsonPath); + Assert.Equal(0, exitCode); + } + + + [Fact] + public async Task TestPushOptionsErrorsWithNoPath() + { + string[] input = new string[] { "push" }; + + var output = new StringWriter(); + System.Console.SetOut(output); + var obj = new object(); + var rootCommand = OptionsGenerator.GenerateCommandLineOptions((DefaultOptions) => + { + obj = DefaultOptions; + + return Task.CompletedTask; + }); + var exitCode = await rootCommand.InvokeAsync(input); + Assert.Equal(1, exitCode); + } + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Azure.Sdk.Tools.TestProxy.csproj b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Azure.Sdk.Tools.TestProxy.csproj index 274d5a4c52e..b6cc7713b91 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Azure.Sdk.Tools.TestProxy.csproj +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Azure.Sdk.Tools.TestProxy.csproj @@ -22,6 +22,6 @@ - + diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/CLICommandOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/CLICommandOptions.cs new file mode 100644 index 00000000000..0b5a93b8715 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/CLICommandOptions.cs @@ -0,0 +1,35 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + /// + /// CLICommandOptions contain options common to all CLI Commands (Push, Reset, Restore) + /// + public class CLICommandOptions : DefaultOptions + { + public string AssetsJsonPath { get; set; } + } + + public class CLICommandOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _assetsJsonPathOption; + + public CLICommandOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _assetsJsonPathOption = assetsJsonPathOption; + } + + protected override CLICommandOptions GetBoundValue(BindingContext bindingContext) => + new CLICommandOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigCreateOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigCreateOptions.cs new file mode 100644 index 00000000000..2a1ea9a8bb5 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigCreateOptions.cs @@ -0,0 +1,34 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + /// + /// Any unique options to the push command will reside here. + /// + public class ConfigCreateOptions : CLICommandOptions + { + } + + public class ConfigCreateOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _assetsJsonPathOption; + + public ConfigCreateOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _assetsJsonPathOption = assetsJsonPathOption; + } + + protected override ConfigCreateOptions GetBoundValue(BindingContext bindingContext) => + new ConfigCreateOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigLocateOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigLocateOptions.cs new file mode 100644 index 00000000000..78fc1a6a4a1 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigLocateOptions.cs @@ -0,0 +1,34 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + /// + /// Any unique options to the push command will reside here. + /// + public class ConfigLocateOptions : CLICommandOptions + { + } + + public class ConfigLocateOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _assetsJsonPathOption; + + public ConfigLocateOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _assetsJsonPathOption = assetsJsonPathOption; + } + + protected override ConfigLocateOptions GetBoundValue(BindingContext bindingContext) => + new ConfigLocateOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigShowOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigShowOptions.cs new file mode 100644 index 00000000000..47a821ffe76 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/Config/ConfigShowOptions.cs @@ -0,0 +1,34 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + /// + /// Any unique options to the push command will reside here. + /// + public class ConfigShowOptions : CLICommandOptions + { + } + + public class ConfigShowOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _assetsJsonPathOption; + + public ConfigShowOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _assetsJsonPathOption = assetsJsonPathOption; + } + + protected override ConfigShowOptions GetBoundValue(BindingContext bindingContext) => + new ConfigShowOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/ConfigOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/ConfigOptions.cs new file mode 100644 index 00000000000..7dfbada9bf3 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/ConfigOptions.cs @@ -0,0 +1,34 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + /// + /// Any unique options to the push command will reside here. + /// + public class ConfigOptions : CLICommandOptions + { + } + + public class ConfigOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _assetsJsonPathOption; + + public ConfigOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _assetsJsonPathOption = assetsJsonPathOption; + } + + protected override ConfigOptions GetBoundValue(BindingContext bindingContext) => + new ConfigOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/DefaultOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/DefaultOptions.cs new file mode 100644 index 00000000000..f1010c5f18a --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/DefaultOptions.cs @@ -0,0 +1,31 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + public class DefaultOptions + { + public string StorageLocation { get; set; } + + public string StoragePlugin { get; set; } + } + + public class DefaultOptsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + + public DefaultOptsBinder(Option storageLocationOption, Option storagePluginOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + } + + protected override DefaultOptions GetBoundValue(BindingContext bindingContext) => + new DefaultOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs new file mode 100644 index 00000000000..78cdea9329a --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/OptionsGenerator.cs @@ -0,0 +1,126 @@ +using System; +using System.CommandLine; +using System.CommandLine.Binding; +using System.Threading.Tasks; +using static System.CommandLine.Help.HelpBuilder; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + public static class OptionsGenerator + { + public static RootCommand GenerateCommandLineOptions(Func callback) + { + #region option definitions + var storageLocationOption = new Option( + name: "--storage-location", + description: "The path to the target local git repo. If not provided as an argument, Environment variable TEST_PROXY_FOLDER will be consumed. Lacking both, the current working directory will be utilized.", + getDefaultValue: () => null); + storageLocationOption.AddAlias("-f"); + + var storagePluginOption = new Option( + name: "--storage-plugin", + description: "The plugin for the selected storage, default is Git storage is GitStore. (Currently the only option)", + getDefaultValue: () => "GitStore"); + storagePluginOption.AddAlias("-l"); + + var assetsJsonPathOption = new Option( + name: "--assets-json-path", + description: "Required for any operation that requires an assets.json path. Currently Push/Reset/Restore. This should be a path to a valid assets.json within a language repository.") + { + IsRequired = true + }; + assetsJsonPathOption.AddAlias("-a"); + + var confirmResetOption = new Option( + name: "--yes", + description: "Do not prompt for confirmation when resetting pending changes.", + getDefaultValue: () => false); + confirmResetOption.AddAlias("-y"); + + var insecureOption = new Option( + name: "--insecure", + description: "Flag; Allow insecure upstream SSL certs.", + getDefaultValue: () => false); + insecureOption.AddAlias("-i"); + + var dumpOption = new Option( + name: "--dump", + description: "Flag; Output configuration values when starting the Test-Proxy.", + getDefaultValue: () => false); + dumpOption.AddAlias("-d"); + + var collectedArgs = new Argument("args") + { + Arity = ArgumentArity.ZeroOrMore, + Description = "Remaining arguments after \"--\". Used for asp.net arguments." + }; + #endregion + + var root = new RootCommand(); + root.AddGlobalOption(storageLocationOption); + root.AddGlobalOption(storagePluginOption); + + root.SetHandler(async (defaultOpts) => await callback(defaultOpts), + new DefaultOptsBinder(storageLocationOption, storagePluginOption) + ); + + var startCommand = new Command("start", "Start the TestProxy."); + startCommand.AddOption(insecureOption); + startCommand.AddOption(dumpOption); + startCommand.AddArgument(collectedArgs); + startCommand.SetHandler(async (startOpts) => await callback(startOpts), + new StartOptionsBinder(storageLocationOption, storagePluginOption, insecureOption, dumpOption, collectedArgs) + ); + root.Add(startCommand); + + var pushCommand = new Command("push", "Push the assets, referenced by assets.json, into git."); + pushCommand.AddOption(assetsJsonPathOption); + pushCommand.SetHandler(async (pushOpts) => await callback(pushOpts), + new PushOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption) + ); + root.Add(pushCommand); + + var restoreCommand = new Command("restore", "Restore the assets, referenced by assets.json, from git."); + restoreCommand.AddOption(assetsJsonPathOption); + restoreCommand.SetHandler(async (restoreOpts) => await callback(restoreOpts), + new RestoreOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption) + ); + root.Add(restoreCommand); + + var resetCommand = new Command("reset", "Reset the assets, referenced by assets.json, from git to their original files referenced by the tag. Will prompt if there are pending changes unless indicated by -y/--yes."); + resetCommand.AddOption(assetsJsonPathOption); + resetCommand.AddOption(confirmResetOption); + resetCommand.SetHandler(async (resetOpts) => await callback(resetOpts), + new ResetOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption, confirmResetOption) + ); + root.Add(resetCommand); + + var configCommand = new Command("config", "Interact with an assets.json."); + configCommand.SetHandler(async (configOpts) => await callback(configOpts), + new ConfigOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption) + ); + var configCreateCommand = new Command("create", "Enter a prompt and create an assets.json."); + configCreateCommand.AddOption(assetsJsonPathOption); + configCreateCommand.SetHandler(async (configOpts) => await callback(configOpts), + new ConfigCreateOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption) + ); + var configShowCommand = new Command("show", "Show the content of a given assets.json."); + configShowCommand.AddOption(assetsJsonPathOption); + configShowCommand.SetHandler(async (configOpts) => await callback(configOpts), + new ConfigShowOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption) + ); + var configLocateCommand = new Command("locate", "Get the assets repo root for a given assets.json path."); + configLocateCommand.AddOption(assetsJsonPathOption); + configLocateCommand.SetHandler(async (configOpts) => await callback(configOpts), + new ConfigLocateOptionsBinder(storageLocationOption, storagePluginOption, assetsJsonPathOption) + ); + + configCommand.AddCommand(configCreateCommand); + configCommand.AddCommand(configShowCommand); + configCommand.AddCommand(configLocateCommand); + root.Add(configCommand); + + return root; + } + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/PushOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/PushOptions.cs new file mode 100644 index 00000000000..71f76b5aa99 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/PushOptions.cs @@ -0,0 +1,34 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + /// + /// Any unique options to the push command will reside here. + /// + public class PushOptions : CLICommandOptions + { + } + + public class PushOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _assetsJsonPathOption; + + public PushOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _assetsJsonPathOption = assetsJsonPathOption; + } + + protected override PushOptions GetBoundValue(BindingContext bindingContext) => + new PushOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/ResetOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/ResetOptions.cs new file mode 100644 index 00000000000..75c74eadcd1 --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/ResetOptions.cs @@ -0,0 +1,38 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + /// + /// Any unique options to the reset command will reside here. + /// + public class ResetOptions : CLICommandOptions + { + public bool ConfirmReset { get; set; } + } + + public class ResetOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _assetsJsonPathOption; + private readonly Option _confirmResetOption; + + public ResetOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption, Option confirmResetOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _assetsJsonPathOption = assetsJsonPathOption; + _confirmResetOption = confirmResetOption; + } + + protected override ResetOptions GetBoundValue(BindingContext bindingContext) => + new ResetOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption), + ConfirmReset = bindingContext.ParseResult.GetValueForOption(_confirmResetOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/RestoreOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/RestoreOptions.cs new file mode 100644 index 00000000000..f7c46d0450f --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/RestoreOptions.cs @@ -0,0 +1,34 @@ +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + /// + /// Any unique options to the restore command will reside here. + /// + public class RestoreOptions : CLICommandOptions + { + } + + public class RestoreOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _assetsJsonPathOption; + + public RestoreOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option assetsJsonPathOption) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _assetsJsonPathOption = assetsJsonPathOption; + } + + protected override RestoreOptions GetBoundValue(BindingContext bindingContext) => + new RestoreOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + AssetsJsonPath = bindingContext.ParseResult.GetValueForOption(_assetsJsonPathOption) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/StartOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/StartOptions.cs new file mode 100644 index 00000000000..944936bb62f --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandOptions/StartOptions.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.Binding; + +namespace Azure.Sdk.Tools.TestProxy.CommandOptions +{ + public class StartOptions : DefaultOptions + { + public bool Insecure { get; set; } + public bool Dump { get; set; } + + // On the command line, use -- and everything after that becomes arguments to Host.CreateDefaultBuilder + // For example Test-Proxy start -i -d -- --urls https://localhost:8002 would set AdditionaArgs to a list containing + // --urls and https://localhost:8002 as individual entries. This is converted to a string[] before being + // passed to Host.CreateDefaultBuilder + public IEnumerable AdditionalArgs { get; set; } + } + public class StartOptionsBinder : BinderBase + { + private readonly Option _storageLocationOption; + private readonly Option _storagePluginOption; + private readonly Option _insecureOption; + private readonly Option _dumpOption; + private readonly Argument _additionalArgs; + + public StartOptionsBinder(Option storageLocationOption, Option storagePluginOption, Option insecureOption, Option dumpOption, Argument additionalArgs) + { + _storageLocationOption = storageLocationOption; + _storagePluginOption = storagePluginOption; + _insecureOption = insecureOption; + _dumpOption = dumpOption; + _additionalArgs = additionalArgs; + + } + + protected override StartOptions GetBoundValue(BindingContext bindingContext) => + new StartOptions + { + StorageLocation = bindingContext.ParseResult.GetValueForOption(_storageLocationOption), + StoragePlugin = bindingContext.ParseResult.GetValueForOption(_storagePluginOption), + Insecure = bindingContext.ParseResult.GetValueForOption(_insecureOption), + Dump = bindingContext.ParseResult.GetValueForOption(_dumpOption), + AdditionalArgs = bindingContext.ParseResult.GetValueForArgument(_additionalArgs) + }; + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/CLICommandOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/CLICommandOptions.cs deleted file mode 100644 index b8a641008c4..00000000000 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/CLICommandOptions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using CommandLine; - -namespace Azure.Sdk.Tools.TestProxy.CommandParserOptions -{ - /// - /// CLICommandOptions contain options common to all CLI Commands (Push, Reset, Restore) - /// - class CLICommandOptions : DefaultOptions - { - [Option('a', "assets-json-path", Required = true, HelpText = "Required for Push/Reset/Restore. This should be a path to a valid assets.json within a language repository.")] - public string AssetsJsonPath { get; set; } - } -} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/DefaultOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/DefaultOptions.cs deleted file mode 100644 index 9395575f4f1..00000000000 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/DefaultOptions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using CommandLine; - -namespace Azure.Sdk.Tools.TestProxy.CommandParserOptions -{ - /// - /// DefaultOptions is the base for all CommandParser Verbs. The only options that should go in here are ones common to everything. - /// - class DefaultOptions - { - [Option('l', "storage-location", Default = null, HelpText = "The path to the target local git repo. If not provided as an argument, Environment variable TEST_PROXY_FOLDER will be consumed. Lacking both, the current working directory will be utilized.")] - public string StorageLocation { get; set; } - - [Option('p', "storage-plugin", Default = "GitStore", HelpText = "The plugin for the selected storage, default is Git storage is GitStore. (Currently the only option)")] - public string StoragePlugin { get; set; } - } -} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/PushOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/PushOptions.cs deleted file mode 100644 index 3626022d531..00000000000 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/PushOptions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using CommandLine.Text; -using CommandLine; - -namespace Azure.Sdk.Tools.TestProxy.CommandParserOptions -{ - /// - /// Any unique options to the push command will reside here. - /// - [Verb("push", HelpText = "Push the assets, referenced by assets.json, into git.")] - class PushOptions : CLICommandOptions - { - } -} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/ResetOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/ResetOptions.cs deleted file mode 100644 index f6af33ea280..00000000000 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/ResetOptions.cs +++ /dev/null @@ -1,15 +0,0 @@ -using CommandLine; - -namespace Azure.Sdk.Tools.TestProxy.CommandParserOptions -{ - /// - /// Any unique options to the reset command will reside here. - /// - [Verb("reset", HelpText = "Reset the assets, referenced by assets.json, from git to their original files referenced by the tag. Will prompt if there are pending changes unless indicated by -y/--yes.")] - class ResetOptions : CLICommandOptions - { - - [Option('y', "yes", Default = null, HelpText = "Do not prompt for confirmation when resetting pending changes.")] - public string ConfirmReset { get; set; } - } -} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/RestoreOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/RestoreOptions.cs deleted file mode 100644 index 88b952dcee9..00000000000 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/RestoreOptions.cs +++ /dev/null @@ -1,12 +0,0 @@ -using CommandLine; - -namespace Azure.Sdk.Tools.TestProxy.CommandParserOptions -{ - /// - /// Any unique options to the restore command will reside here. - /// - [Verb("restore", HelpText = "Restore the assets, referenced by assets.json, from git.")] - class RestoreOptions : CLICommandOptions - { - } -} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/StartOptions.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/StartOptions.cs deleted file mode 100644 index 81cd7b5c738..00000000000 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/CommandParserOptions/StartOptions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using CommandLine; -using System.Collections.Generic; - -namespace Azure.Sdk.Tools.TestProxy.CommandParserOptions -{ - [Verb("start", isDefault: true, HelpText = "Start the TestProxy.")] - class StartOptions : DefaultOptions - { - [Option('i', "insecure", Default = false, HelpText = "Flag; Allow insecure upstream SSL certs.")] - public bool Insecure { get; set; } - - [Option('d', "dump", Default = false, HelpText = "Flag; Output configuration values when starting the Test-Proxy.")] - public bool Dump { get; set; } - - // On the command line, use -- and everything after that becomes arguments to Host.CreateDefaultBuilder - // For example Test-Proxy -i -d -- --urls https://localhost:8002 would set AdditionaArgs to a list containing - // --urls and https://localhost:8002 as individual entries. This is converted to a string[] before being - // passed to Host.CreateDefaultBuilder - [CommandLine.Value(0)] - public IEnumerable AdditionalArgs { get; set; } - - } - -} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs index b4a8bb20c9d..26ac09a4f4b 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using CommandLine; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -18,14 +17,13 @@ using System.Reflection; using Microsoft.AspNetCore.Server.Kestrel.Core; using Azure.Sdk.Tools.TestProxy.Store; -using Azure.Sdk.Tools.TestProxy.Console; using System.Diagnostics.CodeAnalysis; -using System.Security.Cryptography.X509Certificates; -using Microsoft.Extensions.Options; -using Microsoft.AspNetCore.Identity; -using System.Collections.Generic; using System.Linq; -using Azure.Sdk.Tools.TestProxy.CommandParserOptions; +using System.CommandLine; +using Azure.Sdk.Tools.TestProxy.CommandOptions; +using Microsoft.AspNetCore.Identity; +using Microsoft.CodeAnalysis.VisualBasic.Syntax; +using System.Text.Json; namespace Azure.Sdk.Tools.TestProxy { @@ -43,6 +41,7 @@ public Startup(IConfiguration configuration) { } public static string TargetLocation; public static StoreResolver Resolver; public static IAssetsStore DefaultStore; + public static string[] storedArgs; private static string resolveRepoLocation(string storageLocation = null) { @@ -56,97 +55,52 @@ private static string resolveRepoLocation(string storageLocation = null) /// CommandLineParser arguments. In server mode use double dash '--' and everything after that becomes additional arguments to Host.CreateDefaultBuilder. Ex. -- arg1 value1 arg2 value2 public static async Task Main(string[] args = null) { - VerifyVerb(args); - var parser = new Parser(settings => - { - settings.CaseSensitive = false; - settings.HelpWriter = System.Console.Out; - settings.EnableDashDash = true; - }); + storedArgs = args; + var rootCommand = OptionsGenerator.GenerateCommandLineOptions(Run); + var resultCode = await rootCommand.InvokeAsync(args); - await parser.ParseArguments(args) - .WithNotParsed(ExitWithError) - .WithParsedAsync(Run); - } - - static void ExitWithError(IEnumerable errors) - { - - // ParseArguments lumps help/--help and version/--version into WithNotParsed - // but their type is VersionRequestedError and HelpRequestedError/HelpVerbRequestedError. - // If the user is requesting help or version, don't exit 1, just exit 0 - if (errors.Count() == 1) - { - Error err = errors.First(); - if ((err.Tag == ErrorType.HelpVerbRequestedError || err.Tag == ErrorType.HelpRequestedError || err.Tag == ErrorType.VersionRequestedError)) - { - Environment.Exit(0); - } - } - Environment.Exit(1); - } - - /// - /// This is only necessary because if there's a default verb defined, ours is start, - /// CommandLineParser doesn't verify the verb. If the issue is fixed this function - /// can be removed. - /// https://github.com/commandlineparser/commandline/issues/849 - /// - /// - static void VerifyVerb(string[] args) - { - // no arguments means the server is starting with all the default options - if (args.Length == 0) - { - return; - } - - // if the first argument starts with a dash then they're options and the - // default verb is being used. - if (args[0].StartsWith("-")) - { - return; - } - - // last but not least, the first argument is a verb, verify it's our verb - // version and help are default verbs and need to be in here - string[] array = { "start", "reset", "restore", "push", "version", "help" }; - if (!array.Contains(args[0])) - { - // The odd looking formatting is to make this look like the same error - // CommandLineParser would output if the verb wasn't recognized. - string error = @$"ERROR(S): - Verb '{args[0]}' is not recognized. - - --help Display this help screen. - - --version Display version information. -"; - System.Console.WriteLine(error); - Environment.Exit(1); - } + Environment.Exit(resultCode); } private static async Task Run(object commandObj) { - new GitProcessHandler().VerifyGitMinVersion(); - DefaultOptions defaultOptions = (DefaultOptions)commandObj; - var assembly = System.Reflection.Assembly.GetExecutingAssembly(); var semanticVersion = assembly.GetCustomAttribute().InformationalVersion; System.Console.WriteLine($"Running proxy version is Azure.Sdk.Tools.TestProxy {semanticVersion}"); + new GitProcessHandler().VerifyGitMinVersion(); + DefaultOptions defaultOptions = (DefaultOptions)commandObj; + TargetLocation = resolveRepoLocation(defaultOptions.StorageLocation); Resolver = new StoreResolver(); DefaultStore = Resolver.ResolveStore(defaultOptions.StoragePlugin ?? "GitStore"); + var assetsJson = string.Empty; switch (commandObj) { + case ConfigLocateOptions configOptions: + assetsJson = RecordingHandler.GetAssetsJsonLocation(configOptions.AssetsJsonPath, TargetLocation); + System.Console.WriteLine(await DefaultStore.GetPath(assetsJson)); + break; + case ConfigShowOptions configOptions: + assetsJson = RecordingHandler.GetAssetsJsonLocation(configOptions.AssetsJsonPath, TargetLocation); + using(var f = File.OpenRead(assetsJson)) + { + using var json = JsonDocument.Parse(f); + System.Console.WriteLine(JsonSerializer.Serialize(json, new JsonSerializerOptions { WriteIndented = true })); + } + break; + case ConfigCreateOptions configOptions: + assetsJson = RecordingHandler.GetAssetsJsonLocation(configOptions.AssetsJsonPath, TargetLocation); + throw new NotImplementedException("Interactive creation of assets.json feature is not yet implemented."); + case ConfigOptions configOptions: + System.Console.WriteLine("Config verb requires a subcommand after the \"config\" verb.\n\nCorrect Usage: \"Azure.Sdk.Tools.TestProxy config locate|show|create -a path/to/assets.json\""); + break; case StartOptions startOptions: StartServer(startOptions); break; case PushOptions pushOptions: - var assetsJson = RecordingHandler.GetAssetsJsonLocation(pushOptions.AssetsJsonPath, TargetLocation); + assetsJson = RecordingHandler.GetAssetsJsonLocation(pushOptions.AssetsJsonPath, TargetLocation); await DefaultStore.Push(assetsJson); break; case ResetOptions resetOptions: @@ -157,8 +111,18 @@ private static async Task Run(object commandObj) assetsJson = RecordingHandler.GetAssetsJsonLocation(restoreOptions.AssetsJsonPath, TargetLocation); await DefaultStore.Restore(assetsJson); break; + case DefaultOptions defaultOpts: + StartServer(new StartOptions() + { + AdditionalArgs = new string[] { }, + StorageLocation = defaultOpts.StorageLocation, + StoragePlugin = defaultOpts.StoragePlugin, + Insecure = false, + Dump = false + }); + break; default: - throw new ArgumentException("Invalid verb. The only supported verbs are start, push, reset and restore."); + throw new ArgumentException($"Unable to parse the argument set: {string.Join(" ", storedArgs)}"); } } @@ -173,7 +137,7 @@ private static void StartServer(StartOptions startOptions) () => $"[{DateTime.UtcNow.ToString("HH:mm:ss")}] Recorded: {RequestsRecorded}\tPlayed Back: {RequestsPlayedBack}", newLine: true, statusThreadCts.Token); - var host = Host.CreateDefaultBuilder(startOptions.AdditionalArgs.ToArray()); + var host = Host.CreateDefaultBuilder((startOptions.AdditionalArgs??new string[] { }).ToArray()); host.ConfigureWebHostDefaults( builder => diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs index bfebebbb48c..56e0184c021 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/GitStore.cs @@ -66,16 +66,16 @@ public GitStore(GitProcessHandler processHandler) { /// /// /// - public async Task GetPath(string pathToAssetsJson) + public async Task GetPath(string pathToAssetsJson) { var config = await ParseConfigurationFile(pathToAssetsJson); - if (!string.IsNullOrWhiteSpace(config.AssetsRepoPrefixPath.ToString())) + if (!string.IsNullOrWhiteSpace(config.AssetsRepoPrefixPath)) { - return Path.Combine(config.AssetsRepoLocation.ToString(), config.AssetsRepoPrefixPath.ToString()); + return new NormalizedString(Path.Combine(config.AssetsRepoLocation, config.AssetsRepoPrefixPath)); } - return config.AssetsRepoLocation.ToString(); + return new NormalizedString(config.AssetsRepoLocation); } /// diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs index 8a7f303efed..62e971283a0 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/IAssetsStore.cs @@ -1,5 +1,6 @@ using System.IO; using System.Threading.Tasks; +using Azure.Sdk.tools.TestProxy.Common; using Azure.Sdk.Tools.TestProxy.Console; namespace Azure.Sdk.Tools.TestProxy.Store @@ -29,6 +30,6 @@ public interface IAssetsStore /// /// /// - public abstract Task GetPath(string pathToAssetsJson); + public abstract Task GetPath(string pathToAssetsJson); } } diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs index e28a644fe0d..2b90c851884 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Store/NullStore.cs @@ -1,6 +1,7 @@ using System.IO; using System.Net; using System.Threading.Tasks; +using Azure.Sdk.tools.TestProxy.Common; using Azure.Sdk.Tools.TestProxy.Common.Exceptions; using Azure.Sdk.Tools.TestProxy.Console; @@ -23,6 +24,6 @@ public AssetsConfiguration ParseConfigurationFile(string pathToAssetsJson) return new AssetsConfiguration(); } - public Task GetPath(string pathToAssetsJson) { return null; } + public Task GetPath(string pathToAssetsJson) { return null; } } }