Skip to content

Commit ce9cfc4

Browse files
committed
1 parent b0b0ec9 commit ce9cfc4

File tree

3 files changed

+76
-4
lines changed

3 files changed

+76
-4
lines changed

src/CommandLine/Core/ReflectionExtensions.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ static class ReflectionExtensions
1515
{
1616
public static IEnumerable<T> GetSpecifications<T>(this Type type, Func<PropertyInfo, T> selector)
1717
{
18-
return from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties())
18+
return from pi in type.FlattenHierarchy()
19+
.SelectMany(x => x.GetTypeInfo()
20+
.GetProperties(BindingFlags.Instance | BindingFlags.Static |
21+
BindingFlags.NonPublic | BindingFlags.Public))
1922
let attrs = pi.GetCustomAttributes(true)
2023
where
2124
attrs.OfType<OptionAttribute>().Any() ||
@@ -38,7 +41,9 @@ public static Maybe<VerbAttribute> GetVerbSpecification(this Type type)
3841
public static Maybe<Tuple<PropertyInfo, UsageAttribute>> GetUsageData(this Type type)
3942
{
4043
return
41-
(from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties())
44+
(from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties(
45+
BindingFlags.Instance | BindingFlags.Static |
46+
BindingFlags.NonPublic | BindingFlags.Public))
4247
let attrs = pi.GetCustomAttributes(typeof(UsageAttribute), true)
4348
where attrs.Any()
4449
select Tuple.Create(pi, (UsageAttribute)attrs.First()))

src/CommandLine/Text/HelpText.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -839,8 +839,10 @@ private static Maybe<Tuple<UsageAttribute, IEnumerable<Example>>> GetUsageFromTy
839839
var prop = tuple.Item1;
840840
var attr = tuple.Item2;
841841

842-
var examples = (IEnumerable<Example>)prop
843-
.GetValue(null, BindingFlags.Public | BindingFlags.Static | BindingFlags.GetProperty, null, null, null);
842+
var examples = (IEnumerable<Example>) prop
843+
.GetValue(null,
844+
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static |
845+
BindingFlags.GetProperty, null, null, null);
844846

845847
return Tuple.Create(attr, examples);
846848
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using CommandLine.Text;
4+
using FluentAssertions;
5+
using Xunit;
6+
7+
// Issue #830
8+
// Allow private properties as options and usage
9+
namespace CommandLine.Tests.Unit
10+
{
11+
public class Issue830Tests
12+
{
13+
[Fact]
14+
public void Parse_options_with_private_value_and_option()
15+
{
16+
var expectedOptions = new Options
17+
{
18+
Option = "a",
19+
Value = "b"
20+
};
21+
22+
var result = Parser.Default.ParseArguments<Options>(
23+
new[] { "b", "--opt", "a" });
24+
25+
((Parsed<Options>)result).Value.Should().BeEquivalentTo(expectedOptions);
26+
}
27+
28+
[Fact]
29+
public void Print_private_usage()
30+
{
31+
var help = new StringWriter();
32+
var sut = new Parser(config => config.HelpWriter = help);
33+
34+
sut.ParseArguments<Options>(new string[] { "--help" });
35+
var result = help.ToString();
36+
37+
var lines = result.ToLines().TrimStringArray();
38+
lines[3].Should().BeEquivalentTo("Do something very cool:");
39+
lines[4].Should().BeEquivalentTo("CommandLine --opt test1 test2");
40+
}
41+
42+
private class Options
43+
{
44+
public string Option { get => PrivateOption; set => PrivateOption = value; }
45+
46+
public string Value { get => PrivateValue; set => PrivateValue = value; }
47+
48+
[Option("opt", Required = true)]
49+
private string PrivateOption { get; set; }
50+
51+
[Value(0, Required = true)]
52+
private string PrivateValue { get; set; }
53+
54+
[Usage]
55+
private static IEnumerable<Example> PrivateUsage { get; } = new List<Example>
56+
{
57+
new Example("Do something very cool", new Options
58+
{
59+
PrivateOption = "test1",
60+
PrivateValue = "test2"
61+
})
62+
};
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)