8000 Add ServiceProvider to CommandSettings by s2quake · Pull Request #49 · s2quake/commands · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add ServiceProvider to CommandSettings #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
8000
Diff view
Diff view
11 changes: 7 additions & 4 deletions CHANGES.md
8000
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ Commands changes
To be Released.

* Renamed method `GetCompletion` to `GetCompletions`. [[#47]]
* Added a `ServiceProvider` property to the `CommandSettings` [[#49]]

[#47]: https://github.com/s2quake/commands/pull/47
[#49]: https://github.com/s2quake/commands/pull/49



7.0.0
Expand All @@ -33,12 +36,12 @@ Released on November 19, 2024.
* Added the `CommandPropertyExclusionAttribute`. [[#31]]
* Added a `Category` property to the `CommandMemberDescriptor`. [[#33]]
* Simplified the process of getting strings from `ResourceManager`. [[#34]]
* Removed `ICommandUsage`, `CommandUsageDescriptorBase`,
* Removed `ICommandUsage`, `CommandUsageDescriptorBase`,
`ResourceUsageDescriptor`. [[#34]]
* Fixed an issue with the display order of options and commands in Help.
* Fixed an issue with the display order of options and commands in Help.
[[#37]]
* Removed commands sorting code in `CommandContextBase`. [[#38]]
* Integrated usage-related properties(`Summary`, `Description`, `Example`) into
* Integrated usage-related properties(`Summary`, `Description`, `Example`) into
the `CommandUsage` property. [[#40]]
* Added `StepProgress` to make it easier to work with progress. [[#41]]
* Added `RunAsync` and `StopAsync` methods to `SystemTerminalBase`. [[#42]]
Expand Down Expand Up @@ -71,7 +74,7 @@ Released on November 19, 2024.

Released on May 31, 2024.

* Fixed an issue where an exception was thrown when multiple
* Fixed an issue where an exception was thrown when multiple
commands using `PartialCommandAttribute` were inside an assembly. [[#8]]

[#8]: https://github.com/s2quake/commands/pull/8
Expand Down
14 changes: 8 additions & 6 deletions src/JSSoft.Commands/CommandContextBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ public string[] GetCompletions(string[] items, string find)
{
var completionList = new List<string>(items.Length);
var itemList = new List<string>(items);
var completions = GetCompletions(_commandNode, itemList);
var settings = Settings;
var completions = GetCompletions(_commandNode, itemList, settings);
for (var i = 0; i < completions.Length; i++)
{
var completion = completions[i];
Expand Down Expand Up @@ -339,7 +340,7 @@ private static void AttachContext(ICommand command, ICommandContext commandConte
}

private static string[] GetCompletions(
ICommand parent, IList<string> itemList)
ICommand parent, IList<string> itemList, CommandSettings settings)
{
if (itemList.Count is 0)
{
10000 Expand All @@ -357,12 +358,12 @@ where child.IsEnabled is true
if (command.IsEnabled is true && command.Commands.Count > 0)
{
itemList.RemoveAt(0);
return GetCompletions(command, itemList);
return GetCompletions(command, itemList, settings);
}
else
{
var args = itemList.Skip(1).ToArray();
if (GetCompletions(command, args) is string[] completions)
if (GetCompletions(command, args, settings) is string[] completions)
{
return completions;
}
Expand All @@ -373,10 +374,11 @@ where child.IsEnabled is true
}
}

private static string[] GetCompletions(ICommand command, string[] args)
private static string[] GetCompletions(
ICommand command, string[] args, CommandSettings settings)
{
var memberDescriptors = CommandDescriptor.GetMemberDescriptors(command);
var parseContext = ParseContext.Create(memberDescriptors, args);
var parseContext = ParseContext.Create(memberDescriptors, args, settings);
if (parseContext.Descriptor is { } descriptor)
{
var properties = parseContext.GetProperties();
Expand Down
6 changes: 3 additions & 3 deletions src/JSSoft.Commands/CommandInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ private void Invoke(CommandMethodDescriptor methodDescriptor, string[] args)
var instance = Instance;
var memberDescriptors = methodDescriptor.Members;
var settings = Settings;
var parseContext = ParseContext.Create(memberDescriptors, args);
var parseContext = ParseContext.Create(memberDescriptors, args, settings);
var methodInstance = new CommandMethodInstance(methodDescriptor, instance);
parseContext.SetValue(methodInstance, settings);
methodDescriptor.Invoke(instance, methodInstance);
Expand All @@ -190,7 +190,7 @@ private Task InvokeAsync(
var instance = Instance;
var memberDescriptors = methodDescriptor.Members;
var settings = Settings;
var parseContext = ParseContext.Create(memberDescriptors, args);
var parseContext = ParseContext.Create(memberDescriptors, args, settings);
var methodInstance = new CommandMethodInstance(methodDescriptor, instance);
parseContext.SetValue(methodInstance, settings);
return methodDescriptor.InvokeAsync(
Expand All @@ -202,7 +202,7 @@ private void Parse(string[] args)
var instance = Instance;
var memberDescriptors = CommandDescriptor.GetMemberDescriptors(instance);
var settings = Settings;
var parserContext = ParseContext.Create(memberDescriptors, args);
var parserContext = ParseContext.Create(memberDescriptors, args, settings);
parserContext.SetValue(instance, settings);
}
}
133 changes: 133 additions & 0 deletions src/JSSoft.Commands/CommandParentBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// <copyright file="CommandParentBase.cs" company="JSSoft">
// Copyright (c) 2024 Jeesu Choi. All Rights Reserved.
// Licensed under the MIT License. See LICENSE.md in the project root for license information.
// </copyright>

using System.IO;
using JSSoft.Commands.Extensions;

namespace JSSoft.Commands;

public abstract class CommandParentBase : ICommand
{
private readonly CommandUsage _usage;
private readonly CommandCollection _commands = [];
private ICommandContext? _context;

protected CommandParentBase()
: this(parent: null!, name: string.Empty, aliases: [])
{
}

protected CommandParentBase(string[] aliases)
: this(parent: null!, name: string.Empty, aliases)
{
}

protected CommandParentBase(string name)
: this(parent: null!, name, aliases: [])
{
}

protected CommandParentBase(string name, string[] aliases)
: this(parent: null!, name, aliases)
{
}

protected CommandParentBase(ICommand parent)
: this(parent, name: string.Empty, aliases: [])
{
}

protected CommandParentBase(ICommand parent, string[] aliases)
: this(parent, name: string.Empty, aliases)
{
}

protected CommandParentBase(ICommand parent, string name)
: this(parent, name, aliases: [])
{
}

protected CommandParentBase(ICommand parent, string name, string[] aliases)
{
Name = name == string.Empty ? CommandUtility.ToSpinalCase(GetType()) : name;
Aliases = aliases;
_usage = CommandDescriptor.GetUsage(GetType());
ICommandExtensions.SetParent(this, parent);
}

public string Name { get; }

public string[] Aliases { get; }

public virtual bool IsEnabled => true;

bool ICommand.AllowsSubCommands => true;

public TextWriter Out => Context.Out;

public TextWriter Error => Context.Error;

public ICommandContext Context
=> _context ?? throw new InvalidOperationException("The command node is not available.");

ICommand? ICommand.Parent { get; set; }

CommandCollection ICommand.Commands => _commands;

[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Minor Code Smell",
"S2292:Trivial properties should be auto-implemented",
Justification = "This property does not need to be public.")]
ICommandContext? ICommand.Context
{
get => _context;
set => _context = value;
}

CommandUsage ICommand.Usage => _usage;

string ICommand.Category => AttributeUtility.GetCategory(GetType());

internal string ExecutionName
{
get
{
var executionName = CommandUtility.GetExecutionName(Name, Aliases);
if (Context.ExecutionName != string.Empty)
{
return $"{Context.ExecutionName} {executionName}";
}

return executionName;
}
}

string ICommand.GetUsage(bool isDetail) => OnUsagePrint(isDetail);

string[] ICommand.GetCompletions(CommandCompletionContext completionContext)
=> GetCompletions(completionContext);

protected virtual string[] GetCompletions(CommandCompletionContext completionContext)
{
var memberDescriptor = completionContext.MemberDescriptor;
var instance = this;
return memberDescriptor.GetCompletionsInternal(instance);
}

protected CommandMemberDescriptor GetDescriptor(string propertyName)
=> CommandDescriptor.GetMemberDescriptors(GetType())[propertyName];

protected virtual string OnUsagePrint(bool isDetail)
{
var settings = Context.Settings;
var usagePrinter = new CommandUsagePrinter(this, settings)
{
IsDetail = isDetail,
};
using var sw = new StringWriter();
usagePrinter.Print(sw);
return sw.ToString();
}
}
2 changes: 1 addition & 1 deletion src/JSSoft.Commands/CommandParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void Parse(string[] args)
var instance = Instance;
var memberDescriptors = CommandDescriptor.GetMemberDescriptors(instance);
var settings = Settings;
var parserContext = ParseContext.Create(memberDescriptors, args);
var parserContext = ParseContext.Create(memberDescriptors, args, settings);
parserContext.SetValue(instance, settings);
}

Expand Down
9 changes: 9 additions & 0 deletions src/JSSoft.Commands/CommandSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using JSSoft.Commands.Extensions;
using static JSSoft.Commands.CommandUtility;

Expand Down Expand Up @@ -87,6 +88,10 @@ public int IndentSpaces

public Predicate<string> CategoryPredicate { get; init; } = DefaultCategoryPredicate;

public IServiceProvider? ServiceProvider { get; init; }

public CultureInfo? CultureInfo { get; init; }

internal static TimeSpan AsyncTimeout { get; } = TimeSpan.FromSeconds(1);

internal static BindingFlags GetBindingFlags(Type type)
Expand Down Expand Up @@ -176,4 +181,8 @@ internal bool ContainsVersionOption(string[] args)

internal string GetLabelString(string label)
=> GetLabelString(label, LabelWidth, IndentSpaces);

internal ITypeDescriptorContext? CreateTypeDescriptorContext()
=> ServiceProvider is not null
? new TypeDescriptorContext(ServiceProvider) : null;
}
16 changes: 9 additions & 7 deletions src/JSSoft.Commands/ParseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ public ParseContext(CommandMemberDescriptorCollection memberDescriptors)
public ParseDescriptor? Descriptor { get; private set; }

public static ParseContext Create(
CommandMemberDescriptorCollection memberDescriptors, string[] args)
CommandMemberDescriptorCollection memberDescriptors,
string[] args,
CommandSettings settings)
{
try
{
var parseContext = new ParseContext(memberDescriptors);
parseContext.Next(args);
parseContext.Next(args, settings);
return parseContext;
}
catch (Exception e)
Expand All @@ -43,11 +45,11 @@ public static ParseContext Create(
}
}

public void Next(params string[] args)
public void Next(string[] args, CommandSettings settings)
{
foreach (var arg in args)
{
Next(arg);
Next(arg, settings);
}
}

Expand Down Expand Up @@ -157,7 +159,7 @@ private static void ThrowIfInvalidValue(ParseDescriptorCollection parseDescripto
return _variablesDescriptor;
}

private void Next(string arg)
private void Next(string arg, CommandSettings settings)
{
if (_memberDescriptors.FindByOptionName(arg) is { } memberDescriptor)
{
Expand Down Expand Up @@ -239,11 +241,11 @@ private void Next(string arg)
if (descriptor == _variablesDescriptor)
{
_variableList.Add(arg);
descriptor.SetVariablesValue([.. _variableList]);
descriptor.SetVariablesValue([.. _variableList], settings);
}
else
{
descriptor.SetValue(arg);
descriptor.SetValue(arg, settings);
Descriptor = FindNextDescriptor(descriptor);
}
}
Expand Down
Loading
Loading
0