stryker-mutator / stryker-net

Mutation testing for .NET core and .NET framework!
https://stryker-mutator.io
Apache License 2.0
1.76k stars 175 forks source link

Failure to build project with modified IntermediateOutputPath #2083

Closed eatdrinksleepcode closed 1 year ago

eatdrinksleepcode commented 2 years ago

Describe the bug Running Stryker on a project with a modified IntermediateOutputPath MSBuild property results in two copies of the *AssemblyInfo.cs file being generated and included in the build, which results in build errors ("Duplicate 'System.Reflection.AssemblyVersionAttribute' attribute").

Logs This repro was captured using the repository at https://github.com/eatdrinksleepcode/StrykerBugRepro and executing the commands in the repro.sh file.

Repro ❯ cat Directory.Build.props <Project> <PropertyGroup> <Company>Repro Company</Company> <Product>Repro Product</Product> <Authors>Repro Author</Authors> <Copyright>Copyright (c) Repro Company</Copyright> <OriginalSolutionDir>$(SolutionDir)</OriginalSolutionDir> <SolutionDir Condition="'$(SolutionDir)'==''">$(MSBuildThisFileDirectory)</SolutionDir> <BaseIntermediateOutputPath>$(SolutionDir)obj\\$(Configuration)\\$(MSBuildProjectName)\\</BaseIntermediateOutputPath> <IntermediateOutputPath>$(BaseIntermediateOutputPath)</IntermediateOutputPath> <OutputPath>$(SolutionDir)bin\\$(Configuration)\\</OutputPath> <PublishDir>$(SolutionDir)publish\\$(Configuration)\\</PublishDir> <AppendTargetFrameworkToOutputPath>False</AppendTargetFrameworkToOutputPath> <RuntimeFrameworkVersion>3.1.12</RuntimeFrameworkVersion> </PropertyGroup> <Target Name="EchoPath" BeforeTargets="BeforeCompile"> <Message Text="$(ProjectName).OriginalSolutionDir = $(OriginalSolutionDir)" Importance="high"/> <Message Text="$(ProjectName).SolutionDir = $(SolutionDir)" Importance="high"/> <Message Text="$(ProjectName).BaseIntermediateOutputPath = $(BaseIntermediateOutputPath)" Importance="high"/> <Message Text="$(ProjectName).IntermediateOutputPath = $(IntermediateOutputPath)" Importance="high"/> </Target> </Project> ❯ dotnet clean -v minimal && rm -r **/bin **/obj Microsoft (R) Build Engine version 16.7.2+b60ddb6f4 for .NET Copyright (C) Microsoft Corporation. All rights reserved. ❯ find . -name "*AssemblyInfo.cs" # There are no AssemblyInfo.cs files before building ❯ dotnet build Microsoft (R) Build Engine version 16.7.2+b60ddb6f4 for .NET Copyright (C) Microsoft Corporation. All rights reserved. Determining projects to restore... Restored /Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj (in 195 ms). Restored /Users/dnelson/Projects/StrykerBugRepro/TestProj/TestProj.csproj (in 1.85 sec). MainProj.OriginalSolutionDir = /Users/dnelson/Projects/StrykerBugRepro/ MainProj.SolutionDir = /Users/dnelson/Projects/StrykerBugRepro/ MainProj.BaseIntermediateOutputPath = /Users/dnelson/Projects/StrykerBugRepro/obj/Debug/MainProj/ MainProj.IntermediateOutputPath = /Users/dnelson/Projects/StrykerBugRepro/obj/Debug/MainProj/ MainProj -> /Users/dnelson/Projects/StrykerBugRepro/bin/Debug/MainProj.dll TestProj.OriginalSolutionDir = /Users/dnelson/Projects/StrykerBugRepro/ TestProj.SolutionDir = /Users/dnelson/Projects/StrykerBugRepro/ TestProj.BaseIntermediateOutputPath = /Users/dnelson/Projects/StrykerBugRepro/obj/Debug/TestProj/ TestProj.IntermediateOutputPath = /Users/dnelson/Projects/StrykerBugRepro/obj/Debug/TestProj/ TestProj -> /Users/dnelson/Projects/StrykerBugRepro/bin/Debug/TestProj.dll Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:05.36 ❯ find . -name "*AssemblyInfo.cs" # Each project has a generated AssemblyInfo.cs file at the configured IntermediateOutputPath ./obj/Debug/MainProj/MainProj.AssemblyInfo.cs ./obj/Debug/TestProj/TestProj.AssemblyInfo.cs ❯ dotnet clean -v minimal && rm -r **/bin **/obj Microsoft (R) Build Engine version 16.7.2+b60ddb6f4 for .NET Copyright (C) Microsoft Corporation. All rights reserved. ❯ dotnet stryker --log-to-file -tp TestProj -p MainProj _____ _ _ _ _ ______ _______   / ____| | | | | \ | | ____|__ __|  | (___ | |_ _ __ _ _| | _____ _ __ | \| | |__ | |   \___ \| __| '__| | | | |/ / _ \ '__| | . ` | __| | |   ____) | |_| | | |_| | < __/ | | |\ | |____ | |   |_____/ \__|_| \__, |_|\_\___|_| (_)|_| \_|______| |_|   __/ |   |___/   Version: 2.0.0 [00:51:10 INF] Identifying project to mutate. [00:51:12 INF] The project /Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj will be mutated. [00:51:14 WRN] Buildalyzer could not find sourcefiles. This should not happen. Will fallback to filesystem scan. Please report an issue at github. [00:51:14 INF] Analysis complete. [00:51:14 INF] Building test project /Users/dnelson/Projects/StrykerBugRepro/TestProj/TestProj.csproj (1/1) [00:51:16 INF] Time Elapsed 00:00:06.5408775 Stryker.NET failed to mutate your project. For more information see the logs below: Microsoft (R) Build Engine version 16.7.2+b60ddb6f4 for .NET Copyright (C) Microsoft Corporation. All rights reserved. Determining projects to restore... All projects are up-to-date for restore. MainProj.OriginalSolutionDir = MainProj.SolutionDir = /Users/dnelson/Projects/StrykerBugRepro/ MainProj.BaseIntermediateOutputPath = /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/ MainProj.IntermediateOutputPath = /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/ /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(13,12): error CS0579: Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(14,12): error CS0579: Duplicate 'System.Reflection.AssemblyConfigurationAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(15,12): error CS0579: Duplicate 'System.Reflection.AssemblyCopyrightAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(16,12): error CS0579: Duplicate 'System.Reflection.AssemblyFileVersionAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(17,12): error CS0579: Duplicate 'System.Reflection.AssemblyInformationalVersionAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(18,12): error CS0579: Duplicate 'System.Reflection.AssemblyProductAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(19,12): error CS0579: Duplicate 'System.Reflection.AssemblyTitleAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(20,12): error CS0579: Duplicate 'System.Reflection.AssemblyVersionAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] Build FAILED. /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(13,12): error CS0579: Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(14,12): error CS0579: Duplicate 'System.Reflection.AssemblyConfigurationAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(15,12): error CS0579: Duplicate 'System.Reflection.AssemblyCopyrightAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(16,12): error CS0579: Duplicate 'System.Reflection.AssemblyFileVersionAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(17,12): error CS0579: Duplicate 'System.Reflection.AssemblyInformationalVersionAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(18,12): error CS0579: Duplicate 'System.Reflection.AssemblyProductAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(19,12): error CS0579: Duplicate 'System.Reflection.AssemblyTitleAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] /Users/dnelson/Projects/StrykerBugRepro/obj/MainProj/MainProj.AssemblyInfo.cs(20,12): error CS0579: Duplicate 'System.Reflection.AssemblyVersionAttribute' attribute [/Users/dnelson/Projects/StrykerBugRepro/MainProj/MainProj.csproj] 0 Warning(s) 8 Error(s) Time Elapsed 00:00:01.62 Initial build of targeted project failed. Please make sure the targeted project is buildable. You can reproduce this error yourself using: "dotnet build "TestProj.csproj"" ❯ find . -name "*AssemblyInfo.cs" # In addition to the AssemblyInfo.cs files at the configured IntermediateOutputPath, there is a duplicate AssemblyInfo.cs file at the same relative path under the project directory ./obj/MainProj/MainProj.AssemblyInfo.cs ./MainProj/obj/MainProj/MainProj.AssemblyInfo.cs ./TestProj/obj/TestProj/TestProj.AssemblyInfo.cs

log-20220613.txt

Expected behavior Stryker should build the project successfully, just as dotnet build does, without generating duplicate AssemblyInfo.cs files.

Desktop (please complete the following information):

Additional context Note that the Directory.Build.props file has a custom target which prints key paths. One difference that I noticed between the successful dotnet build and the unsuccessful dotnet stryker is that Stryker is not setting the SolutionDir property, while the normal build is. I thought that might be important since the modified IntermediateOutputPath is dependent on SolutionDir. However, the Directory.Build.props file correctly sets the SolutionDir if it is not provided; and that also would not explain why there end up being duplicate AssemblyInfo.cs files, instead of just one in the wrong place.

There is an open Buildalyzer issue which seems somewhat similar, but there is no additional information.

rouke-broersma commented 2 years ago

Apologies for not replying to you yet. These issues are pretty common in a number of scenarios. See for example #2077. So far I have not found a way to deal with this. We are not receiving this information from buildalyzer, which suggests that msbuild is doing some internal magic or using some msbuild targets that buildalyzer is not. This is extermely difficult to investigate and track. Thank you for the reproduction project, when we get around to investigating this that will be a great help.

rouke-broersma commented 1 year ago

Close as duplicate of #2077