Class: RevTree

Inherits:
Object
  • Object
show all
Defined in:
lib/revtree.rb

Overview

The RevTree class provides a tree structure representing file directories and files, allowing for version tracking based on MD5 hashes.

This class can traverse directories, compare versions of trees, and serialize/deserialize itself to/from JSON.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, whitelist = nil) ⇒ RevTree

Initializes a new RevTree object representing a directory or file.

Parameters:

  • path (String, Pathname)

    the path to the file or directory

  • whitelist (Array<String>, nil) (defaults to: nil)

    a list of file patterns to include (optional)



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/revtree.rb', line 54

def initialize(path, whitelist = nil)
  @path = Pathname.new(path)
  @name = @path.basename.to_s
  @whitelist = whitelist || []
  @status = :unmodified

  if @path.directory?
    init_dir
  else
    init_file
  end
end

Instance Attribute Details

#childrenArray<RevTree> (readonly)

Returns the list of children in the tree (empty for files).

Returns:

  • (Array<RevTree>)

    the list of children in the tree (empty for files)



36
37
38
# File 'lib/revtree.rb', line 36

def children
  @children
end

#nameString (readonly)

Returns the name of the file or directory.

Returns:

  • (String)

    the name of the file or directory



42
43
44
# File 'lib/revtree.rb', line 42

def name
  @name
end

#revString (readonly)

Returns the revision (MD5 hash) of the file or directory.

Returns:

  • (String)

    the revision (MD5 hash) of the file or directory



45
46
47
# File 'lib/revtree.rb', line 45

def rev
  @rev
end

#statusSymbol (readonly)

Returns the status of the file or directory (:unmodified, :modified, :added, :removed).

Returns:

  • (Symbol)

    the status of the file or directory (:unmodified, :modified, :added, :removed)



48
49
50
# File 'lib/revtree.rb', line 48

def status
  @status
end

#typeSymbol (readonly)

Returns the type of the node (:folder or :file).

Returns:

  • (Symbol)

    the type of the node (:folder or :file)



39
40
41
# File 'lib/revtree.rb', line 39

def type
  @type
end

Class Method Details

.from_h(h) ⇒ RevTree

Reconstructs a RevTree object from a hash.

Parameters:

  • h (Hash)

    the hash to deserialize

Returns:

  • (RevTree)

    the reconstructed RevTree object



101
102
103
# File 'lib/revtree.rb', line 101

def self.from_h(h)
  new_tree(h[:name], h[:type].to_sym, h[:rev], h[:children], h[:status])
end

.from_json(json_str) ⇒ RevTree

Reconstructs a RevTree object from a JSON string.

Parameters:

  • json_str (String)

    the JSON string to deserialize

Returns:

  • (RevTree)

    the reconstructed RevTree object



109
110
111
112
113
114
# File 'lib/revtree.rb', line 109

def self.from_json(json_str)
  data = JSON.parse(json_str, symbolize_names: true)
  file_tree = from_h(data)

  file_tree
end

Instance Method Details

#for_each(status_whitelist = [:unmodified, :modified, :added, :removed]) {|node, full_path| ... } ⇒ void

This method returns an undefined value.

Executes a block of code for each file matching the provided status whitelist.

Parameters:

  • status_whitelist (Array<Symbol>) (defaults to: [:unmodified, :modified, :added, :removed])

    the list of statuses to match (:added, :modified, etc.)

Yields:

  • (node, full_path)

    the block to be executed for each matching file

Yield Parameters:

  • node (RevTree)

    the current node being traversed

  • full_path (String)

    the full path of the current node



123
124
125
126
127
# File 'lib/revtree.rb', line 123

def for_each(status_whitelist = [:unmodified, :modified, :added, :removed], &block)
  return unless block_given?

  RevTree.traverse_tree(self, status_whitelist, @path, nil, &block)
end

This method returns an undefined value.

Prints the tree structure, including file names and statuses, to the console.

Parameters:

  • indent (Integer) (defaults to: 0)

    the indentation level (default: 0)



71
72
73
74
75
# File 'lib/revtree.rb', line 71

def print_tree(indent = 0)
  status_str = @status ? " (status: #{@status})" : ''
  puts "#{'  ' * indent}#{@type == :folder ? '[Folder]' : '[File]'} #{@name} (rev: #{@rev})#{status_str}"
  @children.each { |child| child.print_tree(indent + 1) }
end

#to_hHash

Serializes the RevTree object to a hash.

Returns:

  • (Hash)

    a hash representing the object



80
81
82
83
84
85
86
87
88
# File 'lib/revtree.rb', line 80

def to_h
  {
    type: @type,
    name: @name,
    rev: @rev,
    status: @status,
    children: @children.map(&:to_h),
  }
end

#to_jsonString

Converts the RevTree object to JSON format.

Returns:

  • (String)

    a JSON string representing the object



93
94
95
# File 'lib/revtree.rb', line 93

def to_json
  JSON.pretty_generate(self.to_h)
end

#watch(status_whitelist = [:modified, :added, :removed]) {|node, full_path| ... } ⇒ void

This method returns an undefined value.

Watches the tree for changes

Compares the refreshed tree to its last version and calls the provided block for each node that matches the statuses in the status_whitelist.

Parameters:

  • status_whitelist (Array<Symbol>) (defaults to: [:modified, :added, :removed])

    the list of statuses to match (:added, :modified, etc.)

Yields:

  • (node, full_path)

    the block to be executed for each matching file

Yield Parameters:

  • node (RevTree)

    the node that was changed

  • full_path (String)

    the full path of the node



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/revtree.rb', line 139

def watch(status_whitelist = [:modified, :added, :removed], &block)
  current_tree = self
  @interval ||= 5

  Signal.trap('INT') { exit }
  Signal.trap('TERM') { exit }
  loop do
    sleep @interval

    new_tree = RevTree.new(@path, @whitelist)
    diff_tree = RevTree.compare(current_tree, new_tree)

    next if diff_tree.nil?

    diff_tree.for_each(status_whitelist) do |node, full_path|
      block.call(node, full_path)
    end

    current_tree = new_tree
  end
end

#with_interval(interval) ⇒ RevTree

Sets the interval for the watch method’s sleep duration.

Parameters:

  • interval (Integer)

    the number of seconds to sleep between checks

Returns:

  • (RevTree)

    the current instance for chaining



165
166
167
168
# File 'lib/revtree.rb', line 165

def with_interval(interval)
  @interval = interval
  self
end