Check that .NET ports have at least one executable project; and some project properties

This commit is contained in:
Zev Spitz
2022-01-17 00:03:14 +02:00
parent 75def2707d
commit 18284fa3d4
3 changed files with 118 additions and 7 deletions

View File

@@ -0,0 +1,21 @@
using System.Xml.Linq;
namespace DotnetUtils;
public static class Functions {
public static string? getValue(string path, params string[] names) {
if (names.Length == 0) { throw new InvalidOperationException(); }
var parent = XDocument.Load(path).Element("Project")?.Element("PropertyGroup");
return getValue(parent, names);
}
public static string? getValue(XElement? parent, params string[] names) {
if (names.Length == 0) { throw new InvalidOperationException(); }
XElement? elem = null;
foreach (var name in names) {
elem = parent?.Element(name);
if (elem != null) { break; }
}
return elem?.Value;
}
}

View File

@@ -44,6 +44,38 @@ public static class Methods {
process.WaitForExit(); process.WaitForExit();
return new ProcessResult(process.ExitCode, output, error); return new ProcessResult(process.ExitCode, output, error);
} }
public static Task<ProcessResult> RunProcessAsync(Process process, string input = "") {
var tcs = new TaskCompletionSource<ProcessResult>();
var (output, error) = ("", "");
var (redirectOut, redirectErr) = (
process.StartInfo.RedirectStandardOutput,
process.StartInfo.RedirectStandardError
);
process.Exited += (s, e) => tcs.SetResult(new ProcessResult(process.ExitCode, output, error));
if (redirectOut) {
process.OutputDataReceived += (s, ea) => output += ea.Data + "\n";
}
if (redirectErr) {
process.ErrorDataReceived += (s, ea) => error += ea.Data + "\n";
}
if (!process.Start()) {
// what happens to the Exited event if process doesn't start successfully?
throw new InvalidOperationException();
}
if (redirectOut) { process.BeginOutputReadLine(); }
if (redirectErr) { process.BeginErrorReadLine(); }
if (!string.IsNullOrEmpty(input)) {
process.StandardInput.WriteLine(input);
process.StandardInput.Close();
}
return tcs.Task;
}
} }
public sealed record ProcessResult(int ExitCode, string StdOut, string StdErr) { public sealed record ProcessResult(int ExitCode, string StdOut, string StdErr) {

View File

@@ -1,7 +1,9 @@
using DotnetUtils; using System.Xml.Linq;
using DotnetUtils;
using static System.Console; using static System.Console;
using static System.IO.Path; using static System.IO.Path;
using static DotnetUtils.Methods; using static DotnetUtils.Methods;
using static DotnetUtils.Functions;
var infos = PortInfos.Get; var infos = PortInfos.Get;
@@ -13,6 +15,8 @@ var actions = new (Action action, string description)[] {
(missingProj, "Output missing project file"), (missingProj, "Output missing project file"),
(unexpectedProjName, "Output misnamed project files"), (unexpectedProjName, "Output misnamed project files"),
(multipleProjs, "Output multiple project files"), (multipleProjs, "Output multiple project files"),
(checkProjects, "Check .csproj/.vbproj files for target framework, nullability etc."),
(checkExecutableProject, "Check that there is at least one executable project per port"),
(generateMissingSlns, "Generate solution files when missing"), (generateMissingSlns, "Generate solution files when missing"),
(generateMissingProjs, "Generate project files when missing") (generateMissingProjs, "Generate project files when missing")
@@ -220,12 +224,66 @@ void generateMissingProjs() {
} }
void checkProjects() { void checkProjects() {
// warn if project files do not: foreach (var (proj,item) in infos.SelectMany(item => item.Projs.Select(proj => (proj,item)))) {
// target .NET 6 var warnings = new List<string>();
// implicit using var parent = XDocument.Load(proj).Element("Project")?.Element("PropertyGroup");
// nullable enable
// warn if none og the projects have: var (
// output type exe framework,
nullable,
implicitUsing,
rootNamespace,
langVersion
) = (
getValue(parent, "TargetFramework", "TargetFrameworks"),
getValue(parent, "Nullable"),
getValue(parent, "ImplicitUsings"),
getValue(parent, "RootNamespace"),
getValue(parent, "LangVersion")
);
if (framework != "net6.0") {
warnings.Add($"Target: {framework}");
}
if (item.Lang == "csharp") {
if (nullable != "enable") {
warnings.Add($"Nullable: {nullable}");
}
if (implicitUsing != "enable") {
warnings.Add($"ImplicitUsings: {implicitUsing}");
}
if (rootNamespace != null && rootNamespace != item.GameName) {
warnings.Add($"RootNamespace: {rootNamespace}");
}
if (langVersion != "10") {
warnings.Add($"LangVersion: {langVersion}");
}
}
if (item.Lang == "vbnet") {
if (rootNamespace != item.GameName) {
warnings.Add($"RootNamespace: {rootNamespace}");
}
if (langVersion != "16.9") {
warnings.Add($"LangVersion: {langVersion}");
}
}
if (warnings.Any()) {
WriteLine(proj);
WriteLine(string.Join("\n", warnings));
WriteLine();
}
}
}
void checkExecutableProject() {
foreach (var item in infos) {
if (item.Projs.All(proj => getValue(proj,"OutputType") != "Exe")) {
WriteLine($"{item.LangPath}");
}
}
} }
void tryBuild() { void tryBuild() {