Skip to content

Commit

Permalink
Prevent duplicate targets Fixes #5071 (#5109)
Browse files Browse the repository at this point in the history
* Prevent duplicate targets

Duplicate targets break the build; this prevents MSBuild's default targets from being added if they already exist.

Fixes #5071
  • Loading branch information
Forgind authored Feb 12, 2020
1 parent 67991ed commit 77da97f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
26 changes: 26 additions & 0 deletions src/Build.UnitTests/Construction/SolutionProjectGenerator_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,32 @@ public void Dispose()
ProjectCollection.GlobalProjectCollection.UnloadAllProjects();
}

/// <summary>
/// Test that if a before.{sln}>.targets or after.{sln}.targets file has one of the default targets (Build, Clean, etc.) that it includes only the user-defined target.
/// </summary>
[Theory]
[InlineData("before.MySln.sln.targets")]
[InlineData("after.MySln.sln.targets")]
[InlineData("name.that.does.Not.Affect.The.Build.targets")]
public void SolutionProjectIgnoresDuplicateDefaultTargets(string name)
{
using (TestEnvironment testEnvironment = TestEnvironment.Create())
{
TransientTestFolder folder = testEnvironment.CreateFolder(createFolder: true);
TransientTestFile sln = testEnvironment.CreateFile(folder, "MySln.sln", @"Microsoft Visual Studio Solution File, Format Version 16.00");
TransientTestFile targetsFile = testEnvironment.CreateFile(folder, name,
@"<Project>
<Target Name=""Build"" AfterTargets=""NonsenseTarget"">
</Target>
</Project>");
ProjectInstance[] instances = SolutionProjectGenerator.Generate(SolutionFile.Parse(sln.Path), null, null, _buildEventContext, CreateMockLoggingService());
instances.ShouldHaveSingleItem();
instances[0].Targets["Build"].AfterTargets.ShouldBe(string.Empty);
MockLogger logger = new MockLogger(output);
instances[0].Build(targets: null, new List<ILogger> { logger }).ShouldBeTrue();
}
}

/// <summary>
/// Test that a solution filter file excludes projects not covered by its list of projects or their dependencies.
/// </summary>
Expand Down
5 changes: 4 additions & 1 deletion src/Build/Construction/Solution/SolutionProjectGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1969,7 +1969,10 @@ private static void AddTraversalReferencesTarget(ProjectInstance traversalProjec
outputItemAsItem = "@(" + outputItem + ")";
}

ProjectTargetInstance target = traversalProject.AddTarget(targetName ?? "Build", String.Empty, String.Empty, outputItemAsItem, null, String.Empty, String.Empty, String.Empty, String.Empty, false /* legacy target returns behaviour */);
string correctedTargetName = targetName ?? "Build";

traversalProject.RemoveTarget(correctedTargetName);
ProjectTargetInstance target = traversalProject.AddTarget(correctedTargetName, string.Empty, string.Empty, outputItemAsItem, null, string.Empty, string.Empty, string.Empty, string.Empty, false /* legacy target returns behaviour */);
AddReferencesBuildTask(target, targetName, outputItem);
}

Expand Down

0 comments on commit 77da97f

Please sign in to comment.