mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -08:00
Check that .NET ports have at least one executable project; and some project properties
This commit is contained in:
21
00_Utilities/DotnetUtils/DotnetUtils/Functions.cs
Normal file
21
00_Utilities/DotnetUtils/DotnetUtils/Functions.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user