public static LockFileTargetLibrary CreateLockFileTargetLibrary(LockFileLibrary library, IPackage package, RestoreContext context, string correctedPackageName) { var lockFileLib = new LockFileTargetLibrary(); var framework = context.FrameworkName; var runtimeIdentifier = context.RuntimeName; // package.Id is read from nuspec and it might be in wrong casing. // correctedPackageName should be the package name used by dependency graph and // it has the correct casing that runtime needs during dependency resolution. lockFileLib.Name = correctedPackageName ?? package.Id; lockFileLib.Version = package.Version; var files = library.Files.Select(p => p.Replace(Path.DirectorySeparatorChar, '/')); var contentItems = new ContentItemCollection(); contentItems.Load(files); IEnumerable<PackageDependencySet> dependencySet; if (VersionUtility.GetNearest(framework, package.DependencySets, out dependencySet)) { var set = dependencySet.FirstOrDefault()?.Dependencies?.ToList(); if (set != null) { lockFileLib.Dependencies = set; } } // TODO: Remove this when we do #596 // ASP.NET Core and .NET Core 5.0 don't have framework reference assemblies if (!VersionUtility.IsPackageBased(framework)) { IEnumerable<FrameworkAssemblyReference> frameworkAssemblies; if (VersionUtility.GetNearest(framework, package.FrameworkAssemblies, out frameworkAssemblies)) { AddFrameworkReferences(lockFileLib, framework, frameworkAssemblies); } // Add framework assemblies with empty supported frameworks AddFrameworkReferences(lockFileLib, framework, package.FrameworkAssemblies.Where(f => !f.SupportedFrameworks.Any())); } var patterns = PatternDefinitions.DotNetPatterns; var criteriaBuilderWithTfm = new SelectionCriteriaBuilder(patterns.Properties.Definitions); var criteriaBuilderWithoutTfm = new SelectionCriteriaBuilder(patterns.Properties.Definitions); if (context.RuntimeSpecs != null) { foreach (var runtimeSpec in context.RuntimeSpecs) { criteriaBuilderWithTfm = criteriaBuilderWithTfm .Add["tfm", framework]["rid", runtimeSpec.Name]; criteriaBuilderWithoutTfm = criteriaBuilderWithoutTfm .Add["rid", runtimeSpec.Name]; } } criteriaBuilderWithTfm = criteriaBuilderWithTfm .Add["tfm", framework]; var criteria = criteriaBuilderWithTfm.Criteria; var compileGroup = contentItems.FindBestItemGroup(criteria, patterns.CompileTimeAssemblies, patterns.ManagedAssemblies); if (compileGroup != null) { lockFileLib.CompileTimeAssemblies = compileGroup.Items.Select(t => (LockFileItem)t.Path).ToList(); } var runtimeGroup = contentItems.FindBestItemGroup(criteria, patterns.ManagedAssemblies); if (runtimeGroup != null) { lockFileLib.RuntimeAssemblies = runtimeGroup.Items.Select(p => (LockFileItem)p.Path).ToList(); } var resourceGroup = contentItems.FindBestItemGroup(criteria, patterns.ResourceAssemblies); if (resourceGroup != null) { lockFileLib.ResourceAssemblies = resourceGroup.Items.Select(ToResourceLockFileItem).ToList(); } var nativeGroup = contentItems.FindBestItemGroup(criteriaBuilderWithoutTfm.Criteria, patterns.NativeLibraries); if (nativeGroup != null) { lockFileLib.NativeLibraries = nativeGroup.Items.Select(p => (LockFileItem)p.Path).ToList(); } // COMPAT: Support lib/contract so older packages can be consumed string contractPath = "lib/contract/" + package.Id + ".dll"; var hasContract = files.Any(path => path == contractPath); var hasLib = lockFileLib.RuntimeAssemblies.Any(); if (hasContract && hasLib && !VersionUtility.IsDesktop(framework)) { lockFileLib.CompileTimeAssemblies.Clear(); lockFileLib.CompileTimeAssemblies.Add(contractPath); } // See if there's a list of specific references defined for this target framework IEnumerable<PackageReferenceSet> referenceSets; if (VersionUtility.GetNearest(framework, package.PackageAssemblyReferences, out referenceSets)) { // Get the first compatible reference set var referenceSet = referenceSets.FirstOrDefault(); if (referenceSet != null) { // Remove all assemblies of which names do not appear in the References list lockFileLib.RuntimeAssemblies.RemoveAll(path => path.Path.StartsWith("lib/") && !referenceSet.References.Contains(Path.GetFileName(path), StringComparer.OrdinalIgnoreCase)); lockFileLib.CompileTimeAssemblies.RemoveAll(path => path.Path.StartsWith("lib/") && !referenceSet.References.Contains(Path.GetFileName(path), StringComparer.OrdinalIgnoreCase)); } } return lockFileLib; }
private static void AddFrameworkReferences(LockFileTargetLibrary lockFileLib, FrameworkName framework, IEnumerable<FrameworkAssemblyReference> frameworkAssemblies) { foreach (var assemblyReference in frameworkAssemblies) { if (!assemblyReference.SupportedFrameworks.Any() && !VersionUtility.IsDesktop(framework)) { // REVIEW: This isn't 100% correct since none *can* mean // any in theory, but in practice it means .NET full reference assembly // If there's no supported target frameworks and we're not targeting // the desktop framework then skip it. // To do this properly we'll need all reference assemblies supported // by each supported target framework which isn't always available. continue; } lockFileLib.FrameworkAssemblies.Add(assemblyReference.AssemblyName); } }