spout 0.12.1 → 0.13.0.beta1
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/CHANGELOG.md +7 -0
- data/README.md +5 -5
- data/Rakefile +4 -4
- data/bin/spout +1 -1
- data/lib/spout/commands/coverage.rb +18 -18
- data/lib/spout/commands/deploy.rb +89 -89
- data/lib/spout/commands/exporter.rb +16 -16
- data/lib/spout/commands/graphs.rb +37 -37
- data/lib/spout/commands/help.rb +1 -1
- data/lib/spout/commands/importer.rb +59 -57
- data/lib/spout/commands/outliers.rb +17 -17
- data/lib/spout/commands/project_generator.rb +25 -25
- data/lib/spout/commands/update.rb +38 -38
- data/lib/spout/helpers/array_statistics.rb +7 -7
- data/lib/spout/helpers/chart_types.rb +2 -2
- data/lib/spout/helpers/config_reader.rb +21 -20
- data/lib/spout/helpers/framework.rb +11 -11
- data/lib/spout/helpers/iterators.rb +1 -3
- data/lib/spout/helpers/json_loader.rb +2 -4
- data/lib/spout/helpers/json_request.rb +11 -11
- data/lib/spout/helpers/number_helper.rb +1 -1
- data/lib/spout/helpers/quietly.rb +1 -1
- data/lib/spout/helpers/semantic.rb +1 -1
- data/lib/spout/helpers/send_file.rb +14 -14
- data/lib/spout/helpers/subject_loader.rb +24 -24
- data/lib/spout/helpers/table_formatting.rb +12 -12
- data/lib/spout/models/coverage_result.rb +8 -8
- data/lib/spout/models/dictionary.rb +10 -10
- data/lib/spout/models/domain.rb +7 -7
- data/lib/spout/models/empty.rb +1 -1
- data/lib/spout/models/form.rb +6 -6
- data/lib/spout/models/graphables/choices_vs_choices.rb +3 -5
- data/lib/spout/models/graphables/choices_vs_numeric.rb +4 -6
- data/lib/spout/models/graphables/default.rb +6 -6
- data/lib/spout/models/graphables/histogram.rb +4 -4
- data/lib/spout/models/graphables/numeric_vs_choices.rb +1 -1
- data/lib/spout/models/graphables/numeric_vs_numeric.rb +6 -6
- data/lib/spout/models/graphables.rb +14 -14
- data/lib/spout/models/outlier_result.rb +16 -18
- data/lib/spout/models/record.rb +3 -3
- data/lib/spout/models/tables/choices_vs_choices.rb +11 -11
- data/lib/spout/models/tables/choices_vs_numeric.rb +8 -8
- data/lib/spout/models/tables/default.rb +5 -5
- data/lib/spout/models/tables/numeric_vs_choices.rb +7 -7
- data/lib/spout/models/tables/numeric_vs_numeric.rb +7 -7
- data/lib/spout/models/tables.rb +11 -11
- data/lib/spout/models/variable.rb +14 -14
- data/lib/spout/tasks/engine.rake +4 -4
- data/lib/spout/templates/CHANGELOG.md.erb +1 -1
- data/lib/spout/templates/Gemfile +2 -2
- data/lib/spout/templates/Rakefile +1 -1
- data/lib/spout/templates/test/dictionary_test.rb +3 -3
- data/lib/spout/templates/test/test_helper.rb +1 -1
- data/lib/spout/tests/domain_existence_validation.rb +6 -6
- data/lib/spout/tests/domain_format.rb +1 -1
- data/lib/spout/tests/domain_name_format.rb +3 -3
- data/lib/spout/tests/domain_name_uniqueness.rb +2 -2
- data/lib/spout/tests/domain_specified.rb +1 -3
- data/lib/spout/tests/form_existence_validation.rb +2 -4
- data/lib/spout/tests/form_name_format.rb +3 -3
- data/lib/spout/tests/form_name_match.rb +1 -1
- data/lib/spout/tests/json_helper.rb +1 -1
- data/lib/spout/tests/json_validation.rb +0 -2
- data/lib/spout/tests/variable_name_format.rb +3 -3
- data/lib/spout/tests/variable_name_match.rb +1 -3
- data/lib/spout/tests/variable_name_uniqueness.rb +2 -2
- data/lib/spout/tests/variable_type_validation.rb +2 -2
- data/lib/spout/tests.rb +30 -30
- data/lib/spout/version.rb +4 -4
- data/lib/spout/views/index.html.erb +15 -15
- data/lib/spout/views/outliers.html.erb +8 -8
- data/lib/spout.rb +26 -26
- data/spout.gemspec +22 -22
- metadata +5 -5
data/lib/spout/tests.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "rubygems"
|
4
|
+
require "json"
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
6
|
+
require "minitest/autorun"
|
7
|
+
require "minitest/reporters"
|
8
|
+
require "colorize"
|
9
9
|
|
10
10
|
module Minitest
|
11
11
|
module Reporters
|
@@ -14,22 +14,22 @@ module Minitest
|
|
14
14
|
|
15
15
|
def start
|
16
16
|
super
|
17
|
-
print
|
17
|
+
print "Loaded Suite test".colorize(:white)
|
18
18
|
puts
|
19
19
|
puts
|
20
|
-
puts
|
20
|
+
puts "Started"
|
21
21
|
puts
|
22
22
|
end
|
23
23
|
|
24
24
|
def report
|
25
25
|
super
|
26
|
-
puts format(
|
26
|
+
puts format("Finished in %.5f seconds.", total_time)
|
27
27
|
puts
|
28
|
-
print format(
|
29
|
-
print format(
|
28
|
+
print format("%d tests", count).colorize(:white)
|
29
|
+
print format(", %d assertions, ", assertions)
|
30
30
|
color = failures.zero? && errors.zero? ? :green : :red
|
31
|
-
print format(
|
32
|
-
print format(
|
31
|
+
print format("%d failures, %d errors, ", failures, errors).colorize(color)
|
32
|
+
print format("%d skips", skips).colorize(:yellow)
|
33
33
|
puts
|
34
34
|
puts
|
35
35
|
end
|
@@ -37,11 +37,11 @@ module Minitest
|
|
37
37
|
def record(test)
|
38
38
|
super
|
39
39
|
if !test.skipped? && test.failure
|
40
|
-
print
|
40
|
+
print " "
|
41
41
|
print_colored_status(test)
|
42
42
|
print " #{test.name}"
|
43
43
|
puts
|
44
|
-
print
|
44
|
+
print " "
|
45
45
|
print test.failure.to_s.gsub("\n", "\n ")
|
46
46
|
puts
|
47
47
|
puts
|
@@ -74,23 +74,23 @@ end
|
|
74
74
|
|
75
75
|
Minitest::Reporters.use! Minitest::Reporters::SpoutReporter.new
|
76
76
|
|
77
|
-
require
|
78
|
-
require
|
79
|
-
require
|
80
|
-
require
|
81
|
-
require
|
82
|
-
require
|
83
|
-
require
|
84
|
-
require
|
85
|
-
require
|
86
|
-
require
|
87
|
-
require
|
88
|
-
require
|
89
|
-
require
|
90
|
-
require
|
91
|
-
require
|
77
|
+
require "spout/tests/json_validation"
|
78
|
+
require "spout/tests/domain_existence_validation"
|
79
|
+
require "spout/tests/domain_format"
|
80
|
+
require "spout/tests/domain_name_format"
|
81
|
+
require "spout/tests/domain_name_uniqueness"
|
82
|
+
require "spout/tests/domain_specified"
|
83
|
+
require "spout/tests/form_existence_validation"
|
84
|
+
require "spout/tests/form_name_format"
|
85
|
+
require "spout/tests/form_name_match"
|
86
|
+
require "spout/tests/form_name_uniqueness"
|
87
|
+
require "spout/tests/variable_display_name_length"
|
88
|
+
require "spout/tests/variable_name_format"
|
89
|
+
require "spout/tests/variable_name_match"
|
90
|
+
require "spout/tests/variable_name_uniqueness"
|
91
|
+
require "spout/tests/variable_type_validation"
|
92
92
|
|
93
|
-
require
|
93
|
+
require "spout/helpers/iterators"
|
94
94
|
|
95
95
|
module Spout
|
96
96
|
module Tests
|
data/lib/spout/version.rb
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
module Spout
|
4
4
|
module VERSION #:nodoc:
|
5
5
|
MAJOR = 0
|
6
|
-
MINOR =
|
7
|
-
TINY =
|
8
|
-
BUILD =
|
6
|
+
MINOR = 13
|
7
|
+
TINY = 0
|
8
|
+
BUILD = "beta1" # "pre", "rc", "rc2", nil
|
9
9
|
|
10
|
-
STRING = [MAJOR, MINOR, TINY, BUILD].compact.join(
|
10
|
+
STRING = [MAJOR, MINOR, TINY, BUILD].compact.join(".").freeze
|
11
11
|
end
|
12
12
|
end
|
@@ -204,8 +204,8 @@ tfoot td {
|
|
204
204
|
</div>
|
205
205
|
</td>
|
206
206
|
<td style="text-align:center">
|
207
|
-
<% matched = @matching_results.count{|csv_files, column, scr| scr.json[
|
208
|
-
<% total_count = @matching_results.count{|csv_files, column, scr| scr.json[
|
207
|
+
<% matched = @matching_results.count{|csv_files, column, scr| scr.json["type"] == "choices" and scr.domain_test} %>
|
208
|
+
<% total_count = @matching_results.count{|csv_files, column, scr| scr.json["type"] == "choices"} %>
|
209
209
|
<% matched_percent = (total_count == 0 ? 0 : (matched * 100.0 / total_count).floor) %>
|
210
210
|
<% missing_percent = 100 - matched_percent %>
|
211
211
|
<%= number_with_delimiter(matched) %> of <%= number_with_delimiter(total_count) %>
|
@@ -236,7 +236,7 @@ tfoot td {
|
|
236
236
|
<tr>
|
237
237
|
<td>
|
238
238
|
<% csv_files.each do |csv_file| %>
|
239
|
-
<code class="<%=
|
239
|
+
<code class="<%= "success" if scr.number_of_errors == 0 %>"><%= csv_file.gsub(/^csvs\/#{@subject_loader.csv_directory}\//, "") %></code><br />
|
240
240
|
<% end %>
|
241
241
|
</td>
|
242
242
|
<td><%= column %></td>
|
@@ -252,37 +252,37 @@ tfoot td {
|
|
252
252
|
<% if scr.json_id_test %>
|
253
253
|
<code class="success">"id": "<%= column %>"</code>
|
254
254
|
<% else %>
|
255
|
-
<code>"id": <%= scr.json[
|
255
|
+
<code>"id": <%= scr.json["id"].inspect %></code>
|
256
256
|
<% end %>
|
257
257
|
<% end %>
|
258
258
|
</td>
|
259
259
|
<td>
|
260
260
|
<% if scr.file_name_test %>
|
261
|
-
<code class="<%=
|
261
|
+
<code class="<%= "success" if scr.variable_type_test %>">"type": <%= scr.json["type"].inspect %></code>
|
262
262
|
<% end %>
|
263
263
|
</td>
|
264
264
|
<td>
|
265
|
-
<% if (scr.json[
|
266
|
-
<% if scr.domain_test || scr.json[
|
267
|
-
<code class="<%=
|
265
|
+
<% if (scr.json["type"] == "choices" || scr.json["domain"].to_s.downcase.strip != "") && scr.file_name_test %>
|
266
|
+
<% if scr.domain_test || scr.json["domain"].to_s.strip == "" %>
|
267
|
+
<code class="<%= "success" if scr.domain_test %>">"domain": <%= scr.json["domain"].inspect %></code>
|
268
268
|
<% else %>
|
269
|
-
<span class="text-danger"><code><%= scr.json[
|
269
|
+
<span class="text-danger"><code><%= scr.json["domain"] %>.json</code> missing</span>
|
270
270
|
<% end %>
|
271
271
|
<% end %>
|
272
272
|
</td>
|
273
273
|
<td style="white-space:nowrap">
|
274
|
-
<% if scr.json[
|
274
|
+
<% if scr.json["type"] == "choices" || scr.json["domain"].to_s.downcase.strip != "" %>
|
275
275
|
<% unused_domain_values = scr.valid_values - scr.csv_values %>
|
276
276
|
<% unused_values = (scr.valid_values | scr.csv_values) - (scr.valid_values & scr.csv_values) %>
|
277
277
|
<% if scr.values_test && unused_values.empty? %>
|
278
278
|
<div class="text-success" style="text-align:center"><span class="glyphicon glyphicon-ok"></span></div>
|
279
279
|
<% else %>
|
280
280
|
<% (scr.valid_values + scr.csv_values.compact.sort).uniq.each do |value| %>
|
281
|
-
<% value_as_number = format(
|
282
|
-
<% next if !scr.valid_values.include?(value) && %w(numeric integer).include?(scr.json[
|
283
|
-
<% class_type =
|
284
|
-
<% class_type =
|
285
|
-
<% class_type =
|
281
|
+
<% value_as_number = format("%g", value) rescue value_as_number = nil %>
|
282
|
+
<% next if !scr.valid_values.include?(value) && %w(numeric integer).include?(scr.json["type"]) && !value_as_number.nil? %>
|
283
|
+
<% class_type = "" %>
|
284
|
+
<% class_type = "success" if scr.valid_values.include?(value) %>
|
285
|
+
<% class_type = "default" if unused_domain_values.include?(value) %>
|
286
286
|
<code class="<%= class_type %>"><%= value %></code>
|
287
287
|
<% end %>
|
288
288
|
<% end %>
|
@@ -112,12 +112,12 @@ tfoot td {
|
|
112
112
|
<% @overall_results.each do |csv_file, major_outliers, minor_outliers, total_outliers| %>
|
113
113
|
<tr>
|
114
114
|
<td><%= csv_file %></td>
|
115
|
-
<td><code class="<%= major_outliers > 0 ?
|
116
|
-
<td><code class="<%= minor_outliers > 0 ?
|
115
|
+
<td><code class="<%= major_outliers > 0 ? "danger" : "default" %>"><%= number_with_delimiter(major_outliers) %></code></td>
|
116
|
+
<td><code class="<%= minor_outliers > 0 ? "warning" : "default" %>"><%= number_with_delimiter(minor_outliers) %></code></td>
|
117
117
|
<td>
|
118
|
-
<% css_class =
|
119
|
-
<% css_class =
|
120
|
-
<% css_class =
|
118
|
+
<% css_class = "success" %>
|
119
|
+
<% css_class = "warning" if minor_outliers > 0 %>
|
120
|
+
<% css_class = "danger" if major_outliers > 0 %>
|
121
121
|
<code class="<%= css_class %>"><%= number_with_delimiter(total_outliers) %>
|
122
122
|
</td>
|
123
123
|
</tr>
|
@@ -142,9 +142,9 @@ tfoot td {
|
|
142
142
|
<tr>
|
143
143
|
<td>
|
144
144
|
<% outlier_result.csv_files.each do |csv_file| %>
|
145
|
-
<% css_class =
|
146
|
-
<% css_class =
|
147
|
-
<code class="<%= css_class %>"><%= csv_file.gsub(/^csvs\/#{@subject_loader.csv_directory}\//,
|
145
|
+
<% css_class = "success" if outlier_result.outliers.size == 0 %>
|
146
|
+
<% css_class = "warning-pale" if outlier_result.major_outliers.size == 0 and outlier_result.minor_outliers.size > 0 %>
|
147
|
+
<code class="<%= css_class %>"><%= csv_file.gsub(/^csvs\/#{@subject_loader.csv_directory}\//, "") %></code><br />
|
148
148
|
<% end %></td>
|
149
149
|
<td><%= outlier_result.method %></td>
|
150
150
|
<td><%= outlier_result.display_name.to_s[0..20] %></td>
|
data/lib/spout.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spout/version"
|
4
4
|
|
5
|
-
require
|
5
|
+
require "spout/models/dictionary"
|
6
6
|
|
7
7
|
Spout::COMMANDS = {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
8
|
+
"c" => :coverage_report,
|
9
|
+
"d" => :deploy,
|
10
|
+
"e" => :exporter,
|
11
|
+
"g" => :generate_charts_and_tables,
|
12
|
+
"i" => :importer,
|
13
|
+
"n" => :new_project,
|
14
|
+
"o" => :outliers_report,
|
15
|
+
"t" => :test,
|
16
|
+
"u" => :update,
|
17
|
+
"v" => :version
|
18
18
|
}
|
19
19
|
|
20
20
|
# Launch spout commands from command line.
|
@@ -24,56 +24,56 @@ module Spout
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.new_project(argv)
|
27
|
-
require
|
27
|
+
require "spout/commands/project_generator"
|
28
28
|
Spout::Commands::ProjectGenerator.new(argv)
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.coverage_report(argv)
|
32
|
-
require
|
32
|
+
require "spout/commands/coverage"
|
33
33
|
Spout::Commands::Coverage.new(standard_version, argv)
|
34
34
|
rescue NoMemoryError
|
35
35
|
puts "[NoMemoryError] You made Spout cry... Spout doesn't run on potatoes :'-("
|
36
36
|
end
|
37
37
|
|
38
38
|
def self.exporter(argv)
|
39
|
-
require
|
39
|
+
require "spout/commands/exporter"
|
40
40
|
Spout::Commands::Exporter.new(standard_version, argv)
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.generate_charts_and_tables(argv)
|
44
44
|
argv = argv.last(argv.size - 1)
|
45
|
-
require
|
45
|
+
require "spout/commands/graphs"
|
46
46
|
Spout::Commands::Graphs.new(argv, standard_version)
|
47
47
|
end
|
48
48
|
|
49
49
|
def self.help(argv)
|
50
|
-
require
|
50
|
+
require "spout/commands/help"
|
51
51
|
Spout::Commands::Help.new(argv)
|
52
52
|
end
|
53
53
|
|
54
54
|
def self.deploy(argv)
|
55
|
-
require
|
55
|
+
require "spout/commands/deploy"
|
56
56
|
Spout::Commands::Deploy.new(argv, standard_version)
|
57
57
|
end
|
58
58
|
|
59
59
|
def self.importer(argv)
|
60
|
-
require
|
60
|
+
require "spout/commands/importer"
|
61
61
|
Spout::Commands::Importer.new(argv)
|
62
62
|
end
|
63
63
|
|
64
64
|
def self.outliers_report(argv)
|
65
|
-
require
|
65
|
+
require "spout/commands/outliers"
|
66
66
|
Spout::Commands::Outliers.new(standard_version, argv)
|
67
67
|
end
|
68
68
|
|
69
69
|
def self.test(_argv)
|
70
|
-
system
|
71
|
-
# require
|
70
|
+
system "bundle exec rake"
|
71
|
+
# require "spout/commands/test_runner"
|
72
72
|
# Spout::Commands::TestRunner.new(argv)
|
73
73
|
end
|
74
74
|
|
75
75
|
def self.update(argv)
|
76
|
-
require
|
76
|
+
require "spout/commands/update"
|
77
77
|
Spout::Commands::Update.start(argv)
|
78
78
|
end
|
79
79
|
|
@@ -82,9 +82,9 @@ module Spout
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def self.standard_version
|
85
|
-
version = File.open(
|
86
|
-
version ==
|
85
|
+
version = File.open("VERSION", &:readline).strip
|
86
|
+
version == "" ? "1.0.0" : version
|
87
87
|
rescue
|
88
|
-
|
88
|
+
"1.0.0"
|
89
89
|
end
|
90
90
|
end
|
data/spout.gemspec
CHANGED
@@ -8,34 +8,34 @@
|
|
8
8
|
# gem list -r spout
|
9
9
|
# gem install spout
|
10
10
|
|
11
|
-
lib = File.expand_path(
|
11
|
+
lib = File.expand_path("../lib", __FILE__)
|
12
12
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
13
|
-
require
|
13
|
+
require "spout/version"
|
14
14
|
|
15
15
|
Gem::Specification.new do |spec|
|
16
|
-
spec.name =
|
16
|
+
spec.name = "spout"
|
17
17
|
spec.version = Spout::VERSION::STRING
|
18
|
-
spec.authors = [
|
19
|
-
spec.email = [
|
20
|
-
spec.description =
|
21
|
-
spec.summary =
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
spec.homepage =
|
28
|
-
spec.license =
|
18
|
+
spec.authors = ["Remo Mueller"]
|
19
|
+
spec.email = ["remosm@gmail.com"]
|
20
|
+
spec.description = "Manage your data dictionary as a JSON repository, and easily export back to CSV."
|
21
|
+
spec.summary = "Turn your CSV data dictionary into a JSON repository. "\
|
22
|
+
"Collaborate with others to update the data dictionary "\
|
23
|
+
"in JSON format. Generate new Data Dictionary from the "\
|
24
|
+
"JSON repository. Test and validate your data "\
|
25
|
+
"dictionary using built-in tests, or add your own for "\
|
26
|
+
"further validations."
|
27
|
+
spec.homepage = "https://github.com/sleepepi/spout"
|
28
|
+
spec.license = "MIT"
|
29
29
|
|
30
|
-
spec.files = Dir[
|
30
|
+
spec.files = Dir["{bin,lib}/**/*"] + ["CHANGELOG.md", "LICENSE", "Rakefile", "README.md", "spout.gemspec"]
|
31
31
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
32
32
|
spec.test_files = spec.files.grep(%r{^(test)/})
|
33
|
-
spec.require_paths = [
|
33
|
+
spec.require_paths = ["lib"]
|
34
34
|
|
35
|
-
spec.add_dependency
|
36
|
-
spec.add_dependency
|
37
|
-
spec.add_dependency
|
38
|
-
spec.add_dependency
|
39
|
-
spec.add_dependency
|
40
|
-
spec.add_dependency
|
35
|
+
spec.add_dependency "bundler", "~> 1.13"
|
36
|
+
spec.add_dependency "rake"
|
37
|
+
spec.add_dependency "minitest"
|
38
|
+
spec.add_dependency "minitest-reporters"
|
39
|
+
spec.add_dependency "json"
|
40
|
+
spec.add_dependency "colorize", "~> 0.8.1"
|
41
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Remo Mueller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -205,12 +205,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
205
205
|
version: '0'
|
206
206
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
207
207
|
requirements:
|
208
|
-
- - "
|
208
|
+
- - ">"
|
209
209
|
- !ruby/object:Gem::Version
|
210
|
-
version:
|
210
|
+
version: 1.3.1
|
211
211
|
requirements: []
|
212
212
|
rubyforge_project:
|
213
|
-
rubygems_version: 2.6.
|
213
|
+
rubygems_version: 2.6.12
|
214
214
|
signing_key:
|
215
215
|
specification_version: 4
|
216
216
|
summary: Turn your CSV data dictionary into a JSON repository. Collaborate with others
|