importu 0.1.0 → 0.2.0

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.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +15 -0
  3. data/.github/workflows/ci.yml +48 -0
  4. data/.gitignore +4 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +311 -0
  7. data/.simplecov +14 -0
  8. data/.yardstick.yml +36 -0
  9. data/Appraisals +22 -0
  10. data/CHANGELOG.md +51 -0
  11. data/CONTRIBUTING.md +86 -0
  12. data/Gemfile +5 -1
  13. data/LICENSE +21 -0
  14. data/README.md +435 -52
  15. data/Rakefile +71 -0
  16. data/UPGRADING.md +188 -0
  17. data/gemfiles/rails_7_2.gemfile +11 -0
  18. data/gemfiles/rails_7_2.gemfile.lock +268 -0
  19. data/gemfiles/rails_8_0.gemfile +11 -0
  20. data/gemfiles/rails_8_0.gemfile.lock +271 -0
  21. data/gemfiles/rails_8_1.gemfile +11 -0
  22. data/gemfiles/rails_8_1.gemfile.lock +269 -0
  23. data/gemfiles/standalone.gemfile +8 -0
  24. data/gemfiles/standalone.gemfile.lock +197 -0
  25. data/importu.gemspec +41 -22
  26. data/lib/importu/backends/active_record.rb +171 -0
  27. data/lib/importu/backends/middleware/duplicate_manager_proxy.rb +41 -0
  28. data/lib/importu/backends/middleware/enforce_allowed_actions.rb +52 -0
  29. data/lib/importu/backends/middleware.rb +11 -0
  30. data/lib/importu/backends.rb +103 -0
  31. data/lib/importu/config_dsl.rb +381 -0
  32. data/lib/importu/converter_context.rb +94 -0
  33. data/lib/importu/converters.rb +119 -64
  34. data/lib/importu/definition.rb +23 -0
  35. data/lib/importu/duplicate_manager.rb +88 -0
  36. data/lib/importu/exceptions.rb +135 -4
  37. data/lib/importu/importer.rb +183 -96
  38. data/lib/importu/record.rb +138 -102
  39. data/lib/importu/sources/csv.rb +122 -0
  40. data/lib/importu/sources/json.rb +106 -0
  41. data/lib/importu/sources/ruby.rb +46 -0
  42. data/lib/importu/sources/xml.rb +133 -0
  43. data/lib/importu/sources.rb +13 -0
  44. data/lib/importu/summary.rb +277 -0
  45. data/lib/importu/version.rb +3 -1
  46. data/lib/importu.rb +45 -9
  47. data/spec/fixtures/books-duplicates/README.md +7 -0
  48. data/spec/fixtures/books-duplicates/infile.csv +7 -0
  49. data/spec/fixtures/books-duplicates/model.json +23 -0
  50. data/spec/fixtures/books-duplicates/summary.json +10 -0
  51. data/spec/fixtures/books-valid/README.md +13 -0
  52. data/spec/fixtures/books-valid/infile.csv +4 -0
  53. data/spec/fixtures/books-valid/infile.json +23 -0
  54. data/spec/fixtures/books-valid/infile.xml +21 -0
  55. data/spec/fixtures/books-valid/model.json +23 -0
  56. data/spec/fixtures/books-valid/record.json +26 -0
  57. data/spec/fixtures/books-valid/summary.json +8 -0
  58. data/spec/fixtures/source-empty-file/infile.csv +0 -0
  59. data/spec/fixtures/source-empty-file/infile.json +0 -0
  60. data/spec/fixtures/source-empty-file/infile.xml +0 -0
  61. data/spec/fixtures/source-empty-records/infile.csv +3 -0
  62. data/spec/fixtures/source-empty-records/infile.json +1 -0
  63. data/spec/fixtures/source-empty-records/infile.xml +6 -0
  64. data/spec/fixtures/source-malformed/infile.csv +1 -0
  65. data/spec/fixtures/source-malformed/infile.json +1 -0
  66. data/spec/fixtures/source-malformed/infile.xml +3 -0
  67. data/spec/fixtures/source-no-records/infile.csv +1 -0
  68. data/spec/fixtures/source-no-records/infile.json +1 -0
  69. data/spec/fixtures/source-no-records/infile.xml +3 -0
  70. data/spec/lib/importu/backends/active_record_spec.rb +150 -0
  71. data/spec/lib/importu/backends/middleware/duplicate_manager_proxy_spec.rb +70 -0
  72. data/spec/lib/importu/backends/middleware/enforce_allowed_actions_spec.rb +70 -0
  73. data/spec/lib/importu/backends_spec.rb +170 -0
  74. data/spec/lib/importu/converters_spec.rb +184 -141
  75. data/spec/lib/importu/definition_spec.rb +248 -0
  76. data/spec/lib/importu/duplicate_manager_spec.rb +92 -0
  77. data/spec/lib/importu/exceptions_spec.rb +69 -16
  78. data/spec/lib/importu/import_context_spec.rb +199 -0
  79. data/spec/lib/importu/importer_spec.rb +95 -0
  80. data/spec/lib/importu/integration_spec.rb +221 -0
  81. data/spec/lib/importu/record_spec.rb +130 -80
  82. data/spec/lib/importu/sources/csv_spec.rb +29 -0
  83. data/spec/lib/importu/sources/importer_source_examples.rb +175 -0
  84. data/spec/lib/importu/sources/json_spec.rb +29 -0
  85. data/spec/lib/importu/sources/ruby_spec.rb +102 -0
  86. data/spec/lib/importu/sources/xml_spec.rb +70 -0
  87. data/spec/lib/importu/summary_spec.rb +186 -0
  88. data/spec/spec_helper.rb +91 -7
  89. data/spec/support/active_record.rb +20 -0
  90. data/spec/support/book_importer.rb +31 -0
  91. data/spec/support/dummy_backend.rb +50 -0
  92. data/spec/support/fixtures_helper.rb +43 -0
  93. data/spec/support/matchers/delegate_matcher.rb +14 -8
  94. metadata +173 -100
  95. data/lib/importu/core_ext/array/deep_freeze.rb +0 -7
  96. data/lib/importu/core_ext/deep_freeze.rb +0 -3
  97. data/lib/importu/core_ext/hash/deep_freeze.rb +0 -7
  98. data/lib/importu/core_ext/object/deep_freeze.rb +0 -6
  99. data/lib/importu/core_ext.rb +0 -3
  100. data/lib/importu/dsl.rb +0 -127
  101. data/lib/importu/importer/csv.rb +0 -52
  102. data/lib/importu/importer/json.rb +0 -45
  103. data/lib/importu/importer/xml.rb +0 -55
  104. data/spec/factories/importer.rb +0 -12
  105. data/spec/factories/importer_record.rb +0 -13
  106. data/spec/factories/json_importer.rb +0 -14
  107. data/spec/factories/xml_importer.rb +0 -12
  108. data/spec/lib/importu/dsl_spec.rb +0 -26
  109. data/spec/lib/importu/importer/json_spec.rb +0 -37
  110. data/spec/lib/importu/importer/xml_spec.rb +0 -14
data/UPGRADING.md ADDED
@@ -0,0 +1,188 @@
1
+ # Upgrading to Importu 0.2.0
2
+
3
+ This guide covers breaking changes when upgrading from 0.1.0 to 0.2.0.
4
+
5
+ ## Prerequisites
6
+
7
+ Before upgrading, ensure your environment meets the new requirements:
8
+
9
+ - **Ruby >= 3.1** (was 2.3+)
10
+ - **Rails >= 7.2** if using ActiveRecord backend (was 4.x+)
11
+ - **nokogiri >= 1.18.4** (security requirement)
12
+
13
+ ## Step 1: Update Exception Handling
14
+
15
+ The JSON source now uses Ruby's stdlib JSON instead of MultiJson.
16
+
17
+ ```ruby
18
+ # Before (0.1.0)
19
+ rescue MultiJson::DecodeError => e
20
+ # handle JSON parse error
21
+
22
+ # After (0.2.0)
23
+ rescue JSON::ParserError => e
24
+ # handle JSON parse error
25
+ ```
26
+
27
+ ## Step 2: Update Require Statements
28
+
29
+ The main entry point now eager-loads all components.
30
+
31
+ ```ruby
32
+ # Before (0.1.0) - explicit requires needed
33
+ require "importu"
34
+ require "importu/importer"
35
+ require "importu/sources/csv"
36
+
37
+ # After (0.2.0) - single require loads everything
38
+ require "importu"
39
+ # Importer class and all sources are now available
40
+ ```
41
+
42
+ **Note:** If you have custom autoloading or deferred requires, the eager
43
+ loading may affect initialization order.
44
+
45
+ ## Step 3: Update Custom Exception Handling
46
+
47
+ ### InvalidRecord
48
+
49
+ The constructor now accepts a `normalized_message:` keyword argument for
50
+ better error aggregation:
51
+
52
+ ```ruby
53
+ # Before (0.1.0)
54
+ raise Importu::InvalidRecord.new("error message", validation_errors)
55
+
56
+ # After (0.2.0) - still works, but you can optionally add:
57
+ raise Importu::InvalidRecord.new(
58
+ "field is invalid (row 5)",
59
+ validation_errors,
60
+ normalized_message: "field is invalid" # Used for aggregation
61
+ )
62
+ ```
63
+
64
+ The `normalized_message` is used by `Summary#validation_errors` to group
65
+ similar errors together. If not provided, the summary strips trailing
66
+ parenthesized data automatically.
67
+
68
+ ### MissingField
69
+
70
+ The constructor now uses a keyword argument for `available_fields`:
71
+
72
+ ```ruby
73
+ # Before (0.1.0) - if you raised this manually
74
+ raise Importu::MissingField.new(definition, available_fields)
75
+
76
+ # After (0.2.0)
77
+ raise Importu::MissingField.new(definition, available_fields: available_fields)
78
+ ```
79
+
80
+ ## Step 4: Update Error Message Parsing
81
+
82
+ ### Summary#validation_errors Format
83
+
84
+ Error messages are now normalized before aggregation. Trailing parenthesized
85
+ data (like row numbers) is stripped:
86
+
87
+ ```ruby
88
+ # Before (0.1.0) - errors kept exact messages
89
+ summary.validation_errors
90
+ # => { "name is invalid (row 5)" => 1, "name is invalid (row 12)" => 1 }
91
+
92
+ # After (0.2.0) - messages are normalized for aggregation
93
+ summary.validation_errors
94
+ # => { "name is invalid" => 2 }
95
+ ```
96
+
97
+ **If you need exact error messages**, use `itemized_errors` instead:
98
+
99
+ ```ruby
100
+ summary.itemized_errors.each do |index, errors|
101
+ errors.each { |e| puts "Row #{index}: #{e.to_s}" }
102
+ end
103
+ ```
104
+
105
+ ### Rails 7+ Error Format
106
+
107
+ The ActiveRecord backend now uses the Rails 7+ errors API:
108
+
109
+ ```ruby
110
+ # Error messages now formatted as:
111
+ "attribute message" # e.g., "title can't be blank"
112
+
113
+ # Instead of Rails 6 style:
114
+ "Attribute message" # e.g., "Title can't be blank"
115
+ ```
116
+
117
+ This affects how errors appear in `Summary#validation_errors`.
118
+
119
+ ## Step 5: Update Source Usage
120
+
121
+ ### File Handle Management
122
+
123
+ Sources now have a `close` method. For long-running processes, explicitly
124
+ close sources when done:
125
+
126
+ ```ruby
127
+ source = Importu::Sources::CSV.new("data.csv")
128
+ importer = MyImporter.new(source)
129
+ summary = importer.import!
130
+ source.close # New in 0.2.0
131
+ ```
132
+
133
+ The JSON source closes its file handle immediately after reading (since it
134
+ loads everything into memory), so `close` is a no-op for JSON.
135
+
136
+ ### Removed: xml_options Parameter
137
+
138
+ The `xml_options` parameter was removed from `Importu::Sources::XML` as it
139
+ was never implemented:
140
+
141
+ ```ruby
142
+ # Before (0.1.0) - accepted but ignored
143
+ source = Importu::Sources::XML.new("data.xml",
144
+ records_xpath: "//book",
145
+ xml_options: { encoding: "UTF-8" } # This never did anything
146
+ )
147
+
148
+ # After (0.2.0) - parameter removed
149
+ source = Importu::Sources::XML.new("data.xml", records_xpath: "//book")
150
+ ```
151
+
152
+ ### Removed: allow_sources DSL
153
+
154
+ The `allow_sources` DSL method was removed as it was never enforced:
155
+
156
+ ```ruby
157
+ # Before (0.1.0) - accepted but never checked
158
+ class MyImporter < Importu::Importer
159
+ allow_sources :csv, :json # This never did anything
160
+ end
161
+
162
+ # After (0.2.0) - method removed
163
+ # Simply don't use it; pass the correct source type when creating the importer
164
+ ```
165
+
166
+ ## Step 6: Test Your Import Code
167
+
168
+ After upgrading, verify your imports work correctly:
169
+
170
+ 1. Run your test suite
171
+ 2. Test with sample data files
172
+ 3. Check error handling paths
173
+ 4. Verify error message formatting meets your needs
174
+
175
+ ## Summary of Breaking Changes
176
+
177
+ | Change | Impact | Action Required |
178
+ |--------|--------|-----------------|
179
+ | Ruby >= 3.1 | High | Upgrade Ruby |
180
+ | Rails >= 7.2 | High | Upgrade Rails (if using AR backend) |
181
+ | MultiJson removed | Medium | Change exception handling |
182
+ | Require path changed | Low | Simplify requires |
183
+ | Error normalization | Low | Update error parsing if needed |
184
+ | `normalized_message` added | Low | None (backwards compatible) |
185
+ | `available_fields:` keyword | Low | Update if raising MissingField |
186
+ | `xml_options` removed | Low | Remove if passing |
187
+ | `allow_sources` removed | Low | Remove if using |
188
+ | `close` method added | Low | Call for long-running processes |
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "irb"
6
+ gem "yardstick", "~> 0.9", require: false
7
+ gem "sqlite3", "~> 2.0"
8
+ gem "database_cleaner-active_record"
9
+ gem "activerecord", "~> 7.2.0"
10
+
11
+ gemspec path: "../"
@@ -0,0 +1,268 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ importu (0.1.0)
5
+ bigdecimal
6
+ csv
7
+ nokogiri (>= 1.13)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activemodel (7.2.3)
13
+ activesupport (= 7.2.3)
14
+ activerecord (7.2.3)
15
+ activemodel (= 7.2.3)
16
+ activesupport (= 7.2.3)
17
+ timeout (>= 0.4.0)
18
+ activesupport (7.2.3)
19
+ base64
20
+ benchmark (>= 0.3)
21
+ bigdecimal
22
+ concurrent-ruby (~> 1.0, >= 1.3.1)
23
+ connection_pool (>= 2.2.5)
24
+ drb
25
+ i18n (>= 1.6, < 2)
26
+ logger (>= 1.4.2)
27
+ minitest (>= 5.1)
28
+ securerandom (>= 0.3)
29
+ tzinfo (~> 2.0, >= 2.0.5)
30
+ appraisal (2.5.0)
31
+ bundler
32
+ rake
33
+ thor (>= 0.14.0)
34
+ ast (2.4.3)
35
+ base64 (0.3.0)
36
+ benchmark (0.5.0)
37
+ bigdecimal (4.0.1)
38
+ concurrent-ruby (1.3.6)
39
+ connection_pool (3.0.2)
40
+ csv (3.3.5)
41
+ database_cleaner-active_record (2.2.2)
42
+ activerecord (>= 5.a)
43
+ database_cleaner-core (~> 2.0)
44
+ database_cleaner-core (2.0.1)
45
+ date (3.5.1)
46
+ diff-lcs (1.6.2)
47
+ docile (1.4.1)
48
+ drb (2.2.3)
49
+ erb (6.0.1)
50
+ i18n (1.14.8)
51
+ concurrent-ruby (~> 1.0)
52
+ io-console (0.8.2)
53
+ irb (1.16.0)
54
+ pp (>= 0.6.0)
55
+ rdoc (>= 4.0.0)
56
+ reline (>= 0.4.2)
57
+ json (2.18.0)
58
+ language_server-protocol (3.17.0.5)
59
+ lint_roller (1.1.0)
60
+ logger (1.7.0)
61
+ minitest (6.0.1)
62
+ prism (~> 1.5)
63
+ nokogiri (1.19.0-aarch64-linux-gnu)
64
+ racc (~> 1.4)
65
+ nokogiri (1.19.0-aarch64-linux-musl)
66
+ racc (~> 1.4)
67
+ nokogiri (1.19.0-arm-linux-gnu)
68
+ racc (~> 1.4)
69
+ nokogiri (1.19.0-arm-linux-musl)
70
+ racc (~> 1.4)
71
+ nokogiri (1.19.0-arm64-darwin)
72
+ racc (~> 1.4)
73
+ nokogiri (1.19.0-x86_64-darwin)
74
+ racc (~> 1.4)
75
+ nokogiri (1.19.0-x86_64-linux-gnu)
76
+ racc (~> 1.4)
77
+ nokogiri (1.19.0-x86_64-linux-musl)
78
+ racc (~> 1.4)
79
+ parallel (1.27.0)
80
+ parser (3.3.10.1)
81
+ ast (~> 2.4.1)
82
+ racc
83
+ pp (0.6.3)
84
+ prettyprint
85
+ prettyprint (0.2.0)
86
+ prism (1.9.0)
87
+ psych (5.3.1)
88
+ date
89
+ stringio
90
+ racc (1.8.1)
91
+ rainbow (3.1.1)
92
+ rake (13.3.1)
93
+ rdoc (7.1.0)
94
+ erb
95
+ psych (>= 4.0.0)
96
+ tsort
97
+ redcarpet (3.6.1)
98
+ regexp_parser (2.11.3)
99
+ reline (0.6.3)
100
+ io-console (~> 0.5)
101
+ rspec (3.13.2)
102
+ rspec-core (~> 3.13.0)
103
+ rspec-expectations (~> 3.13.0)
104
+ rspec-mocks (~> 3.13.0)
105
+ rspec-core (3.13.6)
106
+ rspec-support (~> 3.13.0)
107
+ rspec-expectations (3.13.5)
108
+ diff-lcs (>= 1.2.0, < 2.0)
109
+ rspec-support (~> 3.13.0)
110
+ rspec-mocks (3.13.7)
111
+ diff-lcs (>= 1.2.0, < 2.0)
112
+ rspec-support (~> 3.13.0)
113
+ rspec-support (3.13.6)
114
+ rubocop (1.84.0)
115
+ json (~> 2.3)
116
+ language_server-protocol (~> 3.17.0.2)
117
+ lint_roller (~> 1.1.0)
118
+ parallel (~> 1.10)
119
+ parser (>= 3.3.0.2)
120
+ rainbow (>= 2.2.2, < 4.0)
121
+ regexp_parser (>= 2.9.3, < 3.0)
122
+ rubocop-ast (>= 1.49.0, < 2.0)
123
+ ruby-progressbar (~> 1.7)
124
+ unicode-display_width (>= 2.4.0, < 4.0)
125
+ rubocop-ast (1.49.0)
126
+ parser (>= 3.3.7.2)
127
+ prism (~> 1.7)
128
+ rubocop-performance (1.26.1)
129
+ lint_roller (~> 1.1)
130
+ rubocop (>= 1.75.0, < 2.0)
131
+ rubocop-ast (>= 1.47.1, < 2.0)
132
+ ruby-progressbar (1.13.0)
133
+ securerandom (0.4.1)
134
+ simplecov (0.22.0)
135
+ docile (~> 1.1)
136
+ simplecov-html (~> 0.11)
137
+ simplecov_json_formatter (~> 0.1)
138
+ simplecov-html (0.13.2)
139
+ simplecov_json_formatter (0.1.4)
140
+ sqlite3 (2.9.0-aarch64-linux-gnu)
141
+ sqlite3 (2.9.0-aarch64-linux-musl)
142
+ sqlite3 (2.9.0-arm-linux-gnu)
143
+ sqlite3 (2.9.0-arm-linux-musl)
144
+ sqlite3 (2.9.0-arm64-darwin)
145
+ sqlite3 (2.9.0-x86_64-darwin)
146
+ sqlite3 (2.9.0-x86_64-linux-gnu)
147
+ sqlite3 (2.9.0-x86_64-linux-musl)
148
+ stringio (3.2.0)
149
+ thor (1.5.0)
150
+ timeout (0.6.0)
151
+ tsort (0.2.0)
152
+ tzinfo (2.0.6)
153
+ concurrent-ruby (~> 1.0)
154
+ unicode-display_width (3.2.0)
155
+ unicode-emoji (~> 4.1)
156
+ unicode-emoji (4.2.0)
157
+ yard (0.9.38)
158
+ yardstick (0.9.9)
159
+ yard (~> 0.8, >= 0.8.7.2)
160
+
161
+ PLATFORMS
162
+ aarch64-linux-gnu
163
+ aarch64-linux-musl
164
+ arm-linux-gnu
165
+ arm-linux-musl
166
+ arm64-darwin
167
+ x86_64-darwin
168
+ x86_64-linux-gnu
169
+ x86_64-linux-musl
170
+
171
+ DEPENDENCIES
172
+ activerecord (~> 7.2.0)
173
+ appraisal
174
+ bundler (>= 2.0)
175
+ database_cleaner-active_record
176
+ importu!
177
+ irb
178
+ redcarpet
179
+ rspec (~> 3.13)
180
+ rubocop (~> 1.70)
181
+ rubocop-performance (~> 1.24)
182
+ simplecov (~> 0.22)
183
+ sqlite3 (~> 2.0)
184
+ yard
185
+ yardstick (~> 0.9)
186
+
187
+ CHECKSUMS
188
+ activemodel (7.2.3) sha256=bbaf66aeb93212e98ebf6ab900f8290f9a831645f0b235427f5acf0e074739db
189
+ activerecord (7.2.3) sha256=6facb7478ceb5f6baa9f0647daa50b4a3a43934997900f0011e6c667ff41a0d7
190
+ activesupport (7.2.3) sha256=5675c9770dac93e371412684249f9dc3c8cec104efd0624362a520ae685c7b10
191
+ appraisal (2.5.0) sha256=36989221be127913b0dba8d114da2001e6b2dceea7bd4951200eaba764eed3ce
192
+ ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
193
+ base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
194
+ benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c
195
+ bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
196
+ concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
197
+ connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
198
+ csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f
199
+ database_cleaner-active_record (2.2.2) sha256=88296b9f3088c31f7c0d4fcec10f68e4b71c96698043916de59b04debec10388
200
+ database_cleaner-core (2.0.1) sha256=8646574c32162e59ed7b5258a97a208d3c44551b854e510994f24683865d846c
201
+ date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
202
+ diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
203
+ docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
204
+ drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
205
+ erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
206
+ i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
207
+ importu (0.1.0)
208
+ io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
209
+ irb (1.16.0) sha256=2abe56c9ac947cdcb2f150572904ba798c1e93c890c256f8429981a7675b0806
210
+ json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505
211
+ language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
212
+ lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
213
+ logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
214
+ minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb
215
+ nokogiri (1.19.0-aarch64-linux-gnu) sha256=11a97ecc3c0e7e5edcf395720b10860ef493b768f6aa80c539573530bc933767
216
+ nokogiri (1.19.0-aarch64-linux-musl) sha256=eb70507f5e01bc23dad9b8dbec2b36ad0e61d227b42d292835020ff754fb7ba9
217
+ nokogiri (1.19.0-arm-linux-gnu) sha256=572a259026b2c8b7c161fdb6469fa2d0edd2b61cd599db4bbda93289abefbfe5
218
+ nokogiri (1.19.0-arm-linux-musl) sha256=23ed90922f1a38aed555d3de4d058e90850c731c5b756d191b3dc8055948e73c
219
+ nokogiri (1.19.0-arm64-darwin) sha256=0811dfd936d5f6dd3f6d32ef790568bf29b2b7bead9ba68866847b33c9cf5810
220
+ nokogiri (1.19.0-x86_64-darwin) sha256=1dad56220b603a8edb9750cd95798bffa2b8dd9dd9aa47f664009ee5b43e3067
221
+ nokogiri (1.19.0-x86_64-linux-gnu) sha256=f482b95c713d60031d48c44ce14562f8d2ce31e3a9e8dd0ccb131e9e5a68b58c
222
+ nokogiri (1.19.0-x86_64-linux-musl) sha256=1c4ca6b381622420073ce6043443af1d321e8ed93cc18b08e2666e5bd02ffae4
223
+ parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
224
+ parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688
225
+ pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
226
+ prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
227
+ prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
228
+ psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
229
+ racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
230
+ rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
231
+ rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
232
+ rdoc (7.1.0) sha256=494899df0706c178596ca6e1d50f1b7eb285a9b2aae715be5abd742734f17363
233
+ redcarpet (3.6.1) sha256=d444910e6aa55480c6bcdc0cdb057626e8a32c054c29e793fa642ba2f155f445
234
+ regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
235
+ reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
236
+ rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
237
+ rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
238
+ rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
239
+ rspec-mocks (3.13.7) sha256=0979034e64b1d7a838aaaddf12bf065ea4dc40ef3d4c39f01f93ae2c66c62b1c
240
+ rspec-support (3.13.6) sha256=2e8de3702427eab064c9352fe74488cc12a1bfae887ad8b91cba480ec9f8afb2
241
+ rubocop (1.84.0) sha256=88dec310153bb685a879f5a7cdb601f6287b8f0ee675d9dc63a17c7204c4190a
242
+ rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd
243
+ rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
244
+ ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
245
+ securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
246
+ simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5
247
+ simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246
248
+ simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
249
+ sqlite3 (2.9.0-aarch64-linux-gnu) sha256=cfe1e0216f46d7483839719bf827129151e6c680317b99d7b8fc1597a3e13473
250
+ sqlite3 (2.9.0-aarch64-linux-musl) sha256=56a35cb2d70779afc2ac191baf2c2148242285ecfed72f9b021218c5c4917913
251
+ sqlite3 (2.9.0-arm-linux-gnu) sha256=a19a21504b0d7c8c825fbbf37b358ae316b6bd0d0134c619874060b2eef05435
252
+ sqlite3 (2.9.0-arm-linux-musl) sha256=fca5b26197c70e3363115d3faaea34d7b2ad9c7f5fa8d8312e31b64e7556ee07
253
+ sqlite3 (2.9.0-arm64-darwin) sha256=a917bd9b84285766ff3300b7d79cd583f5a067594c8c1263e6441618c04a6ed3
254
+ sqlite3 (2.9.0-x86_64-darwin) sha256=59fe51baa3cb33c36d27ce78b4ed9360cd33ccca09498c2ae63850c97c0a6026
255
+ sqlite3 (2.9.0-x86_64-linux-gnu) sha256=72fff9bd750070ba3af695511ba5f0e0a2d8a9206f84869640b3e99dfaf3d5a5
256
+ sqlite3 (2.9.0-x86_64-linux-musl) sha256=ef716ba7a66d7deb1ccc402ac3a6d7343da17fac862793b7f0be3d2917253c90
257
+ stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
258
+ thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
259
+ timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af
260
+ tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
261
+ tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
262
+ unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
263
+ unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
264
+ yard (0.9.38) sha256=721fb82afb10532aa49860655f6cc2eaa7130889df291b052e1e6b268283010f
265
+ yardstick (0.9.9) sha256=c39a166a9a37c0b164dc1969c8e20fe158061079e97c95454ceb58d0515ec06e
266
+
267
+ BUNDLED WITH
268
+ 4.0.3
@@ -0,0 +1,11 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "irb"
6
+ gem "yardstick", "~> 0.9", require: false
7
+ gem "sqlite3", "~> 2.0"
8
+ gem "database_cleaner-active_record"
9
+ gem "activerecord", "~> 8.0.0"
10
+
11
+ gemspec path: "../"