예제 #1
0
        public RestoreRequest(
            PackageSpec project,
            RestoreCommandProviders dependencyProviders,
            SourceCacheContext cacheContext,
            ClientPolicyContext clientPolicyContext,
            PackageSourceMapping packageSourceMapping,
            ILogger log,
            LockFileBuilderCache lockFileBuilderCache)
        {
            CacheContext         = cacheContext ?? throw new ArgumentNullException(nameof(cacheContext));
            LockFileBuilderCache = lockFileBuilderCache ?? throw new ArgumentNullException(nameof(lockFileBuilderCache));
            Log                  = log ?? throw new ArgumentNullException(nameof(log));
            Project              = project ?? throw new ArgumentNullException(nameof(project));
            DependencyProviders  = dependencyProviders ?? throw new ArgumentNullException(nameof(dependencyProviders));
            ClientPolicyContext  = clientPolicyContext;
            PackageSourceMapping = packageSourceMapping;

            ExternalProjects             = new List <ExternalProjectReference>();
            CompatibilityProfiles        = new HashSet <FrameworkRuntimePair>();
            PackagesDirectory            = dependencyProviders.GlobalPackages.RepositoryRoot;
            IsLowercasePackagesDirectory = true;

            // Default to the project folder
            RestoreOutputPath = Path.GetDirectoryName(Project.FilePath);
        }
예제 #2
0
 public DependencyGraphSpecRequestProvider(
     RestoreCommandProvidersCache providerCache,
     DependencyGraphSpec dgFile)
 {
     _dgFile               = dgFile;
     _providerCache        = providerCache;
     _lockFileBuilderCache = new LockFileBuilderCache();
 }
예제 #3
0
 public static LockFileTargetLibrary CreateLockFileTargetLibrary(
     LockFileLibrary library,
     LocalPackageInfo package,
     RestoreTargetGraph targetGraph,
     LibraryIncludeFlags dependencyType,
     NuGetFramework targetFrameworkOverride,
     IEnumerable <LibraryDependency> dependencies,
     LockFileBuilderCache cache)
 {
     return(CreateLockFileTargetLibrary(libraryDependency: null, library, package, targetGraph, dependencyType, targetFrameworkOverride, dependencies, cache));
 }
예제 #4
0
        public static LockFileTargetLibrary CreateLockFileTargetLibrary(
            LockFileLibrary library,
            LocalPackageInfo package,
            RestoreTargetGraph targetGraph,
            LibraryIncludeFlags dependencyType,
            NuGetFramework targetFrameworkOverride,
            IEnumerable <LibraryDependency> dependencies,
            LockFileBuilderCache cache)
        {
            LockFileTargetLibrary lockFileLib = null;
            var runtimeIdentifier             = targetGraph.RuntimeIdentifier;
            var framework = targetFrameworkOverride ?? targetGraph.Framework;

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

            // This will throw an appropriate error if the nuspec is missing
            var nuspec = package.Nuspec;

            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
                };

                // Populate assets
                AddAssets(library, package, targetGraph, dependencyType, lockFileLib, framework, runtimeIdentifier, contentItems, nuspec, orderedCriteriaSets[i]);

                // Check if compatile 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);

            // Exclude items
            ExcludeItems(lockFileLib, dependencyType);

            return(lockFileLib);
        }
예제 #5
0
        public LockFile CreateLockFile(LockFile previousLockFile,
                                       PackageSpec project,
                                       IEnumerable <RestoreTargetGraph> targetGraphs,
                                       IReadOnlyList <NuGetv3LocalRepository> localRepositories,
                                       RemoteWalkContext context)
        {
            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
            foreach (var item in targetGraphs.SelectMany(g => g.Flattened).Distinct()
                     .OrderBy(x => x.Data.Match.Library))
            {
                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);
                    }
                }
            }

            var libraries = lockFile.Libraries.ToDictionary(lib => Tuple.Create(lib.Name, lib.Version));

            var librariesWithWarnings = new HashSet <LibraryIdentity>();

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

            // Cache package data and selection criteria across graphs.
            var builderCache = new LockFileBuilderCache();

            // 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);

                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);

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

                        if (packageInfo == null)
                        {
                            continue;
                        }

                        var package = packageInfo.Package;

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

                        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(
                                libraries[Tuple.Create(library.Name, library.Version)],
                                package,
                                targetGraph,
                                targetFrameworkOverride: nonFallbackFramework,
                                dependencyType: includeFlags,
                                dependencies: graphItem.Data.Dependencies,
                                cache: builderCache);

                            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);
                            }
                        }
                    }
                }

                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);
        }
예제 #6
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;
            }));
        }