Class: Autorespawn::ProgramID

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

Overview

Management of the ID of a complete Ruby program

It basically stores information about all the files that form this program.

Defined Under Namespace

Classes: FileInfo

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeProgramID

Returns a new instance of ProgramID.



18
19
20
# File 'lib/autorespawn/program_id.rb', line 18

def initialize
    @files = Hash.new
end

Instance Attribute Details

#filesHash<Pathname,FileInfo> (readonly)

Information about the files that form this program

Returns:



16
17
18
# File 'lib/autorespawn/program_id.rb', line 16

def files
  @files
end

Class Method Details

.for_selfObject

Compute ID information abou thte current Ruby process



38
39
40
41
42
# File 'lib/autorespawn/program_id.rb', line 38

def self.for_self
    id = ProgramID.new
    id.register_loaded_features
    id
end

Instance Method Details

#changed?Boolean

Whether the state on disk is different than the state stored in self

Returns:

  • (Boolean)


153
154
155
156
157
158
159
# File 'lib/autorespawn/program_id.rb', line 153

def changed?
    files.each_value.any? do |info|
        return true if !info.path.exist?
        stat = info.path.stat
        stat.mtime != info.mtime || stat.size != info.size
    end
end

#clearObject

Remove all tracked files



50
51
52
# File 'lib/autorespawn/program_id.rb', line 50

def clear
    files.clear
end

#each_tracked_file(with_status: false) {|path| ... } ⇒ Object

Enumerate the path of all the files that are being tracked

Yield Parameters:

  • path (Pathname)


131
132
133
134
135
136
137
138
139
140
# File 'lib/autorespawn/program_id.rb', line 131

def each_tracked_file(with_status: false, &block)
    if with_status
        return enum_for(__method__, with_status: true) if !block_given?
        files.each do |path, info|
            yield(path, info.mtime, info.size)
        end
    else
        files.keys.each(&block)
    end
end

#empty?Boolean

Whether this program ID tracks some files

Returns:

  • (Boolean)


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

def empty?
    files.empty?
end

#file_info(path, search_path = ruby_load_path) ⇒ FileInfo

Resolve file information about a single file

Parameters:

  • path (Pathname)

    the path to the file

  • search_path (Array<Pathname>) (defaults to: ruby_load_path)

    the search path to use to resolve ‘path’ if it is relative

Returns:



205
206
207
208
209
# File 'lib/autorespawn/program_id.rb', line 205

def file_info(path, search_path = ruby_load_path)
    resolved = resolve_file_path(path, search_path)
    stat = resolved.stat
    return FileInfo.new(path, resolved, stat.mtime, stat.size)
end

#idObject

Returns a string that can ID this program



143
144
145
146
147
148
149
150
# File 'lib/autorespawn/program_id.rb', line 143

def id
    return @id if @id

    complete_id = files.keys.sort.map do |p|
        "#{p}#{files[p].mtime}#{files[p].size}"
    end.join("")
    @id = Digest::SHA1.hexdigest(complete_id)
end

#include?(path, search_path = ruby_load_path) ⇒ Boolean

Returns:

  • (Boolean)


161
162
163
# File 'lib/autorespawn/program_id.rb', line 161

def include?(path, search_path = ruby_load_path)
    files.has_key?(resolve_file_path(path, search_path))
end

#initialize_copy(old) ⇒ Object



22
23
24
25
# File 'lib/autorespawn/program_id.rb', line 22

def initialize_copy(old)
    super
    @files = @files.dup
end

#merge!(id) ⇒ Object

Merge the information contained in another ProgramID object into self

Parameters:

  • id (ProgramID)

    the object whose information we should merge

Returns:

  • self



31
32
33
34
35
# File 'lib/autorespawn/program_id.rb', line 31

def merge!(id)
    @files.merge!(id.files)
    @id = nil
    self
end

#refreshObject

Update the information about all the files registered on this object



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/autorespawn/program_id.rb', line 116

def refresh
    updated = Hash.new
    files.each_key do |path|
        next if !path.exist?
        info = file_info(path)
        updated[info.path] = info
    end
    @files = updated
    @id = nil
    updated
end

#register_file(file, search_path = ruby_load_path) ⇒ Boolean

Registers file information for one file

Parameters:

  • file (Pathname)

    the path to the file

Returns:

  • (Boolean)

    whether the registration modified the program ID’s state



104
105
106
107
108
109
110
111
112
113
# File 'lib/autorespawn/program_id.rb', line 104

def register_file(file, search_path = ruby_load_path)
    info = file_info(file, search_path)
    modified = (files[info.path] != info)
    files[info.path] = info

    if modified
        @id = nil 
        info.path
    end
end

#register_files(files, search_path = ruby_load_path, ignore_not_found: true) ⇒ Boolean

Register a set of files

Parameters:

  • files (Array<String>)

    the list of files

  • search_path (Array<String>) (defaults to: ruby_load_path)

    the path to resolve relative paths

  • ignore_not_found (Boolean) (defaults to: true)

    whether files that cannot be resolved are ignored or cause a FileNotFound exception

Returns:

  • (Boolean)

    whether the program ID has been modified



81
82
83
84
85
86
87
# File 'lib/autorespawn/program_id.rb', line 81

def register_files(files, search_path = ruby_load_path, ignore_not_found: true)
    modified = Array.new
    files = resolve_file_list(files, search_path, ignore_not_found: ignore_not_found)
    files.find_all do |path|
        register_file(path, search_path)
    end
end

#register_loaded_featuresvoid

This method returns an undefined value.

Registers the file information for all loaded features



57
58
59
60
61
62
# File 'lib/autorespawn/program_id.rb', line 57

def register_loaded_features
    loaded_features = $LOADED_FEATURES.map do |file|
        Pathname.new(file)
    end
    register_files(loaded_features)
end

#resolve_file_list(files, search_path = ruby_load_path, ignore_not_found: true) ⇒ Object

Resolve a file list into absolute paths



65
66
67
68
69
70
71
72
# File 'lib/autorespawn/program_id.rb', line 65

def resolve_file_list(files, search_path = ruby_load_path, ignore_not_found: true)
    files.map do |path|
        begin resolve_file_path(path, search_path)
        rescue FileNotFound
            raise if !ignore_not_found
        end
    end.compact
end

#resolve_file_path(path, search_path = Array.new) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Given a path that may be relative, computes the full path to the corresponding file

Parameters:

  • path (Pathname)

    the file path

  • search_path (Array<Pathname>) (defaults to: Array.new)

    the search path to use to resolve relative paths

Raises:

  • FileNotFound when a relative path cannot be resolved into a global one



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/autorespawn/program_id.rb', line 176

def resolve_file_path(path, search_path = Array.new)
    if !path.absolute?
        search_path.each do |search_p|
            full = search_p + path
            if full.exist?
                return full
            end
        end
        raise FileNotFound.new(path, search_path), "cannot find #{path} in #{search_path.join(", ")}"
    elsif !path.exist?
        raise FileNotFound.new(path, []), "#{path} does not exist"
    else
        return path
    end
end

#ruby_load_pathObject

The ruby load path

Parameters:

  • (Array<Pathname>)


195
196
197
# File 'lib/autorespawn/program_id.rb', line 195

def ruby_load_path
    $LOAD_PATH.map { |p| Pathname.new(p) }
end

#slice(files, search_path = ruby_load_path, ignore_not_found: true) ⇒ Object

Removes any file in self that is not in the given file list and returns the result



91
92
93
94
95
96
97
# File 'lib/autorespawn/program_id.rb', line 91

def slice(files, search_path = ruby_load_path, ignore_not_found: true)
    result = dup
    files = resolve_file_list(files, search_path, ignore_not_found: ignore_not_found).
        to_set
    result.files.delete_if { |k, _| !files.include?(k) }
    result
end