Class: Gem::SpecificationPolicy

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/rubygems/specification_policy.rb

Constant Summary collapse

VALID_NAME_PATTERN =

:nodoc:

/\A[a-zA-Z0-9\.\-\_]+\z/
SPECIAL_CHARACTERS =

:nodoc:

/\A[#{Regexp.escape('.-_')}]+/
VALID_URI_PATTERN =

:nodoc:

%r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}
%w[
  bug_tracker_uri
  changelog_uri
  documentation_uri
  homepage_uri
  mailing_list_uri
  source_code_uri
  wiki_uri
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(specification) ⇒ SpecificationPolicy

:nodoc:


21
22
23
24
25
# File 'lib/rubygems/specification_policy.rb', line 21

def initialize(specification)
  @warnings = 0

  super(specification)
end

Instance Attribute Details

#packagingObject

If set to true, run packaging-specific checks, as well.


30
31
32
# File 'lib/rubygems/specification_policy.rb', line 30

def packaging
  @packaging
end

Instance Method Details

#validate(strict = false) ⇒ Object

Checks that the specification contains all required fields, and does a very basic sanity check.

Raises InvalidSpecificationException if the spec does not pass the checks.


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/rubygems/specification_policy.rb', line 39

def validate(strict = false)
  validate_nil_attributes

  validate_rubygems_version

  validate_required_attributes

  validate_name

  validate_require_paths

  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_licenses

  validate_permissions

  

  validate_values

  validate_dependencies

  if @warnings > 0
    if strict
      error "specification has warnings"
    else
      alert_warning help_text
    end
  end

  true
end

#validate_dependenciesObject

Implementation for Specification#validate_dependencies


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
167
168
169
170
171
172
173
174
# File 'lib/rubygems/specification_policy.rb', line 123

def validate_dependencies # :nodoc:
  # NOTE: see REFACTOR note in Gem::Dependency about types - this might be brittle
  seen = Gem::Dependency::TYPES.inject({}) { |types, type| types.merge({ type => {}}) }

  error_messages = []
  warning_messages = []
  dependencies.each do |dep|
    if prev = seen[dep.type][dep.name] then
      error_messages << "duplicate dependency on \#{dep}, (\#{prev.requirement}) use:\nadd_\#{dep.type}_dependency '\#{dep.name}', '\#{dep.requirement}', '\#{prev.requirement}'\n"
    end

    seen[dep.type][dep.name] = dep

    prerelease_dep = dep.requirements_list.any? do |req|
      Gem::Requirement.new(req).prerelease?
    end

    warning_messages << "prerelease dependency on #{dep} is not recommended" if
        prerelease_dep && !version.prerelease?

    open_ended = dep.requirement.requirements.all? do |op, version|
      not version.prerelease? and (op == '>' or op == '>=')
    end

    if open_ended then
      op, dep_version = dep.requirement.requirements.first

      base = dep_version.segments.first 2

      bugfix = if op == '>' then
                 ", '> #{dep_version}'"
               elsif op == '>=' and base != dep_version.segments then
                 ", '>= #{dep_version}'"
               end

      warning_messages << "open-ended dependency on \#{dep} is not recommended\nif \#{dep.name} is semantically versioned, use:\nadd_\#{dep.type}_dependency '\#{dep.name}', '~> \#{base.join '.'}'\#{bugfix}\n"
    end
  end
  if error_messages.any? then
    error error_messages.join
  end
  if warning_messages.any? then
    warning_messages.each { |warning_message| warning warning_message }
  end
end

#validate_metadataObject

Implementation for Specification#validate_metadata


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
# File 'lib/rubygems/specification_policy.rb', line 90

def 
  unless Hash ===  then
    error 'metadata must be a hash'
  end

  .each do |key, value|
    if !key.kind_of?(String) then
      error "metadata keys must be a String"
    end

    if key.size > 128 then
      error "metadata key too large (#{key.size} > 128)"
    end

    if !value.kind_of?(String) then
      error "metadata values must be a String"
    end

    if value.size > 1024 then
      error "metadata value too large (#{value.size} > 1024)"
    end

    if .include? key then
      if value !~ VALID_URI_PATTERN then
        error "metadata['#{key}'] has invalid link: #{value.inspect}"
      end
    end
  end
end

#validate_permissionsObject

Issues a warning for each file to be packaged which is world-readable.

Implementation for Specification#validate_permissions


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/rubygems/specification_policy.rb', line 181

def validate_permissions
  return if Gem.win_platform?

  files.each do |file|
    next unless File.file?(file)
    next if File.stat(file).mode & 0444 == 0444
    warning "#{file} is not world-readable"
  end

  executables.each do |name|
    exec = File.join bindir, name
    next unless File.file?(exec)
    next if File.stat(exec).executable?
    warning "#{exec} is not executable"
  end
end