Skip to content

Commit

Permalink
Make itemspec matching case insensitive regardless of OS Fixes #5749 (#…
Browse files Browse the repository at this point in the history
…5888)

First commit: update a test such that it passes only if matching is case insensitive.
Second commit: modify FileUtilities.ComparePathsNoThrow such that it can be made to be always case sensitive or case insensitive. Note that this was changed about seven months ago in #4997 where it had previously been a todo to make case sensitivity depend on OS but that implemented it.
Third commit: fix a test that theoretically ensured case insensitivity but in practice did not, changed to care about case in the same PR.

The second commit fixes #5749.
  • Loading branch information
Forgind authored Dec 4, 2020
1 parent 618b66a commit 45a039f
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 24 deletions.
27 changes: 7 additions & 20 deletions src/Build.OM.UnitTests/Definition/ProjectItem_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2831,7 +2831,7 @@ public void EscapeHatchTurnsOffQualifiedMetadataExpansionInUpdateOperation(bool
public void UpdateFromReferencedItemShouldBeCaseInsensitive()
{
string content = @"
<from Include='a'>
<from Include='A'>
<metadata>m1_contents</metadata>
</from>
Expand Down Expand Up @@ -3188,28 +3188,15 @@ public void UpdateAndRemoveShouldUseCaseInsensitiveMatching()

IList<ProjectItem> items = ObjectModelHelpers.GetItemsFromFragment(content);

if (FileUtilities.GetIsFileSystemCaseSensitive())
{
var expectedUpdated = new Dictionary<string, string>
{
{"m1", "m1_contents"},
{"m2", "m2_contents"},
};
items.ShouldHaveSingleItem();

ObjectModelHelpers.AssertItemHasMetadata(expectedUpdated, items[0]);
}
else
var expectedUpdated = new Dictionary<string, string>
{
items.ShouldHaveSingleItem();

var expectedUpdated = new Dictionary<string, string>
{
{"m1", "m1_updated"},
{"m2", "m2_updated"},
};
{"m1", "m1_updated"},
{"m2", "m2_updated"},
};

ObjectModelHelpers.AssertItemHasMetadata(expectedUpdated, items[0]);
}
ObjectModelHelpers.AssertItemHasMetadata(expectedUpdated, items[0]);
}

public static IEnumerable<Object[]> UpdateAndRemoveShouldWorkWithEscapedCharactersTestData
Expand Down
3 changes: 2 additions & 1 deletion src/Build/Utilities/FileSpecMatchTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Build.Shared;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -42,7 +43,7 @@ public bool IsMatch(string fileToMatch)
return _regex.IsMatch(normalizedFileToMatch);
}

return FileUtilities.ComparePathsNoThrow(_unescapedFileSpec, fileToMatch, _currentDirectory);
return FileUtilities.ComparePathsNoThrow(_unescapedFileSpec, fileToMatch, _currentDirectory, alwaysIgnoreCase: true);
}

// this method parses the glob and extracts the fixed directory part in order to normalize it and make it absolute
Expand Down
8 changes: 5 additions & 3 deletions src/Shared/FileUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -735,19 +735,21 @@ internal static string GetFullPathNoThrow(string path)
/// <param name="first"></param>
/// <param name="second"></param>
/// <param name="currentDirectory"></param>
/// <param name="alwaysIgnoreCase"></param>
/// <returns></returns>
internal static bool ComparePathsNoThrow(string first, string second, string currentDirectory)
internal static bool ComparePathsNoThrow(string first, string second, string currentDirectory, bool alwaysIgnoreCase = false)
{
StringComparison pathComparison = alwaysIgnoreCase ? StringComparison.OrdinalIgnoreCase : PathComparison;
// perf: try comparing the bare strings first
if (string.Equals(first, second, PathComparison))
if (string.Equals(first, second, pathComparison))
{
return true;
}

var firstFullPath = NormalizePathForComparisonNoThrow(first, currentDirectory);
var secondFullPath = NormalizePathForComparisonNoThrow(second, currentDirectory);

return string.Equals(firstFullPath, secondFullPath, PathComparison);
return string.Equals(firstFullPath, secondFullPath, pathComparison);
}

/// <summary>
Expand Down

0 comments on commit 45a039f

Please sign in to comment.