spout 0.8.0.beta10 → 0.8.0.beta11
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 +3 -0
- data/README.md +11 -4
- data/bin/spout +1 -1
- data/lib/spout/actions.rb +92 -172
- data/lib/spout/commands/coverage.rb +11 -4
- data/lib/spout/commands/exporter.rb +62 -0
- data/lib/spout/commands/graphs.rb +3 -3
- data/lib/spout/commands/images.rb +45 -36
- data/lib/spout/commands/importer.rb +125 -0
- data/lib/spout/commands/outliers.rb +13 -5
- data/lib/spout/commands/project_generator.rb +66 -0
- data/lib/spout/helpers/number_helper.rb +9 -0
- data/lib/spout/helpers/subject_loader.rb +6 -4
- data/lib/spout/tasks/engine.rake +0 -193
- data/lib/spout/templates/ruby-version +1 -1
- data/lib/spout/templates/spout.yml +2 -0
- data/lib/spout/version.rb +1 -1
- data/lib/spout.rb +108 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d24bb02bdd280c06d7525c64dcf7ba2e8d41cbdd
|
4
|
+
data.tar.gz: 4320a06b3bf72ef336bfd211e4b54c2cfbcc379d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6d305cc70fb6bcbd16e97c7450f0bed6f35bf456f93becc7ce23c97b766d5eda07a06c152941d3c127a61cd8042737013b99c01ba13563226a6bd3186453351
|
7
|
+
data.tar.gz: 2493538c40d38fb5708795f4c4b7dc75b0eb3ecf7ec119e0365244a38dae4f86753e60c5f6422bc1361e1e4b8319e8e61dcfcdbe65710745473043d885a8fb9e
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -37,6 +37,7 @@ spout import data_dictionary.csv
|
|
37
37
|
The CSV should contain at minimal the two column headers:
|
38
38
|
|
39
39
|
`id`: This column will give the variable its name, and also be used to name the file, i.e. `<id>.json`
|
40
|
+
|
40
41
|
`folder`: This can be blank, however it is used to place variables into a folder hiearchy. The folder column can contain forward slashes `/` to place a variable into a subfolder. An example may be, `id`: `myvarid`, `folder`: `Demographics/Subfolder` would create a file `variables/Demographics/Subfolder/myvarid.json`
|
41
42
|
|
42
43
|
Other columns that will be interpreted include:
|
@@ -70,18 +71,21 @@ All other columns get grouped into a hash labeled `other`.
|
|
70
71
|
#### Importing domains from an existing CSV file
|
71
72
|
|
72
73
|
```
|
73
|
-
spout
|
74
|
+
spout import data_dictionary_domains.csv --domains
|
74
75
|
```
|
75
76
|
|
76
77
|
The CSV should contain at minimal three column headers:
|
77
78
|
|
78
79
|
`domain_id`: The name of the associated domain for the choice/option.
|
80
|
+
|
79
81
|
`value`: The value of the choice/option.
|
82
|
+
|
80
83
|
`display_name`: The display name of the choice/option.
|
81
84
|
|
82
85
|
Other columns that are imported include:
|
83
86
|
|
84
87
|
`description`: A longer description of the choice/option.
|
88
|
+
|
85
89
|
`folder`: The name of the folder path where the domain resides.
|
86
90
|
|
87
91
|
|
@@ -203,9 +207,12 @@ Example `.spout.yml` file:
|
|
203
207
|
```yml
|
204
208
|
visit: visitnumber
|
205
209
|
charts:
|
206
|
-
|
207
|
-
|
208
|
-
|
210
|
+
- chart: age
|
211
|
+
title: Age
|
212
|
+
- chart: gender
|
213
|
+
title: Gender
|
214
|
+
- chart: race
|
215
|
+
title: Race
|
209
216
|
```
|
210
217
|
|
211
218
|
To only generate graphs for a few select variables, add the variable names after the `spout graphs` command.
|
data/bin/spout
CHANGED
data/lib/spout/actions.rb
CHANGED
@@ -1,172 +1,92 @@
|
|
1
|
-
module Spout
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
def new_template_dictionary(argv)
|
95
|
-
@full_path = File.join(argv[1].to_s.strip)
|
96
|
-
usage = <<-EOT
|
97
|
-
|
98
|
-
Usage: spout new FOLDER
|
99
|
-
|
100
|
-
The FOLDER must be empty or new.
|
101
|
-
|
102
|
-
EOT
|
103
|
-
|
104
|
-
if @full_path == '' or ( Dir.exists?(@full_path) and (Dir.entries(@full_path) & ['.gitignore', '.ruby-version', '.travis.yml', 'Gemfile', 'Rakefile', 'domains', 'variables', 'test']).size > 0 )
|
105
|
-
puts usage
|
106
|
-
exit(0)
|
107
|
-
end
|
108
|
-
|
109
|
-
FileUtils.mkpath(@full_path)
|
110
|
-
|
111
|
-
copy_file 'gitignore', '.gitignore'
|
112
|
-
copy_file 'ruby-version', '.ruby-version'
|
113
|
-
copy_file 'travis.yml', '.travis.yml'
|
114
|
-
copy_file 'Gemfile'
|
115
|
-
copy_file 'Rakefile'
|
116
|
-
directory 'domains'
|
117
|
-
copy_file 'keep', 'domains/.keep'
|
118
|
-
directory 'variables'
|
119
|
-
copy_file 'keep', 'variables/.keep'
|
120
|
-
directory 'test'
|
121
|
-
copy_file 'test/dictionary_test.rb'
|
122
|
-
copy_file 'test/test_helper.rb'
|
123
|
-
puts " run".colorize( :green ) + " bundle install".colorize( :light_cyan )
|
124
|
-
Dir.chdir(@full_path)
|
125
|
-
system "bundle install"
|
126
|
-
end
|
127
|
-
|
128
|
-
def coverage_report(argv)
|
129
|
-
system "bundle exec rake spout:coverage"
|
130
|
-
end
|
131
|
-
|
132
|
-
def outliers_report(argv)
|
133
|
-
system "bundle exec rake spout:outliers"
|
134
|
-
end
|
135
|
-
|
136
|
-
def flag_values(flags, param)
|
137
|
-
flags.select{|f| f[0..((param.size + 3) - 1)] == "--#{param}-" and f.length > param.size + 3}.collect{|f| f[(param.size + 3)..-1]}
|
138
|
-
end
|
139
|
-
|
140
|
-
def generate_images(flags)
|
141
|
-
params = {}
|
142
|
-
params['types'] = flag_values(flags, 'type')
|
143
|
-
params['variable_ids'] = flag_values(flags, 'id')
|
144
|
-
params['sizes'] = flag_values(flags, 'size')
|
145
|
-
|
146
|
-
params_string = params.collect{|key, values| "#{key}=#{values.join(',')}"}.join(' ')
|
147
|
-
|
148
|
-
system "bundle exec rake spout:images #{params_string}"
|
149
|
-
end
|
150
|
-
|
151
|
-
def generate_charts_and_tables(variables)
|
152
|
-
system "bundle exec rake spout:json variables=#{variables.join(',')}"
|
153
|
-
end
|
154
|
-
|
155
|
-
private
|
156
|
-
|
157
|
-
def copy_file(template_file, file_name = '')
|
158
|
-
file_name = template_file if file_name == ''
|
159
|
-
file_path = File.join(@full_path, file_name)
|
160
|
-
template_file_path = File.join(File.expand_path(File.dirname(__FILE__)), "templates", template_file)
|
161
|
-
puts " create".colorize( :green ) + " #{file_name}"
|
162
|
-
FileUtils.copy(template_file_path, file_path)
|
163
|
-
end
|
164
|
-
|
165
|
-
def directory(directory_name)
|
166
|
-
directory_path = File.join(@full_path, directory_name)
|
167
|
-
puts " create".colorize( :green ) + " #{directory_name}"
|
168
|
-
FileUtils.mkpath(directory_path)
|
169
|
-
end
|
170
|
-
|
171
|
-
end
|
172
|
-
end
|
1
|
+
# module Spout
|
2
|
+
# class Actions
|
3
|
+
|
4
|
+
# def interpret(argv)
|
5
|
+
# # case argv.first.to_s.scan(/\w/).first
|
6
|
+
# case argv.first
|
7
|
+
# when 'new', 'n', 'ne', '-new', '-n', '-ne'
|
8
|
+
# new_template_dictionary(argv)
|
9
|
+
# when '--version', '-v', '-ve', '-ver', 'version', 'v', 've', 'ver'
|
10
|
+
# puts "Spout #{Spout::VERSION::STRING}"
|
11
|
+
# when 'test', 't', 'te', 'tes', '--test', '-t', '-te', '-tes'
|
12
|
+
# system "bundle exec rake HIDE_PASSING_TESTS=true"
|
13
|
+
# # when 'tv'
|
14
|
+
# # system "bundle exec rake"
|
15
|
+
# when 'import', 'i', 'im', 'imp', '--import', '-i', '-im', '-imp'
|
16
|
+
# import_from_csv(argv)
|
17
|
+
# when 'import_domain', '--import_domain', 'import_domains', '--import_domains'
|
18
|
+
# import_from_csv(argv, 'domains')
|
19
|
+
# when 'export', 'e', 'ex', 'exp', '--export', '-e', '-ex', '-exp'
|
20
|
+
# new_data_dictionary_export(argv)
|
21
|
+
# when 'coverage', '-coverage', '--coverage', 'c', '-c'
|
22
|
+
# coverage_report(argv)
|
23
|
+
# when 'pngs', '-pngs', '--pngs', 'p', '-p'
|
24
|
+
# generate_images(argv.last(argv.size - 1))
|
25
|
+
# when 'graphs', '-graphs', '--graphs', 'g', '-g'
|
26
|
+
# generate_charts_and_tables(argv.last(argv.size - 1))
|
27
|
+
# when 'outliers', '-outliers', '--outliers', 'o', '-o'
|
28
|
+
# outliers_report(argv)
|
29
|
+
# # else
|
30
|
+
# # help
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
|
34
|
+
# protected
|
35
|
+
|
36
|
+
# def csv_usage
|
37
|
+
# usage = <<-EOT
|
38
|
+
|
39
|
+
# Usage: spout import CSVFILE
|
40
|
+
|
41
|
+
# The CSVFILE must be the location of a valid CSV file.
|
42
|
+
|
43
|
+
# EOT
|
44
|
+
# usage
|
45
|
+
# end
|
46
|
+
|
47
|
+
# def import_from_csv(argv, type = "")
|
48
|
+
# csv_file = File.join(argv[1].to_s.strip)
|
49
|
+
# if File.exists?(csv_file)
|
50
|
+
# system "bundle exec rake spout:import CSV=#{csv_file} #{'TYPE='+type if type.to_s != ''}"
|
51
|
+
# else
|
52
|
+
# puts csv_usage
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
|
56
|
+
# def new_data_dictionary_export(argv)
|
57
|
+
# version = argv[1].to_s.gsub(/[^a-zA-Z0-9\.-]/, '_').strip
|
58
|
+
# version_string = (version == '' ? "" : "VERSION=#{version}")
|
59
|
+
# system "bundle exec rake spout:create #{version_string}"
|
60
|
+
# end
|
61
|
+
|
62
|
+
# def coverage_report(argv)
|
63
|
+
# require 'spout/commands/coverage'
|
64
|
+
# Spout::Commands::Coverage.new(standard_version, argv)
|
65
|
+
# # system "bundle exec rake spout:coverage"
|
66
|
+
# end
|
67
|
+
|
68
|
+
# def outliers_report(argv)
|
69
|
+
# system "bundle exec rake spout:outliers"
|
70
|
+
# end
|
71
|
+
|
72
|
+
# def flag_values(flags, param)
|
73
|
+
# flags.select{|f| f[0..((param.size + 3) - 1)] == "--#{param}-" and f.length > param.size + 3}.collect{|f| f[(param.size + 3)..-1]}
|
74
|
+
# end
|
75
|
+
|
76
|
+
# def generate_images(flags)
|
77
|
+
# params = {}
|
78
|
+
# params['types'] = flag_values(flags, 'type')
|
79
|
+
# params['variable_ids'] = flag_values(flags, 'id')
|
80
|
+
# params['sizes'] = flag_values(flags, 'size')
|
81
|
+
|
82
|
+
# params_string = params.collect{|key, values| "#{key}=#{values.join(',')}"}.join(' ')
|
83
|
+
|
84
|
+
# system "bundle exec rake spout:images #{params_string}"
|
85
|
+
# end
|
86
|
+
|
87
|
+
# def generate_charts_and_tables(variables)
|
88
|
+
# system "bundle exec rake spout:json variables=#{variables.join(',')}"
|
89
|
+
# end
|
90
|
+
|
91
|
+
# end
|
92
|
+
# end
|
@@ -1,13 +1,18 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'erb'
|
2
3
|
|
3
4
|
require 'spout/helpers/subject_loader'
|
4
5
|
require 'spout/models/coverage_result'
|
6
|
+
require 'spout/helpers/number_helper'
|
5
7
|
|
6
8
|
module Spout
|
7
9
|
module Commands
|
8
10
|
class Coverage
|
9
|
-
|
11
|
+
include Spout::Helpers::NumberHelper
|
12
|
+
|
13
|
+
def initialize(standard_version, argv)
|
10
14
|
@standard_version = standard_version
|
15
|
+
@console = (argv.delete('--console') != nil)
|
11
16
|
|
12
17
|
@variable_files = Dir.glob("variables/**/*.json")
|
13
18
|
@valid_ids = []
|
@@ -60,10 +65,12 @@ module Spout
|
|
60
65
|
file.puts ERB.new(File.read(erb_location)).result(binding)
|
61
66
|
end
|
62
67
|
|
63
|
-
|
64
|
-
|
68
|
+
unless @console
|
69
|
+
open_command = 'open' if RUBY_PLATFORM.match(/darwin/) != nil
|
70
|
+
open_command = 'start' if RUBY_PLATFORM.match(/mingw/) != nil
|
65
71
|
|
66
|
-
|
72
|
+
system "#{open_command} #{coverage_file}" if ['start', 'open'].include?(open_command)
|
73
|
+
end
|
67
74
|
puts "#{coverage_file}\n\n"
|
68
75
|
end
|
69
76
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Spout
|
4
|
+
module Commands
|
5
|
+
class Exporter
|
6
|
+
def initialize(standard_version, argv)
|
7
|
+
@csv_file = argv[1].to_s
|
8
|
+
@standard_version = standard_version
|
9
|
+
expanded_export!
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def expanded_export!
|
15
|
+
folder = "dd/#{@standard_version}"
|
16
|
+
puts " create".colorize( :green ) + " #{folder}"
|
17
|
+
FileUtils.mkpath folder
|
18
|
+
|
19
|
+
variables_export_file = "variables.csv"
|
20
|
+
puts " export".colorize( :blue ) + " #{folder}/#{variables_export_file}"
|
21
|
+
CSV.open("#{folder}/#{variables_export_file}", "wb") do |csv|
|
22
|
+
keys = %w(id display_name description type units domain labels calculation)
|
23
|
+
csv << ['folder'] + keys
|
24
|
+
Dir.glob("variables/**/*.json").each do |file|
|
25
|
+
if json = JSON.parse(File.read(file)) rescue false
|
26
|
+
variable_folder = variable_folder_path(file)
|
27
|
+
csv << [variable_folder] + keys.collect{|key| json[key].kind_of?(Array) ? json[key].join(';') : json[key].to_s}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
domains_export_file = "domains.csv"
|
32
|
+
puts " export".colorize( :blue ) + " #{folder}/#{domains_export_file}"
|
33
|
+
CSV.open("#{folder}/#{domains_export_file}", "wb") do |csv|
|
34
|
+
keys = %w(value display_name description)
|
35
|
+
csv << ['folder', 'domain_id'] + keys
|
36
|
+
Dir.glob("domains/**/*.json").each do |file|
|
37
|
+
if json = JSON.parse(File.read(file)) rescue false
|
38
|
+
domain_folder = domain_folder_path(file)
|
39
|
+
domain_name = extract_domain_name(file)
|
40
|
+
json.each do |hash|
|
41
|
+
csv << [domain_folder, domain_name] + keys.collect{|key| hash[key]}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def extract_domain_name(file)
|
49
|
+
file.gsub(/domains\//, '').split('/').last.to_s.gsub(/.json/, '')
|
50
|
+
end
|
51
|
+
|
52
|
+
def domain_folder_path(file)
|
53
|
+
file.gsub(/domains\//, '').split('/')[0..-2].join('/')
|
54
|
+
end
|
55
|
+
|
56
|
+
def variable_folder_path(file)
|
57
|
+
file.gsub(/variables\//, '').split('/')[0..-2].join('/')
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -28,7 +28,7 @@ module Spout
|
|
28
28
|
else
|
29
29
|
puts "The YAML file needs to be in the following format:"
|
30
30
|
puts "---\nvisit: visit_variable_name\ncharts:\n- chart: age_variable_name\n title: Age\n- chart: gender_variable_name\n title: Gender\n- chart: race_variable_name\n title: Race\n"
|
31
|
-
|
31
|
+
return self
|
32
32
|
end
|
33
33
|
|
34
34
|
if Spout::Helpers::ChartTypes::get_json(@visit, 'variable') == nil
|
@@ -37,12 +37,12 @@ module Spout
|
|
37
37
|
else
|
38
38
|
puts "Could not find the following visit variable: #{@visit}"
|
39
39
|
end
|
40
|
-
|
40
|
+
return self
|
41
41
|
end
|
42
42
|
missing_variables = chart_variables.select{|c| Spout::Helpers::ChartTypes::get_json(c['chart'], 'variable') == nil}
|
43
43
|
if missing_variables.count > 0
|
44
44
|
puts "Could not find the following chart variable#{'s' unless missing_variables.size == 1}: #{missing_variables.join(', ')}"
|
45
|
-
|
45
|
+
return self
|
46
46
|
end
|
47
47
|
|
48
48
|
argv_string = variables.join(',')
|
@@ -11,9 +11,11 @@ module Spout
|
|
11
11
|
module Commands
|
12
12
|
class Images
|
13
13
|
|
14
|
-
def initialize(types, variable_ids, sizes, standard_version)
|
14
|
+
def initialize(types, variable_ids, sizes, standard_version, argv)
|
15
15
|
@variable_files = Dir.glob('variables/**/*.json')
|
16
16
|
@standard_version = standard_version
|
17
|
+
@pretend = (argv.delete('--pretend') != nil)
|
18
|
+
|
17
19
|
|
18
20
|
@valid_ids = variable_ids
|
19
21
|
|
@@ -60,42 +62,44 @@ module Spout
|
|
60
62
|
|
61
63
|
filtered_subjects = @subjects.select{ |s| s.send(@visit) != nil }
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
},
|
76
|
-
"xAxis": {
|
77
|
-
"categories": #{chart_json[:categories].to_json}
|
78
|
-
},
|
79
|
-
"yAxis": {
|
65
|
+
chart_json = Spout::Helpers::ChartTypes::chart_histogram(@visit, filtered_subjects, json, variable_name)
|
66
|
+
|
67
|
+
if chart_json
|
68
|
+
File.open(tmp_options_file, "w") do |outfile|
|
69
|
+
outfile.puts <<-eos
|
70
|
+
{
|
71
|
+
"credits": {
|
72
|
+
"enabled": false
|
73
|
+
},
|
74
|
+
"chart": {
|
75
|
+
"type": "column"
|
76
|
+
},
|
80
77
|
"title": {
|
81
|
-
"text":
|
82
|
-
}
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
"
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
78
|
+
"text": ""
|
79
|
+
},
|
80
|
+
"xAxis": {
|
81
|
+
"categories": #{chart_json[:categories].to_json}
|
82
|
+
},
|
83
|
+
"yAxis": {
|
84
|
+
"title": {
|
85
|
+
"text": #{chart_json[:units].to_json}
|
86
|
+
}
|
87
|
+
},
|
88
|
+
"plotOptions": {
|
89
|
+
"column": {
|
90
|
+
"pointPadding": 0.2,
|
91
|
+
"borderWidth": 0,
|
92
|
+
"stacking": #{chart_json[:stacking].to_json}
|
93
|
+
}
|
94
|
+
},
|
95
|
+
"series": #{chart_json[:series].to_json}
|
96
|
+
}
|
97
|
+
eos
|
98
|
+
end
|
99
|
+
run_phantom_js("#{json['id']}-lg.png", 600, tmp_options_file) if sizes.size == 0 or sizes.include?('lg')
|
100
|
+
run_phantom_js("#{json['id']}.png", 75, tmp_options_file) if sizes.size == 0 or sizes.include?('sm')
|
94
101
|
end
|
95
102
|
|
96
|
-
|
97
|
-
run_phantom_js("#{json['id']}-lg.png", 600, tmp_options_file) if sizes.size == 0 or sizes.include?('lg')
|
98
|
-
run_phantom_js("#{json['id']}.png", 75, tmp_options_file) if sizes.size == 0 or sizes.include?('sm')
|
99
103
|
end
|
100
104
|
File.delete(tmp_options_file) if File.exists?(tmp_options_file)
|
101
105
|
end
|
@@ -267,8 +271,13 @@ module Spout
|
|
267
271
|
end
|
268
272
|
|
269
273
|
phantomjs_command = "#{open_command} #{directory}/highcharts-convert.js -infile #{tmp_options_file} -outfile #{graph_path} -scale 2.5 -width #{width} -constr Chart"
|
270
|
-
|
271
|
-
|
274
|
+
|
275
|
+
if @pretend
|
276
|
+
puts phantomjs_command
|
277
|
+
else
|
278
|
+
`#{phantomjs_command}`
|
279
|
+
end
|
280
|
+
|
272
281
|
end
|
273
282
|
|
274
283
|
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Spout
|
4
|
+
module Commands
|
5
|
+
class Importer
|
6
|
+
def initialize(argv)
|
7
|
+
use_domains = (argv.delete('--domains') != nil)
|
8
|
+
|
9
|
+
@csv_file = argv[1].to_s
|
10
|
+
|
11
|
+
unless File.exists?(@csv_file)
|
12
|
+
puts csv_usage
|
13
|
+
return self
|
14
|
+
end
|
15
|
+
|
16
|
+
if use_domains
|
17
|
+
import_domains
|
18
|
+
else
|
19
|
+
import_variables
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def csv_usage
|
25
|
+
usage = <<-EOT
|
26
|
+
|
27
|
+
Usage: spout import CSVFILE
|
28
|
+
|
29
|
+
The CSVFILE must be the location of a valid CSV file.
|
30
|
+
|
31
|
+
EOT
|
32
|
+
usage
|
33
|
+
end
|
34
|
+
|
35
|
+
def import_variables
|
36
|
+
CSV.parse( File.open(@csv_file, 'r:iso-8859-1:utf-8'){|f| f.read}, headers: true ) do |line|
|
37
|
+
row = line.to_hash
|
38
|
+
if not row.keys.include?('id')
|
39
|
+
puts "\nMissing column header `".colorize( :red ) + "id".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
40
|
+
exit(1)
|
41
|
+
end
|
42
|
+
next if row['id'] == ''
|
43
|
+
folder = File.join('variables', row.delete('folder').to_s)
|
44
|
+
FileUtils.mkpath folder
|
45
|
+
hash = {}
|
46
|
+
id = row.delete('id')
|
47
|
+
hash['id'] = id
|
48
|
+
hash['display_name'] = row.delete('display_name')
|
49
|
+
hash['description'] = row.delete('description').to_s
|
50
|
+
hash['type'] = row.delete('type')
|
51
|
+
domain = row.delete('domain').to_s
|
52
|
+
hash['domain'] = domain if domain != ''
|
53
|
+
units = row.delete('units').to_s
|
54
|
+
hash['units'] = units if units != ''
|
55
|
+
calculation = row.delete('calculation').to_s
|
56
|
+
hash['calculation'] = calculation if calculation != ''
|
57
|
+
labels = row.delete('labels').to_s.split(';')
|
58
|
+
hash['labels'] = labels if labels.size > 0
|
59
|
+
hash['other'] = row unless row.empty?
|
60
|
+
|
61
|
+
file_name = File.join(folder, id.to_s.downcase + '.json')
|
62
|
+
File.open(file_name, 'w') do |file|
|
63
|
+
file.write(JSON.pretty_generate(hash) + "\n")
|
64
|
+
end
|
65
|
+
puts " create".colorize( :green ) + " #{file_name}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def import_domains
|
70
|
+
domains = {}
|
71
|
+
|
72
|
+
CSV.parse( File.open(@csv_file, 'r:iso-8859-1:utf-8'){|f| f.read}, headers: true ) do |line|
|
73
|
+
row = line.to_hash
|
74
|
+
if not row.keys.include?('domain_id')
|
75
|
+
puts "\nMissing column header `".colorize( :red ) + "domain_id".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
76
|
+
exit(1)
|
77
|
+
end
|
78
|
+
if not row.keys.include?('value')
|
79
|
+
puts "\nMissing column header `".colorize( :red ) + "value".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
80
|
+
exit(1)
|
81
|
+
end
|
82
|
+
if not row.keys.include?('display_name')
|
83
|
+
puts "\nMissing column header `".colorize( :red ) + "display_name".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
84
|
+
exit(1)
|
85
|
+
end
|
86
|
+
|
87
|
+
next if row['domain_id'].to_s == '' or row['value'].to_s == '' or row['display_name'].to_s == ''
|
88
|
+
folder = File.join('domains', row['folder'].to_s).gsub(/[^a-zA-Z0-9_\/\.-]/, '_')
|
89
|
+
domain_name = row['domain_id'].to_s.gsub(/[^a-zA-Z0-9_\/\.-]/, '_')
|
90
|
+
domains[domain_name] ||= {}
|
91
|
+
domains[domain_name]["folder"] = folder
|
92
|
+
domains[domain_name]["options"] ||= []
|
93
|
+
|
94
|
+
hash = {}
|
95
|
+
hash['value'] = row.delete('value').to_s
|
96
|
+
hash['display_name'] = row.delete('display_name').to_s
|
97
|
+
hash['description'] = row.delete('description').to_s
|
98
|
+
|
99
|
+
domains[domain_name]["options"] << hash
|
100
|
+
end
|
101
|
+
|
102
|
+
domains.each do |domain_name, domain_hash|
|
103
|
+
folder = domain_hash["folder"]
|
104
|
+
FileUtils.mkpath folder
|
105
|
+
|
106
|
+
file_name = File.join(folder, domain_name.to_s.downcase + '.json')
|
107
|
+
|
108
|
+
File.open(file_name, 'w') do |file|
|
109
|
+
file.write(JSON.pretty_generate(domain_hash["options"]) + "\n")
|
110
|
+
end
|
111
|
+
puts " create".colorize( :green ) + " #{file_name}"
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def additional_csv_info
|
119
|
+
"\n\nFor additional information on specifying CSV column headers before import see:\n\n " + "https://github.com/sleepepi/spout#generate-a-new-repository-from-an-existing-csv-file".colorize( :light_cyan ) + "\n\n"
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -1,13 +1,18 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'erb'
|
2
3
|
|
3
4
|
require 'spout/helpers/subject_loader'
|
4
5
|
require 'spout/models/outlier_result'
|
6
|
+
require 'spout/helpers/number_helper'
|
5
7
|
|
6
8
|
module Spout
|
7
9
|
module Commands
|
8
10
|
class Outliers
|
9
|
-
|
11
|
+
include Spout::Helpers::NumberHelper
|
12
|
+
|
13
|
+
def initialize(standard_version, argv)
|
10
14
|
@standard_version = standard_version
|
15
|
+
@console = (argv.delete('--console') != nil)
|
11
16
|
|
12
17
|
@variable_files = Dir.glob('variables/**/*.json')
|
13
18
|
@valid_ids = []
|
@@ -19,6 +24,7 @@ module Spout
|
|
19
24
|
@subject_loader = Spout::Helpers::SubjectLoader.new(@variable_files, @valid_ids, @standard_version, @number_of_rows, @visit)
|
20
25
|
@subject_loader.load_subjects_from_csvs!
|
21
26
|
@subjects = @subject_loader.subjects
|
27
|
+
run_outliers_report!
|
22
28
|
end
|
23
29
|
|
24
30
|
def run_outliers_report!
|
@@ -47,13 +53,15 @@ module Spout
|
|
47
53
|
file.puts ERB.new(File.read(erb_location)).result(binding)
|
48
54
|
end
|
49
55
|
|
50
|
-
|
51
|
-
|
56
|
+
unless @console
|
57
|
+
open_command = 'open' if RUBY_PLATFORM.match(/darwin/) != nil
|
58
|
+
open_command = 'start' if RUBY_PLATFORM.match(/mingw/) != nil
|
52
59
|
|
53
|
-
|
60
|
+
system "#{open_command} #{html_file}" if ['start', 'open'].include?(open_command)
|
61
|
+
end
|
54
62
|
puts "#{html_file}\n\n"
|
63
|
+
return self
|
55
64
|
end
|
56
|
-
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
TEMPLATES_DIRECTORY = File.expand_path('../../templates', __FILE__)
|
2
|
+
|
3
|
+
module Spout
|
4
|
+
module Commands
|
5
|
+
class ProjectGenerator
|
6
|
+
def initialize(argv)
|
7
|
+
generate_folder_structure!(argv)
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate_folder_structure!(argv)
|
11
|
+
skip_gemfile = (argv.delete('--skip-gemfile') != nil)
|
12
|
+
@full_path = File.join(argv[1].to_s.strip)
|
13
|
+
usage = <<-EOT
|
14
|
+
|
15
|
+
Usage: spout new FOLDER
|
16
|
+
|
17
|
+
The FOLDER must be empty or new.
|
18
|
+
|
19
|
+
EOT
|
20
|
+
|
21
|
+
if @full_path == '' or ( Dir.exists?(@full_path) and (Dir.entries(@full_path) & ['.gitignore', '.ruby-version', '.travis.yml', 'Gemfile', 'Rakefile', 'domains', 'variables', 'test']).size > 0 )
|
22
|
+
puts usage
|
23
|
+
exit(0)
|
24
|
+
end
|
25
|
+
|
26
|
+
FileUtils.mkpath(@full_path)
|
27
|
+
|
28
|
+
copy_file 'gitignore', '.gitignore'
|
29
|
+
copy_file 'ruby-version', '.ruby-version'
|
30
|
+
copy_file 'travis.yml', '.travis.yml'
|
31
|
+
copy_file 'spout.yml', '.spout.yml'
|
32
|
+
copy_file 'Gemfile'
|
33
|
+
copy_file 'Rakefile'
|
34
|
+
directory 'domains'
|
35
|
+
copy_file 'keep', 'domains/.keep'
|
36
|
+
directory 'variables'
|
37
|
+
copy_file 'keep', 'variables/.keep'
|
38
|
+
directory 'test'
|
39
|
+
copy_file 'test/dictionary_test.rb'
|
40
|
+
copy_file 'test/test_helper.rb'
|
41
|
+
unless skip_gemfile
|
42
|
+
puts " run".colorize( :green ) + " bundle install".colorize( :light_cyan )
|
43
|
+
Dir.chdir(@full_path)
|
44
|
+
system "bundle install"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def copy_file(template_file, file_name = '')
|
51
|
+
file_name = template_file if file_name == ''
|
52
|
+
file_path = File.join(@full_path, file_name)
|
53
|
+
template_file_path = File.join(TEMPLATES_DIRECTORY, template_file)
|
54
|
+
puts " create".colorize( :green ) + " #{file_name}"
|
55
|
+
FileUtils.copy(template_file_path, file_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
def directory(directory_name)
|
59
|
+
directory_path = File.join(@full_path, directory_name)
|
60
|
+
puts " create".colorize( :green ) + " #{directory_name}"
|
61
|
+
FileUtils.mkpath(directory_path)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'csv'
|
2
|
+
require 'json'
|
2
3
|
|
4
|
+
require 'spout/models/subject'
|
3
5
|
|
4
6
|
module Spout
|
5
7
|
module Helpers
|
@@ -31,7 +33,6 @@ module Spout
|
|
31
33
|
count = 0
|
32
34
|
puts "Parsing: #{csv_file}"
|
33
35
|
CSV.parse( File.open(csv_file, 'r:iso-8859-1:utf-8'){|f| f.read}, headers: true, header_converters: lambda { |h| h.to_s.downcase } ) do |line|
|
34
|
-
|
35
36
|
row = line.to_hash
|
36
37
|
count += 1
|
37
38
|
puts "Line: #{count}" if (count % 1000 == 0)
|
@@ -42,10 +43,11 @@ module Spout
|
|
42
43
|
unless t.respond_to?(key)
|
43
44
|
t.class.send(:define_method, "#{key}") { instance_variable_get("@#{key}") }
|
44
45
|
t.class.send(:define_method, "#{key}=") { |value| instance_variable_set("@#{key}", value) }
|
45
|
-
all_methods[key] ||= []
|
46
|
-
all_methods[key] << csv_file
|
47
46
|
end
|
48
47
|
|
48
|
+
@all_methods[key] ||= []
|
49
|
+
@all_methods[key] = @all_methods[key] | [csv_file]
|
50
|
+
|
49
51
|
unless value == nil
|
50
52
|
t.send("#{key}=", value)
|
51
53
|
end
|
data/lib/spout/tasks/engine.rake
CHANGED
@@ -9,196 +9,3 @@ Rake::TestTask.new do |t|
|
|
9
9
|
end
|
10
10
|
|
11
11
|
task default: :test
|
12
|
-
|
13
|
-
namespace :spout do
|
14
|
-
require 'csv'
|
15
|
-
require 'fileutils'
|
16
|
-
require 'rubygems'
|
17
|
-
require 'json'
|
18
|
-
require 'erb'
|
19
|
-
|
20
|
-
desc 'Create Data Dictionary from repository'
|
21
|
-
task :create do
|
22
|
-
folder = "dd/#{ENV['VERSION'] || standard_version}"
|
23
|
-
puts " create".colorize( :green ) + " #{folder}"
|
24
|
-
FileUtils.mkpath folder
|
25
|
-
|
26
|
-
expanded_export(folder)
|
27
|
-
end
|
28
|
-
|
29
|
-
desc 'Initialize JSON repository from a CSV file: CSV=datadictionary.csv'
|
30
|
-
task :import do
|
31
|
-
puts ENV['CSV'].inspect
|
32
|
-
if File.exists?(ENV['CSV'].to_s)
|
33
|
-
ENV['TYPE'] == 'domains' ? import_domains : import_variables
|
34
|
-
else
|
35
|
-
puts "\nPlease specify a valid CSV file.".colorize( :red ) + additional_csv_info
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
desc 'Match CSV dataset with JSON repository'
|
40
|
-
task :coverage do
|
41
|
-
require 'spout/commands/coverage'
|
42
|
-
Spout::Commands::Coverage.new(standard_version)
|
43
|
-
end
|
44
|
-
|
45
|
-
desc 'Identify Outliers in CSV dataset'
|
46
|
-
task :outliers do
|
47
|
-
require 'spout/commands/outliers'
|
48
|
-
outliers = Spout::Commands::Outliers.new(standard_version)
|
49
|
-
outliers.run_outliers_report!
|
50
|
-
end
|
51
|
-
|
52
|
-
desc 'Match CSV dataset with JSON repository'
|
53
|
-
task :images do
|
54
|
-
require 'spout/commands/images'
|
55
|
-
types = ENV['types'].to_s.split(',').collect{|t| t.to_s.downcase}
|
56
|
-
variable_ids = ENV['variable_ids'].to_s.split(',').collect{|vid| vid.to_s.downcase}
|
57
|
-
sizes = ENV['sizes'].to_s.split(',').collect{|s| s.to_s.downcase}
|
58
|
-
Spout::Commands::Images.new(types, variable_ids, sizes, standard_version)
|
59
|
-
end
|
60
|
-
|
61
|
-
desc 'Generate JSON charts and tables'
|
62
|
-
task :json do
|
63
|
-
require 'spout/commands/graphs'
|
64
|
-
variables = ENV['variables'].to_s.split(',').collect{|s| s.to_s.downcase}
|
65
|
-
Spout::Commands::Graphs.new(variables, standard_version)
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
def number_with_delimiter(number, delimiter = ",")
|
71
|
-
number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
72
|
-
end
|
73
|
-
|
74
|
-
def standard_version
|
75
|
-
version = File.open('VERSION', &:readline).strip rescue ''
|
76
|
-
version == '' ? '1.0.0' : version
|
77
|
-
end
|
78
|
-
|
79
|
-
def expanded_export(folder)
|
80
|
-
variables_export_file = "variables.csv"
|
81
|
-
puts " export".colorize( :blue ) + " #{folder}/#{variables_export_file}"
|
82
|
-
CSV.open("#{folder}/#{variables_export_file}", "wb") do |csv|
|
83
|
-
keys = %w(id display_name description type units domain labels calculation)
|
84
|
-
csv << ['folder'] + keys
|
85
|
-
Dir.glob("variables/**/*.json").each do |file|
|
86
|
-
if json = JSON.parse(File.read(file)) rescue false
|
87
|
-
variable_folder = variable_folder_path(file)
|
88
|
-
csv << [variable_folder] + keys.collect{|key| json[key].kind_of?(Array) ? json[key].join(';') : json[key].to_s}
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
domains_export_file = "domains.csv"
|
93
|
-
puts " export".colorize( :blue ) + " #{folder}/#{domains_export_file}"
|
94
|
-
CSV.open("#{folder}/#{domains_export_file}", "wb") do |csv|
|
95
|
-
keys = %w(value display_name description)
|
96
|
-
csv << ['folder', 'domain_id'] + keys
|
97
|
-
Dir.glob("domains/**/*.json").each do |file|
|
98
|
-
if json = JSON.parse(File.read(file)) rescue false
|
99
|
-
domain_folder = domain_folder_path(file)
|
100
|
-
domain_name = extract_domain_name(file)
|
101
|
-
json.each do |hash|
|
102
|
-
csv << [domain_folder, domain_name] + keys.collect{|key| hash[key]}
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def extract_domain_name(file)
|
110
|
-
file.gsub(/domains\//, '').split('/').last.to_s.gsub(/.json/, '')
|
111
|
-
end
|
112
|
-
|
113
|
-
def domain_folder_path(file)
|
114
|
-
file.gsub(/domains\//, '').split('/')[0..-2].join('/')
|
115
|
-
end
|
116
|
-
|
117
|
-
def variable_folder_path(file)
|
118
|
-
file.gsub(/variables\//, '').split('/')[0..-2].join('/')
|
119
|
-
end
|
120
|
-
|
121
|
-
def import_variables
|
122
|
-
CSV.parse( File.open(ENV['CSV'].to_s, 'r:iso-8859-1:utf-8'){|f| f.read}, headers: true ) do |line|
|
123
|
-
row = line.to_hash
|
124
|
-
if not row.keys.include?('id')
|
125
|
-
puts "\nMissing column header `".colorize( :red ) + "id".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
126
|
-
exit(1)
|
127
|
-
end
|
128
|
-
next if row['id'] == ''
|
129
|
-
folder = File.join('variables', row.delete('folder').to_s)
|
130
|
-
FileUtils.mkpath folder
|
131
|
-
hash = {}
|
132
|
-
id = row.delete('id')
|
133
|
-
hash['id'] = id
|
134
|
-
hash['display_name'] = row.delete('display_name')
|
135
|
-
hash['description'] = row.delete('description').to_s
|
136
|
-
hash['type'] = row.delete('type')
|
137
|
-
domain = row.delete('domain').to_s
|
138
|
-
hash['domain'] = domain if domain != ''
|
139
|
-
units = row.delete('units').to_s
|
140
|
-
hash['units'] = units if units != ''
|
141
|
-
calculation = row.delete('calculation').to_s
|
142
|
-
hash['calculation'] = calculation if calculation != ''
|
143
|
-
labels = row.delete('labels').to_s.split(';')
|
144
|
-
hash['labels'] = labels if labels.size > 0
|
145
|
-
hash['other'] = row unless row.empty?
|
146
|
-
|
147
|
-
file_name = File.join(folder, id.to_s.downcase + '.json')
|
148
|
-
File.open(file_name, 'w') do |file|
|
149
|
-
file.write(JSON.pretty_generate(hash) + "\n")
|
150
|
-
end
|
151
|
-
puts " create".colorize( :green ) + " #{file_name}"
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def import_domains
|
156
|
-
domains = {}
|
157
|
-
|
158
|
-
CSV.parse( File.open(ENV['CSV'].to_s, 'r:iso-8859-1:utf-8'){|f| f.read}, headers: true ) do |line|
|
159
|
-
row = line.to_hash
|
160
|
-
if not row.keys.include?('domain_id')
|
161
|
-
puts "\nMissing column header `".colorize( :red ) + "domain_id".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
162
|
-
exit(1)
|
163
|
-
end
|
164
|
-
if not row.keys.include?('value')
|
165
|
-
puts "\nMissing column header `".colorize( :red ) + "value".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
166
|
-
exit(1)
|
167
|
-
end
|
168
|
-
if not row.keys.include?('display_name')
|
169
|
-
puts "\nMissing column header `".colorize( :red ) + "display_name".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
170
|
-
exit(1)
|
171
|
-
end
|
172
|
-
|
173
|
-
next if row['domain_id'].to_s == '' or row['value'].to_s == '' or row['display_name'].to_s == ''
|
174
|
-
folder = File.join('domains', row['folder'].to_s).gsub(/[^a-zA-Z0-9_\/\.-]/, '_')
|
175
|
-
domain_name = row['domain_id'].to_s.gsub(/[^a-zA-Z0-9_\/\.-]/, '_')
|
176
|
-
domains[domain_name] ||= {}
|
177
|
-
domains[domain_name]["folder"] = folder
|
178
|
-
domains[domain_name]["options"] ||= []
|
179
|
-
|
180
|
-
hash = {}
|
181
|
-
hash['value'] = row.delete('value').to_s
|
182
|
-
hash['display_name'] = row.delete('display_name').to_s
|
183
|
-
hash['description'] = row.delete('description').to_s
|
184
|
-
|
185
|
-
domains[domain_name]["options"] << hash
|
186
|
-
end
|
187
|
-
|
188
|
-
domains.each do |domain_name, domain_hash|
|
189
|
-
folder = domain_hash["folder"]
|
190
|
-
FileUtils.mkpath folder
|
191
|
-
|
192
|
-
file_name = File.join(folder, domain_name.to_s.downcase + '.json')
|
193
|
-
|
194
|
-
File.open(file_name, 'w') do |file|
|
195
|
-
file.write(JSON.pretty_generate(domain_hash["options"]) + "\n")
|
196
|
-
end
|
197
|
-
puts " create".colorize( :green ) + " #{file_name}"
|
198
|
-
end
|
199
|
-
|
200
|
-
end
|
201
|
-
|
202
|
-
def additional_csv_info
|
203
|
-
"\n\nFor additional information on specifying CSV column headers before import see:\n\n " + "https://github.com/sleepepi/spout#generate-a-new-repository-from-an-existing-csv-file".colorize( :light_cyan ) + "\n\n"
|
204
|
-
end
|
@@ -1 +1 @@
|
|
1
|
-
ruby-2.1.
|
1
|
+
ruby-2.1.2
|
data/lib/spout/version.rb
CHANGED
data/lib/spout.rb
CHANGED
@@ -1,8 +1,115 @@
|
|
1
1
|
require "spout/version"
|
2
|
-
require "spout/actions"
|
3
2
|
require "spout/application"
|
4
3
|
require 'spout/tasks'
|
5
4
|
|
5
|
+
Spout::COMMANDS = {
|
6
|
+
'n' => :new_project,
|
7
|
+
'v' => :version,
|
8
|
+
't' => :test,
|
9
|
+
'i' => :importer,
|
10
|
+
'e' => :exporter,
|
11
|
+
'c' => :coverage_report,
|
12
|
+
'p' => :generate_images,
|
13
|
+
'g' => :generate_charts_and_tables,
|
14
|
+
'o' => :outliers_report
|
15
|
+
}
|
16
|
+
|
6
17
|
module Spout
|
18
|
+
def self.launch(argv)
|
19
|
+
self.send((Spout::COMMANDS[argv.first.to_s.scan(/\w/).first] || :help), argv)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.new_project(argv)
|
23
|
+
require 'spout/commands/project_generator'
|
24
|
+
Spout::Commands::ProjectGenerator.new(argv)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.coverage_report(argv)
|
28
|
+
require 'spout/commands/coverage'
|
29
|
+
Spout::Commands::Coverage.new(standard_version, argv)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.exporter(argv)
|
33
|
+
require 'spout/commands/exporter'
|
34
|
+
Spout::Commands::Exporter.new(standard_version, argv)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.generate_charts_and_tables(argv)
|
38
|
+
argv = argv.last(argv.size - 1)
|
39
|
+
require 'spout/commands/graphs'
|
40
|
+
variables = argv.collect{|s| s.to_s.downcase}
|
41
|
+
Spout::Commands::Graphs.new(variables, standard_version)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.generate_images(argv)
|
45
|
+
argv = argv.last(argv.size - 1)
|
46
|
+
require 'spout/commands/images'
|
47
|
+
types = flag_values(argv, 'type')
|
48
|
+
variable_ids = flag_values(argv, 'id')
|
49
|
+
sizes = flag_values(argv, 'size')
|
50
|
+
Spout::Commands::Images.new(types, variable_ids, sizes, standard_version, argv)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.help(argv)
|
54
|
+
puts <<-EOT
|
55
|
+
|
56
|
+
Usage: spout COMMAND [ARGS]
|
57
|
+
|
58
|
+
The most common spout commands are:
|
59
|
+
[n]ew Create a new Spout dictionary.
|
60
|
+
`spout new <project_name>` creates a new
|
61
|
+
data dictionary in `./<project_name>`
|
62
|
+
[t]est Run tests and show failing tests
|
63
|
+
[t] --verbose Run the tests and show passing and failing
|
64
|
+
tests
|
65
|
+
[i]mport Import a CSV file into the JSON dictionary
|
66
|
+
[e]xport [1.0.0] Export the JSON dictionary to CSV format
|
67
|
+
[c]overage Coverage report, requires dataset CSVs
|
68
|
+
in `<project_name>/csvs/<version>`
|
69
|
+
[o]utliers Outlier report, requires dataset CSVs
|
70
|
+
in `<project_name>/csvs/<version>`
|
71
|
+
[p]ngs Generates images for each variable in a
|
72
|
+
dataset and places them
|
73
|
+
in `<project_name>/images/<version>/`
|
74
|
+
[g]raphs Generates JSON graphs for each variable
|
75
|
+
in a dataset and places them
|
76
|
+
in `<project_name>/graphs/<version>/`
|
77
|
+
[v]ersion Returns the version of Spout
|
78
|
+
|
79
|
+
Commands can be referenced by the first letter:
|
80
|
+
Ex: `spout t`, for test
|
81
|
+
|
82
|
+
EOT
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.importer(argv)
|
86
|
+
require 'spout/commands/importer'
|
87
|
+
Spout::Commands::Importer.new(argv)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.outliers_report(argv)
|
91
|
+
require 'spout/commands/outliers'
|
92
|
+
Spout::Commands::Outliers.new(standard_version, argv)
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.test(argv)
|
96
|
+
hide_passing_tests = (argv.delete('--verbose') == nil)
|
97
|
+
system "bundle exec rake#{' HIDE_PASSING_TESTS=true' if hide_passing_tests}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.version(argv)
|
101
|
+
puts "Spout #{Spout::VERSION::STRING}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.standard_version
|
105
|
+
version = File.open('VERSION', &:readline).strip rescue ''
|
106
|
+
version == '' ? '1.0.0' : version
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def self.flag_values(flags, param)
|
112
|
+
flags.select{|f| f[0..((param.size + 3) - 1)] == "--#{param}-" and f.length > param.size + 3}.collect{|f| f[(param.size + 3)..-1]}
|
113
|
+
end
|
7
114
|
|
8
115
|
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.8.0.
|
4
|
+
version: 0.8.0.beta11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Remo Mueller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -98,12 +98,16 @@ files:
|
|
98
98
|
- lib/spout/actions.rb
|
99
99
|
- lib/spout/application.rb
|
100
100
|
- lib/spout/commands/coverage.rb
|
101
|
+
- lib/spout/commands/exporter.rb
|
101
102
|
- lib/spout/commands/graphs.rb
|
102
103
|
- lib/spout/commands/images.rb
|
104
|
+
- lib/spout/commands/importer.rb
|
103
105
|
- lib/spout/commands/outliers.rb
|
106
|
+
- lib/spout/commands/project_generator.rb
|
104
107
|
- lib/spout/helpers/array_statistics.rb
|
105
108
|
- lib/spout/helpers/chart_types.rb
|
106
109
|
- lib/spout/helpers/json_loader.rb
|
110
|
+
- lib/spout/helpers/number_helper.rb
|
107
111
|
- lib/spout/helpers/subject_loader.rb
|
108
112
|
- lib/spout/helpers/table_formatting.rb
|
109
113
|
- lib/spout/hidden_reporter.rb
|
@@ -122,6 +126,7 @@ files:
|
|
122
126
|
- lib/spout/templates/gitignore
|
123
127
|
- lib/spout/templates/keep
|
124
128
|
- lib/spout/templates/ruby-version
|
129
|
+
- lib/spout/templates/spout.yml
|
125
130
|
- lib/spout/templates/test/dictionary_test.rb
|
126
131
|
- lib/spout/templates/test/test_helper.rb
|
127
132
|
- lib/spout/templates/travis.yml
|