Skip to content
Permalink
Browse files

[Assets] Properly process dependency graph using remote info to perfo…

…rm package upgrades before downloading nuget packages
  • Loading branch information
xen2 committed Sep 6, 2018
1 parent b9e915a commit 1d51c472eb7622005881985916c99ab3af0e0a81
@@ -78,7 +78,7 @@ IEnumerator IEnumerable.GetEnumerator()
public Package Find(Dependency dependency)
{
if (dependency == null) throw new ArgumentNullException(nameof(dependency));
return Find(dependency.Name, dependency.VersionRange);
return Find(dependency.Name, new PackageVersionRange(dependency.Version));
}

/// <summary>

Large diffs are not rendered by default.

@@ -7,8 +7,6 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Build.Evaluation;
using NuGet.ProjectModel;
using Xenko.Core;
using Xenko.Core.Annotations;
using Xenko.Core.Assets.Analysis;
@@ -43,7 +41,7 @@ public PackageContainer([NotNull] Package package)
[NotNull]
public Package Package { get; }

public List<Package> LoadedDependencies { get; } = new List<Package>();
public ObservableCollection<Package> LoadedDependencies { get; } = new ObservableCollection<Package>();

internal void SetSessionInternal(PackageSession session)
{
@@ -69,7 +67,25 @@ public enum DependencyType

public class Dependency
{
public Dependency(string name, PackageVersionRange versionRange, DependencyType type)
public Dependency(string name, PackageVersion version, DependencyType type)
{
Name = name;
Version = version;
Type = type;
}

public string Name { get; set; }

public string MSBuildProject { get; set; }

public PackageVersion Version { get; set; }

public DependencyType Type { get; set; }
}

public class DependencyRange
{
public DependencyRange(string name, PackageVersionRange versionRange, DependencyType type)
{
Name = name;
VersionRange = versionRange;
@@ -78,6 +94,8 @@ public Dependency(string name, PackageVersionRange versionRange, DependencyType

public string Name { get; set; }

public string MSBuildProject { get; set; }

public PackageVersionRange VersionRange { get; set; }

public DependencyType Type { get; set; }
@@ -130,7 +148,9 @@ public SolutionProject(Package package, VisualStudio.Project vsProject)

public ProjectState State { get; set; }

public List<Dependency> Dependencies { get; } = new List<Dependency>();
public ObservableCollection<DependencyRange> DirectDependencies { get; } = new ObservableCollection<DependencyRange>();

public ObservableCollection<Dependency> FlattenedDependencies { get; } = new ObservableCollection<Dependency>();
}

public sealed class ProjectCollection : ObservableCollection<PackageContainer>
@@ -140,7 +160,7 @@ public sealed class ProjectCollection : ObservableCollection<PackageContainer>
/// <summary>
/// A session for editing a package.
/// </summary>
public sealed class PackageSession : IDisposable, IAssetFinder
public sealed partial class PackageSession : IDisposable, IAssetFinder
{
/// <summary>
/// The visual studio version property used for newly created project solution files
@@ -305,7 +325,7 @@ public IEnumerable<Package> GetPackagesFromCurrent()
yield return CurrentProject.Package;
}

foreach (var dependency in CurrentProject.Dependencies)
foreach (var dependency in CurrentProject.FlattenedDependencies)
{
var loadedPackage = packages.Find(dependency);
// In case the package is not found (when working with session not fully loaded/resolved with all deps)
@@ -631,7 +651,7 @@ public void LoadMissingDependencies(ILogger log, PackageLoadParameters loadParam
}

if (project is SolutionProject solutionProject)
PreLoadPackageDependencies(log, solutionProject, loadParameters);
PreLoadPackageDependencies(log, solutionProject, loadParameters).Wait();
}
}

@@ -1281,100 +1301,6 @@ private static PackageUpgrader CheckPackageUpgrade(ILogger log, Package dependen

return null;
}

private void PreLoadPackageDependencies(ILogger log, SolutionProject project, PackageLoadParameters loadParameters)
{
if (log == null) throw new ArgumentNullException(nameof(log));
if (project == null) throw new ArgumentNullException(nameof(project));
if (loadParameters == null) throw new ArgumentNullException(nameof(loadParameters));

bool packageDependencyErrors = false;

// TODO: Remove and recheck Dependencies Ready if some secondary packages are removed?
if (project.State >= ProjectState.DependenciesReady)
return;

project.Dependencies.Clear();
project.LoadedDependencies.Clear();

log.Verbose("Restore NuGet packages...");
VSProjectHelper.RestoreNugetPackages(log, project.FullPath).Wait();

var projectAssetsJsonPath = Path.Combine(project.FullPath.GetFullDirectory(), @"obj", LockFileFormat.AssetsFileName);
if (File.Exists(projectAssetsJsonPath))
{
var format = new LockFileFormat();
var projectAssets = format.Read(projectAssetsJsonPath);

// Update dependencies
foreach (var library in projectAssets.Libraries)
{
// TODO CSPROJ=XKPKG rewrite this with new nuget code
project.Dependencies.Add(new Dependency(library.Name, new PackageVersionRange(new PackageVersion(library.Version.Version, library.Version.Release)), library.Type == "project" ? DependencyType.Project : DependencyType.Package));
}

// Load dependency (if external)

// Compute output path
}


// 1. Load store package
foreach (var projectDependency in project.Dependencies)
{
var loadedPackage = packages.Find(projectDependency);
if (loadedPackage == null)
{
var file = PackageStore.Instance.GetPackageFileName(projectDependency.Name, new PackageVersionRange(new PackageVersion(projectDependency.VersionRange.MinVersion.Version, projectDependency.VersionRange.MinVersion.SpecialVersion)), constraintProvider);

if (file == null)
{
// TODO: We need to support automatic download of packages. This is not supported yet when only Xenko
// package is supposed to be installed, but It will be required for full store
log.Error($"The project {project.Name ?? "[Untitled]"} depends on project or package {projectDependency} which is not installed");
packageDependencyErrors = true;
continue;
}

// Load package
loadedPackage = PreLoadPackage(log, file, true, loadParameters);
Projects.Add(new StandalonePackage(loadedPackage));
}

if (loadedPackage != null)
project.LoadedDependencies.Add(loadedPackage);
// TODO CSPROJ=XKPKG
//if (loadedPackage == null || loadedPackage.State < ProjectState.DependenciesReady)
// packageDependencyErrors = true;
}

// 2. Load local packages
/*foreach (var packageReference in package.LocalDependencies)
{
// Check that the package was not already loaded, otherwise return the same instance
if (Packages.ContainsById(packageReference.Id))
{
continue;
}
// Expand the string of the location
var newLocation = packageReference.Location;
var subPackageFilePath = package.RootDirectory != null ? UPath.Combine(package.RootDirectory, newLocation) : newLocation;
// Recursive load
var loadedPackage = PreLoadPackage(log, subPackageFilePath.FullPath, false, loadedPackages, loadParameters);
if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
packageDependencyErrors = true;
}*/

// 3. Update package state
if (!packageDependencyErrors)
{
project.State = ProjectState.DependenciesReady;
}
}

public class PendingPackageUpgrade
{
@@ -9,8 +9,10 @@
using Microsoft.Build.Evaluation;
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
using NuGet.ProjectModel;
using Xenko.Core;
using Xenko.Core.Diagnostics;
using Xenko.Core.IO;
using ILogger = Xenko.Core.Diagnostics.ILogger;

namespace Xenko.Core.Assets
@@ -114,6 +116,48 @@ public static ICancellableAsyncBuild CompileProjectAssemblyAsync(string solution
return null;
}

public static async Task<DependencyGraphSpec> GenerateRestoreGraphFile(ILogger logger, string projectPath)
{
DependencyGraphSpec spec = null;
using (var restoreGraphResult = new TemporaryFile())
{
await Task.Run(() =>
{
var pc = new Microsoft.Build.Evaluation.ProjectCollection();

try
{
var parameters = new BuildParameters(pc)
{
Loggers = new[] { new LoggerRedirect(logger, true) } //Instance of ILogger instantiated earlier
};

// Run a MSBuild /t:Restore <projectfile>
var request = new BuildRequestData(projectPath, new Dictionary<string, string> { { "RestoreGraphOutputPath", restoreGraphResult.Path }, { "RestoreRecursive", "false" } }, null, new[] { "GenerateRestoreGraphFile" }, null, BuildRequestDataFlags.None);

mainBuildManager.Build(parameters, request);
}
finally
{
pc.UnloadAllProjects();
pc.Dispose();
}
});

if (File.Exists(restoreGraphResult.Path) && new FileInfo(restoreGraphResult.Path).Length != 0)
{
spec = DependencyGraphSpec.Load(restoreGraphResult.Path);
File.Delete(restoreGraphResult.Path);
}
else
{
spec = new DependencyGraphSpec();
}
}

return spec;
}

public static async Task RestoreNugetPackages(ILogger logger, string projectPath)
{
if (Path.GetExtension(projectPath)?.ToLowerInvariant() == ".csproj")
@@ -1,4 +1,4 @@
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

using System;
@@ -13,7 +13,7 @@

namespace Xenko.Core.Packages
{
internal static class NuGet3Extensions
public static class NuGet3Extensions
{
/// <summary>
/// Converts a <see cref="VersionRange"/> into a <see cref="PackageVersionRange"/>.
@@ -5,7 +5,7 @@

namespace Xenko.Core.IO
{
internal partial class TemporaryFile : IDisposable
public partial class TemporaryFile : IDisposable
{
private bool isDisposed;
private string path;
@@ -68,6 +68,14 @@ protected override void UpdateIsDeletedStatus()
}
}

public class DependencyViewModel : PackageReferenceViewModel
{
public DependencyViewModel(PackageViewModel target, PackageViewModel referencer, DependencyCategoryViewModel dependencies)
{

}
}

/// <summary>
/// Implementation of the <see cref="PackageReferenceViewModel"/> for local package references.
/// </summary>
@@ -451,7 +451,7 @@ private static PackageLoadParameters CreatePackageLoadParameters(WorkProgressVie

foreach (var pendingUpgrade in pendingUpgrades)
{
message.AppendLine(string.Format(Tr._p("Message", "- Dependency to **{0}** must be upgraded from version **{1}** to **{2}**"), pendingUpgrade.Dependency.Name, pendingUpgrade.Dependency.Version, pendingUpgrade.DependencyPackage.Meta.Version));
message.AppendLine(string.Format(Tr._p("Message", "- Dependency to **{0}** must be upgraded from version **{1}** to **{2}**"), pendingUpgrade.Dependency.Name, pendingUpgrade.Dependency.Version, pendingUpgrade.PackageUpgrader.Attribute.UpdatedVersionRange.MinVersion));
}

message.AppendLine();

0 comments on commit 1d51c47

Please sign in to comment.
You can’t perform that action at this time.