| File: ProductRelease.cs | Web Access |
| Project: src\deployment-tools\src\Microsoft.Deployment.DotNet.Releases\src\Microsoft.Deployment.DotNet.Releases.csproj (Microsoft.Deployment.DotNet.Releases) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Text.Json; namespace Microsoft.Deployment.DotNet.Releases { /// <summary> /// Describes a single .NET <see cref="ProductRelease"/>. A release may include multiple SDKs and runtime releases. /// </summary> [DebuggerDisplay("{DebuggerDisplay,nq}")] public class ProductRelease { private string DebuggerDisplay => $"Release {Version} (SDKs: {Sdks.Count}, Runtimes: {Runtimes.Count})"; /// <summary> /// The ASP.NET Core runtime included in this release, or <see langword="null"/> if the component is absent."/> /// </summary> public AspNetCoreReleaseComponent AspNetCoreRuntime { get; } /// <summary> /// Gets a collection of all the release components (SDKs and runtimes) in the release. /// </summary> public ReadOnlyCollection<ReleaseComponent> Components { get; } /// <summary> /// The collection of CVEs addressed by this release. The collection may be empty if no CVEs are associated with /// it, typically when the release does not contain any security fixes. /// </summary> public ReadOnlyCollection<Cve> Cves { get; } /// <summary> /// Gets all files from all the release components (SDKs and runtimes) associated with this <see cref="ProductRelease"/>. /// </summary> public ReadOnlyCollection<ReleaseFile> Files { get; } /// <summary> /// <see langword="true"/> if the release version describes a prerelease; <see langword="false"/> otherwise. /// </summary> public bool IsPreview => !string.IsNullOrWhiteSpace(Version.Prerelease); /// <summary> /// <see langword="true"/> if the release includes security fixes; otherwise <see langword="false"/>. /// </summary> public bool IsSecurityUpdate { get; } /// <summary> /// The <see cref="Product"/> to which this <see cref="ProductRelease"/> belongs. /// </summary> public Product Product { get; } /// <summary> /// The date this <see cref="ProductRelease"/> was published. /// </summary> public DateTime ReleaseDate { get; } /// <summary> /// A <see cref="Uri"/> pointing to the release notes of this <see cref="ProductRelease"/>. /// </summary> public Uri ReleaseNotes { get; } /// <summary> /// The .NET runtime included with this <see cref="ProductRelease"/>. /// </summary> public RuntimeReleaseComponent Runtime { get; } /// <summary> /// A collection of all the runtime components (.NET, ASP.NET Core, Windows Desktop, etc.) included in this <see cref="ProductRelease"/>. /// </summary> public ReadOnlyCollection<ReleaseComponent> Runtimes { get; } /// <summary> /// All SDKs included in this release. /// </summary> public ReadOnlyCollection<SdkReleaseComponent> Sdks { get; } /// <summary> /// The version of this <see cref="ProductRelease"/>. /// </summary> public ReleaseVersion Version { get; } /// <summary> /// The Windows desktop runtime associated with this release or <see langword="null"/> if the component is absent. /// </summary> public WindowsDesktopReleaseComponent WindowsDesktopRuntime { get; } /// <summary> /// Creates a new <see cref="ProductRelease"/> instance. /// </summary> /// <param name="element">The JSON element of the release.</param> /// <param name="product">The product to which the release belongs.</param> internal ProductRelease(JsonElement element, Product product) { ReleaseDate = element.GetProperty("release-date").GetDateTime(); Version = element.GetReleaseVersionOrDefault("release-version"); IsSecurityUpdate = element.GetProperty("security").GetBoolean(); ReleaseNotes = element.GetUriOrDefault("release-notes"); Product = product; var cves = new List<Cve>(); if (element.TryGetProperty("cve-list", out JsonElement cveListElement) && cveListElement.ValueKind == JsonValueKind.Array) { var enumerator = cveListElement.EnumerateArray(); while (enumerator.MoveNext()) { cves.Add(new(enumerator.Current)); } } Cves = new ReadOnlyCollection<Cve>(cves); var runtimes = new List<ReleaseComponent>(); if (element.TryGetProperty("aspnetcore-runtime", out JsonElement aspNetCoreValue) && aspNetCoreValue.ValueKind != JsonValueKind.Null) { AspNetCoreRuntime = new AspNetCoreReleaseComponent(aspNetCoreValue, this); runtimes.Add(AspNetCoreRuntime); } if (element.TryGetProperty("runtime", out JsonElement runtimeValue) && runtimeValue.ValueKind != JsonValueKind.Null) { Runtime = new RuntimeReleaseComponent(runtimeValue, this); runtimes.Add(Runtime); } if (element.TryGetProperty("windowsdesktop", out JsonElement desktopValue) && desktopValue.ValueKind != JsonValueKind.Null) { WindowsDesktopRuntime = new WindowsDesktopReleaseComponent(desktopValue, this); runtimes.Add(WindowsDesktopRuntime); } Runtimes = new ReadOnlyCollection<ReleaseComponent>(runtimes); var sdks = new List<SdkReleaseComponent>(); if (element.TryGetProperty("sdks", out JsonElement sdksValue) && sdksValue.ValueKind == JsonValueKind.Array) { var enumerator = sdksValue.EnumerateArray(); while (enumerator.MoveNext()) { sdks.Add(new SdkReleaseComponent(enumerator.Current, this)); } } else if (element.TryGetProperty("sdk", out JsonElement sdkValue) && sdkValue.ValueKind != JsonValueKind.Null) { sdks.Add(new SdkReleaseComponent(sdkValue, this)); } Sdks = new ReadOnlyCollection<SdkReleaseComponent>(sdks); var components = new List<ReleaseComponent>(); components.AddRange(runtimes); components.AddRange(sdks); Components = new ReadOnlyCollection<ReleaseComponent>(components); // Distinct is necessary because some releases have overlapping files. Files = new ReadOnlyCollection<ReleaseFile>( Components.SelectMany(c => c.Files).Distinct().ToList()); } } }