PageRenderTime 24ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/ironruby/Lib/ruby/1.9.1/rubygems/validator.rb

https://bitbucket.org/cavelti/ea_launcher
Ruby | 246 lines | 173 code | 30 blank | 43 comment | 7 complexity | b7fb89fafe5c394204d82c4236c53082 MD5 | raw file
  1. #--
  2. # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
  3. # All rights reserved.
  4. # See LICENSE.txt for permissions.
  5. #++
  6. require 'find'
  7. require 'digest'
  8. require 'rubygems/format'
  9. require 'rubygems/installer'
  10. begin
  11. gem 'test-unit'
  12. rescue Gem::LoadError
  13. # Ignore - use the test-unit library that's part of the standard library
  14. end
  15. ##
  16. # Validator performs various gem file and gem database validation
  17. class Gem::Validator
  18. include Gem::UserInteraction
  19. ##
  20. # Given a gem file's contents, validates against its own MD5 checksum
  21. # gem_data:: [String] Contents of the gem file
  22. def verify_gem(gem_data)
  23. raise Gem::VerificationError, 'empty gem file' if gem_data.size == 0
  24. unless gem_data =~ /MD5SUM/ then
  25. return # Don't worry about it...this sucks. Need to fix MD5 stuff for
  26. # new format
  27. # FIXME
  28. end
  29. sum_data = gem_data.gsub(/MD5SUM = "([a-z0-9]+)"/,
  30. "MD5SUM = \"#{"F" * 32}\"")
  31. unless Digest::MD5.hexdigest(sum_data) == $1.to_s then
  32. raise Gem::VerificationError, 'invalid checksum for gem file'
  33. end
  34. end
  35. ##
  36. # Given the path to a gem file, validates against its own MD5 checksum
  37. #
  38. # gem_path:: [String] Path to gem file
  39. def verify_gem_file(gem_path)
  40. open gem_path, Gem.binary_mode do |file|
  41. gem_data = file.read
  42. verify_gem gem_data
  43. end
  44. rescue Errno::ENOENT, Errno::EINVAL
  45. raise Gem::VerificationError, "missing gem file #{gem_path}"
  46. end
  47. private
  48. def find_files_for_gem(gem_directory)
  49. installed_files = []
  50. Find.find gem_directory do |file_name|
  51. fn = file_name[gem_directory.size..file_name.size-1].sub(/^\//, "")
  52. installed_files << fn unless
  53. fn =~ /CVS/ || fn.empty? || File.directory?(file_name)
  54. end
  55. installed_files
  56. end
  57. public
  58. ErrorData = Struct.new :path, :problem
  59. ##
  60. # Checks the gem directory for the following potential
  61. # inconsistencies/problems:
  62. #
  63. # * Checksum gem itself
  64. # * For each file in each gem, check consistency of installed versions
  65. # * Check for files that aren't part of the gem but are in the gems directory
  66. # * 1 cache - 1 spec - 1 directory.
  67. #
  68. # returns a hash of ErrorData objects, keyed on the problem gem's name.
  69. def alien(gems=[])
  70. errors = Hash.new { |h,k| h[k] = {} }
  71. Gem::SourceIndex.from_installed_gems.each do |gem_name, gem_spec|
  72. next unless gems.include? gem_spec.name unless gems.empty?
  73. install_dir = gem_spec.installation_path
  74. gem_path = File.join install_dir, "cache", gem_spec.file_name
  75. spec_path = File.join install_dir, "specifications", gem_spec.spec_name
  76. gem_directory = gem_spec.full_gem_path
  77. unless File.directory? gem_directory then
  78. errors[gem_name][gem_spec.full_name] =
  79. "Gem registered but doesn't exist at #{gem_directory}"
  80. next
  81. end
  82. unless File.exist? spec_path then
  83. errors[gem_name][spec_path] = "Spec file missing for installed gem"
  84. end
  85. begin
  86. verify_gem_file(gem_path)
  87. good, gone, unreadable = nil, nil, nil, nil
  88. open gem_path, Gem.binary_mode do |file|
  89. format = Gem::Format.from_file_by_path(gem_path)
  90. good, gone = format.file_entries.partition { |entry, _|
  91. File.exist? File.join(gem_directory, entry['path'])
  92. }
  93. gone.map! { |entry, _| entry['path'] }
  94. gone.sort.each do |path|
  95. errors[gem_name][path] = "Missing file"
  96. end
  97. good, unreadable = good.partition { |entry, _|
  98. File.readable? File.join(gem_directory, entry['path'])
  99. }
  100. unreadable.map! { |entry, _| entry['path'] }
  101. unreadable.sort.each do |path|
  102. errors[gem_name][path] = "Unreadable file"
  103. end
  104. good.each do |entry, data|
  105. begin
  106. next unless data # HACK `gem check -a mkrf`
  107. open File.join(gem_directory, entry['path']), Gem.binary_mode do |f|
  108. unless Digest::MD5.hexdigest(f.read).to_s ==
  109. Digest::MD5.hexdigest(data).to_s then
  110. errors[gem_name][entry['path']] = "Modified from original"
  111. end
  112. end
  113. end
  114. end
  115. end
  116. installed_files = find_files_for_gem(gem_directory)
  117. good.map! { |entry, _| entry['path'] }
  118. extras = installed_files - good - unreadable
  119. extras.each do |extra|
  120. errors[gem_name][extra] = "Extra file"
  121. end
  122. rescue Gem::VerificationError => e
  123. errors[gem_name][gem_path] = e.message
  124. end
  125. end
  126. errors.each do |name, subhash|
  127. errors[name] = subhash.map { |path, msg| ErrorData.new(path, msg) }
  128. end
  129. errors
  130. end
  131. =begin
  132. if RUBY_VERSION < '1.9' then
  133. class TestRunner
  134. def initialize(suite, ui)
  135. @suite = suite
  136. @ui = ui
  137. end
  138. def self.run(suite, ui)
  139. require 'test/unit/ui/testrunnermediator'
  140. return new(suite, ui).start
  141. end
  142. def start
  143. @mediator = Test::Unit::UI::TestRunnerMediator.new(@suite)
  144. @mediator.add_listener(Test::Unit::TestResult::FAULT, &method(:add_fault))
  145. return @mediator.run_suite
  146. end
  147. def add_fault(fault)
  148. if Gem.configuration.verbose then
  149. @ui.say fault.long_display
  150. end
  151. end
  152. end
  153. autoload :TestRunner, 'test/unit/ui/testrunnerutilities'
  154. end
  155. =end
  156. ##
  157. # Runs unit tests for a given gem specification
  158. def unit_test(gem_spec)
  159. start_dir = Dir.pwd
  160. Dir.chdir(gem_spec.full_gem_path)
  161. $: << gem_spec.full_gem_path
  162. # XXX: why do we need this gem_spec when we've already got 'spec'?
  163. test_files = gem_spec.test_files
  164. if test_files.empty? then
  165. say "There are no unit tests to run for #{gem_spec.full_name}"
  166. return nil
  167. end
  168. gem gem_spec.name, "= #{gem_spec.version.version}"
  169. test_files.each do |f| require f end
  170. =begin
  171. if RUBY_VERSION < '1.9' then
  172. suite = Test::Unit::TestSuite.new("#{gem_spec.name}-#{gem_spec.version}")
  173. ObjectSpace.each_object(Class) do |klass|
  174. suite << klass.suite if (klass < Test::Unit::TestCase)
  175. end
  176. result = TestRunner.run suite, ui
  177. alert_error result.to_s unless result.passed?
  178. else
  179. result = MiniTest::Unit.new
  180. result.run
  181. end
  182. =end
  183. result = MiniTest::Unit.new
  184. result.run
  185. result
  186. ensure
  187. Dir.chdir(start_dir)
  188. end
  189. def remove_leading_dot_dir(path)
  190. path.sub(/^\.\//, "")
  191. end
  192. end