public async Task <bool> RestoreAsync(string entryProjectFilePath, IDictionary <string, string> globalProperties, IReadOnlyDictionary <string, string> options) { var dependencyGraphSpec = GetDependencyGraphSpec(entryProjectFilePath, globalProperties); // If the dependency graph spec is null, something went wrong evaluating the projects, so return false if (dependencyGraphSpec == null) { return(false); } try { return(await BuildTasksUtility.RestoreAsync( dependencyGraphSpec : dependencyGraphSpec, interactive : IsOptionTrue(nameof(RestoreTaskEx.Interactive), options), recursive : IsOptionTrue(nameof(RestoreTaskEx.Recursive), options), noCache : IsOptionTrue(nameof(RestoreTaskEx.NoCache), options), ignoreFailedSources : IsOptionTrue(nameof(RestoreTaskEx.IgnoreFailedSources), options), disableParallel : IsOptionTrue(nameof(RestoreTaskEx.DisableParallel), options), force : IsOptionTrue(nameof(RestoreTaskEx.Force), options), forceEvaluate : IsOptionTrue(nameof(RestoreTaskEx.ForceEvaluate), options), hideWarningsAndErrors : IsOptionTrue(nameof(RestoreTaskEx.HideWarningsAndErrors), options), restorePC : IsOptionTrue(nameof(RestoreTaskEx.RestorePackagesConfig), options), log : MSBuildLogger, cancellationToken : CancellationToken.None)); } catch (Exception e) { LoggingQueue.TaskLoggingHelper.LogErrorFromException(e, showStackTrace: true); return(false); } }
/// <summary> /// Gets the package sources of the specified project. /// </summary> /// <param name="project">An <see cref="IMSBuildItem" /> representing the project..</param> /// <param name="innerNodes">An <see cref="IReadOnlyCollection{IMSBuildItem}" /> containing the inner nodes of the project if its targets multiple frameworks.</param> /// <param name="settings">The <see cref="ISettings" /> of the specified project.</param> /// <returns>A <see cref="List{PackageSource}" /> object containing the packages sources for the specified project.</returns> internal static List <PackageSource> GetSources(IMSBuildProject project, IReadOnlyCollection <IMSBuildProject> innerNodes, ISettings settings) { return(BuildTasksUtility.GetSources( project.Directory, project.SplitPropertyValueOrNull("RestoreSources"), project.SplitPropertyValueOrNull("RestoreSourcesOverride"), innerNodes.SelectMany(i => MSBuildStringUtility.Split(i.GetProperty("RestoreAdditionalProjectSources"))), settings) .Select(i => new PackageSource(i)) .ToList()); }
public void GetSources_WithRestoreSourcesGlobal_Property_ResolvesAgainstWorkingDirectory() { using (var testDir = TestDirectory.CreateInTemp()) { // Arrange var startupDirectory = Path.Combine(testDir, "startup"); var projectDirectory = Path.Combine(testDir, "project"); var relativePath = "relativeSource"; // Act var effectiveSources = BuildTasksUtility.GetSources( startupDirectory: startupDirectory, projectDirectory: projectDirectory, sources: new string[] { relativePath }, sourcesOverride: new string[] { relativePath }, additionalProjectSources: Array.Empty <string>(), settings: NullSettings.Instance ); // Assert effectiveSources.ShouldBeEquivalentTo(new[] { Path.Combine(startupDirectory, relativePath) }); } }
/// <summary> /// Gets the restore metadata and target framework information for the specified project. /// </summary> /// <param name="project">An <see cref="IMSBuildProject" /> representing the project.</param> /// <param name="projectsByTargetFramework">A <see cref="IReadOnlyDictionary{NuGetFramework,IMSBuildProject}" /> containing the inner nodes by target framework.</param> /// <param name="settings">The <see cref="ISettings" /> of the specified project.</param> /// <returns>A <see cref="Tuple" /> containing the <see cref="ProjectRestoreMetadata" /> and <see cref="List{TargetFrameworkInformation}" /> for the specified project.</returns> private (ProjectRestoreMetadata RestoreMetadata, List <TargetFrameworkInformation> TargetFrameworkInfos) GetProjectRestoreMetadataAndTargetFrameworkInformation(IMSBuildProject project, IReadOnlyDictionary <NuGetFramework, IMSBuildProject> projectsByTargetFramework, ISettings settings) { var projectName = GetProjectName(project); var outputPath = GetRestoreOutputPath(project); var targetFrameworkInfos = GetTargetFrameworkInfos(projectsByTargetFramework); var projectStyleResult = BuildTasksUtility.GetProjectRestoreStyle( restoreProjectStyle: project.GetProperty("RestoreProjectStyle"), hasPackageReferenceItems: targetFrameworkInfos.Any(i => i.Dependencies.Any()), projectJsonPath: project.GetProperty("_CurrentProjectJsonPath"), projectDirectory: project.Directory, projectName: project.GetProperty("MSBuildProjectName"), log: MSBuildLogger); var projectStyle = projectStyleResult.ProjectStyle; var innerNodes = projectsByTargetFramework.Values.ToList(); ProjectRestoreMetadata restoreMetadata; if (projectStyle == ProjectStyle.PackagesConfig) { restoreMetadata = new PackagesConfigProjectRestoreMetadata { PackagesConfigPath = projectStyleResult.PackagesConfigFilePath, RepositoryPath = GetRepositoryPath(project, settings) }; } else { restoreMetadata = new ProjectRestoreMetadata { CrossTargeting = (projectStyle == ProjectStyle.PackageReference || projectStyle == ProjectStyle.DotnetToolReference) && projectsByTargetFramework.Count > 1, FallbackFolders = BuildTasksUtility.GetFallbackFolders( project.Directory, project.SplitPropertyValueOrNull("RestoreFallbackFolders"), project.SplitPropertyValueOrNull("RestoreFallbackFoldersOverride"), innerNodes.SelectMany(i => MSBuildStringUtility.Split(i.GetProperty("RestoreAdditionalProjectFallbackFolders"))), innerNodes.SelectMany(i => MSBuildStringUtility.Split(i.GetProperty("RestoreAdditionalProjectFallbackFoldersExcludes"))), settings), SkipContentFileWrite = IsLegacyProject(project), ValidateRuntimeAssets = project.IsPropertyTrue("ValidateRuntimeIdentifierCompatibility") }; } restoreMetadata.CacheFilePath = NoOpRestoreUtilities.GetProjectCacheFilePath(outputPath, project.FullPath); restoreMetadata.ConfigFilePaths = settings.GetConfigFilePaths(); restoreMetadata.OutputPath = outputPath; restoreMetadata.OriginalTargetFrameworks = GetOriginalTargetFrameworks(project, projectsByTargetFramework.Keys.ToList()); restoreMetadata.PackagesPath = GetPackagesPath(project, settings); restoreMetadata.ProjectName = projectName; restoreMetadata.ProjectPath = project.FullPath; restoreMetadata.ProjectStyle = projectStyle; restoreMetadata.ProjectUniqueName = project.FullPath; restoreMetadata.ProjectWideWarningProperties = WarningProperties.GetWarningProperties(project.GetProperty("TreatWarningsAsErrors"), project.GetProperty("WarningsAsErrors"), project.GetProperty("NoWarn")); restoreMetadata.RestoreLockProperties = new RestoreLockProperties(project.GetProperty("RestorePackagesWithLockFile"), project.GetProperty("NuGetLockFilePath"), project.IsPropertyTrue("RestoreLockedMode")); restoreMetadata.Sources = GetSources(project, innerNodes, settings); restoreMetadata.TargetFrameworks = GetProjectRestoreMetadataFrameworkInfos(projectsByTargetFramework); return(restoreMetadata, targetFrameworkInfos); }
/// <summary> /// Gets a <see cref="DependencyGraphSpec" /> for the specified project. /// </summary> /// <param name="entryProjectPath">The full path to a project or Visual Studio Solution File.</param> /// <param name="globalProperties">An <see cref="IDictionary{String,String}" /> containing the global properties to use when evaluation MSBuild projects.</param> /// <returns>A <see cref="DependencyGraphSpec" /> for the specified project if they could be loaded, otherwise <code>null</code>.</returns> private DependencyGraphSpec GetDependencyGraphSpec(string entryProjectPath, IDictionary <string, string> globalProperties) { try { // TODO: Use a localized resource from https://github.com/NuGet/NuGet.Client/pull/3111 MSBuildLogger.LogMinimal("Determining projects to restore..."); var entryProjects = GetProjectGraphEntryPoints(entryProjectPath, globalProperties); // Load the projects via MSBuild and create an array of them since Parallel.ForEach is optimized for arrays var projects = LoadProjects(entryProjects)?.ToArray(); // If no projects were loaded, return null indicating that the projects could not be loaded. if (projects == null || projects.Length == 0) { return(null); } var sw = Stopwatch.StartNew(); var dependencyGraphSpec = new DependencyGraphSpec(isReadOnly: true); // Unique names created by the MSBuild restore target are project paths, these // can be different on case-insensitive file systems for the same project file. // To workaround this unique names should be compared based on the OS. var uniqueNameComparer = PathUtility.GetStringComparerBasedOnOS(); var projectPathLookup = new ConcurrentDictionary <string, string>(uniqueNameComparer); try { // Get the PackageSpecs in parallel because creating each one is relatively expensive so parallelism speeds things up Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, project => { var packageSpec = GetPackageSpec(project.OuterProject, project); if (packageSpec != null) { // Keep track of all project path casings var uniqueName = packageSpec.RestoreMetadata.ProjectUniqueName; if (uniqueName != null && !projectPathLookup.ContainsKey(uniqueName)) { projectPathLookup.TryAdd(uniqueName, uniqueName); } var projectPath = packageSpec.RestoreMetadata.ProjectPath; if (projectPath != null && !projectPathLookup.ContainsKey(projectPath)) { projectPathLookup.TryAdd(projectPath, projectPath); } // TODO: Remove this lock once https://github.com/NuGet/Home/issues/9002 is fixed lock (dependencyGraphSpec) { dependencyGraphSpec.AddProject(packageSpec); } } }); } catch (AggregateException e) { // Log exceptions thrown while creating PackageSpec objects foreach (var exception in e.Flatten().InnerExceptions) { LoggingQueue.TaskLoggingHelper.LogErrorFromException(exception); } return(null); } // Fix project reference casings to match the original project on case insensitive file systems. MSBuildRestoreUtility.NormalizePathCasings(projectPathLookup, dependencyGraphSpec); // Add all entry projects if they support restore. In most cases this is just a single project but if the entry // project is a solution, then all projects in the solution are added (if they support restore) foreach (var entryPoint in entryProjects) { PackageSpec project = dependencyGraphSpec.GetProjectSpec(entryPoint.ProjectFile); if (project != null && BuildTasksUtility.DoesProjectSupportRestore(project)) { dependencyGraphSpec.AddRestore(entryPoint.ProjectFile); } } sw.Stop(); MSBuildLogger.LogDebug(string.Format(CultureInfo.CurrentCulture, Strings.CreatedDependencyGraphSpec, sw.ElapsedMilliseconds)); return(dependencyGraphSpec); } catch (Exception e) { LoggingQueue.TaskLoggingHelper.LogErrorFromException(e, showStackTrace: true); } return(null); }