actionmailer 5.2.4.4 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90fc993b805040c5725969b90de09554c72aec1d5f4cf66a1a46ba900819cc4e
4
- data.tar.gz: fc8acc72f8440d3d6ffe825c282f0358a10a9a425801f6b50e21297662fdd172
3
+ metadata.gz: 00f824272685e39446fc6ed13c338cc7af4267ebf1bff0f054d2e9841bb1acfb
4
+ data.tar.gz: f4dc2df9e80a598e284423859edce30f8569f3e658702c13bb3363b009511d1d
5
5
  SHA512:
6
- metadata.gz: c0c1415209be4aef5f6a18a1a61dcf37507836d3fab499bfca546f25fb2274958df844c2e5c47267c6f11eaacbe557807f22fd4d3415b423f9c483f9e06e064b
7
- data.tar.gz: fab44a1954da322622868b6f17791c452a36c1e1df357d0d5024979d6d5e99ec96b7292784945bdfa755ba1bfc06af01b8dfb6e6a0894fbcc7fdfbe76f5fae65
6
+ metadata.gz: aa013d9eebe8d3464e8898f5749d0662e2e643725f4015af59c662b7c2059bab86af8aceeba81a8777579b1df13a66728d46ac7c649ebd38a398e0290100567d
7
+ data.tar.gz: 726821207ca4b5e892e8d7b037467ac8d45eeedae6da0192fac2d3db08548290dac796a3ba7785da71b1624716ac270e67f21745f75e0d66b82519d50781e91f
data/CHANGELOG.md CHANGED
@@ -1,74 +1,28 @@
1
- ## Rails 5.2.4.4 (September 09, 2020) ##
1
+ ## Rails 6.1.1 (January 07, 2021) ##
2
2
 
3
- * No changes.
3
+ * Sets default mailer queue to `"default"` in the mail assertions.
4
4
 
5
+ *Paul Keen*
5
6
 
6
- ## Rails 5.2.4.3 (May 18, 2020) ##
7
7
 
8
- * No changes.
8
+ ## Rails 6.1.0 (December 09, 2020) ##
9
9
 
10
+ * Change default queue name of the deliver (`:mailers`) job to be the job adapter's
11
+ default (`:default`).
10
12
 
11
- ## Rails 5.2.4.1 (December 18, 2019) ##
13
+ *Rafael Mendonça França*
12
14
 
13
- * No changes.
15
+ * Remove deprecated `ActionMailer::Base.receive` in favor of [Action Mailbox](https://github.com/rails/rails/tree/master/actionmailbox).
14
16
 
17
+ *Rafael Mendonça França*
15
18
 
16
- ## Rails 5.2.4 (November 27, 2019) ##
19
+ * Fix ActionMailer assertions don't work for parameterized mail with legacy delivery job.
17
20
 
18
- * No changes.
21
+ *bogdanvlviv*
19
22
 
23
+ * Added `email_address_with_name` to properly escape addresses with names.
20
24
 
21
- ## Rails 5.2.3 (March 27, 2019) ##
25
+ *Sunny Ripert*
22
26
 
23
- * No changes.
24
27
 
25
-
26
- ## Rails 5.2.2.1 (March 11, 2019) ##
27
-
28
- * No changes.
29
-
30
-
31
- ## Rails 5.2.2 (December 04, 2018) ##
32
-
33
- * No changes.
34
-
35
-
36
- ## Rails 5.2.1.1 (November 27, 2018) ##
37
-
38
- * No changes.
39
-
40
-
41
- ## Rails 5.2.1 (August 07, 2018) ##
42
-
43
- * Ensure mail gem is eager autoloaded when eager load is true to prevent thread deadlocks.
44
-
45
- *Samuel Cochran*
46
-
47
-
48
- ## Rails 5.2.0 (April 09, 2018) ##
49
-
50
- * Bring back proc with arity of 1 in `ActionMailer::Base.default` proc
51
- since it was supported in Rails 5.0 but not deprecated.
52
-
53
- *Jimmy Bourassa*
54
-
55
- * Add `assert_enqueued_email_with` test helper.
56
-
57
- assert_enqueued_email_with ContactMailer, :welcome do
58
- ContactMailer.welcome.deliver_later
59
- end
60
-
61
- *Mikkel Malmberg*
62
-
63
- * Allow Action Mailer classes to configure their delivery job.
64
-
65
- class MyMailer < ApplicationMailer
66
- self.delivery_job = MyCustomDeliveryJob
67
-
68
- ...
69
- end
70
-
71
- *Matthew Mongeau*
72
-
73
-
74
- Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/actionmailer/CHANGELOG.md) for previous changes.
28
+ Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/actionmailer/CHANGELOG.md) for previous changes.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2018 David Heinemeier Hansson
1
+ Copyright (c) 2004-2020 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -13,6 +13,8 @@ Additionally, an Action Mailer class can be used to process incoming email,
13
13
  such as allowing a blog to accept new posts from an email (which could even
14
14
  have been sent from a phone).
15
15
 
16
+ You can read more about Action Mailer in the {Action Mailer Basics}[https://edgeguides.rubyonrails.org/action_mailer_basics.html] guide.
17
+
16
18
  == Sending emails
17
19
 
18
20
  The framework works by initializing any instance variables you want to be
@@ -93,42 +95,6 @@ Example:
93
95
  .....
94
96
  end
95
97
 
96
- == Receiving emails
97
-
98
- To receive emails, you need to implement a public instance method called
99
- +receive+ that takes an email object as its single parameter. The Action Mailer
100
- framework has a corresponding class method, which is also called +receive+, that
101
- accepts a raw, unprocessed email as a string, which it then turns into the email
102
- object and calls the receive instance method.
103
-
104
- Example:
105
-
106
- class Mailman < ActionMailer::Base
107
- def receive(email)
108
- page = Page.find_by(address: email.to.first)
109
- page.emails.create(
110
- subject: email.subject, body: email.body
111
- )
112
-
113
- if email.has_attachments?
114
- email.attachments.each do |attachment|
115
- page.attachments.create({
116
- file: attachment, description: email.subject
117
- })
118
- end
119
- end
120
- end
121
- end
122
-
123
- This Mailman can be the target for Postfix or other MTAs. In Rails, you would use
124
- the runner in the trivial case like this:
125
-
126
- rails runner 'Mailman.receive(STDIN.read)'
127
-
128
- However, invoking Rails in the runner for each mail to be received is very
129
- resource intensive. A single instance of Rails should be run within a daemon, if
130
- it is going to process more than just a limited amount of email.
131
-
132
98
  == Configuration
133
99
 
134
100
  The Base class has the full list of configuration options. Here's an example:
@@ -150,7 +116,7 @@ The latest version of Action Mailer can be installed with RubyGems:
150
116
 
151
117
  Source code can be downloaded as part of the Rails project on GitHub:
152
118
 
153
- * https://github.com/rails/rails/tree/5-2-stable/actionmailer
119
+ * https://github.com/rails/rails/tree/master/actionmailer
154
120
 
155
121
 
156
122
  == License
@@ -164,7 +130,7 @@ Action Mailer is released under the MIT license:
164
130
 
165
131
  API documentation is at
166
132
 
167
- * http://api.rubyonrails.org
133
+ * https://api.rubyonrails.org
168
134
 
169
135
  Bug reports for the Ruby on Rails project can be filed here:
170
136
 
@@ -172,4 +138,4 @@ Bug reports for the Ruby on Rails project can be filed here:
172
138
 
173
139
  Feature requests should be discussed on the rails-core mailing list here:
174
140
 
175
- * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
141
+ * https://discuss.rubyonrails.org/c/rubyonrails-core
data/lib/action_mailer.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2004-2018 David Heinemeier Hansson
4
+ # Copyright (c) 2004-2020 David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -52,6 +52,7 @@ module ActionMailer
52
52
  autoload :TestHelper
53
53
  autoload :MessageDelivery
54
54
  autoload :DeliveryJob
55
+ autoload :MailDeliveryJob
55
56
 
56
57
  def self.eager_load!
57
58
  super
@@ -66,4 +67,5 @@ autoload :Mime, "action_dispatch/http/mime_type"
66
67
  ActiveSupport.on_load(:action_view) do
67
68
  ActionView::Base.default_formats ||= Mime::SET.symbols
68
69
  ActionView::Template::Types.delegate_to Mime
70
+ ActionView::LookupContext::DetailsKey.clear
69
71
  end
@@ -16,11 +16,11 @@ module ActionMailer
16
16
  #
17
17
  # To use Action Mailer, you need to create a mailer model.
18
18
  #
19
- # $ rails generate mailer Notifier
19
+ # $ bin/rails generate mailer Notifier
20
20
  #
21
21
  # The generated model inherits from <tt>ApplicationMailer</tt> which in turn
22
22
  # inherits from <tt>ActionMailer::Base</tt>. A mailer model defines methods
23
- # used to generate an email message. In these methods, you can setup variables to be used in
23
+ # used to generate an email message. In these methods, you can set up variables to be used in
24
24
  # the mailer views, options on the mail itself such as the <tt>:from</tt> address, and attachments.
25
25
  #
26
26
  # class ApplicationMailer < ActionMailer::Base
@@ -408,7 +408,7 @@ module ActionMailer
408
408
  # really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name
409
409
  # of an OpenSSL verify constant (<tt>'none'</tt> or <tt>'peer'</tt>) or directly the constant
410
410
  # (<tt>OpenSSL::SSL::VERIFY_NONE</tt> or <tt>OpenSSL::SSL::VERIFY_PEER</tt>).
411
- # <tt>:ssl/:tls</tt> Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection)
411
+ # * <tt>:ssl/:tls</tt> Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection)
412
412
  #
413
413
  # * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method.
414
414
  # * <tt>:location</tt> - The location of the sendmail executable. Defaults to <tt>/usr/sbin/sendmail</tt>.
@@ -455,10 +455,6 @@ module ActionMailer
455
455
 
456
456
  PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [:@_action_has_layout]
457
457
 
458
- def _protected_ivars # :nodoc:
459
- PROTECTED_IVARS
460
- end
461
-
462
458
  helper ActionMailer::MailHelper
463
459
 
464
460
  class_attribute :delivery_job, default: ::ActionMailer::DeliveryJob
@@ -475,11 +471,21 @@ module ActionMailer
475
471
  observers.flatten.compact.each { |observer| register_observer(observer) }
476
472
  end
477
473
 
474
+ # Unregister one or more previously registered Observers.
475
+ def unregister_observers(*observers)
476
+ observers.flatten.compact.each { |observer| unregister_observer(observer) }
477
+ end
478
+
478
479
  # Register one or more Interceptors which will be called before mail is sent.
479
480
  def register_interceptors(*interceptors)
480
481
  interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
481
482
  end
482
483
 
484
+ # Unregister one or more previously registered Interceptors.
485
+ def unregister_interceptors(*interceptors)
486
+ interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
487
+ end
488
+
483
489
  # Register an Observer which will be notified when mail is delivered.
484
490
  # Either a class, string or symbol can be passed in as the Observer.
485
491
  # If a string or symbol is passed in it will be camelized and constantized.
@@ -487,6 +493,13 @@ module ActionMailer
487
493
  Mail.register_observer(observer_class_for(observer))
488
494
  end
489
495
 
496
+ # Unregister a previously registered Observer.
497
+ # Either a class, string or symbol can be passed in as the Observer.
498
+ # If a string or symbol is passed in it will be camelized and constantized.
499
+ def unregister_observer(observer)
500
+ Mail.unregister_observer(observer_class_for(observer))
501
+ end
502
+
490
503
  # Register an Interceptor which will be called before mail is sent.
491
504
  # Either a class, string or symbol can be passed in as the Interceptor.
492
505
  # If a string or symbol is passed in it will be camelized and constantized.
@@ -494,6 +507,13 @@ module ActionMailer
494
507
  Mail.register_interceptor(observer_class_for(interceptor))
495
508
  end
496
509
 
510
+ # Unregister a previously registered Interceptor.
511
+ # Either a class, string or symbol can be passed in as the Interceptor.
512
+ # If a string or symbol is passed in it will be camelized and constantized.
513
+ def unregister_interceptor(interceptor)
514
+ Mail.unregister_interceptor(observer_class_for(interceptor))
515
+ end
516
+
497
517
  def observer_class_for(value) # :nodoc:
498
518
  case value
499
519
  when String, Symbol
@@ -527,27 +547,6 @@ module ActionMailer
527
547
  # config.action_mailer.default_options = { from: "no-reply@example.org" }
528
548
  alias :default_options= :default
529
549
 
530
- # Receives a raw email, parses it into an email object, decodes it,
531
- # instantiates a new mailer, and passes the email object to the mailer
532
- # object's +receive+ method.
533
- #
534
- # If you want your mailer to be able to process incoming messages, you'll
535
- # need to implement a +receive+ method that accepts the raw email string
536
- # as a parameter:
537
- #
538
- # class MyMailer < ActionMailer::Base
539
- # def receive(mail)
540
- # # ...
541
- # end
542
- # end
543
- def receive(raw_mail)
544
- ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload|
545
- mail = Mail.new(raw_mail)
546
- set_payload_for_mail(payload, mail)
547
- new.receive(mail)
548
- end
549
- end
550
-
551
550
  # Wraps an email delivery inside of <tt>ActiveSupport::Notifications</tt> instrumentation.
552
551
  #
553
552
  # This method is actually called by the <tt>Mail::Message</tt> object itself
@@ -561,18 +560,26 @@ module ActionMailer
561
560
  end
562
561
  end
563
562
 
564
- private
563
+ # Returns an email in the format "Name <email@example.com>".
564
+ def email_address_with_name(address, name)
565
+ Mail::Address.new.tap do |builder|
566
+ builder.address = address
567
+ builder.display_name = name
568
+ end.to_s
569
+ end
565
570
 
571
+ private
566
572
  def set_payload_for_mail(payload, mail)
567
- payload[:mailer] = name
568
- payload[:message_id] = mail.message_id
569
- payload[:subject] = mail.subject
570
- payload[:to] = mail.to
571
- payload[:from] = mail.from
572
- payload[:bcc] = mail.bcc if mail.bcc.present?
573
- payload[:cc] = mail.cc if mail.cc.present?
574
- payload[:date] = mail.date
575
- payload[:mail] = mail.encoded
573
+ payload[:mail] = mail.encoded
574
+ payload[:mailer] = name
575
+ payload[:message_id] = mail.message_id
576
+ payload[:subject] = mail.subject
577
+ payload[:to] = mail.to
578
+ payload[:from] = mail.from
579
+ payload[:bcc] = mail.bcc if mail.bcc.present?
580
+ payload[:cc] = mail.cc if mail.cc.present?
581
+ payload[:date] = mail.date
582
+ payload[:perform_deliveries] = mail.perform_deliveries
576
583
  end
577
584
 
578
585
  def method_missing(method_name, *args)
@@ -582,6 +589,7 @@ module ActionMailer
582
589
  super
583
590
  end
584
591
  end
592
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
585
593
 
586
594
  def respond_to_missing?(method, include_all = false)
587
595
  action_methods.include?(method.to_s) || super
@@ -627,6 +635,11 @@ module ActionMailer
627
635
  self.class.mailer_name
628
636
  end
629
637
 
638
+ # Returns an email in the format "Name <email@example.com>".
639
+ def email_address_with_name(address, name)
640
+ self.class.email_address_with_name(address, name)
641
+ end
642
+
630
643
  # Allows you to pass random and unusual headers to the new <tt>Mail::Message</tt>
631
644
  # object which will add them to itself.
632
645
  #
@@ -708,7 +721,7 @@ module ActionMailer
708
721
  end
709
722
 
710
723
  class LateAttachmentsProxy < SimpleDelegator
711
- def inline; _raise_error end
724
+ def inline; self end
712
725
  def []=(_name, _content); _raise_error end
713
726
 
714
727
  private
@@ -829,8 +842,9 @@ module ActionMailer
829
842
  @_mail_was_called = true
830
843
 
831
844
  create_parts_from_responses(message, responses)
845
+ wrap_inline_attachments(message)
832
846
 
833
- # Setup content type, reapply charset and handle parts order
847
+ # Set up content type, reapply charset and handle parts order
834
848
  message.content_type = set_content_type(message, content_type, headers[:content_type])
835
849
  message.charset = charset
836
850
 
@@ -843,7 +857,6 @@ module ActionMailer
843
857
  end
844
858
 
845
859
  private
846
-
847
860
  # Used by #mail to set the content type of the message.
848
861
  #
849
862
  # It will use the given +user_content_type+, or multipart if the mail
@@ -859,7 +872,7 @@ module ActionMailer
859
872
  when user_content_type.present?
860
873
  user_content_type
861
874
  when m.has_attachments?
862
- if m.attachments.detect(&:inline?)
875
+ if m.attachments.all?(&:inline?)
863
876
  ["multipart", "related", params]
864
877
  else
865
878
  ["multipart", "mixed", params]
@@ -877,7 +890,7 @@ module ActionMailer
877
890
  # If the subject has interpolations, you can pass them through the +interpolations+ parameter.
878
891
  def default_i18n_subject(interpolations = {}) # :doc:
879
892
  mailer_scope = self.class.mailer_name.tr("/", ".")
880
- I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
893
+ I18n.t(:subject, **interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
881
894
  end
882
895
 
883
896
  # Emails do not support relative path links.
@@ -886,12 +899,9 @@ module ActionMailer
886
899
  end
887
900
 
888
901
  def apply_defaults(headers)
889
- default_values = self.class.default.map do |key, value|
890
- [
891
- key,
892
- compute_default(value)
893
- ]
894
- end.to_h
902
+ default_values = self.class.default.transform_values do |value|
903
+ compute_default(value)
904
+ end
895
905
 
896
906
  headers_with_defaults = headers.reverse_merge(default_values)
897
907
  headers_with_defaults[:subject] ||= default_i18n_subject
@@ -914,11 +924,9 @@ module ActionMailer
914
924
  assignable.each { |k, v| message[k] = v }
915
925
  end
916
926
 
917
- def collect_responses(headers)
927
+ def collect_responses(headers, &block)
918
928
  if block_given?
919
- collector = ActionMailer::Collector.new(lookup_context) { render(action_name) }
920
- yield(collector)
921
- collector.responses
929
+ collect_responses_from_block(headers, &block)
922
930
  elsif headers[:body]
923
931
  collect_responses_from_text(headers)
924
932
  else
@@ -926,6 +934,13 @@ module ActionMailer
926
934
  end
927
935
  end
928
936
 
937
+ def collect_responses_from_block(headers)
938
+ templates_name = headers[:template_name] || action_name
939
+ collector = ActionMailer::Collector.new(lookup_context) { render(templates_name) }
940
+ yield(collector)
941
+ collector.responses
942
+ end
943
+
929
944
  def collect_responses_from_text(headers)
930
945
  [{
931
946
  body: headers.delete(:body),
@@ -938,10 +953,10 @@ module ActionMailer
938
953
  templates_name = headers[:template_name] || action_name
939
954
 
940
955
  each_template(Array(templates_path), templates_name).map do |template|
941
- self.formats = template.formats
956
+ format = template.format || self.formats.first
942
957
  {
943
- body: render(template: template),
944
- content_type: template.type.to_s
958
+ body: render(template: template, formats: [format]),
959
+ content_type: Mime[format].to_s
945
960
  }
946
961
  end
947
962
  end
@@ -951,7 +966,28 @@ module ActionMailer
951
966
  if templates.empty?
952
967
  raise ActionView::MissingTemplate.new(paths, name, paths, false, "mailer")
953
968
  else
954
- templates.uniq(&:formats).each(&block)
969
+ templates.uniq(&:format).each(&block)
970
+ end
971
+ end
972
+
973
+ def wrap_inline_attachments(message)
974
+ # If we have both types of attachment, wrap all the inline attachments
975
+ # in multipart/related, but not the actual attachments
976
+ if message.attachments.detect(&:inline?) && message.attachments.detect { |a| !a.inline? }
977
+ related = Mail::Part.new
978
+ related.content_type = "multipart/related"
979
+ mixed = [ related ]
980
+
981
+ message.parts.each do |p|
982
+ if p.attachment? && !p.inline?
983
+ mixed << p
984
+ else
985
+ related.add_part(p)
986
+ end
987
+ end
988
+
989
+ message.parts.clear
990
+ mixed.each { |c| message.add_part(c) }
955
991
  end
956
992
  end
957
993
 
@@ -983,7 +1019,11 @@ module ActionMailer
983
1019
  end
984
1020
 
985
1021
  def instrument_name
986
- "action_mailer".freeze
1022
+ "action_mailer"
1023
+ end
1024
+
1025
+ def _protected_ivars
1026
+ PROTECTED_IVARS
987
1027
  end
988
1028
 
989
1029
  ActiveSupport.run_load_hooks(:action_mailer, self)
@@ -12,9 +12,18 @@ module ActionMailer
12
12
 
13
13
  rescue_from StandardError, with: :handle_exception_with_mailer_class
14
14
 
15
+ before_perform do
16
+ ActiveSupport::Deprecation.warn <<~MSG.squish
17
+ Sending mail with DeliveryJob and Parameterized::DeliveryJob
18
+ is deprecated and will be removed in Rails 6.2.
19
+ Please use MailDeliveryJob instead.
20
+ MSG
21
+ end
22
+
15
23
  def perform(mailer, mail_method, delivery_method, *args) #:nodoc:
16
24
  mailer.constantize.public_send(mail_method, *args).send(delivery_method)
17
25
  end
26
+ ruby2_keywords(:perform) if respond_to?(:ruby2_keywords, true)
18
27
 
19
28
  private
20
29
  # "Deserialize" the mailer class name by hand in case another argument
@@ -49,7 +49,7 @@ module ActionMailer
49
49
  # arguments: '-i'
50
50
  def add_delivery_method(symbol, klass, default_options = {})
51
51
  class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
52
- send(:"#{symbol}_settings=", default_options)
52
+ public_send(:"#{symbol}_settings=", default_options)
53
53
  self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
54
54
  end
55
55
 
@@ -7,10 +7,10 @@ module ActionMailer
7
7
  end
8
8
 
9
9
  module VERSION
10
- MAJOR = 5
11
- MINOR = 2
12
- TINY = 4
13
- PRE = "4"
10
+ MAJOR = 6
11
+ MINOR = 1
12
+ TINY = 1
13
+ PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -40,9 +40,7 @@ module ActionMailer
40
40
  end
41
41
 
42
42
  private
43
- def message
44
- @message
45
- end
43
+ attr_reader :message
46
44
 
47
45
  def html_part
48
46
  @html_part ||= message.html_part
@@ -9,19 +9,17 @@ module ActionMailer
9
9
  # An email was delivered.
10
10
  def deliver(event)
11
11
  info do
12
- recipients = Array(event.payload[:to]).join(", ")
13
- "Sent mail to #{recipients} (#{event.duration.round(1)}ms)"
12
+ perform_deliveries = event.payload[:perform_deliveries]
13
+ if perform_deliveries
14
+ "Delivered mail #{event.payload[:message_id]} (#{event.duration.round(1)}ms)"
15
+ else
16
+ "Skipped delivery of mail #{event.payload[:message_id]} as `perform_deliveries` is false"
17
+ end
14
18
  end
15
19
 
16
20
  debug { event.payload[:mail] }
17
21
  end
18
22
 
19
- # An email was received.
20
- def receive(event)
21
- info { "Received mail (#{event.duration.round(1)}ms)" }
22
- debug { event.payload[:mail] }
23
- end
24
-
25
23
  # An email was generated.
26
24
  def process(event)
27
25
  debug do
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_job"
4
+
5
+ module ActionMailer
6
+ # The <tt>ActionMailer::MailDeliveryJob</tt> class is used when you
7
+ # want to send emails outside of the request-response cycle. It supports
8
+ # sending either parameterized or normal mail.
9
+ #
10
+ # Exceptions are rescued and handled by the mailer class.
11
+ class MailDeliveryJob < ActiveJob::Base # :nodoc:
12
+ queue_as { ActionMailer::Base.deliver_later_queue_name }
13
+
14
+ rescue_from StandardError, with: :handle_exception_with_mailer_class
15
+
16
+ def perform(mailer, mail_method, delivery_method, args:, kwargs: nil, params: nil)
17
+ mailer_class = params ? mailer.constantize.with(params) : mailer.constantize
18
+ message = if kwargs
19
+ mailer_class.public_send(mail_method, *args, **kwargs)
20
+ else
21
+ mailer_class.public_send(mail_method, *args)
22
+ end
23
+ message.send(delivery_method)
24
+ end
25
+
26
+ private
27
+ # "Deserialize" the mailer class name by hand in case another argument
28
+ # (like a Global ID reference) raised DeserializationError.
29
+ def mailer_class
30
+ if mailer = Array(@serialized_arguments).first || Array(arguments).first
31
+ mailer.constantize
32
+ end
33
+ end
34
+
35
+ def handle_exception_with_mailer_class(exception)
36
+ if klass = mailer_class
37
+ klass.handle_exception exception
38
+ else
39
+ raise exception
40
+ end
41
+ end
42
+ end
43
+ end
@@ -23,13 +23,14 @@ module ActionMailer
23
23
  @processed_mailer = nil
24
24
  @mail_message = nil
25
25
  end
26
+ ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
26
27
 
27
28
  # Method calls are delegated to the Mail::Message that's ready to deliver.
28
29
  def __getobj__ #:nodoc:
29
30
  @mail_message ||= processed_mailer.message
30
31
  end
31
32
 
32
- # Unused except for delegator internals (dup, marshaling).
33
+ # Unused except for delegator internals (dup, marshalling).
33
34
  def __setobj__(mail_message) #:nodoc:
34
35
  @mail_message = mail_message
35
36
  end
@@ -52,12 +53,14 @@ module ActionMailer
52
53
  # Notifier.welcome(User.first).deliver_later!
53
54
  # Notifier.welcome(User.first).deliver_later!(wait: 1.hour)
54
55
  # Notifier.welcome(User.first).deliver_later!(wait_until: 10.hours.from_now)
56
+ # Notifier.welcome(User.first).deliver_later!(priority: 10)
55
57
  #
56
58
  # Options:
57
59
  #
58
60
  # * <tt>:wait</tt> - Enqueue the email to be delivered with a delay
59
61
  # * <tt>:wait_until</tt> - Enqueue the email to be delivered at (after) a specific date / time
60
62
  # * <tt>:queue</tt> - Enqueue the email on the specified queue
63
+ # * <tt>:priority</tt> - Enqueues the email with the specified priority
61
64
  #
62
65
  # By default, the email will be enqueued using <tt>ActionMailer::DeliveryJob</tt>. Each
63
66
  # <tt>ActionMailer::Base</tt> class can specify the job to use by setting the class variable
@@ -76,12 +79,14 @@ module ActionMailer
76
79
  # Notifier.welcome(User.first).deliver_later
77
80
  # Notifier.welcome(User.first).deliver_later(wait: 1.hour)
78
81
  # Notifier.welcome(User.first).deliver_later(wait_until: 10.hours.from_now)
82
+ # Notifier.welcome(User.first).deliver_later(priority: 10)
79
83
  #
80
84
  # Options:
81
85
  #
82
86
  # * <tt>:wait</tt> - Enqueue the email to be delivered with a delay.
83
87
  # * <tt>:wait_until</tt> - Enqueue the email to be delivered at (after) a specific date / time.
84
88
  # * <tt>:queue</tt> - Enqueue the email on the specified queue.
89
+ # * <tt>:priority</tt> - Enqueues the email with the specified priority
85
90
  #
86
91
  # By default, the email will be enqueued using <tt>ActionMailer::DeliveryJob</tt>. Each
87
92
  # <tt>ActionMailer::Base</tt> class can specify the job to use by setting the class variable
@@ -135,9 +140,38 @@ module ActionMailer
135
140
  "#deliver_later, 2. only touch the message *within your mailer " \
136
141
  "method*, or 3. use a custom Active Job instead of #deliver_later."
137
142
  else
138
- args = @mailer_class.name, @action.to_s, delivery_method.to_s, *@args
139
143
  job = @mailer_class.delivery_job
140
- job.set(options).perform_later(*args)
144
+
145
+ if use_new_args?(job)
146
+ job.set(options).perform_later(
147
+ @mailer_class.name, @action.to_s, delivery_method.to_s, args: @args)
148
+ elsif job <= DeliveryJob
149
+ job.set(options).perform_later(
150
+ @mailer_class.name, @action.to_s, delivery_method.to_s, *@args)
151
+ else
152
+ ActiveSupport::Deprecation.warn(<<~EOM)
153
+ In Rails 6.2, Action Mailer will pass the mail arguments inside the `:args` keyword argument.
154
+ The `perform` method of the #{job} needs to change and forward the mail arguments
155
+ from the `args` keyword argument.
156
+
157
+ The `perform` method should now look like:
158
+
159
+ `def perform(mailer, mail_method, delivery, args:)`
160
+ EOM
161
+
162
+ job.set(options).perform_later(
163
+ @mailer_class.name, @action.to_s, delivery_method.to_s, *@args)
164
+ end
165
+ end
166
+ end
167
+
168
+ def use_new_args?(job)
169
+ parameters = job.public_instance_method(:perform).parameters
170
+
171
+ parameters.find do |key, name|
172
+ return true if key == :keyreq && name == :args
173
+
174
+ key == :keyrest
141
175
  end
142
176
  end
143
177
  end
@@ -115,17 +115,26 @@ module ActionMailer
115
115
  super
116
116
  end
117
117
  end
118
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
118
119
 
119
120
  def respond_to_missing?(method, include_all = false)
120
121
  @mailer.respond_to?(method, include_all)
121
122
  end
122
123
  end
123
124
 
125
+ class DeliveryJob < ActionMailer::DeliveryJob # :nodoc:
126
+ def perform(mailer, mail_method, delivery_method, params, *args)
127
+ mailer.constantize.with(params).public_send(mail_method, *args).send(delivery_method)
128
+ end
129
+ ruby2_keywords(:perform) if respond_to?(:ruby2_keywords, true)
130
+ end
131
+
124
132
  class MessageDelivery < ActionMailer::MessageDelivery # :nodoc:
125
133
  def initialize(mailer_class, action, params, *args)
126
134
  super(mailer_class, action, *args)
127
135
  @params = params
128
136
  end
137
+ ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
129
138
 
130
139
  private
131
140
  def processed_mailer
@@ -139,16 +148,25 @@ module ActionMailer
139
148
  if processed?
140
149
  super
141
150
  else
142
- args = @mailer_class.name, @action.to_s, delivery_method.to_s, @params, *@args
143
- ActionMailer::Parameterized::DeliveryJob.set(options).perform_later(*args)
151
+ job = delivery_job_class
152
+
153
+ if job <= MailDeliveryJob
154
+ job.set(options).perform_later(
155
+ @mailer_class.name, @action.to_s, delivery_method.to_s, params: @params, args: @args)
156
+ else
157
+ job.set(options).perform_later(
158
+ @mailer_class.name, @action.to_s, delivery_method.to_s, @params, *@args)
159
+ end
144
160
  end
145
161
  end
146
- end
147
162
 
148
- class DeliveryJob < ActionMailer::DeliveryJob # :nodoc:
149
- def perform(mailer, mail_method, delivery_method, params, *args)
150
- mailer.constantize.with(params).public_send(mail_method, *args).send(delivery_method)
151
- end
163
+ def delivery_job_class
164
+ if @mailer_class.delivery_job <= MailDeliveryJob
165
+ @mailer_class.delivery_job
166
+ else
167
+ Parameterized::DeliveryJob
168
+ end
169
+ end
152
170
  end
153
171
  end
154
172
  end
@@ -31,22 +31,38 @@ module ActionMailer
31
31
  interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) }
32
32
  end
33
33
 
34
+ # Unregister one or more previously registered Interceptors.
35
+ def unregister_preview_interceptors(*interceptors)
36
+ interceptors.flatten.compact.each { |interceptor| unregister_preview_interceptor(interceptor) }
37
+ end
38
+
34
39
  # Register an Interceptor which will be called before mail is previewed.
35
40
  # Either a class or a string can be passed in as the Interceptor. If a
36
41
  # string is passed in it will be constantized.
37
42
  def register_preview_interceptor(interceptor)
38
- preview_interceptor = \
43
+ preview_interceptor = interceptor_class_for(interceptor)
44
+
45
+ unless preview_interceptors.include?(preview_interceptor)
46
+ preview_interceptors << preview_interceptor
47
+ end
48
+ end
49
+
50
+ # Unregister a previously registered Interceptor.
51
+ # Either a class or a string can be passed in as the Interceptor. If a
52
+ # string is passed in it will be constantized.
53
+ def unregister_preview_interceptor(interceptor)
54
+ preview_interceptors.delete(interceptor_class_for(interceptor))
55
+ end
56
+
57
+ private
58
+ def interceptor_class_for(interceptor)
39
59
  case interceptor
40
60
  when String, Symbol
41
61
  interceptor.to_s.camelize.constantize
42
62
  else
43
63
  interceptor
44
64
  end
45
-
46
- unless preview_interceptors.include?(preview_interceptor)
47
- preview_interceptors << preview_interceptor
48
65
  end
49
- end
50
66
  end
51
67
  end
52
68
 
@@ -98,7 +114,7 @@ module ActionMailer
98
114
 
99
115
  # Returns the underscored name of the mailer preview without the suffix.
100
116
  def preview_name
101
- name.sub(/Preview$/, "").underscore
117
+ name.delete_suffix("Preview").underscore
102
118
  end
103
119
 
104
120
  private
@@ -18,11 +18,6 @@ module ActionMailer
18
18
  paths = app.config.paths
19
19
  options = app.config.action_mailer
20
20
 
21
- if app.config.force_ssl
22
- options.default_url_options ||= {}
23
- options.default_url_options[:protocol] ||= "https"
24
- end
25
-
26
21
  options.assets_dir ||= paths["public"].first
27
22
  options.javascripts_dir ||= paths["public/javascripts"].first
28
23
  options.stylesheets_dir ||= paths["public/stylesheets"].first
@@ -46,10 +41,25 @@ module ActionMailer
46
41
  register_preview_interceptors(options.delete(:preview_interceptors))
47
42
  register_observers(options.delete(:observers))
48
43
 
44
+ if delivery_job = options.delete(:delivery_job)
45
+ self.delivery_job = delivery_job.constantize
46
+ end
47
+
49
48
  options.each { |k, v| send("#{k}=", v) }
50
49
  end
51
50
 
52
- ActiveSupport.on_load(:action_dispatch_integration_test) { include ActionMailer::TestCase::ClearTestDeliveries }
51
+ ActiveSupport.on_load(:action_dispatch_integration_test) do
52
+ include ActionMailer::TestHelper
53
+ include ActionMailer::TestCase::ClearTestDeliveries
54
+ end
55
+ end
56
+
57
+ initializer "action_mailer.set_autoload_paths" do |app|
58
+ options = app.config.action_mailer
59
+
60
+ if options.show_previews && options.preview_path
61
+ ActiveSupport::Dependencies.autoload_paths << options.preview_path
62
+ end
53
63
  end
54
64
 
55
65
  initializer "action_mailer.compile_config_methods" do
@@ -69,12 +79,8 @@ module ActionMailer
69
79
 
70
80
  if options.show_previews
71
81
  app.routes.prepend do
72
- get "/rails/mailers" => "rails/mailers#index", internal: true
73
- get "/rails/mailers/*path" => "rails/mailers#preview", internal: true
74
- end
75
-
76
- if options.preview_path
77
- ActiveSupport::Dependencies.autoload_paths << options.preview_path
82
+ get "/rails/mailers" => "rails/mailers#index", internal: true
83
+ get "/rails/mailers/*path" => "rails/mailers#preview", internal: true
78
84
  end
79
85
  end
80
86
  end
@@ -22,7 +22,6 @@ module ActionMailer
22
22
  end
23
23
 
24
24
  private
25
-
26
25
  def clear_test_deliveries
27
26
  if ActionMailer::Base.delivery_method == :test
28
27
  ActionMailer::Base.deliveries.clear
@@ -76,7 +75,6 @@ module ActionMailer
76
75
  end
77
76
 
78
77
  private
79
-
80
78
  def initialize_test_deliveries
81
79
  set_delivery_method :test
82
80
  @old_perform_deliveries = ActionMailer::Base.perform_deliveries
@@ -28,13 +28,13 @@ module ActionMailer
28
28
  #
29
29
  # assert_emails 2 do
30
30
  # ContactMailer.welcome.deliver_now
31
- # ContactMailer.welcome.deliver_now
31
+ # ContactMailer.welcome.deliver_later
32
32
  # end
33
33
  # end
34
- def assert_emails(number)
34
+ def assert_emails(number, &block)
35
35
  if block_given?
36
36
  original_count = ActionMailer::Base.deliveries.size
37
- yield
37
+ perform_enqueued_jobs(only: ->(job) { delivery_job_filter(job) }, &block)
38
38
  new_count = ActionMailer::Base.deliveries.size
39
39
  assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent"
40
40
  else
@@ -90,10 +90,23 @@ module ActionMailer
90
90
  # end
91
91
  # end
92
92
  def assert_enqueued_emails(number, &block)
93
- assert_enqueued_jobs number, only: [ ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob ], &block
93
+ assert_enqueued_jobs(number, only: ->(job) { delivery_job_filter(job) }, &block)
94
94
  end
95
95
 
96
- # Asserts that block should cause the specified email
96
+ # Asserts that a specific email has been enqueued, optionally
97
+ # matching arguments.
98
+ #
99
+ # def test_email
100
+ # ContactMailer.welcome.deliver_later
101
+ # assert_enqueued_email_with ContactMailer, :welcome
102
+ # end
103
+ #
104
+ # def test_email_with_arguments
105
+ # ContactMailer.welcome("Hello", "Goodbye").deliver_later
106
+ # assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"]
107
+ # end
108
+ #
109
+ # If a block is passed, that block should cause the specified email
97
110
  # to be enqueued.
98
111
  #
99
112
  # def test_email_in_block
@@ -106,20 +119,17 @@ module ActionMailer
106
119
  #
107
120
  # def test_parameterized_email
108
121
  # assert_enqueued_email_with ContactMailer, :welcome,
109
- # args: {email: 'user@example.com} do
122
+ # args: {email: 'user@example.com'} do
110
123
  # ContactMailer.with(email: 'user@example.com').welcome.deliver_later
111
124
  # end
112
125
  # end
113
- def assert_enqueued_email_with(mailer, method, args: nil, queue: "mailers", &block)
114
- if args.is_a? Hash
115
- job = ActionMailer::Parameterized::DeliveryJob
116
- args = [mailer.to_s, method.to_s, "deliver_now", args]
126
+ def assert_enqueued_email_with(mailer, method, args: nil, queue: ActionMailer::Base.deliver_later_queue_name || "default", &block)
127
+ args = if args.is_a?(Hash)
128
+ [mailer.to_s, method.to_s, "deliver_now", params: args, args: []]
117
129
  else
118
- job = ActionMailer::DeliveryJob
119
- args = [mailer.to_s, method.to_s, "deliver_now", *args]
130
+ [mailer.to_s, method.to_s, "deliver_now", args: Array(args)]
120
131
  end
121
-
122
- assert_enqueued_with(job: job, args: args, queue: queue, &block)
132
+ assert_enqueued_with(job: mailer.delivery_job, args: args, queue: queue.to_s, &block)
123
133
  end
124
134
 
125
135
  # Asserts that no emails are enqueued for later delivery.
@@ -138,7 +148,15 @@ module ActionMailer
138
148
  # end
139
149
  # end
140
150
  def assert_no_enqueued_emails(&block)
141
- assert_no_enqueued_jobs only: [ ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob ], &block
151
+ assert_enqueued_emails 0, &block
142
152
  end
153
+
154
+ private
155
+ def delivery_job_filter(job)
156
+ job_class = job.is_a?(Hash) ? job.fetch(:job) : job.class
157
+
158
+ Base.descendants.map(&:delivery_job).include?(job_class) ||
159
+ ActionMailer::Parameterized::DeliveryJob == job_class
160
+ end
143
161
  end
144
162
  end
@@ -1,6 +1,6 @@
1
1
  Description:
2
2
  ============
3
- Stubs out a new mailer and its views. Passes the mailer name, either
3
+ Generates a new mailer and its views. Passes the mailer name, either
4
4
  CamelCased or under_scored, and an optional list of emails as arguments.
5
5
 
6
6
  This generates a mailer class in app/mailers and invokes your template
@@ -8,10 +8,9 @@ Description:
8
8
 
9
9
  Example:
10
10
  ========
11
- rails generate mailer Notifications signup forgot_password invoice
11
+ bin/rails generate mailer Notifications signup forgot_password invoice
12
12
 
13
13
  creates a Notifications mailer class, views, and test:
14
14
  Mailer: app/mailers/notifications_mailer.rb
15
15
  Views: app/views/notifications_mailer/signup.text.erb [...]
16
16
  Test: test/mailers/notifications_mailer_test.rb
17
-
@@ -23,7 +23,7 @@ module Rails
23
23
 
24
24
  private
25
25
  def file_name # :doc:
26
- @_file_name ||= super.gsub(/_mailer/i, "")
26
+ @_file_name ||= super.sub(/_mailer\z/i, "")
27
27
  end
28
28
 
29
29
  def application_mailer_file_name
metadata CHANGED
@@ -1,57 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionmailer
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.4.4
4
+ version: 6.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-09 00:00:00.000000000 Z
11
+ date: 2021-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 6.1.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 6.1.1
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: actionpack
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - '='
18
32
  - !ruby/object:Gem::Version
19
- version: 5.2.4.4
33
+ version: 6.1.1
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - '='
25
39
  - !ruby/object:Gem::Version
26
- version: 5.2.4.4
40
+ version: 6.1.1
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: actionview
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - '='
32
46
  - !ruby/object:Gem::Version
33
- version: 5.2.4.4
47
+ version: 6.1.1
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - '='
39
53
  - !ruby/object:Gem::Version
40
- version: 5.2.4.4
54
+ version: 6.1.1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: activejob
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - '='
46
60
  - !ruby/object:Gem::Version
47
- version: 5.2.4.4
61
+ version: 6.1.1
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - '='
53
67
  - !ruby/object:Gem::Version
54
- version: 5.2.4.4
68
+ version: 6.1.1
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: mail
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -86,8 +100,8 @@ dependencies:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
102
  version: '2.0'
89
- description: Email on Rails. Compose, deliver, receive, and test emails using the
90
- familiar controller/view pattern. First-class support for multipart email and attachments.
103
+ description: Email on Rails. Compose, deliver, and test emails using the familiar
104
+ controller/view pattern. First-class support for multipart email and attachments.
91
105
  email: david@loudthinking.com
92
106
  executables: []
93
107
  extensions: []
@@ -104,6 +118,7 @@ files:
104
118
  - lib/action_mailer/gem_version.rb
105
119
  - lib/action_mailer/inline_preview_interceptor.rb
106
120
  - lib/action_mailer/log_subscriber.rb
121
+ - lib/action_mailer/mail_delivery_job.rb
107
122
  - lib/action_mailer/mail_helper.rb
108
123
  - lib/action_mailer/message_delivery.rb
109
124
  - lib/action_mailer/parameterized.rb
@@ -117,13 +132,16 @@ files:
117
132
  - lib/rails/generators/mailer/mailer_generator.rb
118
133
  - lib/rails/generators/mailer/templates/application_mailer.rb.tt
119
134
  - lib/rails/generators/mailer/templates/mailer.rb.tt
120
- homepage: http://rubyonrails.org
135
+ homepage: https://rubyonrails.org
121
136
  licenses:
122
137
  - MIT
123
138
  metadata:
124
- source_code_uri: https://github.com/rails/rails/tree/v5.2.4.4/actionmailer
125
- changelog_uri: https://github.com/rails/rails/blob/v5.2.4.4/actionmailer/CHANGELOG.md
126
- post_install_message:
139
+ bug_tracker_uri: https://github.com/rails/rails/issues
140
+ changelog_uri: https://github.com/rails/rails/blob/v6.1.1/actionmailer/CHANGELOG.md
141
+ documentation_uri: https://api.rubyonrails.org/v6.1.1/
142
+ mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
143
+ source_code_uri: https://github.com/rails/rails/tree/v6.1.1/actionmailer
144
+ post_install_message:
127
145
  rdoc_options: []
128
146
  require_paths:
129
147
  - lib
@@ -131,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
131
149
  requirements:
132
150
  - - ">="
133
151
  - !ruby/object:Gem::Version
134
- version: 2.2.2
152
+ version: 2.5.0
135
153
  required_rubygems_version: !ruby/object:Gem::Requirement
136
154
  requirements:
137
155
  - - ">="
@@ -139,8 +157,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
157
  version: '0'
140
158
  requirements:
141
159
  - none
142
- rubygems_version: 3.1.2
143
- signing_key:
160
+ rubygems_version: 3.2.3
161
+ signing_key:
144
162
  specification_version: 4
145
- summary: Email composition, delivery, and receiving framework (part of Rails).
163
+ summary: Email composition and delivery framework (part of Rails).
146
164
  test_files: []