| File: ComputeEndpointsForReferenceStaticWebAssets.cs | Web Access |
| Project: src\sdk\src\StaticWebAssetsSdk\Tasks\Microsoft.NET.Sdk.StaticWebAssets.Tasks.csproj (Microsoft.NET.Sdk.StaticWebAssets.Tasks) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable using Microsoft.Build.Framework; namespace Microsoft.AspNetCore.StaticWebAssets.Tasks; [MSBuildMultiThreadableTask] public class ComputeEndpointsForReferenceStaticWebAssets : Task, IMultiThreadableTask { /// <inheritdoc/> public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback; [Required] public ITaskItem[] Assets { get; set; } [Required] public ITaskItem[] CandidateEndpoints { get; set; } [Output] public ITaskItem[] Endpoints { get; set; } public override bool Execute() { var assets = StaticWebAsset.ToAssetDictionary(Assets, TaskEnvironment); var result = CandidateEndpoints; var routeSegments = new List<PathTokenizer.Segment>(); var basePathSegments = new List<PathTokenizer.Segment>(); for (var i = 0; i < CandidateEndpoints.Length; i++) { var candidateEndpoint = StaticWebAssetEndpoint.FromTaskItem(CandidateEndpoints[i]); if (assets.TryGetValue(candidateEndpoint.AssetFile, out var asset)) { // We need to adjust the path to include the base path for the asset, since this is going to be used // as a reference. // Note that the caller is responsible for ensuring that only assets meant for the current project and // destined to be used as a reference by other project are passed to this task. var oldRoute = candidateEndpoint.Route; if (StaticWebAssetEndpoint.RouteHasPathPrefix(oldRoute, asset.BasePath, routeSegments, basePathSegments)) { Log.LogMessage(MessageImportance.Low, "Skipping endpoint '{0}' because route '{1}' is already updated.", asset.Identity, oldRoute); } else { candidateEndpoint.Route = StaticWebAsset.CombineNormalizedPaths("", asset.BasePath, candidateEndpoint.Route, '/'); for (var j = 0; j < candidateEndpoint.EndpointProperties.Length; j++) { ref var property = ref candidateEndpoint.EndpointProperties[j]; if (string.Equals(property.Name, "label", StringComparison.OrdinalIgnoreCase)) { property.Value = StaticWebAsset.CombineNormalizedPaths("", asset.BasePath, property.Value, '/'); // We need to do this because we are modifying the properties in place. // We could instead do candidateEndpoint.EndpointProperties = candidateEndpoint.EndpointProperties // but that's more obscure than this. candidateEndpoint.MarkProperiesAsModified(); } } Log.LogMessage(MessageImportance.Low, "Adding endpoint {0} for asset {1} with updated route {2}.", candidateEndpoint.Route, candidateEndpoint.AssetFile, candidateEndpoint.Route); result[i] = candidateEndpoint.ToTaskItem(); } } else { Log.LogMessage(MessageImportance.Low, "Skipping endpoint {0} because the asset {1} was not found.", candidateEndpoint.Route, candidateEndpoint.AssetFile); result[i] = null; } } Endpoints = result; return true; } }