Skip to content

Commit

Permalink
Fix duplicate resolved files to publish (#3320)
Browse files Browse the repository at this point in the history
  • Loading branch information
nguerrera authored Jun 12, 2019
1 parent 8e7f7cf commit 9d81590
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
19 changes: 19 additions & 0 deletions src/Tasks/Common/ConflictResolution/ConflictResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,25 @@ private TConflictItem ResolveConflict(TConflictItem item1, TConflictItem item2,
return item2;
}

if (item1.ItemType == ConflictItemType.CopyLocal && item2.ItemType == ConflictItemType.CopyLocal)
{
// If two items are copy local, we must pick one even if versions are identical, as only
// one of them can be copied locally. The policy here must be deterministic, but it can
// be chosen arbitrarily. The assumption is that the assemblies are fully semantically
// equivalent.
//
// We choose ordinal string comparison of package id as a final tie-breaker for this case.
// We will get here in the real case of frameworks with overlapping assemblies (including
// version) and self-contained apps. The assembly we choose here is not guaranteed to match
// the assembly that would be chosen by the host for a framework-dependent app. The host
// is free to make its own deterministic but arbitrary choice.
int cmp = string.CompareOrdinal(item1.PackageId, item2.PackageId);
if (cmp != 0)
{
return cmp < 0 ? item1 : item2;
}
}

if (logUnresolvedConflicts)
{
string message = conflictMessage + SENTENCE_SPACING + string.Format(CultureInfo.CurrentCulture, Strings.ConflictCouldNotDetermineWinner);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,8 @@ Copyright (c) .NET Foundation. All rights reserved.
<ItemGroup>
<_ResolvedCopyLocalPublishAssets Include="@(ReferenceCopyLocalPaths)"
Exclude="@(_ResolvedCopyLocalBuildAssets);@(RuntimePackAsset)"
Condition="'$(PublishReferencesDocumentationFiles)' == 'true' or '%(Extension)' != '.xml'">
<DestinationSubPath>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(Filename)%(Extension)</DestinationSubPath>
Condition="'$(PublishReferencesDocumentationFiles)' == 'true' or '%(ReferenceCopyLocalPaths.Extension)' != '.xml'">
<DestinationSubPath>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</DestinationSubPath>
</_ResolvedCopyLocalPublishAssets>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,14 @@ public void It_fails_if_nobuild_was_requested_but_build_was_invoked()
.HaveStdOutContaining("NETSDK1085");
}

[Fact]
public void It_contains_no_duplicates_in_resolved_publish_assets()
[WindowsOnlyFact]
public void It_contains_no_duplicates_in_resolved_publish_assets_on_windows()
=> It_contains_no_duplicates_in_resolved_publish_assets("windows");

[Theory]
[InlineData("console")]
[InlineData("web")]
public void It_contains_no_duplicates_in_resolved_publish_assets(string type)
{
// Use a specific RID to guarantee a consistent set of assets
var testProject = new TestProject()
Expand All @@ -514,9 +520,25 @@ public void It_contains_no_duplicates_in_resolved_publish_assets()
IsExe = true
};

switch (type)
{
case "windows":
testProject.ProjectSdk = "Microsoft.NET.Sdk.WindowsDesktop";
testProject.AdditionalProperties.Add("UseWpf", "true");
testProject.AdditionalProperties.Add("UseWindowsForms", "true");
break;
case "console":
break;
case "web":
testProject.ProjectSdk = "Microsoft.NET.Sdk.Web";
break;
default:
throw new ArgumentOutOfRangeException(nameof(type));
}

testProject.PackageReferences.Add(new TestPackageReference("NewtonSoft.Json", "9.0.1"));

var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name)
var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name, identifier: type)
.WithProjectChanges(project =>
{
project.Root.Add(XElement.Parse(@"
Expand All @@ -526,12 +548,12 @@ public void It_contains_no_duplicates_in_resolved_publish_assets()
</RemoveDuplicates>
<Message Condition=""'@(_ResolvedCopyLocalPublishAssets)' != '@(FilteredAssets)'"" Importance=""High"" Text=""Duplicate items are present in: @(_ResolvedCopyLocalPublishAssets)!"" />
<ItemGroup>
<AssetFilenames Include=""@(_ResolvedCopyLocalPublishAssets->'%(Filename)%(Extension)')"" />
<AssetDestinationSubPaths Include=""@(_ResolvedCopyLocalPublishAssets->'%(DestinationSubPath)')"" />
</ItemGroup>
<RemoveDuplicates Inputs=""@(AssetFilenames)"">
<Output TaskParameter=""Filtered"" ItemName=""FilteredAssetFilenames""/>
<RemoveDuplicates Inputs=""@(AssetDestinationSubPaths)"">
<Output TaskParameter=""Filtered"" ItemName=""FilteredAssetDestinationSubPaths""/>
</RemoveDuplicates>
<Message Condition=""'@(AssetFilenames)' != '@(FilteredAssetFilenames)'"" Importance=""High"" Text=""Duplicate filenames are present in: @(_ResolvedCopyLocalPublishAssets)!"" />
<Message Condition=""'@(AssetDestinationSubPaths)' != '@(FilteredAssetDestinationSubPaths)'"" Importance=""High"" Text=""Duplicate DestinationSubPaths are present in: @(AssetDestinationSubPaths)!"" />
</Target>"));
})
.Restore(Log, testProject.Name);
Expand Down

0 comments on commit 9d81590

Please sign in to comment.