diff --git a/src/dotnet/CommonLocalizableStrings.resx b/src/dotnet/CommonLocalizableStrings.resx index 708b0daf3..a2f5c3270 100644 --- a/src/dotnet/CommonLocalizableStrings.resx +++ b/src/dotnet/CommonLocalizableStrings.resx @@ -520,4 +520,7 @@ Show help information. + + Does not do an implicit restore when executing the command. + \ No newline at end of file diff --git a/src/dotnet/CommonOptions.cs b/src/dotnet/CommonOptions.cs index 06047fcd3..e3103b64c 100644 --- a/src/dotnet/CommonOptions.cs +++ b/src/dotnet/CommonOptions.cs @@ -65,5 +65,11 @@ namespace Microsoft.DotNet.Cli public static ArgumentsRule DefaultToCurrentDirectory(this ArgumentsRule rule) => rule.With(defaultValue: () => PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory())); + + public static Option NoRestoreOption() => + Create.Option( + "--no-restore", + CommonLocalizableStrings.NoRestoreDescription, + Accept.NoArguments()); } } \ No newline at end of file diff --git a/src/dotnet/commands/CommandWithRestoreOptions.cs b/src/dotnet/commands/CommandWithRestoreOptions.cs new file mode 100644 index 000000000..aaf9748d5 --- /dev/null +++ b/src/dotnet/commands/CommandWithRestoreOptions.cs @@ -0,0 +1,39 @@ +// 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.Collections.Generic; +using System.Linq; +using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; +using Microsoft.DotNet.Tools.MSBuild; +using Microsoft.DotNet.Tools.Restore; + +namespace Microsoft.DotNet.Tools +{ + public static class CreateWithRestoreOptions + { + public static Command Command( + string name, + string help, + ArgumentsRule arguments, + params Option[] options) + { + return Create.Command(name, help, arguments, RestoreCommandParser.AddImplicitRestoreOptions(options)); + } + + public static Command Command( + string name, + string help, + ArgumentsRule arguments, + bool treatUnmatchedTokensAsErrors, + params Option[] options) + { + return Create.Command( + name, + help, + arguments, + treatUnmatchedTokensAsErrors, + RestoreCommandParser.AddImplicitRestoreOptions(options)); + } + } +} \ No newline at end of file diff --git a/src/dotnet/commands/RestoringCommand.cs b/src/dotnet/commands/RestoringCommand.cs new file mode 100644 index 000000000..67c114577 --- /dev/null +++ b/src/dotnet/commands/RestoringCommand.cs @@ -0,0 +1,56 @@ +// 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.Collections.Generic; +using System.Linq; +using Microsoft.DotNet.Tools.MSBuild; +using Microsoft.DotNet.Tools.Restore; + +namespace Microsoft.DotNet.Tools +{ + public class RestoringCommand : MSBuildForwardingApp + { + private bool NoRestore { get; } + + private IEnumerable ArgsToForward { get; } + + private IEnumerable ArgsToForwardToRestore() + { + var restoreArguments = ArgsToForward.Where(a => + !a.StartsWith("/t:") && + !a.StartsWith("/target:") && + !a.StartsWith("/ConsoleLoggerParameters:") && + !a.StartsWith("/clp:")); + + if (!restoreArguments.Any(a => a.StartsWith("/v:") || a.StartsWith("/verbosity:"))) + { + restoreArguments = restoreArguments.Concat(new string[] { "/v:q" }); + } + + return restoreArguments; + } + + private bool ShouldRunImplicitRestore => !NoRestore; + + public RestoringCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) + : base(msbuildArgs, msbuildPath) + { + NoRestore = noRestore; + ArgsToForward = msbuildArgs; + } + + public override int Execute() + { + if (ShouldRunImplicitRestore) + { + int exitCode = RestoreCommand.Run(ArgsToForwardToRestore().ToArray()); + if (exitCode != 0) + { + return exitCode; + } + } + + return base.Execute(); + } + } +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-build/BuildCommand.cs b/src/dotnet/commands/dotnet-build/BuildCommand.cs index 691d5ef21..95539c662 100644 --- a/src/dotnet/commands/dotnet-build/BuildCommand.cs +++ b/src/dotnet/commands/dotnet-build/BuildCommand.cs @@ -2,18 +2,21 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; +using System.Linq; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.MSBuild; +using Microsoft.DotNet.Tools; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Tools.Restore; using Parser = Microsoft.DotNet.Cli.Parser; namespace Microsoft.DotNet.Tools.Build { - public class BuildCommand : MSBuildForwardingApp + public class BuildCommand : RestoringCommand { - public BuildCommand(IEnumerable msbuildArgs, string msbuildPath = null) - : base(msbuildArgs, msbuildPath) + public BuildCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) + : base(msbuildArgs, noRestore, msbuildPath) { } @@ -44,7 +47,9 @@ namespace Microsoft.DotNet.Tools.Build msbuildArgs.Add($"/clp:Summary"); - return new BuildCommand(msbuildArgs, msbuildPath); + bool noRestore = appliedBuildOptions.HasOption("--no-restore"); + + return new BuildCommand(msbuildArgs, noRestore, msbuildPath); } public static int Run(string[] args) diff --git a/src/dotnet/commands/dotnet-build/BuildCommandParser.cs b/src/dotnet/commands/dotnet-build/BuildCommandParser.cs index eaa00740f..76da0258e 100644 --- a/src/dotnet/commands/dotnet-build/BuildCommandParser.cs +++ b/src/dotnet/commands/dotnet-build/BuildCommandParser.cs @@ -1,6 +1,7 @@ // 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.Collections.Generic; using System.Linq; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Tools; @@ -11,7 +12,7 @@ namespace Microsoft.DotNet.Cli internal static class BuildCommandParser { public static Command Build() => - Create.Command( + CreateWithRestoreOptions.Command( "build", LocalizableStrings.AppFullName, Accept.ZeroOrMoreArguments() @@ -37,6 +38,7 @@ namespace Microsoft.DotNet.Cli LocalizableStrings.NoDependenciesOptionDescription, Accept.NoArguments() .ForwardAs("/p:BuildProjectReferences=false")), + CommonOptions.NoRestoreOption(), CommonOptions.VerbosityOption()); } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs b/src/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs index b3edf4abe..dbf81dd6e 100644 --- a/src/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs +++ b/src/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs @@ -58,7 +58,7 @@ namespace Microsoft.DotNet.Tools.MSBuild return ret; } - public int Execute() + public virtual int Execute() { return GetProcessStartInfo().Execute(); } diff --git a/src/dotnet/commands/dotnet-pack/PackCommand.cs b/src/dotnet/commands/dotnet-pack/PackCommand.cs index 2821c23d8..0c7146356 100644 --- a/src/dotnet/commands/dotnet-pack/PackCommand.cs +++ b/src/dotnet/commands/dotnet-pack/PackCommand.cs @@ -5,16 +5,17 @@ using System.Collections.Generic; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.MSBuild; +using Microsoft.DotNet.Tools; using Microsoft.DotNet.Cli; using System.Diagnostics; using Parser = Microsoft.DotNet.Cli.Parser; namespace Microsoft.DotNet.Tools.Pack { - public class PackCommand : MSBuildForwardingApp + public class PackCommand : RestoringCommand { - public PackCommand(IEnumerable msbuildArgs, string msbuildPath = null) - : base(msbuildArgs, msbuildPath) + public PackCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) + : base(msbuildArgs, noRestore, msbuildPath) { } @@ -30,14 +31,16 @@ namespace Microsoft.DotNet.Tools.Pack var msbuildArgs = new List() { - "/t:pack" + "/t:pack" }; msbuildArgs.AddRange(parsedPack.OptionValuesToBeForwarded()); msbuildArgs.AddRange(parsedPack.Arguments); - return new PackCommand(msbuildArgs, msbuildPath); + bool noRestore = parsedPack.HasOption("--no-restore"); + + return new PackCommand(msbuildArgs, noRestore, msbuildPath); } public static int Run(string[] args) diff --git a/src/dotnet/commands/dotnet-pack/PackCommandParser.cs b/src/dotnet/commands/dotnet-pack/PackCommandParser.cs index 56be1ee3d..036e12072 100644 --- a/src/dotnet/commands/dotnet-pack/PackCommandParser.cs +++ b/src/dotnet/commands/dotnet-pack/PackCommandParser.cs @@ -1,8 +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. +using System.Collections.Generic; using System.Linq; using Microsoft.DotNet.Cli.CommandLine; +using Microsoft.DotNet.Tools; using LocalizableStrings = Microsoft.DotNet.Tools.Pack.LocalizableStrings; namespace Microsoft.DotNet.Cli @@ -10,7 +12,7 @@ namespace Microsoft.DotNet.Cli internal static class PackCommandParser { public static Command Pack() => - Create.Command( + CreateWithRestoreOptions.Command( "pack", LocalizableStrings.AppFullName, Accept.ZeroOrMoreArguments(), @@ -39,6 +41,7 @@ namespace Microsoft.DotNet.Cli "-s|--serviceable", LocalizableStrings.CmdServiceableDescription, Accept.NoArguments().ForwardAs("/p:Serviceable=true")), + CommonOptions.NoRestoreOption(), CommonOptions.VerbosityOption()); } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-publish/Program.cs b/src/dotnet/commands/dotnet-publish/Program.cs index 8c8fbc9cf..d4337e107 100644 --- a/src/dotnet/commands/dotnet-publish/Program.cs +++ b/src/dotnet/commands/dotnet-publish/Program.cs @@ -5,15 +5,16 @@ using System.Collections.Generic; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Tools; using Microsoft.DotNet.Tools.MSBuild; using Parser = Microsoft.DotNet.Cli.Parser; namespace Microsoft.DotNet.Tools.Publish { - public class PublishCommand : MSBuildForwardingApp + public class PublishCommand : RestoringCommand { - private PublishCommand(IEnumerable msbuildArgs, string msbuildPath = null) - : base(msbuildArgs, msbuildPath) + private PublishCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) + : base(msbuildArgs, noRestore, msbuildPath) { } @@ -37,7 +38,9 @@ namespace Microsoft.DotNet.Tools.Publish msbuildArgs.AddRange(appliedPublishOption.Arguments); - return new PublishCommand(msbuildArgs, msbuildPath); + bool noRestore = appliedPublishOption.HasOption("--no-restore"); + + return new PublishCommand(msbuildArgs, noRestore, msbuildPath); } public static int Run(string[] args) diff --git a/src/dotnet/commands/dotnet-publish/PublishCommandParser.cs b/src/dotnet/commands/dotnet-publish/PublishCommandParser.cs index 600d4c459..9149c1dfd 100644 --- a/src/dotnet/commands/dotnet-publish/PublishCommandParser.cs +++ b/src/dotnet/commands/dotnet-publish/PublishCommandParser.cs @@ -1,8 +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. +using System.Collections.Generic; using System.Linq; using Microsoft.DotNet.Cli.CommandLine; +using Microsoft.DotNet.Tools; using LocalizableStrings = Microsoft.DotNet.Tools.Publish.LocalizableStrings; namespace Microsoft.DotNet.Cli @@ -10,7 +12,7 @@ namespace Microsoft.DotNet.Cli internal static class PublishCommandParser { public static Command Publish() => - Create.Command( + CreateWithRestoreOptions.Command( "publish", LocalizableStrings.AppDescription, Accept.ZeroOrMoreArguments(), @@ -41,6 +43,7 @@ namespace Microsoft.DotNet.Cli string value = o.Arguments.Any() ? o.Arguments.Single() : "true"; return $"/p:SelfContained={value}"; })), + CommonOptions.NoRestoreOption(), CommonOptions.VerbosityOption()); } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-restore/Program.cs b/src/dotnet/commands/dotnet-restore/Program.cs index 65a18e975..b0269370f 100644 --- a/src/dotnet/commands/dotnet-restore/Program.cs +++ b/src/dotnet/commands/dotnet-restore/Program.cs @@ -37,7 +37,7 @@ namespace Microsoft.DotNet.Tools.Restore "/t:Restore" }; - if (!parsedRestore.HasOption("verbosity")) + if (!HasVerbosityOption(parsedRestore)) { msbuildArgs.Add("/ConsoleLoggerParameters:Verbosity=Minimal"); } @@ -45,7 +45,7 @@ namespace Microsoft.DotNet.Tools.Restore msbuildArgs.AddRange(parsedRestore.OptionValuesToBeForwarded()); msbuildArgs.AddRange(parsedRestore.Arguments); - + return new RestoreCommand(msbuildArgs, msbuildPath); } @@ -65,5 +65,12 @@ namespace Microsoft.DotNet.Tools.Restore return cmd.Execute(); } + + private static bool HasVerbosityOption(AppliedOption parsedRestore) + { + return parsedRestore.HasOption("verbosity") || + parsedRestore.Arguments.Any(a => a.Contains("/v:")) || + parsedRestore.Arguments.Any(a => a.Contains("/verbosity:")); + } } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-restore/RestoreCommandParser.cs b/src/dotnet/commands/dotnet-restore/RestoreCommandParser.cs index a50c464a3..46b17d0f3 100644 --- a/src/dotnet/commands/dotnet-restore/RestoreCommandParser.cs +++ b/src/dotnet/commands/dotnet-restore/RestoreCommandParser.cs @@ -1,6 +1,7 @@ // 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.Collections.Generic; using System.Linq; using Microsoft.DotNet.Cli.CommandLine; using LocalizableStrings = Microsoft.DotNet.Tools.Restore.LocalizableStrings; @@ -14,15 +15,41 @@ namespace Microsoft.DotNet.Cli "restore", LocalizableStrings.AppFullName, Accept.ZeroOrMoreArguments(), - CommonOptions.HelpOption(), + FullRestoreOptions()); + + private static Option[] FullRestoreOptions() + { + var fullRestoreOptions = AddImplicitRestoreOptions(new Option[] { CommonOptions.HelpOption() }, true, true); + + return fullRestoreOptions.Concat(new Option[] { CommonOptions.VerbosityOption() }).ToArray(); + } + + public static Option[] AddImplicitRestoreOptions( + IEnumerable