class Rulebow::WatchList

Encapsulates list of file globs to be watched.

Attributes

root[R]

Project’s root directory.

Public Class Methods

new(options={}) click to toggle source

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

accept(*globs) click to toggle source
# File lib/rulebow/watchlist.rb, line 78
def accept(*globs)
  @accept.concat(globs.flatten)
end
accept!(*globs) click to toggle source
# File lib/rulebow/watchlist.rb, line 83
def accept!(*globs)
  @accept.replace(globs.flatten)
end
digest(root=nil) click to toggle source

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(files) click to toggle source

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_accept(files) click to toggle source

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_ignore(files) click to toggle source

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
ignore(*globs) click to toggle source
# File lib/rulebow/watchlist.rb, line 88
def ignore(*globs)
  @ignore.concat(globs.flatten)
end
ignore!(*globs) click to toggle source
# File lib/rulebow/watchlist.rb, line 93
def ignore!(*globs)
  @ignore.replace(globs.flatten)
end

Private Instance Methods

checksum(file) click to toggle source

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
fnmatch?(pattern, file, mode=File::FNM_PATHNAME) click to toggle source

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
match?(pattern, file) click to toggle source

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
read_digest() click to toggle source
# 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