Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove RelationshipTree for now.
  • Loading branch information
erdembayar committed Aug 2, 2020
commit 7c5eaf421b698261d354ac820472450c26420f41
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
using TelemetryPiiProperty = Microsoft.VisualStudio.Telemetry.TelemetryPiiProperty;
using NuGet.ProjectManagement.Projects;
using NuGet.ProjectModel;
using System.Windows;

namespace NuGet.PackageManagement.UI
{
Expand Down Expand Up @@ -262,7 +261,7 @@ await _packageManager.ExecuteNuGetProjectActionsAsync(
/// <param name="packagesToUpdate">The list of packages to update.</param>
/// <param name="token">Cancellation token.</param>
/// <returns>The list of actions.</returns>
private async Task<(IReadOnlyList<ResolvedAction>, RelationshipTree)> ResolveActionsForUpdateAsync(
private async Task<IReadOnlyList<ResolvedAction>> ResolveActionsForUpdateAsync(
INuGetUI uiService,
List<PackageIdentity> packagesToUpdate,
CancellationToken token)
Expand Down Expand Up @@ -300,7 +299,7 @@ await _packageManager.ExecuteNuGetProjectActionsAsync(
.ToList());
}

return (resolvedActions, null);
return resolvedActions;
}

/// <summary>
Expand All @@ -312,7 +311,7 @@ await _packageManager.ExecuteNuGetProjectActionsAsync(
/// the project actions.</param>
private async Task PerformActionImplAsync(
INuGetUI uiService,
Func<SourceCacheContext, Task<(IReadOnlyList<ResolvedAction>, RelationshipTree)>> resolveActionsAsync,
Func<SourceCacheContext, Task<IReadOnlyList<ResolvedAction>>> resolveActionsAsync,
Func<IReadOnlyList<ResolvedAction>, SourceCacheContext, Task> executeActionsAsync,
NuGetOperationType operationType,
UserAction userAction,
Expand Down Expand Up @@ -374,7 +373,7 @@ await _lockService.ExecuteNuGetOperationAsync(async () =>

using (var sourceCacheContext = new SourceCacheContext())
{
(IReadOnlyList<ResolvedAction> actions, RelationshipTree relationshipTree) = await resolveActionsAsync(sourceCacheContext);
IReadOnlyList<ResolvedAction> actions = await resolveActionsAsync(sourceCacheContext);
var results = GetPreviewResults(actions);

if (operationType == NuGetOperationType.Uninstall)
Expand Down Expand Up @@ -825,7 +824,7 @@ private static PackageIdentity GetDirectInstall(IEnumerable<NuGetProjectAction>
/// <summary>
/// Return the resolve package actions
/// </summary>
private async Task<(IReadOnlyList<ResolvedAction>, RelationshipTree)> GetActionsAsync(
private async Task<IReadOnlyList<ResolvedAction>> GetActionsAsync(
INuGetUI uiService,
IEnumerable<NuGetProject> targets,
UserAction userAction,
Expand All @@ -836,17 +835,13 @@ private static PackageIdentity GetDirectInstall(IEnumerable<NuGetProjectAction>
CancellationToken token)
{
var results = new List<ResolvedAction>();
RelationshipTree relationshipTree =null;

Debug.Assert(userAction.PackageId != null, "Package id can never be null in a User action");
if (userAction.Action == NuGetProjectActionType.Install)
{
// find out build integrated projects so that we can arrange them in reverse dependency order
var buildIntegratedProjectsToUpdate = targets.OfType<BuildIntegratedNuGetProject>().ToList();

// Currently doing RelationshipTree populate only for install action, but if needed move to outside to cover uninstall action too.
relationshipTree = await GetPopulateRelationshipTree(targets.OfType<BuildIntegratedNuGetProject>(), projectContext);

// order won't matter for other type of projects so just add rest of the projects in result
var sortedTargetProjectsToUpdate = targets.Except(buildIntegratedProjectsToUpdate).ToList();
DependencyGraphSpec _buildIntegratedProjectsCache;
Expand Down Expand Up @@ -921,119 +916,7 @@ var projectUniqueNamesForBuildIntToUpdate
}
}

return (results, relationshipTree);
}

private async Task<RelationshipTree> GetPopulateRelationshipTree(IEnumerable<BuildIntegratedNuGetProject> targets, INuGetProjectContext projectContext)
{
if(!targets.Any())
{
return null;
}

var relationshipTree = new RelationshipTree();
DependencyGraphSpec _buildIntegratedProjectsCache;

// find list of buildintegrated projects
//var projects = (await _packageManager.SolutionManager.GetNuGetProjectsAsync()).OfType<BuildIntegratedNuGetProject>().ToList();
//var uniqueProjects = projects.Select(p => p.MSBuildProjectPath).ToHashSet(StringComparer.OrdinalIgnoreCase);

//// build reference cache if there are projects.
//if (uniqueProjects.Any())
//{
var logger = new ProjectContextLogger(projectContext);
var referenceContext = new DependencyGraphCacheContext(logger, _packageManager.Settings);
_buildIntegratedProjectsCache = await
DependencyGraphRestoreUtility.GetSolutionRestoreSpec(_packageManager.SolutionManager, referenceContext);
//}
//else
//{
// return null;
//}

var targetsHash = new HashSet<string>(targets.Select(t => t.MSBuildProjectPath), StringComparer.OrdinalIgnoreCase);

// Build whole relationship tree, it's only made at targeted projects relationship based so cost is not high, we have hundreds times complex calculation inside Remotewalk for all dependencies.
// Can be furthure optimized, I'll do it later if current approach get green light.
// filtering to currently targetted projects, if only just few projects from very large solution with hundreds of solution targetted then not waste too much time figuring out whole tree.
foreach (var target in targets)
{
var closure = _buildIntegratedProjectsCache.GetClosure(target.MSBuildProjectPath).ToList();
var children = closure.Where(c => c.RestoreMetadata.ProjectUniqueName != target.MSBuildProjectPath).ToList();
var ancestor = closure.First(c => c.RestoreMetadata.ProjectUniqueName == target.MSBuildProjectPath);

foreach(var child in children)
{
// Upward traversal not necessary, as go downward we should encounter one another if targets depend each other.
TraverseDownward(child, targetsHash, relationshipTree, _buildIntegratedProjectsCache, ancestor, new Stack<PackageSpec>());
}
}

return relationshipTree;
}

// Currently dfs style approach can be changed to bfs if current approach get green light.
private void TraverseDownward(PackageSpec target, HashSet<string> targets, RelationshipTree relationshipTree, DependencyGraphSpec _buildIntegratedProjectsCache, PackageSpec ancestor, Stack<PackageSpec> path)
{
//if (!relationshipTree.Childs.ContainsKey(target.MSBuildProjectPath))
//{
// relationshipTree.Childs[target.MSBuildProjectPath] = _buildIntegratedProjectsCache.GetClosure(target.MSBuildProjectPath).Where(c => c.RestoreMetadata.ProjectUniqueName != target.MSBuildProjectPath).ToList();
//}

//if(!relationshipTree.Childs.ContainsKey(target.MSBuildProjectPath))
//{
// relationshipTree.Parents[target.MSBuildProjectPath] = _buildIntegratedProjectsCache.GetParentSpecs(target.MSBuildProjectPath).Where(c => c.RestoreMetadata.ProjectUniqueName != target.MSBuildProjectPath).ToList();
//}

var projectUniqueName = string.Empty;

if (target?.RestoreMetadata?.ProjectUniqueName != null)
{
projectUniqueName = target?.RestoreMetadata?.ProjectUniqueName;
}

if(string.IsNullOrWhiteSpace(projectUniqueName))
{
return;
}

if ((!ancestor.RestoreMetadata.ProjectUniqueName.Equals(projectUniqueName, StringComparison.OrdinalIgnoreCase)) && targets.Contains(target.RestoreMetadata.ProjectUniqueName))
{
// Happy path, we found each other
if (!relationshipTree.Descendants.ContainsKey(ancestor.RestoreMetadata.ProjectUniqueName))
{
relationshipTree.Descendants[ancestor.RestoreMetadata.ProjectUniqueName] = new HashSet<PackageSpec>();
}

if (!relationshipTree.Ancestors.ContainsKey(projectUniqueName))
{
relationshipTree.Ancestors[projectUniqueName] = new HashSet<PackageSpec>();
}

while(path.Any())
{
var stop = path.Pop();
relationshipTree.Descendants[ancestor.RestoreMetadata.ProjectUniqueName].Add(stop);
relationshipTree.Ancestors[projectUniqueName].Add(stop);
}

relationshipTree.Descendants[ancestor.RestoreMetadata.ProjectUniqueName].Add(target);
relationshipTree.Ancestors[projectUniqueName].Add(ancestor);
}

//var children = target
// .TargetFrameworks
// .SelectMany(f => f.FrameworkReferences)
// .ToArray();

var children = _buildIntegratedProjectsCache.GetClosure(target.RestoreMetadata.ProjectUniqueName).Where(c => c.RestoreMetadata.ProjectUniqueName != projectUniqueName).ToList();
var newPath = new Stack<PackageSpec>(path);
newPath.Push(target);

foreach(var child in children)
{
TraverseDownward(child, targets, relationshipTree, _buildIntegratedProjectsCache, ancestor, newPath);
}
return results;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ public async Task<NuGetProject> GetDefaultNuGetProjectAsync()

public string DefaultNuGetProjectName { get; set; }

public RelationshipTree TargettedRelationshipTree { get; set; }

#region Events

public event EventHandler<NuGetProjectEventArgs> NuGetProjectAdded;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ public class NuGetPackageManager

public IInstallationCompatibility InstallationCompatibility { get; set; }

#pragma warning disable CA2227 // Collection properties should be read only
public Dictionary<string, PackageSpec> UpdatedPackageSpecsCache { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only

/// <summary>
/// Event to be raised when batch processing of install/ uninstall packages starts at a project level
Expand Down
18 changes: 0 additions & 18 deletions src/NuGet.Core/NuGet.PackageManagement/RelationshipTree.cs

This file was deleted.

11 changes: 3 additions & 8 deletions src/NuGet.Core/NuGet.ProjectModel/DependencyGraphSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,6 @@ public PackageSpec GetProjectSpec(string projectUniqueName)
}

public IReadOnlyList<string> GetParents(string rootUniqueName)
{
return GetParentSpecs(rootUniqueName)
.Select(e => e.RestoreMetadata.ProjectUniqueName)
.ToList();
}

public IReadOnlyList<PackageSpec> GetParentSpecs(string rootUniqueName)
{
var parents = new List<PackageSpec>();

Expand All @@ -128,7 +121,9 @@ public IReadOnlyList<PackageSpec> GetParentSpecs(string rootUniqueName)
}
}

return parents;
return parents
.Select(e => e.RestoreMetadata.ProjectUniqueName)
.ToList();
}

/// <summary>
Expand Down