Skip to content

Commit

Permalink
WIP: use resolved version of package from assets file
Browse files Browse the repository at this point in the history
  • Loading branch information
Pato Beltran committed Sep 28, 2017
1 parent f82b986 commit 9415900
Show file tree
Hide file tree
Showing 18 changed files with 312 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ public override void CleanUp()
protected override void CreateVersions()
{
_versions = new List<DisplayVersion>();
var installedDependency = InstalledPackageDependencies.Where(p =>
StringComparer.OrdinalIgnoreCase.Equals(p.Id, Id) && p.VersionRange != null && p.VersionRange.HasLowerBound)
.OrderByDescending(p => p.VersionRange.MinVersion)
var installedDependency = InstalledPackages.Where(p =>
StringComparer.OrdinalIgnoreCase.Equals(p.Id, Id))
.OrderByDescending(p => p.Version)
.FirstOrDefault();

// installVersion is null if the package is not installed
var installedVersion = installedDependency?.VersionRange?.MinVersion;
var installedVersion = installedDependency?.Version;

var allVersions = _allPackageVersions?.OrderByDescending(v => v).ToArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using NuGet.PackageManagement.VisualStudio;
using NuGet.Packaging.Core;
using NuGet.ProjectManagement;
using NuGet.ProjectManagement.Projects;
using NuGet.Protocol.Core.Types;
using NuGet.Resolver;
using NuGet.Versioning;
Expand Down Expand Up @@ -99,6 +100,7 @@ public PackageManagerControl(
_uiLogger = uiLogger;
Model = model;
Settings = nugetSettings;

if (!Model.IsSolution)
{
_detailModel = new PackageDetailControlModel(Model.Context.SolutionManager, Model.Context.Projects);
Expand Down Expand Up @@ -627,6 +629,12 @@ private void SearchPackagesAndRefreshUpdateCount(string searchText, bool useCach
{
NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
foreach (var project in Model.Context.Projects)
{
// Read the dependencies out off the latest asset file
await Task.Run(() => DependencyVersionLookup.LoadAssetsFileAndCreateLookupForProjectAsync(project as INuGetIntegratedProject));
}
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var loadContext = new PackageLoadContext(ActiveSources, Model.IsSolution, Model.Context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public LegacyPackageReferenceProject(
IVsProjectAdapter vsProjectAdapter,
string projectId,
INuGetProjectServices projectServices,
IVsProjectThreadingService threadingService)
IVsProjectThreadingService threadingService) :
base()
{
Assumes.Present(vsProjectAdapter);
Assumes.NotNullOrEmpty(projectId);
Expand Down Expand Up @@ -131,7 +132,7 @@ public override async Task<IReadOnlyList<PackageSpec>> GetPackageSpecsAsync(Depe
public override async Task<IEnumerable<PackageReference>> GetInstalledPackagesAsync(CancellationToken token)
{
// Settings are not needed for this purpose, this only finds the installed packages
return GetPackageReferences(await GetPackageSpecAsync(NullSettings.Instance));
return GetPackageReferences(await GetPackageSpecAsync(NullSettings.Instance), _dependencyVersionLookup);
}

public override async Task<bool> InstallPackageAsync(
Expand Down Expand Up @@ -251,30 +252,35 @@ private IList<string> GetConfigFilePaths(ISettings settings)
return SettingsUtility.GetConfigFilePaths(settings).ToList();
}

private static PackageReference[] GetPackageReferences(PackageSpec packageSpec)
private static PackageReference[] GetPackageReferences(PackageSpec packageSpec, DependencyVersionLookup lookup)
{
var frameworkSorter = new NuGetFrameworkSorter();

return packageSpec
.TargetFrameworks
.SelectMany(f => GetPackageReferences(f.Dependencies, f.FrameworkName))
.SelectMany(f => GetPackageReferences(f.Dependencies, f.FrameworkName, lookup))
.GroupBy(p => p.PackageIdentity)
.Select(g => g.OrderBy(p => p.TargetFramework, frameworkSorter).First())
.ToArray();
}

private static IEnumerable<PackageReference> GetPackageReferences(IEnumerable<LibraryDependency> libraries, NuGetFramework targetFramework)
private static IEnumerable<PackageReference> GetPackageReferences(IEnumerable<LibraryDependency> libraries, NuGetFramework targetFramework, DependencyVersionLookup lookup)
{
return libraries
.Where(l => l.LibraryRange.TypeConstraint == LibraryDependencyTarget.Package)
.Select(l => ToPackageReference(l, targetFramework));
.Select(l => ToPackageReference(l, targetFramework, lookup));
}

private static PackageReference ToPackageReference(LibraryDependency library, NuGetFramework targetFramework)
private static PackageReference ToPackageReference(LibraryDependency library, NuGetFramework targetFramework, DependencyVersionLookup lookup)
{
NuGetVersion version;
if (!lookup.TryGet(library.LibraryRange.Name, out version))
{
version = library.LibraryRange.VersionRange.MinVersion;
}
var identity = new PackageIdentity(
library.LibraryRange.Name,
library.LibraryRange.VersionRange.MinVersion);
version);

return new PackageReference(identity, targetFramework);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public NetCorePackageReferenceProject(
IVsProjectAdapter vsProjectAdapter,
UnconfiguredProject unconfiguredProject,
INuGetProjectServices projectServices,
string projectId)
string projectId) :
base()
{
Assumes.Present(projectFullPath);
Assumes.Present(projectSystemCache);
Expand All @@ -66,6 +67,7 @@ public NetCorePackageReferenceProject(
_projectSystemCache = projectSystemCache;
_vsProjectAdapter = vsProjectAdapter;
_unconfiguredProject = unconfiguredProject;
_dependencyVersionLookup = new DependencyVersionLookup();
ProjectServices = projectServices;

InternalMetadata.Add(NuGetProjectMetadataKeys.Name, _projectName);
Expand Down Expand Up @@ -190,7 +192,7 @@ public override Task<IEnumerable<PackageReference>> GetInstalledPackagesAsync(Ca
var packageSpec = GetPackageSpec();
if (packageSpec != null)
{
installedPackages = GetPackageReferences(packageSpec);
installedPackages = GetPackageReferences(packageSpec, _dependencyVersionLookup);
}
else
{
Expand All @@ -200,23 +202,23 @@ public override Task<IEnumerable<PackageReference>> GetInstalledPackagesAsync(Ca
return Task.FromResult<IEnumerable<PackageReference>>(installedPackages);
}

private static PackageReference[] GetPackageReferences(PackageSpec packageSpec)
private static PackageReference[] GetPackageReferences(PackageSpec packageSpec, DependencyVersionLookup lookup)
{
var frameworkSorter = new NuGetFrameworkSorter();

return packageSpec
.TargetFrameworks
.SelectMany(f => GetPackageReferences(f.Dependencies, f.FrameworkName))
.SelectMany(f => GetPackageReferences(f.Dependencies, f.FrameworkName, lookup))
.GroupBy(p => p.PackageIdentity)
.Select(g => g.OrderBy(p => p.TargetFramework, frameworkSorter).First())
.ToArray();
}

private static IEnumerable<PackageReference> GetPackageReferences(IEnumerable<LibraryDependency> libraries, NuGetFramework targetFramework)
private static IEnumerable<PackageReference> GetPackageReferences(IEnumerable<LibraryDependency> libraries, NuGetFramework targetFramework, DependencyVersionLookup lookup)
{
return libraries
.Where(l => l.LibraryRange.TypeConstraint == LibraryDependencyTarget.Package)
.Select(l => new BuildIntegratedPackageReference(l, targetFramework));
.Select(l => new BuildIntegratedPackageReference(l, targetFramework, lookup));
}

public override async Task<bool> InstallPackageAsync(
Expand Down Expand Up @@ -276,8 +278,21 @@ await conditionalService.AddAsync(
// This is the update operation
if (!result.Added)
{
var existingReference = result.Reference;
await existingReference.Metadata.SetPropertyValueAsync("Version", formattedRange);
var existingReferenceMetadata = result.Reference.Metadata;
var currentVersionString = await existingReferenceMetadata.GetEvaluatedPropertyValueAsync("Version");
var currentVersion = VersionRange.Parse(currentVersionString);

// Only update the package reference if any:
// 1. The current version is not floating or a range
// 2. The current version is a range and the new version is not a subset of it
// 3. The current version is a float and the new version doesn't satisfies it
var currentIsSingleVersion = (!currentVersion.IsFloating && !currentVersion.WasOriginallyRange);
var currentIsRangeAndNewIsNotSubset = currentVersion.WasOriginallyRange && !range.IsSubSetOrEqualTo(currentVersion);
var currentIsFloatAndNewDoesNotSatisfies = currentVersion.IsFloating && !currentVersion.Float.Satisfies(range.MinVersion);
if (currentIsSingleVersion || currentIsRangeAndNewIsNotSubset || currentIsFloatAndNewDoesNotSatisfies)
{
await existingReferenceMetadata.SetPropertyValueAsync("Version", formattedRange);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public override Task PreProcessAsync(INuGetProjectContext nuGetProjectContext, C
}

[SuppressMessage("Microsoft.VisualStudio.Threading.Analyzers", "VSTHRD002", Justification = "NuGet/Home#4833 Baseline")]
public ProjectKNuGetProject(INuGetPackageManager project, string projectName, string uniqueName, string projectId)
public ProjectKNuGetProject(INuGetPackageManager project, string projectName, string uniqueName, string projectId) : base()
{
_project = project;
InternalMetadata.Add(NuGetProjectMetadataKeys.Name, projectName);
Expand Down Expand Up @@ -187,13 +187,17 @@ public override async Task<IEnumerable<PackageReference>> GetInstalledPackagesAs
var moniker = item as INuGetPackageMoniker;
if (moniker != null)
{
// As with build integrated projects (UWP project.json), treat the version as a
// version range and use the minimum version of that range. Eventually, this
// method should return VersionRange instances, not NuGetVersion so that the
// UI can express the full project.json intent. This improvement is tracked
// here: https://github.com/NuGet/Home/issues/3101
var versionRange = VersionRange.Parse(moniker.Version);
var version = versionRange.MinVersion;
NuGetVersion version;
if (!_dependencyVersionLookup.TryGet(moniker.Id, out version))
{
// As with build integrated projects (UWP project.json), treat the version as a
// version range and use the minimum version of that range. Eventually, this
// method should return VersionRange instances, not NuGetVersion so that the
// UI can express the full project.json intent. This improvement is tracked
// here: https://github.com/NuGet/Home/issues/3101
var versionRange = VersionRange.Parse(moniker.Version);
version = versionRange.MinVersion;
}

identity = new PackageIdentity(moniker.Id, version);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public VsPathContextProvider(
_settings = settings;
_solutionManager = solutionManager;
_logger = logger;
_getLockFileOrNullAsync = BuildIntegratedProjectUtility.GetLockFileOrNull;
_getLockFileOrNullAsync = IntegratedProjectUtility.GetLockFileOrNull;

_dte = new AsyncLazy<EnvDTE.DTE>(
async () =>
Expand Down Expand Up @@ -105,7 +105,7 @@ public VsPathContextProvider(
_settings = new Lazy<ISettings>(() => settings);
_solutionManager = new Lazy<IVsSolutionManager>(() => solutionManager);
_logger = new Lazy<NuGet.Common.ILogger>(() => logger);
_getLockFileOrNullAsync = getLockFileOrNullAsync ?? BuildIntegratedProjectUtility.GetLockFileOrNull;
_getLockFileOrNullAsync = getLockFileOrNullAsync ?? IntegratedProjectUtility.GetLockFileOrNull;
}

public bool TryCreateContext(string projectUniqueName, out IVsPathContext outputPathContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public InstalledPackageEnumerator(

_solutionManager = solutionManager;
_settings = settings;
_getLockFileOrNullAsync = BuildIntegratedProjectUtility.GetLockFileOrNull;
_getLockFileOrNullAsync = IntegratedProjectUtility.GetLockFileOrNull;
}

/// <summary>
Expand All @@ -113,7 +113,7 @@ internal InstalledPackageEnumerator(

_solutionManager = solutionManager;
_settings = settings;
_getLockFileOrNullAsync = getLockFileOrNullAsync ?? BuildIntegratedProjectUtility.GetLockFileOrNull;
_getLockFileOrNullAsync = getLockFileOrNullAsync ?? IntegratedProjectUtility.GetLockFileOrNull;
}

public async Task<IEnumerable<PackageItem>> EnumeratePackagesAsync(
Expand Down Expand Up @@ -324,7 +324,7 @@ private async Task CollectPackagesForBuildIntegratedProjectAsync(
fppr = new FallbackPackagePathResolver(pathContext);
}

foreach (var package in BuildIntegratedProjectUtility.GetOrderedLockFilePackageDependencies(lockFile))
foreach (var package in IntegratedProjectUtility.GetLockFilePackageDependencies(lockFile, true))
{
if (!finishedPackages.Contains(package))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public class BuildIntegratedPackageReference : PackageReference
/// Create a PackageReference based on a LibraryDependency.
/// </summary>
/// <param name="dependency">Full PackageReference metadata.</param>
public BuildIntegratedPackageReference(LibraryDependency dependency, NuGetFramework projectFramework)
: base(GetIdentity(dependency),
public BuildIntegratedPackageReference(LibraryDependency dependency, NuGetFramework projectFramework, DependencyVersionLookup lookup)
: base(GetIdentity(dependency, lookup),
targetFramework: projectFramework,
userInstalled: true,
developmentDependency: dependency?.SuppressParent == LibraryIncludeFlags.All,
Expand All @@ -43,15 +43,19 @@ public BuildIntegratedPackageReference(LibraryDependency dependency, NuGetFramew
/// <summary>
/// Convert range to a PackageIdentity
/// </summary>
private static PackageIdentity GetIdentity(LibraryDependency dependency)
private static PackageIdentity GetIdentity(LibraryDependency dependency, DependencyVersionLookup lookup)
{
if (dependency == null)
{
throw new ArgumentNullException(nameof(dependency));
}

// MinVersion may not exist for ranges such as ( , 2.0.0];
var version = dependency.LibraryRange?.VersionRange?.MinVersion ?? new NuGetVersion(0, 0, 0);
NuGetVersion version;
if (!lookup.TryGet(dependency.Name, out version))
{
// MinVersion may not exist for ranges such as ( , 2.0.0];
version = dependency.LibraryRange?.VersionRange?.MinVersion ?? new NuGetVersion(0, 0, 0);
}

return new PackageIdentity(dependency.Name, version);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static async Task ExecuteInitPs1ScriptsAsync(
CancellationToken token)
{
// Find all dependencies in sorted order
var sortedPackages = await BuildIntegratedProjectUtility.GetOrderedProjectPackageDependencies(project);
var sortedPackages = await IntegratedProjectUtility.GetProjectPackageDependenciesAsync(project, true);

// Keep track of the packages that need to be executed.
var packagesToExecute = new HashSet<PackageIdentity>(packages, PackageIdentity.Comparer);
Expand Down
Loading

0 comments on commit 9415900

Please sign in to comment.