// NOTE: Assumes auto-including items. Only used by the scripts metadata generator, which will be replaced with source generators in the future. public static IEnumerable <string> GetIncludeFiles(string projectPath, string itemType) { var excluded = new List <string>(); var includedFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs"); var root = ProjectRootElement.Open(projectPath); Debug.Assert(root != null); foreach (var item in root.Items) { if (string.IsNullOrEmpty(item.Condition)) { continue; } if (item.ItemType != itemType) { continue; } string normalizedExclude = item.Exclude.NormalizePath(); var glob = MSBuildGlob.Parse(normalizedExclude); excluded.AddRange(includedFiles.Where(includedFile => glob.IsMatch(includedFile))); } includedFiles.RemoveAll(f => excluded.Contains(f)); return(includedFiles); }
public void GlobMatchingShouldWorkWithComplexRelativeLiterals() { var glob = MSBuildGlob.Parse("u/x", "../../u/x/d11/d21/../d22/../../d12/a.cs"); Assert.True(glob.IsMatch(@"../x/d13/../../x/d12/d23/../a.cs")); Assert.False(glob.IsMatch(@"../x/d13/../x/d12/d23/../a.cs")); }
public static ProjectItemElement FindItemOrNullAbs(this ProjectRootElement root, string itemType, string include, bool noCondition = false) { string normalizedInclude = Path.GetFullPath(include).NormalizePath(); foreach (var itemGroup in root.ItemGroups) { if (noCondition && itemGroup.Condition.Length != 0) { continue; } foreach (var item in itemGroup.Items) { if (item.ItemType != itemType) { continue; } var glob = MSBuildGlob.Parse(Path.GetFullPath(item.Include).NormalizePath()); if (glob.IsMatch(normalizedInclude)) { return(item); } } } return(null); }
public void GlobFromRootWithInvalidPathThrows() { foreach (var invalidPathChar in FileUtilities.InvalidPathChars) { Assert.Throws <ArgumentException>(() => MSBuildGlob.Parse(invalidPathChar.ToString(), "*")); } }
public void MSBuildGlobVisitorShouldFindAllLeaves() { var g1 = MSBuildGlob.Parse("1*"); var g2 = MSBuildGlob.Parse("2*"); var g3 = MSBuildGlob.Parse("3*"); var g4 = MSBuildGlob.Parse("4*"); var expectedCollectedGlobs = new[] { g1, g2, g3, g4 }; var composite = new CompositeGlob( g1, g2, new CompositeGlob( new MSBuildGlobWithGaps(g3, MSBuildGlob.Parse("x*")), new CompositeGlob( g4 ) ) ); var leafGlobs = composite.GetParsedGlobs().ToArray(); Assert.Equal(4, leafGlobs.Length); foreach (var expectedGlob in expectedCollectedGlobs) { Assert.Contains(expectedGlob, leafGlobs); } }
public void CreateShouldReturnSingleChildUnchanged() { var glob = MSBuildGlob.Parse(""); IMSBuildGlob composite = CompositeGlob.Create(new[] { glob }); Assert.Same(glob, composite); }
public void GlobFromRelativeGlobRootNormalizesRootAgainstCurrentDirectory() { var globRoot = "a/b/c"; var glob = MSBuildGlob.Parse(globRoot, "*"); var expectedRoot = NormalizeRelativePathForGlobRepresentation(globRoot); Assert.Equal(expectedRoot, glob.TestOnlyGlobRoot); }
public void GlobFromAbsoluteRootDoesNotChangeTheRoot() { var globRoot = NativeMethodsShared.IsWindows ? @"c:\a" : "/a"; var glob = MSBuildGlob.Parse(globRoot, "*"); var expectedRoot = Path.Combine(Directory.GetCurrentDirectory(), globRoot).WithTrailingSlash(); Assert.Equal(expectedRoot, glob.TestOnlyGlobRoot); }
public void GlobMatchingShouldTreatIllegalFileSpecAsLiteral() { var illegalSpec = "|...*"; var glob = MSBuildGlob.Parse(illegalSpec); Assert.False(glob.IsLegal); Assert.True(glob.IsMatch(illegalSpec)); }
public void GlobWithRelativeFixedDirectoryPartShouldMissmatchTheGlobRoot(string globRoot, string filespec, string expectedFixedDirectoryPart) { var glob = MSBuildGlob.Parse(globRoot, filespec); var expectedFixedDirectory = NormalizeRelativePathForGlobRepresentation(expectedFixedDirectoryPart); Assert.Equal(expectedFixedDirectory, glob.FixedDirectoryPart); }
public void GlobParsingShouldDeduplicateRegexes() { var globRoot = NativeMethodsShared.IsWindows ? @"c:\a" : "/a"; var fileSpec = $"b/**/*.cs"; var glob1 = MSBuildGlob.Parse(globRoot, fileSpec); var glob2 = MSBuildGlob.Parse(globRoot, fileSpec); Assert.Same(glob1.TestOnlyRegex, glob2.TestOnlyRegex); }
public void GlobIsNotUnescaped() { var glob = MSBuildGlob.Parse("%42/%42"); Assert.True(glob.IsLegal); Assert.True(glob.FixedDirectoryPart.EndsWith("%42" + Path.DirectorySeparatorChar)); Assert.Equal(string.Empty, glob.WildcardDirectoryPart); Assert.Equal("%42", glob.FilenamePart); }
public void CreateShouldReturnNewCompositeWhenMultipleProvided() { var glob1 = MSBuildGlob.Parse(""); var glob2 = MSBuildGlob.Parse(""); IMSBuildGlob result = CompositeGlob.Create(new[] { glob1, glob2 }); var composite = Assert.IsType <CompositeGlob>(result); Assert.Same(glob1, composite.Globs.First()); Assert.Same(glob2, composite.Globs.Skip(1).First()); Assert.Equal(2, composite.Globs.Count()); }
public void GlobMatchingShouldRespectTheRootOfTheGlob(string fileSpec, string stringToMatch, string globRoot, bool shouldMatch) { var glob = MSBuildGlob.Parse(globRoot, fileSpec); if (shouldMatch) { Assert.True(glob.IsMatch(stringToMatch)); } else { Assert.False(glob.IsMatch(stringToMatch)); } }
public void GlobParsingShouldInitializePartialStateOnIllegalFileSpec() { var globRoot = NativeMethodsShared.IsWindows ? @"c:\a" : "/a"; var illegalFileSpec = $"b/.../**/*.cs"; var glob = MSBuildGlob.Parse(globRoot, illegalFileSpec); Assert.False(glob.IsLegal); Assert.Equal(false, glob._needsRecursion); Assert.Equal(illegalFileSpec, glob._fileSpec); Assert.Equal(globRoot.WithTrailingSlash(), glob._globRoot); Assert.Equal(string.Empty, glob.FixedDirectoryPart); Assert.Equal(string.Empty, glob.WildcardDirectoryPart); Assert.Equal(string.Empty, glob.FilenamePart); }
public void GlobParsingShouldInitializeState() { var globRoot = NativeMethodsShared.IsWindows ? @"c:\a" : "/a"; var fileSpec = $"b/**/*.cs"; var glob = MSBuildGlob.Parse(globRoot, fileSpec); var expectedFixedDirectory = Path.Combine(globRoot, "b").WithTrailingSlash(); Assert.True(glob.IsLegal); Assert.Equal(true, glob._needsRecursion); Assert.Equal(fileSpec, glob._fileSpec); Assert.Equal(globRoot.WithTrailingSlash(), glob._globRoot); Assert.True(glob.FixedDirectoryPart.StartsWith(glob._globRoot)); Assert.Equal(expectedFixedDirectory, glob.FixedDirectoryPart); Assert.Equal("**/", glob.WildcardDirectoryPart); Assert.Equal("*.cs", glob.FilenamePart); }
public void GlobMatchShouldReturnFalseIfArgumentContainsInvalidPathOrFileCharacters() { var glob = MSBuildGlob.Parse("*"); foreach (var invalidPathChar in FileUtilities.InvalidPathChars) { Assert.False(glob.IsMatch(invalidPathChar.ToString())); } foreach (var invalidFileChar in FileUtilities.InvalidFileNameChars) { if (invalidFileChar == '\\' || invalidFileChar == '/') { continue; } Assert.False(glob.IsMatch(invalidFileChar.ToString())); } }
public static void RenameItemInProjectChecked(string projectPath, string itemType, string oldInclude, string newInclude) { var dir = Directory.GetParent(projectPath).FullName; var root = ProjectRootElement.Open(projectPath); Debug.Assert(root != null); if (root.AreDefaultCompileItemsEnabled()) { // No need to add. It's already included automatically by the MSBuild Sdk. // This assumes the source file is inside the project directory and not manually excluded in the csproj return; } var normalizedOldInclude = oldInclude.NormalizePath(); var normalizedNewInclude = newInclude.NormalizePath(); var item = root.FindItemOrNullAbs(itemType, normalizedOldInclude); if (item == null) { return; } // Check if the found item include already matches the new path var glob = MSBuildGlob.Parse(item.Include); if (glob.IsMatch(normalizedNewInclude)) { return; } // Otherwise, if the item include uses globbing it's better to add a new item instead of modifying if (!string.IsNullOrEmpty(glob.WildcardDirectoryPart) || glob.FilenamePart.Contains("*")) { root.AddItem(itemType, normalizedNewInclude.RelativeToPath(dir).Replace("/", "\\")); root.Save(); return; } item.Include = normalizedNewInclude.RelativeToPath(dir).Replace("/", "\\"); root.Save(); }
public static string[] GetIncludeFiles(string projectPath, string itemType) { var result = new List <string>(); var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs"); var root = ProjectRootElement.Open(projectPath); Debug.Assert(root != null); foreach (var itemGroup in root.ItemGroups) { if (itemGroup.Condition.Length != 0) { continue; } foreach (var item in itemGroup.Items) { if (item.ItemType != itemType) { continue; } string normalizedInclude = item.Include.NormalizePath(); var glob = MSBuildGlob.Parse(normalizedInclude); // TODO Check somehow if path has no blob to avoid the following loop... foreach (var existingFile in existingFiles) { if (glob.IsMatch(existingFile)) { result.Add(existingFile); } } } } return(result.ToArray()); }
public void GlobMatchingBehaviourWhenInputIsASingleSlash() { var glob = MSBuildGlob.Parse("*"); if (NativeMethodsShared.IsUnixLike) { // \ is an acceptable file character on Unix, * should match it Assert.True(glob.IsMatch("\\")); // / means root on Unix Assert.False(glob.IsMatch("/")); } else { // \ means partition root on Windows Assert.False(glob.IsMatch("\\")); // / also means partition root on Windows Assert.False(glob.IsMatch("/")); } }
public void GlobMatchingIgnoresSlashOrientationAndRepetitions(string globRoot, string fileSpec, string stringToMatch, string fixedDirectoryPart, string wildcardDirectoryPart, string filenamePart) { var glob = MSBuildGlob.Parse(globRoot, fileSpec); Assert.True(glob.IsMatch(stringToMatch)); MSBuildGlob.MatchInfoResult result = glob.MatchInfo(stringToMatch); Assert.True(result.IsMatch); string NormalizeSlashes(string path) { string normalizedPath = path.Replace(Path.DirectorySeparatorChar == '/' ? '\\' : '/', Path.DirectorySeparatorChar); return NativeMethodsShared.IsWindows ? normalizedPath.Replace("\\\\", "\\") : normalizedPath; } var rootedFixedDirectoryPart = Path.Combine(FileUtilities.NormalizePath(globRoot), fixedDirectoryPart); Assert.Equal(FileUtilities.GetFullPathNoThrow(rootedFixedDirectoryPart), result.FixedDirectoryPartMatchGroup); Assert.Equal(NormalizeSlashes(wildcardDirectoryPart), result.WildcardDirectoryPartMatchGroup); Assert.Equal(NormalizeSlashes(filenamePart), result.FilenamePartMatchGroup); }
public void GlobRootEndsWithTrailingSlash(string globRoot) { var glob = MSBuildGlob.Parse(globRoot, "*"); Assert.Equal(glob._globRoot.LastOrDefault(), Path.DirectorySeparatorChar); }
public static string[] GetIncludeFiles(string projectPath, string itemType) { var result = new List <string>(); var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs"); var root = ProjectRootElement.Open(projectPath); Debug.Assert(root != null); if (root.AreDefaultCompileItemsEnabled()) { var excluded = new List <string>(); result.AddRange(existingFiles); foreach (var item in root.Items) { if (string.IsNullOrEmpty(item.Condition)) { continue; } if (item.ItemType != itemType) { continue; } string normalizedRemove = item.Remove.NormalizePath(); var glob = MSBuildGlob.Parse(normalizedRemove); excluded.AddRange(result.Where(includedFile => glob.IsMatch(includedFile))); } result.RemoveAll(f => excluded.Contains(f)); } foreach (var itemGroup in root.ItemGroups) { if (itemGroup.Condition.Length != 0) { continue; } foreach (var item in itemGroup.Items) { if (item.ItemType != itemType) { continue; } string normalizedInclude = item.Include.NormalizePath(); var glob = MSBuildGlob.Parse(normalizedInclude); foreach (var existingFile in existingFiles) { if (glob.IsMatch(existingFile)) { result.Add(existingFile); } } } } return(result.ToArray()); }
protected virtual IMSBuildGlob CreateMsBuildGlob() { return(MSBuildGlob.Parse(ProjectDirectory, EscapingUtilities.UnescapeAll(TextFragment))); }
protected virtual IMSBuildGlob CreateMsBuildGlob() { return MSBuildGlob.Parse(ProjectDirectory, TextFragment.Unescape()); }
public void GlobShouldMatchEmptyArgWhenGlobAcceptsEmptyString(string globRoot) { var glob = MSBuildGlob.Parse(globRoot, "*"); Assert.True(glob.IsMatch(string.Empty)); }
public void GlobFromNullRootThrows() { Assert.Throws <ArgumentNullException>(() => MSBuildGlob.Parse(null, "*")); }
public void GlobFromEmptyRootUsesCurrentDirectory() { var glob = MSBuildGlob.Parse(string.Empty, "*"); Assert.Equal(Directory.GetCurrentDirectory().WithTrailingSlash(), glob._globRoot); }
public void GlobMatchingIgnoresSlashOrientationAndRepetitions(string globRoot, string fileSpec, string stringToMatch) { var glob = MSBuildGlob.Parse(globRoot, fileSpec); Assert.True(glob.IsMatch(stringToMatch)); }
public void GlobShouldNotMatchEmptyArgWhenGlobDoesNotRepresentEmpty(string globRoot) { var glob = MSBuildGlob.Parse(globRoot, "*a*"); Assert.False(glob.IsMatch(string.Empty)); }