mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
asd
This commit is contained in:
@@ -4,33 +4,25 @@ namespace CliFx.Attributes;
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Annotates a type that defines a command.
|
/// 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Only one default command is allowed per application.
|
||||||
|
/// All commands registered in an application must have unique names (comparison IS NOT case-sensitive).
|
||||||
|
/// </remarks>
|
||||||
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||||
public class CommandAttribute : Attribute
|
public class CommandAttribute(string? name = null) : Attribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Initializes an instance of <see cref="CommandAttribute" />.
|
|
||||||
/// </summary>
|
|
||||||
public CommandAttribute(string name) => Name = name;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes an instance of <see cref="CommandAttribute" />.
|
|
||||||
/// </summary>
|
|
||||||
public CommandAttribute() { }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command name.
|
/// Command name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
public string? Name { get; } = 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).
|
|
||||||
/// </remarks>
|
|
||||||
public string? Name { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Command description.
|
/// Command description.
|
||||||
/// This is shown to the user in the help text.
|
/// This is shown to the user in the help text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
namespace CliFx.Attributes;
|
namespace CliFx.Attributes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Annotates a property that defines the help option for a command.
|
/// Binds a property to the help option of a command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This attribute is applied automatically by the framework and should not be used explicitly.
|
||||||
|
/// </remarks>
|
||||||
public class CommandHelpOptionAttribute : CommandOptionAttribute
|
public class CommandHelpOptionAttribute : CommandOptionAttribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
34
CliFx/Attributes/CommandInputAttribute.cs
Normal file
34
CliFx/Attributes/CommandInputAttribute.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using CliFx.Extensibility;
|
||||||
|
|
||||||
|
namespace CliFx.Attributes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Binds a property to a command-line input.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public abstract class CommandInputAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Input description, as shown in the help text.
|
||||||
|
/// </summary>
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Custom converter used for mapping the raw command-line argument into
|
||||||
|
/// the type and shape expected by the underlying property.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Converter must derive from <see cref="BindingConverter{T}" />.
|
||||||
|
/// </remarks>
|
||||||
|
public Type? Converter { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Custom validators used for verifying the value of the underlying
|
||||||
|
/// property, after it has been set.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Validators must derive from <see cref="BindingValidator{T}" />.
|
||||||
|
/// </remarks>
|
||||||
|
public Type[] Validators { get; set; } = [];
|
||||||
|
}
|
||||||
@@ -4,10 +4,13 @@ using CliFx.Extensibility;
|
|||||||
namespace CliFx.Attributes;
|
namespace CliFx.Attributes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// All options in a command must have unique names (comparison IS NOT case-sensitive) and short names (comparison IS case-sensitive).
|
||||||
|
/// </remarks>
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
public class CommandOptionAttribute : Attribute
|
public class CommandOptionAttribute : CommandInputAttribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes an instance of <see cref="CommandOptionAttribute" />.
|
/// Initializes an instance of <see cref="CommandOptionAttribute" />.
|
||||||
@@ -39,20 +42,11 @@ public class CommandOptionAttribute : Attribute
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Option name.
|
/// Option name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// Must contain at least two characters and start with a letter.
|
|
||||||
/// Either <see cref="Name" /> or <see cref="ShortName" /> must be set.
|
|
||||||
/// All options in a command must have unique names (comparison IS NOT case-sensitive).
|
|
||||||
/// </remarks>
|
|
||||||
public string? Name { get; }
|
public string? Name { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Option short name.
|
/// Option short name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// Either <see cref="Name" /> or <see cref="ShortName" /> must be set.
|
|
||||||
/// All options in a command must have unique short names (comparison IS case-sensitive).
|
|
||||||
/// </remarks>
|
|
||||||
public char? ShortName { get; }
|
public char? ShortName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -70,28 +64,4 @@ public class CommandOptionAttribute : Attribute
|
|||||||
/// has not been explicitly set through command-line arguments.
|
/// has not been explicitly set through command-line arguments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? EnvironmentVariable { get; set; }
|
public string? EnvironmentVariable { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Option description.
|
|
||||||
/// This is shown to the user in the help text.
|
|
||||||
/// </summary>
|
|
||||||
public string? Description { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Custom converter used for mapping the raw command-line argument into
|
|
||||||
/// a value expected by the underlying property.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Converter must derive from <see cref="BindingConverter{T}" />.
|
|
||||||
/// </remarks>
|
|
||||||
public Type? Converter { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Custom validators used for verifying the value of the underlying
|
|
||||||
/// property, after it has been bound.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Validators must derive from <see cref="BindingValidator{T}" />.
|
|
||||||
/// </remarks>
|
|
||||||
public Type[] Validators { get; set; } = Array.Empty<Type>();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,21 +5,21 @@ using CliFx.Extensibility;
|
|||||||
namespace CliFx.Attributes;
|
namespace CliFx.Attributes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// 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, <see cref="List{T}" />; except <see cref="string" />),
|
||||||
|
/// then it must have the highest order in the command.
|
||||||
|
/// Only one sequential parameter is allowed per command.
|
||||||
|
/// </remarks>
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
public class CommandParameterAttribute(int order) : Attribute
|
public class CommandParameterAttribute(int order) : CommandInputAttribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parameter order.
|
/// Parameter order.
|
||||||
/// Higher order means the parameter appears later, lower order means it appears earlier.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// All parameters in a command must have unique order.
|
|
||||||
/// Parameter whose type is a sequence (e.g. Array, <see cref="List{T}" />; except <see cref="string" />),
|
|
||||||
/// must always be the last parameter based on order.
|
|
||||||
/// Only one sequential parameter is allowed in a command.
|
|
||||||
/// </remarks>
|
|
||||||
public int Order { get; } = order;
|
public int Order { get; } = order;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -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.
|
/// If a parameter is required, the user will get an error if they don't set it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Parameter marked as non-required must always be the last in order.
|
/// Parameter marked as non-required must have the highest order in the command.
|
||||||
/// Only one non-required parameter is allowed in a command.
|
/// Only one non-required parameter is allowed per command.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public bool IsRequired { get; set; } = true;
|
public bool IsRequired { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parameter name.
|
/// Parameter name, as shown in the help text.
|
||||||
/// This is shown to the user in the help text.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// If this isn't specified, parameter name is inferred from the property name.
|
/// If this isn't specified, parameter name is inferred from the property name.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Parameter description.
|
|
||||||
/// This is shown to the user in the help text.
|
|
||||||
/// </summary>
|
|
||||||
public string? Description { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Custom converter used for mapping the raw command-line argument into
|
|
||||||
/// a value expected by the underlying property.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Converter must derive from <see cref="BindingConverter{T}" />.
|
|
||||||
/// </remarks>
|
|
||||||
public Type? Converter { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Custom validators used for verifying the value of the underlying
|
|
||||||
/// property, after it has been bound.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Validators must derive from <see cref="BindingValidator{T}" />.
|
|
||||||
/// </remarks>
|
|
||||||
public Type[] Validators { get; set; } = Array.Empty<Type>();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
namespace CliFx.Attributes;
|
namespace CliFx.Attributes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Annotates a property that defines the version option for a command.
|
/// Binds a property to the version option of a command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This attribute is applied automatically by the framework and should not be used explicitly.
|
||||||
|
/// </remarks>
|
||||||
public class CommandVersionOptionAttribute : CommandOptionAttribute
|
public class CommandVersionOptionAttribute : CommandOptionAttribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace CliFx.Schema;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class InputSchema(
|
public abstract class InputSchema(
|
||||||
PropertyBinding property,
|
PropertyBinding property,
|
||||||
|
string? description,
|
||||||
IBindingConverter converter,
|
IBindingConverter converter,
|
||||||
IReadOnlyList<IBindingValidator> validators
|
IReadOnlyList<IBindingValidator> validators
|
||||||
)
|
)
|
||||||
@@ -22,6 +23,11 @@ public abstract class InputSchema(
|
|||||||
property.Type != typeof(string)
|
property.Type != typeof(string)
|
||||||
&& property.Type.TryGetEnumerableUnderlyingType() is not null;
|
&& property.Type.TryGetEnumerableUnderlyingType() is not null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Input description, used in the help text.
|
||||||
|
/// </summary>
|
||||||
|
public string? Description { get; } = description;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CLR property to which this input is bound.
|
/// CLR property to which this input is bound.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -119,7 +125,8 @@ public abstract class InputSchema<
|
|||||||
TProperty
|
TProperty
|
||||||
>(
|
>(
|
||||||
PropertyBinding<TCommand, TProperty> property,
|
PropertyBinding<TCommand, TProperty> property,
|
||||||
|
string? description,
|
||||||
BindingConverter<TProperty> converter,
|
BindingConverter<TProperty> converter,
|
||||||
IReadOnlyList<BindingValidator<TProperty>> validators
|
IReadOnlyList<BindingValidator<TProperty>> validators
|
||||||
) : InputSchema(property, converter, validators)
|
) : InputSchema(property, description, converter, validators)
|
||||||
where TCommand : ICommand;
|
where TCommand : ICommand;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class OptionSchema(
|
|||||||
string? description,
|
string? description,
|
||||||
IBindingConverter converter,
|
IBindingConverter converter,
|
||||||
IReadOnlyList<IBindingValidator> validators
|
IReadOnlyList<IBindingValidator> validators
|
||||||
) : InputSchema(property, converter, validators)
|
) : InputSchema(property,description, converter, validators)
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Option name.
|
/// Option name.
|
||||||
@@ -40,11 +40,6 @@ public class OptionSchema(
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsRequired { get; } = isRequired;
|
public bool IsRequired { get; } = isRequired;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Option description.
|
|
||||||
/// </summary>
|
|
||||||
public string? Description { get; } = description;
|
|
||||||
|
|
||||||
internal bool MatchesName(string? name) =>
|
internal bool MatchesName(string? name) =>
|
||||||
!string.IsNullOrWhiteSpace(Name)
|
!string.IsNullOrWhiteSpace(Name)
|
||||||
&& string.Equals(Name, name, StringComparison.OrdinalIgnoreCase);
|
&& string.Equals(Name, name, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class ParameterSchema(
|
|||||||
string? description,
|
string? description,
|
||||||
IBindingConverter converter,
|
IBindingConverter converter,
|
||||||
IReadOnlyList<IBindingValidator> validators
|
IReadOnlyList<IBindingValidator> validators
|
||||||
) : InputSchema(property, converter, validators)
|
) : InputSchema(property, description, converter, validators)
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Order, in which the parameter is bound from the command-line arguments.
|
/// Order, in which the parameter is bound from the command-line arguments.
|
||||||
@@ -32,11 +32,6 @@ public class ParameterSchema(
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsRequired { get; } = isRequired;
|
public bool IsRequired { get; } = isRequired;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Parameter description.
|
|
||||||
/// </summary>
|
|
||||||
public string? Description { get; } = description;
|
|
||||||
|
|
||||||
internal override string GetKind() => "Parameter";
|
internal override string GetKind() => "Parameter";
|
||||||
|
|
||||||
internal override string GetFormattedIdentifier() => IsSequence ? $"<{Name}>" : $"<{Name}...>";
|
internal override string GetFormattedIdentifier() => IsSequence ? $"<{Name}>" : $"<{Name}...>";
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ internal class NoPreambleEncoding(Encoding underlyingEncoding)
|
|||||||
public override bool IsMailNewsSave => underlyingEncoding.IsMailNewsSave;
|
public override bool IsMailNewsSave => underlyingEncoding.IsMailNewsSave;
|
||||||
|
|
||||||
// This is the only part that changes
|
// This is the only part that changes
|
||||||
public override byte[] GetPreamble() => Array.Empty<byte>();
|
public override byte[] GetPreamble() => [];
|
||||||
|
|
||||||
[ExcludeFromCodeCoverage]
|
[ExcludeFromCodeCoverage]
|
||||||
public override int GetByteCount(char[] chars, int index, int count) =>
|
public override int GetByteCount(char[] chars, int index, int count) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user