From 82b0c6fd98a56c49b574385305f5ff0b733319ba Mon Sep 17 00:00:00 2001
From: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
Date: Sun, 11 Aug 2024 22:12:36 +0300
Subject: [PATCH] asd
---
CliFx/Attributes/CommandAttribute.cs | 28 ++++-------
.../Attributes/CommandHelpOptionAttribute.cs | 5 +-
CliFx/Attributes/CommandInputAttribute.cs | 34 +++++++++++++
CliFx/Attributes/CommandOptionAttribute.cs | 40 ++-------------
CliFx/Attributes/CommandParameterAttribute.cs | 49 +++++--------------
.../CommandVersionOptionAttribute.cs | 5 +-
CliFx/Schema/InputSchema.cs | 9 +++-
CliFx/Schema/OptionSchema.cs | 7 +--
CliFx/Schema/ParameterSchema.cs | 7 +--
CliFx/Utils/NoPreambleEncoding.cs | 2 +-
10 files changed, 80 insertions(+), 106 deletions(-)
create mode 100644 CliFx/Attributes/CommandInputAttribute.cs
diff --git a/CliFx/Attributes/CommandAttribute.cs b/CliFx/Attributes/CommandAttribute.cs
index d7cbb1d..13025b6 100644
--- a/CliFx/Attributes/CommandAttribute.cs
+++ b/CliFx/Attributes/CommandAttribute.cs
@@ -4,33 +4,25 @@ namespace CliFx.Attributes;
///
/// Annotates a type that defines a command.
+/// If a command is named, then the user must provide its name through the command-line arguments in order to execute it.
+/// If a command is not named, then it is treated as the application's default command and is executed when no other
+/// command is specified.
///
+///
+/// Only one default command is allowed per application.
+/// All commands registered in an application must have unique names (comparison IS NOT case-sensitive).
+///
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
-public class CommandAttribute : Attribute
+public class CommandAttribute(string? name = null) : Attribute
{
- ///
- /// Initializes an instance of .
- ///
- public CommandAttribute(string name) => Name = name;
-
- ///
- /// Initializes an instance of .
- ///
- public CommandAttribute() { }
-
///
/// Command name.
///
- ///
- /// Command can have no name, in which case it's treated as the application's default command.
- /// Only one default command is allowed in an application.
- /// All commands registered in an application must have unique names (comparison IS NOT case-sensitive).
- ///
- public string? Name { get; }
+ public string? Name { get; } = name;
///
/// Command description.
/// This is shown to the user in the help text.
///
public string? Description { get; set; }
-}
+}
\ No newline at end of file
diff --git a/CliFx/Attributes/CommandHelpOptionAttribute.cs b/CliFx/Attributes/CommandHelpOptionAttribute.cs
index 2c7ba04..fa0fd71 100644
--- a/CliFx/Attributes/CommandHelpOptionAttribute.cs
+++ b/CliFx/Attributes/CommandHelpOptionAttribute.cs
@@ -1,8 +1,11 @@
namespace CliFx.Attributes;
///
-/// Annotates a property that defines the help option for a command.
+/// Binds a property to the help option of a command.
///
+///
+/// This attribute is applied automatically by the framework and should not be used explicitly.
+///
public class CommandHelpOptionAttribute : CommandOptionAttribute
{
///
diff --git a/CliFx/Attributes/CommandInputAttribute.cs b/CliFx/Attributes/CommandInputAttribute.cs
new file mode 100644
index 0000000..53457ce
--- /dev/null
+++ b/CliFx/Attributes/CommandInputAttribute.cs
@@ -0,0 +1,34 @@
+using System;
+using CliFx.Extensibility;
+
+namespace CliFx.Attributes;
+
+///
+/// Binds a property to a command-line input.
+///
+[AttributeUsage(AttributeTargets.Property)]
+public abstract class CommandInputAttribute : Attribute
+{
+ ///
+ /// Input description, as shown in the help text.
+ ///
+ public string? Description { get; set; }
+
+ ///
+ /// Custom converter used for mapping the raw command-line argument into
+ /// the type and shape expected by the underlying property.
+ ///
+ ///
+ /// Converter must derive from .
+ ///
+ public Type? Converter { get; set; }
+
+ ///
+ /// Custom validators used for verifying the value of the underlying
+ /// property, after it has been set.
+ ///
+ ///
+ /// Validators must derive from .
+ ///
+ public Type[] Validators { get; set; } = [];
+}
\ No newline at end of file
diff --git a/CliFx/Attributes/CommandOptionAttribute.cs b/CliFx/Attributes/CommandOptionAttribute.cs
index 4cd8ea6..6dd90a7 100644
--- a/CliFx/Attributes/CommandOptionAttribute.cs
+++ b/CliFx/Attributes/CommandOptionAttribute.cs
@@ -4,10 +4,13 @@ using CliFx.Extensibility;
namespace CliFx.Attributes;
///
-/// Annotates a property that defines a command option.
+/// Binds a property to a command option — a command-line input that is identified by a name and/or a short name.
///
+///
+/// All options in a command must have unique names (comparison IS NOT case-sensitive) and short names (comparison IS case-sensitive).
+///
[AttributeUsage(AttributeTargets.Property)]
-public class CommandOptionAttribute : Attribute
+public class CommandOptionAttribute : CommandInputAttribute
{
///
/// Initializes an instance of .
@@ -39,20 +42,11 @@ public class CommandOptionAttribute : Attribute
///
/// Option name.
///
- ///
- /// Must contain at least two characters and start with a letter.
- /// Either or must be set.
- /// All options in a command must have unique names (comparison IS NOT case-sensitive).
- ///
public string? Name { get; }
///
/// Option short name.
///
- ///
- /// Either or must be set.
- /// All options in a command must have unique short names (comparison IS case-sensitive).
- ///
public char? ShortName { get; }
///
@@ -70,28 +64,4 @@ public class CommandOptionAttribute : Attribute
/// has not been explicitly set through command-line arguments.
///
public string? EnvironmentVariable { get; set; }
-
- ///
- /// Option description.
- /// This is shown to the user in the help text.
- ///
- public string? Description { get; set; }
-
- ///
- /// Custom converter used for mapping the raw command-line argument into
- /// a value expected by the underlying property.
- ///
- ///
- /// Converter must derive from .
- ///
- public Type? Converter { get; set; }
-
- ///
- /// Custom validators used for verifying the value of the underlying
- /// property, after it has been bound.
- ///
- ///
- /// Validators must derive from .
- ///
- public Type[] Validators { get; set; } = Array.Empty();
}
diff --git a/CliFx/Attributes/CommandParameterAttribute.cs b/CliFx/Attributes/CommandParameterAttribute.cs
index db5cc61..9cc1f5e 100644
--- a/CliFx/Attributes/CommandParameterAttribute.cs
+++ b/CliFx/Attributes/CommandParameterAttribute.cs
@@ -5,21 +5,21 @@ using CliFx.Extensibility;
namespace CliFx.Attributes;
///
-/// Annotates a property that defines a command parameter.
+/// Binds a property to a command parameter — a command-line input that is identified by its relative position (order).
+/// Higher order means that the parameter appears later, lower order means that it appears earlier.
///
+///
+/// All parameters in a command must have unique order values.
+/// If a parameter is bound to a property whose type is a sequence (e.g. Array, ; except ),
+/// then it must have the highest order in the command.
+/// Only one sequential parameter is allowed per command.
+///
[AttributeUsage(AttributeTargets.Property)]
-public class CommandParameterAttribute(int order) : Attribute
+public class CommandParameterAttribute(int order) : CommandInputAttribute
{
///
/// Parameter order.
- /// Higher order means the parameter appears later, lower order means it appears earlier.
///
- ///
- /// All parameters in a command must have unique order.
- /// Parameter whose type is a sequence (e.g. Array, ; except ),
- /// must always be the last parameter based on order.
- /// Only one sequential parameter is allowed in a command.
- ///
public int Order { get; } = order;
///
@@ -27,41 +27,16 @@ public class CommandParameterAttribute(int order) : Attribute
/// If a parameter is required, the user will get an error if they don't set it.
///
///
- /// Parameter marked as non-required must always be the last in order.
- /// Only one non-required parameter is allowed in a command.
+ /// Parameter marked as non-required must have the highest order in the command.
+ /// Only one non-required parameter is allowed per command.
///
public bool IsRequired { get; set; } = true;
///
- /// Parameter name.
- /// This is shown to the user in the help text.
+ /// Parameter name, as shown in the help text.
///
///
/// If this isn't specified, parameter name is inferred from the property name.
///
public string? Name { get; set; }
-
- ///
- /// Parameter description.
- /// This is shown to the user in the help text.
- ///
- public string? Description { get; set; }
-
- ///
- /// Custom converter used for mapping the raw command-line argument into
- /// a value expected by the underlying property.
- ///
- ///
- /// Converter must derive from .
- ///
- public Type? Converter { get; set; }
-
- ///
- /// Custom validators used for verifying the value of the underlying
- /// property, after it has been bound.
- ///
- ///
- /// Validators must derive from .
- ///
- public Type[] Validators { get; set; } = Array.Empty();
}
diff --git a/CliFx/Attributes/CommandVersionOptionAttribute.cs b/CliFx/Attributes/CommandVersionOptionAttribute.cs
index 44cce02..0169d28 100644
--- a/CliFx/Attributes/CommandVersionOptionAttribute.cs
+++ b/CliFx/Attributes/CommandVersionOptionAttribute.cs
@@ -1,8 +1,11 @@
namespace CliFx.Attributes;
///
-/// Annotates a property that defines the version option for a command.
+/// Binds a property to the version option of a command.
///
+///
+/// This attribute is applied automatically by the framework and should not be used explicitly.
+///
public class CommandVersionOptionAttribute : CommandOptionAttribute
{
///
diff --git a/CliFx/Schema/InputSchema.cs b/CliFx/Schema/InputSchema.cs
index f692e94..94af029 100644
--- a/CliFx/Schema/InputSchema.cs
+++ b/CliFx/Schema/InputSchema.cs
@@ -14,6 +14,7 @@ namespace CliFx.Schema;
///
public abstract class InputSchema(
PropertyBinding property,
+ string? description,
IBindingConverter converter,
IReadOnlyList validators
)
@@ -22,6 +23,11 @@ public abstract class InputSchema(
property.Type != typeof(string)
&& property.Type.TryGetEnumerableUnderlyingType() is not null;
+ ///
+ /// Input description, used in the help text.
+ ///
+ public string? Description { get; } = description;
+
///
/// CLR property to which this input is bound.
///
@@ -119,7 +125,8 @@ public abstract class InputSchema<
TProperty
>(
PropertyBinding property,
+ string? description,
BindingConverter converter,
IReadOnlyList> validators
-) : InputSchema(property, converter, validators)
+) : InputSchema(property, description, converter, validators)
where TCommand : ICommand;
diff --git a/CliFx/Schema/OptionSchema.cs b/CliFx/Schema/OptionSchema.cs
index 84554b1..52cbd3b 100644
--- a/CliFx/Schema/OptionSchema.cs
+++ b/CliFx/Schema/OptionSchema.cs
@@ -18,7 +18,7 @@ public class OptionSchema(
string? description,
IBindingConverter converter,
IReadOnlyList validators
-) : InputSchema(property, converter, validators)
+) : InputSchema(property,description, converter, validators)
{
///
/// Option name.
@@ -40,11 +40,6 @@ public class OptionSchema(
///
public bool IsRequired { get; } = isRequired;
- ///
- /// Option description.
- ///
- public string? Description { get; } = description;
-
internal bool MatchesName(string? name) =>
!string.IsNullOrWhiteSpace(Name)
&& string.Equals(Name, name, StringComparison.OrdinalIgnoreCase);
diff --git a/CliFx/Schema/ParameterSchema.cs b/CliFx/Schema/ParameterSchema.cs
index 4ed896f..232fe68 100644
--- a/CliFx/Schema/ParameterSchema.cs
+++ b/CliFx/Schema/ParameterSchema.cs
@@ -15,7 +15,7 @@ public class ParameterSchema(
string? description,
IBindingConverter converter,
IReadOnlyList validators
-) : InputSchema(property, converter, validators)
+) : InputSchema(property, description, converter, validators)
{
///
/// Order, in which the parameter is bound from the command-line arguments.
@@ -32,11 +32,6 @@ public class ParameterSchema(
///
public bool IsRequired { get; } = isRequired;
- ///
- /// Parameter description.
- ///
- public string? Description { get; } = description;
-
internal override string GetKind() => "Parameter";
internal override string GetFormattedIdentifier() => IsSequence ? $"<{Name}>" : $"<{Name}...>";
diff --git a/CliFx/Utils/NoPreambleEncoding.cs b/CliFx/Utils/NoPreambleEncoding.cs
index e6c2ad4..d3494f2 100644
--- a/CliFx/Utils/NoPreambleEncoding.cs
+++ b/CliFx/Utils/NoPreambleEncoding.cs
@@ -51,7 +51,7 @@ internal class NoPreambleEncoding(Encoding underlyingEncoding)
public override bool IsMailNewsSave => underlyingEncoding.IsMailNewsSave;
// This is the only part that changes
- public override byte[] GetPreamble() => Array.Empty();
+ public override byte[] GetPreamble() => [];
[ExcludeFromCodeCoverage]
public override int GetByteCount(char[] chars, int index, int count) =>