Update tool (#8794)

This commit is contained in:
William Lee 2018-03-15 19:45:11 -07:00 committed by GitHub
parent 3d13658f97
commit 3f09a889d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 2855 additions and 57 deletions

View file

@ -121,7 +121,7 @@ namespace Microsoft.DotNet.Tools.Tests.ComponentMocks
FilePath? nugetConfig = null,
string source = null)
{
var package = _feeds
var allPackages = _feeds
.Where(f => {
if (nugetConfig != null)
{
@ -134,8 +134,11 @@ namespace Microsoft.DotNet.Tools.Tests.ComponentMocks
return true;
})
.SelectMany(f => f.Packages)
.Where(p => MatchPackage(p, packageId, versionRange)).OrderByDescending(p => p.Version)
.FirstOrDefault();
.Where(f => f.PackageId == packageId);
var bestVersion = versionRange.FindBestMatch(allPackages.Select(p => NuGetVersion.Parse(p.Version)));
var package = allPackages.Where(p => NuGetVersion.Parse(p.Version).Equals(bestVersion)).FirstOrDefault();
if (package == null)
{

View file

@ -41,6 +41,7 @@ SDK commands:
store Stores the specified assemblies in the runtime store.
install Installs an item into the development environment.
uninstall Uninstalls an item from the development environment.
update Updates an item in the development environment.
help Show help.
Common options:

View file

@ -155,7 +155,9 @@ namespace Microsoft.DotNet.Tests.Commands
Action a = () => installToolCommand.Execute();
a.ShouldThrow<GracefulException>().And.Message
.Should().Contain(string.Format(LocalizableStrings.ToolInstallationFailed, PackageId));
.Should().Contain(
"Simulated error" + Environment.NewLine
+ string.Format(LocalizableStrings.ToolInstallationFailed, PackageId));
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
}

View file

@ -0,0 +1,243 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ToolPackage;
using Microsoft.DotNet.Tools.Install.Tool;
using Microsoft.DotNet.Tools.Tests.ComponentMocks;
using Microsoft.DotNet.Tools.Test.Utilities;
using Microsoft.DotNet.Tools.Update.Tool;
using Microsoft.Extensions.DependencyModel.Tests;
using Microsoft.Extensions.EnvironmentAbstractions;
using Xunit;
using Parser = Microsoft.DotNet.Cli.Parser;
using LocalizableStrings = Microsoft.DotNet.Tools.Update.Tool.LocalizableStrings;
namespace Microsoft.DotNet.Tests.Commands
{
public class UpdateToolCommandTests
{
private readonly BufferedReporter _reporter;
private readonly IFileSystem _fileSystem;
private readonly EnvironmentPathInstructionMock _environmentPathInstructionMock;
private readonly ToolPackageStoreMock _store;
private readonly PackageId _packageId = new PackageId("global.tool.console.demo");
private readonly List<MockFeed> _mockFeeds;
private const string LowerPackageVersion = "1.0.4";
private const string HigherPackageVersion = "1.0.5";
private const string ShimsDirectory = "shims";
private const string ToolsDirectory = "tools";
public UpdateToolCommandTests()
{
_reporter = new BufferedReporter();
_fileSystem = new FileSystemMockBuilder().Build();
_environmentPathInstructionMock = new EnvironmentPathInstructionMock(_reporter, ShimsDirectory);
_store = new ToolPackageStoreMock(new DirectoryPath(ToolsDirectory), _fileSystem);
_mockFeeds = new List<MockFeed>
{
new MockFeed
{
Type = MockFeedType.FeedFromLookUpNugetConfig,
Packages = new List<MockFeedPackage>
{
new MockFeedPackage
{
PackageId = _packageId.ToString(),
Version = LowerPackageVersion
},
new MockFeedPackage
{
PackageId = _packageId.ToString(),
Version = HigherPackageVersion
}
}
}
};
}
[Fact]
public void GivenANonExistentPackageItErrors()
{
var packageId = "does.not.exist";
var command = CreateUpdateCommand($"-g {packageId}");
Action a = () => command.Execute();
a.ShouldThrow<GracefulException>().And.Message
.Should().Contain(
string.Format(
LocalizableStrings.ToolNotInstalled,
packageId));
}
[Fact]
public void GivenAnExistedLowerversionInstallationWhenCallItCanUpdateThePackageVersion()
{
CreateInstallCommand($"-g {_packageId} --version {LowerPackageVersion}").Execute();
var command = CreateUpdateCommand($"-g {_packageId}");
command.Execute();
_store.EnumeratePackageVersions(_packageId).Single().Version.ToFullString().Should()
.Be(HigherPackageVersion);
}
[Fact]
public void GivenAnExistedLowerversionInstallationWhenCallItCanPrintSucessMessage()
{
CreateInstallCommand($"-g {_packageId} --version {LowerPackageVersion}").Execute();
_reporter.Lines.Clear();
var command = CreateUpdateCommand($"-g {_packageId}");
command.Execute();
_reporter.Lines.First().Should().Contain(string.Format(
LocalizableStrings.UpdateSucceeded,
_packageId, LowerPackageVersion, HigherPackageVersion));
}
[Fact]
public void GivenAnExistedSameVersionInstallationWhenCallItCanPrintSucessMessage()
{
CreateInstallCommand($"-g {_packageId} --version {HigherPackageVersion}").Execute();
_reporter.Lines.Clear();
var command = CreateUpdateCommand($"-g {_packageId}");
command.Execute();
_reporter.Lines.First().Should().Contain(string.Format(
LocalizableStrings.UpdateSucceededVersionNoChange,
_packageId, HigherPackageVersion));
}
[Fact]
public void GivenAnExistedLowerversionWhenReinstallThrowsIthasTheFirstLineIndicateUpdateFailure()
{
CreateInstallCommand($"-g {_packageId} --version {LowerPackageVersion}").Execute();
_reporter.Lines.Clear();
ParseResult result = Parser.Instance.Parse("dotnet update tool " + $"-g {_packageId}");
var command = new UpdateToolCommand(
result["dotnet"]["update"]["tool"],
result,
_ => (_store,
new ToolPackageInstallerMock(
_fileSystem,
_store,
new ProjectRestorerMock(
_fileSystem,
_reporter,
_mockFeeds
),
installCallback: () => throw new ToolConfigurationException("Simulated error"))),
_ => new ShellShimRepositoryMock(new DirectoryPath(ShimsDirectory), _fileSystem),
_reporter);
Action a = () => command.Execute();
a.ShouldThrow<GracefulException>().And.Message.Should().Contain(
string.Format(LocalizableStrings.UpdateToolFailed, _packageId) + Environment.NewLine +
string.Format(Tools.Install.Tool.LocalizableStrings.InvalidToolConfiguration, "Simulated error"));
}
[Fact]
public void GivenAnExistedLowerversionWhenReinstallThrowsItRollsBack()
{
CreateInstallCommand($"-g {_packageId} --version {LowerPackageVersion}").Execute();
_reporter.Lines.Clear();
ParseResult result = Parser.Instance.Parse("dotnet update tool " + $"-g {_packageId}");
var command = new UpdateToolCommand(
result["dotnet"]["update"]["tool"],
result,
_ => (_store,
new ToolPackageInstallerMock(
_fileSystem,
_store,
new ProjectRestorerMock(
_fileSystem,
_reporter,
_mockFeeds
),
installCallback: () => throw new ToolConfigurationException("Simulated error"))),
_ => new ShellShimRepositoryMock(new DirectoryPath(ShimsDirectory), _fileSystem),
_reporter);
Action a = () => command.Execute();
_store.EnumeratePackageVersions(_packageId).Single().Version.ToFullString().Should()
.Be(LowerPackageVersion);
}
[Fact]
public void WhenRunWithBothGlobalAndToolPathShowErrorMessage()
{
var command = CreateUpdateCommand($"-g --tool-path /tmp/folder {_packageId}");
Action a = () => command.Execute();
a.ShouldThrow<GracefulException>().And.Message
.Should().Contain(
LocalizableStrings.UpdateToolCommandInvalidGlobalAndToolPath);
}
[Fact]
public void WhenRunWithNeitherOfGlobalNorToolPathShowErrorMessage()
{
var command = CreateUpdateCommand($"{_packageId}");
Action a = () => command.Execute();
a.ShouldThrow<GracefulException>().And.Message
.Should().Contain(
LocalizableStrings.UpdateToolCommandNeedGlobalOrToolPath);
}
private InstallToolCommand CreateInstallCommand(string options)
{
ParseResult result = Parser.Instance.Parse("dotnet install tool " + options);
return new InstallToolCommand(
result["dotnet"]["install"]["tool"],
result,
(_) => (_store, new ToolPackageInstallerMock(
_fileSystem,
_store,
new ProjectRestorerMock(
_fileSystem,
_reporter,
_mockFeeds
))),
(_) => new ShellShimRepositoryMock(new DirectoryPath(ShimsDirectory), _fileSystem),
_environmentPathInstructionMock,
_reporter);
}
private UpdateToolCommand CreateUpdateCommand(string options)
{
ParseResult result = Parser.Instance.Parse("dotnet update tool " + options);
return new UpdateToolCommand(
result["dotnet"]["update"]["tool"],
result,
(_) => (_store, new ToolPackageInstallerMock(
_fileSystem,
_store,
new ProjectRestorerMock(
_fileSystem,
_reporter,
_mockFeeds
))),
(_) => new ShellShimRepositoryMock(new DirectoryPath(ShimsDirectory), _fileSystem),
_reporter);
}
}
}

View file

@ -0,0 +1,93 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Linq;
using FluentAssertions;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Xunit;
using Xunit.Abstractions;
using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tests.ParserTests
{
public class UpdateInstallToolParserTests
{
private readonly ITestOutputHelper _output;
public UpdateInstallToolParserTests(ITestOutputHelper output)
{
_output = output;
}
[Fact]
public void UpdateGlobaltoolParserCanGetPackageId()
{
var command = Parser.Instance;
var result = command.Parse("dotnet update tool -g console.test.app");
var parseResult = result["dotnet"]["update"]["tool"];
var packageId = parseResult.Arguments.Single();
packageId.Should().Be("console.test.app");
}
[Fact]
public void UpdateToolParserCanGetGlobalOption()
{
var result = Parser.Instance.Parse("dotnet update tool -g console.test.app");
var appliedOptions = result["dotnet"]["update"]["tool"];
appliedOptions.ValueOrDefault<bool>("global").Should().Be(true);
}
[Fact]
public void UpdateToolParserCanGetFollowingArguments()
{
var command = Parser.Instance;
var result =
command.Parse(
@"dotnet update tool -g console.test.app --version 1.0.1 --framework netcoreapp2.0 --configfile C:\TestAssetLocalNugetFeed");
var parseResult = result["dotnet"]["update"]["tool"];
parseResult.ValueOrDefault<string>("configfile").Should().Be(@"C:\TestAssetLocalNugetFeed");
parseResult.ValueOrDefault<string>("framework").Should().Be("netcoreapp2.0");
}
[Fact]
public void UpdateToolParserCanParseSourceOption()
{
const string expectedSourceValue = "TestSourceValue";
var result =
Parser.Instance.Parse($"dotnet update tool -g --source {expectedSourceValue} console.test.app");
var appliedOptions = result["dotnet"]["update"]["tool"];
appliedOptions.ValueOrDefault<string>("source").Should().Be(expectedSourceValue);
}
[Fact]
public void UpdateToolParserCanParseVerbosityOption()
{
const string expectedVerbosityLevel = "diag";
var result =
Parser.Instance.Parse($"dotnet update tool -g --verbosity:{expectedVerbosityLevel} console.test.app");
var appliedOptions = result["dotnet"]["update"]["tool"];
appliedOptions.SingleArgumentOrDefault("verbosity").Should().Be(expectedVerbosityLevel);
}
[Fact]
public void UpdateToolParserCanParseToolPathOption()
{
var result =
Parser.Instance.Parse(@"dotnet update tool --tool-path C:\TestAssetLocalNugetFeed console.test.app");
var appliedOptions = result["dotnet"]["update"]["tool"];
appliedOptions.SingleArgumentOrDefault("tool-path").Should().Be(@"C:\TestAssetLocalNugetFeed");
}
}
}