Beispiel #1
0
        private static List <LockFileRuntimeTarget> GetRuntimeTargetLockFileItems(
            ContentItemCollection contentItems,
            NuGetFramework framework,
            LibraryIncludeFlags dependencyType,
            LibraryIncludeFlags groupType,
            PatternSet patternSet,
            string assetType,
            MaccatalystFallback maccatalystFallback)
        {
            var groups = contentItems.FindItemGroups(patternSet).ToList();

            var groupsForFramework = GetContentGroupsForFramework(
                framework,
                groups,
                ManagedCodeConventions.PropertyNames.RuntimeIdentifier,
                maccatalystFallback);

            var items = GetRuntimeTargetItems(groupsForFramework, assetType);

            if ((dependencyType & groupType) == LibraryIncludeFlags.None)
            {
                ClearIfExists <LockFileRuntimeTarget>(items);
            }

            return(items);
        }
Beispiel #2
0
        /// <summary>
        /// Group all items by the primary key, then select the nearest TxM
        /// within each group.
        /// Items that do not contain the primaryKey will be filtered out.
        /// </summary>
        private static List <ContentItemGroup> GetContentGroupsForFramework(
            NuGetFramework framework,
            List <ContentItemGroup> contentGroups,
            string primaryKey,
            MaccatalystFallback maccatalystFallback)
        {
            var groups = new List <ContentItemGroup>();

            // Group by primary key and find the nearest TxM under each.
            var primaryGroups = new Dictionary <string, List <ContentItemGroup> >(StringComparer.Ordinal);

            foreach (var group in contentGroups)
            {
                object keyObj;
                if (group.Properties.TryGetValue(primaryKey, out keyObj))
                {
                    var key = (string)keyObj;

                    List <ContentItemGroup> index;
                    if (!primaryGroups.TryGetValue(key, out index))
                    {
                        index = new List <ContentItemGroup>(1);
                        primaryGroups.Add(key, index);
                    }

                    index.Add(group);
                }
            }

            // Find the nearest TxM within each primary key group.
            foreach (var primaryGroup in primaryGroups)
            {
                var groupedItems = primaryGroup.Value;

                var nearestGroup = NuGetFrameworkUtility.GetNearest <ContentItemGroup>(groupedItems, framework,
                                                                                       group =>
                {
                    // In the case of /native there is no TxM, here any should be used.
                    object frameworkObj;
                    if (group.Properties.TryGetValue(
                            ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker,
                            out frameworkObj))
                    {
                        return((NuGetFramework)frameworkObj);
                    }

                    return(NuGetFramework.AnyFramework);
                });

                // If a compatible group exists within the secondary key add it to the results
                if (nearestGroup != null)
                {
                    MaccatalystFallback.CheckFallback(maccatalystFallback, nearestGroup.Properties);
                    groups.Add(nearestGroup);
                }
            }

            return(groups);
        }
Beispiel #3
0
 /// <summary>
 /// Create lock file items for the best matching group.
 /// </summary>
 /// <remarks>Enumerate this once after calling.</remarks>
 private static IEnumerable <LockFileItem> GetLockFileItems(
     IReadOnlyList <SelectionCriteria> criteria,
     ContentItemCollection items,
     MaccatalystFallback maccatalystFallback,
     params PatternSet[] patterns)
 {
     return(GetLockFileItems(criteria, items, additionalAction: null, maccatalystFallback, patterns));
 }
Beispiel #4
0
 internal static void CheckFallback(MaccatalystFallback fallback, IDictionary <string, object> properties)
 {
     if (fallback != null)
     {
         if (properties.TryGetValue(ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker, out object tfmObj))
         {
             var tfm = (NuGetFramework)tfmObj;
             if (tfm.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.XamarinIOs, StringComparison.OrdinalIgnoreCase))
             {
                 fallback._usedXamarinIOs = true;
             }
         }
     }
 }
Beispiel #5
0
        /// <summary>
        /// Runtime targets
        /// These are applied only to non-RID target graphs.
        /// They are not used for compatibility checks.
        /// </summary>
        private static void AddRuntimeTargets(
            RestoreTargetGraph targetGraph,
            LibraryIncludeFlags dependencyType,
            LockFileTargetLibrary lockFileLib,
            NuGetFramework framework,
            string runtimeIdentifier,
            ContentItemCollection contentItems,
            MaccatalystFallback maccatalystFallback)
        {
            if (string.IsNullOrEmpty(runtimeIdentifier))
            {
                // Runtime targets contain all the runtime specific assets
                // that could be contained in the runtime specific target graphs.
                // These items are contained in a flat list and have additional properties
                // for the RID and lock file section the assembly would belong to.
                var runtimeTargetItems = new List <LockFileRuntimeTarget>();

                // Runtime
                runtimeTargetItems.AddRange(GetRuntimeTargetLockFileItems(
                                                contentItems,
                                                framework,
                                                dependencyType,
                                                LibraryIncludeFlags.Runtime,
                                                targetGraph.Conventions.Patterns.RuntimeAssemblies,
                                                "runtime",
                                                maccatalystFallback));

                // Resource
                runtimeTargetItems.AddRange(GetRuntimeTargetLockFileItems(
                                                contentItems,
                                                framework,
                                                dependencyType,
                                                LibraryIncludeFlags.Runtime,
                                                targetGraph.Conventions.Patterns.ResourceAssemblies,
                                                "resource",
                                                maccatalystFallback));

                // Native
                runtimeTargetItems.AddRange(GetRuntimeTargetLockFileItems(
                                                contentItems,
                                                framework,
                                                dependencyType,
                                                LibraryIncludeFlags.Native,
                                                targetGraph.Conventions.Patterns.NativeLibraries,
                                                "native",
                                                maccatalystFallback));

                lockFileLib.RuntimeTargets = runtimeTargetItems;
            }
        }
Beispiel #6
0
        private static void AddDependencies(
            IEnumerable <LibraryDependency> dependencies,
            LockFileTargetLibrary lockFileLib,
            NuGetFramework framework,
            NuspecReader nuspec,
            MaccatalystFallback maccatalystFallback)
        {
            if (dependencies == null)
            {
                // DualCompatibilityFramework & AssetFallbackFramework does not apply to dependencies.
                // Convert it to a fallback framework if needed.
                NuGetFramework currentFramework = framework;
                if (framework is AssetTargetFallbackFramework atf)
                {
                    currentFramework = atf.AsFallbackFramework();
                }
                else if (framework is DualCompatibilityFramework mcf)
                {
                    currentFramework = mcf.AsFallbackFramework();
                }

                var dependencySet = nuspec
                                    .GetDependencyGroups()
                                    .GetNearest(currentFramework);

                if (dependencySet != null)
                {
                    var set = dependencySet.Packages;

                    if (set != null)
                    {
                        lockFileLib.Dependencies = set.AsList();
                    }
                }
            }
            else
            {
                // Filter the dependency set down to packages and projects.
                // Framework references will not be displayed
                lockFileLib.Dependencies = dependencies
                                           .Where(ld => ld.LibraryRange.TypeConstraintAllowsAnyOf(LibraryDependencyTarget.PackageProjectExternal))
                                           .Select(ld => new PackageDependency(ld.Name, ld.LibraryRange.VersionRange))
                                           .ToList();
            }
        }
        /// <summary>
        /// Get all content groups that have the nearest TxM
        /// </summary>
        internal static List <ContentItemGroup> GetContentGroupsForFramework(
            LockFileTargetLibrary lockFileLib,
            NuGetFramework framework,
            IEnumerable <ContentItemGroup> contentGroups,
            MaccatalystFallback maccatalystFallback)
        {
            var groups = new List <ContentItemGroup>();

            // Group by content by code language and find the nearest TxM under each language.
            var groupsByLanguage = new Dictionary <string, List <ContentItemGroup> >(StringComparer.OrdinalIgnoreCase);

            foreach (var group in contentGroups)
            {
                var codeLanguage = (string)group.Properties[ManagedCodeConventions.PropertyNames.CodeLanguage];

                List <ContentItemGroup> index;
                if (!groupsByLanguage.TryGetValue(codeLanguage, out index))
                {
                    index = new List <ContentItemGroup>(1);
                    groupsByLanguage.Add(codeLanguage, index);
                }

                index.Add(group);
            }

            // Find the nearest TxM within each language
            foreach (var codeLanguagePair in groupsByLanguage)
            {
                var languageGroups = codeLanguagePair.Value;

                var nearestGroup = NuGetFrameworkUtility.GetNearest <ContentItemGroup>(languageGroups, framework,
                                                                                       group =>
                                                                                       (NuGetFramework)group.Properties[ManagedCodeConventions.PropertyNames.TargetFrameworkMoniker]);

                // If a compatible group exists within the code language add it to the results
                if (nearestGroup != null)
                {
                    MaccatalystFallback.CheckFallback(maccatalystFallback, nearestGroup.Properties);
                    groups.Add(nearestGroup);
                }
            }

            return(groups);
        }
Beispiel #8
0
        private static void AddMSBuildAssets(
            LockFileLibrary library,
            RestoreTargetGraph targetGraph,
            LockFileTargetLibrary lockFileLib,
            IReadOnlyList <SelectionCriteria> orderedCriteria,
            ContentItemCollection contentItems,
            MaccatalystFallback maccatalystFallback)
        {
            // Build Transitive
            var btGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.MSBuildTransitiveFiles);

            var filteredBTGroup = GetBuildItemsForPackageId(btGroup, library.Name);

            lockFileLib.Build.AddRange(filteredBTGroup);

            // Build
            var buildGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.MSBuildFiles);

            // filter any build asset already being added as part of build transitive
            var filteredBuildGroup = GetBuildItemsForPackageId(buildGroup, library.Name).
                                     Where(buildItem => !filteredBTGroup.Any(
                                               btItem => Path.GetFileName(btItem.Path).Equals(Path.GetFileName(buildItem.Path), StringComparison.OrdinalIgnoreCase)));

            lockFileLib.Build.AddRange(filteredBuildGroup);

            // Build multi targeting
            var buildMultiTargetingGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.MSBuildMultiTargetingFiles);

            lockFileLib.BuildMultiTargeting.AddRange(GetBuildItemsForPackageId(buildMultiTargetingGroup, library.Name));
        }
Beispiel #9
0
        private static void AddToolsAssets(LockFileLibrary library,
                                           LocalPackageInfo package,
                                           RestoreTargetGraph targetGraph,
                                           LibraryIncludeFlags dependencyType,
                                           LockFileTargetLibrary lockFileLib,
                                           NuGetFramework framework,
                                           string runtimeIdentifier,
                                           ContentItemCollection contentItems,
                                           NuspecReader nuspec,
                                           IReadOnlyList <SelectionCriteria> orderedCriteria,
                                           MaccatalystFallback maccatalystFallback)
        {
            var toolsGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.ToolsAssemblies);

            lockFileLib.ToolsAssemblies.AddRange(toolsGroup);
        }
Beispiel #10
0
        /// <summary>
        /// Create lock file items for the best matching group.
        /// </summary>
        /// <remarks>Enumerate this once after calling.</remarks>
        private static IEnumerable <LockFileItem> GetLockFileItems(
            IReadOnlyList <SelectionCriteria> criteria,
            ContentItemCollection items,
            Action <LockFileItem> additionalAction,
            MaccatalystFallback maccatalystFallback,
            params PatternSet[] patterns)
        {
            // Loop through each criteria taking the first one that matches one or more items.
            foreach (var managedCriteria in criteria)
            {
                var group = items.FindBestItemGroup(
                    managedCriteria,
                    patterns);

                if (group != null)
                {
                    MaccatalystFallback.CheckFallback(maccatalystFallback, group.Properties);

                    foreach (var item in group.Items)
                    {
                        var    newItem = new LockFileItem(item.Path);
                        object locale;
                        if (item.Properties.TryGetValue("locale", out locale))
                        {
                            newItem.Properties["locale"] = (string)locale;
                        }
                        additionalAction?.Invoke(newItem);
                        yield return(newItem);
                    }

                    // Take only the first group that has items
                    break;
                }
            }

            yield break;
        }
Beispiel #11
0
        public LockFile CreateLockFile(LockFile previousLockFile,
                                       PackageSpec project,
                                       IEnumerable <RestoreTargetGraph> targetGraphs,
                                       IReadOnlyList <NuGetv3LocalRepository> localRepositories,
                                       RemoteWalkContext context,
                                       LockFileBuilderCache lockFileBuilderCache)
        {
            var lockFile = new LockFile()
            {
                Version = _lockFileVersion
            };

            var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => Tuple.Create(l.Name, l.Version));

            if (project.RestoreMetadata?.ProjectStyle == ProjectStyle.PackageReference ||
                project.RestoreMetadata?.ProjectStyle == ProjectStyle.DotnetToolReference)
            {
                AddProjectFileDependenciesForPackageReference(project, lockFile, targetGraphs);
            }
            else
            {
                AddProjectFileDependenciesForSpec(project, lockFile);
            }

            // Record all libraries used
            var libraryItems = targetGraphs
                               .SelectMany(g => g.Flattened)                                   // All GraphItem<RemoteResolveResult> resolved in the graph.
                               .Distinct(GraphItemKeyComparer <RemoteResolveResult> .Instance) // Distinct list of GraphItems. Two items are equal only if the itmes' Keys are equal.
                               .OrderBy(x => x.Data.Match.Library);

            foreach (var item in libraryItems)
            {
                var library = item.Data.Match.Library;

                if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase))
                {
                    // Do not include the project itself as a library.
                    continue;
                }

                if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject)
                {
                    // Project
                    var localMatch = (LocalMatch)item.Data.Match;

                    var projectLib = new LockFileLibrary()
                    {
                        Name    = library.Name,
                        Version = library.Version,
                        Type    = LibraryType.Project,
                    };

                    // Set the relative path if a path exists
                    // For projects without project.json this will be empty
                    if (!string.IsNullOrEmpty(localMatch.LocalLibrary.Path))
                    {
                        projectLib.Path = PathUtility.GetRelativePath(
                            project.FilePath,
                            localMatch.LocalLibrary.Path,
                            '/');
                    }

                    // The msbuild project path if it exists
                    object msbuildPath;
                    if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.MSBuildProjectPath, out msbuildPath))
                    {
                        var msbuildRelativePath = PathUtility.GetRelativePath(
                            project.FilePath,
                            (string)msbuildPath,
                            '/');

                        projectLib.MSBuildProject = msbuildRelativePath;
                    }

                    lockFile.Libraries.Add(projectLib);
                }
                else if (library.Type == LibraryType.Package)
                {
                    // Packages
                    var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version);

                    // Add the library if it was resolved, unresolved packages are not added to the assets file.
                    if (packageInfo != null)
                    {
                        var package  = packageInfo.Package;
                        var resolver = packageInfo.Repository.PathResolver;

                        var             sha512          = package.Sha512;
                        var             path            = PathUtility.GetPathWithForwardSlashes(resolver.GetPackageDirectory(package.Id, package.Version));
                        LockFileLibrary lockFileLib     = null;
                        LockFileLibrary previousLibrary = null;

                        if (previousLibraries?.TryGetValue(Tuple.Create(package.Id, package.Version), out previousLibrary) == true)
                        {
                            // Check that the previous library is still valid
                            if (previousLibrary != null &&
                                StringComparer.Ordinal.Equals(path, previousLibrary.Path) &&
                                StringComparer.Ordinal.Equals(sha512, previousLibrary.Sha512))
                            {
                                // We mutate this previous library so we must take a clone of it. This is
                                // important because later, when deciding whether the lock file has changed,
                                // we compare the new lock file to the previous (in-memory) lock file.
                                lockFileLib = previousLibrary.Clone();
                            }
                        }

                        // Create a new lock file library if one doesn't exist already.
                        if (lockFileLib == null)
                        {
                            lockFileLib = CreateLockFileLibrary(package, sha512, path);
                        }

                        // Create a new lock file library
                        lockFile.Libraries.Add(lockFileLib);
                    }
                }
            }

            Dictionary <Tuple <string, NuGetVersion>, LockFileLibrary> libraries = EnsureUniqueLockFileLibraries(lockFile);

            var librariesWithWarnings = new HashSet <LibraryIdentity>();

            var rootProjectStyle = project.RestoreMetadata?.ProjectStyle ?? ProjectStyle.Unknown;

            // Add the targets
            foreach (var targetGraph in targetGraphs
                     .OrderBy(graph => graph.Framework.ToString(), StringComparer.Ordinal)
                     .ThenBy(graph => graph.RuntimeIdentifier, StringComparer.Ordinal))
            {
                var target = new LockFileTarget
                {
                    TargetFramework   = targetGraph.Framework,
                    RuntimeIdentifier = targetGraph.RuntimeIdentifier
                };

                var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph);

                // Check if warnings should be displayed for the current framework.
                var tfi = project.GetTargetFramework(targetGraph.Framework);

                bool warnForImportsOnGraph = tfi.Warn &&
                                             (target.TargetFramework is FallbackFramework ||
                                              target.TargetFramework is AssetTargetFallbackFramework);

                // This is used for a special-case warning we need to do when net6.0-maccatalyst selects a xamarin.ios asset.
                MaccatalystFallback maccatalystFallback = MaccatalystFallback.FallbackIfNeeded(targetGraph.Framework);

                foreach (var graphItem in targetGraph.Flattened.OrderBy(x => x.Key))
                {
                    var library = graphItem.Key;

                    // include flags
                    LibraryIncludeFlags includeFlags;
                    if (!flattenedFlags.TryGetValue(library.Name, out includeFlags))
                    {
                        includeFlags = ~LibraryIncludeFlags.ContentFiles;
                    }

                    if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject)
                    {
                        if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // Do not include the project itself as a library.
                            continue;
                        }

                        var projectLib = LockFileUtils.CreateLockFileTargetProject(
                            graphItem,
                            library,
                            includeFlags,
                            targetGraph,
                            rootProjectStyle,
                            maccatalystFallback);

                        target.Libraries.Add(projectLib);
                    }
                    else if (library.Type == LibraryType.Package)
                    {
                        var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version);

                        if (packageInfo == null)
                        {
                            continue;
                        }

                        var package           = packageInfo.Package;
                        var libraryDependency = tfi.Dependencies.FirstOrDefault(e => e.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase));

                        var targetLibrary = LockFileUtils.CreateLockFileTargetLibrary(
                            libraryDependency?.Aliases,
                            libraries[Tuple.Create(library.Name, library.Version)],
                            package,
                            targetGraph,
                            dependencyType: includeFlags,
                            targetFrameworkOverride: null,
                            dependencies: graphItem.Data.Dependencies,
                            cache: lockFileBuilderCache,
                            maccatalystFallback);

                        target.Libraries.Add(targetLibrary);

                        // Log warnings if the target library used the fallback framework
                        if (warnForImportsOnGraph && !librariesWithWarnings.Contains(library))
                        {
                            var nonFallbackFramework = new NuGetFramework(target.TargetFramework);

                            var targetLibraryWithoutFallback = LockFileUtils.CreateLockFileTargetLibrary(
                                libraryDependency?.Aliases,
                                libraries[Tuple.Create(library.Name, library.Version)],
                                package,
                                targetGraph,
                                targetFrameworkOverride: nonFallbackFramework,
                                dependencyType: includeFlags,
                                dependencies: graphItem.Data.Dependencies,
                                cache: lockFileBuilderCache,
                                maccatalystFallback: maccatalystFallback);

                            if (!targetLibrary.Equals(targetLibraryWithoutFallback))
                            {
                                var libraryName = DiagnosticUtility.FormatIdentity(library);

                                var message = string.Format(CultureInfo.CurrentCulture,
                                                            Strings.Log_ImportsFallbackWarning,
                                                            libraryName,
                                                            GetFallbackFrameworkString(target.TargetFramework),
                                                            nonFallbackFramework);

                                var logMessage = RestoreLogMessage.CreateWarning(
                                    NuGetLogCode.NU1701,
                                    message,
                                    library.Name,
                                    targetGraph.TargetGraphName);

                                _logger.Log(logMessage);

                                // only log the warning once per library
                                librariesWithWarnings.Add(library);
                            }
                        }
                    }

                    if (maccatalystFallback != null && maccatalystFallback._usedXamarinIOs)
                    {
                        var libraryName = DiagnosticUtility.FormatIdentity(library);

                        var message = string.Format(CultureInfo.CurrentCulture,
                                                    Strings.Warning_MacCatalystXamarinIOSCompat,
                                                    libraryName,
                                                    project.Name,
                                                    targetGraph.Framework);

                        var logMessage = RestoreLogMessage.CreateWarning(
                            NuGetLogCode.NU1703,
                            message,
                            library.Name,
                            targetGraph.TargetGraphName);

                        _logger.Log(logMessage);

                        // only log the warning once per library
                        librariesWithWarnings.Add(library);
                    }
                }

                EnsureUniqueLockFileTargetLibraries(target);
                lockFile.Targets.Add(target);
            }

            PopulatePackageFolders(localRepositories.Select(repo => repo.RepositoryRoot).Distinct(), lockFile);

            AddCentralTransitiveDependencyGroupsForPackageReference(project, lockFile, targetGraphs);

            // Add the original package spec to the lock file.
            lockFile.PackageSpec = project;

            return(lockFile);
        }
Beispiel #12
0
        /// <summary>
        /// Create a lock file target library for the given <paramref name="library"/>
        /// </summary>
        /// <param name="aliases">When an alias is specified, all assemblies coming from the library will need to be referenced with an alias.</param>
        /// <param name="library">The lock file library, expected to be for the equivalent package as <paramref name="library"/> and <paramref name="package"/>. </param>
        /// <param name="package">The local package info.</param>
        /// <param name="targetGraph">The target graph for which the asset selection needs to happen.</param>
        /// <param name="dependencyType">The resolved dependency type.</param>
        /// <param name="targetFrameworkOverride">The original framework if the asset selection is happening for a fallback framework.</param>
        /// <param name="dependencies">The dependencies of this package.</param>
        /// <param name="cache">The lock file build cache.</param>
        /// <returns>The LockFileTargetLibrary</returns>
        internal static LockFileTargetLibrary CreateLockFileTargetLibrary(
            string aliases,
            LockFileLibrary library,
            LocalPackageInfo package,
            RestoreTargetGraph targetGraph,
            LibraryIncludeFlags dependencyType,
            NuGetFramework targetFrameworkOverride,
            List <LibraryDependency> dependencies,
            LockFileBuilderCache cache,
            MaccatalystFallback maccatalystFallback)
        {
            var runtimeIdentifier = targetGraph.RuntimeIdentifier;
            var framework         = targetFrameworkOverride ?? targetGraph.Framework;

            return(cache.GetLockFileTargetLibrary(targetGraph, framework, package, aliases, dependencyType,
                                                  () =>
            {
                LockFileTargetLibrary lockFileLib = null;
                // This will throw an appropriate error if the nuspec is missing
                var nuspec = package.Nuspec;

                var orderedCriteriaSets = cache.GetSelectionCriteria(targetGraph, framework);
                var contentItems = cache.GetContentItems(library, package);

                var packageTypes = nuspec.GetPackageTypes().AsList();

                for (var i = 0; i < orderedCriteriaSets.Count; i++)
                {
                    // Create a new library each time to avoid
                    // assets being added from other criteria.
                    lockFileLib = new LockFileTargetLibrary()
                    {
                        Name = package.Id,
                        Version = package.Version,
                        Type = LibraryType.Package,
                        PackageType = packageTypes
                    };

                    // Populate assets

                    if (lockFileLib.PackageType.Contains(PackageType.DotnetTool))
                    {
                        AddToolsAssets(library, package, targetGraph, dependencyType, lockFileLib, framework,
                                       runtimeIdentifier, contentItems, nuspec, orderedCriteriaSets[i], maccatalystFallback);
                        if (CompatibilityChecker.HasCompatibleToolsAssets(lockFileLib))
                        {
                            break;
                        }
                    }
                    else
                    {
                        AddAssets(aliases, library, package, targetGraph, dependencyType, lockFileLib,
                                  framework, runtimeIdentifier, contentItems, nuspec, orderedCriteriaSets[i], maccatalystFallback);
                        // Check if compatible assets were found.
                        // If no compatible assets were found and this is the last check
                        // continue on with what was given, this will fail in the normal
                        // compat verification.
                        if (CompatibilityChecker.HasCompatibleAssets(lockFileLib))
                        {
                            // Stop when compatible assets are found.
                            break;
                        }
                    }
                }

                // Add dependencies
                AddDependencies(dependencies, lockFileLib, framework, nuspec, maccatalystFallback);

                // Exclude items
                ExcludeItems(lockFileLib, dependencyType);

                return lockFileLib;
            }));
        }
Beispiel #13
0
        /// <summary>
        /// Create a library for a project.
        /// </summary>
        internal static LockFileTargetLibrary CreateLockFileTargetProject(
            GraphItem <RemoteResolveResult> graphItem,
            LibraryIdentity library,
            LibraryIncludeFlags dependencyType,
            RestoreTargetGraph targetGraph,
            ProjectStyle rootProjectStyle,
            MaccatalystFallback maccatalystFallback)
        {
            var localMatch = (LocalMatch)graphItem.Data.Match;

            // Target framework information is optional and may not exist for csproj projects
            // that do not have a project.json file.
            string projectFramework = null;
            object frameworkInfoObject;

            if (localMatch.LocalLibrary.Items.TryGetValue(
                    KnownLibraryProperties.TargetFrameworkInformation,
                    out frameworkInfoObject))
            {
                // Retrieve the resolved framework name, if this is null it means that the
                // project is incompatible. This is marked as Unsupported.
                var targetFrameworkInformation = (TargetFrameworkInformation)frameworkInfoObject;
                var fwName = targetFrameworkInformation.FrameworkName;
                if (maccatalystFallback != null && fwName != null)
                {
                    if (fwName.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.XamarinIOs, StringComparison.OrdinalIgnoreCase))
                    {
                        maccatalystFallback._usedXamarinIOs = true;
                    }
                }

                projectFramework = fwName?.DotNetFrameworkName
                                   ?? NuGetFramework.UnsupportedFramework.DotNetFrameworkName;
            }

            // Create the target entry
            var projectLib = new LockFileTargetLibrary()
            {
                Name      = library.Name,
                Version   = library.Version,
                Type      = LibraryType.Project,
                Framework = projectFramework,

                // Find all dependencies which would be in the nuspec
                // Include dependencies with no constraints, or package/project/external
                // Exclude suppressed dependencies, the top level project is not written
                // as a target so the node depth does not matter.
                Dependencies = graphItem.Data.Dependencies
                               .Where(
                    d => (d.LibraryRange.TypeConstraintAllowsAnyOf(LibraryDependencyTarget.PackageProjectExternal)) &&
                    d.SuppressParent != LibraryIncludeFlags.All &&
                    d.ReferenceType == LibraryDependencyReferenceType.Direct)
                               .Select(d => GetDependencyVersionRange(d))
                               .ToList()
            };

            if (rootProjectStyle == ProjectStyle.PackageReference)
            {
                // Add files under asset groups
                object filesObject;
                object msbuildPath;
                if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.MSBuildProjectPath, out msbuildPath))
                {
                    var files      = new List <ProjectRestoreMetadataFile>();
                    var fileLookup = new Dictionary <string, ProjectRestoreMetadataFile>(StringComparer.OrdinalIgnoreCase);

                    // Find the project path, this is provided by the resolver
                    var msbuildFilePathInfo = new FileInfo((string)msbuildPath);

                    // Ensure a trailing slash for the relative path helper.
                    var projectDir = PathUtility.EnsureTrailingSlash(msbuildFilePathInfo.Directory.FullName);

                    // Read files from the project if they were provided.
                    if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.ProjectRestoreMetadataFiles, out filesObject))
                    {
                        files.AddRange((List <ProjectRestoreMetadataFile>)filesObject);
                    }

                    var targetFrameworkShortName = targetGraph.Framework.GetShortFolderName();
                    var libAnyPath = $"lib/{targetFrameworkShortName}/any.dll";

                    if (files.Count == 0)
                    {
                        // If the project did not provide a list of assets, add in default ones.
                        // These are used to detect transitive vs non-transitive project references.
                        var absolutePath = Path.Combine(projectDir, "bin", "placeholder", $"{localMatch.Library.Name}.dll");

                        files.Add(new ProjectRestoreMetadataFile(libAnyPath, absolutePath));
                    }

                    // Process and de-dupe files
                    for (var i = 0; i < files.Count; i++)
                    {
                        var path = files[i].PackagePath;

                        // LIBANY avoid compatibility checks and will always be used.
                        if (LIBANY.Equals(path, StringComparison.Ordinal))
                        {
                            path = libAnyPath;
                        }

                        if (!fileLookup.ContainsKey(path))
                        {
                            fileLookup.Add(path, files[i]);
                        }
                    }

                    var contentItems = new ContentItemCollection();
                    contentItems.Load(fileLookup.Keys);

                    // Create an ordered list of selection criteria. Each will be applied, if the result is empty
                    // fallback frameworks from "imports" will be tried.
                    // These are only used for framework/RID combinations where content model handles everything.
                    var orderedCriteria = CreateCriteria(targetGraph, targetGraph.Framework);

                    // Compile
                    // ref takes precedence over lib
                    var compileGroup = GetLockFileItems(
                        orderedCriteria,
                        contentItems,
                        maccatalystFallback,
                        targetGraph.Conventions.Patterns.CompileRefAssemblies,
                        targetGraph.Conventions.Patterns.CompileLibAssemblies);

                    projectLib.CompileTimeAssemblies.AddRange(
                        ConvertToProjectPaths(fileLookup, projectDir, compileGroup));

                    // Runtime
                    var runtimeGroup = GetLockFileItems(
                        orderedCriteria,
                        contentItems,
                        maccatalystFallback,
                        targetGraph.Conventions.Patterns.RuntimeAssemblies);

                    projectLib.RuntimeAssemblies.AddRange(
                        ConvertToProjectPaths(fileLookup, projectDir, runtimeGroup));
                }
            }

            // Add frameworkAssemblies for projects
            object frameworkAssembliesObject;

            if (localMatch.LocalLibrary.Items.TryGetValue(
                    KnownLibraryProperties.FrameworkAssemblies,
                    out frameworkAssembliesObject))
            {
                projectLib.FrameworkAssemblies.AddRange((List <string>)frameworkAssembliesObject);
            }

            // Add frameworkReferences for projects
            object frameworkReferencesObject;

            if (localMatch.LocalLibrary.Items.TryGetValue(
                    KnownLibraryProperties.FrameworkReferences,
                    out frameworkReferencesObject))
            {
                projectLib.FrameworkReferences.AddRange(
                    ((ISet <FrameworkDependency>)frameworkReferencesObject)
                    .Where(e => e.PrivateAssets != FrameworkDependencyFlags.All)
                    .Select(f => f.Name));
            }

            // Exclude items
            ExcludeItems(projectLib, dependencyType);

            return(projectLib);
        }
Beispiel #14
0
        private static void AddContentFiles(RestoreTargetGraph targetGraph, LockFileTargetLibrary lockFileLib, NuGetFramework framework, ContentItemCollection contentItems, NuspecReader nuspec, MaccatalystFallback maccatalystFallback)
        {
            // content v2 items
            var contentFileGroups = contentItems.FindItemGroups(targetGraph.Conventions.Patterns.ContentFiles).ToList();

            if (contentFileGroups.Count > 0)
            {
                // Multiple groups can match the same framework, find all of them
                var contentFileGroupsForFramework = ContentFileUtils.GetContentGroupsForFramework(
                    lockFileLib,
                    framework,
                    contentFileGroups,
                    maccatalystFallback);

                lockFileLib.ContentFiles = ContentFileUtils.GetContentFileGroup(
                    framework,
                    nuspec,
                    contentFileGroupsForFramework);
            }
        }
Beispiel #15
0
        /// <summary>
        /// Populate assets for a <see cref="LockFileLibrary"/>.
        /// </summary>
        private static void AddAssets(
            string aliases,
            LockFileLibrary library,
            LocalPackageInfo package,
            RestoreTargetGraph targetGraph,
            LibraryIncludeFlags dependencyType,
            LockFileTargetLibrary lockFileLib,
            NuGetFramework framework,
            string runtimeIdentifier,
            ContentItemCollection contentItems,
            NuspecReader nuspec,
            IReadOnlyList <SelectionCriteria> orderedCriteria,
            MaccatalystFallback maccatalystFallback)
        {
            // Add framework references for desktop projects.
            AddFrameworkReferences(lockFileLib, framework, nuspec);

            // Compile
            // Set-up action to update the compile time items.
            Action <LockFileItem> applyAliases = (item) => ApplyAliases(aliases, item);

            // ref takes precedence over lib
            var compileGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                applyAliases,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.CompileRefAssemblies,
                targetGraph.Conventions.Patterns.CompileLibAssemblies);

            lockFileLib.CompileTimeAssemblies.AddRange(compileGroup);

            // Runtime
            var runtimeGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.RuntimeAssemblies);

            lockFileLib.RuntimeAssemblies.AddRange(runtimeGroup);

            // Embed
            var embedGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.EmbedAssemblies);

            lockFileLib.EmbedAssemblies.AddRange(embedGroup);

            // Resources
            var resourceGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.ResourceAssemblies);

            lockFileLib.ResourceAssemblies.AddRange(resourceGroup);

            // Native
            var nativeGroup = GetLockFileItems(
                orderedCriteria,
                contentItems,
                maccatalystFallback,
                targetGraph.Conventions.Patterns.NativeLibraries);

            lockFileLib.NativeLibraries.AddRange(nativeGroup);

            // Add MSBuild files
            AddMSBuildAssets(library, targetGraph, lockFileLib, orderedCriteria, contentItems, maccatalystFallback);

            // Add content files
            AddContentFiles(targetGraph, lockFileLib, framework, contentItems, nuspec, maccatalystFallback);

            // Runtime targets
            // These are applied only to non-RID target graphs.
            // They are not used for compatibility checks.
            AddRuntimeTargets(targetGraph, dependencyType, lockFileLib, framework, runtimeIdentifier, contentItems, maccatalystFallback);

            // COMPAT: Support lib/contract so older packages can be consumed
            ApplyLibContract(package, lockFileLib, framework, contentItems);

            // Apply filters from the <references> node in the nuspec
            ApplyReferenceFilter(lockFileLib, framework, nuspec);
        }