Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/DiffEngine.Tests/BundledViewerRidTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#if NET10_0
/// <summary>
/// Which RIDs the bundled viewer is probed for.
/// <para>
/// The framework's own RID comes first, and on Alpine that is linux-musl-x64, which the package
/// does not ship - so the probe is supposed to miss and the caller falls through to the dotnet
/// tool. The synthesised linux-{arch} that followed it undid that, because it names the glibc
/// build, and resolving one against musl hands back an apphost that cannot start.
/// </para>
/// </summary>
public class BundledViewerRidTests
{
[Test]
[Arguments("linux-musl-x64")]
[Arguments("linux-musl-arm64")]
public async Task MuslProbesItsOwnRidAndNothingElse(string runtimeIdentifier)
{
var rids = BundledViewerDirectory.Rids(runtimeIdentifier).ToList();

await Assert.That(rids).IsEquivalentTo([runtimeIdentifier]);
}

/// <summary>
/// Everywhere else the synthesised RID still follows, which is what makes the probe work when
/// the framework reports something the package does not ship under that exact name.
/// </summary>
[Test]
public async Task GlibcStillFallsBackToTheSynthesisedRid()
{
var rids = BundledViewerDirectory.Rids("linux-x64").ToList();

await Assert.That(rids.Count).IsGreaterThan(1);
await Assert.That(rids[0]).IsEqualTo("linux-x64");
}
}
#endif
23 changes: 20 additions & 3 deletions src/DiffEngine/Viewer/BundledViewerDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,30 @@ static class BundledViewerDirectory
}
#endif

static IEnumerable<string> Rids()
{
static IEnumerable<string> Rids() =>
#if NET6_0_OR_GREATER
Rids(RuntimeInformation.RuntimeIdentifier);

internal static IEnumerable<string> Rids(string runtimeIdentifier)
{
// The framework's own value first. On Alpine that is linux-musl-x64, a RID we do not
// ship, so the probe misses and the caller falls through to the dotnet tool rather than
// resolving a glibc build against musl.
yield return RuntimeInformation.RuntimeIdentifier;
yield return runtimeIdentifier;

// And nothing else, or the synthesised RID below undoes that: linux-{arch} is the glibc
// build, so on musl the probe would hit after all and hand back an apphost that cannot
// start. Falling through to the dotnet tool is the outcome the comment above describes and
// was not what happened
if (runtimeIdentifier.Contains("-musl-", StringComparison.Ordinal))
{
yield break;
}
#else
InnerRids();

static IEnumerable<string> InnerRids()
{
#endif

var architecture = RuntimeInformation.OSArchitecture switch
Expand Down
Loading