Пример #1
0
        /// <summary>
        /// Validates that the compatible frameworks have compatible surface area.
        /// </summary>
        /// <param name="package">Nuget Package that needs to be validated.</param>
        public void Validate(PackageValidatorOption option)
        {
            ApiCompatRunner apiCompatRunner = new(_log,
                                                  option.EnableStrictMode,
                                                  option.FrameworkReferences,
                                                  option.Package.PackagePath);

            ManagedCodeConventions conventions = new(null);
            PatternSet             patternSet  = option.Package.RefAssets.Any() ?
                                                 conventions.Patterns.CompileRefAssemblies :
                                                 conventions.Patterns.CompileLibAssemblies;

            IEnumerable <ContentItem> compileAssets      = option.Package.CompileAssets.OrderByDescending(t => ((NuGetFramework)t.Properties["tfm"]).Version);
            Queue <ContentItem>       compileAssetsQueue = new(compileAssets);

            while (compileAssetsQueue.Count > 0)
            {
                ContentItem compileTimeAsset = compileAssetsQueue.Dequeue();
                // If no assets are available for comparison, stop the iteration.
                if (compileAssetsQueue.Count == 0)
                {
                    break;
                }

                // The runtime graph doesn't need to be passed in to the collection as compile time assets can't be rid specific.
                ContentItemCollection contentItemCollection = new();
                // The collection won't contain the current compile time asset as it is already dequeued.
                contentItemCollection.Load(compileAssetsQueue.Select(t => t.Path));
                NuGetFramework    framework       = (NuGetFramework)compileTimeAsset.Properties["tfm"];
                SelectionCriteria managedCriteria = conventions.Criteria.ForFramework(framework);

                // Searches for a compatible compile time asset and compares it.
                ContentItem?compatibleFrameworkAsset = contentItemCollection.FindBestItemGroup(managedCriteria, patternSet)?.Items.FirstOrDefault();
                if (compatibleFrameworkAsset != null)
                {
                    string header = string.Format(Resources.ApiCompatibilityHeader, compatibleFrameworkAsset.Path, compileTimeAsset.Path);
                    apiCompatRunner.QueueApiCompatFromContentItem(option.Package.PackageId, compatibleFrameworkAsset, compileTimeAsset, header);
                }
            }

            apiCompatRunner.RunApiCompat();
        }
Пример #2
0
        /// <summary>
        /// Validates that there are compile time and runtime assets for all the compatible frameworks.
        /// Validates that the surface between compile time and runtime assets is compatible.
        /// </summary>
        /// <param name="package">Nuget Package that needs to be validated.</param>
        public void Validate(PackageValidatorOption option)
        {
            ApiCompatRunner apiCompatRunner = new(_log,
                                                  option.EnableStrictMode,
                                                  option.FrameworkReferences,
                                                  option.Package.PackagePath);

            HashSet <NuGetFramework> compatibleTargetFrameworks = new();

            foreach (NuGetFramework item in option.Package.FrameworksInPackage)
            {
                compatibleTargetFrameworks.Add(item);
                if (s_packageTfmMapping.ContainsKey(item))
                {
                    compatibleTargetFrameworks.UnionWith(s_packageTfmMapping[item]);
                }
            }

            foreach (NuGetFramework framework in compatibleTargetFrameworks)
            {
                ContentItem?compileTimeAsset = option.Package.FindBestCompileAssetForFramework(framework);
                if (compileTimeAsset == null)
                {
                    _log.LogError(
                        new Suppression(DiagnosticIds.ApplicableCompileTimeAsset)
                    {
                        Target = framework.ToString()
                    },
                        DiagnosticIds.ApplicableCompileTimeAsset,
                        Resources.NoCompatibleCompileTimeAsset,
                        framework.ToString());
                    break;
                }

                ContentItem?runtimeAsset = option.Package.FindBestRuntimeAssetForFramework(framework);
                if (runtimeAsset == null)
                {
                    _log.LogError(
                        new Suppression(DiagnosticIds.CompatibleRuntimeRidLessAsset)
                    {
                        Target = framework.ToString()
                    },
                        DiagnosticIds.CompatibleRuntimeRidLessAsset,
                        Resources.NoCompatibleRuntimeAsset,
                        framework.ToString());
                }
                // Invoke ApiCompat to compare the compile time asset with the runtime asset if they are not the same assembly.
                else if (option.RunApiCompat && compileTimeAsset.Path != runtimeAsset.Path)
                {
                    string header = string.Format(Resources.ApiCompatibilityHeader, compileTimeAsset.Path, runtimeAsset.Path);
                    apiCompatRunner.QueueApiCompatFromContentItem(option.Package.PackageId, compileTimeAsset, runtimeAsset, header);
                }

                foreach (string rid in option.Package.Rids.Where(t => IsSupportedRidTargetFrameworkPair(framework, t)))
                {
                    ContentItem?runtimeRidSpecificAsset = option.Package.FindBestRuntimeAssetForFrameworkAndRuntime(framework, rid);
                    if (runtimeRidSpecificAsset == null)
                    {
                        _log.LogError(
                            new Suppression(DiagnosticIds.CompatibleRuntimeRidSpecificAsset)
                        {
                            Target = framework.ToString() + "-" + rid
                        },
                            DiagnosticIds.CompatibleRuntimeRidSpecificAsset,
                            Resources.NoCompatibleRidSpecificRuntimeAsset,
                            framework.ToString(),
                            rid);
                    }
                    // Invoke ApiCompat to compare the compile time asset with the runtime specific asset if they are not the same and
                    // if the comparison hasn't already happened (when the runtime asset is the same as the runtime specific asset).
                    else if (option.RunApiCompat &&
                             compileTimeAsset.Path != runtimeRidSpecificAsset.Path &&
                             (runtimeAsset == null || runtimeAsset.Path != runtimeRidSpecificAsset.Path))
                    {
                        string header = string.Format(Resources.ApiCompatibilityHeader, compileTimeAsset.Path, runtimeRidSpecificAsset.Path);
                        apiCompatRunner.QueueApiCompatFromContentItem(option.Package.PackageId, compileTimeAsset, runtimeRidSpecificAsset, header);
                    }
                }
            }

            if (option.RunApiCompat)
            {
                apiCompatRunner.RunApiCompat();
            }
        }
Пример #3
0
        /// <summary>
        /// Validates the latest nuget package doesnot drop any target framework/rid and does not introduce any breaking changes.
        /// </summary>
        /// <param name="package">Nuget Package that needs to be validated.</param>
        public void Validate(PackageValidatorOption option)
        {
            if (option.BaselinePackage is null)
            {
                throw new ArgumentNullException(nameof(option.BaselinePackage));
            }

            ApiCompatRunner apiCompatRunner = new(_log,
                                                  option.EnableStrictMode,
                                                  option.FrameworkReferences,
                                                  option.BaselinePackage.PackagePath,
                                                  option.Package.PackagePath);

            // Iterate over all available baseline assets
            foreach (ContentItem baselineCompileTimeAsset in option.BaselinePackage.RefAssets)
            {
                // Search for a compatible compile time asset in the latest package
                NuGetFramework baselineTargetFramework = (NuGetFramework)baselineCompileTimeAsset.Properties["tfm"];
                ContentItem?   latestCompileTimeAsset  = option.Package.FindBestCompileAssetForFramework(baselineTargetFramework);
                if (latestCompileTimeAsset == null)
                {
                    _log.LogError(
                        new Suppression(DiagnosticIds.TargetFrameworkDropped)
                    {
                        Target = baselineTargetFramework.ToString()
                    },
                        DiagnosticIds.TargetFrameworkDropped,
                        Resources.MissingTargetFramework,
                        baselineTargetFramework.ToString());
                }
                else if (option.RunApiCompat)
                {
                    string header = string.Format(Resources.ApiCompatibilityBaselineHeader, baselineCompileTimeAsset.Path, latestCompileTimeAsset.Path, option.BaselinePackage.Version, option.Package.Version);
                    apiCompatRunner.QueueApiCompatFromContentItem(option.Package.PackageId, baselineCompileTimeAsset, latestCompileTimeAsset, header, isBaseline: true);
                }
            }

            // Iterates over both runtime and runtime specific baseline assets and searches for a compatible non runtime
            // specific asset in the latest package.
            foreach (ContentItem baselineRuntimeAsset in option.BaselinePackage.RuntimeAssets)
            {
                // Search for a compatible runtime asset in the latest package
                NuGetFramework baselineTargetFramework = (NuGetFramework)baselineRuntimeAsset.Properties["tfm"];
                ContentItem?   latestRuntimeAsset      = option.Package.FindBestRuntimeAssetForFramework(baselineTargetFramework);
                if (latestRuntimeAsset == null)
                {
                    _log.LogError(
                        new Suppression(DiagnosticIds.TargetFrameworkDropped)
                    {
                        Target = baselineTargetFramework.ToString()
                    },
                        DiagnosticIds.TargetFrameworkDropped,
                        Resources.MissingTargetFramework,
                        baselineTargetFramework.ToString());
                }
                else if (option.RunApiCompat)
                {
                    string header = string.Format(Resources.ApiCompatibilityBaselineHeader, baselineRuntimeAsset.Path, latestRuntimeAsset.Path, option.BaselinePackage.Version, option.Package.Version);
                    apiCompatRunner.QueueApiCompatFromContentItem(option.Package.PackageId, baselineRuntimeAsset, latestRuntimeAsset, header, isBaseline: true);
                }
            }

            // Compares runtime specific baseline assets against runtime specific latest assets.
            foreach (ContentItem baselineRuntimeSpecificAsset in option.BaselinePackage.RuntimeSpecificAssets)
            {
                NuGetFramework baselineTargetFramework    = (NuGetFramework)baselineRuntimeSpecificAsset.Properties["tfm"];
                string         baselineRid                = (string)baselineRuntimeSpecificAsset.Properties["rid"];
                ContentItem?   latestRuntimeSpecificAsset = option.Package.FindBestRuntimeAssetForFrameworkAndRuntime(baselineTargetFramework, baselineRid);
                if (latestRuntimeSpecificAsset == null)
                {
                    _log.LogError(
                        new Suppression(DiagnosticIds.TargetFrameworkAndRidPairDropped)
                    {
                        Target = baselineTargetFramework.ToString() + "-" + baselineRid
                    },
                        DiagnosticIds.TargetFrameworkAndRidPairDropped,
                        Resources.MissingTargetFrameworkAndRid,
                        baselineTargetFramework.ToString(),
                        baselineRid);
                }
                else if (option.RunApiCompat)
                {
                    string header = string.Format(Resources.ApiCompatibilityBaselineHeader, baselineRuntimeSpecificAsset.Path, latestRuntimeSpecificAsset.Path, option.BaselinePackage.Version, option.Package.Version);
                    apiCompatRunner.QueueApiCompatFromContentItem(option.Package.PackageId, baselineRuntimeSpecificAsset, latestRuntimeSpecificAsset, header, isBaseline: true);
                }
            }

            if (option.RunApiCompat)
            {
                apiCompatRunner.RunApiCompat();
            }
        }