Created
May 21, 2018 21:14
-
-
Save abock/eb676f07b344234f280ccb6adf5a19af to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) Microsoft Corporation. All rights reserved. | |
// Licensed under the MIT License. | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
using System.Threading; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
namespace Xamarin.Interactive | |
{ | |
static class RuntimeIdentifier | |
{ | |
public static string CurrentProcessRid { get; } | |
static RuntimeIdentifier () | |
{ | |
string rid; | |
if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) | |
rid = "win-"; | |
else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) | |
rid = "osx-"; | |
else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) | |
rid = "linux-"; | |
else | |
rid = "any-"; | |
CurrentProcessRid = rid + RuntimeInformation | |
.ProcessArchitecture | |
.ToString () | |
.ToLowerInvariant (); | |
} | |
static Lazy<IReadOnlyDictionary<string, IReadOnlyList<string>>> allRids | |
= new Lazy<IReadOnlyDictionary<string, IReadOnlyList<string>>> (() => { | |
var rids = new Dictionary<string, IReadOnlyList<string>> (); | |
using (var stream = typeof (RuntimeIdentifier) | |
.Assembly | |
.GetManifestResourceStream ("netcore-rids.json")) | |
using (var streamReader = new StreamReader (stream)) | |
using (var jsonReader = new JsonTextReader (streamReader)) { | |
var root = JObject.Load (jsonReader); | |
if (root ["runtimes"] is JObject runtimes) { | |
foreach (var rid in runtimes) { | |
List<string> imports = null; | |
if (rid.Value is JObject ridObject && | |
ridObject ["#import"] is JArray importsArray) { | |
imports = importsArray.ToObject<List<string>> (); | |
} | |
rids [rid.Key] = imports; | |
} | |
} | |
} | |
return rids; | |
}); | |
static readonly ReaderWriterLockSlim expansionCacheLock | |
= new ReaderWriterLockSlim (); | |
static readonly Dictionary<string, List<string>> expansionCache | |
= new Dictionary<string, List<string>> (); | |
public static IReadOnlyList<string> Expand (string rid) | |
{ | |
expansionCacheLock.EnterUpgradeableReadLock (); | |
try { | |
if (!expansionCache.TryGetValue (rid, out var expandedRids)) { | |
expansionCacheLock.EnterWriteLock (); | |
try { | |
var ridEnum = CoreExpand (rid); | |
expandedRids = new List<string> (ridEnum); | |
expansionCache [rid] = expandedRids; | |
} finally { | |
expansionCacheLock.ExitWriteLock (); | |
} | |
} | |
return expandedRids; | |
} finally { | |
expansionCacheLock.ExitUpgradeableReadLock (); | |
} | |
} | |
static IEnumerable<string> CoreExpand (string rid) | |
{ | |
yield return rid; | |
var visitedRids = new HashSet<string> (); | |
var expandedRids = new List<string> (); | |
visitedRids.Add (rid); | |
expandedRids.Add (rid); | |
for (var i = 0; i < expandedRids.Count; i++) { | |
if (allRids.Value.TryGetValue (expandedRids [i], out var imports) && imports != null) { | |
foreach (var importedRid in imports) { | |
if (visitedRids.Add (importedRid)) { | |
yield return importedRid; | |
expandedRids.Add (importedRid); | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) Microsoft Corporation. All rights reserved. | |
// Licensed under the MIT License. | |
using System; | |
using System.Collections.Generic; | |
using Xunit; | |
namespace Xamarin.Interactive | |
{ | |
public class RuntimeIdentifierTests | |
{ | |
[Theory] | |
[MemberData (nameof (GetTestCases))] | |
public void Expand (string [] expectedExpansion) | |
=> Assert.Equal (expectedExpansion, RuntimeIdentifier.Expand (expectedExpansion [0])); | |
// sampling of https://raw.githubusercontent.com/dotnet/corefx/master/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json | |
public static IEnumerable<object []> GetTestCases () | |
{ | |
yield return new [] { | |
new [] { | |
"osx.10.12-x64", | |
"osx.10.12", | |
"osx.10.11-x64", | |
"osx.10.11", | |
"osx.10.10-x64", | |
"osx.10.10", | |
"osx-x64", | |
"osx", | |
"unix-x64", | |
"unix", | |
"any", | |
"base" | |
} | |
}; | |
yield return new [] { | |
new [] { | |
"win7-x64", | |
"win7", | |
"win-x64", | |
"win", | |
"any", | |
"base" | |
} | |
}; | |
yield return new [] { | |
new [] { | |
"fedora.26-x64", | |
"fedora.26", | |
"fedora-x64", | |
"fedora", | |
"linux-x64", | |
"linux", | |
"unix-x64", | |
"unix", | |
"any", | |
"base" | |
} | |
}; | |
yield return new [] { | |
new [] { | |
"linux", | |
"unix", | |
"any", | |
"base" | |
} | |
}; | |
yield return new [] { | |
new [] { | |
"osx", | |
"unix", | |
"any", | |
"base" | |
} | |
}; | |
yield return new [] { | |
new [] { | |
"any", | |
"base" | |
} | |
}; | |
yield return new [] { | |
new [] { | |
"base" | |
} | |
}; | |
yield return new [] { | |
new [] { | |
"unknown-rid" | |
} | |
}; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment