mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-21 23:00:43 -08:00
Script - output info on a single port
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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()!;
|
||||
}
|
||||
|
||||
@@ -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<string>();
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user