heart_seed 0.0.1.beta1 → 0.0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 00e700cd31219d035de3f79465a7100761273f02
4
- data.tar.gz: ae3bb179f7bd42d1f0529dd495bdc8b96fbbca7a
3
+ metadata.gz: b6cdf153eeacd0a2bb25e04f0b086d6c3d5b47f5
4
+ data.tar.gz: d7c2518396273ff9de9771c6985b6f3590fedd97
5
5
  SHA512:
6
- metadata.gz: 43c0dbba243860dfc16ace5d25f6ea84ed4518bda85bd82365fdf16081f48297c4ecb411897e8414616368e323575ac33c626c6dbc886f6db2e980a943b966af
7
- data.tar.gz: 8e1d46e47673368a8840d19aff78de1fd1410a251825c33bec1b64b0fb9ab1a24e3c8ab9d735c977e39539ccd56bbeb73e18a10cd20fef2745652c67d16fe877
6
+ metadata.gz: 6634e532e3fbef27ceb93dce2d138428df7ed6992fab00f5164b8b8a4918888fa396a7d2998da703533bc2f9613a4ac31f0496c9ae07dfd5322e9c2c666a8e90
7
+ data.tar.gz: d99648ac07a0816d9c11c9c7e5c9dfda693010b63b6d2a224a7ea90655a63cff751ceeaa65290bf19966712cbce72a7ab5f7f9ada57c7944e3e160bccff96e48
data/README.md CHANGED
@@ -1,12 +1,15 @@
1
1
  # [WIP] HeartSeed
2
2
 
3
- seed util (excel -> yaml -> db)
3
+ seed util (excel -> yaml -> db)
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/heart_seed.svg)](http://badge.fury.io/rb/heart_seed)
5
6
  [![Build Status](https://travis-ci.org/sue445/heart_seed.svg)](https://travis-ci.org/sue445/heart_seed)
6
7
  [![Code Climate](https://codeclimate.com/github/sue445/heart_seed.png)](https://codeclimate.com/github/sue445/heart_seed)
7
8
  [![Coverage Status](https://img.shields.io/coveralls/sue445/heart_seed.svg)](https://coveralls.io/r/sue445/heart_seed?branch=master)
8
9
  [![Dependency Status](https://gemnasium.com/sue445/heart_seed.svg)](https://gemnasium.com/sue445/heart_seed)
9
10
 
11
+ [![Stories in Ready](https://badge.waffle.io/sue445/heart_seed.png?label=ready&title=Ready)](https://waffle.io/sue445/heart_seed)
12
+
10
13
  ## Installation
11
14
 
12
15
  Add this line to your application's Gemfile:
@@ -27,13 +30,105 @@ Or install it yourself as:
27
30
  * create `config/heart_seed.yml`, `db/xls`, `db/seeds`
28
31
  * append to `db/seeds.rb`
29
32
  2. Create xls
33
+ * sheet name (xls,xlsx) = table name (DB)
30
34
  * example https://github.com/sue445/heart_seed/tree/master/spec/dummy/db/xls
31
35
  3. `bundle exec rake heart_seed:xls`
32
36
  * Generate yml to `db/seeds`
33
- * If you want to specify files: `FILES=comments_and_likes.xls SHEETS=comments,likes bundle exec rake heart_seed:xls`
34
- 4. `bundle exec rake db:seed`
37
+ * If you want to specify files: `FILES=comments_and_likes.xls SHEETS=comments,likes bundle exec rake heart_seed:xls`
38
+ 4. `bundle exec rake db:seed` or `bundle exec rake heart_seed:db:seed`
35
39
  * Import yml to db
36
- * If you want to specify tables: `TABLES=articles,comments bundle exec rake db:seed`
40
+ * Exists `TABLES`, `CATALOGS` options
41
+
42
+ examples
43
+
44
+ ```sh
45
+ TABLES=articles,comments bundle exec rake db:seed
46
+ CATALOGS=article,user bundle exec rake db:seed
47
+ ```
48
+
49
+ ### other Rails
50
+
51
+ append this to `Rakefile`
52
+
53
+ ```ruby
54
+ require 'heart_seed/tasks'
55
+ ```
56
+
57
+ ### Snippets
58
+ #### config/heart_seed.yml
59
+ ```yml
60
+ seed_dir: db/seeds
61
+ xls_dir: db/xls
62
+ catalogs:
63
+ # user:
64
+ # - users
65
+ # - user_profiles
66
+ ```
67
+
68
+ #### db/seeds.rb
69
+ ```ruby
70
+ # Appended by `rake heart_seed:init`
71
+ HeartSeed::DbSeed.import_all
72
+ ```
73
+
74
+ ## Specification
75
+ ### Supported xls/xlsx format
76
+
77
+ Example sheet
78
+
79
+ id | title | description | created_at | | this is dummy
80
+ --- | ------ | ------------ | -------------- | --- | --------------
81
+ 1 | title1 | description1 | 2014/6/1 12:10 | | foo
82
+ 2 | title2 | description2 | 2014/6/2 12:10 | | baz
83
+
84
+ * Sheet name is mapped table name
85
+ * If sheet name is not found in database, this is ignored
86
+ * 1st row : table column names
87
+ * If the spaces are included in the middle, right columns are ignored
88
+ * 2nd row ~ : records
89
+ * [ActiveSupport::TimeWithZone](http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html) is used for timezone
90
+
91
+ ### Yaml format
92
+
93
+ example
94
+
95
+ ```yaml
96
+ ---
97
+ articles_1:
98
+ id: 1
99
+ title: title1
100
+ description: description1
101
+ created_at: '2014-06-01 12:10:00 +0900'
102
+ articles_2:
103
+ id: 2
104
+ title: title2
105
+ description: description2
106
+ created_at: '2014-06-02 12:10:00 +0900'
107
+ ```
108
+
109
+ * same as [ActiveRecord::FixtureSet](http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html) format
110
+
111
+ ### Catalog
112
+ Catalog is table groups defined in heart_seed.yml
113
+
114
+ example
115
+
116
+ ```yml
117
+ catalogs:
118
+ user:
119
+ - users
120
+ - user_profiles
121
+ ```
122
+
123
+ `user` catalog = `users`, `user_profiles` tables
124
+
125
+
126
+ You can specify the catalogs at `db:seed` task
127
+
128
+ ```sh
129
+ CATALOGS=user bundle exec rake db:seed
130
+ # same to) TABLES=users,user_profiles bundle exec rake db:seed
131
+ ```
37
132
 
38
133
  ## Contributing
39
134
 
@@ -87,7 +87,7 @@ module HeartSeed
87
87
  #
88
88
  # @return [ Hash{ String => Hash{ String => Object } } ]
89
89
  def self.read_sheet(sheet, row_prefix)
90
- header_keys = sheet.row(HEADER_ROW)
90
+ header_keys = select_left_of_blank(sheet.row(HEADER_ROW))
91
91
  fixtures = {}
92
92
 
93
93
  (HEADER_ROW + 1 .. sheet.last_row).each do |row_num|
@@ -95,11 +95,11 @@ module HeartSeed
95
95
  header_keys.each_with_index do |key, col_index|
96
96
  value = sheet.cell(row_num, col_index + 1)
97
97
 
98
- case sheet.celltype(row_num, col_index + 1)
99
- when :float
98
+ case value
99
+ when Float
100
100
  # ex) 1.0 -> 1
101
101
  value = value.to_i if value == value.to_i
102
- when :date, :time, :datetime
102
+ when DateTime
103
103
  # value is DateTime and localtime, but not included TimeZone(UTC)
104
104
  time = Time.zone.at(value.to_i - Time.zone.utc_offset)
105
105
  value = time.to_s
@@ -116,5 +116,15 @@ module HeartSeed
116
116
 
117
117
  fixtures
118
118
  end
119
+
120
+ def self.select_left_of_blank(array)
121
+ response = []
122
+ array.each do |element|
123
+ break unless element
124
+ break if element.respond_to?(:blank?) && element.blank?
125
+ response << element
126
+ end
127
+ response
128
+ end
119
129
  end
120
130
  end
@@ -21,30 +21,49 @@ module HeartSeed
21
21
  #
22
22
  # @param seed_dir [String]
23
23
  # @param tables [Array<String>,String] table names array or comma separated table names. if empty, import all seed yaml. if not empty, import only these tables.
24
- def self.import_all(seed_dir: HeartSeed::Helper.seed_dir, tables: [])
25
- target_tables = parse_arg_tables(tables)
24
+ def self.import_all(seed_dir: HeartSeed::Helper.seed_dir, tables: ENV["TABLES"], catalogs: ENV["CATALOGS"])
25
+ # use tables in catalogs
26
+ target_tables = parse_arg_catalogs(catalogs)
27
+ if target_tables.empty?
28
+ # use tables
29
+ target_tables = parse_string_or_array_arg(tables)
30
+ end
26
31
 
32
+ ActiveRecord::Migration.verbose = true
27
33
  Dir.glob(File.join(seed_dir, "*.yml")) do |file|
28
34
  table_name = File.basename(file, '.*')
29
35
  next unless target_table?(table_name, target_tables)
30
36
 
31
- begin
32
- model_class = table_name.classify.constantize
33
- bulk_insert(source_file: file, model_class: model_class)
34
- puts "[INFO] #{file} -> #{table_name}"
35
- rescue => e
36
- puts "[ERROR] #{e.message}"
37
+ ActiveRecord::Migration.say_with_time("#{file} -> #{table_name}") do
38
+ begin
39
+ model_class = table_name.classify.constantize
40
+ bulk_insert(source_file: file, model_class: model_class)
41
+ ActiveRecord::Migration.say("[INFO] success", true)
42
+ rescue => e
43
+ ActiveRecord::Migration.say("[ERROR] #{e.message}", true)
44
+ end
37
45
  end
38
46
  end
39
47
  end
40
48
 
41
- def self.parse_arg_tables(tables)
49
+ def self.parse_string_or_array_arg(tables)
42
50
  return [] unless tables
43
51
  return tables if tables.class == Array
44
52
 
45
53
  tables.class == String ? tables.split(",") : []
46
54
  end
47
55
 
56
+ def self.parse_arg_catalogs(catalogs)
57
+ array_catalogs = parse_string_or_array_arg(catalogs)
58
+ return [] if array_catalogs.empty?
59
+
60
+ tables = []
61
+ array_catalogs.each do |catalog|
62
+ tables += HeartSeed::Helper.catalog_tables(catalog)
63
+ end
64
+ tables.compact
65
+ end
66
+
48
67
  private
49
68
  def self.target_table?(source_table, target_tables)
50
69
  return true if target_tables.empty?
@@ -11,6 +11,7 @@ module HeartSeed
11
11
  {
12
12
  "seed_dir" => "db/seeds",
13
13
  "xls_dir" => "db/xls",
14
+ "catalogs" => {},
14
15
  }
15
16
  end
16
17
  end
@@ -45,5 +46,16 @@ module HeartSeed
45
46
  def self.root_dir=(dir)
46
47
  @root_dir = Pathname.new(dir)
47
48
  end
49
+
50
+ # @return [Hash{String => Array<String>}] key: catalog name, value: table names
51
+ def self.catalogs
52
+ config["catalogs"] || {}
53
+ end
54
+
55
+ # @param catalog_name [String]
56
+ # @return [Array<String>] table names in a specify catalog
57
+ def self.catalog_tables(catalog_name)
58
+ self.catalogs[catalog_name] || []
59
+ end
48
60
  end
49
61
  end
@@ -1,7 +1,7 @@
1
1
  module HeartSeed
2
2
  class Railtie < ::Rails::Railtie
3
3
  rake_tasks do
4
- load "heart_seed/tasks/heart_seed.rake"
4
+ require "heart_seed/tasks"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1 @@
1
+ load "heart_seed/tasks/heart_seed.rake"
@@ -1,10 +1,10 @@
1
1
  namespace :heart_seed do
2
2
  desc "create dir and file"
3
- task :init => ["config/heart_seed.yml", "db/xls", "db/seeds"] do
3
+ task :init => ["config/heart_seed.yml", "db/xls/.gitkeep", "db/seeds/.gitkeep"] do
4
4
  template = <<RUBY
5
5
 
6
6
  # Appended by `rake heart_seed:init`
7
- HeartSeed::DbSeed.import_all(tables: ENV["TABLES"])
7
+ HeartSeed::DbSeed.import_all
8
8
 
9
9
  RUBY
10
10
 
@@ -15,43 +15,64 @@ RUBY
15
15
  template = <<YAML
16
16
  seed_dir: db/seeds
17
17
  xls_dir: db/xls
18
+ catalogs:
19
+ # user:
20
+ # - users
21
+ # - user_profiles
18
22
  YAML
19
23
 
20
24
  create_file("config/heart_seed.yml", template)
21
25
  end
22
26
 
27
+ file "db/xls/.gitkeep" => "db/xls" do
28
+ create_file("db/xls/.gitkeep")
29
+ end
30
+
31
+ file "db/seeds/.gitkeep" => "db/seeds" do
32
+ create_file("db/seeds/.gitkeep")
33
+ end
34
+
23
35
  directory "config"
24
36
  directory "db/xls"
25
37
  directory "db/seeds"
26
38
 
27
- desc "create seed files by xls directory"
39
+ desc "create seed files by xls directory (options: FILES=table1.xls,table2.xlsx SHEETS=sheet1,sheet2)"
28
40
  task :xls => :environment do
41
+ ActiveRecord::Migration.verbose = true
29
42
  Dir.glob(File.join(HeartSeed::Helper.xls_dir, "*.{xls,xlsx}")) do |file|
30
43
  next if File.basename(file) =~ /^~/
31
44
 
32
45
  next unless target_file?(file)
33
46
 
34
- puts "Source File: #{file}"
35
- sheets = HeartSeed::Converter.table_sheets(file)
36
- sheets.each do |sheet|
37
- unless ActiveRecord::Base.connection.table_exists?(sheet)
38
- puts " [#{sheet}] Table is not found"
39
- next
40
- end
41
-
42
- next unless target_sheet?(sheet)
43
-
44
- dist_file = File.join(HeartSeed::Helper.seed_dir, "#{sheet}.yml")
45
- fixtures = HeartSeed::Converter.convert_to_yml(source_file: file, source_sheet: sheet, dist_file: dist_file)
46
- if fixtures
47
- puts " [#{sheet}] Create seed: #{dist_file}"
48
- else
49
- puts " [#{sheet}] Sheet is empty"
47
+ ActiveRecord::Migration.say_with_time("Source File: #{file}") do
48
+ sheets = HeartSeed::Converter.table_sheets(file)
49
+ sheets.each do |sheet|
50
+ unless ActiveRecord::Base.connection.table_exists?(sheet)
51
+ ActiveRecord::Migration.say("[#{sheet}] Table is not found", true)
52
+ next
53
+ end
54
+
55
+ next unless target_sheet?(sheet)
56
+
57
+ dist_file = File.join(HeartSeed::Helper.seed_dir, "#{sheet}.yml")
58
+ fixtures = HeartSeed::Converter.convert_to_yml(source_file: file, source_sheet: sheet, dist_file: dist_file)
59
+ if fixtures
60
+ ActiveRecord::Migration.say("[#{sheet}] Create seed: #{dist_file}", true)
61
+ else
62
+ ActiveRecord::Migration.say(" [#{sheet}] Sheet is empty", true)
63
+ end
50
64
  end
51
65
  end
52
66
  end
53
67
  end
54
68
 
69
+ namespace :db do
70
+ desc "Load the seed data from db/seeds/*.yml (options: TABLES=table1,table2 CATALOGS=catalog1,catalog2)"
71
+ task :seed => :environment do
72
+ HeartSeed::DbSeed.import_all
73
+ end
74
+ end
75
+
55
76
  private
56
77
  def target_file?(file)
57
78
  return true if ENV["FILES"].blank?
@@ -65,9 +86,9 @@ YAML
65
86
  ENV["SHEETS"].split(",").include?(sheet)
66
87
  end
67
88
 
68
- def create_file(file, str)
89
+ def create_file(file, str = nil)
69
90
  open(file, "w") do |out|
70
- out.write(str)
91
+ out.write(str) if str
71
92
  end
72
93
 
73
94
  puts "create: #{file}"
@@ -1,3 +1,3 @@
1
1
  module HeartSeed
2
- VERSION = "0.0.1.beta1"
2
+ VERSION = "0.0.1.beta2"
3
3
  end
Binary file
@@ -56,4 +56,20 @@ YAML
56
56
 
57
57
  it{ should == ["articles", "Sheet2"] }
58
58
  end
59
+
60
+ describe "#select_left_of_blank" do
61
+ subject{ HeartSeed::Converter.select_left_of_blank(array) }
62
+
63
+ context "When not include blank cell" do
64
+ let(:array){ ["id", "name"] }
65
+
66
+ it{ should eq ["id", "name"] }
67
+ end
68
+
69
+ context "When include blank cell" do
70
+ let(:array){ ["id", "name", "", "this is not table column"] }
71
+
72
+ it{ should eq ["id", "name"] }
73
+ end
74
+ end
59
75
  end
@@ -9,9 +9,16 @@ describe HeartSeed::DbSeed do
9
9
  end
10
10
 
11
11
  describe "#import_all" do
12
- subject{ HeartSeed::DbSeed.import_all(seed_dir: seed_dir, tables: tables) }
12
+ subject{ HeartSeed::DbSeed.import_all(seed_dir: seed_dir, tables: tables, catalogs: catalogs) }
13
13
 
14
14
  let(:seed_dir){ FIXTURE_DIR }
15
+ let(:tables) { [] }
16
+ let(:catalogs){ [] }
17
+
18
+ before do
19
+ # FIXME can not clear if using `DatabaseRewinder.clean`
20
+ DatabaseRewinder.clean_all
21
+ end
15
22
 
16
23
  after do
17
24
  # FIXME can not clear if using `DatabaseRewinder.clean`
@@ -19,8 +26,6 @@ describe HeartSeed::DbSeed do
19
26
  end
20
27
 
21
28
  context "When empty tables" do
22
- let(:tables) { [] }
23
-
24
29
  it{ expect{ subject }.to change(Article, :count).by(2) }
25
30
  it{ expect{ subject }.to change(Comment, :count).by(2) }
26
31
  it{ expect{ subject }.to change(Like , :count).by(1) }
@@ -33,10 +38,24 @@ describe HeartSeed::DbSeed do
33
38
  it{ expect{ subject }.to change(Comment, :count).by(0) }
34
39
  it{ expect{ subject }.to change(Like , :count).by(0) }
35
40
  end
41
+
42
+ context "When specify catalogs" do
43
+ let(:catalogs){ ["article"] }
44
+
45
+ before do
46
+ allow(HeartSeed::Helper).to receive(:catalogs){
47
+ { "article" => ["articles", "likes"] }
48
+ }
49
+ end
50
+
51
+ it{ expect{ subject }.to change(Article, :count).by(2) }
52
+ it{ expect{ subject }.to change(Comment, :count).by(0) }
53
+ it{ expect{ subject }.to change(Like , :count).by(1) }
54
+ end
36
55
  end
37
56
 
38
- describe "#parse_arg_tables" do
39
- subject{ HeartSeed::DbSeed.parse_arg_tables(tables) }
57
+ describe "#parse_string_or_array_arg" do
58
+ subject{ HeartSeed::DbSeed.parse_string_or_array_arg(tables) }
40
59
 
41
60
  where(:tables, :expected) do
42
61
  [
@@ -51,4 +70,32 @@ describe HeartSeed::DbSeed do
51
70
  it{ should eq expected }
52
71
  end
53
72
  end
73
+
74
+ describe "#parse_arg_catalogs" do
75
+ subject{ HeartSeed::DbSeed.parse_arg_catalogs(catalogs) }
76
+
77
+ before do
78
+ allow(HeartSeed::Helper).to receive(:catalogs){
79
+ {
80
+ "article" => ["articles", "likes"],
81
+ "user" => ["users", "user_profiles"],
82
+ }
83
+ }
84
+ end
85
+
86
+ where(:catalogs, :expected) do
87
+ [
88
+ [nil , []],
89
+ ["" , []],
90
+ ["article" , %w(articles likes)],
91
+ ["article,user" , %w(articles likes users user_profiles)],
92
+ [%w(article) , %w(articles likes)],
93
+ [%w(article user) , %w(articles likes users user_profiles)],
94
+ ]
95
+ end
96
+
97
+ with_them do
98
+ it{ should eq expected }
99
+ end
100
+ end
54
101
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heart_seed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.beta1
4
+ version: 0.0.1.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - sue445
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-16 00:00:00.000000000 Z
11
+ date: 2014-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -298,6 +298,7 @@ files:
298
298
  - lib/heart_seed/db_seed.rb
299
299
  - lib/heart_seed/helper.rb
300
300
  - lib/heart_seed/railtie.rb
301
+ - lib/heart_seed/tasks.rb
301
302
  - lib/heart_seed/tasks/heart_seed.rake
302
303
  - lib/heart_seed/version.rb
303
304
  - spec/data/articles.xls