diff --git a/.gitignore b/.gitignore index 2f2f78c8..b66be003 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,5 @@ artifacts/* *.nuget.props *.DotSettings.user +*/build/* +build diff --git a/appveyor.yml b/appveyor.yml index 01984685..8e139384 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,9 +1,25 @@ +version: 0.0.1.{build} + +clone_depth: 1 +pull_requests: + do_not_increment_build_number: true + init: - git config --global core.autocrlf input + build_script: - cmd: build.cmd + test: off -version: 0.0.1.{build} + artifacts: - - path: bin - name: bin +- path: build/*.nupkg + name: NugetPackage + +deploy: +- provider: NuGet + api_key: + secure: sQzzieUQGkTU0CvzXLcv5Wph6K7h3T+8teovqwa/Dzk1p9WhpmuUHiRxd3U0YhqO + artifact: 'NuGetPackage' + on: + branch: release \ No newline at end of file diff --git a/build.cmd b/build.cmd index b5a72cab..39db539c 100644 --- a/build.cmd +++ b/build.cmd @@ -15,4 +15,7 @@ if errorlevel 1 ( .\packages\FAKE\tools\Fake %* dotnet restore -dotnet build --configuration Release --output build\netstandard1.5 --framework netstandard1.5 src\commandline \ No newline at end of file +dotnet build --configuration Release --output .\build\netstandard1.5 --framework netstandard1.5 src\commandline /p:PackageVersion=%APPVEYOR_BUILD_VERSION% + +dotnet restore .\src\CommandLine\CommandLine.netstandard.csproj +dotnet build --configuration Release --output .\build\netstandard2.0 --framework netstandard2.0 src\commandline\commandline.netstandard.csproj /p:PackageVersion=%APPVEYOR_BUILD_VERSION% diff --git a/src/CommandLine/CommandLine.csproj b/src/CommandLine/CommandLine.csproj index 7b791726..d645ed6c 100644 --- a/src/CommandLine/CommandLine.csproj +++ b/src/CommandLine/CommandLine.csproj @@ -75,6 +75,7 @@ + @@ -83,6 +84,7 @@ + @@ -168,7 +170,7 @@ - + ..\..\packages\FSharp.Core\lib\net40\FSharp.Core.dll @@ -177,7 +179,7 @@ - + ..\..\packages\FSharp.Core\lib\portable-net45+netcore45\FSharp.Core.dll @@ -186,37 +188,28 @@ - + - ..\..\packages\FSharp.Core\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll - True - True - - - - - - - ..\..\packages\FSharp.Core\lib\portable-net45+sl5+netcore45\FSharp.Core.dll + ..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wp8\FSharp.Core.dll True True - + - ..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wp8\FSharp.Core.dll + ..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wpa81+wp8\FSharp.Core.dll True True - + - ..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wpa81+wp8\FSharp.Core.dll + ..\..\packages\FSharp.Core\lib\portable-net45+sl5+netcore45\FSharp.Core.dll True True diff --git a/src/CommandLine/CommandLine.netstandard.csproj b/src/CommandLine/CommandLine.netstandard.csproj new file mode 100644 index 00000000..5eb0728b --- /dev/null +++ b/src/CommandLine/CommandLine.netstandard.csproj @@ -0,0 +1,63 @@ + + + + netstandard2.0 + true + CommandLine-NetStandard + gsscoder, clmcgrath + + CommandLine.netstandard20 + + 1.0.0.0 + false + + + + TRACE;DEBUG;CSX_EITHER_INTERNAL; CSX_REM_EITHER_BEYOND_2; CSX_ENUM_INTERNAL; ERRH_INTERNAL; ERRH_DISABLE_INLINE_METHODS; CSX_MAYBE_INTERNAL; CSX_REM_EITHER_FUNC;NETSTANDARD2_0 + + + + TRACE;CSX_EITHER_INTERNAL; CSX_REM_EITHER_BEYOND_2; CSX_ENUM_INTERNAL; ERRH_INTERNAL; ERRH_DISABLE_INLINE_METHODS; CSX_MAYBE_INTERNAL; CSX_REM_EITHER_FUNC;RELEASE;NETSTANDARD2_0 + + + + + + + + + + + + + + + + + + + + True + Infrastructure/ErrorHandling.cs + + + True + Infrastructure/EnumerableExtensions.cs + + + True + Infrastructure/Maybe.cs + + + + + + + + + + + + + + diff --git a/src/CommandLine/Core/InstanceBuilder.cs b/src/CommandLine/Core/InstanceBuilder.cs index 0c24fddd..dcebc0d6 100644 --- a/src/CommandLine/Core/InstanceBuilder.cs +++ b/src/CommandLine/Core/InstanceBuilder.cs @@ -16,6 +16,7 @@ namespace CommandLine.Core { static class InstanceBuilder { + public static ParserResult Build( Maybe> factory, Func, IEnumerable, Result, Error>> tokenizer, @@ -82,7 +83,7 @@ public static ParserResult Build( Func buildMutable = () => { - var mutable = factory.MapValueOrDefault(f => f(), Activator.CreateInstance()); + var mutable = factory.MapValueOrDefault(f => f(), ParserSettings.ObjectFactory.Resolve()); mutable = mutable.SetProperties(specPropsWithValue, sp => sp.Value.IsJust(), sp => sp.Value.FromJustOrFail()) .SetProperties( diff --git a/src/CommandLine/Core/ReflectionExtensions.cs b/src/CommandLine/Core/ReflectionExtensions.cs index 3b011316..7d400391 100644 --- a/src/CommandLine/Core/ReflectionExtensions.cs +++ b/src/CommandLine/Core/ReflectionExtensions.cs @@ -168,7 +168,7 @@ public static object AutoDefault(this Type type) { if (type.IsMutable()) { - return Activator.CreateInstance(type); + return ParserSettings.ObjectFactory.Resolve(type); } var ctorTypes = type.GetSpecifications(pi => pi.PropertyType).ToArray(); @@ -183,10 +183,11 @@ public static TypeInfo ToTypeInfo(this Type type) public static object StaticMethod(this Type type, string name, params object[] args) { -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 MethodInfo method = type.GetTypeInfo().GetDeclaredMethod(name); return method.Invoke(null, args); #else + return type.GetTypeInfo().InvokeMember( name, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, @@ -198,7 +199,7 @@ public static object StaticMethod(this Type type, string name, params object[] a public static object StaticProperty(this Type type, string name) { -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 PropertyInfo property = type.GetTypeInfo().GetDeclaredProperty(name); return property.GetValue(null); #else @@ -213,7 +214,7 @@ public static object StaticProperty(this Type type, string name) public static object InstanceProperty(this Type type, string name, object target) { -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 PropertyInfo property = type.GetTypeInfo().GetDeclaredProperty(name); return property.GetValue(target); #else diff --git a/src/CommandLine/Infrastructure/DefaultObjectFactory.cs b/src/CommandLine/Infrastructure/DefaultObjectFactory.cs new file mode 100644 index 00000000..c8392ca6 --- /dev/null +++ b/src/CommandLine/Infrastructure/DefaultObjectFactory.cs @@ -0,0 +1,22 @@ +using System; + +namespace CommandLine.Infrastructure +{ + /// + /// Default object factory to use with parser, defaults to Activator.CreateInstance() + /// + public class DefaultObjectFactory : IObjectFactory + { + /// + public T Resolve() + { + return Activator.CreateInstance(); + } + + /// + public object Resolve(Type type) + { + return Activator.CreateInstance(type); + } + } +} \ No newline at end of file diff --git a/src/CommandLine/Infrastructure/FSharpOptionHelper.cs b/src/CommandLine/Infrastructure/FSharpOptionHelper.cs index 783cfa83..e38e15d5 100644 --- a/src/CommandLine/Infrastructure/FSharpOptionHelper.cs +++ b/src/CommandLine/Infrastructure/FSharpOptionHelper.cs @@ -14,9 +14,14 @@ public static Type GetUnderlyingType(Type type) { return type #if NETSTANDARD1_5 - .GetTypeInfo() -#endif + .GetTypeInfo().GetGenericArguments()[0]; +#elif NETSTANDARD2_0 + .GenericTypeArguments[0]; +#else .GetGenericArguments()[0]; +#endif + + } public static object Some(Type type, object value) diff --git a/src/CommandLine/Infrastructure/IObjectFactory.cs b/src/CommandLine/Infrastructure/IObjectFactory.cs new file mode 100644 index 00000000..00ebb6ce --- /dev/null +++ b/src/CommandLine/Infrastructure/IObjectFactory.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CommandLine.Infrastructure +{ + /// + /// + /// + public interface IObjectFactory + { + /// + /// Creates an instance of specified type "/> + /// + /// + T Resolve(); + /// + /// Creates an instance of specified type "/> + /// + /// /// + /// + object Resolve(Type type); + } +} diff --git a/src/CommandLine/Infrastructure/ReflectionHelper.cs b/src/CommandLine/Infrastructure/ReflectionHelper.cs index c054f83c..2ba63879 100644 --- a/src/CommandLine/Infrastructure/ReflectionHelper.cs +++ b/src/CommandLine/Infrastructure/ReflectionHelper.cs @@ -103,7 +103,7 @@ private static Assembly GetExecutingOrEntryAssembly() { var assembly = Assembly.GetEntryAssembly(); -#if !NETSTANDARD1_5 +#if !NETSTANDARD1_5 && !NETSTANDARD2_0 assembly = assembly ?? Assembly.GetExecutingAssembly(); #endif diff --git a/src/CommandLine/Parser.cs b/src/CommandLine/Parser.cs index 69a7e862..d5aa01e0 100644 --- a/src/CommandLine/Parser.cs +++ b/src/CommandLine/Parser.cs @@ -88,7 +88,7 @@ public ParserResult ParseArguments(IEnumerable args) if (args == null) throw new ArgumentNullException("args"); var factory = typeof(T).IsMutable() - ? Maybe.Just>(Activator.CreateInstance) + ? Maybe.Just>(ParserSettings.ObjectFactory.Resolve) : Maybe.Nothing>(); return MakeParserResult( @@ -103,6 +103,7 @@ public ParserResult ParseArguments(IEnumerable args) settings); } + /// /// Parses a string array of command line arguments constructing values in an instance of type . /// Grammar rules are defined decorating public properties with appropriate attributes. @@ -114,7 +115,6 @@ public ParserResult ParseArguments(IEnumerable args) /// and a sequence of . /// Thrown if one or more arguments are null. public ParserResult ParseArguments(Func factory, IEnumerable args) - where T : new() { if (factory == null) throw new ArgumentNullException("factory"); if (!typeof(T).IsMutable()) throw new ArgumentException("factory"); @@ -222,4 +222,5 @@ private void Dispose(bool disposing) } } } + } \ No newline at end of file diff --git a/src/CommandLine/ParserSettings.cs b/src/CommandLine/ParserSettings.cs index 93962566..8ea899a3 100644 --- a/src/CommandLine/ParserSettings.cs +++ b/src/CommandLine/ParserSettings.cs @@ -32,6 +32,7 @@ public ParserSettings() caseSensitive = true; caseInsensitiveEnumValues = false; parsingCulture = CultureInfo.InvariantCulture; + try { maximumDisplayWidth = Console.WindowWidth; @@ -42,6 +43,11 @@ public ParserSettings() } } + /// + /// Object Factory to use for new instances + /// + public static IObjectFactory ObjectFactory { get; set; } = new DefaultObjectFactory(); + /// /// Finalizes an instance of the class. /// @@ -50,6 +56,7 @@ public ParserSettings() Dispose(false); } + /// /// Gets or sets a value indicating whether perform case sensitive comparisons. /// Note that case insensitivity only applies to parameters, not the values diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index eaa6ade5..1fda10ec 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -694,7 +694,7 @@ private static Maybe>> GetUsageFromTy var prop = tuple.Item1; var attr = tuple.Item2; -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 var examples = (IEnumerable)prop.GetValue(null); #else var examples = (IEnumerable)prop