class Rulebow::WatchList
Encapsulates list of file globs to be watched.
Attributes
Project’s root directory.
Public Class Methods
Initialize new instance of Ignore
.
Returns nothing.
# File lib/rulebow/watchlist.rb, line 13 def initialize(options={}) @accept = options[:accept].to_a.flatten @ignore = options[:ignore].to_a.flatten end
Public Instance Methods
# File lib/rulebow/watchlist.rb, line 78 def accept(*globs) @accept.concat(globs.flatten) end
# File lib/rulebow/watchlist.rb, line 83 def accept!(*globs) @accept.replace(globs.flatten) end
Get a current digest.
Returns digest. [Hash]
# File lib/rulebow/watchlist.rb, line 100 def digest(root=nil) if root Dir.chdir(root) do read_digest end else read_digest end end
Filter a list of files in accordance with the accept and ignore lists.
# File lib/rulebow/watchlist.rb, line 24 def filter(files) filter_ignore(filter_accept(files)) end
Filter a list of files in accordance with the ignore list.
files - The list of files. [Array<String>]
Returns [Array<String>]
# File lib/rulebow/watchlist.rb, line 34 def filter_accept(files) list = [] files.each do |file| hit = @accept.any? do |pattern| match?(pattern, file) end list << file if hit end list end
Filter a list of files in accordance with the ignore list.
files - The list of files. [Array<String>]
Returns [Array<String>]
# File lib/rulebow/watchlist.rb, line 51 def filter_ignore(files) list = [] files.each do |file| hit = @ignore.any? do |pattern| match?(pattern, file) end list << file unless hit end list end
# File lib/rulebow/watchlist.rb, line 88 def ignore(*globs) @ignore.concat(globs.flatten) end
# File lib/rulebow/watchlist.rb, line 93 def ignore!(*globs) @ignore.replace(globs.flatten) end
Private Instance Methods
Compute the sha1 identifer for a file.
file - path to a file
Returns [String] SHA1 digest string.
# File lib/rulebow/watchlist.rb, line 172 def checksum(file) sha = ::Digest::SHA1.new File.open(file, 'r') do |fh| fh.each_line do |l| sha << l end end sha.hexdigest end
Shortcut to ‘File.fnmatch?` method.
Returns [Boolean]
# File lib/rulebow/watchlist.rb, line 163 def fnmatch?(pattern, file, mode=File::FNM_PATHNAME) File.fnmatch?(pattern, file, File::FNM_PATHNAME) end
Given a pattern and a file, does the file match the pattern? This code is based on the rules used by git’s .gitignore file.
TODO: The code is probably not quite right.
TODO: Handle regular expressions.
Returns [Boolean]
# File lib/rulebow/watchlist.rb, line 134 def match?(pattern, file) if Regexp === pattern return pattern.match(file) ? true : false end if pattern.start_with?('!') return !match?(pattern.sub('!','').strip) end dir = pattern.end_with?('/') pattern = pattern.chomp('/') if dir if pattern.start_with?('/') fnmatch?(pattern.sub('/',''), file) else if dir fnmatch?(File.join(pattern, '**', '*'), file) || fnmatch?(pattern, file) && File.directory?(file) elsif pattern.include?('/') fnmatch?(pattern, file) else fnmatch?(File.join('**',pattern), file) end end end
# File lib/rulebow/watchlist.rb, line 112 def read_digest dig = {} list = filter(Dir.glob('**/*', File::FNM_PATHNAME)) list.each do |path| if File.directory?(path) # TODO: how to handle directories as a whole? elsif File.exist?(path) dig[path] = checksum(path) end end dig end