Skip to content

Instantly share code, notes, and snippets.

@voithos
Forked from kamranayub/ExcludeDirectorySearch.cs
Created September 12, 2012 17:06
Show Gist options
  • Save voithos/3708180 to your computer and use it in GitHub Desktop.
Save voithos/3708180 to your computer and use it in GitHub Desktop.
Cassette ExcludeDirectorySearch
/// <summary>
/// An exclude directory search for Cassette.
/// </summary>
public class ExcludeDirectorySearch : IFileSearch
{
/// <summary>
/// The file search pattern. For example, "*.js;*.coffee".
/// </summary>
public string Pattern { get; set; }
/// <summary>
/// Files with full paths matching this regular expression will be excluded.
/// </summary>
public Regex Exclude { get; set; }
/// <summary>
/// Directories matching these patterns will be excluded.
/// </summary>
public string[] ExcludeDirectories { get; set; }
/// <summary>
/// Searches the given directory for files matching the search parameters of this object.
/// </summary>
/// <param name="directory">The directory to search.</param>
/// <returns>A collection of files.</returns>
public IEnumerable<IFile> FindFiles(IDirectory directory)
{
var files =
from pattern in GetFilePatterns()
from file in directory.GetFiles(pattern, SearchOption.AllDirectories)
where IsAssetFile(file)
select file;
files = files.Distinct(new FilePathComparer());
return RemoveMinifiedFilesWhereNonMinExist(files);
}
IEnumerable<string> GetFilePatterns()
{
return Pattern.IsNullOrWhiteSpace()
? new[] { "*" }
: Pattern.Split(new[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);
}
bool IsAssetFile(IFile file)
{
return !IsDescriptorFilename(file) && !IsExcluded(file.FullPath);
}
bool IsExcluded(string filename)
{
bool directoryExcluded = false,
fileExcluded = false;
if (ExcludeDirectories != null)
{
var directoryRegexes = ExcludeDirectories.Select(CreateDirectoryRegexFromPattern);
directoryExcluded = directoryRegexes.Any(regex => regex.IsMatch(filename));
}
if (Exclude != null)
{
fileExcluded = Exclude.IsMatch(filename);
}
return directoryExcluded || fileExcluded;
}
public bool IsMatch(string filename)
{
if (IsExcluded(filename)) return false;
var patternRegexes = GetFilePatterns().Select(CreateRegexFromPattern);
return patternRegexes.Any(regex => regex.IsMatch(filename));
}
static Regex CreateRegexFromPattern(string filenamePattern)
{
var expression = filenamePattern
.Replace(".", "\\.")
.Replace("*", ".*?")
+ "$";
return new Regex(expression, RegexOptions.IgnoreCase);
}
static Regex CreateDirectoryRegexFromPattern(string dirPattern)
{
var expression = String.Format("{0}[\\/].*",
dirPattern
.Replace("*", ".*?"));
return new Regex(expression, RegexOptions.IgnoreCase);
}
IEnumerable<IFile> RemoveMinifiedFilesWhereNonMinExist(IEnumerable<IFile> files)
{
var filter = new ConventionalMinifiedFileFilter();
return filter.Apply(files);
}
static bool IsDescriptorFilename(IFile file)
{
return file.FullPath.EndsWith("/bundle.txt", StringComparison.OrdinalIgnoreCase) ||
file.FullPath.EndsWith("/scriptbundle.txt", StringComparison.OrdinalIgnoreCase) ||
file.FullPath.EndsWith("/stylesheetbundle.txt", StringComparison.OrdinalIgnoreCase) ||
file.FullPath.EndsWith("/htmltemplatebundle.txt", StringComparison.OrdinalIgnoreCase);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment