From 3a50c818950c807124fe74ab84723356ec01e120 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Sat, 26 Aug 2017 21:08:18 +0200 Subject: [PATCH] Use SimpleCommandLineParser --- .../SimpleCommandLineParser.cs | 85 +++++++++++ .../StandAloneApp.CommandLineParser.cs | 142 ++++++++++++++++++ src/WireMock.Net.StandAlone/StandAloneApp.cs | 141 +++++------------ .../WireMock.Net.StandAlone.csproj | 5 +- 4 files changed, 268 insertions(+), 105 deletions(-) create mode 100644 src/WireMock.Net.StandAlone/SimpleCommandLineParser.cs create mode 100644 src/WireMock.Net.StandAlone/StandAloneApp.CommandLineParser.cs diff --git a/src/WireMock.Net.StandAlone/SimpleCommandLineParser.cs b/src/WireMock.Net.StandAlone/SimpleCommandLineParser.cs new file mode 100644 index 00000000..11bfeba4 --- /dev/null +++ b/src/WireMock.Net.StandAlone/SimpleCommandLineParser.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace WireMock.Net.StandAlone +{ + // Based on http://blog.gauffin.org/2014/12/simple-command-line-parser/ + internal class SimpleCommandLineParser + { + public IDictionary Arguments { get; private set; } = new Dictionary(); + + public void Parse(string[] args) + { + string currentName = null; + + var values = new List(); + foreach (string arg in args) + { + if (arg.StartsWith("--")) + { + if (!string.IsNullOrEmpty(currentName)) + { + Arguments[currentName] = values.ToArray(); + } + + values.Clear(); + currentName = arg.Substring(2); + } + else if (string.IsNullOrEmpty(currentName)) + { + Arguments[arg] = new string[0]; + } + else + { + values.Add(arg); + } + } + + if (!string.IsNullOrEmpty(currentName)) + { + Arguments[currentName] = values.ToArray(); + } + } + public bool Contains(string name) + { + return Arguments.ContainsKey(name); + } + + public string[] GetValues(string name, string[] defaultValue = null) + { + return Contains(name) ? Arguments[name] : defaultValue; + } + + public T GetValue(string name, Func func, T defaultValue = default(T)) + { + return Contains(name) ? func(Arguments[name]) : defaultValue; + } + + public bool GetBoolValue(string name, bool defaultValue = false) + { + return GetValue(name, (values) => + { + string value = values.FirstOrDefault(); + return !string.IsNullOrEmpty(value) ? bool.Parse(value) : defaultValue; + }, defaultValue); + } + + public int? GetIntValue(string name, int? defaultValue = null) + { + return GetValue(name, (values) => + { + string value = values.FirstOrDefault(); + return !string.IsNullOrEmpty(value) ? int.Parse(value) : defaultValue; + }, defaultValue); + } + + public string GetStringValue(string name, string defaultValue = null) + { + return GetValue(name, (values) => + { + return values.FirstOrDefault() ?? defaultValue; + }, defaultValue); + } + } +} \ No newline at end of file diff --git a/src/WireMock.Net.StandAlone/StandAloneApp.CommandLineParser.cs b/src/WireMock.Net.StandAlone/StandAloneApp.CommandLineParser.cs new file mode 100644 index 00000000..43191fda --- /dev/null +++ b/src/WireMock.Net.StandAlone/StandAloneApp.CommandLineParser.cs @@ -0,0 +1,142 @@ +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using CommandLineParser.Arguments; +// using CommandLineParser.Exceptions; +// using WireMock.Server; +// using WireMock.Settings; +// using WireMock.Validation; +// using JetBrains.Annotations; +// using Newtonsoft.Json; + +// namespace WireMock.Net.StandAlone +// { +// /// +// /// The StandAloneApp +// /// +// public static class StandAloneApp +// { +// private class Options +// { +// [ValueArgument(typeof(int?), "Port", Description = "Port to listen on.", Optional = true)] +// public int? Port { get; set; } + +// [ValueArgument(typeof(string), "Urls", Description = "URL(s) to listen on.", Optional = true, AllowMultiple = true)] +// public List Urls { get; set; } + +// [SwitchArgument("AllowPartialMapping", false, Description = "Allow Partial Mapping (default set to false).", Optional = true)] +// public bool AllowPartialMapping { get; set; } + +// [SwitchArgument("StartAdminInterface", true, Description = "Start the AdminInterface (default set to true).", Optional = true)] +// public bool StartAdminInterface { get; set; } + +// [SwitchArgument("ReadStaticMappings", true, Description = "Read StaticMappings from ./__admin/mappings (default set to true).", Optional = true)] +// public bool ReadStaticMappings { get; set; } + +// [ValueArgument(typeof(string), "ProxyURL", Description = "The ProxyURL to use.", Optional = true)] +// public string ProxyURL { get; set; } + +// [SwitchArgument("SaveProxyMapping", true, Description = "Save the proxied request and response mapping files in ./__admin/mappings. (default set to true).", Optional = true)] +// public bool SaveMapping { get; set; } + +// [ValueArgument(typeof(string), "X509Certificate2ThumbprintOrSubjectName", Description = "The X509Certificate2 Thumbprint or SubjectName to use.", Optional = true)] +// public string X509Certificate2ThumbprintOrSubjectName { get; set; } + +// [ValueArgument(typeof(string), "AdminUsername", Description = "The username needed for __admin access.", Optional = true)] +// public string AdminUsername { get; set; } + +// [ValueArgument(typeof(string), "AdminPassword", Description = "The password needed for __admin access.", Optional = true)] +// public string AdminPassword { get; set; } + +// [ValueArgument(typeof(int?), "RequestLogExpirationDuration", Description = "The RequestLog expiration in hours.", Optional = true)] +// public int? RequestLogExpirationDuration { get; set; } + +// [ValueArgument(typeof(int?), "MaxRequestLogCount", Description = "The MaxRequestLog count.", Optional = true)] +// public int? MaxRequestLogCount { get; set; } +// } + +// /// +// /// Start WireMock.Net standalone based on the FluentMockServerSettings. +// /// +// /// The FluentMockServerSettings +// [PublicAPI] +// public static FluentMockServer Start([NotNull] FluentMockServerSettings settings) +// { +// Check.NotNull(settings, nameof(settings)); + +// return FluentMockServer.Start(settings); +// } + +// /// +// /// Start WireMock.Net standalone based on the commandline arguments. +// /// +// /// The commandline arguments +// [PublicAPI] +// public static FluentMockServer Start([NotNull] string[] args) +// { +// Check.NotNull(args, nameof(args)); + +// // Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'"))); + +// var options = new Options(); +// var parser = new CommandLineParser.CommandLineParser(); +// parser.ExtractArgumentAttributes(options); + +// try +// { +// parser.ParseCommandLine(args); + +// Console.WriteLine("WireMock.Net server options {0}", JsonConvert.SerializeObject(options, Formatting.Indented)); + +// var settings = new FluentMockServerSettings +// { +// StartAdminInterface = options.StartAdminInterface, +// ReadStaticMappings = options.ReadStaticMappings, +// AllowPartialMapping = options.AllowPartialMapping, +// AdminUsername = options.AdminUsername, +// AdminPassword = options.AdminPassword, +// MaxRequestLogCount = options.MaxRequestLogCount, +// RequestLogExpirationDuration = options.RequestLogExpirationDuration +// }; + +// if (options.Port != null) +// { +// settings.Port = options.Port; +// } +// else if (options.Urls != null && options.Urls.Any()) +// { +// settings.Urls = options.Urls.ToArray(); +// } +// else +// { +// settings.Urls = new [] { "http://*:9091/" }; +// } + +// if (!string.IsNullOrEmpty(options.ProxyURL)) +// { +// settings.ProxyAndRecordSettings = new ProxyAndRecordSettings +// { +// Url = options.ProxyURL, +// SaveMapping = options.SaveMapping, +// X509Certificate2ThumbprintOrSubjectName = options.X509Certificate2ThumbprintOrSubjectName +// }; +// } + +// Console.WriteLine("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented)); + +// FluentMockServer server = Start(settings); + +// Console.WriteLine("WireMock.Net server listening at {0}", string.Join(" and ", server.Urls)); + +// return server; +// } +// catch (CommandLineException e) +// { +// Console.WriteLine(e.Message); +// parser.ShowUsage(); + +// throw; +// } +// } +// } +// } \ No newline at end of file diff --git a/src/WireMock.Net.StandAlone/StandAloneApp.cs b/src/WireMock.Net.StandAlone/StandAloneApp.cs index 5789534c..39afd651 100644 --- a/src/WireMock.Net.StandAlone/StandAloneApp.cs +++ b/src/WireMock.Net.StandAlone/StandAloneApp.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using CommandLineParser.Arguments; -using CommandLineParser.Exceptions; using WireMock.Server; using WireMock.Settings; using WireMock.Validation; @@ -16,45 +14,6 @@ namespace WireMock.Net.StandAlone /// public static class StandAloneApp { - private class Options - { - [ValueArgument(typeof(int), "Port", Description = "Port to listen on.", Optional = true)] - public int? Port { get; set; } - - [ValueArgument(typeof(string), "Urls", Description = "URL(s) to listen on.", Optional = true, AllowMultiple = true)] - public List Urls { get; set; } - - [SwitchArgument("AllowPartialMapping", false, Description = "Allow Partial Mapping (default set to false).", Optional = true)] - public bool AllowPartialMapping { get; set; } - - [SwitchArgument("StartAdminInterface", true, Description = "Start the AdminInterface (default set to true).", Optional = true)] - public bool StartAdminInterface { get; set; } - - [SwitchArgument("ReadStaticMappings", true, Description = "Read StaticMappings from ./__admin/mappings (default set to true).", Optional = true)] - public bool ReadStaticMappings { get; set; } - - [ValueArgument(typeof(string), "ProxyURL", Description = "The ProxyURL to use.", Optional = true)] - public string ProxyURL { get; set; } - - [SwitchArgument("SaveProxyMapping", true, Description = "Save the proxied request and response mapping files in ./__admin/mappings. (default set to true).", Optional = true)] - public bool SaveMapping { get; set; } - - [ValueArgument(typeof(string), "X509Certificate2ThumbprintOrSubjectName", Description = "The X509Certificate2 Thumbprint or SubjectName to use.", Optional = true)] - public string X509Certificate2ThumbprintOrSubjectName { get; set; } - - [ValueArgument(typeof(string), "AdminUsername", Description = "The username needed for __admin access.", Optional = true)] - public string AdminUsername { get; set; } - - [ValueArgument(typeof(string), "AdminPassword", Description = "The password needed for __admin access.", Optional = true)] - public string AdminPassword { get; set; } - - [ValueArgument(typeof(int?), "RequestLogExpirationDuration", Description = "The RequestLog expiration in hours (optional).", Optional = true)] - public int? RequestLogExpirationDuration { get; set; } - - [ValueArgument(typeof(int?), "MaxRequestLogCount", Description = "The MaxRequestLog count (optional).", Optional = true)] - public int? MaxRequestLogCount { get; set; } - } - /// /// Start WireMock.Net standalone based on the FluentMockServerSettings. /// @@ -68,7 +27,7 @@ namespace WireMock.Net.StandAlone } /// - /// Start WireMock.Net standalone bases on the commandline arguments. + /// Start WireMock.Net standalone based on the commandline arguments. /// /// The commandline arguments [PublicAPI] @@ -76,75 +35,49 @@ namespace WireMock.Net.StandAlone { Check.NotNull(args, nameof(args)); - var options = new Options(); - var parser = new CommandLineParser.CommandLineParser(); - parser.ExtractArgumentAttributes(options); + Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'"))); - try + var parser = new SimpleCommandLineParser(); + parser.Parse(args); + + var settings = new FluentMockServerSettings { - parser.ParseCommandLine(args); + StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true), + ReadStaticMappings = parser.GetBoolValue("ReadStaticMappings"), + AllowPartialMapping = parser.GetBoolValue("AllowPartialMapping", true), + AdminUsername = parser.GetStringValue("AdminUsername"), + AdminPassword = parser.GetStringValue("AdminPassword"), + MaxRequestLogCount = parser.GetIntValue("MaxRequestLogCount"), + RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"), + }; - if (!options.Urls.Any()) + if (parser.Contains("Port")) + { + settings.Port = parser.GetIntValue("Port"); + } + else + { + settings.Urls = parser.GetValues("Urls", new[] { "http://*:9091/" }); + } + + string proxyURL = parser.GetStringValue("ProxyURL"); + if (!string.IsNullOrEmpty(proxyURL)) + { + settings.ProxyAndRecordSettings = new ProxyAndRecordSettings { - options.Urls.Add("http://localhost:9091/"); - } - - var settings = new FluentMockServerSettings - { - StartAdminInterface = options.StartAdminInterface, - ReadStaticMappings = options.ReadStaticMappings, - AllowPartialMapping = options.AllowPartialMapping, - AdminUsername = options.AdminUsername, - AdminPassword = options.AdminPassword, - MaxRequestLogCount = options.MaxRequestLogCount, - RequestLogExpirationDuration = options.RequestLogExpirationDuration - + Url = proxyURL, + SaveMapping = parser.GetBoolValue("SaveMapping"), + X509Certificate2ThumbprintOrSubjectName = parser.GetStringValue("X509Certificate2ThumbprintOrSubjectName") }; - - if (options.Port != null) - { - settings.Port = options.Port; - } - else if (options.Urls != null) - { - settings.Urls = options.Urls.ToArray(); - } - - // if (options.MaxRequestLogCount > 0) - // { - // settings.MaxRequestLogCount = options.MaxRequestLogCount; - // } - - // if (options.RequestLogExpirationDuration > 0) - // { - // settings.RequestLogExpirationDuration = options.RequestLogExpirationDuration; - // } - - if (!string.IsNullOrEmpty(options.ProxyURL)) - { - settings.ProxyAndRecordSettings = new ProxyAndRecordSettings - { - Url = options.ProxyURL, - SaveMapping = options.SaveMapping, - X509Certificate2ThumbprintOrSubjectName = options.X509Certificate2ThumbprintOrSubjectName - }; - } - - Console.WriteLine("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented)); - - FluentMockServer server = Start(settings); - - Console.WriteLine("WireMock.Net server listening at {0}", string.Join(" and ", server.Urls)); - - return server; } - catch (CommandLineException e) - { - Console.WriteLine(e.Message); - parser.ShowUsage(); - throw; - } + Console.WriteLine("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented)); + + FluentMockServer server = Start(settings); + + Console.WriteLine("WireMock.Net server listening at {0}", string.Join(" and ", server.Urls)); + + return server; } } } \ No newline at end of file diff --git a/src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj b/src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj index 2b06714f..61684ace 100644 --- a/src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj +++ b/src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj @@ -31,7 +31,10 @@ All - + + + +