JSSoft.Commands
7.0.0
dotnet add package JSSoft.Commands --version 7.0.0
NuGet\Install-Package JSSoft.Commands -Version 7.0.0
<PackageReference Include="JSSoft.Commands" Version="7.0.0" />
paket add JSSoft.Commands --version 7.0.0
#r "nuget: JSSoft.Commands, 7.0.0"
// Install JSSoft.Commands as a Cake Addin #addin nuget:?package=JSSoft.Commands&version=7.0.0 // Install JSSoft.Commands as a Cake Tool #tool nuget:?package=JSSoft.Commands&version=7.0.0
Commands
Summary
Parses a string to set a value to a specified property or invoke a specified method.
Like Terminal or Powershell, it provides a REPL environment to provide a command-based development environment.
Requirements
dotnet sdk 8.0.100 or later
c# 12
Clone
git clone https://github.com/s2quake/commands.git
Build - NET 8.0
dotnet build
Other Framework Build
# net7.0
dotnet build -p:TargetFrameworks=net7.0 --framework net7.0
# netcoreapp3.1
dotnet build -p:TargetFrameworks=netcoreapp3.1 --framework netcoreapp3.1
# netstandard2.1
dotnet build -p:TargetFrameworks=netstandard2.1 --framework netstandard2.1
# net481
dotnet build -p:TargetFrameworks=net481 --framework net481
Run Examples
# Run the property settings example project
dotnet run --project JSSoft.Commands.Parse --framework net8.0 -- --help
# Run the method call example project
dotnet run --project JSSoft.Commands.Invoke --framework net8.0 -- --help
# Run the CommandContext Execution example Project
dotnet run --project JSSoft.Commands.Sets --framework net8.0 -- --help
# Run the CommandContext Execution Example Project in the REPL environment
dotnet run --project JSSoft.Commands.Repl --framework net8.0
# Run the CommandContext Execution Example Project with Avalonia UI
dotnet run --project JSSoft.Commands.AppUI --framework net8.0
Parse
This is the most basic way to parse the command. Provides a function to set a value for a specified property.
var settings = new Settings();
var parser = new CommandParser(settings);
parser.Parse(args);
See the JSSoft.Commands.Parse project
Invoke
As an extension of Parse, it provides the ability to call a specified method by parsing the command.
var commands = new Commands();
var invoker = new CommandInvoker(commands);
invoker.Invoke(args);
See the JSSoft.Commands.Invoke project
CommandContext
It provides various functions to manage and process more commands.
var commands = new ICommand[]
{
new LoginCommand(),
new LogoutCommand(),
new ExitCommand()
};
var commandContext = new CommandContext(commands);
commandContext.Execute(args);
or
await commandContext.ExecuteAsync(args);
See the JSSoft.Commands.Sets project
It can be combined with user input such as EditBox, TextBox, InputText to build a console or REPL-like environment.
var commands = new ICommand[]
{
new LoginCommand(),
new LogoutCommand(),
new ExitCommand()
};
var commandContext = new CommandContext(commands);
var terminal = new SystemTerminal(commandContext);
await terminal.StartAsync(CancellationToken.None);
See the JSSoft.Commands.Repl project
Property
Required argument definition
To define the value required for command syntax, define CommandPropertyRequired in the property.
[CommandPropertyRequired]
public string Value1 { get; set; } = string.Empty;
[CommandPropertyRequired]
public int Value2 { get; set; }
"value" // error! value for Value2 does not exists.
3 // format error!
"value" 3 // Value1 is "value", Value2 is 3
You can set default values like this: If there is no value in the command syntax, it is replaced with the default value.
[CommandPropertyRequired]
public string Value1 { get; set; } = string.Empty;
[CommandPropertyRequired(DefaultValue = 1)]
public int Value2 { get; set; }
"value" 2 // Value1 is "value", Value2 is 2
"value" // Value1 is "value", Value2 is 1
Explicit required argument definition
An explicit required argument indicates that the command syntax must have a value, but must include a switch statement, such as --value "2".
[CommandPropertyRequired]
public string Value1 { get; set; } = string.Empty;
[CommandPropertyExplicitRequired]
public int Value2 { get; set; }
"value" // error!
"value" 2 // error!
"value" --value2 // error!
"value" --value2 3 // Value1 is "value", Value2 is 3
--value2 3 "value" // Value1 is "value", Value2 is 3
In order to use the default values of explicit required arguments, the command syntax must include a switch statement such as --value.
[CommandPropertyRequired]
public string Value1 { get; set; } = string.Empty;
[CommandPropertyExplicitRequired(DefaultValue = 1)]
public int Value2 { get; set; }
"value" // error!
"value" 2 // error!
"value" --value2 // Value1 is "value", Value2 is 1
"value" --value2 3 // Value1 is "value", Value2 is 3
--value2 3 "value" // Value1 is "value", Value2 is 3
--value2 "value" // error! "value" is not int
Optional argument definition
The optional argument can be set whether or not to use a value using a switch statement.
[CommandProperty]
public string Value { get; set; } = string.Empty;
--value // error
--value text // value is "text"
To use the default, the command syntax must include a switch statement such as --value.
[CommandProperty(DefaultValue = "1")]
public string Value { get; set; } = string.Empty;
--value // value is "1"
--value text // value is "text"
A bool type switch statement that does not use a value should be defined as follows.
[CommandPropertySwitch]
public bool Switch { get; set; }
Variable arguments definition
Variable arguments represent the values of the remaining arguments that were not parsed in the command syntax.
The property type of a variable arguments must be an array and must be defined for only one property.
[CommandPropertyArray]
public string[] Values { get; set; } = Array.Empty<string>();
-- value1 value2 value3 "value4"
Method
Method definition
To execute an attribute method through command syntax, you must define a CommandMethod in the method as follows.
Each parameter of the method is automatically defined as a required argument.
[CommandMethod]
public void Save(string message)
{
}
save "message"
If you want to additionally define optional arguments in the method, you can use CommandMethodProperty and add the name of the property defined as CommandProperty.
[CommandMethod]
[CommandMethodProperty("Value")]
public void Save(string message)
{
}
save "comment"
save "comment" --value text
You can use params as below as a variable arguments.
[CommandMethod]
public void Save(string message, params string[] args)
{
}
save "comment"
save "comment" -- "1" "text" "string"
Enable or Disable Method
Define the properties by prefixing "Can" to the method name as shown below.
public bool Can{MethodName} { get; }
example:
public bool CanSave => true;
Static properties and methods
Properties and methods defined as static can be included in the object and used.
static class GlobalSettings
{
[CommandProperty]
public static string ID { get; set; } = string.Empty;
[CommandProperty]
public static string Password { get; set; }
}
[CommandStaticProperty(typeof(GlobalSettings))]
class Settings
{
}
static class StaticCommand
{
[CommandMethod]
[CommandMethodProperty(nameof(Value))]
public static void List()
{
}
[CommandProperty]
public static int Value { get; set; }
}
[CommandStaticMethod(typeof(StaticCommand))]
class Commands
{
}
Naming
The property and method names defined as CommandProperty and CommandMethod are changed to kebab-case (spinal-case, Train-Case, Lisp-case).
Property name example
Property name | Changed property name |
---|---|
Value | --value |
Message | --message |
IsLocked | --is-locked |
When using a name and a short name
[CommandProperty("custom-value", 'v')]
public string Value { get; set; } = string.Empty;
--custom-value or -v
When using only short names
[CommandProperty('v')]
public string Value { get; set; } = string.Empty;
-v
When using a short name and a default name
[CommandProperty('v', AllowName = true)]
public string Value { get; set; } = string.Empty;
-v or --value
Method name example
Method name | Changed method name |
---|---|
Save | save |
LockTable | lock-table |
You can also set the method name yourself.
[CommandMethod("save")]
public void Save(string message)
{
}
Command
You can define commands in the CommandContext.
class ExitCommand : CommandBase
{
[CommandPropertyRequired(DefaultValue = 0)]
public int ExitCode { get; set; }
protected override void OnExecute()
{
Environment.Exit(ExitCode);
}
}
exit
exit 0
SubCommand
You can define commands that have subcommands in CommandContext.
class UserCommand : CommandMethodBase
{
[CommandMethod]
[CommandMethodProperty(nameof(Message))]
public void Create(string userID)
{
}
[CommandMethod]
public void Delete(string userID)
{
}
[CommandMethod]
public void List()
{
}
[CommandProperty]
public string Message { get; set; }
}
user create "user1"
user create "user1" --message "new user"
user delete "user1"
user list
SubCommand extension
By implementing a partial class, you can add subcommand to the already implemented command.
[PartialCommand]
class UserPartialCommand : CommandMethodBase
{
public UserPartialCommand()
: base("user")
{
}
[CommandMethod]
public void SendMessage(string userID, string message)
{
}
}
SubCommand AsyncMethod
You can use asynchronous methods, as shown in the example below. The parameters CancellationToken and IProgress<ProgressInfo> are optional, but should always be the last declaration.
For more information, see the Choosing the overloads to provide
topic in the TAP.
The name of an asynchronous method is used without the suffix Async.
class UserCommand : CommandMethodBase
{
[CommandMethod]
public Task Invoke1Async()
{
return Task.CompletedTask;
}
[CommandMethod]
public Task Invoke2Async(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
[CommandMethod]
public Task Invoke3Async(IProgress<ProgressInfo> progress)
{
return Task.CompletedTask;
}
[CommandMethod]
public Task Invoke4Async(CancellationToken cancellationToken, IProgress<ProgressInfo> progress)
{
return Task.CompletedTask;
}
}
License
Released under the MIT License.
Copyright (c) 2024 Jeesu Choi
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
7.0.0 | 94 | 11/19/2024 |
7.0.0-pr.45 | 32 | 11/19/2024 |
7.0.0-pr.44 | 30 | 11/19/2024 |
7.0.0-pr.43 | 34 | 11/18/2024 |
7.0.0-pr.42 | 103 | 10/5/2024 |
7.0.0-pr.41 | 42 | 9/23/2024 |
7.0.0-pr.40 | 101 | 9/18/2024 |
7.0.0-pr.39 | 51 | 9/18/2024 |
7.0.0-pr.38 | 49 | 9/18/2024 |
7.0.0-pr.37 | 49 | 9/18/2024 |
7.0.0-pr.36 | 58 | 9/16/2024 |
7.0.0-pr.35 | 51 | 9/16/2024 |
7.0.0-pr.34 | 49 | 9/16/2024 |
7.0.0-pr.33 | 51 | 9/15/2024 |
7.0.0-pr.32 | 51 | 9/14/2024 |
7.0.0-pr.31 | 64 | 9/14/2024 |
7.0.0-pr.30 | 53 | 9/6/2024 |
7.0.0-pr.29 | 44 | 9/6/2024 |
7.0.0-pr.28 | 44 | 9/4/2024 |
7.0.0-pr.27 | 43 | 9/2/2024 |
7.0.0-pr.26 | 50 | 9/1/2024 |
7.0.0-pr.25 | 50 | 8/31/2024 |
7.0.0-pr.24 | 72 | 8/24/2024 |
7.0.0-pr.23 | 74 | 8/22/2024 |
7.0.0-pr.22 | 66 | 8/13/2024 |
7.0.0-pr.21 | 60 | 7/26/2024 |
7.0.0-pr.20 | 56 | 7/25/2024 |
7.0.0-pr.19 | 56 | 7/24/2024 |
7.0.0-pr.18 | 53 | 7/23/2024 |
7.0.0-pr.17 | 49 | 7/23/2024 |
6.0.2-pr.16 | 61 | 7/21/2024 |
6.0.2-pr.15 | 68 | 7/21/2024 |
6.0.2-pr.13 | 59 | 7/5/2024 |
6.0.1 | 496 | 5/31/2024 |
6.0.0 | 115 | 5/29/2024 |