Class
Constants
No documentation available
No documentation available
No documentation available
No documentation available
No documentation available
No documentation available
No documentation available
Attributes
Read & Write
If set to true, run packaging-specific checks, as well.
Class Methods
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 26
def initialize(specification)
@warnings = 0
@specification = specification
end
No documentation available
Instance Methods
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 46
def validate(strict = false)
validate_required!
validate_optional(strict) if packaging || strict
true
end
Does a sanity check on the specification.
Raises InvalidSpecificationException if the spec does not pass the checks.
It also performs some validations that do not raise but print warning messages instead.
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 340
def validate_array_attribute(field)
val = @specification.send(field)
klass = case field
when :dependencies then
Gem::Dependency
else
String
end
unless Array === val && val.all? {|x| x.is_a?(klass) || (field == :licenses && x.nil?) }
error "#{field} must be an Array of #{klass}"
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 334
def validate_array_attributes
Gem::Specification.array_attributes.each do |field|
validate_array_attribute(field)
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 463
def validate_attribute_present(attribute)
value = @specification.send attribute
warning("no #{attribute} specified") if value.nil? || value.empty?
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 354
def validate_authors_field
return unless @specification.authors.empty?
error "authors may not be empty"
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 409
def validate_lazy_metadata
unless @specification.authors.grep(LAZY_PATTERN).empty?
error "#{LAZY} is not an author"
end
unless Array(@specification.email).grep(LAZY_PATTERN).empty?
error "#{LAZY} is not an email"
end
if LAZY_PATTERN.match?(@specification.description)
error "#{LAZY} is not a description"
end
if LAZY_PATTERN.match?(@specification.summary)
error "#{LAZY} is not a summary"
end
homepage = @specification.homepage
# Make sure a homepage is valid HTTP/HTTPS URI
if homepage && !homepage.empty?
require "uri"
begin
homepage_uri = URI.parse(homepage)
unless [URI::HTTP, URI::HTTPS].member? homepage_uri.class
error "\"#{homepage}\" is not a valid HTTP URI"
end
rescue URI::InvalidURIError
error "\"#{homepage}\" is not a valid HTTP URI"
end
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 372
def validate_licenses
licenses = @specification.licenses
licenses.each do |license|
next if Gem::Licenses.match?(license) || license.nil?
license_id_deprecated = Gem::Licenses.deprecated_license_id?(license)
exception_id_deprecated = Gem::Licenses.deprecated_exception_id?(license)
suggestions = Gem::Licenses.suggestions(license)
if license_id_deprecated
main_message = "License identifier '#{license}' is deprecated"
elsif exception_id_deprecated
main_message = "Exception identifier at '#{license}' is deprecated"
else
main_message = "License identifier '#{license}' is invalid"
end
message = <<-WARNING
#{main_message}. Use an identifier from
https://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license,
or set it to nil if you don't want to specify a license.
WARNING
message += "Did you mean #{suggestions.map {|s| "'#{s}'" }.join(", ")}?\n" unless suggestions.nil?
warning(message)
end
warning <<-WARNING if licenses.empty?
licenses is empty, but is recommended. Use an license identifier from
https://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license,
or set it to nil if you don't want to specify a license.
WARNING
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 360
def validate_licenses_length
licenses = @specification.licenses
licenses.each do |license|
next if license.nil?
if license.length > 64
error "each license must be 64 characters or less"
end
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 124
def validate_metadata
metadata = @specification.metadata
unless Hash === metadata
error "metadata must be a hash"
end
metadata.each do |key, value|
entry = "metadata['#{key}']"
unless key.is_a?(String)
error "metadata keys must be a String"
end
if key.size > 128
error "metadata key is too large (#{key.size} > 128)"
end
unless value.is_a?(String)
error "#{entry} value must be a String"
end
if value.size > 1024
error "#{entry} value is too large (#{value.size} > 1024)"
end
next unless METADATA_LINK_KEYS.include? key
unless VALID_URI_PATTERN.match?(value)
error "#{entry} has invalid link: #{value.inspect}"
end
end
end
Implementation for Specification#validate_metadata
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 280
def validate_name
name = @specification.name
if !name.is_a?(String)
error "invalid value for attribute name: \"#{name.inspect}\" must be a string"
elsif !/[a-zA-Z]/.match?(name)
error "invalid value for attribute name: #{name.dump} must include at least one letter"
elsif !VALID_NAME_PATTERN.match?(name)
error "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
elsif SPECIAL_CHARACTERS.match?(name)
error "invalid value for attribute name: #{name.dump} can not begin with a period, dash, or underscore"
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 254
def validate_nil_attributes
nil_attributes = Gem::Specification.non_nil_attributes.select do |attrname|
@specification.instance_variable_get("@#{attrname}").nil?
end
return if nil_attributes.empty?
error "#{nil_attributes.join ", "} must not be nil"
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 300
def validate_non_files
return unless packaging
non_files = @specification.files.reject {|x| File.file?(x) || File.symlink?(x) }
unless non_files.empty?
error "[\"#{non_files.join "\", \""}\"] are not files"
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 97
def validate_optional(strict)
validate_licenses
validate_permissions
validate_values
validate_dependencies
validate_extensions
validate_removed_attributes
validate_unique_links
if @warnings > 0
if strict
error "specification has warnings"
else
alert_warning help_text
end
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 235
def validate_permissions
return if Gem.win_platform?
@specification.files.each do |file|
next unless File.file?(file)
next if File.stat(file).mode & 0o444 == 0o444
warning "#{file} is not world-readable"
end
@specification.executables.each do |name|
exec = File.join @specification.bindir, name
next unless File.file?(exec)
next if File.stat(exec).executable?
warning "#{exec} is not executable"
end
end
Issues a warning for each file to be packaged which is world-readable.
Implementation for Specification#validate_permissions
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 324
def validate_platform
platform = @specification.platform
case platform
when Gem::Platform, Gem::Platform::RUBY # ok
else
error "invalid platform #{platform.inspect}, see Gem::Platform"
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 294
def validate_require_paths
return unless @specification.raw_require_paths.empty?
error "specification must have at least one require_path"
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 63
def validate_required!
validate_nil_attributes
validate_rubygems_version
validate_required_attributes
validate_name
validate_require_paths
@specification.keep_only_files_and_directories
validate_non_files
validate_self_inclusion_in_files_list
validate_specification_version
validate_platform
validate_array_attributes
validate_authors_field
validate_metadata
validate_licenses_length
validate_lazy_metadata
validate_duplicate_dependencies
end
Does a sanity check on the specification.
Raises InvalidSpecificationException if the spec does not pass the checks.
Only runs checks that are considered necessary for the specification to be functional.
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 272
def validate_required_attributes
Gem::Specification.required_attributes.each do |symbol|
unless @specification.send symbol
error "missing value for attribute #{symbol}"
end
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 262
def validate_rubygems_version
return unless packaging
rubygems_version = @specification.rubygems_version
return if rubygems_version == Gem::VERSION
error "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 310
def validate_self_inclusion_in_files_list
file_name = @specification.file_name
return unless @specification.files.include?(file_name)
error "#{@specification.full_name} contains itself (#{file_name}), check your files list"
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 468
def validate_shebang_line_in(executable)
executable_path = File.join(@specification.bindir, executable)
return if File.read(executable_path, 2) == "#!"
warning "#{executable_path} is missing #! line"
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 318
def validate_specification_version
return if @specification.specification_version.is_a?(Integer)
error "specification_version must be an Integer (did you mean version?)"
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 507
def validate_unique_links
links = @specification.metadata.slice(*METADATA_LINK_KEYS)
grouped = links.group_by {|_key, uri| uri }
grouped.each do |uri, copies|
next unless copies.length > 1
keys = copies.map(&:first).join("\n ")
warning <<~WARNING
You have specified the uri:
#{uri}
for all of the following keys:
#{keys}
Only the first one will be shown on rubygems.org
WARNING
end
end
No documentation available
lib/rubygems/specification_policy.rb
View on GitHub
# File tmp/rubies/ruby-3.3.0/lib/rubygems/specification_policy.rb, line 442
def validate_values
%w[author homepage summary files].each do |attribute|
validate_attribute_present(attribute)
end
if @specification.description == @specification.summary
warning "description and summary are identical"
end
# TODO: raise at some given date
warning "deprecated autorequire specified" if @specification.autorequire
@specification.executables.each do |executable|
validate_shebang_line_in(executable)
end
@specification.files.select {|f| File.symlink?(f) }.each do |file|
warning "#{file} is a symlink, which is not supported on all platforms"
end
end
No documentation available