diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln
index 3eaadc0d2..c18e98378 100644
--- a/Microsoft.DotNet.Cli.sln
+++ b/Microsoft.DotNet.Cli.sln
@@ -166,6 +166,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet.Tests", "test\dotnet
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-build.Tests", "test\dotnet-build.Tests\dotnet-build.Tests.csproj", "{BBB5A4C8-CD2D-4A6A-9159-0FEAF84B745E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-help.Tests", "test\dotnet-help.Tests\dotnet-help.Tests.csproj", "{8AA88E83-6A98-4AD6-86EB-2ED4F6EDA17F}"
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-migrate.Tests", "test\dotnet-migrate.Tests\dotnet-migrate.Tests.csproj", "{726D2CB9-80E5-4496-9C86-910AC452C45E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-msbuild.Tests", "test\dotnet-msbuild.Tests\dotnet-msbuild.Tests.csproj", "{EF745C56-0350-4C42-AA22-86D592E1D8D5}"
diff --git a/build/DependencyVersions.props b/build/DependencyVersions.props
index b0dddb67f..3e7e45278 100644
--- a/build/DependencyVersions.props
+++ b/build/DependencyVersions.props
@@ -16,8 +16,8 @@
1.0.0-beta2-20170410-189
1.0.3
1.0.3
- 0.1.0-alpha-140
-
+ 0.1.0-alpha-142
+
diff --git a/src/dotnet/Parser.cs b/src/dotnet/Parser.cs
index acfbfe9c6..5f9ec884d 100644
--- a/src/dotnet/Parser.cs
+++ b/src/dotnet/Parser.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.DotNet.Cli.CommandLine;
+using Microsoft.DotNet.Tools.Help;
using static System.Environment;
using static Microsoft.DotNet.Cli.CommandLine.LocalizableStrings;
using LocalizableStrings = Microsoft.DotNet.Tools.Run.LocalizableStrings;
@@ -47,6 +48,7 @@ namespace Microsoft.DotNet.Cli
ListCommandParser.List(),
NuGetCommandParser.NuGet(),
StoreCommandParser.Store(),
+ HelpCommandParser.Help(),
Create.Command("msbuild", ""),
Create.Command("vstest", ""),
CompleteCommandParser.Complete(),
diff --git a/src/dotnet/commands/dotnet-help/HelpCommand.cs b/src/dotnet/commands/dotnet-help/HelpCommand.cs
index 9bff37221..799ba9314 100644
--- a/src/dotnet/commands/dotnet-help/HelpCommand.cs
+++ b/src/dotnet/commands/dotnet-help/HelpCommand.cs
@@ -1,68 +1,66 @@
// 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.Diagnostics;
-using System.Reflection;
+using System.Linq;
using System.Runtime.InteropServices;
+using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
-using Microsoft.DotNet.Cli;
-using static HelpUsageText;
+using Command = Microsoft.DotNet.Cli.CommandLine.Command;
+using Parser = Microsoft.DotNet.Cli.Parser;
namespace Microsoft.DotNet.Tools.Help
{
public class HelpCommand
{
+ private readonly AppliedOption _appliedOption;
+
+ public HelpCommand(AppliedOption appliedOption)
+ {
+ _appliedOption = appliedOption;
+ }
+
public static int Run(string[] args)
{
- CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false);
- app.Name = "dotnet help";
- app.FullName = LocalizableStrings.AppFullName;
- app.Description = LocalizableStrings.AppDescription;
+ DebugHelper.HandleDebugSwitch(ref args);
- CommandArgument commandNameArgument = app.Argument($"<{LocalizableStrings.CommandArgumentName}>", LocalizableStrings.CommandArgumentDescription);
+ var parser = Parser.Instance;
+ var result = parser.ParseFrom("dotnet help", args);
+ var helpAppliedOption = result["dotnet"]["help"];
- app.OnExecute(() =>
+ result.ShowHelpIfRequested();
+
+ HelpCommand cmd;
+ try
{
- BuiltInCommandMetadata builtIn;
- if (BuiltInCommandsCatalog.Commands.TryGetValue(commandNameArgument.Value, out builtIn))
- {
- var process = ConfigureProcess(builtIn.DocLink);
- process.Start();
- process.WaitForExit();
- }
- else
- {
- Reporter.Error.WriteLine(String.Format(LocalizableStrings.CommandDoesNotExist, commandNameArgument.Value));
- Reporter.Output.WriteLine(UsageText);
- return 1;
- }
- return 0;
- });
-
- if (args.Length == 0)
+ cmd = new HelpCommand(helpAppliedOption);
+ }
+ catch (CommandCreationException e)
{
- PrintHelp();
- return 0;
+ return e.ExitCode;
+ }
+
+ if (helpAppliedOption.Arguments.Any())
+ {
+ return cmd.Execute();
}
else
{
- return app.Execute(args);
+ PrintHelp();
+ return 0;
}
}
public static void PrintHelp()
{
PrintVersionHeader();
- Reporter.Output.WriteLine(UsageText);
+ Reporter.Output.WriteLine(HelpUsageText.UsageText);
}
public static void PrintVersionHeader()
{
- var versionString = string.IsNullOrEmpty(Product.Version) ?
- string.Empty :
- $" ({Product.Version})";
+ var versionString = string.IsNullOrEmpty(Product.Version) ? string.Empty : $" ({Product.Version})";
Reporter.Output.WriteLine(Product.LongName + versionString);
}
@@ -93,11 +91,34 @@ namespace Microsoft.DotNet.Tools.Help
Arguments = docUrl
};
}
-
+
return new Process
{
StartInfo = psInfo
};
}
+
+ public int Execute()
+ {
+ if (BuiltInCommandsCatalog.Commands.TryGetValue(
+ _appliedOption.Arguments.Single(),
+ out BuiltInCommandMetadata builtIn))
+ {
+ var process = ConfigureProcess(builtIn.DocLink);
+ process.Start();
+ process.WaitForExit();
+ return 0;
+ }
+ else
+ {
+ Reporter.Error.WriteLine(
+ string.Format(
+ LocalizableStrings.CommandDoesNotExist,
+ _appliedOption.Arguments.Single()));
+ Reporter.Output.WriteLine(HelpUsageText.UsageText);
+ return 1;
+ }
+ }
}
}
+
diff --git a/src/dotnet/commands/dotnet-help/HelpCommandParser.cs b/src/dotnet/commands/dotnet-help/HelpCommandParser.cs
new file mode 100644
index 000000000..ccab6bd21
--- /dev/null
+++ b/src/dotnet/commands/dotnet-help/HelpCommandParser.cs
@@ -0,0 +1,21 @@
+using Microsoft.DotNet.Cli;
+using Microsoft.DotNet.Cli.CommandLine;
+
+namespace Microsoft.DotNet.Tools.Help
+{
+ internal static class HelpCommandParser
+ {
+ public static Command Help()
+ {
+ return Create.Command(
+ "help",
+ LocalizableStrings.AppFullName,
+ Accept.ZeroOrOneArgument()
+ .With(
+ LocalizableStrings.CommandArgumentDescription,
+ LocalizableStrings.CommandArgumentName),
+ CommonOptions.HelpOption());
+ }
+ }
+}
+
diff --git a/src/dotnet/commands/dotnet-help/HelpUsageText.cs b/src/dotnet/commands/dotnet-help/HelpUsageText.cs
index f1f2f39a5..30605ec11 100644
--- a/src/dotnet/commands/dotnet-help/HelpUsageText.cs
+++ b/src/dotnet/commands/dotnet-help/HelpUsageText.cs
@@ -3,7 +3,7 @@ using Microsoft.DotNet.Tools.Help;
internal static class HelpUsageText
{
public static readonly string UsageText =
- $@"{LocalizableStrings.Usage}: dotnet [host-options] [command] [arguments] [common-options]
+$@"{LocalizableStrings.Usage}: dotnet [host-options] [command] [arguments] [common-options]
{LocalizableStrings.Arguments}:
[command] {LocalizableStrings.CommandDefinition}
@@ -13,7 +13,7 @@ internal static class HelpUsageText
{LocalizableStrings.CommonOptions}:
-v|--verbose {LocalizableStrings.VerboseDefinition}
- -h|--help {LocalizableStrings.HelpDefinition}
+ -h|--help {LocalizableStrings.HelpDefinition}
{LocalizableStrings.HostOptions}:
-d|--diagnostics {LocalizableStrings.DiagnosticsDefinition}
@@ -41,4 +41,5 @@ Project modification commands:
nuget {LocalizableStrings.NugetDefinition}
msbuild {LocalizableStrings.MsBuildDefinition}
vstest {LocalizableStrings.VsTestDefinition}";
-}
\ No newline at end of file
+}
+
diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/HelpCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/HelpCommand.cs
index ce3948e61..222d92368 100644
--- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/HelpCommand.cs
+++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/HelpCommand.cs
@@ -9,8 +9,17 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
{
public override CommandResult Execute(string args = "")
{
- args = $"help {args}";
- return base.Execute(args);
+ return base.Execute(AppendHelp(args));
+ }
+
+ public override CommandResult ExecuteWithCapturedOutput(string args = "")
+ {
+ return base.ExecuteWithCapturedOutput(AppendHelp(args));
+ }
+
+ private string AppendHelp(string args)
+ {
+ return args = $"help {args}";
}
}
}
diff --git a/test/dotnet-help.Tests/GivenThatIWantToShowHelpForDotnetCommand.cs b/test/dotnet-help.Tests/GivenThatIWantToShowHelpForDotnetCommand.cs
index 09cae73ab..dbeb144bb 100644
--- a/test/dotnet-help.Tests/GivenThatIWantToShowHelpForDotnetCommand.cs
+++ b/test/dotnet-help.Tests/GivenThatIWantToShowHelpForDotnetCommand.cs
@@ -25,7 +25,7 @@ Arguments:
Common options:
-v|--verbose Enable verbose output
- -h|--help Show help
+ -h|--help Show help
Host options (passed before the command):
-d|--diagnostics Enable diagnostic output
@@ -67,12 +67,21 @@ Advanced Commands:
cmd.StdOut.Should().ContainVisuallySameFragment(HelpText);
}
+ [Fact]
+ public void WhenHelpCommandIsPassedToDotnetItPrintsUsage()
+ {
+ var cmd = new HelpCommand()
+ .ExecuteWithCapturedOutput();
+ cmd.Should().Pass();
+ cmd.StdOut.Should().ContainVisuallySameFragment(HelpText);
+ }
+
[Fact]
public void WhenInvalidCommandIsPassedToDotnetHelpItPrintsError()
{
var cmd = new DotnetCommand()
.ExecuteWithCapturedOutput("help invalid");
-
+
cmd.Should().Fail();
cmd.StdErr.Should().ContainVisuallySameFragment($"Specified command 'invalid' is not a valid CLI command. Please specify a valid CLI commands. For more information, run dotnet help.");
cmd.StdOut.Should().ContainVisuallySameFragment(HelpText);
@@ -92,7 +101,7 @@ Advanced Commands:
var proc = HelpActual.HelpCommand.ConfigureProcess("https://aka.ms/dotnet-build");
Assert.Equal("xdg-open", proc.StartInfo.FileName);
Assert.Equal("https://aka.ms/dotnet-build", proc.StartInfo.Arguments);
-
+
}
[MacOsOnlyFact]
public void WhenRunOnMacOsDotnetHelpCommandShouldContainProperProcessInformation()
diff --git a/test/dotnet-help.Tests/GivenThatIWantToShowHelpForDotnetHelpCommand.cs b/test/dotnet-help.Tests/GivenThatIWantToShowHelpForDotnetHelpCommand.cs
new file mode 100644
index 000000000..e24d4e56a
--- /dev/null
+++ b/test/dotnet-help.Tests/GivenThatIWantToShowHelpForDotnetHelpCommand.cs
@@ -0,0 +1,37 @@
+// 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.Tools.Test.Utilities;
+using Xunit;
+using FluentAssertions;
+using HelpActual = Microsoft.DotNet.Tools.Help;
+
+namespace Microsoft.DotNet.Help.Tests
+{
+ public class GivenThatIWantToShowHelpForDotnetHelpCommand : TestBase
+ {
+ private const string HelpText =
+@".NET CLI help utility
+
+Usage: dotnet help [options]
+
+Arguments:
+ CLI command for which to view more detailed help.
+
+Options:
+ -h, --help Show help information";
+
+ [Theory]
+ [InlineData("--help")]
+ [InlineData("-h")]
+ [InlineData("-?")]
+ [InlineData("/?")]
+ public void WhenHelpOptionIsPassedToDotnetHelpCommandItPrintsUsage(string helpArg)
+ {
+ var cmd = new HelpCommand()
+ .ExecuteWithCapturedOutput($"{helpArg}");
+ cmd.Should().Pass();
+ cmd.StdOut.Should().ContainVisuallySameFragment(HelpText);
+ }
+ }
+}