public void GlobWithGapsShouldNotMatchIfGapsMatch() { var glob = new MSBuildGlobWithGaps(MSBuildGlob.Parse("a*"), MSBuildGlob.Parse("*b")); Assert.False(glob.IsMatch("ab")); }
public void GlobWithGapsShouldMatchIfNoGapsMatch() { var glob = new MSBuildGlobWithGaps(MSBuildGlob.Parse("a*"), MSBuildGlob.Parse("b*")); Assert.True(glob.IsMatch("ab")); }
/// <inheritdoc/> public void PredictInputsAndOutputs( ProjectInstance projectInstance, ProjectPredictionReporter predictionReporter) { List <string> configFiles = FindConfigFiles(projectInstance); foreach (string configFile in configFiles) { string configFileFullPath = Path.Combine(projectInstance.Directory, configFile); string configFileContent = File.ReadAllText(configFileFullPath); bool isTsConfig = Path.GetFileName(configFile).Equals(TsConfigFileName, PathComparer.Comparison); TsConfig tsConfig; try { tsConfig = JsonSerializer.Deserialize <TsConfig>(configFileContent, _jsonSerializerOptions); } catch (JsonException) { // Ignore invalid config files continue; } string configFileDir = Path.GetDirectoryName(configFileFullPath); tsConfig.ApplyDefaults(); if (tsConfig.Files != null) { foreach (string file in tsConfig.Files) { string fileFullPath = PathUtilities.NormalizePath(Path.Combine(configFileDir, file)); predictionReporter.ReportInputFile(fileFullPath); } } // Reuse MSBuild's globbing logic as it should match what tsc does. if (tsConfig.Include != null) { var directoriesToEnumerate = new Queue <string>(); var includeGlobs = new MSBuildGlob[tsConfig.Include.Count]; for (var i = 0; i < tsConfig.Include.Count; i++) { string include = tsConfig.Include[i]; MSBuildGlob includeGlob = MSBuildGlob.Parse(configFileDir, include); directoriesToEnumerate.Enqueue(includeGlob.FixedDirectoryPart); includeGlobs[i] = includeGlob; } var excludeGlobs = new MSBuildGlob[tsConfig.Exclude.Count]; for (var i = 0; i < tsConfig.Exclude.Count; i++) { string exclude = tsConfig.Exclude[i]; // Handle the case where just a folder name is used as an exclude value if (exclude.IndexOf('*', StringComparison.Ordinal) == -1) { exclude += "/**"; } excludeGlobs[i] = MSBuildGlob.Parse(configFileDir, exclude); } var finalGlob = new MSBuildGlobWithGaps(new CompositeGlob(includeGlobs), excludeGlobs); var visitedDirectories = new HashSet <string>(PathComparer.Instance); while (directoriesToEnumerate.Count > 0) { string directoryToEnumerate = directoriesToEnumerate.Dequeue(); // In case the initial globs has parent/child relationships if (!visitedDirectories.Add(directoryToEnumerate)) { continue; } // Some globs might point to non-existent paths. if (!Directory.Exists(directoryToEnumerate)) { continue; } foreach (string file in Directory.EnumerateFiles(directoryToEnumerate, "*", SearchOption.TopDirectoryOnly)) { if (finalGlob.IsMatch(file)) { predictionReporter.ReportInputFile(file); } } foreach (string directory in Directory.EnumerateDirectories(directoryToEnumerate, "*", SearchOption.TopDirectoryOnly)) { directoriesToEnumerate.Enqueue(directory); } } } if (isTsConfig && tsConfig.CompilerOptions != null) { if (!string.IsNullOrEmpty(tsConfig.CompilerOptions.OutFile)) { string outFileFullPath = PathUtilities.NormalizePath(Path.Combine(configFileDir, tsConfig.CompilerOptions.OutFile)); predictionReporter.ReportOutputFile(outFileFullPath); } if (!string.IsNullOrEmpty(tsConfig.CompilerOptions.OutDir)) { string outDirFullPath = PathUtilities.NormalizePath(Path.Combine(configFileDir, tsConfig.CompilerOptions.OutDir)); predictionReporter.ReportOutputDirectory(outDirFullPath); } } } }
public void GlobWithGapsShouldWorkWithNoGaps() { var glob = new MSBuildGlobWithGaps(MSBuildGlob.Parse("a*"), Enumerable.Empty <IMSBuildGlob>()); Assert.True(glob.IsMatch("ab")); }
protected virtual void VisitGlobWithGaps(MSBuildGlobWithGaps globWithGaps) { }