diff --git a/src/Tests/NativePackerTests.cs b/src/Tests/NativePackerTests.cs index 16caddb..d9852f3 100644 --- a/src/Tests/NativePackerTests.cs +++ b/src/Tests/NativePackerTests.cs @@ -84,6 +84,34 @@ public void Program_main_packs_through_the_shipped_entry_point() Assert.StartsWith(expected, File.ReadAllText(sha).Trim(), StringComparison.OrdinalIgnoreCase); } + [Fact] + public void Osx_rid_ignores_dsym_dwarf_also_named_ndx() + { + using var dir = new TempDir(); + var payload = "osx-native-bytes"u8.ToArray(); + var nupkg = RidNupkg.Write(dir.Nupkg, "osx-arm64", payload); + + using (var zip = ZipFile.OpenRead(nupkg)) + { + var namedNdx = zip.Entries + .Where(entry => Path.GetFileName(entry.FullName) == "ndx") + .Select(entry => entry.FullName.Replace('\\', '/')) + .ToArray(); + Assert.Contains("tools/any/osx-arm64/ndx", namedNdx); + Assert.Contains("tools/any/osx-arm64/ndx.dSYM/Contents/Resources/DWARF/ndx", namedNdx); + } + + var result = NativePacker.Pack(nupkg, "osx-arm64", dir.Output, "1.0.0"); + using var file = File.OpenRead(result.ArchivePath); + using var gzip = new GZipStream(file, CompressionMode.Decompress); + using var tar = new TarReader(gzip); + var entry = tar.GetNextEntry(copyData: true); + Assert.NotNull(entry); + using var memory = new MemoryStream(); + entry.DataStream!.CopyTo(memory); + Assert.Equal(payload, memory.ToArray()); + } + [Fact] public void Missing_binary_is_a_packer_error() { diff --git a/src/Tests/RidNupkg.cs b/src/Tests/RidNupkg.cs index f44321f..21ca0c9 100644 --- a/src/Tests/RidNupkg.cs +++ b/src/Tests/RidNupkg.cs @@ -22,6 +22,13 @@ public static string Write(string directory, string rid, byte[] payload) WriteEntry(zip, $"tools/any/{rid}/DotnetToolSettings.xml", """"""u8.ToArray()); WriteEntry(zip, $"tools/any/{rid}/{Path.GetFileNameWithoutExtension(binary)}.pdb", "pdb"u8.ToArray()); + if (rid.StartsWith("osx", StringComparison.OrdinalIgnoreCase)) + { + WriteEntry( + zip, + $"tools/any/{rid}/{binary}.dSYM/Contents/Resources/DWARF/{binary}", + "dwarf-debug-bytes"u8.ToArray()); + } WriteEntry(zip, "readme.md", "# ndx"u8.ToArray()); return path; } diff --git a/src/nativepack/NativePacker.cs b/src/nativepack/NativePacker.cs index 8025258..201c19d 100644 --- a/src/nativepack/NativePacker.cs +++ b/src/nativepack/NativePacker.cs @@ -33,7 +33,7 @@ public static NativePackResult Pack( ArgumentException.ThrowIfNullOrWhiteSpace(version); var binaryName = BinaryFileName(rid); - var payload = ReadNativeBinary(nupkgPath, binaryName); + var payload = ReadNativeBinary(nupkgPath, rid, binaryName); Directory.CreateDirectory(outputDirectory); @@ -55,7 +55,7 @@ public static NativePackResult Pack( return new NativePackResult(archivePath, sha256Path, sha256, binaryName); } - static byte[] ReadNativeBinary(string nupkgPath, string binaryName) + static byte[] ReadNativeBinary(string nupkgPath, string rid, string binaryName) { if (!File.Exists(nupkgPath)) { @@ -66,9 +66,7 @@ static byte[] ReadNativeBinary(string nupkgPath, string binaryName) using var zip = ZipFile.OpenRead(nupkgPath); var matches = zip.Entries - .Where(entry => - entry.Length > 0 && - string.Equals(Path.GetFileName(entry.FullName), binaryName, StringComparison.OrdinalIgnoreCase)) + .Where(entry => IsNativeBinaryEntry(entry, binaryName)) .ToArray(); if (matches.Length == 0) @@ -78,18 +76,44 @@ static byte[] ReadNativeBinary(string nupkgPath, string binaryName) binaryName); } - if (matches.Length > 1) + var preferred = "tools/any/" + rid + "/" + binaryName; + var chosen = matches.FirstOrDefault(entry => + PathsEqual(entry.FullName, preferred)) + ?? (matches.Length == 1 ? matches[0] : null); + + if (chosen is null) { throw new InvalidOperationException( $"Multiple '{binaryName}' entries in '{nupkgPath}'."); } - using var stream = matches[0].Open(); + using var stream = chosen.Open(); using var memory = new MemoryStream(); stream.CopyTo(memory); return memory.ToArray(); } + static bool IsNativeBinaryEntry(ZipArchiveEntry entry, string binaryName) + { + if (entry.Length <= 0) + return false; + + var path = entry.FullName.Replace('\\', '/'); + if (path.Contains(".dSYM/", StringComparison.OrdinalIgnoreCase) || + path.EndsWith(".dSYM", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + return string.Equals(Path.GetFileName(path), binaryName, StringComparison.OrdinalIgnoreCase); + } + + static bool PathsEqual(string left, string right) + => string.Equals( + left.Replace('\\', '/').TrimStart('/'), + right.Replace('\\', '/').TrimStart('/'), + StringComparison.OrdinalIgnoreCase); + static void PackZip(byte[] payload, string binaryName, string archivePath) { using var zip = ZipFile.Open(archivePath, ZipArchiveMode.Create);