mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 15:16:33 -08:00
Script - output info on a single port
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) ?
|
|
||||||
n :
|
|
||||||
(int?)null;
|
|
||||||
|
|
||||||
var gameName =
|
var (index, gameName) = (
|
||||||
parts.Length <= 1 ?
|
int.TryParse(parts[0], out var n) && n > 0 ? // ignore utilities folder
|
||||||
null :
|
n :
|
||||||
|
(int?)null,
|
||||||
specialGameNames.TryGetValue(parts[1], out var specialName) ?
|
specialGameNames.TryGetValue(parts[1], out var specialName) ?
|
||||||
specialName :
|
specialName :
|
||||||
parts[1].Replace("_", "").Replace("-", "");
|
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 (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),
|
||||||
|
|||||||
@@ -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()!;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user