Class: Bow::Locker

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

Constant Summary collapse

SEPARATOR =
";\t".freeze
LINE_SEP =
"\n".freeze
NOT_FOUND =
:not_found

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeLocker

Returns a new instance of Locker.



26
27
28
29
30
31
# File 'lib/bow/locker.rb', line 26

def initialize
  @file_path = self.class.file_path || Config.guest[:history]
  @modified = false
  @file_opened = false
  @runtime_cache = {}
end

Class Attribute Details

.file_pathObject

Returns the value of attribute file_path.



9
10
11
# File 'lib/bow/locker.rb', line 9

def file_path
  @file_path
end

Instance Attribute Details

#runtime_cacheObject

Returns the value of attribute runtime_cache.



24
25
26
# File 'lib/bow/locker.rb', line 24

def runtime_cache
  @runtime_cache
end

Class Method Details

.loadObject



11
12
13
# File 'lib/bow/locker.rb', line 11

def load
  @instance ||= new
end

.load!Object



15
16
17
# File 'lib/bow/locker.rb', line 15

def load!
  @instance = new
end

Instance Method Details

#add(task, applied = false, reverted = false) ⇒ Object

rubocop:enable Style/PerlBackrefs rubocop:enable Metrics/MethodLength



121
122
123
124
125
126
# File 'lib/bow/locker.rb', line 121

def add(task, applied = false, reverted = false)
  reset(task)
  file.seek(0, IO::SEEK_END)
  write(task, applied, reverted)
  self
end

#applied?(task) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
36
# File 'lib/bow/locker.rb', line 33

def applied?(task)
  record = parse(find(task))
  !!(record && record[1])
end

#apply(task) ⇒ Object



43
44
45
46
# File 'lib/bow/locker.rb', line 43

def apply(task)
  return if applied?(task)
  add(task, true, reverted?(task))
end

#compactObject



147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/bow/locker.rb', line 147

def compact
  compressed = ''
  file.each do |l|
    compressed << l unless l[0] == ' '
  end
  file.rewind
  file.write(compressed)
  file.truncate(compressed.size)
  @runtime_cache = {}
  @modified = true
  self
end

#empty!Object



160
161
162
163
164
# File 'lib/bow/locker.rb', line 160

def empty!
  file.rewind
  file.truncate(0)
  @runtime_cache = {}
end

#ensure_file(name) ⇒ Object



174
175
176
177
178
# File 'lib/bow/locker.rb', line 174

def ensure_file(name)
  return if File.exist?(name)
  FileUtils.mkdir_p(File.dirname(name))
  FileUtils.touch(name)
end

#fileObject



166
167
168
169
170
171
172
# File 'lib/bow/locker.rb', line 166

def file
  return @file if @file && @file_opened
  ensure_file(@file_path)
  @file = File.open(@file_path, 'r+')
  @file_opened = true
  file
end

#find(task) ⇒ Object



75
76
77
78
79
80
# File 'lib/bow/locker.rb', line 75

def find(task)
  cached = from_cache(task)
  return cached if cached
  result = pure_find(task)
  result
end

#flushObject



139
140
141
142
143
144
145
# File 'lib/bow/locker.rb', line 139

def flush
  return unless @modified && @file_opened
  file.close
  @file_opened = false
  @modified = false
  self
end

#from_cache(task) ⇒ Object



82
83
84
# File 'lib/bow/locker.rb', line 82

def from_cache(task)
  @runtime_cache[task]
end

#parse(meta) ⇒ Object



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

def parse(meta)
  return false if meta[:record] == NOT_FOUND
  record = meta[:record].split(SEPARATOR)
  record.map do |v|
    v.strip!
    case v
    when 'true' then true
    when 'false' then false
    else v
    end
  end
end

#pure_find(task) ⇒ Object

rubocop:disable Metrics/MethodLength rubocop:disable Style/PerlBackrefs



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/bow/locker.rb', line 96

def pure_find(task)
  file.rewind
  current_line = ''
  first_c = 0
  last_c = 0
  file.each_char.with_index do |c, idx|
    if c == LINE_SEP
      current_line =~ /^([^\s]+)#{SEPARATOR}/
      to_cache(task, record: $1, first_c: first_c, last_c: last_c)
      if task == $1
        return { record: current_line, first_c: first_c, last_c: last_c }
      end
      current_line = ''
      first_c = idx + 1
      last_c = first_c
    else
      current_line << c
      last_c = idx
    end
  end
  { record: NOT_FOUND, first_c: nil, last_c: nil }
end

#reset(task) ⇒ Object



66
67
68
69
70
71
72
73
# File 'lib/bow/locker.rb', line 66

def reset(task)
  meta = find(task)
  reset_cache(task)
  return if meta[:record] == NOT_FOUND
  file.seek(meta[:first_c], IO::SEEK_SET)
  str_len = meta[:last_c] - meta[:first_c] + 1
  file.write ' ' * str_len
end

#reset_cache(task) ⇒ Object



90
91
92
# File 'lib/bow/locker.rb', line 90

def reset_cache(task)
  @runtime_cache[task] = nil
end

#revert(task) ⇒ Object



48
49
50
51
# File 'lib/bow/locker.rb', line 48

def revert(task)
  return if reverted?(task)
  add(task, applied?(task), true)
end

#reverted?(task) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
# File 'lib/bow/locker.rb', line 38

def reverted?(task)
  record = parse(find(task))
  !!(record && record[2])
end

#to_cache(task, result) ⇒ Object



86
87
88
# File 'lib/bow/locker.rb', line 86

def to_cache(task, result)
  @runtime_cache[task] = result
end

#write(task, applied = false, reverted = false) ⇒ Object



128
129
130
131
132
133
134
135
136
137
# File 'lib/bow/locker.rb', line 128

def write(task, applied = false, reverted = false)
  reset_cache(task)
  record = [task, applied, reverted].join(SEPARATOR)
  first_c = file.tell
  file.puts(record)
  last_c = first_c + record.size - 1
  to_cache(task, record: record, first_c: first_c, last_c: last_c)
  @modified = true
  self
end