crosby 0.1.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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +211 -0
- data/Rakefile +7 -0
- data/crosby.gemspec +26 -0
- data/lib/crosby/configuration.rb +25 -0
- data/lib/crosby/diff.rb +81 -0
- data/lib/crosby/errors.rb +5 -0
- data/lib/crosby/exporter.rb +108 -0
- data/lib/crosby/rspec_helper.rb +31 -0
- data/lib/crosby/tasks.rb +44 -0
- data/lib/crosby/version.rb +3 -0
- data/lib/crosby.rb +20 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7b6644351cbd94255b116edf49999a4aa7f8a202
|
4
|
+
data.tar.gz: d206eadba0406bd3d0df0f7c07f7d819ec6eb38a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4a8bbab03e19b11417d517d44b76d7fa59c7a09d4d70fe35dc9ebb660538842d0ad8d431589b7296e0c431fb4575f174e314e16ffd46a41d91c82c393d3a6b90
|
7
|
+
data.tar.gz: 44460e785fa692c1249d98df48c912bd50a8b55f4fe6773d00c0dba1ddff5aeed78545110ffacf60c97af8995c47bd659d275010c34d847b4a2bd58ee7092e5d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Dan Matthews
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
# Crosby
|
2
|
+
|
3
|
+
Allows for quality checks on `ActionMailer` emails when migrating to new systems.
|
4
|
+
|
5
|
+
http://en.wikipedia.org/wiki/Philip_B._Crosby
|
6
|
+
|
7
|
+
```
|
8
|
+
Crosby's response to the quality crisis was the principle of
|
9
|
+
"doing it right the first time" (DIRFT). He also included four major principles:
|
10
|
+
|
11
|
+
The definition of quality is conformance to requirements
|
12
|
+
(requirements meaning both the product and the customer's requirements)
|
13
|
+
The system of quality is prevention
|
14
|
+
The performance standard is zero defects (relative to requirements)
|
15
|
+
The measurement of quality is the price of nonconformance
|
16
|
+
```
|
17
|
+
|
18
|
+
This is a work in progress which came out of a need to compare emails generated
|
19
|
+
on our 'nextjenn' platform to emails generated in our legacy codebase.
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
Add this line to your application's Gemfile:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem "crosby"
|
27
|
+
```
|
28
|
+
|
29
|
+
And then execute:
|
30
|
+
|
31
|
+
$ bundle
|
32
|
+
|
33
|
+
Or install it yourself as:
|
34
|
+
|
35
|
+
$ gem install crosby
|
36
|
+
|
37
|
+
## Configuration
|
38
|
+
|
39
|
+
Crosby has 2 configurable values, `app_name` and `export_path` with the
|
40
|
+
following defaults:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
Crosby.config
|
44
|
+
# => { :app_name => "6f292f17", :export_path => "tmp/crosby" }
|
45
|
+
```
|
46
|
+
|
47
|
+
NOTE: The value of `app_name` is randomized and will not stay consistent across
|
48
|
+
application loads unless specifically set. Config options can be set via a
|
49
|
+
block.
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Crosby.config do |c|
|
53
|
+
c.app_name = "ExampleApp"
|
54
|
+
c.export_path = "../crosby_files"
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
## Usage
|
59
|
+
|
60
|
+
### Basic Usage
|
61
|
+
|
62
|
+
Crosby exports a slightly curated version of `Mail::Message` objects produced
|
63
|
+
by `ActionMailer` subclasses to a `.crosby` file. The class responsible for
|
64
|
+
producing this file is `Crosby::Exporter`.
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
exporter = Crosby::Exporter.new(
|
68
|
+
MailerClass, :method, 'a-unique-id'[, arg1[, arg2[, ...]]]
|
69
|
+
)
|
70
|
+
|
71
|
+
exporter.export
|
72
|
+
```
|
73
|
+
|
74
|
+
Also available is the `Crosby::Exporter#to_s` method which will return the
|
75
|
+
`.crosby` file's contents as a string.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
exporter.to_s
|
79
|
+
```
|
80
|
+
|
81
|
+
### RSpec
|
82
|
+
|
83
|
+
`Crosby::RSpecHelper` works with RSpec 1, 2 & 3, and adds the `#crosby_email`
|
84
|
+
helper method. You can use this method to create `.crosby` files inside your
|
85
|
+
existing tests.
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
# spec_helper.rb
|
89
|
+
|
90
|
+
require "crosby/rspec_helper"
|
91
|
+
|
92
|
+
Crosby.config do |c|
|
93
|
+
# ...
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
# spec/mailers/example_mailer_spec.rb
|
99
|
+
require "spec_helper"
|
100
|
+
|
101
|
+
describe ExampleMailer do
|
102
|
+
context "#notify" do
|
103
|
+
it "should send a notification email" do
|
104
|
+
mailer = ExampleMailer.notify(arg1, arg1)
|
105
|
+
|
106
|
+
# becomes
|
107
|
+
mailer = crosby_email(ExampleMailer, :notify, arg1, arg2)
|
108
|
+
|
109
|
+
# ...
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# ...
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
In the above example, Crosby will generate a uuid based on the mailer class,
|
118
|
+
method name and argument values. While this is fine, it may be helpful to
|
119
|
+
implicitly set the uuid. You can do this by setting the `@crosby_uuid` instance
|
120
|
+
variable in your test.
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
# spec/mailers/example_mailer_spec.rb
|
124
|
+
require "spec_helper"
|
125
|
+
|
126
|
+
describe ExampleMailer do
|
127
|
+
context "#notify" do
|
128
|
+
it "should send a notification email" do
|
129
|
+
@crosby_uuid = "example_mailer_notify"
|
130
|
+
mailer = crosby_email(ExampleMailer, :notify, arg1, arg2)
|
131
|
+
|
132
|
+
# ...
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# ...
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
### Generating a diff
|
141
|
+
|
142
|
+
`Crosby::Diff` is responsible for comparing files of the same uuid to eachother.
|
143
|
+
There must be at least 2 files with the same uuid present in the configured
|
144
|
+
directory for a diff to be generated. If there are more than 2 files for a
|
145
|
+
given uuid, a diff will be generated for each unique pair of files.
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
Crosby::Diff.compare("example_mailer_notify")
|
149
|
+
# => [diff_str, ...]
|
150
|
+
```
|
151
|
+
|
152
|
+
`Crosby::Diff.compare` returns an array of diff strings, one for each file pair.
|
153
|
+
When no pairs are present, `compare` returns an empty array.
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
Crosby::Diff.compare("not-an-existing-uuid")
|
157
|
+
# => []
|
158
|
+
```
|
159
|
+
|
160
|
+
It also accepts an optional block, to be called once per diff string.
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
Crosby::Diff.compare("example_mailer_notify") { |diff| puts diff }
|
164
|
+
# diff output
|
165
|
+
# => [diff_str, ...]
|
166
|
+
```
|
167
|
+
|
168
|
+
`Crosby::Diff.compare` and `Crosby::Diff.new` both accept an options hash to
|
169
|
+
override `Crosby.config` settings.
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
Crosby::Diff.compare("example_mailer_notify", :export_path => "../crosby_files")
|
173
|
+
Crosby::Diff.new("example_mailer_notify", :export_path => "../crosby_files")
|
174
|
+
```
|
175
|
+
|
176
|
+
`Crosby::Diff` uses the excellent [Diffy gem](https://github.com/samg/diffy)
|
177
|
+
behind the scenes. If you would like access to the `Diffy::Diff` objects, you
|
178
|
+
can access them through the `Crosby::Diff#diffs` method.
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
cdiff = Crosby::Diff.new("example_mailer_notify")
|
182
|
+
cdiff.diffs
|
183
|
+
# => [ [#<Diffy::Diff:0x00000000>, #<Diffy::Diff:0x00000001], [..., ...], ... ]
|
184
|
+
```
|
185
|
+
|
186
|
+
### Rake
|
187
|
+
|
188
|
+
Crosby provides a simple `rake crosby:diff` command which outputs diffs for all
|
189
|
+
of the uuids represented by files in the directory specified at
|
190
|
+
`Crosby.config[:export_path]`.
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
# Rakefile
|
194
|
+
require "crosby/tasks"
|
195
|
+
|
196
|
+
Crosby.config do |c|
|
197
|
+
c.export_path = "../crosby_files"
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
201
|
+
```sh
|
202
|
+
bundle exec rake crosby:diff
|
203
|
+
```
|
204
|
+
|
205
|
+
## Contributing
|
206
|
+
|
207
|
+
1. Fork it ( https://github.com/[my-github-username]/crosby/fork )
|
208
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
209
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
210
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
211
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/crosby.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "crosby/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "crosby"
|
8
|
+
spec.version = Crosby::VERSION
|
9
|
+
spec.authors = ["Dan Matthews"]
|
10
|
+
spec.email = ["dan.matthews@teamsnap.com"]
|
11
|
+
spec.summary = %q{Quality Assurance for ActionMailer}
|
12
|
+
spec.description = %q{Allows generation and comparison of email output}
|
13
|
+
spec.homepage = "https://github.com/teamsnap/crosby"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
|
24
|
+
spec.add_dependency "diffy", "~> 3.0"
|
25
|
+
spec.add_dependency "nokogiri", "~> 1.6"
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
|
3
|
+
module Crosby
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :app_name, :export_path
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
self.app_name = SecureRandom.hex(4)
|
9
|
+
self.export_path = "tmp/crosby"
|
10
|
+
end
|
11
|
+
|
12
|
+
def config(&block)
|
13
|
+
block.call(self) if block_given?
|
14
|
+
to_hsh
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hsh
|
18
|
+
{
|
19
|
+
:app_name => app_name,
|
20
|
+
:export_path => export_path
|
21
|
+
}
|
22
|
+
end
|
23
|
+
alias :to_h :to_hsh
|
24
|
+
end
|
25
|
+
end
|
data/lib/crosby/diff.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require "diffy"
|
2
|
+
|
3
|
+
module Crosby
|
4
|
+
class Diff
|
5
|
+
class << self
|
6
|
+
def compare(uuid, options = {}, &block)
|
7
|
+
new(uuid, options).compare(&block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(uuid, options = {})
|
12
|
+
@uuid = uuid
|
13
|
+
@config = Crosby.config.merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
# https://github.com/samg/diffy#supported-formats
|
17
|
+
def compare(format = :color, &block)
|
18
|
+
diffs.map { |diff|
|
19
|
+
out = diff.to_s(format)
|
20
|
+
block_given? ? block.call(out) : out
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def diffs
|
25
|
+
@diffs ||= [].tap { |diffs|
|
26
|
+
pairs.each { |pair|
|
27
|
+
diffs << Diffy::Diff.new(
|
28
|
+
*pair,
|
29
|
+
:context => 0,
|
30
|
+
:include_diff_info => true,
|
31
|
+
:source => "files"
|
32
|
+
)
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def build_file_paths(pairs)
|
40
|
+
pairs.map { |pair|
|
41
|
+
pair.map { |filename|
|
42
|
+
File.realpath(File.join(@config[:export_path], filename))
|
43
|
+
}
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def files
|
48
|
+
matcher = Regexp.new("#{@uuid}\\.crosby\\z")
|
49
|
+
|
50
|
+
Dir.new(@config[:export_path]).entries.select { |entry|
|
51
|
+
entry =~ matcher ? true : false
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def pairs
|
56
|
+
[
|
57
|
+
:unique_pairs,
|
58
|
+
:sort_pairs,
|
59
|
+
:build_file_paths
|
60
|
+
].reduce([]) { |obj, meth|
|
61
|
+
send(meth, obj)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def sort_pairs(pairs)
|
66
|
+
pairs.map { |pair|
|
67
|
+
pair.first =~ Regexp.new(@config[:app_name]) ? pair.reverse : pair
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def unique_pairs(arr)
|
72
|
+
arr.tap { |pairs|
|
73
|
+
files.repeated_permutation(2) { |permutation|
|
74
|
+
pairs << permutation.sort unless permutation.uniq.length == 1
|
75
|
+
}
|
76
|
+
|
77
|
+
pairs.uniq!
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "securerandom"
|
3
|
+
require "nokogiri"
|
4
|
+
|
5
|
+
module Crosby
|
6
|
+
class Exporter
|
7
|
+
WRITE_MODE = "w"
|
8
|
+
|
9
|
+
attr_reader :mail
|
10
|
+
|
11
|
+
def initialize(mailer, method, uuid = SecureRandom.hex(8), *args)
|
12
|
+
@args = args
|
13
|
+
@mailer = mailer
|
14
|
+
@method = method
|
15
|
+
@uuid = uuid
|
16
|
+
@version = Crosby.action_mailer_version
|
17
|
+
|
18
|
+
config = Crosby.config
|
19
|
+
@path = config[:export_path]
|
20
|
+
@app_name = config[:app_name]
|
21
|
+
end
|
22
|
+
|
23
|
+
def export
|
24
|
+
ensure_path_exists
|
25
|
+
write
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
create_mail unless mail
|
31
|
+
|
32
|
+
[
|
33
|
+
"TO: #{mail.to}",
|
34
|
+
"CC: #{mail.cc}",
|
35
|
+
"BCC: #{mail.bcc}",
|
36
|
+
"REPLY TO: #{mail.reply_to}",
|
37
|
+
"FROM: #{mail.from}",
|
38
|
+
"HTML:",
|
39
|
+
commonize_html(mail.html_part.body.raw_source),
|
40
|
+
"TEXT:",
|
41
|
+
commonize_text(mail.text_part.body.raw_source)
|
42
|
+
].join("\n")
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def commonize_html(str)
|
48
|
+
commonize_text(str)
|
49
|
+
compact(Nokogiri::HTML::Document.parse(commonize_text(str)).to_s)
|
50
|
+
end
|
51
|
+
|
52
|
+
def commonize_text(str)
|
53
|
+
str
|
54
|
+
.gsub(/([^=])=\n/, '\1') # single quotes required for encoding
|
55
|
+
.gsub(/=3D/, "=")
|
56
|
+
end
|
57
|
+
|
58
|
+
def compact(str)
|
59
|
+
str
|
60
|
+
.each_line
|
61
|
+
.reject(&:blank?)
|
62
|
+
.map{ |line|
|
63
|
+
line
|
64
|
+
.gsub(/\s+/, " ")
|
65
|
+
.gsub(/^ /, "")
|
66
|
+
.gsub(/ $/, "\n")
|
67
|
+
.gsub(/></, ">\n<")
|
68
|
+
}
|
69
|
+
.join
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_mail
|
73
|
+
method = @method
|
74
|
+
|
75
|
+
case @version::MAJOR
|
76
|
+
when 2
|
77
|
+
method = "create_#{method}"
|
78
|
+
when 3
|
79
|
+
# supported, no additional action required
|
80
|
+
when 4
|
81
|
+
# supported, no additional action required
|
82
|
+
else
|
83
|
+
raise Crosby::UnsupportedVersion, "We do not yet support version " \
|
84
|
+
"#{@version::STRING} of ActionMailer"
|
85
|
+
end
|
86
|
+
|
87
|
+
@mail = @mailer.send(method, *@args)
|
88
|
+
end
|
89
|
+
|
90
|
+
def ensure_path_exists
|
91
|
+
@dir = Dir.new(FileUtils.mkdir_p(@path).first)
|
92
|
+
end
|
93
|
+
|
94
|
+
def file(&block)
|
95
|
+
File.open(filename, WRITE_MODE, &block)
|
96
|
+
end
|
97
|
+
|
98
|
+
def filename
|
99
|
+
File.join(@dir, "#{@mailer.name}.#{@method}.#{@app_name}.#{@uuid}.crosby")
|
100
|
+
end
|
101
|
+
|
102
|
+
def write
|
103
|
+
file do |f|
|
104
|
+
f.write(to_s)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "base64"
|
2
|
+
require "crosby"
|
3
|
+
|
4
|
+
module Crosby
|
5
|
+
module RSpecHelper
|
6
|
+
def crosby_email(mailer, method, *args)
|
7
|
+
@crosby_uuid ||= generate_crosby_digest(mailer, method, *args)
|
8
|
+
exporter = Crosby::Exporter.new(mailer, method, @crosby_uuid, *args)
|
9
|
+
return (exporter.export ? exporter.mail : false)
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_crosby_digest(*args)
|
13
|
+
Base64.encode64(args.map(&:to_s).join("|")).chomp
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
if Kernel.const_defined?(:Spec)
|
20
|
+
class ActiveSupport::TestCase
|
21
|
+
include Crosby::RSpecHelper
|
22
|
+
end
|
23
|
+
else
|
24
|
+
RSpec.configure do |c|
|
25
|
+
c.include Crosby::RSpecHelper
|
26
|
+
end
|
27
|
+
end
|
28
|
+
rescue NameError
|
29
|
+
raise Crosby::MissingRSpec, "Crosby can't find RSpec at the Spec::Runner " \
|
30
|
+
"or RSpec namespace."
|
31
|
+
end
|
data/lib/crosby/tasks.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require "crosby"
|
2
|
+
|
3
|
+
module Crosby
|
4
|
+
class Tasks
|
5
|
+
include Rake::DSL if defined? Rake::DSL
|
6
|
+
|
7
|
+
def install_tasks
|
8
|
+
namespace :crosby do
|
9
|
+
desc "displays all diffs in the configured folder " +
|
10
|
+
"(#{Crosby.config[:export_path]})"
|
11
|
+
task :diff do
|
12
|
+
each_uuid do |uuid|
|
13
|
+
puts "============================================================"
|
14
|
+
puts "UUID: #{uuid}"
|
15
|
+
puts "============================================================"
|
16
|
+
Crosby::Diff.compare(uuid) { |diff| puts diff }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def each_uuid(&block)
|
25
|
+
[].tap { |uuids|
|
26
|
+
Dir.new(Crosby.config[:export_path]).each { |filename|
|
27
|
+
uuids << extract_uuid(filename) if filename =~ /\.crosby$/
|
28
|
+
}
|
29
|
+
|
30
|
+
uuids.compact!
|
31
|
+
uuids.uniq!
|
32
|
+
uuids.sort!
|
33
|
+
|
34
|
+
uuids.each { |uuid| block.call(uuid) } if block_given?
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def extract_uuid(filename)
|
39
|
+
filename.gsub(/^.+\..+\..+\.(\S+)\.crosby$/, '\1')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Crosby::Tasks.new.install_tasks
|
data/lib/crosby.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "crosby/version"
|
2
|
+
|
3
|
+
module Crosby
|
4
|
+
def self.config(&block)
|
5
|
+
@@configuration ||= Configuration.new
|
6
|
+
@@configuration.config(&block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.action_mailer_version
|
10
|
+
require "action_mailer/version"
|
11
|
+
ActionMailer::VERSION
|
12
|
+
rescue
|
13
|
+
raise Crosby::MissingDependency, "Some version of ActionMailer is required"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require "crosby/configuration"
|
18
|
+
require "crosby/errors"
|
19
|
+
require "crosby/exporter"
|
20
|
+
require "crosby/diff"
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: crosby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dan Matthews
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: diffy
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.6'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.6'
|
69
|
+
description: Allows generation and comparison of email output
|
70
|
+
email:
|
71
|
+
- dan.matthews@teamsnap.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- crosby.gemspec
|
82
|
+
- lib/crosby.rb
|
83
|
+
- lib/crosby/configuration.rb
|
84
|
+
- lib/crosby/diff.rb
|
85
|
+
- lib/crosby/errors.rb
|
86
|
+
- lib/crosby/exporter.rb
|
87
|
+
- lib/crosby/rspec_helper.rb
|
88
|
+
- lib/crosby/tasks.rb
|
89
|
+
- lib/crosby/version.rb
|
90
|
+
homepage: https://github.com/teamsnap/crosby
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubyforge_project:
|
110
|
+
rubygems_version: 2.2.2
|
111
|
+
signing_key:
|
112
|
+
specification_version: 4
|
113
|
+
summary: Quality Assurance for ActionMailer
|
114
|
+
test_files: []
|