spout 0.12.0.beta1 → 0.12.0.beta2
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 +10 -2
- data/lib/spout/commands/exporter.rb +24 -14
- data/lib/spout/commands/importer.rb +7 -11
- data/lib/spout/commands/project_generator.rb +2 -5
- data/lib/spout/helpers/subject_loader.rb +1 -1
- data/lib/spout/models/graphables/numeric_vs_choices.rb +2 -6
- data/lib/spout/models/variable.rb +2 -3
- data/lib/spout/templates/ruby-version +1 -1
- data/lib/spout/templates/travis.yml +1 -1
- data/lib/spout/version.rb +1 -1
- data/spout.gemspec +6 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8d706e8d746c0ae4c64014bbcf38f47d51e388a
|
4
|
+
data.tar.gz: b2a49b2f165531f6a96ad677cb6a1d9f4045a283
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b4fa147fc6914b594afd25acc72f5de98c929dbc2631489fd8267c1a3ff3e432a16292a28ce2f5565d011879263a3cfa265b004c1af9deebcf6525d6fa5411d
|
7
|
+
data.tar.gz: 9f3dfd7ee30b971b2d3152c486dac7bb87b9d3811a6d7fd30267bfdf9285ec4330cfece6956e217dffb64827fa7f902f9f43aec3aed4fd4ea25622b670965017
|
data/CHANGELOG.md
CHANGED
@@ -3,11 +3,19 @@
|
|
3
3
|
### Enhancements
|
4
4
|
- **General Changes**
|
5
5
|
- Spout now provides a warning and skips columns in CSVs with blank headers
|
6
|
+
- **Exporter Changes**
|
7
|
+
- The export command now exports the variable forms attribute
|
8
|
+
- **Importer Changes**
|
9
|
+
- The import command now reads in the `commonly_used` column
|
10
|
+
- The import command now imports the variable forms attribute
|
6
11
|
- **Gem Changes**
|
7
|
-
- Updated to Ruby 2.4.
|
12
|
+
- Updated to Ruby 2.4.1
|
8
13
|
- Updated to bundler 1.13
|
9
14
|
- Updated to colorize 0.8.1
|
10
|
-
- Updated to simplecov 0.
|
15
|
+
- Updated to simplecov 0.14.1
|
16
|
+
|
17
|
+
### Refactoring
|
18
|
+
- General code cleanup based on Rubocop recommendations
|
11
19
|
|
12
20
|
## 0.11.1 (February 4, 2016)
|
13
21
|
|
@@ -9,9 +9,10 @@ require 'spout/helpers/config_reader'
|
|
9
9
|
|
10
10
|
module Spout
|
11
11
|
module Commands
|
12
|
+
# Exports the JSON data dictionary to a CSV format.
|
12
13
|
class Exporter
|
13
14
|
def initialize(standard_version, argv)
|
14
|
-
@quiet =
|
15
|
+
@quiet = !argv.delete('--quiet').nil?
|
15
16
|
@standard_version = standard_version
|
16
17
|
@config = Spout::Helpers::ConfigReader.new
|
17
18
|
expanded_export!
|
@@ -21,33 +22,42 @@ module Spout
|
|
21
22
|
|
22
23
|
def expanded_export!
|
23
24
|
folder = "dd/#{@standard_version}"
|
24
|
-
puts
|
25
|
+
puts ' create'.colorize(:green) + " #{folder}" unless @quiet
|
25
26
|
FileUtils.mkpath folder
|
26
|
-
|
27
|
-
|
27
|
+
generic_export(
|
28
|
+
folder,
|
29
|
+
'variables',
|
30
|
+
%w(
|
31
|
+
id display_name description type units domain labels calculation
|
32
|
+
commonly_used forms
|
33
|
+
)
|
34
|
+
)
|
28
35
|
generic_export(folder, 'domains', %w(value display_name description), true)
|
29
36
|
generic_export(folder, 'forms', %w(id display_name code_book))
|
30
37
|
end
|
31
38
|
|
32
39
|
def generic_export(folder, type, keys, include_domain_name = false)
|
33
40
|
export_file = export_file_name(type)
|
34
|
-
puts
|
35
|
-
CSV.open("#{folder}/#{export_file}",
|
36
|
-
if include_domain_name
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
+
puts ' export'.colorize(:blue) + " #{folder}/#{export_file}" unless @quiet
|
42
|
+
CSV.open("#{folder}/#{export_file}", 'wb') do |csv|
|
43
|
+
csv << if include_domain_name
|
44
|
+
%w(folder domain_id) + keys
|
45
|
+
else
|
46
|
+
%w(folder) + keys
|
47
|
+
end
|
41
48
|
Dir.glob("#{type}/**/*.json").sort.each do |file|
|
42
|
-
|
49
|
+
json = JSON.parse(File.read(file)) rescue false
|
50
|
+
if json
|
43
51
|
relative_folder = generic_folder_path(file, type)
|
44
52
|
if include_domain_name
|
45
53
|
domain_name = extract_domain_name(file)
|
46
54
|
json.each do |hash|
|
47
|
-
csv << [relative_folder, domain_name] + keys.collect{|key| hash[key]}
|
55
|
+
csv << [relative_folder, domain_name] + keys.collect { |key| hash[key] }
|
48
56
|
end
|
49
57
|
else
|
50
|
-
csv << [relative_folder] + keys.collect
|
58
|
+
csv << [relative_folder] + keys.collect do |key|
|
59
|
+
json[key].is_a?(Array) ? json[key].join(';') : json[key].to_s
|
60
|
+
end
|
51
61
|
end
|
52
62
|
end
|
53
63
|
end
|
@@ -9,21 +9,17 @@ module Spout
|
|
9
9
|
module Commands
|
10
10
|
class Importer
|
11
11
|
def initialize(argv)
|
12
|
-
use_domains =
|
13
|
-
|
12
|
+
use_domains = !argv.delete('--domains').nil?
|
14
13
|
@csv_file = argv[1].to_s
|
15
|
-
|
16
14
|
unless File.exist?(@csv_file)
|
17
15
|
puts csv_usage
|
18
16
|
return self
|
19
17
|
end
|
20
|
-
|
21
18
|
if use_domains
|
22
19
|
import_domains
|
23
20
|
else
|
24
21
|
import_variables
|
25
22
|
end
|
26
|
-
|
27
23
|
end
|
28
24
|
|
29
25
|
def csv_usage
|
@@ -38,7 +34,7 @@ EOT
|
|
38
34
|
end
|
39
35
|
|
40
36
|
def import_variables
|
41
|
-
CSV.parse(
|
37
|
+
CSV.parse(File.open(@csv_file, 'r:iso-8859-1:utf-8', &:read), headers: true) do |line|
|
42
38
|
row = line.to_hash
|
43
39
|
if not row.keys.include?('id')
|
44
40
|
puts "\nMissing column header `".colorize( :red ) + "id".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
@@ -60,7 +56,10 @@ EOT
|
|
60
56
|
calculation = row.delete('calculation').to_s
|
61
57
|
hash['calculation'] = calculation if calculation != ''
|
62
58
|
labels = row.delete('labels').to_s.split(';')
|
63
|
-
hash['labels'] = labels
|
59
|
+
hash['labels'] = labels unless labels.empty?
|
60
|
+
hash['commonly_used'] = true if row.delete('commonly_used').to_s.casecmp('true').zero?
|
61
|
+
forms = row.delete('forms').to_s.split(';')
|
62
|
+
hash['forms'] = forms unless forms.empty?
|
64
63
|
hash['other'] = row unless row.empty?
|
65
64
|
|
66
65
|
file_name = File.join(folder, id + '.json')
|
@@ -74,7 +73,7 @@ EOT
|
|
74
73
|
def import_domains
|
75
74
|
domains = {}
|
76
75
|
|
77
|
-
CSV.parse(
|
76
|
+
CSV.parse(File.open(@csv_file, 'r:iso-8859-1:utf-8', &:read), headers: true) do |line|
|
78
77
|
row = line.to_hash
|
79
78
|
if not row.keys.include?('domain_id')
|
80
79
|
puts "\nMissing column header `".colorize( :red ) + "domain_id".colorize( :light_cyan ) + "` in data dictionary.".colorize( :red ) + additional_csv_info
|
@@ -116,7 +115,6 @@ EOT
|
|
116
115
|
end
|
117
116
|
puts " create".colorize( :green ) + " #{file_name}"
|
118
117
|
end
|
119
|
-
|
120
118
|
end
|
121
119
|
|
122
120
|
# Converts ALL-CAPS display names to title case
|
@@ -135,8 +133,6 @@ EOT
|
|
135
133
|
def additional_csv_info
|
136
134
|
"\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"
|
137
135
|
end
|
138
|
-
|
139
|
-
|
140
136
|
end
|
141
137
|
end
|
142
138
|
end
|
@@ -13,7 +13,7 @@ module Spout
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def generate_folder_structure!(argv)
|
16
|
-
skip_gemfile =
|
16
|
+
skip_gemfile = !argv.delete('--skip-gemfile').nil?
|
17
17
|
@full_path = File.join(argv[1].to_s.strip)
|
18
18
|
usage = <<-EOT
|
19
19
|
|
@@ -22,14 +22,11 @@ Usage: spout new FOLDER
|
|
22
22
|
The FOLDER must be empty or new.
|
23
23
|
|
24
24
|
EOT
|
25
|
-
|
26
|
-
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 )
|
25
|
+
if @full_path == '' || (Dir.exist?(@full_path) && (Dir.entries(@full_path) & ['.gitignore', '.ruby-version', '.travis.yml', 'Gemfile', 'Rakefile', 'domains', 'variables', 'test']).size > 0)
|
27
26
|
puts usage
|
28
27
|
exit(0)
|
29
28
|
end
|
30
|
-
|
31
29
|
FileUtils.mkpath(@full_path)
|
32
|
-
|
33
30
|
copy_file 'gitignore', '.gitignore'
|
34
31
|
copy_file 'ruby-version', '.ruby-version'
|
35
32
|
copy_file 'travis.yml', '.travis.yml'
|
@@ -59,7 +59,7 @@ module Spout
|
|
59
59
|
puts " #{current_folder}".colorize(:white) if current_folder.to_s != '' && current_folder != last_folder
|
60
60
|
print " #{current_file}"
|
61
61
|
last_folder = current_folder
|
62
|
-
CSV.parse(File.open(csv_file, 'r:iso-8859-1:utf-8'
|
62
|
+
CSV.parse(File.open(csv_file, 'r:iso-8859-1:utf-8', &:read), headers: true, header_converters: lambda { |h| h.to_s.downcase }) do |line|
|
63
63
|
row = line.to_hash
|
64
64
|
count += 1
|
65
65
|
print "\r #{current_file} " + "##{count}".colorize(:yellow) if (count % 10 == 0)
|
@@ -6,7 +6,6 @@ module Spout
|
|
6
6
|
module Models
|
7
7
|
module Graphables
|
8
8
|
class NumericVsChoices < Spout::Models::Graphables::Default
|
9
|
-
|
10
9
|
def categories
|
11
10
|
categories_result = []
|
12
11
|
@stratification_variable.domain.options.each do |option|
|
@@ -28,13 +27,11 @@ module Spout
|
|
28
27
|
@stratification_variable.domain.options.each do |option|
|
29
28
|
visit_subjects = @subjects.select{ |s| s._visit == option.value and s.send(@variable.id) != nil } rescue visit_subjects = []
|
30
29
|
if visit_subjects.count > 0
|
31
|
-
|
32
|
-
|
33
|
-
values = visit_subjects.select{|s| s.send(@chart_variable.id) == option.value }.collect(&@variable.id.to_sym)
|
30
|
+
filtered_domain_options(@chart_variable).each_with_index do |filtered_option, index|
|
31
|
+
values = visit_subjects.select{|s| s.send(@chart_variable.id) == filtered_option.value }.collect(&@variable.id.to_sym)
|
34
32
|
data[index] ||= []
|
35
33
|
data[index] << (values.mean.round(2) rescue 0.0)
|
36
34
|
end
|
37
|
-
|
38
35
|
end
|
39
36
|
end
|
40
37
|
|
@@ -42,7 +39,6 @@ module Spout
|
|
42
39
|
{ name: option.display_name, data: data[index] }
|
43
40
|
end
|
44
41
|
end
|
45
|
-
|
46
42
|
end
|
47
43
|
end
|
48
44
|
end
|
@@ -23,6 +23,7 @@ module Spout
|
|
23
23
|
@id = file_name.to_s.gsub(%r{^(.*)/|\.json$}, '').downcase
|
24
24
|
@folder = file_name.to_s.gsub(%r{^#{dictionary_root}/variables/|#{@id}\.json$}, '')
|
25
25
|
@form_names = []
|
26
|
+
@domain_name = nil
|
26
27
|
|
27
28
|
json = begin
|
28
29
|
JSON.parse(File.read(file_name))
|
@@ -31,7 +32,7 @@ module Spout
|
|
31
32
|
nil
|
32
33
|
end
|
33
34
|
|
34
|
-
if json.is_a?
|
35
|
+
if json.is_a?(Hash)
|
35
36
|
%w(display_name description type units commonly_used calculation).each do |method|
|
36
37
|
instance_variable_set("@#{method}", json[method])
|
37
38
|
end
|
@@ -45,9 +46,7 @@ module Spout
|
|
45
46
|
elsif json
|
46
47
|
@errors << "Variable must be a valid hash in the following format: {\n\"id\": \"VARIABLE_ID\",\n \"display_name\": \"VARIABLE DISPLAY NAME\",\n \"description\": \"VARIABLE DESCRIPTION\"\n}"
|
47
48
|
end
|
48
|
-
|
49
49
|
@errors = (@errors + [error]).compact
|
50
|
-
|
51
50
|
@domain = Spout::Models::Domain.find_by_id(@domain_name)
|
52
51
|
@forms = @form_names.collect { |form_name| Spout::Models::Form.find_by_id(form_name) }.compact
|
53
52
|
end
|
@@ -1 +1 @@
|
|
1
|
-
ruby-2.4.
|
1
|
+
ruby-2.4.1
|
data/lib/spout/version.rb
CHANGED
data/spout.gemspec
CHANGED
@@ -18,7 +18,12 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.authors = ['Remo Mueller']
|
19
19
|
spec.email = ['remosm@gmail.com']
|
20
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.
|
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.'
|
22
27
|
spec.homepage = 'https://github.com/sleepepi/spout'
|
23
28
|
spec.license = 'MIT'
|
24
29
|
|
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.12.0.
|
4
|
+
version: 0.12.0.beta2
|
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-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -206,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
206
|
version: 1.3.1
|
207
207
|
requirements: []
|
208
208
|
rubyforge_project:
|
209
|
-
rubygems_version: 2.6.
|
209
|
+
rubygems_version: 2.6.11
|
210
210
|
signing_key:
|
211
211
|
specification_version: 4
|
212
212
|
summary: Turn your CSV data dictionary into a JSON repository. Collaborate with others
|