| File: FindInList.cs | Web Access |
| Project: src\msbuild\src\Tasks\Microsoft.Build.Tasks.csproj (Microsoft.Build.Tasks.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.IO; using Microsoft.Build.Framework; #nullable disable namespace Microsoft.Build.Tasks { /// <summary> /// A task that finds an item with the specified itemspec, if present, /// in the provided list. /// </summary> [MSBuildMultiThreadableTask] public class FindInList : TaskExtension { private ITaskItem[] _list; /// <summary> /// The list to search through /// </summary> [Required] public ITaskItem[] List { get { ArgumentNullException.ThrowIfNull(_list, nameof(List)); return _list; } set => _list = value; } /// <summary> /// Whether to match against just the file part of the itemspec, /// or the whole itemspec (the default) /// </summary> public bool MatchFileNameOnly { get; set; } /// <summary> /// The first matching item found in the list, if any /// </summary> [Output] public ITaskItem ItemFound { get; set; } /// <summary> /// The itemspec to try to find /// </summary> [Required] public string ItemSpecToFind { get; set; } /// <summary> /// Whether or not to match case sensitively /// </summary> public bool CaseSensitive { get; set; } /// <summary> /// Whether or not to return the last match, instead of /// the first one /// </summary> public bool FindLastMatch { get; set; } /// <summary> /// Entry point /// </summary> public override bool Execute() { StringComparison comparison = CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; if (!FindLastMatch) { // Walk forwards foreach (ITaskItem item in List) { if (IsMatchingItem(comparison, item)) { return true; } } } else { // Walk backwards for (int i = List.Length - 1; i >= 0; i--) { if (IsMatchingItem(comparison, List[i])) { return true; } } } // Not found return true; } /// <summary> /// Examines the item to see if it matches what we are looking for. /// If it does, returns true. /// </summary> private bool IsMatchingItem(StringComparison comparison, ITaskItem item) { try { var path = FileUtilities.FixFilePath(item.ItemSpec); string filename = (MatchFileNameOnly ? Path.GetFileName(path) : path); if (String.Equals(filename, ItemSpecToFind, comparison)) { ItemFound = item; Log.LogMessageFromResources(MessageImportance.Low, "FindInList.Found", path); return true; } } catch (ArgumentException ex) { // Just log this: presumably this item spec is not intended to be // a file path Log.LogMessageFromResources(MessageImportance.Low, "FindInList.InvalidPath", item.ItemSpec, ex.Message); } return false; } } }