Class: Ergo::Digest

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

Overview

Digest class is used to read and write lists of files with their associated checksums. This class uses SHA1.

Constant Summary collapse

MASTER_NAME =

The name of the master digest.

'Master'
DIRECTORY =

The digest file to use if the root directory has a ‘log/` directory.

".ergo/digest"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Digest

Initialize new instance of Digest.



67
68
69
70
71
72
73
74
75
76
# File 'lib/ergo/digest.rb', line 67

def initialize(options={})
  @ignore = options[:ignore]
  @name   = options[:name] || MASTER_NAME

  @current = {}
  @saved   = {}

  read
  refresh
end

Instance Attribute Details

#currentObject (readonly)

Set of files as they appear on disk.



56
57
58
# File 'lib/ergo/digest.rb', line 56

def current
  @current
end

#ignoreIgnore (readonly)

Instance of Ignore is used to filter “boring files”.

Returns:



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

def ignore
  @ignore
end

#nameIgnore (readonly)

Name of digest, which corresponds to the rule bookmark.

Returns:



53
54
55
# File 'lib/ergo/digest.rb', line 53

def name
  @name
end

#savedObject (readonly)

Set of files as saved in the digest.



59
60
61
# File 'lib/ergo/digest.rb', line 59

def saved
  @saved
end

Class Method Details

.clear_digestsObject

Remove all digests.



31
32
33
34
35
# File 'lib/ergo/digest.rb', line 31

def self.clear_digests
  Dir.glob(File.join(DIRECTORY, "*.digest")).each do |file|
    FileUtils.rm(file)
  end
end

.latest(*names) ⇒ String

Get the name of the most recent digest given a selection of names from which to choose.

Parameters:

  • names

    Selection of names. [Array<String>]

Returns:

  • (String)

    Returns the digests name.



21
22
23
24
25
26
27
28
# File 'lib/ergo/digest.rb', line 21

def self.latest(*names)
  names = names.select do |name|
    File.exist?(File.join(DIRECTORY, "#{name}.digest"))
  end
  names.max do |name|
     File.mtime(File.join(DIRECTORY, "#{name}.digest"))
  end
end

.remove_digest(name) ⇒ Object

Remove digest by name.



38
39
40
41
42
43
# File 'lib/ergo/digest.rb', line 38

def self.remove_digest(name)
  file = File.join(DIRECTORY, "#{name}.digest")
  if file.exist?(file)
    FileUtils.rm(file)
  end
end

Instance Method Details

#checksum(file) ⇒ String

Compute the sha1 identifer for a file.

Parameters:

  • file

    path to a file

Returns:

  • (String)

    Returns String SHA1 digest string.



170
171
172
173
174
175
176
177
178
# File 'lib/ergo/digest.rb', line 170

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

#filenameString

The digest file’s path.

Returns:

  • (String)

    Returns



81
82
83
# File 'lib/ergo/digest.rb', line 81

def filename
  File.join(DIRECTORY, "#{name}.digest")
end

#filter(list) ⇒ Array<String>

Filter files of those to be ignored.

Returns:

  • (Array<String>)

    Return



183
184
185
186
187
188
189
190
191
192
# File 'lib/ergo/digest.rb', line 183

def filter(list)
  case ignore
  when Ignore
    ignore.filter(list)
  when Array
    list.reject{ |path| ignore.any?{ |ig| /^#{ig}/ =~ path } }
  else
    list
  end
end

#readvoid

This method returns an undefined value.

Load digest from file system.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ergo/digest.rb', line 88

def read
  file = filename

  # if the digest doesn't exist fallback to master digest
  unless File.exist?(file)
    file = File.join(DIRECTORY, "#{MASTER_NAME}.digest")
  end

  return unless File.exist?(file)

  File.read(file).lines.each do |line|
    if md = /^(\w+)\s+(.*?)$/.match(line)
      @saved[md[2]] = md[1]
    end
  end
end

#refreshvoid

This method returns an undefined value.

Gather current digest for all files.



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/ergo/digest.rb', line 124

def refresh
  list = Dir['**/*']
  list = filter(list)
  list.each do |path|
    if File.directory?(path)
      # how to handle directories as a whole?
    elsif File.exist?(path)
      id = checksum(path)
      @current[path] = id
    end
  end
end

#removeObject

Remove digest.



148
149
150
151
152
# File 'lib/ergo/digest.rb', line 148

def remove
  if File.exist?(filename)
    FileUtils.rm(filename)
  end
end

#savevoid

This method returns an undefined value.

Save current digest.



140
141
142
143
144
145
# File 'lib/ergo/digest.rb', line 140

def save
  FileUtils.mkdir_p(DIRECTORY) unless File.directory?(DIRECTORY)
  File.open(filename, 'w') do |f|
    f << to_s
  end
end

#to_sString

Produce the test representation of the digest that is stored to disk.

Returns:

  • (String)

    Returns digest file format.



157
158
159
160
161
162
163
# File 'lib/ergo/digest.rb', line 157

def to_s
  s = ""
  current.each do |path, id|
    s << "#{id} #{path}\n"
  end
  s
end