File: ValidateFrameworkPackage.cs
Web Access
Project: src\src\Microsoft.DotNet.Build.Tasks.Packaging\src\Microsoft.DotNet.Build.Tasks.Packaging.csproj (Microsoft.DotNet.Build.Tasks.Packaging)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NuGet.Frameworks;
using NuGet.Versioning;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using PropertyNames = NuGet.Client.ManagedCodeConventions.PropertyNames;
 
namespace Microsoft.DotNet.Build.Tasks.Packaging
{
    public class ValidateFrameworkPackage : ValidationTask
    {
        [Required]
        public string Framework
        {
            get;
            set;
        }
        
        public string Runtime
        {
            get;
            set;
        }
 
        public override bool Execute()
        {
            InitializeValidationTask();
 
            var fx = NuGetFramework.Parse(Framework);
 
            var testAssets = GetTestAssets(fx, Runtime);
            var testAssetsByName = testAssets.Where(a => Path.GetExtension(a.PackagePath) == ".dll")
                                             .ToDictionary(a => Path.GetFileNameWithoutExtension(a.PackagePath), a => a);
 
            var permittedInbox = GetSuppressionValues(Suppression.PermitInbox) ?? new HashSet<string>();
 
            foreach (var testAssetByName in testAssetsByName)
            {
                var name = testAssetByName.Key;
                var testAsset = testAssetByName.Value;
 
                var logMissingInbox = permittedInbox.Contains(name) ? 
                    new Action<string>(s => Log.LogMessage(LogImportance.Low, $"Suppressed: {s}")) :
                    new Action<string>(s => Log.LogError(s));
 
                PackageInfo packageInfo;
                if (!_index.Packages.TryGetValue(name, out packageInfo))
                {
                    logMissingInbox($"File {name} was included framework package {_report.Id}/{_report.Version} but that file is missing from package index {string.Join(";", _index.IndexSources)}.  Please add it with appropriate {nameof(PackageInfo.InboxOn)} entry for {Framework} or suppress this message with {nameof(Suppression.PermitInbox)} suppression.");
                    continue;
                }
 
                if (!packageInfo.InboxOn.IsInbox(fx, testAsset.Version))
                {
                    logMissingInbox($"File {name}, version {testAsset.Version} was included framework package {_report.Id}/{_report.Version} but that version is not considered inbox in package index {string.Join(";", _index.IndexSources)}.  Please add it with appropriate {nameof(PackageInfo.InboxOn)} entry for {Framework} or suppress this message with {nameof(Suppression.PermitInbox)} suppression.");
                    continue;
                }
            }
 
            var permittedMissingInbox = GetSuppressionValues(Suppression.PermitMissingInbox) ?? new HashSet<string>();
            
            var missingInboxAssemblies = _index.Packages.Where(packageInfo => packageInfo.Value.InboxOn.IsAnyVersionInbox(fx) && !testAssetsByName.ContainsKey(packageInfo.Key));
 
            foreach(var missingInboxAssembly in missingInboxAssemblies)
            {
                var logMissingPackage = permittedMissingInbox.Contains(missingInboxAssembly.Key) ?
                    new Action<string>(s => Log.LogMessage(LogImportance.Low, $"Suppressed: {s}")) :
                    new Action<string>(s => Log.LogError(s));
 
                logMissingPackage($"File {missingInboxAssembly.Key}.dll is marked as inbox for framework {Framework} but was missing from framework package {_report.Id}/{_report.Version}.  Either add the file or update {nameof(PackageInfo.InboxOn)} entry in {string.Join(";", _index.IndexSources)}.   This may be suppressed with {nameof(Suppression.PermitMissingInbox)} suppression");
            }
            
            return !Log.HasLoggedErrors;
        }
 
        private IEnumerable<PackageAsset> GetTestAssets(NuGetFramework fx, string runtimeId)
        {
 
            var targetKey = string.IsNullOrEmpty(runtimeId) ? fx.ToString() : $"{fx}/{runtimeId}";
 
            Target target = null;
            if (!_report.Targets.TryGetValue(targetKey, out target))
            {
                Log.LogError($"Could not find target {targetKey} in {ReportFile}.");
                return Enumerable.Empty<PackageAsset>();
            }
 
            return string.IsNullOrEmpty(Runtime) ? target.CompileAssets : target.RuntimeAssets;
        }
    }
 
}