class Ghost::TokenizedFile

TODO: make it not necessarily line-based tokenization TODO: make it delegate or inherit from File/IO/StringIO to allow it to be a

drop-in to things expecting an IO.
  - Allow consumer to manipulate a real IO, and sync the contents
    into the real file between the tokens?

TODO: make this it’s own gem/library. This has nothing to do (specifically)

with hosts file management

Attributes

end_token[RW]
path[RW]
start_token[RW]

Public Class Methods

new(path, start_token, end_token) click to toggle source
# File lib/ghost/tokenized_file.rb, line 12
def initialize(path, start_token, end_token)
  self.path        = path
  self.start_token = start_token
  self.end_token   = end_token
end

Public Instance Methods

read() click to toggle source
# File lib/ghost/tokenized_file.rb, line 18
def read
  read_capturing
end
write(content) click to toggle source
# File lib/ghost/tokenized_file.rb, line 22
def write(content)
  existing_lines = []

  # TODO: how to do this without closing the file so
  #       we can reopen with write mode and maintain a
  #       lock
  read_capturing { |line| existing_lines << line}

  # TODO: lock file
  File.open(path, 'w') do |file|
    file.puts(existing_lines)

    unless content.nil? || content.empty?
      file.puts(start_token)
      file.puts(content)
      file.puts(end_token)
    end
  end
end

Private Instance Methods

read_capturing() { |line| ... } click to toggle source
# File lib/ghost/tokenized_file.rb, line 44
def read_capturing
  between_tokens = false
  lines = []

  File.open(path, 'r') do |file|
    file.each_line do |line|
      if line =~ /^#{start_token}\s*$/
        between_tokens = true
      elsif line =~ /^#{end_token}\s*$/
        between_tokens = false
      elsif between_tokens
        lines << line
      else
        yield(line) if block_given?
      end
    end
  end

  lines.join
end