From dd76fec56482825a1aa3566a5be66b93c9579e22 Mon Sep 17 00:00:00 2001 From: Livar Cunha Date: Thu, 1 Jun 2017 21:25:06 -0700 Subject: [PATCH 1/3] Implicit restore for build, pack, publish, run and test. --- src/dotnet/CommonOptions.cs | 6 +++ src/dotnet/commands/RestoringCommand.cs | 40 +++++++++++++++++++ .../commands/dotnet-build/BuildCommand.cs | 13 ++++-- .../dotnet-build/BuildCommandParser.cs | 1 + .../dotnet-msbuild/MSBuildForwardingApp.cs | 2 +- .../commands/dotnet-pack/PackCommand.cs | 13 +++--- .../commands/dotnet-pack/PackCommandParser.cs | 1 + src/dotnet/commands/dotnet-publish/Program.cs | 11 +++-- .../dotnet-publish/PublishCommandParser.cs | 1 + src/dotnet/commands/dotnet-run/RunCommand.cs | 9 ++++- .../commands/dotnet-run/RunCommandParser.cs | 4 +- src/dotnet/commands/dotnet-test/Program.cs | 10 +++-- .../commands/dotnet-test/TestCommandParser.cs | 1 + 13 files changed, 91 insertions(+), 21 deletions(-) create mode 100644 src/dotnet/commands/RestoringCommand.cs 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/RestoringCommand.cs b/src/dotnet/commands/RestoringCommand.cs new file mode 100644 index 000000000..944457260 --- /dev/null +++ b/src/dotnet/commands/RestoringCommand.cs @@ -0,0 +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.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; } + + 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(ArgsToForward.ToArray()); + if (exitCode != 0) + { + return exitCode; + } + } + + return base.Execute(); + } + + private bool ShouldRunImplicitRestore => !NoRestore; + } +} \ 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..d911db785 100644 --- a/src/dotnet/commands/dotnet-build/BuildCommandParser.cs +++ b/src/dotnet/commands/dotnet-build/BuildCommandParser.cs @@ -37,6 +37,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..1e1b708ab 100644 --- a/src/dotnet/commands/dotnet-pack/PackCommandParser.cs +++ b/src/dotnet/commands/dotnet-pack/PackCommandParser.cs @@ -39,6 +39,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..ef167402c 100644 --- a/src/dotnet/commands/dotnet-publish/PublishCommandParser.cs +++ b/src/dotnet/commands/dotnet-publish/PublishCommandParser.cs @@ -41,6 +41,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-run/RunCommand.cs b/src/dotnet/commands/dotnet-run/RunCommand.cs index 3401f1ac1..11e137f88 100644 --- a/src/dotnet/commands/dotnet-run/RunCommand.cs +++ b/src/dotnet/commands/dotnet-run/RunCommand.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Tools; using Microsoft.DotNet.Tools.MSBuild; using Microsoft.DotNet.Tools.Run.LaunchSettings; @@ -19,6 +20,7 @@ namespace Microsoft.DotNet.Tools.Run public bool NoBuild { get; private set; } public string Project { get; private set; } public IReadOnlyCollection Args { get; private set; } + public bool NoRestore { get; private set; } private List _args; private bool ShouldBuild => !NoBuild; @@ -55,6 +57,7 @@ namespace Microsoft.DotNet.Tools.Run string project, string launchProfile, bool noLaunchProfile, + bool noRestore, IReadOnlyCollection args) { Configuration = configuration; @@ -64,6 +67,7 @@ namespace Microsoft.DotNet.Tools.Run LaunchProfile = launchProfile; NoLaunchProfile = noLaunchProfile; Args = args; + NoRestore = noRestore; } public RunCommand MakeNewWithReplaced(string configuration = null, @@ -72,6 +76,7 @@ namespace Microsoft.DotNet.Tools.Run string project = null, string launchProfile = null, bool? noLaunchProfile = null, + bool? noRestore = null, IReadOnlyCollection args = null) { return new RunCommand( @@ -81,6 +86,7 @@ namespace Microsoft.DotNet.Tools.Run project ?? this.Project, launchProfile ?? this.LaunchProfile, noLaunchProfile ?? this.NoLaunchProfile, + noRestore ?? this.NoRestore, args ?? this.Args ); } @@ -142,8 +148,7 @@ namespace Microsoft.DotNet.Tools.Run buildArgs.Add($"/p:TargetFramework={Framework}"); } - var buildResult = new MSBuildForwardingApp(buildArgs).Execute(); - + var buildResult = new RestoringCommand(buildArgs, NoRestore).Execute(); if (buildResult != 0) { Reporter.Error.WriteLine(); diff --git a/src/dotnet/commands/dotnet-run/RunCommandParser.cs b/src/dotnet/commands/dotnet-run/RunCommandParser.cs index ec0839c88..e608bd4d5 100644 --- a/src/dotnet/commands/dotnet-run/RunCommandParser.cs +++ b/src/dotnet/commands/dotnet-run/RunCommandParser.cs @@ -23,6 +23,7 @@ namespace Microsoft.DotNet.Cli project: o.SingleArgumentOrDefault("--project"), launchProfile: o.SingleArgumentOrDefault("--launch-profile"), noLaunchProfile: o.HasOption("--no-launch-profile"), + noRestore: o.HasOption("--no-restore"), args: o.Arguments )), options: new[] @@ -45,7 +46,8 @@ namespace Microsoft.DotNet.Cli Create.Option( "--no-build", LocalizableStrings.CommandOptionNoBuildDescription, - Accept.NoArguments()) + Accept.NoArguments()), + CommonOptions.NoRestoreOption(), }); } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-test/Program.cs b/src/dotnet/commands/dotnet-test/Program.cs index a7f9a0380..805639d9e 100644 --- a/src/dotnet/commands/dotnet-test/Program.cs +++ b/src/dotnet/commands/dotnet-test/Program.cs @@ -14,10 +14,10 @@ using Parser = Microsoft.DotNet.Cli.Parser; namespace Microsoft.DotNet.Tools.Test { - public class TestCommand : MSBuildForwardingApp + public class TestCommand : RestoringCommand { - public TestCommand(IEnumerable msbuildArgs, string msbuildPath = null) - : base(msbuildArgs, msbuildPath) + public TestCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) + : base(msbuildArgs, noRestore, msbuildPath) { } @@ -65,7 +65,9 @@ namespace Microsoft.DotNet.Tools.Test } } - return new TestCommand(msbuildArgs, msbuildPath); + bool noRestore = parsedTest.HasOption("--no-restore"); + + return new TestCommand(msbuildArgs, noRestore, msbuildPath); } public static int Run(string[] args) diff --git a/src/dotnet/commands/dotnet-test/TestCommandParser.cs b/src/dotnet/commands/dotnet-test/TestCommandParser.cs index a17aa20a7..c8b830f54 100644 --- a/src/dotnet/commands/dotnet-test/TestCommandParser.cs +++ b/src/dotnet/commands/dotnet-test/TestCommandParser.cs @@ -81,6 +81,7 @@ namespace Microsoft.DotNet.Cli Accept.OneOrMoreArguments() .With(name: LocalizableStrings.cmdCollectFriendlyName) .ForwardAsSingle(o => $"/p:VSTestCollect=\"{string.Join(";", o.Arguments)}\"")), + CommonOptions.NoRestoreOption(), CommonOptions.VerbosityOption()); private static string GetSemiColonEsacpedstring(string arg) From 3231295acf2cdd51832315ff26d721e33298770f Mon Sep 17 00:00:00 2001 From: Livar Cunha Date: Fri, 2 Jun 2017 23:32:53 -0700 Subject: [PATCH 2/3] Fixing a bug in the restore option where specifying verbosity through /v was not entirely honored. Adding tests for implicit restore for all the affected commands. Fixing an issue where the command target was being passed to the restore command during implicit restore. Adding restore params to all commands with implicit restore. Also, implicitly set the restore output to quiet. Adding tests for the no-restore option. --- src/dotnet/commands/RestoringCommand.cs | 25 ++- .../dotnet-build/BuildCommandParser.cs | 59 ++++--- .../commands/dotnet-pack/PackCommandParser.cs | 70 +++++--- .../dotnet-publish/PublishCommandParser.cs | 74 +++++---- src/dotnet/commands/dotnet-restore/Program.cs | 11 +- .../dotnet-restore/RestoreCommandParser.cs | 50 ++++-- src/dotnet/commands/dotnet-run/RunCommand.cs | 15 +- .../commands/dotnet-run/RunCommandParser.cs | 21 ++- .../commands/dotnet-test/TestCommandParser.cs | 154 ++++++++++-------- .../GivenDotnetBuildBuildsCsproj.cs | 31 +++- test/dotnet-pack.Tests/PackTests.cs | 31 +++- .../GivenDotnetPublishPublishesProjects.cs | 35 +++- .../GivenDotnetRunRunsCsProj.cs | 36 +++- ...enDotnetTestBuildsAndRunsTestfromCsproj.cs | 42 ++++- 14 files changed, 475 insertions(+), 179 deletions(-) diff --git a/src/dotnet/commands/RestoringCommand.cs b/src/dotnet/commands/RestoringCommand.cs index 944457260..89e4afa5b 100644 --- a/src/dotnet/commands/RestoringCommand.cs +++ b/src/dotnet/commands/RestoringCommand.cs @@ -14,6 +14,27 @@ namespace Microsoft.DotNet.Tools private IEnumerable ArgsToForward { get; } + private IEnumerable ArgsToForwardToRestore + { + get + { + 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) { @@ -25,7 +46,7 @@ namespace Microsoft.DotNet.Tools { if (ShouldRunImplicitRestore) { - int exitCode = RestoreCommand.Run(ArgsToForward.ToArray()); + int exitCode = RestoreCommand.Run(ArgsToForwardToRestore.ToArray()); if (exitCode != 0) { return exitCode; @@ -34,7 +55,5 @@ namespace Microsoft.DotNet.Tools return base.Execute(); } - - private bool ShouldRunImplicitRestore => !NoRestore; } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-build/BuildCommandParser.cs b/src/dotnet/commands/dotnet-build/BuildCommandParser.cs index d911db785..60b1a4b1c 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; @@ -18,26 +19,42 @@ namespace Microsoft.DotNet.Cli .With(name: CommonLocalizableStrings.CmdProjectFile, description: "The MSBuild project file to build. If a project file is not specified, MSBuild searches the current working directory for a file that has a file extension that ends in `proj` and uses that file."), - CommonOptions.HelpOption(), - Create.Option( - "-o|--output", - LocalizableStrings.OutputOptionDescription, - Accept.ExactlyOneArgument() - .With(name: LocalizableStrings.OutputOptionName) - .ForwardAsSingle(o => $"/p:OutputPath={o.Arguments.Single()}")), - CommonOptions.FrameworkOption(), - CommonOptions.RuntimeOption(), - CommonOptions.ConfigurationOption(), - CommonOptions.VersionSuffixOption(), - Create.Option( - "--no-incremental", - LocalizableStrings.NoIncrementialOptionDescription), - Create.Option( - "--no-dependencies", - LocalizableStrings.NoDependenciesOptionDescription, - Accept.NoArguments() - .ForwardAs("/p:BuildProjectReferences=false")), - CommonOptions.NoRestoreOption(), - CommonOptions.VerbosityOption()); + FullBuildOptions + ); + + private static Option[] FullBuildOptions + { + get + { + var fullBuildOptions = new List