bmg 0.17.7 → 0.18.3
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/Gemfile +0 -3
- data/README.md +236 -57
- data/lib/bmg.rb +6 -0
- data/lib/bmg/algebra.rb +1 -0
- data/lib/bmg/algebra/shortcuts.rb +14 -0
- data/lib/bmg/operator/allbut.rb +27 -0
- data/lib/bmg/operator/autosummarize.rb +27 -4
- data/lib/bmg/operator/autowrap.rb +27 -0
- data/lib/bmg/operator/constants.rb +7 -0
- data/lib/bmg/operator/extend.rb +7 -0
- data/lib/bmg/operator/group.rb +1 -0
- data/lib/bmg/operator/image.rb +41 -2
- data/lib/bmg/operator/join.rb +1 -0
- data/lib/bmg/operator/matching.rb +1 -0
- data/lib/bmg/operator/not_matching.rb +1 -0
- data/lib/bmg/operator/page.rb +2 -7
- data/lib/bmg/operator/project.rb +3 -2
- data/lib/bmg/operator/rename.rb +7 -0
- data/lib/bmg/operator/restrict.rb +1 -0
- data/lib/bmg/operator/rxmatch.rb +1 -0
- data/lib/bmg/operator/summarize.rb +2 -17
- data/lib/bmg/operator/transform.rb +39 -1
- data/lib/bmg/operator/union.rb +1 -0
- data/lib/bmg/reader.rb +1 -0
- data/lib/bmg/reader/csv.rb +29 -10
- data/lib/bmg/reader/excel.rb +22 -3
- data/lib/bmg/reader/text_file.rb +56 -0
- data/lib/bmg/relation.rb +31 -2
- data/lib/bmg/relation/empty.rb +4 -0
- data/lib/bmg/relation/in_memory.rb +10 -1
- data/lib/bmg/relation/materialized.rb +6 -0
- data/lib/bmg/relation/spied.rb +6 -1
- data/lib/bmg/sequel/relation.rb +5 -0
- data/lib/bmg/sql/relation.rb +2 -3
- data/lib/bmg/summarizer.rb +29 -1
- data/lib/bmg/summarizer/avg.rb +3 -3
- data/lib/bmg/summarizer/by_proc.rb +41 -0
- data/lib/bmg/summarizer/distinct.rb +36 -0
- data/lib/bmg/summarizer/multiple.rb +46 -0
- data/lib/bmg/summarizer/percentile.rb +47 -0
- data/lib/bmg/support.rb +2 -0
- data/lib/bmg/support/ordering.rb +20 -0
- data/lib/bmg/support/output_preferences.rb +44 -0
- data/lib/bmg/support/tuple_algebra.rb +6 -0
- data/lib/bmg/support/tuple_transformer.rb +4 -5
- data/lib/bmg/version.rb +2 -2
- data/lib/bmg/writer.rb +16 -0
- data/lib/bmg/writer/csv.rb +7 -7
- data/lib/bmg/writer/xlsx.rb +68 -0
- data/tasks/test.rake +9 -2
- metadata +37 -15
@@ -0,0 +1,36 @@
|
|
1
|
+
module Bmg
|
2
|
+
class Summarizer
|
3
|
+
#
|
4
|
+
# Collect the distinct values as an array.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# # direct ruby usage
|
9
|
+
# Bmg::Summarizer.distinct(:qty).summarize(...)
|
10
|
+
#
|
11
|
+
class Distinct < Summarizer
|
12
|
+
|
13
|
+
# Returns [] as least value.
|
14
|
+
def least()
|
15
|
+
{}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Adds val to the memo array
|
19
|
+
def _happens(memo, val)
|
20
|
+
memo[val] = true
|
21
|
+
memo
|
22
|
+
end
|
23
|
+
|
24
|
+
def finalize(memo)
|
25
|
+
memo.keys
|
26
|
+
end
|
27
|
+
|
28
|
+
end # class Distinct
|
29
|
+
|
30
|
+
# Factors a distinct summarizer
|
31
|
+
def self.distinct(*args, &bl)
|
32
|
+
Distinct.new(*args, &bl)
|
33
|
+
end
|
34
|
+
|
35
|
+
end # class Summarizer
|
36
|
+
end # module Bmg
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Bmg
|
2
|
+
class Summarizer
|
3
|
+
#
|
4
|
+
# A summarizer that collects multiple summarization as a wrapped
|
5
|
+
# tuple.
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
#
|
9
|
+
# # direct ruby usage
|
10
|
+
# Bmg::Summarizer.multiple(x: ..., y: ...).summarize(...)
|
11
|
+
#
|
12
|
+
class Multiple < Summarizer
|
13
|
+
|
14
|
+
def initialize(defs)
|
15
|
+
@summarization = Summarizer.summarization(defs)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns [] as least value.
|
19
|
+
def least()
|
20
|
+
@summarization.each_pair.each_with_object({}){|(k,v),memo|
|
21
|
+
memo[k] = v.least
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Adds val to the memo array
|
26
|
+
def happens(memo, val)
|
27
|
+
@summarization.each_pair.each_with_object({}){|(k,v),memo2|
|
28
|
+
memo2[k] = v.happens(memo[k], val)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def finalize(memo)
|
33
|
+
@summarization.each_pair.each_with_object({}){|(k,v),memo2|
|
34
|
+
memo2[k] = v.finalize(memo[k])
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
end # class Multiple
|
39
|
+
|
40
|
+
# Factors a distinct summarizer
|
41
|
+
def self.multiple(defs)
|
42
|
+
Multiple.new(defs)
|
43
|
+
end
|
44
|
+
|
45
|
+
end # class Summarizer
|
46
|
+
end # module Bmg
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Bmg
|
2
|
+
class Summarizer
|
3
|
+
#
|
4
|
+
# Percentile summarizer.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# # direct ruby usage
|
9
|
+
# Bmg::Summarizer.percentile(:qty, 50).summarize(...)
|
10
|
+
#
|
11
|
+
class Percentile < Summarizer
|
12
|
+
|
13
|
+
def initialize(attribute = nil, nth = 50, &bl)
|
14
|
+
attribute, nth = nil, attribute if attribute.is_a?(Integer)
|
15
|
+
super(*[attribute].compact, &bl)
|
16
|
+
@nth = nth
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns [] as least value.
|
20
|
+
def least()
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Collects the value
|
25
|
+
def _happens(memo, val)
|
26
|
+
memo << val
|
27
|
+
end
|
28
|
+
|
29
|
+
# Finalizes the computation.
|
30
|
+
def finalize(memo)
|
31
|
+
return nil if memo.empty?
|
32
|
+
index = memo.size * (@nth / 100.0)
|
33
|
+
above = [[index.ceil - 1, memo.size - 1].min, 0].max
|
34
|
+
below = [index.floor - 1, 0].max
|
35
|
+
sorted = memo.sort
|
36
|
+
(sorted[above] + sorted[below]) / 2
|
37
|
+
end
|
38
|
+
|
39
|
+
end # class Avg
|
40
|
+
|
41
|
+
# Factors an average summarizer
|
42
|
+
def self.percentile(*args, &bl)
|
43
|
+
Percentile.new(*args, &bl)
|
44
|
+
end
|
45
|
+
|
46
|
+
end # class Summarizer
|
47
|
+
end # module Bmg
|
data/lib/bmg/support.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Bmg
|
2
|
+
class Ordering
|
3
|
+
|
4
|
+
def initialize(attrs)
|
5
|
+
@attrs = attrs
|
6
|
+
end
|
7
|
+
attr_reader :attrs
|
8
|
+
|
9
|
+
def comparator
|
10
|
+
->(t1, t2) {
|
11
|
+
attrs.each do |(attr,direction)|
|
12
|
+
c = t1[attr] <=> t2[attr]
|
13
|
+
return (direction == :desc ? -c : c) unless c==0
|
14
|
+
end
|
15
|
+
0
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
end # class Ordering
|
20
|
+
end # module Bmg
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Bmg
|
2
|
+
class OutputPreferences
|
3
|
+
|
4
|
+
DEFAULT_PREFS = {
|
5
|
+
attributes_ordering: nil,
|
6
|
+
extra_attributes: :after
|
7
|
+
}
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@options = DEFAULT_PREFS.merge(options)
|
11
|
+
end
|
12
|
+
attr_reader :options
|
13
|
+
|
14
|
+
def self.dress(arg)
|
15
|
+
return arg if arg.is_a?(OutputPreferences)
|
16
|
+
arg = {} if arg.nil?
|
17
|
+
new(arg)
|
18
|
+
end
|
19
|
+
|
20
|
+
def attributes_ordering
|
21
|
+
options[:attributes_ordering]
|
22
|
+
end
|
23
|
+
|
24
|
+
def extra_attributes
|
25
|
+
options[:extra_attributes]
|
26
|
+
end
|
27
|
+
|
28
|
+
def order_attrlist(attrlist)
|
29
|
+
return attrlist if attributes_ordering.nil?
|
30
|
+
index = Hash[attributes_ordering.each_with_index.to_a]
|
31
|
+
attrlist.sort{|a,b|
|
32
|
+
ai, bi = index[a], index[b]
|
33
|
+
if ai && bi
|
34
|
+
ai <=> bi
|
35
|
+
elsif ai
|
36
|
+
extra_attributes == :after ? -1 : 1
|
37
|
+
else
|
38
|
+
extra_attributes == :after ? 1 : -1
|
39
|
+
end
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
end # class OutputPreferences
|
44
|
+
end # module Bmg
|
@@ -26,11 +26,7 @@ module Bmg
|
|
26
26
|
|
27
27
|
def transform_tuple(tuple, with)
|
28
28
|
case with
|
29
|
-
when Symbol
|
30
|
-
tuple.each_with_object({}){|(k,v),dup|
|
31
|
-
dup[k] = transform_attr(v, with)
|
32
|
-
}
|
33
|
-
when Proc
|
29
|
+
when Symbol, Proc, Regexp
|
34
30
|
tuple.each_with_object({}){|(k,v),dup|
|
35
31
|
dup[k] = transform_attr(v, with)
|
36
32
|
}
|
@@ -51,6 +47,9 @@ module Bmg
|
|
51
47
|
case with
|
52
48
|
when Symbol
|
53
49
|
value.send(with)
|
50
|
+
when Regexp
|
51
|
+
m = with.match(value.to_s)
|
52
|
+
m.nil? ? m : m.to_s
|
54
53
|
when Proc
|
55
54
|
with.call(value)
|
56
55
|
when Hash
|
data/lib/bmg/version.rb
CHANGED
data/lib/bmg/writer.rb
CHANGED
@@ -1 +1,17 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Writer
|
3
|
+
|
4
|
+
protected
|
5
|
+
|
6
|
+
def infer_headers(from)
|
7
|
+
attrlist = if from.is_a?(Type) && from.knows_attrlist?
|
8
|
+
from.to_attrlist
|
9
|
+
elsif from.is_a?(Hash)
|
10
|
+
from.keys
|
11
|
+
end
|
12
|
+
attrlist ? output_preferences.order_attrlist(attrlist) : nil
|
13
|
+
end
|
14
|
+
|
15
|
+
end # module Writer
|
16
|
+
end # module Bmg
|
1
17
|
require_relative 'writer/csv'
|
data/lib/bmg/writer/csv.rb
CHANGED
@@ -6,20 +6,20 @@ module Bmg
|
|
6
6
|
DEFAULT_OPTIONS = {
|
7
7
|
}
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
@
|
9
|
+
def initialize(csv_options, output_preferences = nil)
|
10
|
+
@csv_options = DEFAULT_OPTIONS.merge(csv_options)
|
11
|
+
@output_preferences = OutputPreferences.dress(output_preferences)
|
11
12
|
end
|
12
|
-
attr_reader :
|
13
|
+
attr_reader :csv_options, :output_preferences
|
13
14
|
|
14
15
|
def call(relation, string_or_io = nil)
|
15
16
|
require 'csv'
|
16
17
|
string_or_io, to_s = string_or_io.nil? ? [StringIO.new, true] : [string_or_io, false]
|
17
|
-
headers = relation.type
|
18
|
-
csv = nil
|
18
|
+
headers, csv = infer_headers(relation.type), nil
|
19
19
|
relation.each do |tuple|
|
20
20
|
if csv.nil?
|
21
|
-
headers = tuple
|
22
|
-
csv = CSV.new(string_or_io,
|
21
|
+
headers = infer_headers(tuple) if headers.nil?
|
22
|
+
csv = CSV.new(string_or_io, csv_options.merge(headers: headers))
|
23
23
|
end
|
24
24
|
csv << headers.map{|h| tuple[h] }
|
25
25
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Writer
|
3
|
+
class Xlsx
|
4
|
+
include Writer
|
5
|
+
|
6
|
+
DEFAULT_OPTIONS = {
|
7
|
+
}
|
8
|
+
|
9
|
+
def initialize(csv_options, output_preferences = nil)
|
10
|
+
@csv_options = DEFAULT_OPTIONS.merge(csv_options)
|
11
|
+
@output_preferences = OutputPreferences.dress(output_preferences)
|
12
|
+
end
|
13
|
+
attr_reader :csv_options, :output_preferences
|
14
|
+
|
15
|
+
def call(relation, path)
|
16
|
+
require 'write_xlsx'
|
17
|
+
dup._call(relation, path)
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
attr_reader :workbook, :worksheet
|
22
|
+
|
23
|
+
def _call(relation, path)
|
24
|
+
@workbook = WriteXLSX.new(path)
|
25
|
+
@worksheet = workbook.add_worksheet
|
26
|
+
|
27
|
+
headers = infer_headers(relation.type)
|
28
|
+
relation.each_with_index do |tuple,i|
|
29
|
+
headers = infer_headers(tuple) if headers.nil?
|
30
|
+
headers.each_with_index do |h,i|
|
31
|
+
worksheet.write_string(0, i, h)
|
32
|
+
end if i == 0
|
33
|
+
headers.each_with_index do |h,j|
|
34
|
+
meth, *args = write_pair(tuple[h])
|
35
|
+
worksheet.send(meth, 1+i, j, *args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
workbook.close
|
40
|
+
path
|
41
|
+
end
|
42
|
+
|
43
|
+
def write_pair(value)
|
44
|
+
case value
|
45
|
+
when Numeric
|
46
|
+
[:write_number, value]
|
47
|
+
when Date
|
48
|
+
[:write_date_time, value, date_format]
|
49
|
+
else
|
50
|
+
[:write_string, value.to_s]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def date_format
|
55
|
+
@date_format ||= workbook.add_format(:num_format => 'yyyy-mm-dd')
|
56
|
+
end
|
57
|
+
|
58
|
+
end # class Xlsx
|
59
|
+
end # module Writer
|
60
|
+
module Relation
|
61
|
+
|
62
|
+
def to_xlsx(options = {}, path = nil, preferences = nil)
|
63
|
+
options, path = {}, options unless options.is_a?(Hash)
|
64
|
+
Writer::Xlsx.new(options, preferences).call(self, path)
|
65
|
+
end
|
66
|
+
|
67
|
+
end # module Relation
|
68
|
+
end # module Bmg
|
data/tasks/test.rake
CHANGED
@@ -6,17 +6,24 @@ namespace :test do
|
|
6
6
|
desc "Runs unit tests"
|
7
7
|
RSpec::Core::RakeTask.new(:unit) do |t|
|
8
8
|
t.pattern = "spec/unit/**/test_*.rb"
|
9
|
-
t.rspec_opts = ["-Ilib", "-Ispec/unit", "--
|
9
|
+
t.rspec_opts = ["-Ilib", "-Ispec/unit", "--color", "--backtrace", "--format=progress"]
|
10
10
|
end
|
11
11
|
tests << :unit
|
12
12
|
|
13
13
|
desc "Runs integration tests"
|
14
14
|
RSpec::Core::RakeTask.new(:integration) do |t|
|
15
15
|
t.pattern = "spec/integration/**/test_*.rb"
|
16
|
-
t.rspec_opts = ["-Ilib", "-Ispec/integration", "--
|
16
|
+
t.rspec_opts = ["-Ilib", "-Ispec/integration", "--color", "--backtrace", "--format=progress"]
|
17
17
|
end
|
18
18
|
tests << :integration
|
19
19
|
|
20
|
+
desc "Runs github regression tests"
|
21
|
+
RSpec::Core::RakeTask.new(:regression) do |t|
|
22
|
+
t.pattern = "spec/regression/**/test_*.rb"
|
23
|
+
t.rspec_opts = ["-Ilib", "-Ispec/regression", "--color", "--backtrace", "--format=progress"]
|
24
|
+
end
|
25
|
+
tests << :regression
|
26
|
+
|
20
27
|
task :all => tests
|
21
28
|
end
|
22
29
|
|
metadata
CHANGED
@@ -1,49 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bmg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: predicate
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '2.4'
|
20
17
|
- - ">="
|
21
18
|
- !ruby/object:Gem::Version
|
22
|
-
version: 2.
|
19
|
+
version: 2.5.0
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.5'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '2.4'
|
30
27
|
- - ">="
|
31
28
|
- !ruby/object:Gem::Version
|
32
|
-
version: 2.
|
29
|
+
version: 2.5.0
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.5'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: path
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '2.0'
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '2.0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rake
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,14 +78,28 @@ dependencies:
|
|
78
78
|
requirements:
|
79
79
|
- - ">="
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '2.
|
81
|
+
version: '2.8'
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '2.
|
88
|
+
version: '2.8'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: write_xlsx
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1.0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '1.0'
|
89
103
|
- !ruby/object:Gem::Dependency
|
90
104
|
name: sequel
|
91
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -154,6 +168,7 @@ files:
|
|
154
168
|
- lib/bmg/reader.rb
|
155
169
|
- lib/bmg/reader/csv.rb
|
156
170
|
- lib/bmg/reader/excel.rb
|
171
|
+
- lib/bmg/reader/text_file.rb
|
157
172
|
- lib/bmg/relation.rb
|
158
173
|
- lib/bmg/relation/empty.rb
|
159
174
|
- lib/bmg/relation/in_memory.rb
|
@@ -250,22 +265,29 @@ files:
|
|
250
265
|
- lib/bmg/sql/version.rb
|
251
266
|
- lib/bmg/summarizer.rb
|
252
267
|
- lib/bmg/summarizer/avg.rb
|
268
|
+
- lib/bmg/summarizer/by_proc.rb
|
253
269
|
- lib/bmg/summarizer/collect.rb
|
254
270
|
- lib/bmg/summarizer/concat.rb
|
255
271
|
- lib/bmg/summarizer/count.rb
|
272
|
+
- lib/bmg/summarizer/distinct.rb
|
256
273
|
- lib/bmg/summarizer/max.rb
|
257
274
|
- lib/bmg/summarizer/min.rb
|
275
|
+
- lib/bmg/summarizer/multiple.rb
|
276
|
+
- lib/bmg/summarizer/percentile.rb
|
258
277
|
- lib/bmg/summarizer/stddev.rb
|
259
278
|
- lib/bmg/summarizer/sum.rb
|
260
279
|
- lib/bmg/summarizer/variance.rb
|
261
280
|
- lib/bmg/support.rb
|
262
281
|
- lib/bmg/support/keys.rb
|
282
|
+
- lib/bmg/support/ordering.rb
|
283
|
+
- lib/bmg/support/output_preferences.rb
|
263
284
|
- lib/bmg/support/tuple_algebra.rb
|
264
285
|
- lib/bmg/support/tuple_transformer.rb
|
265
286
|
- lib/bmg/type.rb
|
266
287
|
- lib/bmg/version.rb
|
267
288
|
- lib/bmg/writer.rb
|
268
289
|
- lib/bmg/writer/csv.rb
|
290
|
+
- lib/bmg/writer/xlsx.rb
|
269
291
|
- tasks/gem.rake
|
270
292
|
- tasks/test.rake
|
271
293
|
homepage: http://github.com/enspirit/bmg
|
@@ -287,7 +309,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
287
309
|
- !ruby/object:Gem::Version
|
288
310
|
version: '0'
|
289
311
|
requirements: []
|
290
|
-
rubygems_version: 3.
|
312
|
+
rubygems_version: 3.0.8
|
291
313
|
signing_key:
|
292
314
|
specification_version: 4
|
293
315
|
summary: Bmg is Alf's successor.
|