class RokuBuilder::Monitor

Monitor development Logs

Public Class Methods

commands() click to toggle source
# File lib/roku_builder/plugins/monitor.rb, line 9
def self.commands
  { monitor: {device: true}}
end
parse_options(parser:, options:) click to toggle source
# File lib/roku_builder/plugins/monitor.rb, line 13
def self.parse_options(parser:, options:)
  parser.separator "Commands:"
  parser.on("-m", "--monitor [TYPE]", "Run telnet to monitor roku log") do |m|
    options[:monitor] = m || "main"
  end
  parser.separator "Options:"
  parser.on("-R", "--regexp REGEXP", "A regular expression used to filter monitor logs") do |r|
    options[:regexp] = r
  end
end

Public Instance Methods

init() click to toggle source

Initialize port config

# File lib/roku_builder/plugins/monitor.rb, line 25
def init()
  @ports = {
    main: 8085,
    profiler: 8080,
  }
  @show_prompt = false
end
monitor(options:) click to toggle source

Monitor a development log on the Roku device

# File lib/roku_builder/plugins/monitor.rb, line 34
def monitor(options:)
  type = options[:monitor].to_sym
  telnet_config = { 'Host' => @roku_ip_address, 'Port' => @ports[type] }
  waitfor_config = { 'Match' => /./, 'Timeout' => false }

  thread = Thread.new(telnet_config, waitfor_config) {|telnet,waitfor|
    @logger.info "Monitoring #{type} console(#{telnet['Port']}) on #{telnet['Host'] }"
    connection = Net::Telnet.new(telnet)
    Thread.current[:connection] = connection
    all_text = ""
    while true
      connection.waitfor(waitfor) do |txt|
        all_text = manage_text(all_text: all_text, txt: txt, regexp: options[:regexp])
      end
    end
  }
  thread.abort_on_exception = true

  init_readline()

  run_prompt(thread: thread)
end

Private Instance Methods

init_readline() click to toggle source

Setup tab completeion for Readline

# File lib/roku_builder/plugins/monitor.rb, line 60
def init_readline
  libedit = false
  begin
    Readline.vi_editing_mode
  rescue NotImplementedError
    libedit = true
  end

  commands = [
    "bsc", "bscs", "brkd", "bt", "c", "classes", "cont", "cont", "down", "d",
    "exit", "gc", "help", "l", "last", "list", "n", "next", "o", "print",
    "p", "?", "s", "stats", "step", "t", "th", "thread", "threads", "ths",
    "over", "out", "up", "u", "q", "v", "var"
  ].sort
  commands.collect { |i| i + ' '  } if libedit

  comp = proc { |s| commands.grep( /^#{Regexp.escape(s)}/  )  }

  Readline.completion_append_character = " "
  Readline.completion_proc = comp
end
manage_text(all_text:, txt:, regexp: nil) click to toggle source

Handle text from telnet

@param all_text [String] remaining partial line text
@param txt [String] current string from telnet
@param regexp [Regexp] regular expression to filter text on
@return [String] remaining partial line text
# File lib/roku_builder/plugins/monitor.rb, line 116
def manage_text(all_text:, txt:, regexp: nil)
  raise ExecutionError, "Connection Closed" unless txt
  if /connection is already in use/ =~ txt
    raise ExecutionError, "Connection is in use"
  end
  all_text += txt
  while line = all_text.slice!(/^.*\n/) do
    if !line.strip.empty?
      puts line if regexp.nil? or line.match(regexp)
    end
  end

  if all_text.downcase == "BrightScript Debugger> ".downcase
    @show_prompt = true
    all_text = ""
  else
    @show_prompt = false
  end
  all_text
end
run_prompt(thread:) click to toggle source

Check if needs to display prompt, displays prompt, and processes input

# File lib/roku_builder/plugins/monitor.rb, line 83
def run_prompt(thread:)
  running = true
  @logger.unknown "Q to exit"
  while running
    begin
      if @show_prompt
        prompt = 'BrightScript Debugger> '
      else
        prompt = ''
      end
      command = Readline.readline(prompt, true)
      if command =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == command
        Readline::HISTORY.pop
      end
      case command
      when "q"
        thread.exit
        running = false
      else
        thread[:connection].puts(command)
        sleep(0.1)
      end
    rescue SystemExit, Interrupt
      thread[:connection].puts("\C-c")
    end
  end
end