diff --git a/TestAssets/DesktopTestProjects/MultiTFMXunitProject/TestLibrary/Helper.cs b/TestAssets/DesktopTestProjects/MultiTFMXunitProject/TestLibrary/Helper.cs new file mode 100644 index 000000000..67b32cfdb --- /dev/null +++ b/TestAssets/DesktopTestProjects/MultiTFMXunitProject/TestLibrary/Helper.cs @@ -0,0 +1,24 @@ +// 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; + +namespace TestLibrary +{ + public static class Helper + { + /// + /// Gets the message from the helper. This comment is here to help test XML documentation file generation, please do not remove it. + /// + /// A message + public static string GetMessage() + { + return "This string came from the test library!"; + } + + public static void SayHi() + { + Console.WriteLine("Hello there!"); + } + } +} \ No newline at end of file diff --git a/TestAssets/DesktopTestProjects/MultiTFMXunitProject/TestLibrary/TestLibrary.csproj b/TestAssets/DesktopTestProjects/MultiTFMXunitProject/TestLibrary/TestLibrary.csproj new file mode 100644 index 000000000..9f5c4f4ab --- /dev/null +++ b/TestAssets/DesktopTestProjects/MultiTFMXunitProject/TestLibrary/TestLibrary.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/TestAssets/DesktopTestProjects/MultiTFMXunitProject/XUnitProject/UnitTest1.cs b/TestAssets/DesktopTestProjects/MultiTFMXunitProject/XUnitProject/UnitTest1.cs new file mode 100644 index 000000000..f86168c43 --- /dev/null +++ b/TestAssets/DesktopTestProjects/MultiTFMXunitProject/XUnitProject/UnitTest1.cs @@ -0,0 +1,24 @@ +// 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 TestLibrary; +using Xunit; + +namespace TestNamespace +{ + public class VSTestXunitTests + { + [Fact] + public void VSTestXunitPassTest() + { + Assert.Equal("This string came from the test library!", Helper.GetMessage()); + } + + [Fact] + public void VSTestXunitFailTest() + { + Assert.Equal(2, 2); + } + } +} diff --git a/TestAssets/DesktopTestProjects/MultiTFMXunitProject/XUnitProject/XUnitProject.csproj b/TestAssets/DesktopTestProjects/MultiTFMXunitProject/XUnitProject/XUnitProject.csproj new file mode 100644 index 000000000..2ae7ce025 --- /dev/null +++ b/TestAssets/DesktopTestProjects/MultiTFMXunitProject/XUnitProject/XUnitProject.csproj @@ -0,0 +1,17 @@ + + + + + net461;netcoreapp2.0 + + + + + + + + + + + + diff --git a/TestAssets/DesktopTestProjects/NETFrameworkReferenceNETStandard20/MultiTFMTestApp/MultiTFMTestApp.csproj b/TestAssets/DesktopTestProjects/NETFrameworkReferenceNETStandard20/MultiTFMTestApp/MultiTFMTestApp.csproj new file mode 100644 index 000000000..cc54ec8ae --- /dev/null +++ b/TestAssets/DesktopTestProjects/NETFrameworkReferenceNETStandard20/MultiTFMTestApp/MultiTFMTestApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.0;net461 + + + + + + + diff --git a/TestAssets/DesktopTestProjects/NETFrameworkReferenceNETStandard20/MultiTFMTestApp/Program.cs b/TestAssets/DesktopTestProjects/NETFrameworkReferenceNETStandard20/MultiTFMTestApp/Program.cs new file mode 100644 index 000000000..a168da37c --- /dev/null +++ b/TestAssets/DesktopTestProjects/NETFrameworkReferenceNETStandard20/MultiTFMTestApp/Program.cs @@ -0,0 +1,15 @@ +// 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; + +namespace TestApp +{ + class Program + { + public static void Main(string[] args) + { + Console.WriteLine(TestLibrary.Helper.GetMessage()); + } + } +} diff --git a/src/dotnet/commands/RestoringCommand.cs b/src/dotnet/commands/RestoringCommand.cs index 67c114577..0239fd69b 100644 --- a/src/dotnet/commands/RestoringCommand.cs +++ b/src/dotnet/commands/RestoringCommand.cs @@ -12,31 +12,36 @@ namespace Microsoft.DotNet.Tools { private bool NoRestore { get; } - private IEnumerable ArgsToForward { get; } + private IEnumerable ParsedArguments { get; } + + private IEnumerable TrailingArguments { get; } private IEnumerable ArgsToForwardToRestore() { - var restoreArguments = ArgsToForward.Where(a => - !a.StartsWith("/t:") && - !a.StartsWith("/target:") && - !a.StartsWith("/ConsoleLoggerParameters:") && - !a.StartsWith("/clp:")); + var restoreArguments = ParsedArguments.Where(a => + !a.StartsWith("/p:TargetFramework")); - if (!restoreArguments.Any(a => a.StartsWith("/v:") || a.StartsWith("/verbosity:"))) + if (!restoreArguments.Any(a => a.StartsWith("/verbosity:"))) { - restoreArguments = restoreArguments.Concat(new string[] { "/v:q" }); + restoreArguments = restoreArguments.Concat(new string[] { "/verbosity:q" }); } - return restoreArguments; + return restoreArguments.Concat(TrailingArguments); } private bool ShouldRunImplicitRestore => !NoRestore; - public RestoringCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) + public RestoringCommand( + IEnumerable msbuildArgs, + IEnumerable parsedArguments, + IEnumerable trailingArguments, + bool noRestore, + string msbuildPath = null) : base(msbuildArgs, msbuildPath) { NoRestore = noRestore; - ArgsToForward = msbuildArgs; + ParsedArguments = parsedArguments; + TrailingArguments = trailingArguments; } public override int Execute() diff --git a/src/dotnet/commands/dotnet-build/BuildCommand.cs b/src/dotnet/commands/dotnet-build/BuildCommand.cs index 95539c662..c7127353b 100644 --- a/src/dotnet/commands/dotnet-build/BuildCommand.cs +++ b/src/dotnet/commands/dotnet-build/BuildCommand.cs @@ -15,8 +15,13 @@ namespace Microsoft.DotNet.Tools.Build { public class BuildCommand : RestoringCommand { - public BuildCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) - : base(msbuildArgs, noRestore, msbuildPath) + public BuildCommand( + IEnumerable msbuildArgs, + IEnumerable userDefinedArguments, + IEnumerable trailingArguments, + bool noRestore, + string msbuildPath = null) + : base(msbuildArgs, userDefinedArguments, trailingArguments, noRestore, msbuildPath) { } @@ -49,7 +54,12 @@ namespace Microsoft.DotNet.Tools.Build bool noRestore = appliedBuildOptions.HasOption("--no-restore"); - return new BuildCommand(msbuildArgs, noRestore, msbuildPath); + return new BuildCommand( + msbuildArgs, + appliedBuildOptions.OptionValuesToBeForwarded(), + appliedBuildOptions.Arguments, + noRestore, + msbuildPath); } public static int Run(string[] args) diff --git a/src/dotnet/commands/dotnet-pack/PackCommand.cs b/src/dotnet/commands/dotnet-pack/PackCommand.cs index 0c7146356..a781fe254 100644 --- a/src/dotnet/commands/dotnet-pack/PackCommand.cs +++ b/src/dotnet/commands/dotnet-pack/PackCommand.cs @@ -14,8 +14,13 @@ namespace Microsoft.DotNet.Tools.Pack { public class PackCommand : RestoringCommand { - public PackCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) - : base(msbuildArgs, noRestore, msbuildPath) + public PackCommand( + IEnumerable msbuildArgs, + IEnumerable userDefinedArguments, + IEnumerable trailingArguments, + bool noRestore, + string msbuildPath = null) + : base(msbuildArgs, userDefinedArguments, trailingArguments, noRestore, msbuildPath) { } @@ -40,7 +45,12 @@ namespace Microsoft.DotNet.Tools.Pack bool noRestore = parsedPack.HasOption("--no-restore"); - return new PackCommand(msbuildArgs, noRestore, msbuildPath); + return new PackCommand( + msbuildArgs, + parsedPack.OptionValuesToBeForwarded(), + parsedPack.Arguments, + noRestore, + msbuildPath); } public static int Run(string[] args) diff --git a/src/dotnet/commands/dotnet-publish/Program.cs b/src/dotnet/commands/dotnet-publish/Program.cs index d4337e107..f44ecb2ca 100644 --- a/src/dotnet/commands/dotnet-publish/Program.cs +++ b/src/dotnet/commands/dotnet-publish/Program.cs @@ -13,8 +13,13 @@ namespace Microsoft.DotNet.Tools.Publish { public class PublishCommand : RestoringCommand { - private PublishCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) - : base(msbuildArgs, noRestore, msbuildPath) + private PublishCommand( + IEnumerable msbuildArgs, + IEnumerable userDefinedArguments, + IEnumerable trailingArguments, + bool noRestore, + string msbuildPath = null) + : base(msbuildArgs, userDefinedArguments, trailingArguments, noRestore, msbuildPath) { } @@ -40,7 +45,12 @@ namespace Microsoft.DotNet.Tools.Publish bool noRestore = appliedPublishOption.HasOption("--no-restore"); - return new PublishCommand(msbuildArgs, noRestore, msbuildPath); + return new PublishCommand( + msbuildArgs, + appliedPublishOption.OptionValuesToBeForwarded(), + appliedPublishOption.Arguments, + noRestore, + msbuildPath); } public static int Run(string[] args) diff --git a/src/dotnet/commands/dotnet-run/RunCommand.cs b/src/dotnet/commands/dotnet-run/RunCommand.cs index 38ef571c5..d760a8690 100644 --- a/src/dotnet/commands/dotnet-run/RunCommand.cs +++ b/src/dotnet/commands/dotnet-run/RunCommand.cs @@ -145,7 +145,8 @@ namespace Microsoft.DotNet.Tools.Run buildArgs.AddRange(RestoreArgs); - var buildResult = new RestoringCommand(buildArgs, NoRestore).Execute(); + var buildResult = + new RestoringCommand(buildArgs, RestoreArgs, new [] { Project }, NoRestore).Execute(); if (buildResult != 0) { Reporter.Error.WriteLine(); diff --git a/src/dotnet/commands/dotnet-test/Program.cs b/src/dotnet/commands/dotnet-test/Program.cs index 805639d9e..d714d2f9e 100644 --- a/src/dotnet/commands/dotnet-test/Program.cs +++ b/src/dotnet/commands/dotnet-test/Program.cs @@ -16,8 +16,13 @@ namespace Microsoft.DotNet.Tools.Test { public class TestCommand : RestoringCommand { - public TestCommand(IEnumerable msbuildArgs, bool noRestore, string msbuildPath = null) - : base(msbuildArgs, noRestore, msbuildPath) + public TestCommand( + IEnumerable msbuildArgs, + IEnumerable userDefinedArguments, + IEnumerable trailingArguments, + bool noRestore, + string msbuildPath = null) + : base(msbuildArgs, userDefinedArguments, trailingArguments, noRestore, msbuildPath) { } @@ -67,7 +72,12 @@ namespace Microsoft.DotNet.Tools.Test bool noRestore = parsedTest.HasOption("--no-restore"); - return new TestCommand(msbuildArgs, noRestore, msbuildPath); + return new TestCommand( + msbuildArgs, + parsedTest.OptionValuesToBeForwarded(), + parsedTest.Arguments, + noRestore, + msbuildPath); } public static int Run(string[] args) diff --git a/test/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs b/test/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs index 29049f238..30b16d53d 100644 --- a/test/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs +++ b/test/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs @@ -4,6 +4,7 @@ using System; using System.IO; using FluentAssertions; +using Microsoft.DotNet.TestFramework; using Microsoft.DotNet.Tools.Test.Utilities; using Xunit; using System.Linq; @@ -52,6 +53,23 @@ namespace Microsoft.DotNet.Cli.Build.Tests .Should().Pass(); } + [Fact] + public void ItCanBuildAMultiTFMProjectWithImplicitRestore() + { + var testInstance = TestAssets.Get( + TestAssetKinds.DesktopTestProjects, + "NETFrameworkReferenceNETStandard20") + .CreateInstance() + .WithSourceFiles(); + + string projectDirectory = Path.Combine(testInstance.Root.FullName, "MultiTFMTestApp"); + + new BuildCommand() + .WithWorkingDirectory(projectDirectory) + .Execute("--framework netcoreapp2.0") + .Should().Pass(); + } + [Fact] public void ItDoesNotImplicitlyRestoreAProjectWhenBuildingWithTheNoRestoreOption() { diff --git a/test/dotnet-publish.Tests/GivenDotnetPublishPublishesProjects.cs b/test/dotnet-publish.Tests/GivenDotnetPublishPublishesProjects.cs index 80985a5a4..ddad9808c 100644 --- a/test/dotnet-publish.Tests/GivenDotnetPublishPublishesProjects.cs +++ b/test/dotnet-publish.Tests/GivenDotnetPublishPublishesProjects.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using FluentAssertions; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.PlatformAbstractions; +using Microsoft.DotNet.TestFramework; using Microsoft.DotNet.Tools.Test.Utilities; using Xunit; @@ -60,6 +61,23 @@ namespace Microsoft.DotNet.Cli.Publish.Tests .Should().Pass(); } + [Fact] + public void ItCanPublishAMultiTFMProjectWithImplicitRestore() + { + var testInstance = TestAssets.Get( + TestAssetKinds.DesktopTestProjects, + "NETFrameworkReferenceNETStandard20") + .CreateInstance() + .WithSourceFiles(); + + string projectDirectory = Path.Combine(testInstance.Root.FullName, "MultiTFMTestApp"); + + new PublishCommand() + .WithWorkingDirectory(projectDirectory) + .Execute("--framework netcoreapp2.0") + .Should().Pass(); + } + [Fact] public void ItDoesNotImplicitlyRestoreAProjectWhenPublishingWithTheNoRestoreOption() { diff --git a/test/dotnet-run.Tests/GivenDotnetRunRunsCsProj.cs b/test/dotnet-run.Tests/GivenDotnetRunRunsCsProj.cs index 21d1dee1a..88cc49dcf 100644 --- a/test/dotnet-run.Tests/GivenDotnetRunRunsCsProj.cs +++ b/test/dotnet-run.Tests/GivenDotnetRunRunsCsProj.cs @@ -3,6 +3,7 @@ using System.IO; using FluentAssertions; +using Microsoft.DotNet.TestFramework; using Microsoft.DotNet.Tools.Test.Utilities; using Xunit; @@ -54,6 +55,24 @@ namespace Microsoft.DotNet.Cli.Run.Tests .And.HaveStdOutContaining("Hello World!"); } + [Fact] + public void ItCanRunAMultiTFMProjectWithImplicitRestore() + { + var testInstance = TestAssets.Get( + TestAssetKinds.DesktopTestProjects, + "NETFrameworkReferenceNETStandard20") + .CreateInstance() + .WithSourceFiles(); + + string projectDirectory = Path.Combine(testInstance.Root.FullName, "MultiTFMTestApp"); + + new RunCommand() + .WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput("--framework netcoreapp2.0") + .Should().Pass() + .And.HaveStdOutContaining("This string came from the test library!"); + } + [Fact] public void ItDoesNotImplicitlyRestoreAProjectWhenRunningWithTheNoRestoreOption() { diff --git a/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs b/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs index a111db3c3..30f1ee12f 100644 --- a/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs +++ b/test/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs @@ -7,6 +7,7 @@ using Microsoft.DotNet.TestFramework; using Microsoft.DotNet.Cli.Utils; using System.IO; using System; +using Xunit; namespace Microsoft.DotNet.Cli.Test.Tests { @@ -75,5 +76,22 @@ namespace Microsoft.DotNet.Cli.Test.Tests result.StdOut.Should().Contain("Failed TestNamespace.VSTestXunitTests.VSTestXunitFailTestNetCoreApp"); result.ExitCode.Should().Be(1); } + + [Fact] + public void ItCanTestAMultiTFMProjectWithImplicitRestore() + { + var testInstance = TestAssets.Get( + TestAssetKinds.DesktopTestProjects, + "MultiTFMXunitProject") + .CreateInstance() + .WithSourceFiles(); + + string projectDirectory = Path.Combine(testInstance.Root.FullName, "XUnitProject"); + + new DotnetTestCommand() + .WithWorkingDirectory(projectDirectory) + .ExecuteWithCapturedOutput($"{TestBase.ConsoleLoggerOutputNormal} --framework netcoreapp2.0") + .Should().Pass(); + } } }