Skip to content

Commit 875968b

Browse files
committed
More streamline package reference type code restore.
1 parent 0b1c6d0 commit 875968b

File tree

2 files changed

+75
-62
lines changed

2 files changed

+75
-62
lines changed

src/NuGet.Core/NuGet.PackageManagement/GlobalSuppressions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,4 @@
177177
[assembly: SuppressMessage("Build", "CA2237:Add [Serializable] to PackageReferenceRollbackException as this type implements ISerializable", Justification = "<Pending>", Scope = "type", Target = "~T:NuGet.PackageManagement.PackageReferenceRollbackException")]
178178
[assembly: SuppressMessage("Build", "CA1067:Type NuGet.ProjectManagement.FileTransformExtensions should override Equals because it implements IEquatable<T>", Justification = "<Pending>", Scope = "type", Target = "~T:NuGet.ProjectManagement.FileTransformExtensions")]
179179
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "<Pending>", Scope = "member", Target = "~P:NuGet.PackageManagement.NuGetPackageManager.UpdatedPackageSpecsCache")]
180+
[assembly: SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "<Pending>", Scope = "member", Target = "~F:NuGet.PackageManagement.NuGetPackageManager._buildIntegratedProjectsUpdateSet")]

src/NuGet.Core/NuGet.PackageManagement/NuGetPackageManager.cs

Lines changed: 74 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ public class NuGetPackageManager
4040

4141
public Configuration.ISettings Settings { get; }
4242

43-
private IDictionary<string, bool> _buildIntegratedProjectsUpdateDict;
43+
private HashSet<string> _buildIntegratedProjectsUpdateSet;
4444

45-
private DependencyGraphSpec _buildIntegratedProjectsCache;
45+
private DependencyGraphSpec _buildIntegratedProjectsCache;
4646

4747
private RestoreCommandProvidersCache _restoreProviderCache;
4848

@@ -2054,52 +2054,90 @@ public async Task ExecuteNuGetProjectActionsAsync(IEnumerable<NuGetProject> nuGe
20542054
{
20552055
var projects = nuGetProjects.ToList();
20562056

2057-
// find out build integrated projects so that we can arrange them in reverse dependency order
2057+
// find out build integrated projects
20582058
var buildIntegratedProjectsToUpdate = projects.OfType<BuildIntegratedNuGetProject>().ToList();
20592059

2060-
// order won't matter for other type of projects so just add rest of the projects in result
2061-
var sortedProjectsToUpdate = projects.Except(buildIntegratedProjectsToUpdate).ToList();
2062-
2063-
if (buildIntegratedProjectsToUpdate.Count > 0)
2060+
if (buildIntegratedProjectsToUpdate.Any())
20642061
{
2065-
var logger = new ProjectContextLogger(nuGetProjectContext);
2066-
var referenceContext = new DependencyGraphCacheContext(logger, Settings);
2067-
_buildIntegratedProjectsUpdateDict = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
2068-
2069-
var projectUniqueNamesForBuildIntToUpdate
2070-
= buildIntegratedProjectsToUpdate.ToDictionary((project) => project.MSBuildProjectPath);
2071-
2072-
var dgFile = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(SolutionManager, referenceContext);
2073-
_buildIntegratedProjectsCache = dgFile;
2074-
var allSortedProjects = DependencyGraphSpec.SortPackagesByDependencyOrder(dgFile.Projects);
2062+
_buildIntegratedProjectsUpdateSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
2063+
_buildIntegratedProjectsUpdateSet.AddRange(
2064+
buildIntegratedProjectsToUpdate.Select(child => child.MSBuildProjectPath));
20752065

2076-
foreach (var projectUniqueName in allSortedProjects.Select(e => e.RestoreMetadata.ProjectUniqueName))
2066+
// execute buildintegrated nuget project actions, if any.
2067+
foreach (var project in buildIntegratedProjectsToUpdate)
20772068
{
2078-
BuildIntegratedNuGetProject project;
2079-
if (projectUniqueNamesForBuildIntToUpdate.TryGetValue(projectUniqueName, out project))
2080-
{
2081-
sortedProjectsToUpdate.Add(project);
2082-
}
2083-
}
2069+
var nugetActions = nuGetProjectActions.Where(action => action.Project.Equals(project));
20842070

2085-
// cache these projects which will be used to avoid duplicate restore as part of parent projects
2086-
_buildIntegratedProjectsUpdateDict.AddRange(
2087-
buildIntegratedProjectsToUpdate.Select(child => new KeyValuePair<string, bool>(child.MSBuildProjectPath, false)));
2071+
await ExecuteBuildIntegratedNuGetProjectActionsAsync(project, nugetActions, nuGetProjectContext, token);
2072+
}
20882073
}
20892074

2090-
// execute all nuget project actions
2091-
foreach (var project in sortedProjectsToUpdate)
2075+
var otherProjects = projects.Except(buildIntegratedProjectsToUpdate).ToList();
2076+
2077+
// execute non-buildintegrated nuget project actions
2078+
foreach (var project in otherProjects)
20922079
{
20932080
var nugetActions = nuGetProjectActions.Where(action => action.Project.Equals(project));
2081+
20942082
await ExecuteNuGetProjectActionsAsync(project, nugetActions, nuGetProjectContext, sourceCacheContext, token);
20952083
}
20962084

20972085
// clear cache which could temper with other updates
2098-
_buildIntegratedProjectsUpdateDict?.Clear();
2099-
_buildIntegratedProjectsCache = null;
21002086
_restoreProviderCache = null;
21012087
}
21022088

2089+
/// <summary>
2090+
/// Executes the list of <paramref name="nuGetProjectActions" /> on <paramref name="buildIntegratedProject" />
2091+
/// </summary>
2092+
/// <param name="buildIntegratedProject"></param>
2093+
/// <param name="nuGetProjectActions"></param>
2094+
/// <param name="nuGetProjectContext"></param>
2095+
/// <param name="token"></param>
2096+
/// <returns></returns>
2097+
internal async Task ExecuteBuildIntegratedNuGetProjectActionsAsync(BuildIntegratedNuGetProject buildIntegratedProject,
2098+
IEnumerable<NuGetProjectAction> nuGetProjectActions,
2099+
INuGetProjectContext nuGetProjectContext,
2100+
CancellationToken token)
2101+
{
2102+
if (buildIntegratedProject == null)
2103+
{
2104+
throw new ArgumentNullException(nameof(buildIntegratedProject));
2105+
}
2106+
2107+
if (nuGetProjectActions == null)
2108+
{
2109+
throw new ArgumentNullException(nameof(nuGetProjectActions));
2110+
}
2111+
2112+
if (nuGetProjectContext == null)
2113+
{
2114+
throw new ArgumentNullException(nameof(nuGetProjectContext));
2115+
}
2116+
2117+
token.ThrowIfCancellationRequested();
2118+
2119+
var stopWatch = Stopwatch.StartNew();
2120+
2121+
// DNU: Find the closure before executing the actions
2122+
await ExecuteBuildIntegratedProjectActionsAsync(buildIntegratedProject,
2123+
nuGetProjectActions,
2124+
nuGetProjectContext,
2125+
token);
2126+
2127+
// calculate total time taken to execute all nuget actions
2128+
stopWatch.Stop();
2129+
nuGetProjectContext.Log(
2130+
MessageLevel.Info, Strings.NugetActionsTotalTime,
2131+
DatetimeUtility.ToReadableTimeFormat(stopWatch.Elapsed));
2132+
2133+
// emit resolve actions telemetry event
2134+
var actionTelemetryEvent = new ActionTelemetryStepEvent(
2135+
nuGetProjectContext.OperationId.ToString(),
2136+
TelemetryConstants.ExecuteActionStepName, stopWatch.Elapsed.TotalSeconds);
2137+
2138+
TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent);
2139+
}
2140+
21032141
/// <summary>
21042142
/// Executes the list of <paramref name="nuGetProjectActions" /> on <paramref name="nuGetProject" /> , which is
21052143
/// likely obtained by calling into
@@ -2804,30 +2842,8 @@ await buildIntegratedProject.UninstallPackageAsync(
28042842
var now = DateTime.UtcNow;
28052843
void cacheContextModifier(SourceCacheContext c) => c.MaxAge = now;
28062844

2807-
// Check if current project is there in update cache and needs revaluation
2808-
var isProjectUpdated = false;
2809-
if (_buildIntegratedProjectsUpdateDict != null &&
2810-
_buildIntegratedProjectsUpdateDict.TryGetValue(
2811-
buildIntegratedProject.MSBuildProjectPath,
2812-
out isProjectUpdated) &&
2813-
isProjectUpdated)
2814-
{
2815-
await DependencyGraphRestoreUtility.RestoreProjectAsync(
2816-
SolutionManager,
2817-
buildIntegratedProject,
2818-
referenceContext,
2819-
GetRestoreProviderCache(),
2820-
cacheContextModifier,
2821-
projectAction.Sources,
2822-
nuGetProjectContext.OperationId,
2823-
logger,
2824-
token);
2825-
}
2826-
else
2827-
{
2828-
// Write out the lock file
2829-
await RestoreRunner.CommitAsync(projectAction.RestoreResultPair, token);
2830-
}
2845+
// Write out the lock file
2846+
await RestoreRunner.CommitAsync(projectAction.RestoreResultPair, token);
28312847

28322848
// add packages lock file into project
28332849
if (PackagesLockFileUtilities.IsNuGetLockFileEnabled(projectAction.RestoreResult.LockFile.PackageSpec))
@@ -2895,13 +2911,9 @@ await BuildIntegratedRestoreUtility.ExecuteInitPs1ScriptsAsync(
28952911

28962912
foreach (var parent in parents)
28972913
{
2898-
// if this parent exists in update cache, then update it's entry to be re-evaluated
2899-
if (_buildIntegratedProjectsUpdateDict != null &&
2900-
_buildIntegratedProjectsUpdateDict.ContainsKey(parent.MSBuildProjectPath))
2901-
{
2902-
_buildIntegratedProjectsUpdateDict[parent.MSBuildProjectPath] = true;
2903-
}
2904-
else
2914+
// if this parent not in current target projects list, it's not evaluated project.
2915+
if (_buildIntegratedProjectsUpdateSet == null ||
2916+
_buildIntegratedProjectsUpdateSet.Contains(parent.MSBuildProjectPath))
29052917
{
29062918
// Mark project for restore
29072919
dgSpecForParents.AddRestore(parent.MSBuildProjectPath);

0 commit comments

Comments
 (0)