csv-importer 0.4.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cfff4468934d3d7fd8e13b81d618bd2691f3fac7
4
- data.tar.gz: f8980b3710130e74d400c9f649da525da7d46145
2
+ SHA256:
3
+ metadata.gz: fa181c8425255dfe4e9a9fe01fc6c8ee3bd312e701e835999893ef4e9d379de5
4
+ data.tar.gz: b2a627e75724210a76fae4fd47eefd4a853006fec1f09d955c3c11d7c2a66120
5
5
  SHA512:
6
- metadata.gz: cd7068f3d2a32f40b58234fc0805883891e5212aeed10dab1c42c1b3198475080e18a88107fd095d02cda7002740b05c1d1436ec0a6e034899d9c0b0a12c93dc
7
- data.tar.gz: aa78cf760944b7db3204e746b480e01a161ab4a834ddb79aae65a4d33d7b41f8b03a34d68e898add41a7b209d033c3613b06f264fdfcbb380d092ce69e89ea7d
6
+ metadata.gz: 2b0cfce7e92e5036ef3cf26c4b874d95b2f531b96a46f38c275d0156206628b9b223b4900d13cd809e30611f8bd883c54c1c3f76075eb247c9783c8da9063bc1
7
+ data.tar.gz: 1fbc086129f7b54be4ec7036523d56ab799e8efaecb843d2fb22a115d6e60c5a1fbc02c0a6ca5b945c22cd453b24b9b22b63de2259cbb95dfeafc2342c74d2df
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.3.0
4
+ - 2.7
4
5
  addons:
5
6
  code_climate:
6
7
  repo_token: bcecbf1b229a2ddd666a2c3830f26a0113fd56ae1586d30d2d3fb1af837bf0e4
data/CHANGELOG.md CHANGED
@@ -2,11 +2,80 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.8.1] - 2021-02-21
6
+
7
+ * Rails 6.2 compability. [#99][] by [@stevenou][]
8
+
9
+ ## [0.8.0] - 2020-09-02
10
+
11
+ ### Fixed
12
+
13
+ * Ruby 2.7 compatibility. [#93][] by [@perezperret][]
14
+
15
+ ## [0.7.0] - 2019-11-29
16
+
17
+ ### Added
18
+
19
+ * Improve algorithm to detect separators. [#88][] by [@brain-geek][]
20
+ * `to:` accepts anything that responds to `#call` (lambda, procs,
21
+ classes etc). [#72][] by [@pcreux][] inspired by [#71][] by [@macfanatic][].
22
+
23
+ ### Fixed
24
+
25
+ * `valid_header?` returns `false` when the CSV is malformed instead of
26
+ raising an exception. [#85][] by [@mltsy][]
27
+ * Header infos (ex: `extra_columns`) aren't discarded after running an
28
+ import. [#83][] by [@mltsy][]
29
+
30
+
31
+ ## [0.6.0] - 2018-05-22
32
+
33
+ ### Added
34
+
35
+ * We now pass the `column` object as the third parameter of the `column`
36
+ block for advanced usage. [#73][] by [@stas][].
37
+
38
+ ```ruby
39
+ column :extra, as: [/extra/], to: ->(value, user, column) do
40
+ attribute = column.name.sub(/^extra /, '')
41
+ user[attribute] = value
42
+ end
43
+ ```
44
+
45
+ ## [0.5.0] - 2018-01-13
46
+
47
+ ### Added
48
+
49
+ * after_save supports block with arity of 2 for access to raw
50
+ attributes. [#68][] by [@macfanatic][].
51
+
52
+ ```ruby
53
+ class Importer
54
+ model Task
55
+
56
+ column :assignee, to: ->(name) { User.active.find_by(name: name) }
57
+
58
+ after_save do |task, attributes|
59
+ if task.errors[:assignee].present? && attributes['Assignee'].present?
60
+ task.errors.add(:assignee, "'#{ attributes['Assignee'] }' is not part of this project."
61
+ end
62
+ end
63
+ end
64
+ ```
65
+
66
+ * support Proc identifiers. [#69][] by [@danielweinmann][]
67
+
68
+ ```ruby
69
+ class Importer
70
+ identifier ->(user) { user.email.present? ? :email : [:company_id, :employee_id] }
71
+ end
72
+ ```
73
+
5
74
  ## [0.4.0] - 2017-08-10
6
75
 
7
76
  ### Added
8
77
 
9
- * Rows are now aware of their line number.
78
+ * Rows are now aware of their line number. [#63][] by [@paulodeleo][]
10
79
 
11
80
  ```ruby
12
81
  import.report.invalid_rows.map { |row| [row.line_number, row.model.email, row.errors] }
@@ -123,11 +192,31 @@ report object instead of raising an exception.
123
192
  * Initial Release
124
193
 
125
194
  <!--- The following link definition list is generated by PimpMyChangelog --->
126
- [#26]: https://github.com/BrewhouseTeam/csv-importer/issues/26
127
- [#38]: https://github.com/BrewhouseTeam/csv-importer/issues/38
128
- [#47]: https://github.com/BrewhouseTeam/csv-importer/issues/47
129
- [#52]: https://github.com/BrewhouseTeam/csv-importer/issues/52
195
+ [#26]: https://github.com/pcreux/csv-importer/issues/26
196
+ [#38]: https://github.com/pcreux/csv-importer/issues/38
197
+ [#47]: https://github.com/pcreux/csv-importer/issues/47
198
+ [#52]: https://github.com/pcreux/csv-importer/issues/52
199
+ [#63]: https://github.com/pcreux/csv-importer/issues/63
200
+ [#68]: https://github.com/pcreux/csv-importer/issues/68
201
+ [#69]: https://github.com/pcreux/csv-importer/issues/69
202
+ [#71]: https://github.com/pcreux/csv-importer/issues/71
203
+ [#72]: https://github.com/pcreux/csv-importer/issues/72
204
+ [#73]: https://github.com/pcreux/csv-importer/issues/73
205
+ [#83]: https://github.com/pcreux/csv-importer/issues/83
206
+ [#85]: https://github.com/pcreux/csv-importer/issues/85
207
+ [#88]: https://github.com/pcreux/csv-importer/issues/88
208
+ [#93]: https://github.com/pcreux/csv-importer/issues/93
209
+ [#99]: https://github.com/pcreux/csv-importer/issues/99
210
+ [@brain-geek]: https://github.com/brain-geek
211
+ [@danielweinmann]: https://github.com/danielweinmann
130
212
  [@egg-chicken]: https://github.com/egg-chicken
131
- [@pnomolos]: https://github.com/pnomolos
132
213
  [@fxgallego]: https://github.com/fxgallego
214
+ [@macfanatic]: https://github.com/macfanatic
215
+ [@mltsy]: https://github.com/mltsy
216
+ [@paulodeleo]: https://github.com/paulodeleo
217
+ [@pcreux]: https://github.com/pcreux
218
+ [@perezperret]: https://github.com/perezperret
219
+ [@pnomolos]: https://github.com/pnomolos
133
220
  [@shvetsovdm]: https://github.com/shvetsovdm
221
+ [@stas]: https://github.com/stas
222
+ [@stevenou]: https://github.com/stevenou
data/Gemfile CHANGED
@@ -2,9 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in csv-importer.gemspec
4
4
  gemspec
5
-
6
- gem 'rspec', '~> 3.3.0'
7
- gem 'guard-rspec'
8
- gem 'activemodel'
9
- gem 'simplecov', require: nil
10
- gem "codeclimate-test-reporter", require: nil
data/README.md CHANGED
@@ -178,6 +178,36 @@ If you need to do more advanced stuff, you've got access to the model:
178
178
  column :email, as: [/e.?mail/i, "courriel"], to: ->(email, user) { user.email = email.downcase; model.super_user! if email[/@brewhouse.io\z/] }
179
179
  ```
180
180
 
181
+ Like very advanced stuff? We grant you access to the [`column`](https://github.com/pcreux/csv-importer/blob/master/lib/csv_importer/column.rb) object itself which contains the column name – quite handy if you want to support arbitrary columns.
182
+
183
+ ```ruby
184
+ column :extra, as: [/extra/], to: ->(value, user, column) do
185
+ attribute = column.name.sub(/^extra /, '')
186
+ user[attribute] = value
187
+ end
188
+ ```
189
+
190
+ Note that `to:` accepts anything that responds to call and take 1, 2 or
191
+ 3 arguments.
192
+
193
+ ```ruby
194
+ class ImportUserCSV
195
+ include CSVImporter
196
+
197
+ model User
198
+
199
+ column :birth_date, to: DateTransformer
200
+ column :renewal_date, to: DateTransformer
201
+ column :next_renewal_at, to: ->(value) { Time.at(value.to_i) }
202
+ end
203
+
204
+ class DateTransformer
205
+ def self.call(date)
206
+ Date.strptime(date, '%m/%d/%y')
207
+ end
208
+ end
209
+ ```
210
+
181
211
  Now, what if the user does not provide the email column? It's not worth
182
212
  running the import, we should just reject the CSV file right away.
183
213
  That's easy:
@@ -197,7 +227,6 @@ import.report.status # => :invalid_header
197
227
  import.report.message # => "The following columns are required: 'email'"
198
228
  ```
199
229
 
200
-
201
230
  ### Update or Create
202
231
 
203
232
  You often want to find-and-update-or-create when importing a CSV file.
@@ -224,6 +253,14 @@ You can also define a composite identifier:
224
253
  identifier :company_id, :employee_id
225
254
  ```
226
255
 
256
+ Or a Proc:
257
+
258
+ ```ruby
259
+ # Update records with email if email is present
260
+ # Update records matching company_id AND employee_id if email is not present
261
+ identifier ->(user) { user.email.empty? ? [:company_id, :employee_id] : :email }
262
+ ```
263
+
227
264
  ### Skip or Abort on error
228
265
 
229
266
  By default, we skip invalid records and report errors back to the user.
data/csv-importer.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["pcreux@gmail.com"]
11
11
 
12
12
  spec.summary = %q{CSV Import for humans}
13
- spec.homepage = "https://github.com/BrewhouseTeam/csv-importer"
13
+ spec.homepage = "https://github.com/pcreux/csv-importer"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
@@ -20,6 +20,10 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "virtus"
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.8"
24
- spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.3.0"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "guard-rspec"
26
+ spec.add_development_dependency "activemodel", "~> 5"
27
+ spec.add_development_dependency "simplecov"
28
+ spec.add_development_dependency "codeclimate-test-reporter"
25
29
  end
data/lib/csv_importer.rb CHANGED
@@ -85,13 +85,16 @@ module CSVImporter
85
85
  end
86
86
 
87
87
  header.valid?
88
+ rescue CSV::MalformedCSVError => e
89
+ @report = Report.new(status: :invalid_csv_file, parser_error: e.message)
90
+ false
88
91
  end
89
92
 
90
93
  # Run the import. Return a Report.
91
94
  def run!
92
95
  if valid_header?
93
96
  @report = Runner.call(rows: rows, when_invalid: config.when_invalid,
94
- after_save_blocks: config.after_save_blocks)
97
+ after_save_blocks: config.after_save_blocks, report: @report)
95
98
  else
96
99
  @report
97
100
  end
@@ -29,7 +29,7 @@ module CSVImporter
29
29
  attribute :name, Symbol
30
30
  attribute :to # Symbol or Proc
31
31
  attribute :as # Symbol, String, Regexp, Array
32
- attribute :required, Boolean
32
+ attribute :required, Virtus::Attribute::Boolean
33
33
 
34
34
  # The model attribute that this column targets
35
35
  def attribute
@@ -5,7 +5,7 @@ module CSVImporter
5
5
 
6
6
  attribute :model
7
7
  attribute :column_definitions, Array[ColumnDefinition], default: proc { [] }
8
- attribute :identifiers, Array[Symbol], default: []
8
+ attribute :identifiers # Array[Symbol] or Proc
9
9
  attribute :when_invalid, Symbol, default: proc { :skip }
10
10
  attribute :after_build_blocks, Array[Proc], default: []
11
11
  attribute :after_save_blocks, Array[Proc], default: []
@@ -27,4 +27,3 @@ module CSVImporter
27
27
  end
28
28
  end
29
29
  end
30
-
@@ -14,8 +14,12 @@ module CSVImporter
14
14
  @csv_rows ||= begin
15
15
  sane_content = sanitize_content(read_content)
16
16
  separator = detect_separator(sane_content)
17
- cells = CSV.parse(sane_content, col_sep: separator, quote_char: quote_char, skip_blanks: true, encoding: encoding)
18
- sanitize_cells(cells)
17
+ cells = CSV.parse(
18
+ sane_content,
19
+ col_sep: separator, quote_char: quote_char, skip_blanks: true,
20
+ external_encoding: source_encoding
21
+ )
22
+ sanitize_cells(encode_cells(cells))
19
23
  end
20
24
  end
21
25
 
@@ -44,16 +48,26 @@ module CSVImporter
44
48
  end
45
49
 
46
50
  def sanitize_content(csv_content)
47
- internal_encoding = encoding.split(':').last
48
51
  csv_content
49
- .encode(Encoding.find(internal_encoding), {invalid: :replace, undef: :replace, replace: ''}) # Remove invalid byte sequences
52
+ .encode(Encoding.find(source_encoding), invalid: :replace, undef: :replace, replace: '') # Remove invalid byte sequences
50
53
  .gsub(/\r\r?\n?/, "\n") # Replaces windows line separators with "\n"
51
54
  end
52
55
 
53
56
  SEPARATORS = [",", ";", "\t"]
54
57
 
55
58
  def detect_separator(csv_content)
56
- SEPARATORS.sort_by { |separator| csv_content.count(separator) }.last
59
+ SEPARATORS.min_by do |separator|
60
+ csv_content.count(separator)
61
+
62
+ all_lines = csv_content.lines
63
+ base_number = all_lines.first.count(separator)
64
+
65
+ if base_number.zero?
66
+ Float::MAX
67
+ else
68
+ all_lines.map{|line| line.count(separator) - base_number }.map(&:abs).inject(0) { |sum, i| sum + i }
69
+ end
70
+ end
57
71
  end
58
72
 
59
73
  # Remove trailing white spaces and ensure we always return a string
@@ -64,5 +78,21 @@ module CSVImporter
64
78
  end
65
79
  end
66
80
  end
81
+
82
+ def encode_cells(rows)
83
+ rows.map do |cells|
84
+ cells.map do |cell|
85
+ cell ? cell.encode(target_encoding) : ""
86
+ end
87
+ end
88
+ end
89
+
90
+ def source_encoding
91
+ encoding.split(':').first || 'UTF-8'
92
+ end
93
+
94
+ def target_encoding
95
+ encoding.split(':').last || 'UTF-8'
96
+ end
67
97
  end
68
98
  end
@@ -10,8 +10,8 @@ module CSVImporter
10
10
  config.column_definitions << options.merge(name: name)
11
11
  end
12
12
 
13
- def identifier(*identifiers)
14
- config.identifiers = identifiers
13
+ def identifier(*params)
14
+ config.identifiers = params.first.is_a?(Proc) ? params.first : params
15
15
  end
16
16
 
17
17
  alias_method :identifiers, :identifier
@@ -12,8 +12,8 @@ module CSVImporter
12
12
 
13
13
  attribute :status, Symbol, default: proc { :pending }
14
14
 
15
- attribute :missing_columns, Array[Symbol], default: proc { [] }
16
- attribute :extra_columns, Array[Symbol], default: proc { [] }
15
+ attribute :missing_columns, Array[String], default: proc { [] }
16
+ attribute :extra_columns, Array[String], default: proc { [] }
17
17
 
18
18
  attribute :parser_error, String
19
19
 
@@ -10,9 +10,9 @@ module CSVImporter
10
10
  attribute :line_number, Integer
11
11
  attribute :row_array, Array[String]
12
12
  attribute :model_klass
13
- attribute :identifiers, Array[Symbol]
13
+ attribute :identifiers # Array[Symbol] or Proc
14
14
  attribute :after_build_blocks, Array[Proc], default: []
15
- attribute :skip, Boolean, default: false
15
+ attribute :skip, Virtus::Attribute::Boolean, default: false
16
16
 
17
17
  # The model to be persisted
18
18
  def model
@@ -41,27 +41,30 @@ module CSVImporter
41
41
  # can't dup Symbols, Integer etc...
42
42
  end
43
43
 
44
- column_definition = column.definition
45
- next if column_definition.nil?
44
+ next if column.definition.nil?
46
45
 
47
- set_attribute(model, column_definition, value)
46
+ set_attribute(model, column, value)
48
47
  end
49
48
 
50
49
  model
51
50
  end
52
51
 
53
52
  # Set the attribute using the column_definition and the csv_value
54
- def set_attribute(model, column_definition, csv_value)
55
- if column_definition.to && column_definition.to.is_a?(Proc)
56
- to_proc = column_definition.to
53
+ def set_attribute(model, column, csv_value)
54
+ column_definition = column.definition
55
+ transformer = column_definition.to
56
+ if transformer.respond_to?(:call)
57
+ arity = transformer.is_a?(Proc) ? transformer.arity : transformer.method(:call).arity
57
58
 
58
- case to_proc.arity
59
+ case arity
59
60
  when 1 # to: ->(email) { email.downcase }
60
- model.public_send("#{column_definition.name}=", to_proc.call(csv_value))
61
+ model.public_send("#{column_definition.name}=", transformer.call(csv_value))
61
62
  when 2 # to: ->(published, post) { post.published_at = Time.now if published == "true" }
62
- to_proc.call(csv_value, model)
63
+ transformer.call(csv_value, model)
64
+ when 3 # to: ->(field_value, post, column) { post.hash_field[column.name] = field_value }
65
+ transformer.call(csv_value, model, column)
63
66
  else
64
- raise ArgumentError, "`to` proc can only have 1 or 2 arguments"
67
+ raise ArgumentError, "arity: #{transformer.arity.inspect} - `to` can only have 1, 2 or 3 arguments"
65
68
  end
66
69
  else
67
70
  attribute = column_definition.attribute
@@ -74,11 +77,11 @@ module CSVImporter
74
77
  # Error from the model mapped back to the CSV header if we can
75
78
  def errors
76
79
  Hash[
77
- model.errors.map do |attribute, errors|
80
+ model.errors.to_hash.map do |attribute, errors|
78
81
  if column_name = header.column_name_for_model_attribute(attribute)
79
- [column_name, errors]
82
+ [column_name, errors.last]
80
83
  else
81
- [attribute, errors]
84
+ [attribute, errors.last]
82
85
  end
83
86
  end
84
87
  ]
@@ -89,10 +92,14 @@ module CSVImporter
89
92
  end
90
93
 
91
94
  def find_model
92
- return nil if identifiers.empty?
95
+ return nil if identifiers.nil?
93
96
 
94
97
  model = build_model
95
98
  set_attributes(model)
99
+
100
+ identifiers = model_identifiers(model)
101
+ return nil if identifiers.empty?
102
+
96
103
  query = Hash[
97
104
  identifiers.map { |identifier| [ identifier, model.public_send(identifier) ] }
98
105
  ]
@@ -106,5 +113,15 @@ module CSVImporter
106
113
  def skip!
107
114
  self.skip = true
108
115
  end
116
+
117
+ private
118
+
119
+ def model_identifiers(model)
120
+ if identifiers.is_a?(Proc)
121
+ [identifiers.call(model)].flatten
122
+ else
123
+ identifiers
124
+ end
125
+ end
109
126
  end
110
127
  end
@@ -63,7 +63,16 @@ module CSVImporter
63
63
  end
64
64
 
65
65
  add_to_report(row, tags)
66
- after_save_blocks.each { |block| block.call(row.model) }
66
+
67
+ after_save_blocks.each do |block|
68
+ case block.arity
69
+ when 0 then block.call
70
+ when 1 then block.call(row.model)
71
+ when 2 then block.call(row.model, row.csv_attributes)
72
+ else
73
+ raise ArgumentError, "after_save block of arity #{ block.arity } is not supported"
74
+ end
75
+ end
67
76
  end
68
77
  end
69
78
  end
@@ -1,3 +1,3 @@
1
1
  module CSVImporter
2
- VERSION = "0.4.0"
2
+ VERSION = "0.8.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv-importer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philippe Creux
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-10 00:00:00.000000000 Z
11
+ date: 2021-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: virtus
@@ -25,34 +25,90 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.8'
33
+ version: 3.3.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.8'
40
+ version: 3.3.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activemodel
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: '10.0'
75
+ version: '5'
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: '10.0'
55
- description:
82
+ version: '5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: codeclimate-test-reporter
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description:
56
112
  email:
57
113
  - pcreux@gmail.com
58
114
  executables: []
@@ -85,11 +141,11 @@ files:
85
141
  - lib/csv_importer/row.rb
86
142
  - lib/csv_importer/runner.rb
87
143
  - lib/csv_importer/version.rb
88
- homepage: https://github.com/BrewhouseTeam/csv-importer
144
+ homepage: https://github.com/pcreux/csv-importer
89
145
  licenses:
90
146
  - MIT
91
147
  metadata: {}
92
- post_install_message:
148
+ post_install_message:
93
149
  rdoc_options: []
94
150
  require_paths:
95
151
  - lib
@@ -104,9 +160,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
160
  - !ruby/object:Gem::Version
105
161
  version: '0'
106
162
  requirements: []
107
- rubyforge_project:
108
- rubygems_version: 2.4.5.1
109
- signing_key:
163
+ rubygems_version: 3.0.3
164
+ signing_key:
110
165
  specification_version: 4
111
166
  summary: CSV Import for humans
112
167
  test_files: []