Class: LibGems::Validator
- Inherits:
-
Object
- Object
- LibGems::Validator
- Includes:
- UserInteraction
- Defined in:
- lib/libgems/validator.rb
Overview
Validator performs various gem file and gem database validation
Defined Under Namespace
Classes: ErrorData, TestRunner
Instance Method Summary collapse
-
#alien(gems = []) ⇒ Object
Checks the gem directory for the following potential inconsistencies/problems:.
- #remove_leading_dot_dir(path) ⇒ Object
-
#unit_test(gem_spec) ⇒ Object
Runs unit tests for a given gem specification.
-
#verify_gem(gem_data) ⇒ Object
- Given a gem file’s contents, validates against its own MD5 checksum gem_data
- String
-
Contents of the gem file.
-
#verify_gem_file(gem_path) ⇒ Object
Given the path to a gem file, validates against its own MD5 checksum.
Methods included from UserInteraction
Methods included from DefaultUserInteraction
ui, #ui, ui=, #ui=, use_ui, #use_ui
Instance Method Details
#alien(gems = []) ⇒ Object
Checks the gem directory for the following potential inconsistencies/problems:
-
Checksum gem itself
-
For each file in each gem, check consistency of installed versions
-
Check for files that aren’t part of the gem but are in the gems directory
-
1 cache - 1 spec - 1 directory.
returns a hash of ErrorData objects, keyed on the problem gem’s name.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/libgems/validator.rb', line 88 def alien(gems=[]) errors = Hash.new { |h,k| h[k] = {} } LibGems::SourceIndex.from_installed_gems.each do |gem_name, gem_spec| next unless gems.include? gem_spec.name unless gems.empty? install_dir = gem_spec.installation_path gem_path = File.join install_dir, "cache", gem_spec.file_name spec_path = File.join install_dir, "specifications", gem_spec.spec_name gem_directory = gem_spec.full_gem_path unless File.directory? gem_directory then errors[gem_name][gem_spec.full_name] = "Gem registered but doesn't exist at #{gem_directory}" next end unless File.exist? spec_path then errors[gem_name][spec_path] = "Spec file missing for installed gem" end begin verify_gem_file(gem_path) good, gone, unreadable = nil, nil, nil, nil open gem_path, LibGems.binary_mode do |file| format = LibGems::Format.from_file_by_path(gem_path) good, gone = format.file_entries.partition { |entry, _| File.exist? File.join(gem_directory, entry['path']) } gone.map! { |entry, _| entry['path'] } gone.sort.each do |path| errors[gem_name][path] = "Missing file" end good, unreadable = good.partition { |entry, _| File.readable? File.join(gem_directory, entry['path']) } unreadable.map! { |entry, _| entry['path'] } unreadable.sort.each do |path| errors[gem_name][path] = "Unreadable file" end good.each do |entry, data| begin next unless data # HACK `gem check -a mkrf` open File.join(gem_directory, entry['path']), LibGems.binary_mode do |f| unless Digest::MD5.hexdigest(f.read).to_s == Digest::MD5.hexdigest(data).to_s then errors[gem_name][entry['path']] = "Modified from original" end end end end end installed_files = find_files_for_gem(gem_directory) good.map! { |entry, _| entry['path'] } extras = installed_files - good - unreadable extras.each do |extra| errors[gem_name][extra] = "Extra file" end rescue LibGems::VerificationError => e errors[gem_name][gem_path] = e. end end errors.each do |name, subhash| errors[name] = subhash.map { |path, msg| ErrorData.new(path, msg) } end errors end |
#remove_leading_dot_dir(path) ⇒ Object
235 236 237 |
# File 'lib/libgems/validator.rb', line 235 def remove_leading_dot_dir(path) path.sub(/^\.\//, "") end |
#unit_test(gem_spec) ⇒ Object
Runs unit tests for a given gem specification
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/libgems/validator.rb', line 199 def unit_test(gem_spec) start_dir = Dir.pwd Dir.chdir(gem_spec.full_gem_path) $: << gem_spec.full_gem_path # XXX: why do we need this gem_spec when we've already got 'spec'? test_files = gem_spec.test_files if test_files.empty? then say "There are no unit tests to run for #{gem_spec.full_name}" return nil end gem gem_spec.name, "= #{gem_spec.version.version}" test_files.each do |f| require f end if RUBY_VERSION < '1.9' then suite = Test::Unit::TestSuite.new("#{gem_spec.name}-#{gem_spec.version}") ObjectSpace.each_object(Class) do |klass| suite << klass.suite if (klass < Test::Unit::TestCase) end result = TestRunner.run suite, ui alert_error result.to_s unless result.passed? else result = MiniTest::Unit.new result.run end result ensure Dir.chdir(start_dir) end |
#verify_gem(gem_data) ⇒ Object
Given a gem file’s contents, validates against its own MD5 checksum
- gem_data
- String
-
Contents of the gem file
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/libgems/validator.rb', line 30 def verify_gem(gem_data) raise LibGems::VerificationError, 'empty gem file' if gem_data.size == 0 unless gem_data =~ /MD5SUM/ then return # Don't worry about it...this sucks. Need to fix MD5 stuff for # new format # FIXME end sum_data = gem_data.gsub(/MD5SUM = "([a-z0-9]+)"/, "MD5SUM = \"#{"F" * 32}\"") unless Digest::MD5.hexdigest(sum_data) == $1.to_s then raise LibGems::VerificationError, 'invalid checksum for gem file' end end |
#verify_gem_file(gem_path) ⇒ Object
Given the path to a gem file, validates against its own MD5 checksum
- gem_path
- String
-
Path to gem file
52 53 54 55 56 57 58 59 |
# File 'lib/libgems/validator.rb', line 52 def verify_gem_file(gem_path) open gem_path, LibGems.binary_mode do |file| gem_data = file.read verify_gem gem_data end rescue Errno::ENOENT, Errno::EINVAL raise LibGems::VerificationError, "missing gem file #{gem_path}" end |