lørdag 21. mars 2009

Build task for searching in files

Technorati Tags: ,

Just to test out the code add-in I just added to Live Writer I thought I would share this little build task for filtering out files based on standard string search, with or without regular expressions. Disclaimer! The regular expression mode didn’t work as I had expected and my needs there and then didn’t exceed pure freetext search, so it may need some tweaking, and of course the usual use at own risk bla bla.

namespace YourNameSpace.BuildTasks
{
using System.Diagnostics;
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Build.Utilities;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;

/// <summary>
/// Finds files with a content that has one or more matches
/// for the pattern provided.
/// </summary>
public class FindFilesWithContent : Task
{
public FindFilesWithContent()
{
results = new List<TaskItem>();
} // Properties
[Required]
public ITaskItem[] FilesToSearch { get; set; }
[Required]
public string Pattern { get; set; }
public bool UseRegExp { get; set; }
private readonly List<TaskItem> results;
[Output]
public ITaskItem[] Results
{
get { return results.ToArray(); }
}
public override bool Execute()
{
if(UseRegExp) Log.LogMessage(MessageImportance.Low,
"Using regular expression", new object[] { null });
Log.LogMessage(MessageImportance.Low,
"Matching with pattern {0}", new object[] { Pattern });
foreach (ITaskItem taskItem in FilesToSearch)
{
if (!File.Exists(taskItem.ItemSpec))
{
Log.LogError("File does not exist: {0}",
new object[] { taskItem.ItemSpec });
}

//Read the whole text file to the end before closing it
StreamReader reader = new StreamReader(taskItem.ItemSpec);
string allRead = reader.ReadToEnd();
reader.Close();

Log.LogMessage(MessageImportance.Low,
"Content of file to match: {0}",
new object[] { allRead });

//Do the matching
if (Compare(allRead, Pattern))
{
results.Add(new TaskItem(taskItem));
Log.LogMessage(MessageImportance.Low,
"File matched: {0}",
new object[] { taskItem.ItemSpec });
}
else
Log.LogMessage(MessageImportance.Low,
"File did not match: {0}",
new object[] { taskItem.ItemSpec });
}
return true;
}

private bool Compare(string stringToSearch, string pattern)
{
if (UseRegExp)
return Regex.IsMatch(stringToSearch, pattern);
return stringToSearch.Contains(pattern);
}
}
}




The usage is as follows:





<!--UseRegExp="false" is default-->
<FindFilesWithContent
FilesToSearch="@(FilesToSearchWithin)"
Pattern="This string I will find"
UseRegExp="false">
<Output TaskParameter="Results"
ItemName="FilesThatHaveMatchingContent"/>
</FindFilesWithContent>





Ingen kommentarer: