module Spoom::Coverage

Public Class Methods

report(snapshots, palette:, path: ".") click to toggle source
# File lib/spoom/coverage.rb, line 67
def self.report(snapshots, palette:, path: ".")
  intro_commit = Git.sorbet_intro_commit(path: path)
  intro_date = intro_commit ? Git.commit_time(intro_commit, path: path) : nil

  Report.new(
    project_name: File.basename(File.expand_path(path)),
    palette: palette,
    snapshots: snapshots,
    sigils_tree: sigils_tree(path: path),
    sorbet_intro_commit: intro_commit,
    sorbet_intro_date: intro_date,
  )
end
sigils_tree(path: ".") click to toggle source
# File lib/spoom/coverage.rb, line 87
def self.sigils_tree(path: ".")
  config = sorbet_config(path: path)
  files = Sorbet.srb_files(config, path: path)

  extensions = config.allowed_extensions
  extensions = [".rb"] if extensions.empty?
  extensions -= [".rbi"]

  pattern = /\.(#{Regexp.union(extensions.map { |ext| ext[1..-1] })})$/
  files.select! { |file| file =~ pattern }
  files.reject! { |file| file =~ %r{/test/} }

  FileTree.new(files, strip_prefix: path)
end
snapshot(path: '.', rbi: true, sorbet_bin: nil) click to toggle source
# File lib/spoom/coverage.rb, line 15
def self.snapshot(path: '.', rbi: true, sorbet_bin: nil)
  config = sorbet_config(path: path)
  config.allowed_extensions.push(".rb", ".rbi") if config.allowed_extensions.empty?

  new_config = config.copy
  new_config.allowed_extensions.reject! { |ext| !rbi && ext == ".rbi" }

  metrics = Spoom::Sorbet.srb_metrics(
    "--no-config",
    "--no-error-sections",
    "--no-error-count",
    "--isolate-error-code=0",
    new_config.options_string,
    path: path,
    capture_err: true,
    sorbet_bin: sorbet_bin
  )

  snapshot = Snapshot.new
  return snapshot unless metrics

  sha = Spoom::Git.last_commit(path: path)
  snapshot.commit_sha = sha
  snapshot.commit_timestamp = Spoom::Git.commit_timestamp(sha, path: path).to_i if sha

  snapshot.files = metrics.fetch("types.input.files", 0)
  snapshot.modules = metrics.fetch("types.input.modules.total", 0)
  snapshot.classes = metrics.fetch("types.input.classes.total", 0)
  snapshot.singleton_classes = metrics.fetch("types.input.singleton_classes.total", 0)
  snapshot.methods_with_sig = metrics.fetch("types.sig.count", 0)
  snapshot.methods_without_sig = metrics.fetch("types.input.methods.total", 0) - snapshot.methods_with_sig
  snapshot.calls_typed = metrics.fetch("types.input.sends.typed", 0)
  snapshot.calls_untyped = metrics.fetch("types.input.sends.total", 0) - snapshot.calls_typed

  snapshot.duration += metrics.fetch("run.utilization.system_time.us", 0)
  snapshot.duration += metrics.fetch("run.utilization.user_time.us", 0)

  Snapshot::STRICTNESSES.each do |strictness|
    next unless metrics.key?("types.input.files.sigil.#{strictness}")
    snapshot.sigils[strictness] = T.must(metrics["types.input.files.sigil.#{strictness}"])
  end

  snapshot.version_static = Spoom::Sorbet.version_from_gemfile_lock(gem: "sorbet-static", path: path)
  snapshot.version_runtime = Spoom::Sorbet.version_from_gemfile_lock(gem: "sorbet-runtime", path: path)

  files = Spoom::Sorbet.srb_files(new_config, path: path)
  snapshot.rbi_files = files.count { |file| file.end_with?(".rbi") }

  snapshot
end
sorbet_config(path: ".") click to toggle source
# File lib/spoom/coverage.rb, line 82
def self.sorbet_config(path: ".")
  Sorbet::Config.parse_file("#{path}/#{Spoom::Sorbet::CONFIG_PATH}")
end