class Gem::Specification

def validate packaging = true

def validate packaging = true
  @warnings = 0
  require 'rubygems/user_interaction'
  extend Gem::UserInteraction
  normalize
  nil_attributes = self.class.non_nil_attributes.find_all do |attrname|
    instance_variable_get("@#{attrname}").nil?
  end
  unless nil_attributes.empty? then
    raise Gem::InvalidSpecificationException,
      "#{nil_attributes.join ', '} must not be nil"
  end
  if packaging and rubygems_version != Gem::VERSION then
    raise Gem::InvalidSpecificationException,
          "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
  end
  @@required_attributes.each do |symbol|
    unless self.send symbol then
      raise Gem::InvalidSpecificationException,
            "missing value for attribute #{symbol}"
    end
  end
  unless String === name then
    raise Gem::InvalidSpecificationException,
          "invalid value for attribute name: \"#{name.inspect}\""
  end
  if raw_require_paths.empty? then
    raise Gem::InvalidSpecificationException,
          'specification must have at least one require_path'
  end
  @files.delete_if            { |x| File.directory?(x) && !File.symlink?(x) }
  @test_files.delete_if       { |x| File.directory?(x) && !File.symlink?(x) }
  @executables.delete_if      { |x| File.directory?(File.join(@bindir, x)) }
  @extra_rdoc_files.delete_if { |x| File.directory?(x) && !File.symlink?(x) }
  @extensions.delete_if       { |x| File.directory?(x) && !File.symlink?(x) }
  non_files = files.reject { |x| File.file?(x) || File.symlink?(x) }
  unless not packaging or non_files.empty? then
    raise Gem::InvalidSpecificationException,
          "[\"#{non_files.join "\", \""}\"] are not files"
  end
  if files.include? file_name then
    raise Gem::InvalidSpecificationException,
          "#{full_name} contains itself (#{file_name}), check your files list"
  end
  unless specification_version.is_a?(Fixnum)
    raise Gem::InvalidSpecificationException,
          'specification_version must be a Fixnum (did you mean version?)'
  end
  case platform
  when Gem::Platform, Gem::Platform::RUBY then # ok
  else
    raise Gem::InvalidSpecificationException,
          "invalid platform #{platform.inspect}, see Gem::Platform"
  end
  self.class.array_attributes.each do |field|
    val = self.send field
    klass = case field
            when :dependencies
              Gem::Dependency
            else
              String
            end
    unless Array === val and val.all? { |x| x.kind_of?(klass) } then
      raise(Gem::InvalidSpecificationException,
            "#{field} must be an Array of #{klass}")
    end
  end
  [:authors].each do |field|
    val = self.send field
    raise Gem::InvalidSpecificationException, "#{field} may not be empty" if
      val.empty?
  end
  unless Hash === metadata
    raise Gem::InvalidSpecificationException,
            'metadata must be a hash'
  end
  metadata.keys.each do |k|
    if !k.kind_of?(String)
      raise Gem::InvalidSpecificationException,
              'metadata keys must be a String'
    end
    if k.size > 128
      raise Gem::InvalidSpecificationException,
              "metadata key too large (#{k.size} > 128)"
    end
  end
  metadata.values.each do |k|
    if !k.kind_of?(String)
      raise Gem::InvalidSpecificationException,
              'metadata values must be a String'
    end
    if k.size > 1024
      raise Gem::InvalidSpecificationException,
              "metadata value too large (#{k.size} > 1024)"
    end
  end
  licenses.each { |license|
    if license.length > 64
      raise Gem::InvalidSpecificationException,
        "each license must be 64 characters or less"
    end
    if !Gem::Licenses.match?(license)
      suggestions = Gem::Licenses.suggestions(license)
      message = <<-warning
cense value '#{license}' is invalid.  Use a license identifier from
tp://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
      warning
      message += "Did you mean #{suggestions.map { |s| "'#{s}'"}.join(', ')}?\n" unless suggestions.nil?
      warning(message)
    end
  }
  warning <<-warning if licenses.empty?
censes is empty, but is recommended.  Use a license identifier from
tp://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
  warning
  validate_permissions
  # reject lazy developers:
  lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '')
  unless authors.grep(/FI XME|TO DO/x).empty? then
    raise Gem::InvalidSpecificationException, "#{lazy} is not an author"
  end
  unless Array(email).grep(/FI XME|TO DO/x).empty? then
    raise Gem::InvalidSpecificationException, "#{lazy} is not an email"
  end
  if description =~ /FI XME|TO DO/x then
    raise Gem::InvalidSpecificationException, "#{lazy} is not a description"
  end
  if summary =~ /FI XME|TO DO/x then
    raise Gem::InvalidSpecificationException, "#{lazy} is not a summary"
  end
  if homepage and not homepage.empty? and
     homepage !~ /\A[a-z][a-z\d+.-]*:/i then
    raise Gem::InvalidSpecificationException,
          "\"#{homepage}\" is not a URI"
  end
  # Warnings
  %w[author email homepage summary].each do |attribute|
    value = self.send attribute
    warning "no #{attribute} specified" if value.nil? or value.empty?
  end
  if description == summary then
    warning 'description and summary are identical'
  end
  # TODO: raise at some given date
  warning "deprecated autorequire specified" if autorequire
  executables.each do |executable|
    executable_path = File.join(bindir, executable)
    shebang = File.read(executable_path, 2) == '#!'
    warning "#{executable_path} is missing #! line" unless shebang
  end
  files.each do |file|
    next unless File.symlink?(file)
    warning "#{file} is a symlink, which is not supported on all platforms"
  end
  validate_dependencies
  true
ensure
  if $! or @warnings > 0 then
    alert_warning "See http://guides.rubygems.org/specification-reference/ for help"
  end
end