Class: Masamune::CachedFilesystem

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/masamune/cached_filesystem.rb

Defined Under Namespace

Classes: PathCache

Constant Summary collapse

MAX_DEPTH =
10
EMPTY_SET =
Set.new

Instance Method Summary collapse

Constructor Details

#initialize(filesystem) ⇒ CachedFilesystem

Returns a new instance of CachedFilesystem.



28
29
30
31
32
# File 'lib/masamune/cached_filesystem.rb', line 28

def initialize(filesystem)
  super filesystem
  @filesystem = filesystem
  clear!
end

Instance Method Details

#clear!Object



34
35
36
# File 'lib/masamune/cached_filesystem.rb', line 34

def clear!
  @cache = PathCache.new(@filesystem)
end

#exists?(file) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/masamune/cached_filesystem.rb', line 38

def exists?(file)
  glob(file, max_depth: 0).include?(file)
end

#glob(file_or_glob, options = {}) ⇒ Object



42
43
44
45
46
47
# File 'lib/masamune/cached_filesystem.rb', line 42

def glob(file_or_glob, options = {})
  return Set.new(to_enum(:glob, file_or_glob, options)) unless block_given?
  glob_stat(file_or_glob, options) do |entry|
    yield entry.name
  end
end

#glob_stat(file_or_glob, options = {}, &block) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/masamune/cached_filesystem.rb', line 58

def glob_stat(file_or_glob, options = {}, &block)
  return Set.new(to_enum(:glob_stat, file_or_glob, options)) unless block_given?
  return if file_or_glob.blank?
  return if root_path?(file_or_glob)
  depth = options.fetch(:depth, 0)
  max_depth = options.fetch(:max_depth, 0)
  return if depth > MAX_DEPTH || depth > max_depth

  glob_stat(dirname(file_or_glob), depth: depth + 1, max_depth: max_depth, &block)

  dirname = dirname(file_or_glob)
  unless @cache.any?(dirname)
    pattern = root_path?(dirname) ? file_or_glob : File.join(dirname, '*')
    @filesystem.glob_stat(pattern) do |entry|
      @cache.put(entry.name, entry)
    end
  end

  file_regexp = glob_to_regexp(file_or_glob, options)
  return unless depth.zero?
  @cache.get(dirname).each do |entry|
    next if entry.name == dirname
    next unless entry.name =~ file_regexp
    yield entry
  end
end

#stat(file_or_dir) ⇒ Object

Raises:

  • (ArgumentError)


49
50
51
52
53
54
55
56
# File 'lib/masamune/cached_filesystem.rb', line 49

def stat(file_or_dir)
  raise ArgumentError, 'cannot contain wildcard' if file_or_dir.include?('*')
  result = glob_stat(file_or_dir, recursive: true)
  return unless result.any?
  max_time = result.map { |stat| stat.try(:mtime) }.compact.max
  sum_size = result.map { |stat| stat.try(:size) }.compact.reduce(:+)
  OpenStruct.new(name: file_or_dir, mtime: max_time, size: sum_size)
end