Skip to content

Instantly share code, notes, and snippets.

@dimitarvp
Last active December 17, 2015 03:09
Show Gist options
  • Save dimitarvp/5541709 to your computer and use it in GitHub Desktop.
Save dimitarvp/5541709 to your computer and use it in GitHub Desktop.
require 'awesome_print'
input = <<TEXT
2 1 app/assets/javascripts/bar.js
16 25 app/assets/javascripts/baz.js.coffee
1 1 app/assets/javascripts/foo.js.coffee
4 9 app/controllers/bar_controller.rb
3 2 app/controllers/baz_controller.rb
11 0 app/controllers/foo_controller.rb
3 2 db/schema.rb
41 1 lib/foobar.rb
12 7 lib/tasks/cache.rake
5 13 lib/tasks/import.rake
TEXT
# totals: add: 98, del: 61
expected =
[
{ name: "app",
add: 37,
del: 38,
children: [
{name: "assets", add: 19, del: 27, children: [
{name: "javascripts", add: 19, del: 27, children: [
{name: "bar.js", add: 2, del: 1},
{name: "baz.js.coffee", add: 16, del: 25},
{name: "foo.js.coffee", add: 1, del: 1}
]
},
]
},
{name: "controllers", add: 18, del: 11, children: [
{name: "bar_controller.rb", add: 4, del: 9},
{name: "baz_controller.rb", add: 3, del: 2},
{name: "foo_controller.rb", add: 11, del: 0},
]
},
]
},
{ add: 3,
del: 2,
name: "db",
children: [ {name: "schema.rb", add: 3, del: 2} ]
},
{ add: 58,
del: 21,
name: "lib",
children: [
{name: "foobar.rb", add: 41, del: 1},
{name: "tasks", add: 17, del: 20, children:
[ {name: "cache.rake", add: 12, del: 7},
{name: "import.rake", add: 5, del: 13} ] }
]
}
]
def git_diffnum_parse_paths(list, depth, out)
to = 1
base = list.first[:name][depth]
while list[to] and list[to][:name][depth] == base do
to += 1
end
if list.first[:name][depth+1]
out << {name: base, add: 0, del: 0, children: []}
# Common directory found for the first N records; recurse deeper.
puts "#{' '*depth}#{base} (0-#{to-1})"
git_diffnum_parse_paths(list[0..to-1], depth + 1, out.last[:children])
add = del = 0
out.last[:children].each do |x| add += x[:add].to_i; del += x[:del].to_i; end
out.last[:add] = add
out.last[:del] = del
else
# It's a file, we can't go any deeper.
#puts "#{' '*depth}#{base}"
puts list.first
out << {name: list.first[:name].last, add: list.first[:add].to_i, del: list.first[:del].to_i}
end
if list[to]
# Recurse in to try find common directories for the deeper records.
#puts "#{' '*depth}#{list[to][:name][depth]} (#{to}-#{list.size-1})"
git_diffnum_parse_paths(list[to..-1], depth, out)
end
nil
end
def to_git_diffnum_tree(txt)
items = txt.split("\n")
.map { |line| line.split }
.map { |line| {add: line[0].to_i, del: line[1].to_i, name: line[2].split('/') } }
.sort_by { |item| item[:name] }
out = []
git_diffnum_parse_paths(items, 0, out)
out
end
out = to_git_diffnum_tree(input)
puts; ap out; puts
puts; puts "Expected result:"; puts expected.inspect
puts; puts "Actual result: "; puts out.inspect
puts; puts "Are expected and actual results identical: #{expected == out}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment