Skip to content

Commit

Permalink
Select latest based on version then date
Browse files Browse the repository at this point in the history
Fixes #40 and updates the test data to make sure we're properly sorting and selecting. Also made a corresponding test-only change to Microsoft/vswhere to make sure this case isn't regressed there (was already handled correctly).
  • Loading branch information
heaths committed Mar 16, 2018
1 parent af3e82f commit 4779037
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 11 deletions.
2 changes: 1 addition & 1 deletion docker/Instances/1/state.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"installationName": "VisualStudio/public.d15rel/15.0.26116.0",
"installationVersion": "15.0.26116",
"installationPath": "C:\\VS\\Community",
"installDate": "2017-01-17T03:00:00Z",
"installDate": "2017-01-17T03:45:00Z",
"product": {
"id": "Microsoft.VisualStudio.Product.Community",
"version": "15.0.26116.0",
Expand Down
12 changes: 3 additions & 9 deletions src/VSSetup.PowerShell/Instance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ internal Instance(ISetupInstance2 instance)
() =>
{
var versionString = instance.GetInstallationVersion();
if (Utilities.TryParseVersion(versionString, out Version version))
if (Utilities.TryParseVersion(versionString, out var version))
{
return version.Normalize();
}
Expand All @@ -94,19 +94,13 @@ internal Instance(ISetupInstance2 instance)
Utilities.TrySet(
ref displayName,
nameof(DisplayName),
() =>
{
return instance.GetDisplayName(lcid);
},
() => instance.GetDisplayName(lcid),
OnError);

Utilities.TrySet(
ref description,
nameof(Description),
() =>
{
return instance.GetDescription(lcid);
},
() => instance.GetDescription(lcid),
OnError);

Utilities.TrySet(
Expand Down
65 changes: 65 additions & 0 deletions src/VSSetup.PowerShell/InstanceComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// <copyright file="InstanceComparer.cs" company="Microsoft Corporation">
// Copyright (C) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt in the project root for license information.
// </copyright>

namespace Microsoft.VisualStudio.Setup
{
using System;
using System.Collections.Generic;

/// <summary>
/// Compares instances of <see cref="Instance"/>.
/// </summary>
internal class InstanceComparer : IComparer<Instance>
{
/// <summary>
/// Gets an instance of the <see cref="InstanceComparer"/> that compares only the
/// <see cref="Instance.InstallationVersion"/> and <see cref="Instance.InstallDate"/> properties.
/// </summary>
public static readonly IComparer<Instance> VersionAndDate = new InstanceComparer();

/// <inheritdoc/>
public int Compare(Instance x, Instance y)
{
if (ReferenceEquals(x, y))
{
return 0;
}
else if (x is null)
{
return -1;
}
else if (y is null)
{
return 1;
}

var result = Compare(x.InstallationVersion, y.InstallationVersion);
if (result != 0)
{
return result;
}

return DateTime.Compare(x.InstallDate, y.InstallDate);
}

private static int Compare(Version x, Version y)
{
if (ReferenceEquals(x, y))
{
return 0;
}
else if (x is null)
{
return -1;
}
else if (y is null)
{
return 1;
}

return x.CompareTo(y);
}
}
}
6 changes: 6 additions & 0 deletions src/VSSetup.PowerShell/PowerShell/SelectInstanceCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ bool Contains(IEnumerable<PackageReference> packages, Func<PackageReference, str
select instance;
}

if (Latest)
{
// Sort by the InstallationVersion then InstallDate so we can easily find the latest.
instances = instances.OrderBy(instance => instance, InstanceComparer.VersionAndDate);
}

foreach (var instance in instances)
{
if (Latest)
Expand Down
3 changes: 2 additions & 1 deletion src/VSSetup.PowerShell/VSSetup.PowerShell.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<Compile Include="Extensions.cs" />
<Compile Include="FailedPackageReference.cs" />
<Compile Include="Instance.cs" />
<Compile Include="InstanceComparer.cs" />
<Compile Include="Module.cs" />
<Compile Include="NativeMethods.cs" />
<Compile Include="PackageReference.cs" />
Expand Down Expand Up @@ -112,4 +113,4 @@
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Nerdbank.GitVersioning.1.5.97\build\portable-net+win+wpa+wp+sl+netmf+MonoAndroid+MonoTouch+Xamarin.iOS\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Nerdbank.GitVersioning.1.5.97\build\portable-net+win+wpa+wp+sl+netmf+MonoAndroid+MonoTouch+Xamarin.iOS\Nerdbank.GitVersioning.targets'))" />
</Target>
</Project>
</Project>
61 changes: 61 additions & 0 deletions test/VSSetup.PowerShell.Test/InstanceComparerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// <copyright file="InstanceComparerTests.cs" company="Microsoft Corporation">
// Copyright (C) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt in the project root for license information.
// </copyright>

namespace Microsoft.VisualStudio.Setup
{
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.VisualStudio.Setup.Configuration;
using Moq;
using Xunit;

public class InstanceComparerTests
{
public static IEnumerable<object[]> GetCompareVersionAndDateData()
{
var empty = new string[0];

var v1 = new Version(1, 0);
var v2 = new Version(2, 0);

var ft1 = new FILETIME { dwHighDateTime = 1 };
var ft2 = new FILETIME { dwHighDateTime = 2 };

Instance Mock(Version v = null, FILETIME ft = default(FILETIME))
{
var mock = new Mock<ISetupInstance2>();
mock.As<ISetupPropertyStore>().Setup(x => x.GetNames()).Returns(empty);

mock.Setup(x => x.GetInstallationVersion()).Returns(v?.ToString());
mock.Setup(x => x.GetInstallDate()).Returns(ft);

return new Instance(mock.Object);
}

return new[]
{
new object[] { null, null, 0 },
new object[] { null, Mock(), -1 },
new object[] { Mock(), null, 1 },
new object[] { Mock(), Mock(v1), -1 },
new object[] { Mock(v1), Mock(), 1 },
new object[] { Mock(v1), Mock(v1), 0 },
new object[] { Mock(v1), Mock(v2), -1 },
new object[] { Mock(v2), Mock(v1), 1 },
new object[] { Mock(v2, ft1), Mock(v2, ft2), -1 },
new object[] { Mock(v2, ft2), Mock(v2, ft1), 1 },
};
}

[Theory]
[MemberData(nameof(GetCompareVersionAndDateData))]
public void CompareVersionAndDate(Instance x, Instance y, int expected)
{
var actual = InstanceComparer.VersionAndDate.Compare(x, y);
Assert.Equal(expected, actual);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
<Compile Include="PowerShell\SelectInstanceCommandTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReadOnlyDictionaryTests.cs" />
<Compile Include="InstanceComparerTests.cs" />
<Compile Include="UtilitiesTests.cs" />
<Compile Include="ValidateTests.cs" />
</ItemGroup>
Expand Down

0 comments on commit 4779037

Please sign in to comment.