Script - output info on a single port

This commit is contained in:
Zev Spitz
2022-01-17 02:55:36 +02:00
parent 18284fa3d4
commit bdd4a459a2
4 changed files with 107 additions and 36 deletions

View File

@@ -1,4 +1,5 @@
using System.Xml.Linq; using System.Xml.Linq;
using static System.Console;
namespace DotnetUtils; namespace DotnetUtils;
@@ -18,4 +19,17 @@ public static class Functions {
} }
return elem?.Value; 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;
}
} }

View File

@@ -5,7 +5,7 @@ using static DotnetUtils.Globals;
namespace DotnetUtils; namespace DotnetUtils;
public record PortInfo( 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 LangPath, string Lang, string Ext, string ProjExt,
string[] CodeFiles, string[] Slns, string[] Projs string[] CodeFiles, string[] Slns, string[] Projs
) { ) {
@@ -24,33 +24,32 @@ public record PortInfo(
{ "23_Matches", "TwentyThreeMatches"} { "23_Matches", "TwentyThreeMatches"}
}; };
public static PortInfo? Create(string fullPath, string langKeyword) { public static PortInfo? Create(string gamePath, string langKeyword) {
var folderName = GetFileName(fullPath); var folderName = GetFileName(gamePath);
var parts = folderName.Split('_', 2); var parts = folderName.Split('_', 2);
var index = if (parts.Length <= 1) { return null; }
parts.Length > 0 && int.TryParse(parts[0], out var n) ?
var (index, gameName) = (
int.TryParse(parts[0], out var n) && n > 0 ? // ignore utilities folder
n : n :
(int?)null; (int?)null,
specialGameNames.TryGetValue(parts[1], out var specialName) ?
specialName :
parts[1].Replace("_", "").Replace("-", "")
);
var gameName = if (index is null || gameName is null) { return null; }
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; }
var (ext, projExt) = LangData[langKeyword]; var (ext, projExt) = LangData[langKeyword];
var langPath = Combine(fullPath, langKeyword); var langPath = Combine(gamePath, langKeyword);
var codeFiles = var codeFiles =
GetFiles(langPath, $"*.{ext}", enumerationOptions) GetFiles(langPath, $"*.{ext}", enumerationOptions)
.Where(x => !x.Contains("\\bin\\") && !x.Contains("\\obj\\")) .Where(x => !x.Contains("\\bin\\") && !x.Contains("\\obj\\"))
.ToArray(); .ToArray();
return new PortInfo( return new PortInfo(
fullPath, folderName, index.Value, gameName, gamePath, folderName, index.Value, gameName,
langPath, langKeyword, ext, projExt, langPath, langKeyword, ext, projExt,
codeFiles, codeFiles,
GetFiles(langPath, "*.sln", enumerationOptions), GetFiles(langPath, "*.sln", enumerationOptions),

View File

@@ -12,8 +12,8 @@ public static class PortInfos {
Root = Root[..Root.IndexOf(@"\00_Utilities")]; Root = Root[..Root.IndexOf(@"\00_Utilities")];
Get = GetDirectories(Root) Get = GetDirectories(Root)
.SelectMany(fullPath => LangData.Keys.Select(keyword => (fullPath, keyword))) .SelectMany(gamePath => LangData.Keys.Select(keyword => (gamePath, keyword)))
.SelectT((fullPath, keyword) => PortInfo.Create(fullPath, keyword)) .SelectT((gamePath, keyword) => PortInfo.Create(gamePath, keyword))
.Where(x => x is not null) .Where(x => x is not null)
.ToArray()!; .ToArray()!;
} }

View File

@@ -17,6 +17,7 @@ var actions = new (Action action, string description)[] {
(multipleProjs, "Output multiple project files"), (multipleProjs, "Output multiple project files"),
(checkProjects, "Check .csproj/.vbproj files for target framework, nullability etc."), (checkProjects, "Check .csproj/.vbproj files for target framework, nullability etc."),
(checkExecutableProject, "Check that there is at least one executable project per port"), (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"), (generateMissingSlns, "Generate solution files when missing"),
(generateMissingProjs, "Generate project files when missing") (generateMissingProjs, "Generate project files when missing")
@@ -30,15 +31,6 @@ WriteLine();
actions[getChoice(actions.Length - 1)].action(); 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) { void printSlns(PortInfo pi) {
switch (pi.Slns.Length) { switch (pi.Slns.Length) {
case 0: case 0:
@@ -73,7 +65,6 @@ void printProjs(PortInfo pi) {
} }
break; break;
} }
WriteLine();
} }
void printInfos() { void printInfos() {
@@ -224,7 +215,15 @@ void generateMissingProjs() {
} }
void checkProjects() { 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<string>(); var warnings = new List<string>();
var parent = XDocument.Load(proj).Element("Project")?.Element("PropertyGroup"); var parent = XDocument.Load(proj).Element("Project")?.Element("PropertyGroup");
@@ -246,14 +245,14 @@ void checkProjects() {
warnings.Add($"Target: {framework}"); warnings.Add($"Target: {framework}");
} }
if (item.Lang == "csharp") { if (info.Lang == "csharp") {
if (nullable != "enable") { if (nullable != "enable") {
warnings.Add($"Nullable: {nullable}"); warnings.Add($"Nullable: {nullable}");
} }
if (implicitUsing != "enable") { if (implicitUsing != "enable") {
warnings.Add($"ImplicitUsings: {implicitUsing}"); warnings.Add($"ImplicitUsings: {implicitUsing}");
} }
if (rootNamespace != null && rootNamespace != item.GameName) { if (rootNamespace != null && rootNamespace != info.GameName) {
warnings.Add($"RootNamespace: {rootNamespace}"); warnings.Add($"RootNamespace: {rootNamespace}");
} }
if (langVersion != "10") { if (langVersion != "10") {
@@ -261,8 +260,8 @@ void checkProjects() {
} }
} }
if (item.Lang == "vbnet") { if (info.Lang == "vbnet") {
if (rootNamespace != item.GameName) { if (rootNamespace != info.GameName) {
warnings.Add($"RootNamespace: {rootNamespace}"); warnings.Add($"RootNamespace: {rootNamespace}");
} }
if (langVersion != "16.9") { if (langVersion != "16.9") {
@@ -271,7 +270,7 @@ void checkProjects() {
} }
if (warnings.Any()) { if (warnings.Any()) {
WriteLine(proj); WriteLine(proj.RelativePath(info.LangPath));
WriteLine(string.Join("\n", warnings)); WriteLine(string.Join("\n", warnings));
WriteLine(); WriteLine();
} }
@@ -280,7 +279,7 @@ void checkProjects() {
void checkExecutableProject() { void checkExecutableProject() {
foreach (var item in infos) { 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}"); WriteLine($"{item.LangPath}");
} }
} }
@@ -289,3 +288,62 @@ void checkExecutableProject() {
void tryBuild() { void tryBuild() {
// if has code files, try to build // 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
}