diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs b/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs index 7fa3115c..cc31170e 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Functions.cs @@ -1,4 +1,5 @@ using System.Xml.Linq; +using static System.Console; namespace DotnetUtils; @@ -18,4 +19,17 @@ public static class Functions { } return elem?.Value; } + + public static int getChoice(int maxValue) => getChoice(0, maxValue); + + public static int getChoice(int minValue, int maxValue) { + int result; + do { + Write("? "); + } while (!int.TryParse(ReadLine(), out result) || result < minValue || result > maxValue); + //WriteLine(); + return result; + } + + } diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs index a1caaf15..1cb0ba03 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfo.cs @@ -5,7 +5,7 @@ using static DotnetUtils.Globals; namespace DotnetUtils; public record PortInfo( - string FullPath, string FolderName, int Index, string GameName, + string GamePath, string FolderName, int Index, string GameName, string LangPath, string Lang, string Ext, string ProjExt, string[] CodeFiles, string[] Slns, string[] Projs ) { @@ -24,33 +24,32 @@ public record PortInfo( { "23_Matches", "TwentyThreeMatches"} }; - public static PortInfo? Create(string fullPath, string langKeyword) { - var folderName = GetFileName(fullPath); + public static PortInfo? Create(string gamePath, string langKeyword) { + var folderName = GetFileName(gamePath); var parts = folderName.Split('_', 2); - var index = - parts.Length > 0 && int.TryParse(parts[0], out var n) ? + if (parts.Length <= 1) { return null; } + + var (index, gameName) = ( + int.TryParse(parts[0], out var n) && n > 0 ? // ignore utilities folder n : - (int?)null; + (int?)null, + specialGameNames.TryGetValue(parts[1], out var specialName) ? + specialName : + parts[1].Replace("_", "").Replace("-", "") + ); - var gameName = - parts.Length <= 1 ? - null : - specialGameNames.TryGetValue(parts[1], out var specialName) ? - specialName : - parts[1].Replace("_", "").Replace("-", ""); - - if (index is 0 or null || gameName is null) { return null; } + if (index is null || gameName is null) { return null; } var (ext, projExt) = LangData[langKeyword]; - var langPath = Combine(fullPath, langKeyword); + var langPath = Combine(gamePath, langKeyword); var codeFiles = GetFiles(langPath, $"*.{ext}", enumerationOptions) .Where(x => !x.Contains("\\bin\\") && !x.Contains("\\obj\\")) .ToArray(); return new PortInfo( - fullPath, folderName, index.Value, gameName, + gamePath, folderName, index.Value, gameName, langPath, langKeyword, ext, projExt, codeFiles, GetFiles(langPath, "*.sln", enumerationOptions), diff --git a/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs b/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs index b8c1afd3..af824b33 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/PortInfos.cs @@ -12,8 +12,8 @@ public static class PortInfos { Root = Root[..Root.IndexOf(@"\00_Utilities")]; Get = GetDirectories(Root) - .SelectMany(fullPath => LangData.Keys.Select(keyword => (fullPath, keyword))) - .SelectT((fullPath, keyword) => PortInfo.Create(fullPath, keyword)) + .SelectMany(gamePath => LangData.Keys.Select(keyword => (gamePath, keyword))) + .SelectT((gamePath, keyword) => PortInfo.Create(gamePath, keyword)) .Where(x => x is not null) .ToArray()!; } diff --git a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs index 6121d131..ab59bd9e 100644 --- a/00_Utilities/DotnetUtils/DotnetUtils/Program.cs +++ b/00_Utilities/DotnetUtils/DotnetUtils/Program.cs @@ -17,6 +17,7 @@ var actions = new (Action action, string description)[] { (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"), + (printPortInfo, "Print info about a single port"), (generateMissingSlns, "Generate solution files when missing"), (generateMissingProjs, "Generate project files when missing") @@ -30,15 +31,6 @@ WriteLine(); actions[getChoice(actions.Length - 1)].action(); -int getChoice(int maxValue) { - int result; - do { - Write("? "); - } while (!int.TryParse(ReadLine(), out result) || result < 0 || result > maxValue); - WriteLine(); - return result; -} - void printSlns(PortInfo pi) { switch (pi.Slns.Length) { case 0: @@ -73,7 +65,6 @@ void printProjs(PortInfo pi) { } break; } - WriteLine(); } void printInfos() { @@ -215,7 +206,7 @@ void generateMissingProjs() { }; var projFullPath = Combine(item.LangPath, $"{item.GameName}.{item.ProjExt}"); File.WriteAllText(projFullPath, projText); - + if (item.Slns.Length == 1) { var result = RunProcess("dotnet", $"sln {item.Slns[0]} add {projFullPath}"); WriteLine(result); @@ -224,7 +215,15 @@ void generateMissingProjs() { } void checkProjects() { - foreach (var (proj,item) in infos.SelectMany(item => item.Projs.Select(proj => (proj,item)))) { + foreach (var info in infos) { + printProjectWarnings(info); + WriteLine(); + } +} + +// TODO make this run on a single project +void printProjectWarnings(PortInfo info) { + foreach (var proj in info.Projs) { var warnings = new List(); var parent = XDocument.Load(proj).Element("Project")?.Element("PropertyGroup"); @@ -246,14 +245,14 @@ void checkProjects() { warnings.Add($"Target: {framework}"); } - if (item.Lang == "csharp") { + if (info.Lang == "csharp") { if (nullable != "enable") { warnings.Add($"Nullable: {nullable}"); } if (implicitUsing != "enable") { warnings.Add($"ImplicitUsings: {implicitUsing}"); } - if (rootNamespace != null && rootNamespace != item.GameName) { + if (rootNamespace != null && rootNamespace != info.GameName) { warnings.Add($"RootNamespace: {rootNamespace}"); } if (langVersion != "10") { @@ -261,8 +260,8 @@ void checkProjects() { } } - if (item.Lang == "vbnet") { - if (rootNamespace != item.GameName) { + if (info.Lang == "vbnet") { + if (rootNamespace != info.GameName) { warnings.Add($"RootNamespace: {rootNamespace}"); } if (langVersion != "16.9") { @@ -271,7 +270,7 @@ void checkProjects() { } if (warnings.Any()) { - WriteLine(proj); + WriteLine(proj.RelativePath(info.LangPath)); WriteLine(string.Join("\n", warnings)); WriteLine(); } @@ -280,7 +279,7 @@ void checkProjects() { void checkExecutableProject() { foreach (var item in infos) { - if (item.Projs.All(proj => getValue(proj,"OutputType") != "Exe")) { + if (item.Projs.All(proj => getValue(proj, "OutputType") != "Exe")) { WriteLine($"{item.LangPath}"); } } @@ -289,3 +288,62 @@ void checkExecutableProject() { void tryBuild() { // if has code files, try to build } + +void printPortInfo() { + // prompt for port number + Write("Enter number from 1 to 96 "); + var index = getChoice(1, 96); + + Write("Enter 0 for C#, 1 for VB "); + var lang = getChoice(1) switch { + 0 => "csharp", + 1 => "vbnet", + _ => throw new InvalidOperationException() + }; + + WriteLine(); + + var info = infos.Single(x => x.Index == index && x.Lang == lang); + + WriteLine(info.LangPath); + WriteLine(new string('-', 50)); + + // print solutions + printSlns(info); + + // mismatched solution name/location? (expected x) + var expectedSlnName = Combine(info.LangPath, $"{info.GameName}.sln"); + if (!info.Slns.Contains(expectedSlnName)) { + WriteLine($"Expected name/path: {expectedSlnName.RelativePath(info.LangPath)}"); + } + + // has executable project? + if (info.Projs.All(proj => getValue(proj, "OutputType") != "Exe")) { + WriteLine("No executable project"); + } + + WriteLine(); + + // print projects + printProjs(info); + + // mimsatched project name/location? (expected x) + var expectedProjName = Combine(info.LangPath, $"{info.GameName}.{info.ProjExt}"); + if (info.Projs.Length < 2 && !info.Projs.Contains(expectedProjName)) { + WriteLine($"Expected name/path: {expectedProjName.RelativePath(info.LangPath)}"); + } + + WriteLine(); + + // verify project properties + printProjectWarnings(info); + + WriteLine("Code files:"); + + // list code files + foreach (var codeFile in info.CodeFiles) { + WriteLine(codeFile.RelativePath(info.LangPath)); + } + + // try build +}