Skip to content

Commit dce1588

Browse files
committed
Feat: Import of old CliArgsParser
1 parent e2e298e commit dce1588

35 files changed

+1582
-34
lines changed

.github/workflows/release.yml

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,6 @@ on:
66
- 'v*.*.*' # Match version tags like v1.0.0
77

88
jobs:
9-
test:
10-
runs-on: ubuntu-latest
11-
12-
steps:
13-
- name: Checkout repository
14-
uses: actions/checkout@v3
15-
16-
- name: Setup .NET
17-
uses: actions/setup-dotnet@v3
18-
with:
19-
dotnet-version: '9.x' # Adjust the version as needed
20-
21-
- name: Install dependencies
22-
run: dotnet restore
23-
24-
- name: Build the solution
25-
run: dotnet build --no-restore
26-
27-
# Ensure that the tests must pass
28-
# The job will fail automatically if any test fails because `dotnet test` exits with a non-zero code
29-
- name: Run tests
30-
run: dotnet test --no-build --verbosity normal
31-
329
publish:
3310

3411
runs-on: ubuntu-latest
@@ -45,13 +22,18 @@ jobs:
4522
dotnet-version: '9.x'
4623

4724
- name: Restore dependencies
48-
run: dotnet restore DependencyInjection.sln
25+
run: dotnet restore CodeOfChaos.CliArgsParser.sln
4926

5027
- name: Build
51-
run: dotnet build DependencyInjection.sln --configuration Release --no-restore
28+
run: dotnet build CodeOfChaos.CliArgsParser.sln --configuration Release --no-restore
29+
30+
- name: Run tests
31+
run: dotnet test --no-build --verbosity normal
5232

5333
- name: Publish to NuGet
5434
env:
5535
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
56-
run: |
57-
dotnet nuget push src/TEMPLATE/bin/Release/*.nupkg --api-key $NUGET_API_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate
36+
run: |
37+
dotnet nuget push src/CodeOfChaos.CliArgsParser.Contracts/bin/Release/*.nupkg --api-key $NUGET_API_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate
38+
dotnet nuget push src/CodeOfChaos.CliArgsParser/bin/Release/*.nupkg --api-key $NUGET_API_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate
39+
dotnet nuget push src/CodeOfChaos.CliArgsParser.Library/bin/Release/*.nupkg --api-key $NUGET_API_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate

CodeOfChaos.CliArgsParser.Library.sln renamed to CodeOfChaos.CliArgsParser.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{AF1A203C
1212
EndProject
1313
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tools.CodeOfChaos.CliArgsParser", "src\Tools.CodeOfChaos.CliArgsParser\Tools.CodeOfChaos.CliArgsParser.csproj", "{ADEADD97-0AFA-4D9E-970B-9FFB932949B3}"
1414
EndProject
15+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeOfChaos.CliArgsParser", "src\CodeOfChaos.CliArgsParser\CodeOfChaos.CliArgsParser.csproj", "{1C9D7DD6-A936-4D08-ADB2-46E32FCB28B9}"
16+
EndProject
17+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeOfChaos.CliArgsParser.Contracts", "src\CodeOfChaos.CliArgsParser.Contracts\CodeOfChaos.CliArgsParser.Contracts.csproj", "{D3A8406F-3E09-47BC-A895-B95C3CBDBC59}"
18+
EndProject
1519
Global
1620
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1721
Debug|Any CPU = Debug|Any CPU
@@ -30,10 +34,20 @@ Global
3034
{ADEADD97-0AFA-4D9E-970B-9FFB932949B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
3135
{ADEADD97-0AFA-4D9E-970B-9FFB932949B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
3236
{ADEADD97-0AFA-4D9E-970B-9FFB932949B3}.Release|Any CPU.Build.0 = Release|Any CPU
37+
{1C9D7DD6-A936-4D08-ADB2-46E32FCB28B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38+
{1C9D7DD6-A936-4D08-ADB2-46E32FCB28B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
39+
{1C9D7DD6-A936-4D08-ADB2-46E32FCB28B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
40+
{1C9D7DD6-A936-4D08-ADB2-46E32FCB28B9}.Release|Any CPU.Build.0 = Release|Any CPU
41+
{D3A8406F-3E09-47BC-A895-B95C3CBDBC59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
42+
{D3A8406F-3E09-47BC-A895-B95C3CBDBC59}.Debug|Any CPU.Build.0 = Debug|Any CPU
43+
{D3A8406F-3E09-47BC-A895-B95C3CBDBC59}.Release|Any CPU.ActiveCfg = Release|Any CPU
44+
{D3A8406F-3E09-47BC-A895-B95C3CBDBC59}.Release|Any CPU.Build.0 = Release|Any CPU
3345
EndGlobalSection
3446
GlobalSection(NestedProjects) = preSolution
3547
{26284571-0E09-4BAF-8C2B-DF87DCC1BA0B} = {8DD280D4-1E14-4D5E-AFE6-58DD8F079DCC}
3648
{64B26DED-68C3-47FF-B409-1C8FAD4F9176} = {197E72AD-DEAB-4350-AFC3-A3BB38720BF5}
3749
{ADEADD97-0AFA-4D9E-970B-9FFB932949B3} = {AF1A203C-6EF1-440E-BB3C-55B1DBFE9C19}
50+
{1C9D7DD6-A936-4D08-ADB2-46E32FCB28B9} = {197E72AD-DEAB-4350-AFC3-A3BB38720BF5}
51+
{D3A8406F-3E09-47BC-A895-B95C3CBDBC59} = {197E72AD-DEAB-4350-AFC3-A3BB38720BF5}
3852
EndGlobalSection
3953
EndGlobal

README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# CliArgsParser
2+
![NuGet Downloads](https://img.shields.io/nuget/dt/CliArgsParser)
3+
![NuGet Version](https://img.shields.io/nuget/v/CliArgsParser?link=https%3A%2F%2Fwww.nuget.org%2Fpackages%2FCliArgsParser)
4+
5+
CliArgsParser is a library built around Dependency Injection to allow you to create Cli tools with ease.
6+
This is particularly useful in scenarios where your application requires a large amount of commands,
7+
with specific arguments.
8+
9+
```shell
10+
dotnet add package CliArgsParser --version 2.2.7
11+
```
12+
13+
## Features
14+
Here are the key features of Cli Args Parser:
15+
- **Command Declaration and Registration**: Commands are declaratively defined within a class using the `ICommandAtlas` interface.
16+
This arrangement provides a well-structured, easy-to-maintain way of defining and locating command handling logic.
17+
- **Asynchronous Command Execution**: CliArgsParser allows for asynchronous execution of commands.
18+
This can provide major performance benefits, especially when commands involve IO-bound operations.
19+
The library also exposes the `ArgsParser.ParseAsyncParallel` method for parallel async execution of cli tools.
20+
- **Argument Mapping**: CliArgsParser allows property-based argument mapping.
21+
Properties of a class implementing the ICommandParameters interface can be used as the target of argument mapping from command line input.
22+
Argument mapping is further simplified through the use of the `ArgValue` and `ArgFlag` attributes which takes the argument name as a parameter.
23+
- **Dependency Injection approach**: The library is built around using DI in your workflow. `ICommandAtlas` classes allow constructors to fully utilize dependency injection.
24+
Yet you are not required to have a `IServiceCollection`, by using the `CliParser.CreateStandalone()` or `ArgsParser.CreateStandalone()` methods.
25+
26+
## F.A.Q:
27+
28+
> **"I tried to create a atlas with async commands, but they did not execute when called"**
29+
>
30+
> This is due to the parser trying to execute the commands as non-async, because the parser was most likely called without using the async methods.
31+
> To resolve this, always run the parsers through their async methods.
32+
33+
## Quick Start
34+
The following section is a basic example on how to get started with CliArgsParser.
35+
For in-code examples, they can be found in the repo under examples : https://github.com/code-of-chaos/CliArgsParser-cs/tree/core/examples
36+
37+
### Dependency Injected approach
38+
```csharp
39+
using CliArgsParser;
40+
41+
// Define a class for mapping arguments
42+
public class ArgsTest : ICommandParameters {
43+
[ArgValue("name"), Description("Defines the name of the user")]
44+
public string Name { get; set; } = "Default Name";
45+
}
46+
47+
public class MyAppCommands : ICommandAtlas {
48+
[Command("hello"), Description("Greets everyone")]
49+
public void CommandHello() {
50+
Console.Writeline("Hello there!");
51+
/* Or your command' implementation, without arguments, goes here... */
52+
}
53+
54+
[Command<ArgsTest>("greet"), Description("Greets you specificly")]
55+
public void CommandGreet(ArgsTest argsTest) {
56+
Console.Writeline($"Hello there and welcome, {argsTest.Name}");
57+
/* Or Your command implementation goes here... */
58+
}
59+
}
60+
61+
internal static class Program {
62+
public async static Task Main(string[] args) {
63+
IServiceCollection serviceCollection = new ServiceCollection();
64+
65+
serviceCollection.AddCliArgsParser(configuration =>
66+
configuration
67+
.SetConfig(new CliArgsParserConfig {
68+
Overridable = true,
69+
GenerateShortNames = true
70+
})
71+
.AddFromType<HelloAtlas>()
72+
);
73+
74+
ServiceProvider provider = serviceCollection.BuildServiceProvider();
75+
76+
var cliParser = provider.GetRequiredService<ICliParser>();
77+
await cliParser.StartParsingAsync();
78+
}
79+
}
80+
```
81+
82+
### Standalone Approach
83+
```csharp
84+
using CliArgsParser;
85+
86+
// Define a class for mapping arguments
87+
public class ArgsTest : ICommandParameters {
88+
[ArgValue("name"), Description("Defines the name of the user")]
89+
public string Name { get; set; } = "Default Name";
90+
}
91+
92+
public class MyAppCommands : ICommandAtlas {
93+
[Command("hello"), Description("Greets everyone")]
94+
public void CommandHello() {
95+
Console.Writeline("Hello there!");
96+
/* Or your command' implementation, without arguments, goes here... */
97+
}
98+
99+
[Command<ArgsTest>("greet"), Description("Greets you specificly")]
100+
public void CommandGreet(ArgsTest argsTest) {
101+
Console.Writeline($"Hello there and welcome, {argsTest.Name}");
102+
/* Or Your command implementation goes here... */
103+
}
104+
}
105+
106+
internal static class Program {
107+
public async static Task Main(string[] args) {
108+
ICliParser parser = CliParser.CreateStandalone(
109+
configuration =>
110+
configuration
111+
.SetConfig(new CliArgsParserConfig {
112+
Overridable = true,
113+
GenerateShortNames = true
114+
})
115+
.AddFromType<HelloAtlas>()
116+
);
117+
await cliParser.StartParsingAsync();
118+
}
119+
}
120+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// ---------------------------------------------------------------------------------------------------------------------
2+
// Imports
3+
// ---------------------------------------------------------------------------------------------------------------------
4+
// ReSharper disable CheckNamespace
5+
namespace CliArgsParser;
6+
// ReSharper restore CheckNamespace
7+
8+
// ---------------------------------------------------------------------------------------------------------------------
9+
// Code
10+
// ---------------------------------------------------------------------------------------------------------------------
11+
/// <summary>
12+
/// When used as an attribute on a property in a <see cref="ICommandParameters"/> class,
13+
/// defines a command argument as a boolean flag.
14+
/// </summary>
15+
[AttributeUsage(AttributeTargets.Property)]
16+
public class ArgFlagAttribute(string name, string? shortName = null) : Attribute, IAttributeWithName {
17+
/// <inheritdoc cref="IAttributeWithName.Name"/>
18+
public string Name { get; } = name;
19+
20+
/// <inheritdoc cref="IAttributeWithName.ShortName"/>
21+
public string? ShortName { get; } = shortName;
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// ---------------------------------------------------------------------------------------------------------------------
2+
// Imports
3+
// ---------------------------------------------------------------------------------------------------------------------
4+
// ReSharper disable CheckNamespace
5+
namespace CliArgsParser;
6+
// ReSharper restore CheckNamespace
7+
8+
// ---------------------------------------------------------------------------------------------------------------------
9+
// Code
10+
// ---------------------------------------------------------------------------------------------------------------------
11+
/// <summary>
12+
/// When used as an attribute on a property in a <see cref="ICommandParameters"/> class,
13+
/// defines a command argument as a string value.
14+
/// </summary>
15+
[AttributeUsage(AttributeTargets.Property)]
16+
public class ArgValueAttribute(string name, string? shortName = null) : Attribute, IAttributeWithName {
17+
/// <inheritdoc cref="IAttributeWithName.Name"/>
18+
public string Name { get; } = name;
19+
20+
/// <inheritdoc cref="IAttributeWithName.ShortName"/>
21+
public string? ShortName { get; } = shortName;
22+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// ---------------------------------------------------------------------------------------------------------------------
2+
// Imports
3+
// ---------------------------------------------------------------------------------------------------------------------
4+
// ReSharper disable CheckNamespace
5+
namespace CliArgsParser;
6+
// ReSharper restore CheckNamespace
7+
8+
// ---------------------------------------------------------------------------------------------------------------------
9+
// Code
10+
// ---------------------------------------------------------------------------------------------------------------------
11+
/// <summary>
12+
/// Represents an attribute that marks a method as a command.
13+
/// </summary>
14+
[AttributeUsage(AttributeTargets.Method)]
15+
public class CommandAttribute(string? name = null, Type? argsType = null) : Attribute {
16+
/// <summary>
17+
/// Represents a command attribute that can be applied to a method.
18+
/// </summary>
19+
public string? Name { get; } = name;
20+
21+
/// <summary>
22+
/// Represents the type of the arguments for a command.
23+
/// </summary>
24+
public Type ArgsType { get; } = argsType ?? typeof(NoArgs);
25+
}
26+
27+
/// <summary>
28+
/// Represents an attribute that marks a method as a command.
29+
/// </summary>
30+
[AttributeUsage(AttributeTargets.Method)]
31+
public class CommandAttribute<T>(string? name = null) : CommandAttribute(name, typeof(T)) where T : ICommandParameters, new();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// ---------------------------------------------------------------------------------------------------------------------
2+
// Imports
3+
// ---------------------------------------------------------------------------------------------------------------------
4+
// ReSharper disable CheckNamespace
5+
namespace CliArgsParser;
6+
// ReSharper restore CheckNamespace
7+
8+
// ---------------------------------------------------------------------------------------------------------------------
9+
// Code
10+
// ---------------------------------------------------------------------------------------------------------------------
11+
/// <summary>
12+
/// When used as an attribute on a property in a <see cref="ICommandParameters"/> class or on a Command method on a <see cref="ICommandAtlas"/>,
13+
/// defines the description to that CLI element. Commonly used by the <c>help</c> command to display helpfull information.
14+
/// </summary>
15+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
16+
public class DescriptionAttribute(string description) : Attribute {
17+
/// <summary>
18+
/// The description string.
19+
/// </summary>
20+
public string Description { get; } = description;
21+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// ---------------------------------------------------------------------------------------------------------------------
2+
// Imports
3+
// ---------------------------------------------------------------------------------------------------------------------
4+
// ReSharper disable CheckNamespace
5+
namespace CliArgsParser;
6+
// ReSharper restore CheckNamespace
7+
8+
// ---------------------------------------------------------------------------------------------------------------------
9+
// Code
10+
// ---------------------------------------------------------------------------------------------------------------------
11+
/// <summary>
12+
/// All properties defined in a <see cref="ICommandParameters"/> class should have attributes which derive from this interface.
13+
/// Used for name assignment of an argument of a command.
14+
/// </summary>
15+
public interface IAttributeWithName {
16+
/// <summary>
17+
/// Sets the name of the command argument
18+
/// </summary>
19+
string Name { get; }
20+
/// <summary>
21+
/// Sets a pre-determined short name (usually a single letter) for the command argument
22+
/// </summary>
23+
string? ShortName { get; }
24+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>true</IsPackable>
9+
<PackageId>CodeOfChaos.CliArgsParser.Contracts</PackageId> <!-- Main package name -->
10+
<Version>2.2.7</Version> <!-- Package version -->
11+
<Authors>Anna Sas</Authors>
12+
<Description>CliArgsParser is a library built around Dependency Injection to allow you to create CLI tools with ease</Description>
13+
<PackageProjectUrl>https://github.com/code-of-chaos/cs-code_of_chaos-cli_args_parser/</PackageProjectUrl>
14+
<PackageTags>cli args cliparser input argsparser</PackageTags>
15+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
16+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
17+
<IncludeSymbols>true</IncludeSymbols>
18+
<DebugType>embedded</DebugType>
19+
<PackageLicenseFile>LICENSE</PackageLicenseFile>
20+
<PackageReadmeFile>README.md</PackageReadmeFile>
21+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
22+
</PropertyGroup>
23+
24+
<ItemGroup>
25+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
26+
</ItemGroup>
27+
28+
</Project>

0 commit comments

Comments
 (0)