Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,36 @@ public override bool Execute()
var candidates = StaticWebAsset.FromTaskItemGroup(CandidateAssets);
var assetsToUpdate = new List<ITaskItem>();

var candidatesByIdentity = candidates.ToDictionary(asset => asset.Identity, OSPath.PathComparer);
var candidatesByIdentity = new Dictionary<string, StaticWebAsset>(OSPath.PathComparer);
foreach (var asset in candidates)
{
if (candidatesByIdentity.TryGetValue(asset.Identity, out var existing))
{
if (existing.SourceId != asset.SourceId ||
existing.RelativePath != asset.RelativePath)
{
Log.LogWarning(
"Duplicate candidate asset '{0}' with differing metadata (SourceId='{1}' vs '{2}', RelativePath='{3}' vs '{4}'). Keeping first occurrence.",
asset.Identity,
existing.SourceId,
asset.SourceId,
existing.RelativePath,
asset.RelativePath);
}
else
{
Log.LogMessage(
MessageImportance.Low,
"Skipping duplicate candidate asset '{0}' (SourceId='{1}'). Assets are identical.",
asset.Identity,
asset.SourceId);
}
}
else
{
candidatesByIdentity[asset.Identity] = asset;
}
}

foreach (var candidate in candidates)
{
Expand Down
33 changes: 31 additions & 2 deletions src/StaticWebAssetsSdk/Tasks/Data/StaticWebAsset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Security.Cryptography;
using Microsoft.AspNetCore.StaticWebAssets.Tasks.Utils;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Microsoft.AspNetCore.StaticWebAssets.Tasks;

Expand Down Expand Up @@ -1228,13 +1229,41 @@ internal static FileInfo ResolveFile(string identity, string originalItemSpec)
throw new InvalidOperationException($"No file exists for the asset at either location '{identity}' or '{originalItemSpec}'.");
}

internal static Dictionary<string, StaticWebAsset> ToAssetDictionary(ITaskItem[] candidateAssets, bool validate = false)
internal static Dictionary<string, StaticWebAsset> ToAssetDictionary(
ITaskItem[] candidateAssets,
bool validate = false,
TaskLoggingHelper log = null)
{
var dictionary = new Dictionary<string, StaticWebAsset>(candidateAssets.Length);
for (var i = 0; i < candidateAssets.Length; i++)
{
var candidateAsset = FromTaskItem(candidateAssets[i], validate);
dictionary.Add(candidateAsset.Identity, candidateAsset);
if (dictionary.TryGetValue(candidateAsset.Identity, out var existing))
{
if (existing.SourceId != candidateAsset.SourceId ||
existing.RelativePath != candidateAsset.RelativePath)
{
log?.LogWarning(
"Duplicate static web asset '{0}' with differing metadata (SourceId='{1}' vs '{2}', RelativePath='{3}' vs '{4}'). Keeping first occurrence.",
candidateAsset.Identity,
existing.SourceId,
candidateAsset.SourceId,
existing.RelativePath,
candidateAsset.RelativePath);
}
else
{
log?.LogMessage(
MessageImportance.Low,
"Skipping duplicate static web asset '{0}' (SourceId='{1}'). Assets are identical.",
candidateAsset.Identity,
candidateAsset.SourceId);
}
}
else
{
dictionary.Add(candidateAsset.Identity, candidateAsset);
}
}

return dictionary;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,37 @@ public override bool Execute()

// Get the list of the asset that need to be part of the manifest (this is similar to GenerateStaticWebAssetsDevelopmentManifest)
var assets = StaticWebAsset.FromTaskItemGroup(Assets);
var manifestAssets = ComputeManifestAssets(assets, ManifestType)
.ToDictionary(a => a.ResolvedAsset.Identity, a => a, OSPath.PathComparer);
var manifestAssetsList = ComputeManifestAssets(assets, ManifestType);
var manifestAssets = new Dictionary<string, TargetPathAssetPair>(OSPath.PathComparer);
foreach (var a in manifestAssetsList)
{
if (manifestAssets.TryGetValue(a.ResolvedAsset.Identity, out var existing))
{
if (existing.TargetPath != a.TargetPath ||
existing.ResolvedAsset.SourceId != a.ResolvedAsset.SourceId)
{
Log.LogWarning(
"Duplicate static web asset '{0}' with differing metadata (TargetPath='{1}' vs '{2}', SourceId='{3}' vs '{4}'). Keeping first occurrence.",
a.ResolvedAsset.Identity,
existing.TargetPath,
a.TargetPath,
existing.ResolvedAsset.SourceId,
a.ResolvedAsset.SourceId);
}
else
{
Log.LogMessage(
MessageImportance.Low,
"Skipping duplicate static web asset '{0}' (SourceId='{1}'). Assets are identical.",
a.ResolvedAsset.Identity,
a.ResolvedAsset.SourceId);
}
}
else
{
manifestAssets[a.ResolvedAsset.Identity] = a;
}
Comment thread
ilonatommy marked this conversation as resolved.
}

// Build exclusion matcher if patterns are provided
StaticWebAssetGlobMatcher exclusionMatcher = null;
Expand Down
31 changes: 30 additions & 1 deletion src/StaticWebAssetsSdk/Tasks/GenerateStaticWebAssetsManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,36 @@ private StaticWebAssetEndpoint[] FilterPublishEndpointsIfNeeded(StaticWebAsset[]
// inside the manifest because its cumbersome to do it in MSBuild directly.
if (StaticWebAssetsManifest.ManifestTypes.IsPublish(ManifestType))
{
var assetsByIdentity = assets.ToDictionary(a => a.Identity, a => a, OSPath.PathComparer);
var assetsByIdentity = new Dictionary<string, StaticWebAsset>(OSPath.PathComparer);
foreach (var a in assets)
{
if (assetsByIdentity.TryGetValue(a.Identity, out var existing))
{
if (existing.SourceId != a.SourceId ||
existing.RelativePath != a.RelativePath)
{
Log.LogWarning(
"Duplicate static web asset '{0}' with differing metadata (SourceId='{1}' vs '{2}', RelativePath='{3}' vs '{4}'). Keeping first occurrence.",
a.Identity,
existing.SourceId,
a.SourceId,
existing.RelativePath,
a.RelativePath);
}
else
{
Log.LogMessage(
MessageImportance.Low,
"Skipping duplicate static web asset '{0}' (SourceId='{1}'). Assets are identical.",
a.Identity,
a.SourceId);
}
}
else
{
assetsByIdentity[a.Identity] = a;
}
Comment thread
ilonatommy marked this conversation as resolved.
}
var filteredEndpoints = new List<StaticWebAssetEndpoint>();

foreach (var endpoint in Endpoints.Select(StaticWebAssetEndpoint.FromTaskItem))
Expand Down
Loading
Loading