diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index c05b823..c2dc9ae 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -10,8 +10,31 @@ on:
jobs:
build:
+ strategy:
+ fail-fast: false
+ matrix:
+ platform:
+ - {os: windows-latest, framework: net7.0-windows, runtime: win-x64}
+ - {os: ubuntu-latest, framework: net7.0, runtime: linux-x64}
+ build_type:
+ - {
+ name: 'Build',
+ configuration: Debug,
+ command: 'dotnet build ConsoleApp --no-self-contained',
+ }
+ - {
+ name: 'Publish to single file',
+ configuration: Release,
+ command: 'dotnet publish ConsoleApp -p:PublishSingleFile=true --self-contained',
+ }
+ - {
+ name: 'Run tests',
+ configuration: Release,
+ command: 'dotnet test --logger "console;verbosity=detailed"',
+ }
- runs-on: windows-latest
+ runs-on: ${{ matrix.platform.os }}
+ name: ${{ matrix.build_type.name }} (${{ matrix.build_type.configuration }}, ${{ matrix.platform.os }}
steps:
- name: Checkout Project
@@ -20,14 +43,10 @@ jobs:
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- - name: Add msbuild to PATH
- uses: microsoft/setup-msbuild@v1.1
- - name: Build Debug
- run: msbuild ConsoleApp\ConsoleApp.csproj -target:Rebuild -property:Configuration=Debug -restore
- - name: Build Release
- run: msbuild ConsoleApp\ConsoleApp.csproj -target:Rebuild -property:Configuration=Release -restore
- - name: Publish to single executable
- run: msbuild ConsoleApp\ConsoleApp.csproj -target:Rebuild /p:DeployOnBuild=true /p:PublishProfile=publish-single-file -restore
- - name: Test
- run: dotnet test --logger "console;verbosity=detailed" --configuration Release
+ - name: ${{ matrix.build_type.name }}
+ run: >
+ ${{ matrix.build_type.command }}
+ --framework=${{ matrix.platform.framework }}
+ --runtime=${{ matrix.platform.runtime }}
+ --configuration=${{ matrix.build_type.configuration }}
diff --git a/ConsoleApp/ConsoleApp.csproj b/ConsoleApp/ConsoleApp.csproj
index bd12c43..66205fb 100644
--- a/ConsoleApp/ConsoleApp.csproj
+++ b/ConsoleApp/ConsoleApp.csproj
@@ -2,7 +2,6 @@
Exe
- net7.0-windows
../github-resources/investigation.ico
AnyCPU;x64
Debug;Release;Debug_ProcessEnts
@@ -11,6 +10,7 @@
UntitledParser
enable
9999
+ net7.0;net7.0-windows
@@ -68,8 +68,8 @@
-
-
-
+
+
+
diff --git a/ConsoleApp/src/DemoArgProcessing/DemoParserSubCommand.cs b/ConsoleApp/src/DemoArgProcessing/DemoParserSubCommand.cs
index d5b66a4..aff3448 100644
--- a/ConsoleApp/src/DemoArgProcessing/DemoParserSubCommand.cs
+++ b/ConsoleApp/src/DemoArgProcessing/DemoParserSubCommand.cs
@@ -123,7 +123,7 @@ private void FlattenDirectories(DemoParsingSetupInfo setupInfo) {
demoPath,
commonParent == ""
? demoPath.FullName
- : PathExt.GetRelativePath(commonParent, demoPath.FullName)
+ : Path.GetRelativePath(commonParent, demoPath.FullName)
));
}
diff --git a/ConsoleApp/src/PathExt.cs b/ConsoleApp/src/PathExt.cs
deleted file mode 100644
index 7376be3..0000000
--- a/ConsoleApp/src/PathExt.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * More-or-less ripped straight from .NET Core runtime, with some ws/comments stripped out
- *
- * Licensed to the .NET Foundation under one or more agreements.
- * The .NET Foundation licenses this file to you under the MIT license.
- */
-
-// FIXME: This is very Windows-specific! This will probably be one of the things
-// that needs fixed up if/when doing a Linux/Mono port.
-
-using System;
-using System.IO;
-using System.Text;
-
-namespace ConsoleApp {
-
- internal static class PathExt {
-
- private static bool IsDirectorySeparator(char c) => c == '\\' || c == '/';
- private static bool EndsInDirectorySeparator(string path)
- => path.Length > 0 && IsDirectorySeparator(path[^1]);
-
- private static unsafe int EqualStartingCharacterCount(string? first, string? second, bool ignoreCase) {
- if (string.IsNullOrEmpty(first) || string.IsNullOrEmpty(second)) return 0;
-
- int commonChars = 0;
- fixed (char* f = first)
- fixed (char* s = second) {
- char* l = f;
- char* r = s;
- char* leftEnd = l + first!.Length;
- char* rightEnd = r + second!.Length;
-
- while (l != leftEnd && r != rightEnd
- && (*l == *r || (ignoreCase && char.ToUpperInvariant(*l) == char.ToUpperInvariant(*r)))) {
- commonChars++;
- l++;
- r++;
- }
- }
-
- return commonChars;
- }
-
- private static int GetCommonPathLength(string first, string second, bool ignoreCase) {
- int commonChars = EqualStartingCharacterCount(first, second, ignoreCase);
- if (commonChars == 0) return commonChars;
- if (commonChars == first.Length && (commonChars == second.Length ||
- IsDirectorySeparator(second[commonChars])))
- return commonChars;
- if (commonChars == second.Length && IsDirectorySeparator(first[commonChars]))
- return commonChars;
- while (commonChars > 0 && !IsDirectorySeparator(first[commonChars - 1]))
- commonChars--;
- return commonChars;
- }
-
- private static bool AreRootsEqual(string first, string second, StringComparison comparisonType) {
- int firstRootLength = GetRootLength(first);
- int secondRootLength = GetRootLength(second);
-
- return firstRootLength == secondRootLength
- && string.Compare(
- strA: first,
- indexA: 0,
- strB: second,
- indexB: 0,
- length: firstRootLength,
- comparisonType: comparisonType) == 0;
- }
-
- private const int
- DevicePrefixLength = 4,
- UncPrefixLength = 2,
- UncExtendedPrefixLength = 8;
-
- private static bool IsExtended(string path) {
- return path.Length >= DevicePrefixLength
- && path[0] == '\\'
- && (path[1] == '\\' || path[1] == '?')
- && path[2] == '?'
- && path[3] == '\\';
- }
-
- private static bool IsDevice(string path) {
- return IsExtended(path)
- ||
- (
- path.Length >= DevicePrefixLength
- && IsDirectorySeparator(path[0])
- && IsDirectorySeparator(path[1])
- && (path[2] == '.' || path[2] == '?')
- && IsDirectorySeparator(path[3])
- );
- }
-
- private static bool IsDeviceUNC(string path) {
- return path.Length >= UncExtendedPrefixLength
- && IsDevice(path)
- && IsDirectorySeparator(path[7])
- && path[4] == 'U'
- && path[5] == 'N'
- && path[6] == 'C';
- }
-
- private static bool IsValidDriveChar(char value) {
- return (value >= 'A' && value <= 'Z') || (value >= 'a' && value <= 'z');
- }
-
- private static int GetRootLength(string path) {
- int pathLength = path.Length;
- int i = 0;
-
- bool deviceSyntax = IsDevice(path);
- bool deviceUnc = deviceSyntax && IsDeviceUNC(path);
- if ((!deviceSyntax || deviceUnc) && pathLength > 0 && IsDirectorySeparator(path[0])) {
- if (deviceUnc || (pathLength > 1 && IsDirectorySeparator(path[1]))) {
- i = deviceUnc ? UncExtendedPrefixLength : UncPrefixLength;
- int n = 2;
- while (i < pathLength && (!IsDirectorySeparator(path[i]) || --n > 0)) i++;
- } else {
- i = 1;
- }
- } else if (deviceSyntax) {
- i = DevicePrefixLength;
- while (i < pathLength && !IsDirectorySeparator(path[i])) i++;
- if (i < pathLength && i > DevicePrefixLength && IsDirectorySeparator(path[i])) i++;
- }
- else if (pathLength >= 2
- && path[1] == ':'
- && IsValidDriveChar(path[0])) {
- i = 2;
- if (pathLength > 2 && IsDirectorySeparator(path[2])) i++;
- }
- return i;
- }
-
- public static string GetRelativePath(string relativeTo, string path, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) {
- if (relativeTo == null) throw new ArgumentNullException(nameof(relativeTo));
- if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Empty path", nameof(relativeTo));
- if (path == null) throw new ArgumentNullException(nameof(path));
- if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Empty path", nameof(path));
- relativeTo = Path.GetFullPath(relativeTo);
- path = Path.GetFullPath(path);
- if (!AreRootsEqual(relativeTo, path, comparisonType)) return path;
- int commonLength = GetCommonPathLength(relativeTo, path, ignoreCase: comparisonType == StringComparison.OrdinalIgnoreCase);
- if (commonLength == 0) return path;
- int relativeToLength = relativeTo.Length;
- if (EndsInDirectorySeparator(relativeTo)) relativeToLength--;
- bool pathEndsInSeparator = EndsInDirectorySeparator(path);
- int pathLength = path.Length;
- if (pathEndsInSeparator) pathLength--;
- if (relativeToLength == pathLength && commonLength >= relativeToLength) return ".";
- var sb = new StringBuilder();
- sb.EnsureCapacity(Math.Max(relativeTo.Length, path.Length));
- if (commonLength < relativeToLength) {
- sb.Append("..");
- for (int i = commonLength + 1; i < relativeToLength; i++) {
- if (IsDirectorySeparator(relativeTo[i])) {
- sb.Append("\\..");
- }
- }
- }
- else if (IsDirectorySeparator(path[commonLength])) {
- commonLength++;
- }
- int differenceLength = pathLength - commonLength;
- if (pathEndsInSeparator) differenceLength++;
- if (differenceLength > 0) {
- if (sb.Length > 0) sb.Append(Path.DirectorySeparatorChar);
- sb.Append(path.AsSpan(commonLength, differenceLength).ToString());
- }
-
- return sb.ToString();
- }
- }
-}
diff --git a/ConsoleApp/src/Program.cs b/ConsoleApp/src/Program.cs
index 70b2e1e..cc9b77a 100644
--- a/ConsoleApp/src/Program.cs
+++ b/ConsoleApp/src/Program.cs
@@ -150,6 +150,8 @@ public static void Main(string[] args) {
Environment.ExitCode = 3;
}
Console.ResetColor();
+ if (!Utils.IsWindows())
+ Console.WriteLine(); // TODO: checkout why linux doesn't give us as many lines as windows
if (Utils.WillBeDestroyedOnExit())
Console.ReadLine();
}
diff --git a/ConsoleApp/src/Utils.cs b/ConsoleApp/src/Utils.cs
index 6f2fc20..a482c77 100644
--- a/ConsoleApp/src/Utils.cs
+++ b/ConsoleApp/src/Utils.cs
@@ -4,6 +4,7 @@
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace ConsoleApp {
@@ -108,13 +109,15 @@ public static string FormatTime(double seconds) {
public static string GetExeName() => QuoteIfHasSpaces(AppDomain.CurrentDomain.FriendlyName);
- [System.Runtime.InteropServices.DllImport("kernel32.dll")]
+ [DllImport("kernel32.dll")]
private static extern int GetConsoleProcessList(int[] buffer, int size);
// used to check if we should use ReadKey() once we finish
public static bool WillBeDestroyedOnExit() {
- return !Debugger.IsAttached && GetConsoleProcessList(new int[2], 2) <= 1;
+ if (IsWindows())
+ return !Debugger.IsAttached && GetConsoleProcessList(new int[2], 2) <= 1;
+ return false; // TODO this is a bit of a hack, see if there's a better solution on linux
}
@@ -140,8 +143,13 @@ public static bool WillBeDestroyedOnExit() {
}
+ public static bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+
+
// microsoft, you autocomplete dir to '.\dir name\' and then that last single quote escapes into a double quote which fucks everything
public static string[] FixPowerShellBullshit(string[] args) {
+ if (!IsWindows())
+ return args;
// example input: '.\nosla 12 50 89\' '.\nosla 12 50 89\' gets converted to [.\nosla 12 50 89" .\nosla, 12, 50, 89"]
var newArgs = new List();
bool fixing = false;
diff --git a/DemoParser/DemoParser.csproj b/DemoParser/DemoParser.csproj
index 18321ef..78ec453 100644
--- a/DemoParser/DemoParser.csproj
+++ b/DemoParser/DemoParser.csproj
@@ -1,7 +1,7 @@
- net7.0-windows
+ net7.0;net7.0-windows
true
UntitledDemoParser
UncraftedName
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index 6cb00f3..7806084 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -1,7 +1,7 @@
- net7.0-windows
+ net7.0;net7.0-windows
false
AnyCPU;x64
Debug;Release;Debug_ProcessEnts
diff --git a/Tests/src/DemoParseTests.cs b/Tests/src/DemoParseTests.cs
index 86f63e5..9d9aa49 100644
--- a/Tests/src/DemoParseTests.cs
+++ b/Tests/src/DemoParseTests.cs
@@ -47,9 +47,30 @@ public abstract class DemoParseTests {
private static readonly Dictionary RawDemoDataLookup = RawDemoDataLookup = new Dictionary();
private static bool _loaded;
- public static readonly string ProjectDir =
- // bin/Debug/net461 -> ../../..
- Directory.GetParent(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!)!.Parent!.Parent!.FullName;
+ private static string _projectDir;
+ public static string ProjectDir {
+ get {
+ if (_projectDir != null)
+ return _projectDir;
+ /*
+ * I keep running into stupid issues with the executable being nested at different levels in the
+ * bin folder, and it seems like C# doesn't provide a way for us to know what the project folder
+ * is (maybe there's some assembly attribute stuff I could use?). So I'll just iterate up the
+ * folders until I get to the project folder; this should always work and will throw exceptions
+ * when it doesn't.
+ */
+ string projectName = Assembly.GetCallingAssembly().GetName().Name!;
+ string dir = Path.GetFullPath(Environment.CurrentDirectory);
+ for (int i = 0; i < 10; i++) {
+ if (dir.EndsWith(projectName, StringComparison.OrdinalIgnoreCase)) {
+ _projectDir = dir;
+ return _projectDir;
+ }
+ dir = Directory.GetParent(dir)!.FullName;
+ }
+ throw new DirectoryNotFoundException($"Could not find directory '{projectName}'");
+ }
+ }
[OneTimeSetUp]
diff --git a/publish-linux.sh b/publish-linux.sh
new file mode 100644
index 0000000..5b6be3f
--- /dev/null
+++ b/publish-linux.sh
@@ -0,0 +1 @@
+dotnet publish ConsoleApp --runtime=linux-x64 --framework=net7.0 -p:PublishSingleFile=true --self-contained=true --configuration=Release
\ No newline at end of file