8000 Use docopt.net to parse extensions generator CLI args by atifaziz · Pull Request #994 · morelinq/MoreLINQ · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Use docopt.net to parse extensions generator CLI args #994

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 2 commits into from
Apr 2, 2023
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
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="docopt.net" Version="0.8.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
<PackageReference Include="System.Collections.Immutable" Version="7.0.0" />
</ItemGroup>
Expand Down
97 changes: 40 additions & 57 deletions bld/ExtensionsGenerator/Program.cs
10000
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using DocoptNet;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
Expand All @@ -35,8 +36,19 @@
try
#pragma warning restore CA1852 // Seal internal types
{
Run(args);
return 0;
var exitCode =
ProgramArguments.CreateParser()
.Parse(args)
.Match(args => { Run(args); return 0; }, _ => 1);

if (exitCode != 0)
{
Console.Error.WriteLine("Invalid argument or usage!");
Console.Error.WriteLine();
Console.Error.WriteLine(ProgramArguments.Help);
}

return exitCode;
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception e)
Expand All @@ -46,63 +58,18 @@
return 0xbad;
}

static void Run(IEnumerable<string> args)
static void Run(ProgramArguments args)
{
var dir = Directory.GetCurrentDirectory();

string? includePattern = null;
string? excludePattern = null;
var debug = false;
var usings = new List<string>();
var noClassLead = false;

using (var arg = args.GetEnumerator())
{
while (arg.MoveNext())
{
switch (arg.Current)
{
case "-i":
case "--include":
includePattern = Read(arg, MissingArgValue);
break;
case "-x":
case "--exclude":
excludePattern = Read(arg, MissingArgValue);
break;
case "-u":
case "--using":
usings.Add(Read(arg, MissingArgValue));
break;
case "--no-class-lead":
noClassLead = true;
break;
case "-d":
case "--debug":
debug = true;
break;
case "":
continue;
default:
dir = arg.Current[0] != '-'
? arg.Current
: throw new Exception("Invalid argument: " + arg.Current);
break;
}
}

static Exception MissingArgValue() =>
new InvalidOperationException("Missing argument value.");
}
var dir = args.ArgDir ?? Directory.GetCurrentDirectory();

static Func<string, bool>
PredicateFromPattern(string? pattern, bool @default) =>
string.IsNullOrEmpty(pattern)
? delegate { return @default; }
: new Func<string, bool>(new Regex(pattern).IsMatch);

var includePredicate = PredicateFromPattern(includePattern, true);
var excludePredicate = PredicateFromPattern(excludePattern, false);
var includePredicate = PredicateFromPattern(args.OptInclude, true);
var excludePredicate = PredicateFromPattern(args.OptExclude, false);

var thisAssemblyName = typeof(TypeKey).GetTypeInfo().Assembly.GetName();

Expand Down Expand Up @@ -198,7 +165,7 @@ from e in ms.Select((m, i) => (SourceOrder: i + 1, Method: m))

q = q.ToArray();

if (debug)
if (args.OptDebug)
{
var ms =
//
Expand Down Expand Up @@ -252,7 +219,7 @@ into e
};

var imports =
from ns in baseImports.Concat(usings)
from ns in baseImports.Concat(args.OptUsing)
select indent + $"using {ns};";

var classes =
Expand Down Expand Up @@ -290,7 +257,7 @@ select Argument(IdentifierName(p.Identifier)),
.WithSemicolonToken(ParseToken(";").WithTrailingTrivia(LineFeed))
}
into m
let classLead = !noClassLead
let classLead = !args.OptNoClassLead
? $$"""

/// <summary><c>{{m.Name}}</c> extension.</summary>
Expand Down Expand Up @@ -373,9 +340,6 @@ select Walk(te.Type))),
};
}

static T Read<T>(IEnumerator<T> e, Func<Exception> errorFactory) =>
e.MoveNext() ? e.Current : throw errorFactory();

//
// Logical type nodes designed to be structurally sortable based on:
//
Expand Down Expand Up @@ -478,3 +442,22 @@ protected override int CompareParameters(TypeKey other)
return base.CompareParameters(other);
}
}

[DocoptArguments(HelpConstName = nameof(HelpText))]
sealed partial class ProgramArguments
{
const string HelpText = """
Usage:
#BIN# [options] [-u NAMESPACE]... [DIR]

Options:
-i, --include REGEX Include files matching pattern.
-x, --exclude REGEX Exclude files matching pattern.
-u, --using NAMESPACE Additional using imports to add.
--no-class-lead Skip generating class lead.
-d, --debug Produce output for debugging.
""";

public static string Help =>
HelpText.Replace("#BIN#", Path.GetFileName(Environment.ProcessPath), StringComparison.Ordinal);
}
0