Example #1
0
        public static async Task <bool> IsRestoreRequiredAsync(
            ISolutionManager solutionManager,
            bool forceRestore,
            INuGetPathContext pathContext,
            DependencyGraphCacheContext cacheContext,
            string oldDependencyGraphSpecHash)
        {
            var projects = solutionManager.GetNuGetProjects().OfType <IDependencyGraphProject>().ToArray();

            var solutionDgSpec = await GetSolutionRestoreSpec(solutionManager, cacheContext);

            if (solutionDgSpec.Restore.Count < 1)
            {
                // Nothing to restore
                return(false);
            }

            var newDependencyGraphSpecHash = solutionDgSpec.GetHash();

            cacheContext.SolutionSpec     = solutionDgSpec;
            cacheContext.SolutionSpecHash = newDependencyGraphSpecHash;

            // Comment by @emgarten from PR -
            // Force is only done during a rebuild, all of the work done here to build the dg file is stored in the cache context and used again later on.
            // The time different should only be the time it takes to create the hash, which @dtivel has perf numbers on.
            if (forceRestore || (oldDependencyGraphSpecHash != newDependencyGraphSpecHash))
            {
                // A new project has been added
                return(true);
            }

            // Read package folder locations, initializing them in order of priority
            var packageFolderPaths = new List <string>();

            packageFolderPaths.Add(pathContext.UserPackageFolder);
            packageFolderPaths.AddRange(pathContext.FallbackPackageFolders);
            var pathResolvers = packageFolderPaths.Select(path => new VersionFolderPathResolver(path));

            var packagesChecked = new HashSet <PackageIdentity>();

            if (
                projects.Select(async p => await p.IsRestoreRequired(pathResolvers, packagesChecked, cacheContext))
                .Any(r => r.Result == true))
            {
                // The project.json file does not match the lock file
                return(true);
            }

            if (cacheContext.DeferredPackageSpecs.Where(spec => spec.RestoreMetadata.ProjectJsonPath != null).
                Select(p => IsRestoreRequired(p, pathResolvers, packagesChecked, cacheContext))
                .Any(r => r == true))
            {
                return(true);
            }

            return(false);
        }
Example #2
0
        public PackageDependencyProvider(INuGetPathContext nugetPathContext, FrameworkReferenceResolver frameworkReferenceResolver)
        {
            if (nugetPathContext != null)
            {
                _packagePathResolver = new FallbackPackagePathResolver(nugetPathContext);

                // This resolver is only used for building file names, so that base path is not required.
                _versionFolderPathResolver = new VersionFolderPathResolver(path: null);
            }

            _frameworkReferenceResolver = frameworkReferenceResolver;
        }
Example #3
0
        public void EnsurePackageCompatibility(
            NuGetProject nuGetProject,
            INuGetPathContext pathContext,
            IEnumerable <NuGetProjectAction> nuGetProjectActions,
            RestoreResult restoreResult)
        {
            // Find all of the installed package identities.
            var requestedPackageIds = new HashSet <string>(
                nuGetProjectActions
                .Where(action => action.NuGetProjectActionType == NuGetProjectActionType.Install)
                .Select(action => action.PackageIdentity.Id),
                StringComparer.OrdinalIgnoreCase);

            var installedIdentities = restoreResult
                                      .RestoreGraphs
                                      .SelectMany(graph => graph.Flattened)
                                      .Where(result => result.Key.Type == LibraryType.Package)
                                      .Select(result => new PackageIdentity(result.Key.Name, result.Key.Version))
                                      .Distinct()
                                      .Where(identity => requestedPackageIds.Contains(identity.Id));

            // Read the .nuspec on disk and ensure package compatibility.
            var resolver = new FallbackPackagePathResolver(pathContext);

            foreach (var identity in installedIdentities)
            {
                var packageInfo = resolver.GetPackageInfo(
                    identity.Id,
                    identity.Version);

                if (packageInfo != null)
                {
                    var manifestPath = packageInfo.PathResolver.GetManifestFilePath(
                        identity.Id,
                        identity.Version);
                    var nuspecReader = new NuspecReader(manifestPath);

                    EnsurePackageCompatibility(
                        nuGetProject,
                        identity,
                        nuspecReader);
                }
            }
        }
Example #4
0
 public NuGetPackageResolver(INuGetPathContext pathContext)
 {
     _packagePathResolver = new FallbackPackagePathResolver(pathContext);
 }
 /// <summary>
 /// Creates a package folder path resolver that scans multiple folders to find a package.
 /// </summary>
 /// <param name="pathContext">NuGet paths loaded from NuGet.Config settings.</param>
 public FallbackPackagePathResolver(INuGetPathContext pathContext)
     : this(pathContext?.UserPackageFolder, pathContext?.FallbackPackageFolders)
 {
 }
        public ProjectContext Build()
        {
            var diagnostics = new List <DiagnosticMessage>();

            ProjectDirectory = Project?.ProjectDirectory ?? ProjectDirectory;

            GlobalSettings globalSettings = null;

            if (ProjectDirectory != null)
            {
                RootDirectory = ProjectRootResolver.ResolveRootDirectory(ProjectDirectory);
                GlobalSettings.TryGetGlobalSettings(RootDirectory, out globalSettings);
            }

            RootDirectory = globalSettings?.DirectoryPath ?? RootDirectory;

            FrameworkReferenceResolver frameworkReferenceResolver;

            if (string.IsNullOrEmpty(ReferenceAssembliesPath))
            {
                // Use the default static resolver
                frameworkReferenceResolver = FrameworkReferenceResolver.Default;
            }
            else
            {
                frameworkReferenceResolver = new FrameworkReferenceResolver(ReferenceAssembliesPath);
            }

            LockFileLookup lockFileLookup = null;

            EnsureProjectLoaded();

            ReadLockFile(diagnostics);

            // some callers only give ProjectContextBuilder a LockFile
            ProjectDirectory = ProjectDirectory ?? TryGetProjectDirectoryFromLockFile();

            INuGetPathContext nugetPathContext = null;

            if (ProjectDirectory != null)
            {
                nugetPathContext = NuGetPathContext.Create(ProjectDirectory);
            }

            PackagesDirectory = PackagesDirectory ?? nugetPathContext?.UserPackageFolder;

            var    validLockFile             = true;
            string lockFileValidationMessage = null;

            if (LockFile != null)
            {
                if (Project != null)
                {
                    validLockFile = LockFile.IsValidForProject(Project, out lockFileValidationMessage);
                }

                lockFileLookup = new LockFileLookup(LockFile);
            }

            var libraries       = new Dictionary <LibraryKey, LibraryDescription>();
            var projectResolver = new ProjectDependencyProvider(ProjectResolver);

            ProjectDescription mainProject = null;

            if (Project != null)
            {
                mainProject = projectResolver.GetDescription(TargetFramework, Project, targetLibrary: null);

                // Add the main project
                libraries.Add(new LibraryKey(mainProject.Identity.Name), mainProject);
            }

            ProjectLibraryDependency platformDependency = null;

            if (mainProject != null)
            {
                platformDependency = mainProject.Dependencies
                                     .Where(d => d.Type.Equals(LibraryDependencyType.Platform))
                                     .Cast <ProjectLibraryDependency>()
                                     .FirstOrDefault();
            }
            bool isPortable = platformDependency != null;

            LockFileTarget     target          = null;
            LibraryDescription platformLibrary = null;

            if (lockFileLookup != null)
            {
                target = SelectTarget(LockFile, isPortable);
                if (target != null)
                {
                    var nugetPackageResolver   = new PackageDependencyProvider(nugetPathContext, frameworkReferenceResolver);
                    var msbuildProjectResolver = new MSBuildDependencyProvider(Project, ProjectResolver);
                    ScanLibraries(target, lockFileLookup, libraries, msbuildProjectResolver, nugetPackageResolver, projectResolver);

                    if (platformDependency != null)
                    {
                        libraries.TryGetValue(new LibraryKey(platformDependency.Name), out platformLibrary);
                    }
                }
            }

            string runtime = target?.RuntimeIdentifier;

            if (string.IsNullOrEmpty(runtime) && TargetFramework.IsDesktop())
            {
                // we got a ridless target for desktop so turning portable mode on
                isPortable = true;
                var legacyRuntime = RuntimeEnvironmentRidExtensions.GetLegacyRestoreRuntimeIdentifier();
                if (RuntimeIdentifiers.Contains(legacyRuntime))
                {
                    runtime = legacyRuntime;
                }
                else
                {
                    runtime = RuntimeIdentifiers.FirstOrDefault();
                }
            }

            var  referenceAssemblyDependencyResolver = new ReferenceAssemblyDependencyResolver(frameworkReferenceResolver);
            bool requiresFrameworkAssemblies;

            // Resolve the dependencies
            ResolveDependencies(libraries, referenceAssemblyDependencyResolver, out requiresFrameworkAssemblies);

            // REVIEW: Should this be in NuGet (possibly stored in the lock file?)
            if (LockFile == null)
            {
                diagnostics.Add(new DiagnosticMessage(
                                    ErrorCodes.NU1009,
                                    $"The expected lock file doesn't exist. Please run \"dotnet restore\" to generate a new lock file.",
                                    Path.Combine(Project.ProjectDirectory, LockFileFormat.LockFileName),
                                    DiagnosticMessageSeverity.Error));
            }

            if (!validLockFile)
            {
                diagnostics.Add(new DiagnosticMessage(
                                    ErrorCodes.NU1006,
                                    $"{lockFileValidationMessage}. Please run \"dotnet restore\" to generate a new lock file.",
                                    Path.Combine(Project.ProjectDirectory, LockFileFormat.LockFileName),
                                    DiagnosticMessageSeverity.Warning));
            }

            if (requiresFrameworkAssemblies)
            {
                var frameworkInfo = Project.GetTargetFramework(TargetFramework);

                if (frameworkReferenceResolver == null || string.IsNullOrEmpty(frameworkReferenceResolver.ReferenceAssembliesPath))
                {
                    // If there was an attempt to use reference assemblies but they were not installed
                    // report an error
                    diagnostics.Add(new DiagnosticMessage(
                                        ErrorCodes.DOTNET1012,
                                        $"The reference assemblies directory was not specified. You can set the location using the DOTNET_REFERENCE_ASSEMBLIES_PATH environment variable.",
                                        filePath: Project.ProjectFilePath,
                                        severity: DiagnosticMessageSeverity.Error,
                                        startLine: frameworkInfo.Line,
                                        startColumn: frameworkInfo.Column
                                        ));
                }
                else if (!frameworkReferenceResolver.IsInstalled(TargetFramework))
                {
                    // If there was an attempt to use reference assemblies but they were not installed
                    // report an error
                    diagnostics.Add(new DiagnosticMessage(
                                        ErrorCodes.DOTNET1011,
                                        $"Framework not installed: {TargetFramework.DotNetFrameworkName} in {ReferenceAssembliesPath}",
                                        filePath: Project.ProjectFilePath,
                                        severity: DiagnosticMessageSeverity.Error,
                                        startLine: frameworkInfo.Line,
                                        startColumn: frameworkInfo.Column
                                        ));
                }
            }

            List <DiagnosticMessage> allDiagnostics = new List <DiagnosticMessage>(diagnostics);

            if (Project != null)
            {
                allDiagnostics.AddRange(Project.Diagnostics);
            }

            // Create a library manager
            var libraryManager = new LibraryManager(libraries.Values.ToList(), allDiagnostics, Project?.ProjectFilePath);

            return(new ProjectContext(
                       globalSettings,
                       mainProject,
                       platformLibrary,
                       TargetFramework,
                       isPortable,
                       runtime,
                       PackagesDirectory,
                       libraryManager,
                       LockFile,
                       diagnostics));
        }