diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index edb0731b..39e58ddf 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -15,7 +15,7 @@ env: jobs: build-project: - runs-on: windows-latest + runs-on: ubuntu-latest env: solution_name: ./uSync.slnx @@ -40,4 +40,4 @@ jobs: run: dotnet test ${{ env.solution_name }} - name: Generate AppSettings Schema - run: dotnet run -c ${{env.Config}} --project ${{ env.schema_gen_project}} + run: dotnet run -c ${{ env.config }} --project ${{ env.schema_gen_project}} diff --git a/uSync.Core/Extensions/StringExtensions.cs b/uSync.Core/Extensions/StringExtensions.cs index 5e11f530..e8999d87 100644 --- a/uSync.Core/Extensions/StringExtensions.cs +++ b/uSync.Core/Extensions/StringExtensions.cs @@ -16,14 +16,22 @@ public static class StringExtensions /// /// convert a file name to one that isn't going to cause us any downlevel problems. /// + /// + /// paths aren't always parsed on the OS they came from (e.g. a Windows-style path + /// loaded on Linux), so we split on both separators here rather than using + /// Path.GetFileName/GetDirectoryName, which only recognise the current OS's separator. + /// public static string ToAppSafeFileName(this string value) { - var filename = Path.GetFileName(value); + var separatorIndex = value.LastIndexOfAny(['\\', '/']); + var directory = separatorIndex >= 0 ? value[..(separatorIndex + 1)] : string.Empty; + var filename = separatorIndex >= 0 ? value[(separatorIndex + 1)..] : value; + if (_badNames.InvariantContains(filename)) { - return Path.Combine( - Path.GetDirectoryName(value) ?? string.Empty, - $"__{Path.GetFileNameWithoutExtension(value)}__{Path.GetExtension(value)}"); + var extension = Path.GetExtension(filename); + var nameWithoutExtension = filename[..^extension.Length]; + return $"{directory}__{nameWithoutExtension}__{extension}"; } return value; }