postmortem 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +4 -46
- data/.ruby-version +1 -1
- data/Gemfile +0 -2
- data/Makefile +4 -0
- data/README.md +20 -12
- data/layout/default.html.erb +53 -13
- data/layout/dependencies.css +0 -4
- data/layout/dependencies.js +3 -1
- data/layout/favicon.b64 +1 -0
- data/layout/layout.css +156 -16
- data/layout/layout.js +303 -78
- data/layout/postmortem_identity.html.erb +20 -0
- data/layout/{index.html.erb → postmortem_index.html.erb} +3 -6
- data/lib/postmortem.rb +5 -2
- data/lib/postmortem/adapters.rb +1 -1
- data/lib/postmortem/adapters/action_mailer.rb +6 -41
- data/lib/postmortem/adapters/base.rb +35 -2
- data/lib/postmortem/adapters/mail.rb +3 -3
- data/lib/postmortem/adapters/pony.rb +3 -6
- data/lib/postmortem/delivery.rb +11 -9
- data/lib/postmortem/identity.rb +20 -0
- data/lib/postmortem/index.rb +12 -4
- data/lib/postmortem/layout.rb +8 -0
- data/lib/postmortem/plugins/action_mailer.rb +7 -0
- data/lib/postmortem/version.rb +1 -1
- data/postmortem.gemspec +6 -3
- metadata +52 -8
- data/doc/screenshot.png +0 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<body>
|
4
|
+
<div data-uuid="<%= uuid %>" id="identity">
|
5
|
+
</div>
|
6
|
+
<script>
|
7
|
+
window.addEventListener('message', function (ev) {
|
8
|
+
const identity = document.querySelector('#identity');
|
9
|
+
const uuid = identity.dataset.uuid;
|
10
|
+
const type = 'identity';
|
11
|
+
ev.source.postMessage({ uuid, type }, '*');
|
12
|
+
});
|
13
|
+
|
14
|
+
setInterval(function () {
|
15
|
+
window.location.reload();
|
16
|
+
}, 3000);
|
17
|
+
|
18
|
+
</script>
|
19
|
+
</body>
|
20
|
+
</html>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<body>
|
4
|
-
<div data-uuid="<%=
|
4
|
+
<div data-uuid="<%= uuid %>" id="index">
|
5
5
|
### INDEX START
|
6
6
|
<% encoded_index.each do |encoded| -%>
|
7
7
|
<%= encoded %>
|
@@ -13,16 +13,13 @@
|
|
13
13
|
const filter = (line) => line !== '' && !line.startsWith('### INDEX');
|
14
14
|
const index = document.querySelector('#index');
|
15
15
|
const uuid = index.dataset.uuid;
|
16
|
+
const type = 'index';
|
16
17
|
const mails = index.innerText
|
17
18
|
.split('\n')
|
18
19
|
.filter(filter)
|
19
20
|
.map(line => JSON.parse(atob(line)));
|
20
|
-
ev.source.postMessage({ uuid, mails }, '*');
|
21
|
+
ev.source.postMessage({ uuid, type, mails }, '*');
|
21
22
|
});
|
22
|
-
|
23
|
-
setInterval(function () {
|
24
|
-
window.location.reload();
|
25
|
-
}, 3000);
|
26
23
|
</script>
|
27
24
|
</body>
|
28
25
|
</html>
|
data/lib/postmortem.rb
CHANGED
@@ -8,12 +8,15 @@ require 'mail'
|
|
8
8
|
require 'erb'
|
9
9
|
require 'json'
|
10
10
|
require 'cgi'
|
11
|
+
require 'digest'
|
12
|
+
require 'securerandom'
|
11
13
|
|
12
14
|
require 'postmortem/version'
|
13
15
|
require 'postmortem/adapters'
|
14
16
|
require 'postmortem/delivery'
|
15
17
|
require 'postmortem/layout'
|
16
18
|
require 'postmortem/configuration'
|
19
|
+
require 'postmortem/identity'
|
17
20
|
require 'postmortem/index'
|
18
21
|
|
19
22
|
# HTML email inspection tool.
|
@@ -54,7 +57,7 @@ module Postmortem
|
|
54
57
|
private
|
55
58
|
|
56
59
|
def log_delivery(delivery)
|
57
|
-
output_file.write(colorized(delivery.
|
60
|
+
output_file.write("#{colorized(delivery.uri)}\n")
|
58
61
|
output_file.flush
|
59
62
|
end
|
60
63
|
|
@@ -65,7 +68,7 @@ module Postmortem
|
|
65
68
|
end
|
66
69
|
|
67
70
|
def output_file
|
68
|
-
return
|
71
|
+
return $stdout if config.log_path.nil?
|
69
72
|
|
70
73
|
@output_file ||= File.open(config.log_path, mode: 'a')
|
71
74
|
end
|
data/lib/postmortem/adapters.rb
CHANGED
@@ -7,53 +7,18 @@ module Postmortem
|
|
7
7
|
private
|
8
8
|
|
9
9
|
def adapted
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
cc: mail.cc,
|
15
|
-
bcc: normalized_bcc,
|
16
|
-
subject: mail.subject,
|
17
|
-
text_body: text_part,
|
18
|
-
html_body: html_part
|
19
|
-
}
|
20
|
-
end
|
21
|
-
|
22
|
-
def text_part
|
23
|
-
return nil unless text?
|
24
|
-
return mail.body.decoded unless mail.text_part
|
25
|
-
|
26
|
-
mail.text_part.decoded
|
27
|
-
end
|
28
|
-
|
29
|
-
def html_part
|
30
|
-
return nil unless html?
|
31
|
-
return mail.body.decoded unless mail.html_part
|
32
|
-
|
33
|
-
mail.html_part.decoded
|
34
|
-
end
|
35
|
-
|
36
|
-
def mail
|
37
|
-
@mail ||= ::Mail.new(@data[:mail])
|
10
|
+
%i[from reply_to to cc subject message_id]
|
11
|
+
.map { |field| [field, mail.public_send(field)] }
|
12
|
+
.to_h
|
13
|
+
.merge({ text_body: text_part, html_body: html_part, bcc: normalized_bcc })
|
38
14
|
end
|
39
15
|
|
40
16
|
def normalized_bcc
|
41
17
|
::Mail.new(to: @data[:bcc]).to
|
42
18
|
end
|
43
19
|
|
44
|
-
def
|
45
|
-
|
46
|
-
return true if mail.content_type.include?('text/plain')
|
47
|
-
return true if mail.multipart? && mail.text_part
|
48
|
-
|
49
|
-
false
|
50
|
-
end
|
51
|
-
|
52
|
-
def html?
|
53
|
-
return true if mail.has_content_type? && mail.content_type.include?('text/html')
|
54
|
-
return true if mail.multipart? && mail.html_part
|
55
|
-
|
56
|
-
false
|
20
|
+
def mail
|
21
|
+
@mail ||= ::Mail.new(@data[:mail])
|
57
22
|
end
|
58
23
|
end
|
59
24
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Postmortem
|
4
4
|
module Adapters
|
5
|
-
FIELDS = %i[from reply_to to cc bcc subject text_body html_body].freeze
|
5
|
+
FIELDS = %i[from reply_to to cc bcc subject text_body html_body message_id].freeze
|
6
6
|
|
7
7
|
# Base interface implementation for all Postmortem adapters.
|
8
8
|
class Base
|
@@ -16,7 +16,11 @@ module Postmortem
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def serializable
|
19
|
-
FIELDS.map { |field| [camelize(field.to_s), public_send(field)] }.to_h
|
19
|
+
(%i[id] + FIELDS).map { |field| [camelize(field.to_s), public_send(field)] }.to_h
|
20
|
+
end
|
21
|
+
|
22
|
+
def id
|
23
|
+
@id ||= SecureRandom.uuid
|
20
24
|
end
|
21
25
|
|
22
26
|
FIELDS.each do |method_name|
|
@@ -46,6 +50,35 @@ module Postmortem
|
|
46
50
|
.map { |substring, index| index.zero? ? substring : substring.capitalize }
|
47
51
|
.join
|
48
52
|
end
|
53
|
+
|
54
|
+
def text_part
|
55
|
+
return nil unless text?
|
56
|
+
return mail.body.decoded unless mail.text_part
|
57
|
+
|
58
|
+
mail.text_part.decoded
|
59
|
+
end
|
60
|
+
|
61
|
+
def html_part
|
62
|
+
return nil unless html?
|
63
|
+
return mail.body.decoded unless mail.html_part
|
64
|
+
|
65
|
+
mail.html_part.decoded
|
66
|
+
end
|
67
|
+
|
68
|
+
def text?
|
69
|
+
return true unless mail.has_content_type?
|
70
|
+
return true if mail.content_type.include?('text/plain')
|
71
|
+
return true if mail.multipart? && mail.text_part
|
72
|
+
|
73
|
+
false
|
74
|
+
end
|
75
|
+
|
76
|
+
def html?
|
77
|
+
return true if mail.has_content_type? && mail.content_type.include?('text/html')
|
78
|
+
return true if mail.multipart? && mail.html_part
|
79
|
+
|
80
|
+
false
|
81
|
+
end
|
49
82
|
end
|
50
83
|
end
|
51
84
|
end
|
@@ -7,10 +7,10 @@ module Postmortem
|
|
7
7
|
private
|
8
8
|
|
9
9
|
def adapted
|
10
|
-
%i[from reply_to to cc bcc subject]
|
11
|
-
.map { |field| [field,
|
10
|
+
%i[from reply_to to cc bcc subject message_id]
|
11
|
+
.map { |field| [field, mail.public_send(field)] }
|
12
12
|
.to_h
|
13
|
-
.merge({ text_body:
|
13
|
+
.merge({ text_body: text_part, html_body: html_part })
|
14
14
|
end
|
15
15
|
|
16
16
|
def mail
|
@@ -8,14 +8,11 @@ module Postmortem
|
|
8
8
|
|
9
9
|
def adapted
|
10
10
|
{
|
11
|
-
from: mail.from,
|
12
|
-
reply_to: mail.reply_to,
|
13
|
-
to: mail.to,
|
14
|
-
cc: mail.cc,
|
15
|
-
bcc: mail.bcc,
|
11
|
+
from: mail.from, reply_to: mail.reply_to, to: mail.to, cc: mail.cc, bcc: mail.bcc,
|
16
12
|
subject: mail.subject,
|
17
13
|
text_body: @data[:body],
|
18
|
-
html_body: @data[:html_body]
|
14
|
+
html_body: @data[:html_body],
|
15
|
+
message_id: mail.message_id # We use a synthetic Mail instance so this is a bit useless.
|
19
16
|
}
|
20
17
|
end
|
21
18
|
|
data/lib/postmortem/delivery.rb
CHANGED
@@ -7,8 +7,9 @@ module Postmortem
|
|
7
7
|
|
8
8
|
def initialize(mail)
|
9
9
|
@mail = mail
|
10
|
-
@path = Postmortem.config.preview_directory.join('
|
11
|
-
@index_path = Postmortem.config.preview_directory.join('
|
10
|
+
@path = Postmortem.config.preview_directory.join('index.html')
|
11
|
+
@index_path = Postmortem.config.preview_directory.join('postmortem_index.html')
|
12
|
+
@identity_path = Postmortem.config.preview_directory.join('postmortem_identity.html')
|
12
13
|
end
|
13
14
|
|
14
15
|
def record
|
@@ -16,20 +17,21 @@ module Postmortem
|
|
16
17
|
content = Layout.new(@mail).content
|
17
18
|
path.write(content)
|
18
19
|
index_path.write(index.content)
|
20
|
+
@identity_path.write(identity.content)
|
21
|
+
end
|
22
|
+
|
23
|
+
def uri
|
24
|
+
"file://#{path}##{@mail.id}"
|
19
25
|
end
|
20
26
|
|
21
27
|
private
|
22
28
|
|
23
29
|
def index
|
24
|
-
@index ||= Index.new(index_path, path,
|
25
|
-
end
|
26
|
-
|
27
|
-
def timestamp
|
28
|
-
@timestamp ||= Time.now
|
30
|
+
@index ||= Index.new(index_path, path, @mail)
|
29
31
|
end
|
30
32
|
|
31
|
-
def
|
32
|
-
|
33
|
+
def identity
|
34
|
+
@identity ||= Identity.new
|
33
35
|
end
|
34
36
|
|
35
37
|
def subject
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Postmortem
|
4
|
+
# Provides an HTML document that announces a unique ID to a parent page via JS message events.
|
5
|
+
class Identity
|
6
|
+
def content
|
7
|
+
ERB.new(File.read(path), nil, '-').result(binding)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def uuid
|
13
|
+
@uuid ||= SecureRandom.uuid
|
14
|
+
end
|
15
|
+
|
16
|
+
def path
|
17
|
+
File.expand_path(File.join(__dir__, '..', '..', 'layout', 'postmortem_identity.html.erb'))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/postmortem/index.rb
CHANGED
@@ -3,10 +3,9 @@
|
|
3
3
|
module Postmortem
|
4
4
|
# Generates and parses an index of previously-sent emails.
|
5
5
|
class Index
|
6
|
-
def initialize(index_path, mail_path,
|
6
|
+
def initialize(index_path, mail_path, mail)
|
7
7
|
@index_path = index_path
|
8
8
|
@mail_path = mail_path
|
9
|
-
@timestamp = timestamp.iso8601
|
10
9
|
@mail = mail
|
11
10
|
end
|
12
11
|
|
@@ -21,6 +20,14 @@ module Postmortem
|
|
21
20
|
|
22
21
|
private
|
23
22
|
|
23
|
+
def uuid
|
24
|
+
@uuid ||= SecureRandom.uuid
|
25
|
+
end
|
26
|
+
|
27
|
+
def timestamp
|
28
|
+
Time.now.iso8601
|
29
|
+
end
|
30
|
+
|
24
31
|
def encoded_index
|
25
32
|
return [encoded_mail] unless @index_path.file?
|
26
33
|
|
@@ -34,8 +41,9 @@ module Postmortem
|
|
34
41
|
def mail_data
|
35
42
|
{
|
36
43
|
subject: @mail.subject || '(no subject)',
|
37
|
-
timestamp:
|
44
|
+
timestamp: timestamp,
|
38
45
|
path: @mail_path,
|
46
|
+
id: @mail.id,
|
39
47
|
content: @mail.serializable
|
40
48
|
}
|
41
49
|
end
|
@@ -54,7 +62,7 @@ module Postmortem
|
|
54
62
|
end
|
55
63
|
|
56
64
|
def template_path
|
57
|
-
File.expand_path(File.join(__dir__, '..', '..', 'layout', '
|
65
|
+
File.expand_path(File.join(__dir__, '..', '..', 'layout', 'postmortem_index.html.erb'))
|
58
66
|
end
|
59
67
|
end
|
60
68
|
end
|
data/lib/postmortem/layout.rb
CHANGED
@@ -37,6 +37,14 @@ module Postmortem
|
|
37
37
|
default_layout_directory.join('headers_template.html').read
|
38
38
|
end
|
39
39
|
|
40
|
+
def favicon_b64
|
41
|
+
default_layout_directory.join('favicon.b64').read
|
42
|
+
end
|
43
|
+
|
44
|
+
def upload_url
|
45
|
+
ENV.fetch('POSTMORTEM_DELIVERY_URL', 'https://postmortem.delivery/emails')
|
46
|
+
end
|
47
|
+
|
40
48
|
private
|
41
49
|
|
42
50
|
def default_layout_directory
|
@@ -1,5 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
ActiveSupport::Notifications.subscribe 'deliver.action_mailer' do |*args|
|
4
|
+
delivery_method = Rails.try(:application)
|
5
|
+
&.try(:config)
|
6
|
+
&.try(:action_mailer)
|
7
|
+
&.try(:delivery_method)
|
8
|
+
next if delivery_method.nil?
|
9
|
+
next if %i[sendmail smtp].include?(delivery_method&.to_sym) # Delegate to Mail plugin.
|
10
|
+
|
4
11
|
Postmortem.record_delivery(Postmortem::Adapters::ActionMailer.new(args.extract_options!))
|
5
12
|
end
|
data/lib/postmortem/version.rb
CHANGED
data/postmortem.gemspec
CHANGED
@@ -12,14 +12,14 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = 'Preview HTML emails in your browser during development'
|
13
13
|
spec.homepage = 'https://github.com/bobf/postmortem'
|
14
14
|
spec.license = 'MIT'
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
|
16
16
|
|
17
17
|
spec.metadata['homepage_uri'] = spec.homepage
|
18
18
|
spec.metadata['source_code_uri'] = spec.homepage
|
19
19
|
spec.metadata['changelog_uri'] = 'https://github.com/bobf/postmortem/blob/master/README.md'
|
20
20
|
|
21
21
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
22
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|doc)/}) }
|
23
23
|
end
|
24
24
|
spec.bindir = 'bin'
|
25
25
|
spec.executables = []
|
@@ -28,10 +28,13 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_runtime_dependency 'mail', '~> 2.7'
|
29
29
|
|
30
30
|
spec.add_development_dependency 'actionmailer', '~> 6.0'
|
31
|
+
spec.add_development_dependency 'devpack', '~> 0.3.2'
|
32
|
+
spec.add_development_dependency 'faker', '~> 2.17'
|
31
33
|
spec.add_development_dependency 'pony', '~> 1.13'
|
32
34
|
spec.add_development_dependency 'rspec', '~> 3.9'
|
33
35
|
spec.add_development_dependency 'rspec-its', '~> 1.3'
|
34
|
-
spec.add_development_dependency 'rubocop', '~>
|
36
|
+
spec.add_development_dependency 'rubocop', '~> 1.10'
|
37
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
|
35
38
|
spec.add_development_dependency 'strong_versions', '~> 0.4.5'
|
36
39
|
spec.add_development_dependency 'timecop', '~> 0.9.1'
|
37
40
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postmortem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Farrell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mail
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '6.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: devpack
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.3.2
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.3.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: faker
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.17'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.17'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: pony
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +114,28 @@ dependencies:
|
|
86
114
|
requirements:
|
87
115
|
- - "~>"
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
117
|
+
version: '1.10'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.10'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.2'
|
90
132
|
type: :development
|
91
133
|
prerelease: false
|
92
134
|
version_requirements: !ruby/object:Gem::Requirement
|
93
135
|
requirements:
|
94
136
|
- - "~>"
|
95
137
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
138
|
+
version: '2.2'
|
97
139
|
- !ruby/object:Gem::Dependency
|
98
140
|
name: strong_versions
|
99
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,14 +182,15 @@ files:
|
|
140
182
|
- Rakefile
|
141
183
|
- bin/console
|
142
184
|
- bin/setup
|
143
|
-
- doc/screenshot.png
|
144
185
|
- layout/default.html.erb
|
145
186
|
- layout/dependencies.css
|
146
187
|
- layout/dependencies.js
|
188
|
+
- layout/favicon.b64
|
147
189
|
- layout/headers_template.html
|
148
|
-
- layout/index.html.erb
|
149
190
|
- layout/layout.css
|
150
191
|
- layout/layout.js
|
192
|
+
- layout/postmortem_identity.html.erb
|
193
|
+
- layout/postmortem_index.html.erb
|
151
194
|
- lib/postmortem.rb
|
152
195
|
- lib/postmortem/adapters.rb
|
153
196
|
- lib/postmortem/adapters/action_mailer.rb
|
@@ -156,6 +199,7 @@ files:
|
|
156
199
|
- lib/postmortem/adapters/pony.rb
|
157
200
|
- lib/postmortem/configuration.rb
|
158
201
|
- lib/postmortem/delivery.rb
|
202
|
+
- lib/postmortem/identity.rb
|
159
203
|
- lib/postmortem/index.rb
|
160
204
|
- lib/postmortem/layout.rb
|
161
205
|
- lib/postmortem/plugins/action_mailer.rb
|
@@ -178,7 +222,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
178
222
|
requirements:
|
179
223
|
- - ">="
|
180
224
|
- !ruby/object:Gem::Version
|
181
|
-
version: 2.
|
225
|
+
version: 2.5.0
|
182
226
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
227
|
requirements:
|
184
228
|
- - ">="
|
@@ -186,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
230
|
version: '0'
|
187
231
|
requirements: []
|
188
232
|
rubyforge_project:
|
189
|
-
rubygems_version: 2.7.6
|
233
|
+
rubygems_version: 2.7.6.2
|
190
234
|
signing_key:
|
191
235
|
specification_version: 4
|
192
236
|
summary: Development HTML Email Inspection Tool
|