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; }
}
}