Compare commits

...

3 Commits

Author SHA1 Message Date
c77b3e0742 LaunchArgumentParser.UnknownArguments 2025-04-26 05:29:30 +05:00
e391f0238a DTLib v1.7.2 2025-04-26 04:20:40 +05:00
823169ca91 LaunchArgumentParser.HelpMessageHeader 2025-04-26 04:19:14 +05:00
4 changed files with 119 additions and 88 deletions

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<!--package info--> <!--package info-->
<PackageId>DTLib.Logging.Microsoft</PackageId> <PackageId>DTLib.Logging.Microsoft</PackageId>
<Version>1.1.1</Version> <Version>1.1.2</Version>
<Authors>Timerix</Authors> <Authors>Timerix</Authors>
<Description>DTLib logger wrapper with dependency injection</Description> <Description>DTLib logger wrapper with dependency injection</Description>
<RepositoryType>GIT</RepositoryType> <RepositoryType>GIT</RepositoryType>
@ -28,6 +28,6 @@
<ProjectReference Include="..\DTLib\DTLib.csproj" /> <ProjectReference Include="..\DTLib\DTLib.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' "> <ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib" Version="1.6.*" /> <PackageReference Include="DTLib" Version="1.7.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -25,6 +25,6 @@
<ProjectReference Include="..\DTLib\DTLib.csproj" /> <ProjectReference Include="..\DTLib\DTLib.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(Configuration)' != 'Debug' "> <ItemGroup Condition=" '$(Configuration)' != 'Debug' ">
<PackageReference Include="DTLib" Version="1.7.1" /> <PackageReference Include="DTLib" Version="1.7.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -2,71 +2,79 @@ namespace DTLib.Console;
public class LaunchArgumentParser public class LaunchArgumentParser
{ {
public bool IsAllowedNoArguments; public string HelpMessageHeader = "USAGE:";
public bool AllowedNoArguments;
public bool AllowedUnknownArguments;
// ReSharper disable once CollectionNeverQueried.Global
public readonly List<string> UnknownArguments = new();
private readonly Dictionary<string, LaunchArgument> argDict = new(); private readonly Dictionary<string, LaunchArgument> argDict = new();
private readonly List<LaunchArgument> argList = new(); private readonly List<LaunchArgument> argList = new();
public class ExitAfterHelpException : Exception
{
internal ExitAfterHelpException() : base("your program can use this exception to exit after displaying help message")
{ }
}
public string CreateHelpMessage()
{
StringBuilder b = new();
foreach (var arg in argList)
arg.AppendHelpInfo(b).Append('\n');
b.Remove(b.Length-1, 1);
return b.ToString();
}
public string CreateHelpArgMessage(string argAlias)
{
StringBuilder b = new();
var arg = Parse(argAlias);
arg.AppendHelpInfo(b);
return b.ToString();
}
private void HelpHandler()
{
System.Console.WriteLine(CreateHelpMessage());
throw new ExitAfterHelpException();
}
private void HelpArgHandler(string argAlias)
{
System.Console.WriteLine(CreateHelpArgMessage(argAlias));
throw new ExitAfterHelpException();
}
public LaunchArgumentParser() public LaunchArgumentParser()
{ {
var help = new LaunchArgument(new[] { "h", "help" }, var help = new LaunchArgument(new[] { "h", "help" },
"shows help message", HelpHandler); "shows help message", HelpHandler);
Add(help); Add(help);
var helpArg = new LaunchArgument(new[] { "ha", "helparg" }, var helpArg = new LaunchArgument(new[] { "ha", "helparg" },
"shows help message for particular argument", "shows help message for specific argument",
HelpArgHandler, "argAlias"); HelpArgHandler, "argument");
Add(helpArg); Add(helpArg);
} }
public LaunchArgumentParser(ICollection<LaunchArgument> arguments) : this() => WithArgs(arguments);
public LaunchArgumentParser(params LaunchArgument[] arguments) : this() => WithArgs(arguments);
public LaunchArgumentParser WithArgs(IEnumerable<LaunchArgument> args)
{
foreach (var arg in args)
Add(arg);
return this;
}
public LaunchArgumentParser WithArgs(params LaunchArgument[] args)
{
foreach (var arg in args)
Add(arg);
return this;
}
public LaunchArgumentParser WithHelpMessageHeader(string header)
{
HelpMessageHeader = header;
return this;
}
public LaunchArgumentParser AllowNoArguments() public LaunchArgumentParser AllowNoArguments()
{ {
IsAllowedNoArguments = true; AllowedNoArguments = true;
return this; return this;
} }
public LaunchArgumentParser(ICollection<LaunchArgument> arguments) : this() public LaunchArgumentParser AllowUnknownArguments()
{ {
foreach (var arg in arguments) AllowedUnknownArguments = true;
Add(arg); return this;
} }
public LaunchArgumentParser(params LaunchArgument[] arguments) : this()
public string CreateHelpMessage()
{ {
foreach (var arg in arguments) StringBuilder b = new(HelpMessageHeader);
Add(arg); foreach (var arg in argList)
{
b.Append('\n');
arg.AppendHelpInfo(b);
}
return b.ToString();
}
public string CreateHelpArgMessage(string argAlias)
{
StringBuilder b = new();
if(!TryParseArg(argAlias, out var arg))
throw new Exception($"unknown argument '{argAlias}'");
arg.AppendHelpInfo(b);
return b.ToString();
} }
public void Add(LaunchArgument arg) public void Add(LaunchArgument arg)
@ -76,16 +84,13 @@ public class LaunchArgumentParser
argDict.Add(alias, arg); argDict.Add(alias, arg);
} }
public LaunchArgument Parse(string argAlias) public bool TryParseArg(string argAlias, out LaunchArgument arg)
{ {
// different argument providing patterns // different argument providing patterns
if (!argDict.TryGetValue(argAlias, out var arg) && // arg arg = null!;
!(argAlias.StartsWith("--") && argDict.TryGetValue(argAlias.Substring(2), out arg)) && // --arg return argAlias.StartsWith("--") && argDict.TryGetValue(argAlias.Substring(2), out arg) || // --arg
!(argAlias.StartsWith('-') && argDict.TryGetValue(argAlias.Substring(1), out arg)) && // -arg argAlias.StartsWith('-') && argDict.TryGetValue(argAlias.Substring(1), out arg) || // -arg
!(argAlias.StartsWith('/') && argDict.TryGetValue(argAlias.Substring(1), out arg))) // /arg argAlias.StartsWith('/') && argDict.TryGetValue(argAlias.Substring(1), out arg); // /arg
throw new Exception($"invalid argument: {argAlias}\n{CreateHelpMessage()}");
return arg;
} }
/// <param name="args">program launch args</param> /// <param name="args">program launch args</param>
@ -95,18 +100,24 @@ public class LaunchArgumentParser
public void ParseAndHandle(string[] args) public void ParseAndHandle(string[] args)
{ {
// show help message and throw ExitAfterHelpException // show help message and throw ExitAfterHelpException
if (args.Length == 0 && !IsAllowedNoArguments) if (args.Length == 0 && !AllowedNoArguments)
HelpHandler(); HelpHandler();
List<LaunchArgument> execQueue = new(); List<LaunchArgument> execQueue = new();
for (int i = 0; i < args.Length; i++) for (int i = 0; i < args.Length; i++)
{ {
LaunchArgument arg = Parse(args[i]); if (!TryParseArg(args[i], out var arg))
{
if (!AllowedUnknownArguments)
throw new Exception($"unknown argument '{args[i]}'");
UnknownArguments.Add(args[i]);
}
for (int j = 0; j < arg.Params.Length; j++) for (int j = 0; j < arg.Params.Length; j++)
{ {
if (++i >= args.Length) if (++i >= args.Length)
throw new Exception($"argument '{arg.Aliases[0]}' should have parameter '{arg.Params[j]}' after it"); throw new Exception(
$"argument '{arg.Aliases[0]}' should have parameter '{arg.Params[j]}' after it");
arg.Params[j].Value = args[i]; arg.Params[j].Value = args[i];
} }
@ -119,4 +130,24 @@ public class LaunchArgumentParser
foreach (var a in execQueue) foreach (var a in execQueue)
a.Handle(); a.Handle();
} }
private void HelpHandler()
{
System.Console.WriteLine(CreateHelpMessage());
throw new ExitAfterHelpException();
}
private void HelpArgHandler(string argAlias)
{
System.Console.WriteLine(CreateHelpArgMessage(argAlias));
throw new ExitAfterHelpException();
}
public class ExitAfterHelpException : Exception
{
public ExitAfterHelpException()
: base("your program can use this exception to exit after displaying help message")
{
}
}
} }

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<!--package info--> <!--package info-->
<PackageId>DTLib</PackageId> <PackageId>DTLib</PackageId>
<Version>1.7.1</Version> <Version>1.7.3</Version>
<Authors>Timerix</Authors> <Authors>Timerix</Authors>
<Description>Library for all my C# projects</Description> <Description>Library for all my C# projects</Description>
<RepositoryType>GIT</RepositoryType> <RepositoryType>GIT</RepositoryType>