class Gem::Comparator::FileListComparator
Gem::Comparator::FileListComparator
can compare file lists from gem's specs based on the given Gem::Package objects
To compare the files it needs to extract gem packages to +options+
Public Class Methods
new()
click to toggle source
# File lib/rubygems/comparator/file_list_comparator.rb, line 18 def initialize expect(:packages) # We need diff begin IO.popen('diff --version') rescue Exception error('Calling `diff` command failed. Do you have it installed?') end end
Public Instance Methods
compare(packages, report, options = {})
click to toggle source
Compare file lists for gem's Gem::Package objects in packages
and writes the changes to the report
If +options+ is set, it compares only that file list
# File lib/rubygems/comparator/file_list_comparator.rb, line 36 def compare(packages, report, options = {}) info 'Checking file lists...' @packages = packages # Check file lists from older versions to newer filter_params(SPEC_FILES_PARAMS, options[:param]).each do |param| all_same = true packages.each_with_index do |pkg, index| unpacked_gem_dirs[packages[index].spec.version] = extract_gem(pkg, options[:output]) next if index == 0 # File lists as arrays previous = value_from_spec(param, packages[index-1].spec) current = value_from_spec(param, pkg.spec) next unless (previous && current) vers = "#{packages[index-1].spec.version}->#{packages[index].spec.version}" deleted = previous - current added = current - previous same = current - added if options[:brief] deleted, dirs_added = dir_changed(previous, current) end report[param].set_header "#{different} #{param}:" report[param][vers].section do set_header "#{Rainbow(packages[index-1].spec.version).cyan}->" + "#{Rainbow(packages[index].spec.version).cyan}:" nest('deleted').section do set_header '* Deleted:' puts deleted unless deleted.empty? end nest('added').section do set_header '* Added:' puts dirs_added if options[:brief] end end # Add information about permissions, shebangs etc. report = check_added_files(param, vers, index, added, report, options[:brief]) report[param][vers]['changed'].set_header '* Changed:' report = check_same_files(param, vers, index, same, report, options[:brief]) same_files = report[param][vers]['changed'].messages.empty? all_same = false unless same_files if previous == current && same_files && !all_same report[param][vers] << "#{Rainbow(packages[index-1].spec.version).cyan}->" + \ "#{Rainbow(packages[index].spec.version).cyan}: No change" end end if all_same && options[:log_all] report[param].set_header "#{same} #{param}:" value = value_from_spec(param, @packages[0].spec) value = '[]' if value.empty? report[param] << value end end report end
Private Instance Methods
check_added_files(param, vers, index, files, report, brief_mode)
click to toggle source
# File lib/rubygems/comparator/file_list_comparator.rb, line 130 def check_added_files(param, vers, index, files, report, brief_mode) files.each do |file| added_file = File.join(unpacked_gem_dirs[@packages[index].spec.version], file) #line_changes = lines_changed(prev_file, curr_file) changes = Monitor.new_file_permissions(added_file), Monitor.new_file_executability(added_file), Monitor.new_file_shebang(added_file) if(!changes.join.empty? || !brief_mode) report[param][vers]['added'] << "#{file}" end changes.each do |change| report[param][vers]['added'] << change unless change.empty? end end report end
check_files(files)
click to toggle source
Check that files exist
# File lib/rubygems/comparator/file_list_comparator.rb, line 179 def check_files(files) files.each do |file| unless File.exist? file warn "#{file} mentioned in spec does not exist " + "in the gem package, skipping check" return false end end true end
check_same_files(param, vers, index, files, report, brief_mode)
click to toggle source
# File lib/rubygems/comparator/file_list_comparator.rb, line 151 def check_same_files(param, vers, index, files, report, brief_mode) files.each do |file| prev_file = File.join(unpacked_gem_dirs[@packages[index-1].spec.version], file) curr_file = File.join(unpacked_gem_dirs[@packages[index].spec.version], file) next unless check_files([prev_file, curr_file]) line_changes = Monitor.lines_changed(prev_file, curr_file) changes = Monitor.files_permissions_changes(prev_file, curr_file), Monitor.files_executability_changes(prev_file, curr_file), Monitor.files_shebang_changes(prev_file, curr_file) if(!changes.join.empty? || (!brief_mode && !line_changes.empty?)) report[param][vers]['changed'] << \ "#{file} #{line_changes}" end changes.each do |change| report[param][vers]['changed'] << change unless change.empty? end end report end
dir_changed(previous, current)
click to toggle source
This returns [deleted, added] directories between previous
and current
file lists
For top level (.) it compares files themselves
# File lib/rubygems/comparator/file_list_comparator.rb, line 122 def dir_changed(previous, current) prev_dirs = DirUtils.dirs_of_files(previous) curr_dirs = DirUtils.dirs_of_files(current) deleted = DirUtils.remove_subdirs(prev_dirs - curr_dirs) added = DirUtils.remove_subdirs(curr_dirs - prev_dirs) [deleted, added] end
unpacked_gem_dirs()
click to toggle source
Access @unpacked_gem_dirs hash that stores paths to the unpacked gem dirs
Keys of the hash are gem's versions
# File lib/rubygems/comparator/file_list_comparator.rb, line 112 def unpacked_gem_dirs @unpacked_gem_dirs ||= {} end