Skip to content
Permalink
Browse files
[Mono.Options] CommandSet and PCL/NetStandard Support (#4719)
When `PCL` is defined, the intent is that the resulting
`Mono.Options.dll` assembly will be usable on all PCL profiles.
This includes "silly" profiles such as Profile259, which lacks the
`System.Console` type, meaning e.g. `Console.Out` doesn't exist.

Unfortunately, the
`CommandSet(string, Converter<string, string, TextWriter, TextWriter)`
constructor would use `Console.Out` and `Console.Error` when the
`TextWriter` parameters were `null`, meaning this constructor can't
be provided for all PCL profiles.

Altering the constructor to instead use `TextWriter.Null` would allow
the constructor to be provided, but would be a *worse* experience,
IMHO: anybody (everybody!) expecting the default values to
"do something useful" will be sorely disappointed, as output and
error messages would instead be dropped. :-(

Instead, remove this constructor:

	public CommandSet (string suite, MessageLocalizerConverter localizer = null, TextWriter output = null, TextWriter error = null);

and replace it with these *two* constructors:

	public CommandSet (string suite, MessageLocalizerConverter localizer = null)
	public CommandSet (string suite, TextWriter output, TextWriter error, MessageLocalizerConverter localizer = null)

The first constructor, which accepts no `TextWriter` parameters, is
only provided in non-PCL builds, allowing it to use `Console.Out`.

The second constructor is available in PCL profiles, and *requires*
that `output` and `error` be non-`null`.

Documentation has been updated accordingly.
  • Loading branch information
mattleibow authored and jonpryor committed Apr 20, 2017
1 parent ca2292b commit 7e2571ed334e9cee3f0d3bafeef02852310f4d3b
@@ -250,17 +250,15 @@ commands: Use `commands help` for usage.
</Docs>
<Members>
<Member MemberName=".ctor">
<MemberSignature Language="C#" Value="public CommandSet (string suite, Converter&lt;string,string&gt; localizer = null, System.IO.TextWriter output = null, System.IO.TextWriter error = null);" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor(string suite, class System.Converter`2&lt;string, string&gt; localizer, class System.IO.TextWriter output, class System.IO.TextWriter error) cil managed" />
<MemberSignature Language="C#" Value="public CommandSet (string suite, Converter&lt;string,string&gt; localizer = null);" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor(string suite, class System.Converter`2&lt;string, string&gt; localizer) cil managed" />
<MemberType>Constructor</MemberType>
<AssemblyInfo>
<AssemblyVersion>0.2.3.0</AssemblyVersion>
</AssemblyInfo>
<Parameters>
<Parameter Name="suite" Type="System.String" />
<Parameter Name="localizer" Type="System.Converter&lt;System.String,System.String&gt;" />
<Parameter Name="output" Type="System.IO.TextWriter" />
<Parameter Name="error" Type="System.IO.TextWriter" />
</Parameters>
<Docs>
<param name="suite">
@@ -272,15 +270,57 @@ commands: Use `commands help` for usage.
instance that will be used to translate strings.
If <see langword="null" />, then no localization is performed.
</param>
<summary>
Creates and initializes a new <c>CommandSet</c> instance.
</summary>
<remarks>
<para>
This constructor initializes
the <see cref="P:Mono.Options.CommandSet.Suite" /> property
of the new instance using <paramref name="suite" />,
the <see cref="P:Mono.Options.CommandSet.MessageLocalizer" /> property
of the new instance using <paramref name="localizer" />,
the <see cref="P:Mono.Options.CommandSet.Out" /> property
to <see cref="P:System.Console.Out" />, and
the <see cref="P:Mono.Options.CommandSet.Error" /> property
to <see cref="P:System.Console.Error" />.
</para>
</remarks>
<exception cref="T:System.ArgumentNullException">
<paramref name="suite" /> is <see langword="null" />.
</exception>
</Docs>
</Member>
<Member MemberName=".ctor">
<MemberSignature Language="C#" Value="public CommandSet (string suite, System.IO.TextWriter output, System.IO.TextWriter error, Converter&lt;string,string&gt; localizer = null);" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor(string suite, class System.IO.TextWriter output, class System.IO.TextWriter error, class System.Converter`2&lt;string, string&gt; localizer) cil managed" />
<MemberType>Constructor</MemberType>
<AssemblyInfo>
<AssemblyVersion>0.2.3.0</AssemblyVersion>
</AssemblyInfo>
<Parameters>
<Parameter Name="suite" Type="System.String" />
<Parameter Name="output" Type="System.IO.TextWriter" />
<Parameter Name="error" Type="System.IO.TextWriter" />
<Parameter Name="localizer" Type="System.Converter&lt;System.String,System.String&gt;" />
</Parameters>
<Docs>
<param name="suite">
A <see cref="T:System.String" /> containing the name of the suite.
This value is used in default <c>help</c> text output.
</param>
<param name="output">
A <see cref="T:System.IO.TextWriter" /> where output messages will be
written to. If <see langword="null" />, then the
<see cref="P:System.Console.Out" /> property will be used.
written to.
</param>
<param name="error">
A <see cref="T:System.IO.TextWriter" /> where error messages will be
written to. If <see langword="null" />, then the
<see cref="P:System.Console.Error" /> property will be used.
written to.
</param>
<param name="localizer">
A <see cref="T:System.Converter{System.String,System.String}" />
instance that will be used to translate strings.
If <see langword="null" />, then no localization is performed.
</param>
<summary>
Creates and initializes a new <c>CommandSet</c> instance.
@@ -301,6 +341,12 @@ commands: Use `commands help` for usage.
<exception cref="T:System.ArgumentNullException">
<paramref name="suite" /> is <see langword="null" />.
</exception>
<exception cref="T:System.ArgumentNullException">
<paramref name="output" /> is <see langword="null" />.
</exception>
<exception cref="T:System.ArgumentNullException">
<paramref name="error" /> is <see langword="null" />.
</exception>
</Docs>
</Member>
<Member MemberName="Add">
@@ -162,10 +162,10 @@
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
#if PCL
using System.Reflection;
#else
using System.Runtime.Serialization;
using System.Security.Permissions;
#endif
using System.Text;
@@ -634,7 +634,7 @@ protected ArgumentSource ()
public abstract string Description { get; }
public abstract bool GetArguments (string value, out IEnumerable<string> replacement);

#if !PCL
#if !PCL || NETSTANDARD1_3
public static IEnumerable<string> GetArgumentsFromFile (string file)
{
return GetArguments (File.OpenText (file), true);
@@ -690,7 +690,7 @@ static IEnumerable<string> GetArguments (TextReader reader, bool close)
}
}

#if !PCL
#if !PCL || NETSTANDARD1_3
public class ResponseFileSource : ArgumentSource {

public override string[] GetNames ()
@@ -1586,14 +1586,26 @@ public class CommandSet : KeyedCollection<string, Command>

internal OptionSet Options => options;

public CommandSet (string suite, MessageLocalizerConverter localizer = null, TextWriter output = null, TextWriter error = null)
#if !PCL || NETSTANDARD1_3
public CommandSet(string suite, MessageLocalizerConverter localizer = null)
: this(suite, Console.Out, Console.Error, localizer)
{
}
#endif

public CommandSet (string suite, TextWriter output, TextWriter error, MessageLocalizerConverter localizer = null)
{
if (suite == null)
throw new ArgumentNullException (nameof (suite));
if (output == null)
throw new ArgumentNullException (nameof (output));
if (error == null)
throw new ArgumentNullException (nameof (error));

this.suite = suite;
options = new CommandOptionSet (this, localizer);
outWriter = output ?? Console.Out;
errorWriter = error ?? Console.Error;
outWriter = output;
errorWriter = error;
}

public string Suite => suite;

0 comments on commit 7e2571e

Please sign in to comment.