mail 2.4.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mail might be problematic. Click here for more details.

@@ -1,3 +1,13 @@
1
+ == Thu Jan 19 13:49:34 UTC 2012 Mikel Lindsaar <mikel@reinteractive.net>
2
+
3
+ * Fix non ascii character folding problems
4
+ * Handle multipart mail in Mail::Message#to_yaml / #from_yaml
5
+ * More warning fixes
6
+ * Normalize the Parse Error class and messages
7
+ * Fix for Mail::Encodings.unquote_and_convert not handling unquoted characters mixed in between quoted strings
8
+ * Updated treetop to latest version, specs now run approximately 25-30% faster!
9
+ * Version bump to 2.4.1 and gem release
10
+
1
11
  == Sun Jan 15 18:15:56 UTC 2011 Mikel Lindsaar <mikel@reinteractive.net>
2
12
 
3
13
  * Speed up reading of messages by about 12x
@@ -578,4 +588,4 @@ content-disposition or content-location
578
588
 
579
589
  == Sat Oct 25 13:38:01 UTC 2009 Mikel Lindsaar <raasdnil@gmail.com>
580
590
 
581
- * Birthday, Mail released as a gem... phew
591
+ * Birthday, Mail released as a gem... phew
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source :rubygems
3
3
  gem "activesupport", ">= 2.3.6"
4
4
  gem "tlsmail" if RUBY_VERSION <= '1.8.6'
5
5
  gem "mime-types", "~> 1.16"
6
- gem "treetop", "~> 1.4.8"
6
+ gem "treetop", "~> 1.4.10"
7
7
  gem "i18n", ">= 0.4.0"
8
8
 
9
9
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
@@ -2,11 +2,15 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  activesupport (3.0.6)
5
+ columnize (0.3.6)
5
6
  diff-lcs (1.1.3)
6
7
  i18n (0.5.0)
8
+ linecache (0.46)
9
+ rbx-require-relative (> 0.0.4)
7
10
  mime-types (1.16)
8
- polyglot (0.3.1)
11
+ polyglot (0.3.3)
9
12
  rake (0.9.2.2)
13
+ rbx-require-relative (0.0.5)
10
14
  rspec (2.8.0)
11
15
  rspec-core (~> 2.8.0)
12
16
  rspec-expectations (~> 2.8.0)
@@ -15,7 +19,13 @@ GEM
15
19
  rspec-expectations (2.8.0)
16
20
  diff-lcs (~> 1.1.2)
17
21
  rspec-mocks (2.8.0)
18
- treetop (1.4.9)
22
+ ruby-debug (0.10.4)
23
+ columnize (>= 0.1)
24
+ ruby-debug-base (~> 0.10.4.0)
25
+ ruby-debug-base (0.10.4)
26
+ linecache (>= 0.3)
27
+ treetop (1.4.10)
28
+ polyglot
19
29
  polyglot (>= 0.3.1)
20
30
 
21
31
  PLATFORMS
@@ -28,4 +38,5 @@ DEPENDENCIES
28
38
  mime-types (~> 1.16)
29
39
  rake (> 0.8.7)
30
40
  rspec (~> 2.8.0)
31
- treetop (~> 1.4.8)
41
+ ruby-debug
42
+ treetop (~> 1.4.10)
@@ -1,4 +1,4 @@
1
1
  major:2
2
2
  minor:4
3
- patch:0
3
+ patch:1
4
4
  build:
@@ -26,7 +26,7 @@ module Mail
26
26
  if tree = parser.parse(string)
27
27
  @address_nodes = tree.addresses
28
28
  else
29
- raise Mail::Field::ParseError, "AddressListsParser can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
29
+ raise Mail::Field::ParseError.new(AddressListsParser, string, parser.failure_reason)
30
30
  end
31
31
  end
32
32
 
@@ -71,4 +71,4 @@ module Mail
71
71
  end
72
72
  end
73
73
  end
74
- end
74
+ end
@@ -10,7 +10,7 @@ module Mail
10
10
  @disposition_type = tree.disposition_type.text_value.downcase
11
11
  @parameters = tree.parameters
12
12
  else
13
- raise Mail::Field::ParseError, "ContentDispositionElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
13
+ raise Mail::Field::ParseError.new(ContentDispositionElement, string, parser.failure_reason)
14
14
  end
15
15
  end
16
16
 
@@ -9,7 +9,7 @@ module Mail
9
9
  if tree = parser.parse(string)
10
10
  @location = tree.location.text_value
11
11
  else
12
- raise Mail::Field::ParseError, "ContentLocationElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
12
+ raise Mail::Field::ParseError.new(ContentLocationElement, string, parser.failure_reason)
13
13
  end
14
14
  end
15
15
 
@@ -12,7 +12,7 @@ module Mail
12
12
  when tree = parser.parse(string.to_s.downcase)
13
13
  @encoding = tree.encoding.text_value
14
14
  else
15
- raise Mail::Field::ParseError, "ContentTransferEncodingElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
15
+ raise Mail::Field::ParseError.new(ContentTransferEncodingElement, string, parser.failure_reason)
16
16
  end
17
17
  end
18
18
 
@@ -11,7 +11,7 @@ module Mail
11
11
  @sub_type = tree.sub_type.text_value.downcase
12
12
  @parameters = tree.parameters
13
13
  else
14
- raise Mail::Field::ParseError, "ContentTypeElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
14
+ raise Mail::Field::ParseError.new(ContentTypeElement, string, parser.failure_reason)
15
15
  end
16
16
  end
17
17
 
@@ -10,7 +10,7 @@ module Mail
10
10
  @date_string = tree.date.text_value
11
11
  @time_string = tree.time.text_value
12
12
  else
13
- raise Mail::Field::ParseError, "DateTimeElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
13
+ raise Mail::Field::ParseError.new(DateTimeElement, string, parser.failure_reason)
14
14
  end
15
15
  end
16
16
 
@@ -10,7 +10,7 @@ module Mail
10
10
  @address = tree.addr_spec.text_value.strip
11
11
  @date_time = ::DateTime.parse("#{tree.ctime_date.text_value}")
12
12
  else
13
- raise Mail::Field::ParseError, "EnvelopeFromElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
13
+ raise Mail::Field::ParseError.new(EnvelopeFromElement, string, parser.failure_reason)
14
14
  end
15
15
  end
16
16
 
@@ -9,7 +9,7 @@ module Mail
9
9
  if tree = parser.parse(string)
10
10
  @message_ids = tree.message_ids.map { |msg_id| clean_msg_id(msg_id.text_value) }
11
11
  else
12
- raise Mail::Field::ParseError, "MessageIdsElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
12
+ raise Mail::Field::ParseError.new(MessageIdsElement, string, parser.failure_reason)
13
13
  end
14
14
  end
15
15
 
@@ -26,4 +26,4 @@ module Mail
26
26
  end
27
27
 
28
28
  end
29
- end
29
+ end
@@ -10,7 +10,7 @@ module Mail
10
10
  @major = tree.major.text_value
11
11
  @minor = tree.minor.text_value
12
12
  else
13
- raise Mail::Field::ParseError, "MimeVersionElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
13
+ raise Mail::Field::ParseError.new(MimeVersionElement, string, parser.failure_reason)
14
14
  end
15
15
  end
16
16
 
@@ -9,7 +9,7 @@ module Mail
9
9
  if tree = parser.parse(string)
10
10
  @phrases = tree.phrases
11
11
  else
12
- raise Mail::Field::ParseError, "PhraseList can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
12
+ raise Mail::Field::ParseError.new(PhraseList, string, parser.failure_reason)
13
13
  end
14
14
  end
15
15
 
@@ -18,4 +18,4 @@ module Mail
18
18
  end
19
19
 
20
20
  end
21
- end
21
+ end
@@ -10,7 +10,7 @@ module Mail
10
10
  @date_time = ::DateTime.parse("#{tree.date_time.date.text_value} #{tree.date_time.time.text_value}")
11
11
  @info = tree.name_val_list.text_value
12
12
  else
13
- raise Mail::Field::ParseError, "ReceivedElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
13
+ raise Mail::Field::ParseError.new(ReceivedElement, string, parser.failure_reason)
14
14
  end
15
15
  end
16
16
 
@@ -126,20 +126,28 @@ module Mail
126
126
  # Join QP encoded-words that are adjacent to avoid decoding partial chars
127
127
  text.gsub!(/\?\=\=\?.+?\?[Qq]\?/m, '') if text =~ /\?==\?/
128
128
 
129
- # Separate encoded-words with a space, so we can treat them one by one
130
- text.gsub!(/\?\=\=\?/, '?= =?')
131
- text.split(/ /).map do |word|
132
- word.to_str.
133
- gsub( /=\?.+\?[Bb]\?.+\?=/m ) { |substr| b_value_decode(substr) }.
134
- gsub( /=\?.+\?[Qq]\?.+\?=/m ) { |substr| q_value_decode(substr) }
129
+ # Search for occurences of quoted strings or plain strings
130
+ text.scan(/( # Group around entire regex to include it in matches
131
+ \=\?[^?]+\?([QB])\?[^?]+?\?\= # Quoted String with subgroup for encoding method
132
+ | # or
133
+ .+?(?=\=\?) # Plain String
134
+ )/xmi).map do |matches|
135
+ string, method = *matches
136
+ if method == 'b' || method == 'B'
137
+ b_value_decode(string)
138
+ elsif method == 'q' || method == 'Q'
139
+ q_value_decode(string)
140
+ else
141
+ string
135
142
  end
143
+ end
136
144
  end
137
145
  end.join("")
138
146
  end
139
147
 
140
148
  # Takes an encoded string of the format =?<encoding>?[QB]?<string>?=
141
149
  def Encodings.unquote_and_convert_to(str, to_encoding)
142
- original_encoding, string = split_encoding_from_string( str )
150
+ original_encoding = split_encoding_from_string( str )
143
151
 
144
152
  output = value_decode( str ).to_s
145
153
 
@@ -253,7 +261,7 @@ module Mail
253
261
  def Encodings.split_encoding_from_string( str )
254
262
  match = str.match(/\=\?([^?]+)?\?[QB]\?(.+)?\?\=/mi)
255
263
  if match
256
- [match[1], match[2]]
264
+ match[1]
257
265
  else
258
266
  nil
259
267
  end
@@ -42,6 +42,14 @@ module Mail
42
42
  # Raised when a parsing error has occurred (ie, a StructuredField has tried
43
43
  # to parse a field that is invalid or improperly written)
44
44
  class ParseError < FieldError #:nodoc:
45
+ attr_accessor :element, :value, :reason
46
+
47
+ def initialize(element, value, reason)
48
+ @element = element
49
+ @value = value
50
+ @reason = reason
51
+ super("#{element} can not parse |#{value}|\nReason was: #{reason}")
52
+ end
45
53
  end
46
54
 
47
55
  # Raised when attempting to set a structured field's contents to an invalid syntax
@@ -47,7 +47,7 @@ module Mail
47
47
  end
48
48
 
49
49
  def address
50
- result = tree.addresses.first
50
+ tree.addresses.first
51
51
  end
52
52
 
53
53
  def encoded
@@ -48,7 +48,7 @@ module Mail
48
48
  end
49
49
 
50
50
  def address
51
- result = tree.addresses.first
51
+ tree.addresses.first
52
52
  end
53
53
 
54
54
  def encoded
@@ -18,9 +18,11 @@ module Mail
18
18
 
19
19
  include Mail::CommonField
20
20
  include Mail::Utilities
21
-
21
+
22
+ attr_accessor :charset
23
+ attr_reader :errors
24
+
22
25
  def initialize(name, value, charset = nil)
23
- self.charset = charset
24
26
  @errors = []
25
27
  if charset
26
28
  self.charset = charset
@@ -35,21 +37,9 @@ module Mail
35
37
  self.value = value
36
38
  self
37
39
  end
38
-
39
- def charset
40
- @charset
41
- end
42
-
43
- def charset=(val)
44
- @charset = val
45
- end
46
-
47
- def errors
48
- @errors
49
- end
50
-
40
+
51
41
  def encoded
52
- do_encode(self.name)
42
+ do_encode
53
43
  end
54
44
 
55
45
  def decoded
@@ -66,7 +56,7 @@ module Mail
66
56
 
67
57
  private
68
58
 
69
- def do_encode(name)
59
+ def do_encode
70
60
  value.nil? ? '' : "#{wrapped_value}\r\n"
71
61
  end
72
62
 
@@ -103,10 +93,7 @@ module Mail
103
93
  # preference to other places where the field could be folded, even if
104
94
  # it is allowed elsewhere.
105
95
  def wrapped_value # :nodoc:
106
- @folded_line = []
107
- @unfolded_line = decoded.to_s.split(/[ \t]/)
108
- fold("#{name}: ".length)
109
- wrap_lines(name, @folded_line)
96
+ wrap_lines(name, fold("#{name}: ".length))
110
97
  end
111
98
 
112
99
  # 6.2. Display of 'encoded-word's
@@ -118,64 +105,86 @@ module Mail
118
105
  # without having to separate 'encoded-word's where spaces occur in the
119
106
  # unencoded text.)
120
107
  def wrap_lines(name, folded_lines)
121
- result = []
122
- index = 0
123
- result[index] = "#{name}: #{folded_lines.shift}"
108
+ result = ["#{name}: #{folded_lines.shift}"]
124
109
  result.concat(folded_lines)
125
110
  result.join("\r\n\s")
126
111
  end
127
112
 
128
113
  def fold(prepend = 0) # :nodoc:
129
- encoding = @charset.to_s.upcase.gsub('_', '-')
130
- while !@unfolded_line.empty?
131
- encoded = false
114
+ encoding = normalized_encoding
115
+ decoded_string = decoded.to_s
116
+ should_encode = decoded_string.not_ascii_only?
117
+ if should_encode
118
+ first = true
119
+ words = decoded_string.split(/[ \t]/).map do |word|
120
+ if first
121
+ first = !first
122
+ else
123
+ word = " " << word
124
+ end
125
+ if word.not_ascii_only?
126
+ word
127
+ else
128
+ word.scan(/.{7}|.+$/)
129
+ end
130
+ end.flatten
131
+ else
132
+ words = decoded_string.split(/[ \t]/)
133
+ end
134
+
135
+ folded_lines = []
136
+ while !words.empty?
132
137
  limit = 78 - prepend
138
+ limit = limit - 7 - encoding.length if should_encode
133
139
  line = ""
134
- while !@unfolded_line.empty?
135
- break unless word = @unfolded_line.first.dup
136
- # Remember whether it was non-ascii before we encode it ('cause then we can't tell anymore)
137
- non_ascii = word.not_ascii_only?
138
- encoded_word = encode(word)
140
+ while !words.empty?
141
+ break unless word = words.first.dup
142
+ word.encode!(charset) if defined?(Encoding) && charset
143
+ word = encode(word) if should_encode
144
+ word = encode_crlf(word)
139
145
  # Skip to next line if we're going to go past the limit
140
146
  # Unless this is the first word, in which case we're going to add it anyway
141
147
  # Note: This means that a word that's longer than 998 characters is going to break the spec. Please fix if this is a problem for you.
142
148
  # (The fix, it seems, would be to use encoded-word encoding on it, because that way you can break it across multiple lines and
143
149
  # the linebreak will be ignored)
144
- break if !line.empty? && (line.length + encoded_word.length + 1 > limit)
145
- # If word was the first non-ascii word, we're going to make the entire line encoded and we're going to reduce the limit accordingly
146
- if non_ascii && !encoded
147
- encoded = true
148
- encoded_word_safify!(line)
149
- limit = limit - 8 - encoding.length # minus the =?...?Q?...?= part, the possible leading white-space, and the name of the encoding
150
- end
150
+ break if !line.empty? && (line.length + word.length + 1 > limit)
151
151
  # Remove the word from the queue ...
152
- @unfolded_line.shift
152
+ words.shift
153
+ # Add word separator
154
+ line << " " unless (line.empty? || should_encode)
153
155
  # ... add it in encoded form to the current line
154
- line << " " unless line.empty?
155
- encoded_word_safify!(encoded_word) if encoded
156
- line << encoded_word
156
+ line << word
157
157
  end
158
- # Add leading whitespace if both this and the last line were encoded, because whitespace between two encoded-words is ignored when decoding
159
- line = " " + line if encoded && @folded_line.last && @folded_line.last.index('=?') == 0
160
158
  # Encode the line if necessary
161
- line = "=?#{encoding}?Q?#{line.gsub(/ /, '_')}?=" if encoded
159
+ line = "=?#{encoding}?Q?#{line}?=" if should_encode
162
160
  # Add the line to the output and reset the prepend
163
- @folded_line << line
161
+ folded_lines << line
164
162
  prepend = 0
165
163
  end
164
+ folded_lines
166
165
  end
167
-
166
+
168
167
  def encode(value)
169
- value.encode!(charset) if charset && value.respond_to?(:encode!)
170
- (value.not_ascii_only? ? [value].pack("M").gsub("=\n", '') : value).gsub("\r", "=0D").gsub("\n", "=0A")
171
- end
172
-
173
- def encoded_word_safify!(value)
168
+ value = [value].pack("M").gsub("=\n", '')
174
169
  value.gsub!(/"/, '=22')
175
170
  value.gsub!(/\(/, '=28')
176
171
  value.gsub!(/\)/, '=29')
177
172
  value.gsub!(/\?/, '=3F')
178
173
  value.gsub!(/_/, '=5F')
174
+ value.gsub!(/ /, '_')
175
+ value
176
+ end
177
+
178
+ def encode_crlf(value)
179
+ value.gsub!("\r", '=0D')
180
+ value.gsub!("\n", '=0A')
181
+ value
182
+ end
183
+
184
+ def normalized_encoding
185
+ encoding = charset.to_s.upcase.gsub('_', '-')
186
+ encoding = 'UTF-8' if encoding == 'UTF8' # Ruby 1.8.x and $KCODE == 'u'
187
+ encoding
179
188
  end
180
189
 
181
190
  end
@@ -1734,6 +1734,11 @@ module Mail
1734
1734
  hash['delivery_handler'] = delivery_handler.to_s if delivery_handler
1735
1735
  hash['transport_encoding'] = transport_encoding.to_s
1736
1736
  special_variables = [:@header, :@delivery_handler, :@transport_encoding]
1737
+ if multipart?
1738
+ hash['multipart_body'] = []
1739
+ body.parts.map { |part| hash['multipart_body'] << part.to_yaml }
1740
+ special_variables.push(:@body, :@text_part, :@html_part)
1741
+ end
1737
1742
  (instance_variables.map(&:to_sym) - special_variables).each do |var|
1738
1743
  hash[var.to_s] = instance_variable_get(var)
1739
1744
  end
@@ -1742,7 +1747,7 @@ module Mail
1742
1747
 
1743
1748
  def self.from_yaml(str)
1744
1749
  hash = YAML.load(str)
1745
- m = Mail::Message.new(:headers => hash['headers'])
1750
+ m = self.new(:headers => hash['headers'])
1746
1751
  hash.delete('headers')
1747
1752
  hash.each do |k,v|
1748
1753
  case
@@ -1753,6 +1758,8 @@ module Mail
1753
1758
  end
1754
1759
  when k == 'transport_encoding'
1755
1760
  m.transport_encoding(v)
1761
+ when k == 'multipart_body'
1762
+ v.map {|part| m.add_part Mail::Part.from_yaml(part) }
1756
1763
  when k =~ /^@/
1757
1764
  m.instance_variable_set(k.to_sym, v)
1758
1765
  end
@@ -435,7 +435,7 @@ module Mail #:nodoc:
435
435
 
436
436
  begin
437
437
  @wrapped_string[0...byte_offset].unpack('U*').length
438
- rescue ArgumentError => e
438
+ rescue ArgumentError
439
439
  byte_offset -= 1
440
440
  retry
441
441
  end
@@ -125,8 +125,8 @@ module Mail
125
125
  def start(config = Configuration.instance, &block)
126
126
  raise ArgumentError.new("Mail::Retrievable#pop3_start takes a block") unless block_given?
127
127
 
128
- pop3 = Net::POP3.new(settings[:address], settings[:port], isapop = false)
129
- pop3.enable_ssl(verify = OpenSSL::SSL::VERIFY_NONE) if settings[:enable_ssl]
128
+ pop3 = Net::POP3.new(settings[:address], settings[:port], false)
129
+ pop3.enable_ssl(OpenSSL::SSL::VERIFY_NONE) if settings[:enable_ssl]
130
130
  pop3.start(settings[:user_name], settings[:password])
131
131
 
132
132
  yield pop3
metadata CHANGED
@@ -1,60 +1,81 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mail
3
- version: !ruby/object:Gem::Version
4
- version: 2.4.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
5
  prerelease:
6
+ segments:
7
+ - 2
8
+ - 4
9
+ - 1
10
+ version: 2.4.1
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Mikel Lindsaar
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-01-15 00:00:00.000000000 +10:30
13
- default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-01-20 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
16
21
  name: mime-types
17
- requirement: &70128923044060 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
18
24
  none: false
19
- requirements:
25
+ requirements:
20
26
  - - ~>
21
- - !ruby/object:Gem::Version
22
- version: '1.16'
27
+ - !ruby/object:Gem::Version
28
+ hash: 47
29
+ segments:
30
+ - 1
31
+ - 16
32
+ version: "1.16"
23
33
  type: :runtime
24
- prerelease: false
25
- version_requirements: *70128923044060
26
- - !ruby/object:Gem::Dependency
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
27
36
  name: treetop
28
- requirement: &70128923043580 !ruby/object:Gem::Requirement
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
29
39
  none: false
30
- requirements:
40
+ requirements:
31
41
  - - ~>
32
- - !ruby/object:Gem::Version
42
+ - !ruby/object:Gem::Version
43
+ hash: 23
44
+ segments:
45
+ - 1
46
+ - 4
47
+ - 8
33
48
  version: 1.4.8
34
49
  type: :runtime
35
- prerelease: false
36
- version_requirements: *70128923043580
37
- - !ruby/object:Gem::Dependency
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
38
52
  name: i18n
39
- requirement: &70128923043120 !ruby/object:Gem::Requirement
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
40
55
  none: false
41
- requirements:
42
- - - ! '>='
43
- - !ruby/object:Gem::Version
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 15
60
+ segments:
61
+ - 0
62
+ - 4
63
+ - 0
44
64
  version: 0.4.0
45
65
  type: :runtime
46
- prerelease: false
47
- version_requirements: *70128923043120
66
+ version_requirements: *id003
48
67
  description: A really Ruby Mail handler.
49
68
  email: raasdnil@gmail.com
50
69
  executables: []
70
+
51
71
  extensions: []
52
- extra_rdoc_files:
72
+
73
+ extra_rdoc_files:
53
74
  - README.md
54
75
  - CONTRIBUTING.md
55
76
  - CHANGELOG.rdoc
56
77
  - TODO.rdoc
57
- files:
78
+ files:
58
79
  - README.md
59
80
  - CONTRIBUTING.md
60
81
  - CHANGELOG.rdoc
@@ -195,29 +216,38 @@ files:
195
216
  - lib/tasks/corpus.rake
196
217
  - lib/tasks/treetop.rake
197
218
  - lib/VERSION
198
- has_rdoc: true
199
219
  homepage: http://github.com/mikel/mail
200
220
  licenses: []
221
+
201
222
  post_install_message:
202
223
  rdoc_options: []
203
- require_paths:
224
+
225
+ require_paths:
204
226
  - lib
205
- required_ruby_version: !ruby/object:Gem::Requirement
227
+ required_ruby_version: !ruby/object:Gem::Requirement
206
228
  none: false
207
- requirements:
208
- - - ! '>='
209
- - !ruby/object:Gem::Version
210
- version: '0'
211
- required_rubygems_version: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - ">="
231
+ - !ruby/object:Gem::Version
232
+ hash: 3
233
+ segments:
234
+ - 0
235
+ version: "0"
236
+ required_rubygems_version: !ruby/object:Gem::Requirement
212
237
  none: false
213
- requirements:
214
- - - ! '>='
215
- - !ruby/object:Gem::Version
216
- version: '0'
238
+ requirements:
239
+ - - ">="
240
+ - !ruby/object:Gem::Version
241
+ hash: 3
242
+ segments:
243
+ - 0
244
+ version: "0"
217
245
  requirements: []
246
+
218
247
  rubyforge_project:
219
- rubygems_version: 1.6.2
248
+ rubygems_version: 1.8.10
220
249
  signing_key:
221
250
  specification_version: 3
222
251
  summary: Mail provides a nice Ruby DSL for making, sending and reading emails.
223
252
  test_files: []
253
+