Give a different error to guide use to install via global tools (#9070)

Give a different error to guide use to install via global tools so, if several bundled DotnetTools cannot finish source build on time. The user can use global tools to get it.

The original plan that adding a different resolver is hard due to resolver can only find dll that will be used to spawn a process. However, the command constructor will give an error message when resolver find null. By adding a different error when the command name is part of the list, it can achieve the same goal.
This commit is contained in:
William Li 2018-04-17 12:21:20 -07:00 committed by GitHub
parent bc83d98f52
commit 854feefe6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 238 additions and 1 deletions

View file

@ -21,6 +21,8 @@ namespace Microsoft.DotNet.Cli.Utils
private bool _running = false;
private static string[] _knownCommandsAvailableAsDotNetTool = new[] { "dotnet-dev-certs", "dotnet-ef", "dotnet-sql-cache", "dotnet-user-secrets", "dotnet-watch" };
private Command(CommandSpec commandSpec)
{
var psi = new ProcessStartInfo
@ -102,7 +104,14 @@ namespace Microsoft.DotNet.Cli.Utils
if (commandSpec == null)
{
throw new CommandUnknownException(commandName);
if (_knownCommandsAvailableAsDotNetTool.Contains(commandName, StringComparer.OrdinalIgnoreCase))
{
throw new CommandAvailableAsDotNetToolException(commandName);
}
else
{
throw new CommandUnknownException(commandName);
}
}
var command = new Command(commandSpec);

View file

@ -0,0 +1,29 @@
// 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;
namespace Microsoft.DotNet.Cli.Utils
{
public class CommandAvailableAsDotNetToolException : GracefulException
{
public CommandAvailableAsDotNetToolException(string commandName) : base(GetMessage(commandName))
{
}
public CommandAvailableAsDotNetToolException(string commandName, Exception innerException) : base(
GetMessage(commandName), innerException)
{
}
private static string GetMessage(string commandName)
{
var commandRemoveLeadningDotnet = commandName.Replace("dotnet-", string.Empty);
var packageName = "dotnet-" + commandRemoveLeadningDotnet.ToLower();
return string.Format(LocalizableStrings.CannotFindCommandAvailableAsTool,
commandRemoveLeadningDotnet,
packageName);
}
}
}

View file

@ -271,4 +271,9 @@
<data name="EmbedAppNameInHostFileNameIsTooLong" xml:space="preserve">
<value>Given file name '{0}' is longer than 1024 bytes</value>
</data>
<data name="CannotFindCommandAvailableAsTool" xml:space="preserve">
<value>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</value>
</data>
</root>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -259,6 +259,15 @@
<target state="new">Given file name '{0}' is longer than 1024 bytes</target>
<note />
</trans-unit>
<trans-unit id="CannotFindCommandAvailableAsTool">
<source>Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</source>
<target state="new">Cannot find command 'dotnet {0}', please run the following command to install
dotnet tool install --global {1}</target>
<note />
</trans-unit>
</body>
</file>
</xliff>

View file

@ -0,0 +1,77 @@
// 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 Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Test.Utilities;
using System;
using Xunit;
using Xunit.Abstractions;
using FluentAssertions;
namespace Microsoft.DotNet.Tests
{
public class CommandObjectTests : TestBase
{
ITestOutputHelper _output;
public CommandObjectTests(ITestOutputHelper output)
{
_output = output;
}
[Fact]
public void WhenItCannotResolveCommandItThrows()
{
Action a = () => { Command.Create(new ResolveNothingCommandResolverPolicy(), "non-exist-command", Array.Empty<string>() ); };
a.ShouldThrow<CommandUnknownException>();
}
[Fact]
public void WhenItCannotResolveCommandButCommandIsInListOfKnownToolsItThrows()
{
Action a = () => { Command.Create(new ResolveNothingCommandResolverPolicy(), "non-exist-command", Array.Empty<string>()); };
a.ShouldThrow<CommandUnknownException>();
}
[Fact]
public void WhenItCannotResolveCommandButCommandIsInListOfKnownToolsItThrowsWithGuideToUseTool()
{
Action a = () => { Command.Create(new ResolveNothingCommandResolverPolicy(), "dotnet-ef", Array.Empty<string>()); };
a.ShouldThrow<CommandAvailableAsDotNetToolException>()
.And.Message.Should()
.Contain(string.Format(LocalizableStrings.CannotFindCommandAvailableAsTool,
"ef",
"dotnet-ef"));
}
[Fact]
public void WhenItCannotResolveCommandButCommandIsInListOfKnownToolsItThrowsWithGuideToUseToolWithNormalizedCasing()
{
Action a = () => { Command.Create(new ResolveNothingCommandResolverPolicy(), "dotnet-EF", Array.Empty<string>()); };
a.ShouldThrow<CommandAvailableAsDotNetToolException>()
.And.Message.Should()
.Contain(string.Format(LocalizableStrings.CannotFindCommandAvailableAsTool,
"EF",
"dotnet-ef"));
}
private class ResolveNothingCommandResolverPolicy : ICommandResolverPolicy
{
public CompositeCommandResolver CreateCommandResolver()
{
var compositeCommandResolver = new CompositeCommandResolver();
compositeCommandResolver.AddCommandResolver(new ResolveNothingCommandResolver());
return compositeCommandResolver;
}
}
private class ResolveNothingCommandResolver : ICommandResolver
{
public CommandSpec Resolve(CommandResolverArguments arguments)
{
return null;
}
}
}
}