diff --git a/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs b/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs index 6e970a835..74d418ffa 100644 --- a/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs +++ b/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs @@ -313,9 +313,12 @@ namespace Microsoft.DotNet.Tools.Common return Path.GetFullPath(path); } - public static void EnsureAllPathsExist(List paths, string pathDoesNotExistLocalizedFormatString) + public static void EnsureAllPathsExist( + IReadOnlyCollection paths, + string pathDoesNotExistLocalizedFormatString) { var notExisting = new List(); + foreach (var p in paths) { if (!File.Exists(p)) @@ -329,7 +332,7 @@ namespace Microsoft.DotNet.Tools.Common throw new GracefulException( string.Join( Environment.NewLine, - notExisting.Select((p) => string.Format(pathDoesNotExistLocalizedFormatString, p)))); + notExisting.Select(p => string.Format(pathDoesNotExistLocalizedFormatString, p)))); } } } diff --git a/src/dotnet/CommandBase.cs b/src/dotnet/CommandBase.cs new file mode 100644 index 000000000..ce9bb13e3 --- /dev/null +++ b/src/dotnet/CommandBase.cs @@ -0,0 +1,10 @@ +// 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. + +namespace Microsoft.DotNet.Cli +{ + public abstract class CommandBase + { + public abstract int Execute(); + } +} \ No newline at end of file diff --git a/src/dotnet/DotNetSubCommandBase.cs b/src/dotnet/DotNetSubCommandBase.cs deleted file mode 100644 index 82d28ab6a..000000000 --- a/src/dotnet/DotNetSubCommandBase.cs +++ /dev/null @@ -1,16 +0,0 @@ -// 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.CommandLine; - -namespace Microsoft.DotNet.Cli -{ - internal abstract class DotNetSubCommandBase : CommandLineApplication - { - internal DotNetSubCommandBase() : base(throwOnUnexpectedArg: false) - { - } - - public abstract int Run(string fileOrDirectory); - } -} diff --git a/src/dotnet/DotNetTopLevelCommandBase.cs b/src/dotnet/DotNetTopLevelCommandBase.cs index 640d8dccc..319c66523 100644 --- a/src/dotnet/DotNetTopLevelCommandBase.cs +++ b/src/dotnet/DotNetTopLevelCommandBase.cs @@ -3,12 +3,9 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Tools; -using Microsoft.DotNet.Tools.Common; namespace Microsoft.DotNet.Cli { @@ -18,60 +15,34 @@ namespace Microsoft.DotNet.Cli protected abstract string FullCommandNameLocalized { get; } protected abstract string ArgumentName { get; } protected abstract string ArgumentDescriptionLocalized { get; } - internal abstract List> SubCommands { get; } + internal abstract Dictionary> SubCommands { get; } public int RunCommand(string[] args) { DebugHelper.HandleDebugSwitch(ref args); - CommandLineApplication command = new CommandLineApplication(throwOnUnexpectedArg: true) - { - Name = $"dotnet {CommandName}", - FullName = FullCommandNameLocalized, - }; + var parser = Parser.Instance; - command.HelpOption("-h|--help"); + var result = parser.ParseFrom($"dotnet {CommandName}", args); - command.Argument(ArgumentName, ArgumentDescriptionLocalized); + Reporter.Output.WriteLine(result.Diagram()); - foreach (var subCommandCreator in SubCommands) - { - var subCommand = subCommandCreator(); - command.AddCommand(subCommand); + result.ShowHelpIfRequested(); - subCommand.OnExecute(() => { - try - { - if (!command.Arguments.Any()) - { - throw new GracefulException(CommonLocalizableStrings.RequiredArgumentNotPassed, ArgumentDescriptionLocalized); - } + var subcommandName = result.Command().Name; - var projectOrDirectory = command.Arguments.First().Value; - if (string.IsNullOrEmpty(projectOrDirectory)) - { - projectOrDirectory = PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory()); - } + var create = SubCommands[subcommandName]; - return subCommand.Run(projectOrDirectory); - } - catch (GracefulException e) - { - Reporter.Error.WriteLine(e.Message.Red()); - subCommand.ShowHelp(); - return 1; - } - }); - } + var command = create(result["dotnet"][CommandName]); try { - return command.Execute(args); + return command.Execute(); } catch (GracefulException e) { Reporter.Error.WriteLine(e.Message.Red()); - command.ShowHelp(); + result.ShowHelp(); return 1; } catch (CommandParsingException e) @@ -81,4 +52,4 @@ namespace Microsoft.DotNet.Cli } } } -} +} \ No newline at end of file diff --git a/src/dotnet/ParseResultExtensions.cs b/src/dotnet/ParseResultExtensions.cs index f4ae8866a..eda1a5590 100644 --- a/src/dotnet/ParseResultExtensions.cs +++ b/src/dotnet/ParseResultExtensions.cs @@ -14,11 +14,9 @@ namespace Microsoft.DotNet.Cli public static void ShowHelpIfRequested(this ParseResult parseResult) { - if (parseResult.HasOption("help")) + if (parseResult.AppliedOptions.Any(o => o.HasOption("help"))) { - // NOTE: this is a temporary stage in refactoring toward the ClicCommandLineParser being used at the CLI entry point. - throw new HelpException(parseResult.Command().HelpView()); } } diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs index b47943ce8..8cf7f58a2 100644 --- a/src/dotnet/Program.cs +++ b/src/dotnet/Program.cs @@ -54,7 +54,7 @@ namespace Microsoft.DotNet.Cli ["test"] = TestCommand.Run, ["vstest"] = VSTestCommand.Run, ["complete"] = CompleteCommand.Run, - ["parse"] = ParseCommand.Run, + ["parse"] = ParseCommand.Run }; public static int Main(string[] args) diff --git a/src/dotnet/commands/dotnet-add/AddCommandParser.cs b/src/dotnet/commands/dotnet-add/AddCommandParser.cs index 6e4a1881f..a3fc0f102 100644 --- a/src/dotnet/commands/dotnet-add/AddCommandParser.cs +++ b/src/dotnet/commands/dotnet-add/AddCommandParser.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net.Http; using System.Threading; using Microsoft.DotNet.Cli.CommandLine; @@ -13,36 +14,46 @@ namespace Microsoft.DotNet.Cli internal static class AddCommandParser { public static Command Add() => - Create.Command("add", - ".NET Add Command", - Accept.ExactlyOneArgument.DefaultToCurrentDirectory(), - Create.Command("package", - ".NET Add Package reference Command", - Accept.ExactlyOneArgument - .WithSuggestionsFrom(QueryNuGet), CommonOptions.HelpOption(), - Create.Option("-v|--version", - "Version for the package to be added.", - Accept.ExactlyOneArgument - .With(name: "VERSION")), - Create.Option("-f|--framework", - "Add reference only when targetting a specific framework", - Accept.ExactlyOneArgument - .With(name: "FRAMEWORK")), - Create.Option("-n|--no-restore ", - "Add reference without performing restore preview and compatibility check."), - Create.Option("-s|--source", - "Use specific NuGet package sources to use during the restore."), - Create.Option("--package-directory", - "Restore the packages to this Directory .", - Accept.ExactlyOneArgument - .With(name: "PACKAGE_DIRECTORY"))), - Create.Command("reference", - "Command to add project to project reference", - Accept.OneOrMoreArguments, CommonOptions.HelpOption(), - Create.Option("-f|--framework", - "Add reference only when targetting a specific framework", - Accept.AnyOneOf(Suggest.TargetFrameworksFromProjectFile) - .With(name: "FRAMEWORK"))), CommonOptions.HelpOption()); + Create.Command( + "add", + ".NET Add Command", + Accept.ExactlyOneArgument + .DefaultToCurrentDirectory(), + Create.Command( + "package", + ".NET Add Package reference Command", + Accept.ExactlyOneArgument + .WithSuggestionsFrom(QueryNuGet), CommonOptions.HelpOption(), + Create.Option("-v|--version", + "Version for the package to be added.", + Accept.ExactlyOneArgument + .With(name: "VERSION") + .ForwardAs(o => $"--version {o.Arguments.Single()}")), + Create.Option("-f|--framework", + "Add reference only when targetting a specific framework", + Accept.ExactlyOneArgument + .With(name: "FRAMEWORK") + .ForwardAs(o => $"--framework {o.Arguments.Single()}")), + Create.Option("-n|--no-restore ", + "Add reference without performing restore preview and compatibility check."), + Create.Option("-s|--source", + "Use specific NuGet package sources to use during the restore.", + Accept.ExactlyOneArgument + .With(name: "SOURCE") + .ForwardAs(o => $"--source {o.Arguments.Single()}")), + Create.Option("--package-directory", + "Restore the packages to this Directory .", + Accept.ExactlyOneArgument + .With(name: "PACKAGE_DIRECTORY") + .ForwardAs(o => $"--package-directory {o.Arguments.Single()}"))), + Create.Command( + "reference", + "Command to add project to project reference", + Accept.OneOrMoreArguments, CommonOptions.HelpOption(), + Create.Option("-f|--framework", + "Add reference only when targetting a specific framework", + Accept.AnyOneOf(Suggest.TargetFrameworksFromProjectFile) + .With(name: "FRAMEWORK"))), CommonOptions.HelpOption()); public static IEnumerable QueryNuGet(string match) { diff --git a/src/dotnet/commands/dotnet-add/Program.cs b/src/dotnet/commands/dotnet-add/Program.cs index 09de6a9f9..25fe203ea 100644 --- a/src/dotnet/commands/dotnet-add/Program.cs +++ b/src/dotnet/commands/dotnet-add/Program.cs @@ -3,7 +3,9 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Add.PackageReference; using Microsoft.DotNet.Tools.Add.ProjectToProjectReference; @@ -16,11 +18,22 @@ namespace Microsoft.DotNet.Tools.Add protected override string FullCommandNameLocalized => LocalizableStrings.NetAddCommand; protected override string ArgumentName => Constants.ProjectArgumentName; protected override string ArgumentDescriptionLocalized => CommonLocalizableStrings.ArgumentsProjectDescription; - internal override List> SubCommands => - new List> + + internal override Dictionary> SubCommands => + new Dictionary> { - AddProjectToProjectReferenceCommand.Create, - AddPackageReferenceCommand.Create, + { + "reference", + add => new AddProjectToProjectReferenceCommand( + add["reference"], + add.Value()) + }, + { + "package", + add => new AddPackageReferenceCommand( + add["package"], + add.Value()) + } }; public static int Run(string[] args) @@ -29,4 +42,4 @@ namespace Microsoft.DotNet.Tools.Add return command.RunCommand(args); } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-add/dotnet-add-package/Program.cs b/src/dotnet/commands/dotnet-add/dotnet-add-package/Program.cs index c5a1fa054..a5ccd858b 100644 --- a/src/dotnet/commands/dotnet-add/dotnet-add-package/Program.cs +++ b/src/dotnet/commands/dotnet-add/dotnet-add-package/Program.cs @@ -1,105 +1,65 @@ // 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.Build.Evaluation; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Tools.MSBuild; using Microsoft.DotNet.Tools.NuGet; -using NuGet.Frameworks; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; namespace Microsoft.DotNet.Tools.Add.PackageReference { - internal class AddPackageReferenceCommand : DotNetSubCommandBase + internal class AddPackageReferenceCommand : CommandBase { - private CommandOption _versionOption; - private CommandOption _frameworkOption; - private CommandOption _noRestoreOption; - private CommandOption _sourceOption; - private CommandOption _packageDirectoryOption; - private CommandArgument _packageNameArgument; + private readonly AppliedOption _appliedCommand; - public static DotNetSubCommandBase Create() + private readonly string _packageId; + private readonly string _fileOrDirectory; + + public AddPackageReferenceCommand(AppliedOption appliedCommand, string fileOrDirectory) { - var command = new AddPackageReferenceCommand - { - Name = "package", - FullName = LocalizableStrings.AppFullName, - Description = LocalizableStrings.AppDescription, - HandleRemainingArguments = false - }; + _appliedCommand = appliedCommand; + _fileOrDirectory = fileOrDirectory; + _packageId = appliedCommand.Value(); - command.HelpOption("-h|--help"); - - command._packageNameArgument = command.Argument( - $"<{LocalizableStrings.CmdPackage}>", - LocalizableStrings.CmdPackageDescription, - multipleValues: false); - - command._versionOption = command.Option( - $"-v|--version <{LocalizableStrings.CmdVersion}>", - description: LocalizableStrings.CmdVersionDescription, - optionType: CommandOptionType.SingleValue); - - command._frameworkOption = command.Option( - $"-f|--framework <{LocalizableStrings.CmdFramework}>", - LocalizableStrings.CmdFrameworkDescription, - CommandOptionType.SingleValue); - - command._noRestoreOption = command.Option( - "-n|--no-restore ", - LocalizableStrings.CmdNoRestoreDescription, - CommandOptionType.NoValue); - - command._sourceOption = command.Option( - $"-s|--source <{LocalizableStrings.CmdSource}>", - LocalizableStrings.CmdSourceDescription, - CommandOptionType.SingleValue); - - command._packageDirectoryOption = command.Option( - $"--package-directory <{LocalizableStrings.CmdPackageDirectory}>", - LocalizableStrings.CmdPackageDirectoryDescription, - CommandOptionType.SingleValue); - - return command; + + if ( string.IsNullOrWhiteSpace(_packageId) || _appliedCommand.Arguments.Count > 1) + { + throw new GracefulException(LocalizableStrings.SpecifyExactlyOnePackageReference); + } } - public override int Run(string fileOrDirectory) + public override int Execute() { - if (_packageNameArgument.Values.Count != 1 || string.IsNullOrWhiteSpace(_packageNameArgument.Value) || RemainingArguments.Count > 0) - { - throw new GracefulException(LocalizableStrings.SpecifyExactlyOnePackageReference); - } - var projectFilePath = string.Empty; - if (!File.Exists(fileOrDirectory)) + if (!File.Exists(_fileOrDirectory)) { - projectFilePath = MsbuildProject.GetProjectFileFromDirectory(fileOrDirectory).FullName; + projectFilePath = MsbuildProject.GetProjectFileFromDirectory(_fileOrDirectory).FullName; } else { - projectFilePath = fileOrDirectory; + projectFilePath = _fileOrDirectory; } var tempDgFilePath = string.Empty; - if (!_noRestoreOption.HasValue()) + if (!_appliedCommand.HasOption("no-restore")) { // Create a Dependency Graph file for the project tempDgFilePath = Path.GetTempFileName(); GetProjectDependencyGraph(projectFilePath, tempDgFilePath); } - var result = NuGetCommand.Run(TransformArgs(_packageNameArgument.Value, tempDgFilePath, projectFilePath)); + var result = NuGetCommand.Run( + TransformArgs( + _packageId, + tempDgFilePath, + projectFilePath)); DisposeTemporaryFile(tempDgFilePath); return result; @@ -136,7 +96,8 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference private string[] TransformArgs(string packageId, string tempDgFilePath, string projectFilePath) { - var args = new List(){ + var args = new List + { "package", "add", "--package", @@ -145,27 +106,11 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference projectFilePath }; - if (_versionOption.HasValue()) - { - args.Add("--version"); - args.Add(_versionOption.Value()); - } - if (_sourceOption.HasValue()) - { - args.Add("--source"); - args.Add(_sourceOption.Value()); - } - if (_frameworkOption.HasValue()) - { - args.Add("--framework"); - args.Add(_frameworkOption.Value()); - } - if (_packageDirectoryOption.HasValue()) - { - args.Add("--package-directory"); - args.Add(_packageDirectoryOption.Value()); - } - if (_noRestoreOption.HasValue()) + args.AddRange(_appliedCommand + .OptionValuesToBeForwarded() + .SelectMany(a => a.Split(' '))); + + if (_appliedCommand.HasOption("no-restore")) { args.Add("--no-restore"); } @@ -178,4 +123,4 @@ namespace Microsoft.DotNet.Tools.Add.PackageReference return args.ToArray(); } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-add/dotnet-add-reference/Program.cs b/src/dotnet/commands/dotnet-add/dotnet-add-reference/Program.cs index aef1d216d..a1159ed23 100644 --- a/src/dotnet/commands/dotnet-add/dotnet-add-reference/Program.cs +++ b/src/dotnet/commands/dotnet-add/dotnet-add-reference/Program.cs @@ -1,59 +1,46 @@ // 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.IO; +using System.Linq; +using System.Text; using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; using NuGet.Frameworks; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference { - internal class AddProjectToProjectReferenceCommand : DotNetSubCommandBase + internal class AddProjectToProjectReferenceCommand : CommandBase { - private CommandOption _frameworkOption; + private readonly AppliedOption _appliedCommand; + private readonly string _fileOrDirectory; - public static DotNetSubCommandBase Create() + public AddProjectToProjectReferenceCommand(AppliedOption appliedCommand, string fileOrDirectory) { - var command = new AddProjectToProjectReferenceCommand() + if (appliedCommand == null) { - Name = "reference", - FullName = LocalizableStrings.AppFullName, - Description = LocalizableStrings.AppDescription, - HandleRemainingArguments = true, - ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText, - }; - - command.HelpOption("-h|--help"); - - command._frameworkOption = command.Option( - $"-f|--framework <{CommonLocalizableStrings.CmdFramework}>", - LocalizableStrings.CmdFrameworkDescription, - CommandOptionType.SingleValue); - - return command; + throw new ArgumentNullException(nameof(appliedCommand)); + } + _appliedCommand = appliedCommand; + _fileOrDirectory = fileOrDirectory; } - public override int Run(string fileOrDirectory) + public override int Execute() { var projects = new ProjectCollection(); - MsbuildProject msbuildProj = MsbuildProject.FromFileOrDirectory(projects, fileOrDirectory); + MsbuildProject msbuildProj = MsbuildProject.FromFileOrDirectory(projects, _fileOrDirectory); - if (RemainingArguments.Count == 0) - { - throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToAdd); - } + var frameworkString = _appliedCommand["framework"].Value(); - string frameworkString = _frameworkOption.Value(); - PathUtility.EnsureAllPathsExist(RemainingArguments, CommonLocalizableStrings.ReferenceDoesNotExist); - List refs = RemainingArguments - .Select((r) => MsbuildProject.FromFile(projects, r)) - .ToList(); + PathUtility.EnsureAllPathsExist(_appliedCommand.Arguments, CommonLocalizableStrings.ReferenceDoesNotExist); + List refs = _appliedCommand.Arguments + .Select((r) => MsbuildProject.FromFile(projects, r)) + .ToList(); if (frameworkString == null) { @@ -64,8 +51,8 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference if (!@ref.CanWorkOnFramework(tfm)) { Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString( - @ref, - msbuildProj.GetTargetFrameworks().Select((fx) => fx.GetShortFolderName()))); + @ref, + msbuildProj.GetTargetFrameworks().Select((fx) => fx.GetShortFolderName()))); return 1; } } @@ -77,9 +64,9 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference if (!msbuildProj.IsTargetingFramework(framework)) { Reporter.Error.WriteLine(string.Format( - CommonLocalizableStrings.ProjectDoesNotTargetFramework, - msbuildProj.ProjectRootElement.FullPath, - frameworkString)); + CommonLocalizableStrings.ProjectDoesNotTargetFramework, + msbuildProj.ProjectRootElement.FullPath, + frameworkString)); return 1; } @@ -88,18 +75,19 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference if (!@ref.CanWorkOnFramework(framework)) { Reporter.Error.Write(GetProjectNotCompatibleWithFrameworksDisplayString( - @ref, - new string[] { frameworkString })); + @ref, + new string[] { frameworkString })); return 1; } } } - var relativePathReferences = RemainingArguments.Select((r) => - PathUtility.GetRelativePath(msbuildProj.ProjectDirectory, Path.GetFullPath(r))).ToList(); + var relativePathReferences = _appliedCommand.Arguments.Select((r) => + PathUtility.GetRelativePath(msbuildProj.ProjectDirectory, Path.GetFullPath(r))) + .ToList(); int numberOfAddedReferences = msbuildProj.AddProjectToProjectReferences( - _frameworkOption.Value(), + frameworkString, relativePathReferences); if (numberOfAddedReferences != 0) @@ -122,4 +110,4 @@ namespace Microsoft.DotNet.Tools.Add.ProjectToProjectReference return sb.ToString(); } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-complete/CompleteCommandParser.cs b/src/dotnet/commands/dotnet-complete/CompleteCommandParser.cs index e79951fcb..c42db5fc1 100644 --- a/src/dotnet/commands/dotnet-complete/CompleteCommandParser.cs +++ b/src/dotnet/commands/dotnet-complete/CompleteCommandParser.cs @@ -15,6 +15,7 @@ namespace Microsoft.DotNet.Cli .With(name: "path"), Create.Option("--position", "", Accept.ExactlyOneArgument - .With(name: "command"))); + .With(name: "command") + .MaterializeAs(o => int.Parse(o.Arguments.Single())))); } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-list/Program.cs b/src/dotnet/commands/dotnet-list/Program.cs index 62cdc3bac..016cfebe9 100644 --- a/src/dotnet/commands/dotnet-list/Program.cs +++ b/src/dotnet/commands/dotnet-list/Program.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.List.ProjectToProjectReferences; @@ -15,10 +16,11 @@ namespace Microsoft.DotNet.Tools.List protected override string FullCommandNameLocalized => LocalizableStrings.NetListCommand; protected override string ArgumentName => Constants.ProjectArgumentName; protected override string ArgumentDescriptionLocalized => CommonLocalizableStrings.ArgumentsProjectDescription; - internal override List> SubCommands => - new List> + + internal override Dictionary> SubCommands => + new Dictionary> { - ListProjectToProjectReferencesCommand.Create, + { "list", o => new ListProjectToProjectReferencesCommand(o) } }; public static int Run(string[] args) @@ -27,4 +29,4 @@ namespace Microsoft.DotNet.Tools.List return command.RunCommand(args); } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-list/dotnet-list-reference/Program.cs b/src/dotnet/commands/dotnet-list/dotnet-list-reference/Program.cs index 28a3f29ff..fe33c9a0f 100644 --- a/src/dotnet/commands/dotnet-list/dotnet-list-reference/Program.cs +++ b/src/dotnet/commands/dotnet-list/dotnet-list-reference/Program.cs @@ -1,40 +1,40 @@ // 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.Linq; using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; -using System.Linq; namespace Microsoft.DotNet.Tools.List.ProjectToProjectReferences { - internal class ListProjectToProjectReferencesCommand : DotNetSubCommandBase + internal class ListProjectToProjectReferencesCommand : CommandBase { - public static DotNetSubCommandBase Create() + private readonly string _fileOrDirectory; + + public ListProjectToProjectReferencesCommand(AppliedOption appliedCommand) { - var command = new ListProjectToProjectReferencesCommand() + if (appliedCommand == null) { - Name = "reference", - FullName = LocalizableStrings.AppFullName, - Description = LocalizableStrings.AppDescription, - }; + throw new ArgumentNullException(nameof(appliedCommand)); + } - command.HelpOption("-h|--help"); - - return command; + _fileOrDirectory = appliedCommand.Arguments.Single(); } - public override int Run(string fileOrDirectory) + public override int Execute() { - var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), fileOrDirectory); + var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), _fileOrDirectory); var p2ps = msbuildProj.GetProjectToProjectReferences(); if (!p2ps.Any()) { Reporter.Output.WriteLine(string.Format( - CommonLocalizableStrings.NoReferencesFound, - CommonLocalizableStrings.P2P, - fileOrDirectory)); + CommonLocalizableStrings.NoReferencesFound, + CommonLocalizableStrings.P2P, + _fileOrDirectory)); return 0; } @@ -48,4 +48,4 @@ namespace Microsoft.DotNet.Tools.List.ProjectToProjectReferences return 0; } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-remove/Program.cs b/src/dotnet/commands/dotnet-remove/Program.cs index 26555a63b..c30791bf5 100644 --- a/src/dotnet/commands/dotnet-remove/Program.cs +++ b/src/dotnet/commands/dotnet-remove/Program.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Remove.PackageReference; using Microsoft.DotNet.Tools.Remove.ProjectToProjectReference; @@ -16,11 +17,12 @@ namespace Microsoft.DotNet.Tools.Remove protected override string FullCommandNameLocalized => LocalizableStrings.NetRemoveCommand; protected override string ArgumentName => Constants.ProjectArgumentName; protected override string ArgumentDescriptionLocalized => CommonLocalizableStrings.ArgumentsProjectDescription; - internal override List> SubCommands => - new List> + + internal override Dictionary> SubCommands => + new Dictionary> { - RemoveProjectToProjectReferenceCommand.Create, - RemovePackageReferenceCommand.Create + { "reference", o => new RemoveProjectToProjectReferenceCommand(o) }, + { "package", o => new RemovePackageReferenceCommand(o) } }; public static int Run(string[] args) @@ -29,4 +31,4 @@ namespace Microsoft.DotNet.Tools.Remove return command.RunCommand(args); } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-remove/dotnet-remove-package/Program.cs b/src/dotnet/commands/dotnet-remove/dotnet-remove-package/Program.cs index 85af67e76..082b97ff6 100644 --- a/src/dotnet/commands/dotnet-remove/dotnet-remove-package/Program.cs +++ b/src/dotnet/commands/dotnet-remove/dotnet-remove-package/Program.cs @@ -1,61 +1,50 @@ // 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.Build.Evaluation; +using System; +using System.IO; +using System.Linq; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Tools.Common; -using Microsoft.DotNet.Tools.MSBuild; using Microsoft.DotNet.Tools.NuGet; -using NuGet.Frameworks; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; namespace Microsoft.DotNet.Tools.Remove.PackageReference { - internal class RemovePackageReferenceCommand : DotNetSubCommandBase + internal class RemovePackageReferenceCommand : CommandBase { + private readonly AppliedOption _appliedCommand; + private readonly string _fileOrDirectory; - public static DotNetSubCommandBase Create() + public RemovePackageReferenceCommand(AppliedOption appliedCommand) { - var command = new RemovePackageReferenceCommand + if (appliedCommand == null) { - Name = "package", - FullName = LocalizableStrings.AppFullName, - Description = LocalizableStrings.AppDescription, - HandleRemainingArguments = true, - ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText, - }; - - command.HelpOption("-h|--help"); - - return command; - } - - public override int Run(string fileOrDirectory) - { - if (RemainingArguments.Count != 1) + throw new ArgumentNullException(nameof(appliedCommand)); + } + if (_appliedCommand.Arguments.Count != 1) { throw new GracefulException(LocalizableStrings.SpecifyExactlyOnePackageReference); } + _appliedCommand = appliedCommand; + _fileOrDirectory = appliedCommand.Arguments.Single(); + } + + public override int Execute() + { var projectFilePath = string.Empty; - if (!File.Exists(fileOrDirectory)) + if (!File.Exists(_fileOrDirectory)) { - projectFilePath = MsbuildProject.GetProjectFileFromDirectory(fileOrDirectory).FullName; + projectFilePath = MsbuildProject.GetProjectFileFromDirectory(_fileOrDirectory).FullName; } else { - projectFilePath = fileOrDirectory; + projectFilePath = _fileOrDirectory; } - var packageToRemove = RemainingArguments.First(); + var packageToRemove = _appliedCommand.Arguments.Single(); var result = NuGetCommand.Run(TransformArgs(packageToRemove, projectFilePath)); return result; @@ -63,7 +52,8 @@ namespace Microsoft.DotNet.Tools.Remove.PackageReference private string[] TransformArgs(string packageId, string projectFilePath) { - return new string[]{ + return new string[] + { "package", "remove", "--package", @@ -73,4 +63,4 @@ namespace Microsoft.DotNet.Tools.Remove.PackageReference }; } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-remove/dotnet-remove-reference/Program.cs b/src/dotnet/commands/dotnet-remove/dotnet-remove-reference/Program.cs index 04d4069f4..55c6b3e2c 100644 --- a/src/dotnet/commands/dotnet-remove/dotnet-remove-reference/Program.cs +++ b/src/dotnet/commands/dotnet-remove/dotnet-remove-reference/Program.cs @@ -1,6 +1,8 @@ // 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.Linq; using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.CommandLine; @@ -8,42 +10,34 @@ using Microsoft.DotNet.Cli.Utils; namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference { - internal class RemoveProjectToProjectReferenceCommand : DotNetSubCommandBase + internal class RemoveProjectToProjectReferenceCommand : CommandBase { - private CommandOption _frameworkOption; + private readonly AppliedOption _appliedCommand; + private readonly string _fileOrDirectory; - public static DotNetSubCommandBase Create() + public RemoveProjectToProjectReferenceCommand(AppliedOption appliedCommand) { - var command = new RemoveProjectToProjectReferenceCommand() + if (appliedCommand == null) { - Name = "reference", - FullName = LocalizableStrings.AppFullName, - Description = LocalizableStrings.AppDescription, - HandleRemainingArguments = true, - ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText, - }; + throw new ArgumentNullException(nameof(appliedCommand)); + } - command.HelpOption("-h|--help"); - - command._frameworkOption = command.Option( - $"-f|--framework <{CommonLocalizableStrings.CmdFramework}>", - LocalizableStrings.CmdFrameworkDescription, - CommandOptionType.SingleValue); - - return command; - } - - public override int Run(string fileOrDirectory) - { - var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), fileOrDirectory); - if (RemainingArguments.Count == 0) + if (_appliedCommand.Arguments.Count == 0) { throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToRemove); } + _appliedCommand = appliedCommand; + _fileOrDirectory = appliedCommand.Arguments.Single(); + } + + public override int Execute() + { + var msbuildProj = MsbuildProject.FromFileOrDirectory(new ProjectCollection(), _fileOrDirectory); + int numberOfRemovedReferences = msbuildProj.RemoveProjectToProjectReferences( - _frameworkOption.Value(), - RemainingArguments); + _appliedCommand["framework"].Value(), + _appliedCommand.Arguments); if (numberOfRemovedReferences != 0) { @@ -53,4 +47,4 @@ namespace Microsoft.DotNet.Tools.Remove.ProjectToProjectReference return 0; } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-sln/Program.cs b/src/dotnet/commands/dotnet-sln/Program.cs index 11e1abe65..484f20aec 100644 --- a/src/dotnet/commands/dotnet-sln/Program.cs +++ b/src/dotnet/commands/dotnet-sln/Program.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Sln.Add; using Microsoft.DotNet.Tools.Sln.List; @@ -17,12 +18,13 @@ namespace Microsoft.DotNet.Tools.Sln protected override string FullCommandNameLocalized => LocalizableStrings.AppFullName; protected override string ArgumentName => Constants.SolutionArgumentName; protected override string ArgumentDescriptionLocalized => CommonLocalizableStrings.ArgumentsSolutionDescription; - internal override List> SubCommands => - new List> + + internal override Dictionary> SubCommands => + new Dictionary> { - AddProjectToSolutionCommand.Create, - ListProjectsInSolutionCommand.Create, - RemoveProjectFromSolutionCommand.Create + { "add", o => new AddProjectToSolutionCommand(o) }, + { "list", o => new ListProjectsInSolutionCommand(o) }, + { "remove", o => new RemoveProjectFromSolutionCommand(o) } }; public static int Run(string[] args) @@ -31,4 +33,4 @@ namespace Microsoft.DotNet.Tools.Sln return command.RunCommand(args); } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-sln/add/Program.cs b/src/dotnet/commands/dotnet-sln/add/Program.cs index 6b6124a29..c5d23ff84 100644 --- a/src/dotnet/commands/dotnet-sln/add/Program.cs +++ b/src/dotnet/commands/dotnet-sln/add/Program.cs @@ -1,49 +1,50 @@ // 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.IO; +using System.Linq; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; -using Microsoft.DotNet.Tools.Sln; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; namespace Microsoft.DotNet.Tools.Sln.Add { - internal class AddProjectToSolutionCommand : DotNetSubCommandBase + internal class AddProjectToSolutionCommand : CommandBase { - public static DotNetSubCommandBase Create() + private readonly AppliedOption _appliedCommand; + private readonly string _fileOrDirectory; + + public AddProjectToSolutionCommand(AppliedOption appliedCommand) { - var command = new AddProjectToSolutionCommand() + if (appliedCommand == null) { - Name = "add", - FullName = LocalizableStrings.AddAppFullName, - Description = LocalizableStrings.AddSubcommandHelpText, - HandleRemainingArguments = true, - ArgumentSeparatorHelpText = LocalizableStrings.AddSubcommandHelpText, - }; + throw new ArgumentNullException(nameof(appliedCommand)); + } + _appliedCommand = appliedCommand; - command.HelpOption("-h|--help"); - - return command; + _fileOrDirectory = appliedCommand.Arguments.Single(); } - public override int Run(string fileOrDirectory) + public override int Execute() { - SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory); + SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory); - if (RemainingArguments.Count == 0) + if (_appliedCommand.Arguments.Count == 0) { throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToAdd); } - PathUtility.EnsureAllPathsExist(RemainingArguments, CommonLocalizableStrings.ProjectDoesNotExist); - var fullProjectPaths = RemainingArguments.Select((p) => Path.GetFullPath(p)).ToList(); + PathUtility.EnsureAllPathsExist(_appliedCommand.Arguments, CommonLocalizableStrings.ProjectDoesNotExist); + + var fullProjectPaths = _appliedCommand.Arguments + .Select(Path.GetFullPath) + .ToList(); + + var preAddProjectCount = slnFile.Projects.Count; - int preAddProjectCount = slnFile.Projects.Count; foreach (var fullProjectPath in fullProjectPaths) { slnFile.AddProject(fullProjectPath); @@ -57,4 +58,4 @@ namespace Microsoft.DotNet.Tools.Sln.Add return 0; } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-sln/list/Program.cs b/src/dotnet/commands/dotnet-sln/list/Program.cs index 3ff1f8480..a82bc2f87 100644 --- a/src/dotnet/commands/dotnet-sln/list/Program.cs +++ b/src/dotnet/commands/dotnet-sln/list/Program.cs @@ -1,33 +1,32 @@ // 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.Linq; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; -using Microsoft.DotNet.Tools.Sln; namespace Microsoft.DotNet.Tools.Sln.List { - internal class ListProjectsInSolutionCommand : DotNetSubCommandBase + internal class ListProjectsInSolutionCommand : CommandBase { - public static DotNetSubCommandBase Create() + private readonly string _fileOrDirectory; + + public ListProjectsInSolutionCommand(AppliedOption appliedCommand) { - var command = new ListProjectsInSolutionCommand() + if (appliedCommand == null) { - Name = "list", - FullName = LocalizableStrings.ListAppFullName, - Description = LocalizableStrings.ListSubcommandHelpText, - }; - - command.HelpOption("-h|--help"); - - return command; + throw new ArgumentNullException(nameof(appliedCommand)); + } + _fileOrDirectory = appliedCommand.Arguments.Single(); } - public override int Run(string fileOrDirectory) + public override int Execute() { - SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory); + SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory); if (slnFile.Projects.Count == 0) { Reporter.Output.WriteLine(CommonLocalizableStrings.NoProjectsFound); @@ -44,4 +43,4 @@ namespace Microsoft.DotNet.Tools.Sln.List return 0; } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-sln/remove/Program.cs b/src/dotnet/commands/dotnet-sln/remove/Program.cs index c147052cd..6327e2181 100644 --- a/src/dotnet/commands/dotnet-sln/remove/Program.cs +++ b/src/dotnet/commands/dotnet-sln/remove/Program.cs @@ -1,49 +1,47 @@ // 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.IO; +using System.Linq; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Sln.Internal; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Common; -using Microsoft.DotNet.Tools.Sln; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; namespace Microsoft.DotNet.Tools.Sln.Remove { - internal class RemoveProjectFromSolutionCommand : DotNetSubCommandBase + internal class RemoveProjectFromSolutionCommand : CommandBase { - public static DotNetSubCommandBase Create() + private readonly AppliedOption _appliedCommand; + private readonly string _fileOrDirectory; + + public RemoveProjectFromSolutionCommand(AppliedOption appliedCommand) { - var command = new RemoveProjectFromSolutionCommand() + if (appliedCommand == null) { - Name = "remove", - FullName = LocalizableStrings.RemoveAppFullName, - Description = LocalizableStrings.RemoveSubcommandHelpText, - HandleRemainingArguments = true, - ArgumentSeparatorHelpText = LocalizableStrings.RemoveSubcommandHelpText, - }; + throw new ArgumentNullException(nameof(appliedCommand)); + } - command.HelpOption("-h|--help"); - - return command; - } - - public override int Run(string fileOrDirectory) - { - SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(fileOrDirectory); - - if (RemainingArguments.Count == 0) + if (_appliedCommand.Arguments.Count == 0) { throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneProjectToRemove); } - var relativeProjectPaths = RemainingArguments.Select((p) => - PathUtility.GetRelativePath( - PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory), - Path.GetFullPath(p))).ToList(); + _appliedCommand = appliedCommand; + _fileOrDirectory = appliedCommand.Arguments.Single(); + } + + public override int Execute() + { + SlnFile slnFile = SlnFileFactory.CreateFromFileOrDirectory(_fileOrDirectory); + + var relativeProjectPaths = _appliedCommand.Arguments.Select(p => + PathUtility.GetRelativePath( + PathUtility.EnsureTrailingSlash(slnFile.BaseDirectory), + Path.GetFullPath(p))) + .ToList(); bool slnChanged = false; foreach (var path in relativeProjectPaths) @@ -63,4 +61,4 @@ namespace Microsoft.DotNet.Tools.Sln.Remove return 0; } } -} +} \ No newline at end of file