diff --git a/src/dotnet/ForwardingApp.cs b/src/dotnet/ForwardingApp.cs index 607c0f43a..2ae292b75 100644 --- a/src/dotnet/ForwardingApp.cs +++ b/src/dotnet/ForwardingApp.cs @@ -67,6 +67,11 @@ namespace Microsoft.DotNet.Cli } public int Execute() + { + return GetProcessStartInfo().Execute(); + } + + public ProcessStartInfo GetProcessStartInfo() { var processInfo = new ProcessStartInfo { @@ -83,15 +88,7 @@ namespace Microsoft.DotNet.Cli } } - var process = new Process - { - StartInfo = processInfo - }; - - process.Start(); - process.WaitForExit(); - - return process.ExitCode; + return processInfo; } public ForwardingApp WithEnvironmentVariable(string name, string value) diff --git a/src/dotnet/ProcessStartInfoExtensions.cs b/src/dotnet/ProcessStartInfoExtensions.cs new file mode 100644 index 000000000..6029f655c --- /dev/null +++ b/src/dotnet/ProcessStartInfoExtensions.cs @@ -0,0 +1,20 @@ +using System.Diagnostics; + +namespace Microsoft.DotNet.Cli +{ + internal static class ProcessStartInfoExtensions + { + public static int Execute(this ProcessStartInfo startInfo) + { + var process = new Process + { + StartInfo = startInfo + }; + + process.Start(); + process.WaitForExit(); + + return process.ExitCode; + } + } +} diff --git a/src/dotnet/commands/dotnet-build/Program.cs b/src/dotnet/commands/dotnet-build/Program.cs index 785d3b944..5618f14c5 100644 --- a/src/dotnet/commands/dotnet-build/Program.cs +++ b/src/dotnet/commands/dotnet-build/Program.cs @@ -5,21 +5,33 @@ using System.Collections.Generic; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.MSBuild; +using System.Diagnostics; +using System; +using Microsoft.DotNet.Cli; namespace Microsoft.DotNet.Tools.Build { public class BuildCommand { - public static int Run(string[] args) + private MSBuildForwardingApp _forwardingApp; + + private BuildCommand() { } + + public BuildCommand(IEnumerable msbuildArgs) { - DebugHelper.HandleDebugSwitch(ref args); + _forwardingApp = new MSBuildForwardingApp(msbuildArgs); + } + + public static BuildCommand FromArgs(params string[] args) + { + var ret = new BuildCommand(); CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false); app.Name = "dotnet build"; app.FullName = LocalizableStrings.AppFullName; app.Description = LocalizableStrings.AppDescription; app.ArgumentSeparatorHelpText = HelpMessageStrings.MSBuildAdditionalArgsHelpText; - app.HandleRemainingArguments = true; + app.HandleRemainingArguments = true; app.HelpOption("-h|--help"); CommandArgument projectArgument = app.Argument($"<{LocalizableStrings.ProjectArgumentValueName}>", LocalizableStrings.ProjectArgumentDescription); @@ -36,8 +48,10 @@ namespace Microsoft.DotNet.Tools.Build CommandOption noDependenciesOption = app.Option("--no-dependencies", LocalizableStrings.NoDependenciesOptionDescription, CommandOptionType.NoValue); CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(app); + bool codeExecuted = false; app.OnExecute(() => { + codeExecuted = true; List msbuildArgs = new List(); if (!string.IsNullOrEmpty(projectArgument.Value)) @@ -93,10 +107,55 @@ namespace Microsoft.DotNet.Tools.Build msbuildArgs.AddRange(app.RemainingArguments); - return new MSBuildForwardingApp(msbuildArgs).Execute(); + ret._forwardingApp = new MSBuildForwardingApp(msbuildArgs); + + return 0; }); - return app.Execute(args); + int exitCode = app.Execute(); + if (!codeExecuted) + { + throw new NonZeroExitCodeException(exitCode); + } + + return ret; + } + + public static int Run(string[] args) + { + DebugHelper.HandleDebugSwitch(ref args); + + BuildCommand cmd; + try + { + cmd = FromArgs(args); + } + catch (NonZeroExitCodeException e) + { + return e.ExitCode; + } + + return cmd.Execute(); + } + + public ProcessStartInfo GetProcessStartInfo() + { + return _forwardingApp.GetProcessStartInfo(); + } + + public int Execute() + { + return GetProcessStartInfo().Execute(); + } + + private class NonZeroExitCodeException : Exception + { + public int ExitCode { get; private set; } + + public NonZeroExitCodeException(int exitCode) + { + ExitCode = exitCode; + } } } } diff --git a/src/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs b/src/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs index 6b2b0f47f..20b17a497 100644 --- a/src/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs +++ b/src/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs @@ -9,6 +9,7 @@ using System.Reflection; using System.Runtime.InteropServices; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.CommandLine; +using System.Diagnostics; namespace Microsoft.DotNet.Tools.MSBuild { @@ -59,18 +60,16 @@ namespace Microsoft.DotNet.Tools.MSBuild environmentVariables: _msbuildRequiredEnvironmentVariables); } + public ProcessStartInfo GetProcessStartInfo() + { + return _forwardingApp + .WithEnvironmentVariable(TelemetrySessionIdEnvironmentVariableName, Telemetry.CurrentSessionId) + .GetProcessStartInfo(); + } + public int Execute() { - try - { - Environment.SetEnvironmentVariable(TelemetrySessionIdEnvironmentVariableName, Telemetry.CurrentSessionId); - - return _forwardingApp.Execute(); - } - finally - { - Environment.SetEnvironmentVariable(TelemetrySessionIdEnvironmentVariableName, null); - } + return GetProcessStartInfo().Execute(); } internal static CommandOption AddVerbosityOption(CommandLineApplication app) diff --git a/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs new file mode 100644 index 000000000..2dcce552f --- /dev/null +++ b/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs @@ -0,0 +1,21 @@ +using Microsoft.DotNet.Tools.Build; +using System; +using System.Collections.Generic; +using System.Text; +using FluentAssertions; +using Xunit; +using System.IO; + +namespace Microsoft.DotNet.Cli.MSBuild.Tests +{ + public class GivenDotnetBuildInvocation + { + [Fact] + public void WhenNoArgsArePassedThenMsbuildInvocationIsCorrect() + { + var msbuildPath = Path.Combine(Directory.GetCurrentDirectory(), "MSBuild.dll"); + BuildCommand.FromArgs() + .GetProcessStartInfo().Arguments.Should().Be($@"exec {msbuildPath} /m /v:m /t:Build /clp:Summary"); + } + } +}