| File: RuntimeModel\JsonRuntimeFormat.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Packaging\NuGet.Packaging.csproj (NuGet.Packaging) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.IO; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NuGet.Frameworks; using NuGet.Versioning; namespace NuGet.RuntimeModel { public static class JsonRuntimeFormat { public static RuntimeGraph ReadRuntimeGraph(string filePath) { using (var fileStream = File.OpenRead(filePath)) { return ReadRuntimeGraph(fileStream); } } public static RuntimeGraph ReadRuntimeGraph(Stream stream) { using (var streamReader = new StreamReader(stream)) { return ReadRuntimeGraph(streamReader); } } public static RuntimeGraph ReadRuntimeGraph(TextReader textReader) { var loadSettings = new JsonLoadSettings() { LineInfoHandling = LineInfoHandling.Ignore, CommentHandling = CommentHandling.Ignore }; using (var jsonReader = new JsonTextReader(textReader)) { return ReadRuntimeGraph(JToken.Load(jsonReader, loadSettings)); } } public static void WriteRuntimeGraph(string filePath, RuntimeGraph runtimeGraph) { using (var fileStream = new FileStream(filePath, FileMode.Create)) using (var textWriter = new StreamWriter(fileStream)) using (var jsonWriter = new JsonTextWriter(textWriter)) using (var writer = new JsonObjectWriter(jsonWriter)) { jsonWriter.Formatting = Formatting.Indented; jsonWriter.WriteStartObject(); WriteRuntimeGraph(writer, runtimeGraph); jsonWriter.WriteEndObject(); } } public static RuntimeGraph ReadRuntimeGraph(JToken json) { return new RuntimeGraph( EachProperty(json["runtimes"]).Select(ReadRuntimeDescription), EachProperty(json["supports"]).Select(ReadCompatibilityProfile)); } public static void WriteRuntimeGraph(IObjectWriter writer, RuntimeGraph runtimeGraph) { if (runtimeGraph != null) { if (runtimeGraph.Runtimes.Any() == true) { writer.WriteObjectStart("runtimes"); IOrderedEnumerable<RuntimeDescription> sortedRuntimes = runtimeGraph.Runtimes.Values .OrderBy(runtime => runtime.RuntimeIdentifier, StringComparer.Ordinal); foreach (RuntimeDescription runtime in sortedRuntimes) { WriteRuntimeDescription(writer, runtime); } writer.WriteObjectEnd(); } if (runtimeGraph.Supports.Any() == true) { writer.WriteObjectStart("supports"); IOrderedEnumerable<CompatibilityProfile> sortedSupports = runtimeGraph.Supports.Values .OrderBy(runtime => runtime.Name, StringComparer.Ordinal); foreach (CompatibilityProfile support in sortedSupports) { WriteCompatibilityProfile(writer, support); } writer.WriteObjectEnd(); } } } private static void WriteRuntimeDescription(IObjectWriter writer, RuntimeDescription data) { writer.WriteObjectStart(data.RuntimeIdentifier); writer.WriteNameArray("#import", data.InheritedRuntimes); var sortedDependencySets = data.RuntimeDependencySets .OrderBy(pair => pair.Key, StringComparer.Ordinal) .Select(pair => pair.Value); foreach (var set in sortedDependencySets) { WriteRuntimeDependencySet(writer, set); } writer.WriteObjectEnd(); } private static void WriteRuntimeDependencySet(IObjectWriter writer, RuntimeDependencySet data) { writer.WriteObjectStart(data.Id); var sortedDependencies = data.Dependencies .OrderBy(pair => pair.Key, StringComparer.Ordinal) .Select(pair => pair.Value); foreach (var dependency in sortedDependencies) { WritePackageDependency(writer, dependency); } writer.WriteObjectEnd(); } private static void WritePackageDependency(IObjectWriter writer, RuntimePackageDependency data) { writer.WriteNameValue(data.Id, data.VersionRange.ToNormalizedString()); } private static void WriteCompatibilityProfile(IObjectWriter writer, CompatibilityProfile data) { writer.WriteObjectStart(data.Name); var frameworkGroups = data.RestoreContexts.GroupBy(context => context.Framework); foreach (var frameworkGroup in frameworkGroups) { var name = frameworkGroup.Key.GetShortFolderName(); var runtimes = frameworkGroup.ToList(); if (runtimes.Count == 1) { // Write a string writer.WriteNameValue(name, runtimes[0].RuntimeIdentifier); } else if (runtimes.Count > 0) { writer.WriteNameArray(name, runtimes.Select(rt => rt.RuntimeIdentifier)); } } writer.WriteObjectEnd(); } private static CompatibilityProfile ReadCompatibilityProfile(KeyValuePair<string, JToken> json) { var name = json.Key; var sets = new List<FrameworkRuntimePair>(); foreach (var property in EachProperty(json.Value)) { var profiles = ReadCompatibilitySets(property); sets.AddRange(profiles); } return new CompatibilityProfile(name, sets); } private static IEnumerable<FrameworkRuntimePair> ReadCompatibilitySets(KeyValuePair<string, JToken> property) { var framework = NuGetFramework.Parse(property.Key); switch (property.Value.Type) { case JTokenType.Array: foreach (var value in (JArray)property.Value) { yield return new FrameworkRuntimePair(framework, value.Value<string>()); } break; case JTokenType.String: yield return new FrameworkRuntimePair(framework, property.Value.ToString()); break; // Other token types are not supported } } private static RuntimeDescription ReadRuntimeDescription(KeyValuePair<string, JToken> json) { var name = json.Key; List<string>? inheritedRuntimes = null; List<RuntimeDependencySet>? additionalDependencies = null; foreach (var property in EachProperty(json.Value)) { if (property.Key == "#import") { var imports = (JArray)property.Value; foreach (var import in imports) { inheritedRuntimes ??= new List<string>(imports.Count); inheritedRuntimes.Add(import.Value<string>()!); } } else { var dependency = ReadRuntimeDependencySet(property); additionalDependencies ??= new(); additionalDependencies.Add(dependency); } } return new RuntimeDescription(name, inheritedRuntimes, additionalDependencies); } private static RuntimeDependencySet ReadRuntimeDependencySet(KeyValuePair<string, JToken> json) { return new RuntimeDependencySet( json.Key, EachProperty(json.Value).Select(ReadRuntimePackageDependency)); } private static RuntimePackageDependency ReadRuntimePackageDependency(KeyValuePair<string, JToken> json) { return new RuntimePackageDependency(json.Key, VersionRange.Parse(json.Value.Value<string>()!)); } private static IEnumerable<KeyValuePair<string, JToken>> EachProperty(JToken? json) { return (json as IEnumerable<KeyValuePair<string, JToken>>) ?? Enumerable.Empty<KeyValuePair<string, JToken>>(); } } }