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