-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathdependency_comparator.rb
More file actions
110 lines (89 loc) · 3.34 KB
/
dependency_comparator.rb
File metadata and controls
110 lines (89 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# frozen_string_literal: true
require 'rubygems/comparator/base'
class Gem::Comparator
##
# Gem::Comparator::DependencyComparator can
# compare dependencies between gem's versions
# based on the given Gem::Specification objects
class DependencyComparator < Gem::Comparator::Base
##
# Compare dependencies in given +specs+ and
# write the changes to the +report+
#
# If +options[:param]+ is set, it compares only
# those dependencies
def compare(specs, report, options = {})
info 'Checking dependencies...'
filter_params(DEPENDENCY_PARAMS, options[:param]).each do |param|
all_same = true
type = param.gsub('_dependency', '').to_sym
specs.each_with_index do |s, index|
next if index == 0
prev_deps = specs[index-1].dependencies.select { |d| d.type == type }
curr_deps = specs[index].dependencies.select { |d| d.type == type }
added, deleted, updated = resolve_dependencies(prev_deps, curr_deps)
if (!deleted.empty? || !added.empty? || !updated.empty?)
all_same = false
end
ver = "#{specs[index-1].version}->#{specs[index].version}"
report[param][ver].section do
set_header "#{Rainbow(specs[index-1].version).cyan}->#{Rainbow(s.version).cyan}:"
nest('deleted').section do
set_header '* Deleted:'
puts deleted.map { |x| "#{x.name} #{x.requirements_list} (#{x.type})" } unless deleted.empty?
end
nest('added').section do
set_header '* Added:'
puts added.map { |x| "#{x.name} #{x.requirements_list} (#{x.type})" } unless added.empty?
end
nest('updated').section do
set_header '* Updated:'
puts updated unless updated.empty?
end
end
end
if all_same && options[:log_all]
report[param].set_header "#{same} #{type} dependencies:" if options[:log_all]
deps = specs[0].dependencies.select{ |d| d.type == type }.map{ |d| "#{d.name}: #{d.requirements_list}" }
deps = '[]' if deps.empty?
report[param] << deps
elsif !all_same
report[param].set_header "#{different} #{type} dependencies:"
end
end
report
end
private
##
# Find dependencies between +prev_deps+ and +curr_deps+
#
# Return [added, deleted, updated] deps
def resolve_dependencies(prev_deps, curr_deps)
added = curr_deps - prev_deps
deleted = prev_deps - curr_deps
split_dependencies(added, deleted)
end
##
# Find updated dependencies between +added+ and
# +deleted+ deps and move them out to +updated+.
#
# Return [added, deleted, updated] deps
def split_dependencies(added, deleted)
updated = []
added.dup.each do |ad|
deleted.dup.each do |dd|
if ad.name == dd.name
unless ad.requirements_list == dd.requirements_list
updated << "#{ad.name} " +
"from: #{dd.requirements_list} " +
"to: #{ad.requirements_list}"
end
added.delete ad
deleted.delete dd
end
end
end
[added, deleted, updated]
end
end
end