sheng 0.5.0 → 0.6.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/lib/sheng/block.rb +2 -2
- data/lib/sheng/check_box.rb +4 -2
- data/lib/sheng/data_set.rb +2 -2
- data/lib/sheng/docx.rb +22 -8
- data/lib/sheng/filters.rb +1 -1
- data/lib/sheng/merge_field.rb +5 -3
- data/lib/sheng/merge_field_set.rb +9 -1
- data/lib/sheng/version.rb +1 -1
- data/lib/sheng/wml_file.rb +4 -20
- data/lib/sheng.rb +9 -9
- data/spec/lib/sheng/check_box_spec.rb +8 -4
- data/spec/lib/sheng/data_set_spec.rb +1 -1
- data/spec/lib/sheng/docx_spec.rb +9 -7
- data/spec/lib/sheng/merge_field_set_spec.rb +25 -1
- data/spec/lib/sheng/merge_field_spec.rb +17 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c3fd415b575d840f656d108d59c7877453e4b21
|
4
|
+
data.tar.gz: cdfe674b6cc940344dc11a98bc7cd6b049b477e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22bd647f4447af076046039d90c0b51ef5394e93b26032b960db3724b33566e93aafc6d4bf2f2eefc18185433d47980f85f187d578c7eda9befc9614367cdaca
|
7
|
+
data.tar.gz: e63a965701379ab2e5c7082cc88b46909c3945580558adf446a7dbb3d6d43345e900688b5d1e914ebb8721f6105dfefb985bd35f5b3cbe0cf0b53fae9db1a8b4
|
data/lib/sheng/block.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Sheng
|
2
2
|
class Block < MergeFieldSet
|
3
|
-
class MissingEndTag <
|
4
|
-
class ImproperNesting <
|
3
|
+
class MissingEndTag < Docx::TemplateError; end
|
4
|
+
class ImproperNesting < Docx::TemplateError; end
|
5
5
|
|
6
6
|
def initialize(merge_field)
|
7
7
|
@start_field = merge_field
|
data/lib/sheng/check_box.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Sheng
|
2
2
|
class CheckBox
|
3
|
-
attr_reader :element, :xml_document
|
3
|
+
attr_reader :element, :xml_document, :errors
|
4
4
|
|
5
5
|
class << self
|
6
6
|
def from_element(element)
|
@@ -11,6 +11,7 @@ module Sheng
|
|
11
11
|
def initialize(element = nil)
|
12
12
|
@element = element
|
13
13
|
@xml_document = element.document
|
14
|
+
@errors = []
|
14
15
|
end
|
15
16
|
|
16
17
|
def ==(other)
|
@@ -29,7 +30,8 @@ module Sheng
|
|
29
30
|
value = data_set.fetch(key)
|
30
31
|
checked_attribute = @element.search('.//w:default').first.attribute('val')
|
31
32
|
checked_attribute.value = value_is_truthy?(value) ? '1' : '0'
|
32
|
-
rescue DataSet::KeyNotFound
|
33
|
+
rescue DataSet::KeyNotFound => e
|
34
|
+
@errors << e
|
33
35
|
# Ignore this error; if the key for this checkbox is not found in the
|
34
36
|
# data set, we don't want to uncheck the checkbox; we just want to leave
|
35
37
|
# it alone.
|
data/lib/sheng/data_set.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Sheng
|
2
2
|
class DataSet
|
3
|
-
class KeyNotFound <
|
3
|
+
class KeyNotFound < Sheng::Error; end
|
4
4
|
|
5
5
|
attr_accessor :raw_hash
|
6
6
|
|
@@ -29,7 +29,7 @@ module Sheng
|
|
29
29
|
if options.has_key?(:default)
|
30
30
|
value = options[:default]
|
31
31
|
else
|
32
|
-
raise KeyNotFound, "
|
32
|
+
raise KeyNotFound, "#{key} (at #{key_part})"
|
33
33
|
end
|
34
34
|
end
|
35
35
|
if (i + 1) < key_parts.length
|
data/lib/sheng/docx.rb
CHANGED
@@ -4,8 +4,10 @@
|
|
4
4
|
#
|
5
5
|
module Sheng
|
6
6
|
class Docx
|
7
|
-
class InvalidFile <
|
8
|
-
class
|
7
|
+
class InvalidFile < Sheng::Error; end
|
8
|
+
class TemplateError < Sheng::Error; end
|
9
|
+
class OutputPathAlreadyExists < Sheng::Error; end
|
10
|
+
class MergeError < Sheng::Error; end
|
9
11
|
|
10
12
|
WMLFileNamePatterns = [
|
11
13
|
/word\/document.xml/,
|
@@ -14,9 +16,12 @@ module Sheng
|
|
14
16
|
/word\/footer(\d)*.xml/
|
15
17
|
]
|
16
18
|
|
19
|
+
attr_reader :errors
|
20
|
+
|
17
21
|
def initialize(input_file_path, params)
|
18
22
|
@input_zip_file = Zip::File.new(input_file_path)
|
19
23
|
@data_set = DataSet.new(params)
|
24
|
+
@errors = {}
|
20
25
|
rescue Zip::Error => e
|
21
26
|
raise InvalidFile.new(e.message)
|
22
27
|
end
|
@@ -39,10 +44,22 @@ module Sheng
|
|
39
44
|
|
40
45
|
def generate(path, force: false)
|
41
46
|
if File.exists?(path) && !force
|
42
|
-
raise
|
47
|
+
raise OutputPathAlreadyExists, "File at #{path} already exists"
|
48
|
+
end
|
49
|
+
|
50
|
+
output_buffer = generate_output_buffer
|
51
|
+
|
52
|
+
if errors.present?
|
53
|
+
raise MergeError.new(errors)
|
43
54
|
end
|
44
55
|
|
45
|
-
|
56
|
+
File.open(path, "w") { |f| f.write(output_buffer.string) }
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def generate_output_buffer
|
62
|
+
Zip::OutputStream.write_buffer do |out|
|
46
63
|
begin
|
47
64
|
@input_zip_file.entries.each do |entry|
|
48
65
|
write_converted_zip_file_to_buffer(entry, out)
|
@@ -51,18 +68,15 @@ module Sheng
|
|
51
68
|
out.close_buffer
|
52
69
|
end
|
53
70
|
end
|
54
|
-
|
55
|
-
File.open(path, "w") { |f| f.write(buffer.string) }
|
56
71
|
end
|
57
72
|
|
58
|
-
private
|
59
|
-
|
60
73
|
def write_converted_zip_file_to_buffer(entry, buffer)
|
61
74
|
contents = entry.get_input_stream.read
|
62
75
|
buffer.put_next_entry(entry.name)
|
63
76
|
if is_wml_file?(entry.name)
|
64
77
|
wml_file = WMLFile.new(entry.name, contents)
|
65
78
|
buffer.write wml_file.interpolate(@data_set)
|
79
|
+
errors.merge!(wml_file.errors)
|
66
80
|
else
|
67
81
|
buffer.write contents
|
68
82
|
end
|
data/lib/sheng/filters.rb
CHANGED
data/lib/sheng/merge_field.rb
CHANGED
@@ -8,7 +8,7 @@ module Sheng
|
|
8
8
|
key_string: /^(?<prefix>start:|end:|if:|end_if:|unless:|end_unless:)?\s*(?<key>[^\|]+)\s*\|?(?<filters>.*)?/
|
9
9
|
}
|
10
10
|
|
11
|
-
class NotAMergeFieldError <
|
11
|
+
class NotAMergeFieldError < Sheng::Error; end
|
12
12
|
|
13
13
|
class << self
|
14
14
|
def from_element(element)
|
@@ -18,12 +18,13 @@ module Sheng
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
attr_reader :element, :xml_document
|
21
|
+
attr_reader :element, :xml_document, :errors
|
22
22
|
|
23
23
|
def initialize(element)
|
24
24
|
@element = element
|
25
25
|
@xml_document = element.document
|
26
26
|
@instruction_text = Sheng::Support.extract_mergefield_instruction_text(element)
|
27
|
+
@errors = []
|
27
28
|
end
|
28
29
|
|
29
30
|
def ==(other)
|
@@ -240,7 +241,8 @@ module Sheng
|
|
240
241
|
def interpolate(data_set)
|
241
242
|
value = get_value(data_set)
|
242
243
|
replace_mergefield(filter_value(value))
|
243
|
-
rescue DataSet::KeyNotFound, Dentaku::UnboundVariableError, Filters::UnsupportedFilterError
|
244
|
+
rescue DataSet::KeyNotFound, Dentaku::UnboundVariableError, Filters::UnsupportedFilterError => e
|
245
|
+
@errors << e
|
244
246
|
# Ignore this error; we'll collect all uninterpolated fields later and
|
245
247
|
# raise a new exception, so we can list all the fields in an error
|
246
248
|
# message.
|
@@ -4,17 +4,25 @@ module Sheng
|
|
4
4
|
class MergeFieldSet
|
5
5
|
include PathHelpers
|
6
6
|
|
7
|
-
attr_reader :xml_fragment, :xml_document, :key
|
7
|
+
attr_reader :xml_fragment, :xml_document, :key, :errors
|
8
8
|
|
9
9
|
def initialize(key, xml_fragment)
|
10
10
|
@key = key
|
11
11
|
@xml_fragment = xml_fragment
|
12
12
|
@xml_document = xml_fragment.document
|
13
|
+
@errors = {}
|
13
14
|
end
|
14
15
|
|
15
16
|
def interpolate(data_set)
|
16
17
|
nodes.each do |node|
|
17
18
|
node.interpolate(data_set)
|
19
|
+
add_errors_from_node(node)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_errors_from_node(node)
|
24
|
+
if node.errors.present?
|
25
|
+
errors[node.raw_key] = node.errors
|
18
26
|
end
|
19
27
|
end
|
20
28
|
|
data/lib/sheng/version.rb
CHANGED
data/lib/sheng/wml_file.rb
CHANGED
@@ -1,37 +1,21 @@
|
|
1
1
|
module Sheng
|
2
2
|
class WMLFile
|
3
|
-
class InvalidWML <
|
4
|
-
class MergefieldNotReplacedError < StandardError
|
5
|
-
def initialize(unmerged_fields)
|
6
|
-
unmerged_keys = unmerged_fields.map(&:raw_key)
|
7
|
-
super("Mergefields not replaced: #{unmerged_keys.join(', ')}")
|
8
|
-
end
|
9
|
-
end
|
3
|
+
class InvalidWML < Docx::TemplateError; end
|
10
4
|
|
11
|
-
attr_reader :xml, :filename
|
5
|
+
attr_reader :xml, :filename, :errors
|
12
6
|
|
13
7
|
def initialize(filename, xml)
|
14
8
|
@filename = filename
|
15
9
|
@xml = Nokogiri::XML(xml)
|
10
|
+
@errors = {}
|
16
11
|
end
|
17
12
|
|
18
13
|
def interpolate(data_set)
|
19
14
|
parent_set.interpolate(data_set)
|
20
|
-
|
15
|
+
errors.merge!(parent_set.errors)
|
21
16
|
parent_set.xml_fragment.to_s
|
22
17
|
end
|
23
18
|
|
24
|
-
def check_for_full_interpolation!
|
25
|
-
modified_parent_set = MergeFieldSet.new('main', xml)
|
26
|
-
unmerged_fields = modified_parent_set.basic_nodes.reject { |node|
|
27
|
-
node.is_a?(CheckBox)
|
28
|
-
}
|
29
|
-
|
30
|
-
unless unmerged_fields.empty?
|
31
|
-
raise MergefieldNotReplacedError.new(unmerged_fields)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
19
|
def parent_set
|
36
20
|
@parent_set ||= MergeFieldSet.new('main', xml)
|
37
21
|
end
|
data/lib/sheng.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
-
|
2
1
|
require 'active_support/inflector'
|
3
2
|
require 'active_support/core_ext/hash'
|
3
|
+
require 'zip'
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module Sheng
|
9
|
+
class Error < StandardError; end
|
10
|
+
end
|
11
|
+
|
4
12
|
require 'sheng/support'
|
5
13
|
require 'sheng/version'
|
6
14
|
require 'sheng/data_set'
|
@@ -12,11 +20,3 @@ require 'sheng/merge_field'
|
|
12
20
|
require 'sheng/sequence'
|
13
21
|
require 'sheng/conditional_block'
|
14
22
|
require 'sheng/check_box'
|
15
|
-
|
16
|
-
require 'zip'
|
17
|
-
require 'nokogiri'
|
18
|
-
require 'fileutils'
|
19
|
-
require 'json'
|
20
|
-
|
21
|
-
module Sheng
|
22
|
-
end
|
@@ -71,17 +71,21 @@ describe Sheng::CheckBox do
|
|
71
71
|
expect(default_checked.xml_document).to be_equivalent_to fragment_with_unchecked_box(default_checked.xml_document)
|
72
72
|
end
|
73
73
|
|
74
|
-
it "does not check the checkbox if key is not found in dataset" do
|
75
|
-
dataset
|
74
|
+
it "records error and does not check the checkbox if key is not found in dataset" do
|
75
|
+
allow(dataset).to receive(:fetch).with("goats").and_raise(Sheng::DataSet::KeyNotFound, "uhoh")
|
76
76
|
subject.interpolate(dataset)
|
77
77
|
expect(subject.xml_document).to be_equivalent_to fragment_with_unchecked_box(subject.xml_document)
|
78
|
+
expect(subject.errors.first).to be_a(Sheng::DataSet::KeyNotFound)
|
79
|
+
expect(subject.errors.first.message).to eq("uhoh")
|
78
80
|
end
|
79
81
|
|
80
|
-
it "does not uncheck a checked checkbox if key is not found in dataset" do
|
81
|
-
dataset
|
82
|
+
it "records error and does not uncheck a checked checkbox if key is not found in dataset" do
|
83
|
+
allow(dataset).to receive(:fetch).with("goats").and_raise(Sheng::DataSet::KeyNotFound, "uhoh")
|
82
84
|
default_checked = described_class.new(fragment_with_checked_box(subject.xml_document))
|
83
85
|
default_checked.interpolate(dataset)
|
84
86
|
expect(default_checked.xml_document).to be_equivalent_to xml_fragment('output/check_box/check_box')
|
87
|
+
expect(default_checked.errors.first).to be_a(Sheng::DataSet::KeyNotFound)
|
88
|
+
expect(default_checked.errors.first.message).to eq("uhoh")
|
85
89
|
end
|
86
90
|
end
|
87
91
|
end
|
@@ -43,7 +43,7 @@ describe Sheng::DataSet do
|
|
43
43
|
it 'raises a KeyNotFound error if key not found' do
|
44
44
|
expect {
|
45
45
|
subject.fetch('rabbits.funky')
|
46
|
-
}.to raise_error(described_class::KeyNotFound, "
|
46
|
+
}.to raise_error(described_class::KeyNotFound, "rabbits.funky (at funky)")
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'does not raise error on key not found if default given' do
|
data/spec/lib/sheng/docx_spec.rb
CHANGED
@@ -26,7 +26,7 @@ describe Sheng::Docx do
|
|
26
26
|
File.open(output_file, "w").write("nothing")
|
27
27
|
expect {
|
28
28
|
subject.generate(output_file)
|
29
|
-
}.to raise_error(described_class::
|
29
|
+
}.to raise_error(described_class::OutputPathAlreadyExists)
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'overwrites file if file already exists but force option is true' do
|
@@ -63,12 +63,14 @@ describe Sheng::Docx do
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
it "should raise an
|
66
|
+
it "should raise an exception and set errors when one or more mergefields isn't merged" do
|
67
67
|
incomplete_hash = JSON.parse(File.read(fixture_path("inputs/incomplete.json")))
|
68
68
|
doc = described_class.new(input_file, incomplete_hash)
|
69
69
|
expect {
|
70
70
|
doc.generate(output_file)
|
71
|
-
}.to raise_error(Sheng::
|
71
|
+
}.to raise_error(Sheng::Docx::MergeError)
|
72
|
+
expect(doc.errors.keys).to eq(["first_name", "last_name"])
|
73
|
+
expect(doc.errors["first_name"].map(&:message)).to eq(["first_name (at first_name)"])
|
72
74
|
end
|
73
75
|
|
74
76
|
shared_examples_for 'a bad document' do |filename, error, error_message = nil|
|
@@ -81,16 +83,16 @@ describe Sheng::Docx do
|
|
81
83
|
end
|
82
84
|
|
83
85
|
it_should_behave_like 'a bad document', 'with_field_not_in_dataset.docx',
|
84
|
-
Sheng::
|
86
|
+
Sheng::Docx::MergeError, {"extra_name"=>[Sheng::DataSet::KeyNotFound.new("extra_name (at extra_name)")] }.to_s
|
85
87
|
|
86
88
|
it_should_behave_like 'a bad document', 'with_unended_sequence.docx',
|
87
|
-
Sheng::
|
89
|
+
Sheng::Docx::TemplateError, "no end tag for start:owner_signature"
|
88
90
|
|
89
91
|
it_should_behave_like 'a bad document', 'with_missing_sequence_start.docx',
|
90
|
-
Sheng::
|
92
|
+
Sheng::Docx::MergeError, {"end:owner_signature"=>[Sheng::DataSet::KeyNotFound.new("owner_signature (at owner_signature)")] }.to_s
|
91
93
|
|
92
94
|
it_should_behave_like 'a bad document', 'with_poorly_nested_sequences.docx',
|
93
|
-
Sheng::
|
95
|
+
Sheng::Docx::TemplateError, "expected end tag for start:birds, got end:animals"
|
94
96
|
end
|
95
97
|
|
96
98
|
describe '#new' do
|
@@ -4,11 +4,35 @@ describe Sheng::MergeFieldSet do
|
|
4
4
|
|
5
5
|
describe '#interpolate' do
|
6
6
|
it 'iterates through nodes and calls interpolate on each' do
|
7
|
-
node1, node2 = double('Node'), double('Node')
|
7
|
+
node1, node2 = double('Node', errors: []), double('Node', errors: [])
|
8
8
|
expect(node1).to receive(:interpolate).with(:the_data_set)
|
9
9
|
expect(node2).to receive(:interpolate).with(:the_data_set)
|
10
10
|
allow(subject).to receive(:nodes).and_return([node1, node2])
|
11
11
|
subject.interpolate(:the_data_set)
|
12
|
+
expect(subject.errors).to be_empty
|
13
|
+
end
|
14
|
+
|
15
|
+
context "with mergefields that raise errors on interpolation" do
|
16
|
+
it "should compile all errors" do
|
17
|
+
node1, node2, node3 =
|
18
|
+
double('Node', raw_key: "node1"),
|
19
|
+
double('Node', raw_key: "node2"),
|
20
|
+
double('Node', raw_key: "node3")
|
21
|
+
allow(node1).to receive(:interpolate).with(:the_data_set)
|
22
|
+
allow(node2).to receive(:interpolate).with(:the_data_set)
|
23
|
+
allow(node3).to receive(:interpolate).with(:the_data_set)
|
24
|
+
allow(node1).to receive(:errors).and_return(["stupid", "oops"])
|
25
|
+
allow(node2).to receive(:errors).and_return({ "node4" => ["uhoh", "darnit"] })
|
26
|
+
allow(node3).to receive(:errors).and_return([])
|
27
|
+
allow(subject).to receive(:nodes).and_return([node1, node2, node3])
|
28
|
+
subject.interpolate(:the_data_set)
|
29
|
+
expect(subject.errors).to eq({
|
30
|
+
"node1" => ["stupid", "oops"],
|
31
|
+
"node2" => {
|
32
|
+
"node4" => ["uhoh", "darnit"]
|
33
|
+
}
|
34
|
+
})
|
35
|
+
end
|
12
36
|
end
|
13
37
|
|
14
38
|
context "with fields that are not valid mergefields" do
|
@@ -212,23 +212,34 @@ describe Sheng::MergeField do
|
|
212
212
|
expect(subject.xml_document).to be_equivalent_to xml_fragment('output/merge_field/merge_field')
|
213
213
|
end
|
214
214
|
|
215
|
-
it "does not replace and returns nil if any keys not found" do
|
216
|
-
allow(subject).to receive(:get_value).with(:a_dataset).and_raise(Sheng::DataSet::KeyNotFound)
|
215
|
+
it "does not replace, records error, and returns nil if any keys not found" do
|
216
|
+
allow(subject).to receive(:get_value).with(:a_dataset).and_raise(Sheng::DataSet::KeyNotFound.new("horses"))
|
217
217
|
expect(subject).to receive(:replace_mergefield).never
|
218
218
|
expect(subject.interpolate(:a_dataset)).to be_nil
|
219
|
+
expect(subject.errors.first).to be_a(Sheng::DataSet::KeyNotFound)
|
220
|
+
expect(subject.errors.first.message).to eq("horses")
|
219
221
|
end
|
220
222
|
|
221
|
-
it "does not replace and returns nil if calculation error encountered" do
|
222
|
-
allow(subject).to receive(:get_value).with(:a_dataset).and_raise(Dentaku::UnboundVariableError.new([]))
|
223
|
+
it "does not replace, records error, and returns nil if calculation error encountered" do
|
224
|
+
allow(subject).to receive(:get_value).with(:a_dataset).and_raise(Dentaku::UnboundVariableError.new([:foo, :bar]))
|
223
225
|
expect(subject).to receive(:replace_mergefield).never
|
224
226
|
expect(subject.interpolate(:a_dataset)).to be_nil
|
227
|
+
expect(subject.errors.first).to be_a(Dentaku::UnboundVariableError)
|
228
|
+
expect(subject.errors.first.unbound_variables).to eq([:foo, :bar])
|
225
229
|
end
|
226
230
|
|
227
|
-
it "does not replace and returns nil if unsupported filter requested" do
|
231
|
+
it "does not replace, records error, and returns nil if unsupported filter requested" do
|
228
232
|
allow(subject).to receive(:get_value).with(:a_dataset).and_return(:got_value)
|
229
|
-
allow(subject).to receive(:filter_value).with(:got_value).and_raise(Sheng::Filters::UnsupportedFilterError)
|
233
|
+
allow(subject).to receive(:filter_value).with(:got_value).and_raise(Sheng::Filters::UnsupportedFilterError.new("woof"))
|
230
234
|
expect(subject).to receive(:replace_mergefield).never
|
231
235
|
expect(subject.interpolate(:a_dataset)).to be_nil
|
236
|
+
expect(subject.errors.first).to be_a(Sheng::Filters::UnsupportedFilterError)
|
237
|
+
expect(subject.errors.first.message).to eq("woof")
|
238
|
+
end
|
239
|
+
|
240
|
+
it "does not rescue other exceptions" do
|
241
|
+
allow(subject).to receive(:get_value).with(:a_dataset).and_raise(NoMethodError)
|
242
|
+
expect { subject.interpolate(:a_dataset) }.to raise_error(NoMethodError)
|
232
243
|
end
|
233
244
|
end
|
234
245
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sheng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ravi Gadad
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-05-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|