class RokuBuilder::Analyzer

Collects information on a package for submission

Public Class Methods

commands() click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 9
def self.commands
  {
    analyze: {source: true, stage: true},
  }
end
dependencies() click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 29
def self.dependencies
  [Loader]
end
parse_options(parser:, options:) click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 15
def self.parse_options(parser:, options:)
  parser.separator "Commands:"
  parser.on("--analyze", "Run a static analysis on a given stage") do
    options[:analyze] = true
  end
  parser.separator "Options:"
  parser.on("--inclide-libraries", "Include libraries in analyze") do
    options[:include_libraries] = true
  end
  parser.on("--sca-precommand COMMAND", "Include libraries in analyze") do |command|
    options[:sca_precommand] = command
  end
end

Public Instance Methods

analyze(options:, quiet: false) click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 33
def analyze(options:, quiet: false)
  @options = options
  @warnings = []
  @sca_warning = {}
  performance_config = get_config("performance_config.json")
  linter_config = get_config(".roku_builder_linter.json", true)
  linter_config ||= {is_ssai: false}
  loader = Loader.new(config: @config)
  Dir.mktmpdir do |dir|
    loader.copy(options: options, path: dir)
    run_sca_tool(path: dir, ssai: linter_config[:is_ssai])
    libraries = @config.project[:libraries]
    libraries ||= []
    Dir.glob(File.join(dir, "**", "*")).each do |file_path|
      file = file_path.dup; file.slice!(dir)
      unless libraries.any_is_start?(file) and not @options[:include_libraries]
        if File.file?(file_path) and file_path.end_with?(".brs", ".xml")
          line_inspector_config = []
          line_inspector_config = performance_config unless linter_config[:skip_performance]
          line_inspector_config += linter_config[:rules] if linter_config[:rules]
          line_inspector = LineInspector.new(inspector_config: line_inspector_config, indent_config: linter_config[:indentation])
          @warnings.concat(line_inspector.run(file_path))
        end
      end
    end
    format_messages(dir)
    print_warnings unless quiet
  end
  @warnings
end

Private Instance Methods

add_warning?(ssai) click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 97
def add_warning?(ssai)
  if @sca_warning and @sca_warning[:severity]
    if ssai and /SetAdUrl\(\) method is missing/.match(@sca_warning[:message])
      return false
    end
    libraries = @config.project[:libraries]
    libraries ||= []
    if @sca_warning[:path] and libraries.any_is_start?(@sca_warning[:path].gsub(/pkg:/, "")) and not @options[:include_libraries]
      return false
    end
    return true
  end
  return false
end
format_messages(dir) click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 141
def format_messages(dir)
  @warnings.each do |warning|
    if warning[:path]
      warning[:path].slice!(dir) if dir
      warning[:path].slice!(/^\//)
      warning[:message] += ". pkg:/"+warning[:path]
      warning[:message] += ":"+(warning[:line]+1).to_s if warning[:line]
    end
  end
end
get_config(file, project_root=false) click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 112
def get_config(file, project_root=false)
  if project_root
    file = File.join(@config.root_dir, file)
  else
    file = File.join(File.dirname(__FILE__), file)
  end
  JSON.parse(File.open(file).read, {symbolize_names: true}) if File.exist? file
end
print_warnings() click to toggle source
process_sca_results(results, ssai) click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 79
def process_sca_results(results, ssai)
  results.each do |result_line|
    if /-----+/.match(result_line) or /\*\*\*\*\*+/.match(result_line)
      @warnings.push(@sca_warning) if add_warning?(ssai)
      @sca_warning = {}
    elsif data = /^(\[WARNING\]|\[INFO\]|\[ERROR\])(.*)$/.match(result_line)
      @warnings.push(@sca_warning) if add_warning?(ssai)
      @sca_warning = {}
      @sca_warning[:severity] = data[1].gsub(/(\[|\])/, "").downcase
      @sca_warning[:message] = data[2]
    elsif data = /^\sPath: ([^ ]*) Line: (\d*)./.match(result_line)
      @sca_warning[:path] = data[1]+":"+data[2]
    elsif @sca_warning and  @sca_warning[:message]
      @sca_warning[:message] += " " + result_line
    end
  end
end
run_sca_tool(path:, ssai:) click to toggle source
# File lib/roku_builder/plugins/analyzer.rb, line 66
def run_sca_tool(path:, ssai:)
  if OS.unix?
    command = File.join(File.dirname(__FILE__), "sca-cmd", "bin", "sca-cmd")
    stderr = "/dev/null"
  else
    command = File.join(File.dirname(__FILE__), "sca-cmd", "bin", "sca-cmd.bat")
    stderr = "nul"
  end
  @logger.debug("Command: '#{command}'")
  results = `#{command} #{path} 2>#{stderr}`.split("\n")
  process_sca_results(results, ssai)
end