class VirtualTree

Attributes

commits[R]
files[R]
issues[R]
path[R]
previous_tree_id[R]
tree_id[R]
trees[R]

Public Class Methods

from_json(tree_json) click to toggle source
# File lib/virtual_tree.rb, line 24
def self.from_json(tree_json)
  new_tree = VirtualTree.new({path: tree_json["path"]}, {})
  new_tree.instance_variable_set(:@commits, tree_json["commits"])
  new_tree.instance_variable_set(:@issues, tree_json["issues"])
  new_tree.instance_variable_set(:@tree_id, tree_json["tree_id"])
  new_tree.instance_variable_set(:@previous_tree_id, tree_json["previous_tree_id"])
  new_tree
end
new(diff_tree, commit) click to toggle source
# File lib/virtual_tree.rb, line 14
def initialize(diff_tree, commit)
  @path = diff_tree[:path]
  @tree_id = nil
  @previous_tree_id = nil
  @commits = []
  @issues = []
  @files = {}
  @trees = {}
end

Public Instance Methods

add_tree(tree) click to toggle source
# File lib/virtual_tree.rb, line 117
def add_tree(tree)
  tree_name = tree_name(tree.path)
  subtree = subtree(tree.path)
  if subtree.path == tree.path
    Loggr.instance.warn("Cannot add pre-existing tree: #{tree.path}")
  else
    subtree.trees[tree_name] = tree
  end
end
all_files() click to toggle source
# File lib/virtual_tree.rb, line 74
def all_files()
  @trees
    .values
    .flat_map { |tree| tree.all_files() }
    .concat(@files.values)
end
as_json() click to toggle source
# File lib/virtual_tree.rb, line 127
def as_json()
  stats = @files
    .values
    .reduce(new_context()) do |acc, file|
      acc[:business_value] += file.business_value
      acc[:lines] += file.lines.count
      acc[:covered_lines] += file.covered_lines
      acc[:uncovered_lines] += file.uncovered_lines
      acc[:buggy_lines] += file.buggy_lines_total
      acc[:changes] += file.revisions_total
      acc[:errors] += file.errors_total
      acc
    end

  {
    path: @path,
    tree_id: @tree_id,
    previous_tree_id: @previous_tree_id,
    issues: @issues,
    commits: @commits,
    files: @files.values.map(&method(:file_json))
  }.merge(stats)
end
delete_file(file_path) click to toggle source
# File lib/virtual_tree.rb, line 41
def delete_file(file_path)
  file_subtree(file_path)
    .files
    .delete(file_path)
end
get_file(file_path) click to toggle source
# File lib/virtual_tree.rb, line 33
def get_file(file_path)
  file_subtree(file_path).files[file_path]
end
move_file(a_file_name, b_file_name) click to toggle source
# File lib/virtual_tree.rb, line 47
def move_file(a_file_name, b_file_name)
  file = get_file(a_file_name)
  delete_file(a_file_name)
  set_file(b_file_name, file)
end
prune(diff_tree, commit) click to toggle source
# File lib/virtual_tree.rb, line 65
def prune(diff_tree, commit)
  return if diff_tree[:operation] != :delete

  tree_name = tree_name(diff_tree[:path])
  subtree(file_tree_path(diff_tree[:path]))
    .trees
    .delete(tree_name)
end
save(commit) click to toggle source

TODO: Figure out how to save only when something changes.

# File lib/virtual_tree.rb, line 82
def save(commit)
  trees_json = @trees
    .values
    .map { |tree| tree.save(commit) }

  json = trees_json
    .reduce(as_json()) do |acc, tree_json|
      [
          :lines,
          :covered_lines,
          :uncovered_lines,
          :changes,
          :errors,
          :buggy_lines,
          :business_value
        ].each do |key|
          acc[key] += tree_json[key]
        end

      acc
    end

  relevant_lines = json[:covered_lines] + json[:uncovered_lines]
  json[:coverage_percent] = relevant_lines > 0 ?
    (json[:covered_lines] / relevant_lines.to_f * 100).round :
    0

  json[:trees] = trees_json.map(&method(:slim_tree_json))

  tree_id = @tree_id.present? ? @tree_id : commit.id
  Cache.write_object(tree_id, json)

  json
end
set_file(file_path, file) click to toggle source
# File lib/virtual_tree.rb, line 37
def set_file(file_path, file)
  file_subtree(file_path).files[file_path] = file
end
touch(diff_tree, commit) click to toggle source

TODO: What happens when a tree moves??

# File lib/virtual_tree.rb, line 54
def touch(diff_tree, commit)
  if @path == diff_tree[:path]
    @previous_tree_id = diff_tree[:a_tree_id]
    @tree_id = diff_tree[:b_tree_id]
    @commits << commit.id
    @issues << commit.issue_id if commit.issue_id.present?
  else
    find_or_create_subtree!(diff_tree, commit).touch(diff_tree, commit)
  end
end

Private Instance Methods

file_json(file) click to toggle source
# File lib/virtual_tree.rb, line 206
def file_json(file)
  {
    path: file.path,
    file_id: file.file_id,
    commits: file.commits.length,
    issues: file.issues.length,
    business_value: file.business_value,
    lines: file.lines.count,
    changes: file.revisions_total,
    errors: file.errors_total,
    buggy_lines: file.buggy_lines_total,
    covered_lines: file.covered_lines,
    uncovered_lines: file.uncovered_lines
  }
end
file_subtree(file_path) click to toggle source
# File lib/virtual_tree.rb, line 175
def file_subtree(file_path)
  subtree(file_tree_path(file_path))
end
file_tree_path(file_path) click to toggle source
# File lib/virtual_tree.rb, line 163
def file_tree_path(file_path)
  file_path
    .split(File::SEPARATOR)[0..-2]
    .join(File::SEPARATOR)
end
find_or_create_subtree!(diff_tree, commit) click to toggle source
# File lib/virtual_tree.rb, line 179
def find_or_create_subtree!(diff_tree, commit)
  subtree = subtree(diff_tree[:path])
  if subtree.path != diff_tree[:path]
    subtree_path = diff_tree[:path]
      .split(File::SEPARATOR)
      .last
    subtree.trees[subtree_path] = subtree = VirtualTree.new(diff_tree, commit)
  end
  subtree
end
new_context() click to toggle source
# File lib/virtual_tree.rb, line 222
def new_context()
  {
    business_value: 0,
    lines: 0,
    changes: 0,
    errors: 0,
    buggy_lines: 0,
    covered_lines: 0,
    uncovered_lines: 0
  }
end
slim_tree_json(tree_json) click to toggle source
# File lib/virtual_tree.rb, line 190
def slim_tree_json(tree_json)
  {
    path: tree_json[:path],
    tree_id: tree_json[:tree_id],
    commits: tree_json[:commits].length,
    issues: tree_json[:commits].length,
    business_value: tree_json[:business_value],
    lines: tree_json[:lines],
    changes: tree_json[:changes],
    errors: tree_json[:errors],
    buggy_lines: tree_json[:buggy_lines],
    covered_lines: tree_json[:covered_lines],
    uncovered_lines: tree_json[:uncovered_lines]
  }
end
subtree(path) click to toggle source
# File lib/virtual_tree.rb, line 153
def subtree(path)
  dirs = path.split(File::SEPARATOR)
  subtree = self
  while dirs.length > 0
    path = dirs.shift()
    subtree = subtree.trees[path] if subtree.trees.has_key?(path)
  end
  subtree
end
tree_name(tree_path) click to toggle source
# File lib/virtual_tree.rb, line 169
def tree_name(tree_path)
  tree_path
    .split(File::SEPARATOR)
    .last
end