smarter_csv 1.17.1 → 1.17.3

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.
data/UPGRADING.md ADDED
@@ -0,0 +1,251 @@
1
+ # Upgrading SmarterCSV
2
+
3
+ > [!TIP]
4
+ > Prefer the interactive [Upgrade Wizard](https://tilo.github.io/smarter_csv/upgrade_wizard.html) for a guided walk-through with Yes/No questions.
5
+ > This document is auto-generated from `CHANGELOG.md` and `docs/upgrade_path.json` by `bin/gen-upgrading-md`.
6
+
7
+ ## How to use this guide
8
+
9
+ 1. Find your current version below. **Newest releases appear first; older ones further down.**
10
+ 2. Read each series section between yours and the latest at the top. For each one, check whether any **If** conditions apply to your code.
11
+ 3. If none apply, you can upgrade all the way through that series with no code changes.
12
+
13
+ Prefer an interactive walk-through? The [Upgrade Wizard](https://tilo.github.io/smarter_csv/upgrade_wizard.html) asks one question at a time and only shows the migration steps that apply to your code.
14
+
15
+ **Latest release:** `1.17.3` (in the `1.17.x` series).
16
+
17
+ ---
18
+
19
+ ## 1.17.x — latest series
20
+
21
+ **Versions in this series:**
22
+ [1.17.0, 1.17.1, 1.17.2, 1.17.3]
23
+
24
+ **Latest release:** `1.17.3`
25
+
26
+ Update your Gemfile to:
27
+
28
+ ```ruby
29
+ gem 'smarter_csv', '~> 1.17.0'
30
+ ```
31
+
32
+ Then run `bundle update smarter_csv`.
33
+
34
+ ## Series 1.16 → 1.17
35
+
36
+ **Coming from any 1.16 version:**
37
+ [1.16.0, 1.16.1, 1.16.2, 1.16.3, 1.16.4, 1.16.5, 1.16.6]
38
+
39
+ > ⚠️ **In-series notes** worth checking if you're upgrading through one of these:
40
+ > - **1.16.1:** **Fibers:** `SmarterCSV.errors` uses `Thread.current` for storage, which is **shared across all fibers running in the same thread**. If you process CSV files concurrently in fibers (e.g. with `Async`, `Falcon`, or manual `Fiber` scheduling), `SmarterCSV.errors` may return stale or wrong results. **Use `SmarterCSV::Reader` directly** — errors are scoped to the reader instance and are always correct regardless of fiber context.
41
+ > - **1.16.2:** If your code references auto-generated keys for blank headers, update those to use the absolute column position.
42
+
43
+ **Upgrading to 1.17.x** (latest: `1.17.3`): you can upgrade all the way — no code changes needed.
44
+
45
+ ---
46
+
47
+ ## Series 1.15 → 1.16
48
+
49
+ **Coming from any 1.15 version:**
50
+ [1.15.0, 1.15.1, 1.15.2, 1.15.3]
51
+
52
+ **Upgrading to 1.16.x** (latest: `1.16.6`):
53
+
54
+ - **If** your CSV files contain stray `"` characters in the middle of unquoted fields:
55
+ → verify the output is now correct — 1.16.0 treats them as literal (RFC 4180). Output gets more correct for almost everyone; the temporary escape hatch `quote_boundary: :legacy` exists if your downstream code depended on the previously-corrupted output (not recommended for new code).
56
+
57
+ ---
58
+
59
+ ## Series 1.14 → 1.15
60
+
61
+ **Coming from any 1.14 version:**
62
+ [1.14.0, 1.14.1, 1.14.2, 1.14.3, 1.14.4]
63
+
64
+ **Upgrading to 1.15.x** (latest: `1.15.3`):
65
+
66
+ - **If** your Ruby version is 2.5 or older:
67
+ → upgrade Ruby to 2.6 or newer — 1.15.0 dropped support for Ruby 2.5.
68
+
69
+ The migration is small: Ruby 2.5 reached end-of-life in March 2021 (no more security fixes anywhere), and Ruby 2.5 → 2.6 is API-compatible for nearly all code. Update your `.ruby-version` or the `ruby` line in your `Gemfile`, run `bundle install`, and you're done. Most users jump straight to a current Ruby (3.x).
70
+
71
+ ---
72
+
73
+ ## Series 1.13 → 1.14
74
+
75
+ **Coming from any 1.13 version:**
76
+ [1.13.0, 1.13.1]
77
+
78
+ **Upgrading to 1.14.x** (latest: `1.14.4`): you can upgrade all the way — no code changes needed.
79
+
80
+ ---
81
+
82
+ ## Series 1.12 → 1.13
83
+
84
+ **Coming from any 1.12 version:**
85
+ [1.12.0, 1.12.1]
86
+
87
+ **Upgrading to 1.13.x** (latest: `1.13.1`):
88
+
89
+ - **If** your CSV rows can have more columns than the header AND your code expects only header-listed keys:
90
+ → filter out the new auto-generated `:column_N` keys, or pass `strict: true` to raise on extras — 1.13.0 keeps extra columns instead of dropping them silently.
91
+
92
+ - **If** any of your input files might have unbalanced quotes:
93
+ → wrap calls in `rescue SmarterCSV::MalformedCSV` — 1.13.0 now raises instead of producing garbled output.
94
+
95
+ - **If** you pass `user_provided_headers:` AND your file has a header line that should be skipped:
96
+ → also pass `headers_in_file: true` explicitly — 1.13.0 made `user_provided_headers:` imply `headers_in_file: false` by default.
97
+
98
+ ---
99
+
100
+ ## Series 1.11 → 1.12
101
+
102
+ **Coming from any 1.11 version:**
103
+ [1.11.0, 1.11.2]
104
+
105
+ **Upgrading to 1.12.x** (latest: `1.12.1`):
106
+
107
+ - **If** you call `SmarterCSV.process` and need to inspect headers / warnings / errors after parsing:
108
+ → switch to using `reader = SmarterCSV::Reader.new(file, options); reader.process`.
109
+
110
+ Version 1.11 class-level accessors `SmarterCSV.headers` / `SmarterCSV.raw_header` are gone in 1.12.0 — if you used those, see the next question.
111
+
112
+ - **If** you call `SmarterCSV.raw_headers` or `SmarterCSV.headers`:
113
+ → switch to instantiating `SmarterCSV::Reader` and reading `reader.raw_headers` / `reader.headers` — 1.12.0 moved these off the class-level API.
114
+
115
+ ---
116
+
117
+ ## Series 1.10 → 1.11
118
+
119
+ **Coming from any 1.10 version:**
120
+ [1.10.0, 1.10.1, 1.10.2, 1.10.3]
121
+
122
+ **Upgrading to 1.11.x** (latest: `1.11.2`): you can upgrade all the way — no code changes needed.
123
+
124
+ ---
125
+
126
+ ## Series 1.9 → 1.10
127
+
128
+ **Coming from any 1.9 version:**
129
+ [1.9.0, 1.9.2, 1.9.3]
130
+
131
+ **Upgrading to 1.10.x** (latest: `1.10.3`):
132
+
133
+ - **If** you use `user_provided_headers:`:
134
+ → write the list in the exact final form you want (all symbols *or* all strings) — 1.10.0 stopped applying additional transformations. `strings_as_keys:` is ignored alongside it.
135
+
136
+ - **If** your `user_provided_headers:` list contains duplicate entries:
137
+ → remove the duplicates — 1.10.0 raises `SmarterCSV::DuplicateHeaders`.
138
+
139
+ - **If** you depended on duplicate-header detection failing fast:
140
+ → pass `duplicate_header_suffix: nil` explicitly — 1.10.0 changed the default to `''` (it auto-disambiguates duplicates as `name`, `name2`, ...).
141
+
142
+ ---
143
+
144
+ ## Series 1.8 → 1.9
145
+
146
+ **Coming from any 1.8 version:**
147
+ [1.8.0, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.8.5]
148
+
149
+ **Upgrading to 1.9.x** (latest: `1.9.3`):
150
+
151
+ - **If** you rescue `SmarterCSV::MissingHeaders`:
152
+ → rename it to `SmarterCSV::MissingKeys` — 1.9.0 renamed the error.
153
+
154
+ - **If** you use `key_mapping:` and want to allow some mapped headers to be missing:
155
+ → pass `silence_missing_keys: true` — 1.9.0 now raises `MissingKeys` for unmapped headers (this makes them optional).
156
+
157
+ ---
158
+
159
+ ## Series 1.7 → 1.8
160
+
161
+ **Coming from any 1.7 version:**
162
+ [1.7.0.pre1, 1.7.0.pre5, 1.7.1, 1.7.2, 1.7.3, 1.7.4]
163
+
164
+ **Upgrading to 1.8.x** (latest: `1.8.5`):
165
+
166
+ - **If** you accept CSV files from users or other external sources where the column separator might not be a comma (e.g. locale-specific exports using `;` or tab), or where a file might have only one column:
167
+ → wrap your `SmarterCSV.process` calls in `rescue SmarterCSV::NoColSepDetected` — 1.8.0 made `col_sep: :auto` and `row_sep: :auto` the new defaults, but in rare cases it raises when separators could not be found.
168
+
169
+ ---
170
+
171
+ ## Series 1.6 → 1.7
172
+
173
+ **Coming from any 1.6 version:**
174
+ [1.6.0, 1.6.1]
175
+
176
+ **Upgrading to 1.7.x** (latest: `1.7.4`): you can upgrade all the way — no code changes needed.
177
+
178
+ ---
179
+
180
+ ## Series 1.5 → 1.6
181
+
182
+ **Coming from any 1.5 version:**
183
+ [1.5.0, 1.5.1, 1.5.2]
184
+
185
+ **Upgrading to 1.6.x** (latest: `1.6.1`):
186
+
187
+ - **If** you rescue an exception when `key_mapping:` has an unused key:
188
+ → remove that rescue clause — 1.6.1 changed this from an exception to a warning.
189
+
190
+ ---
191
+
192
+ ## Series 1.4 → 1.5
193
+
194
+ **Coming from any 1.4 version:**
195
+ [1.4.0, 1.4.2]
196
+
197
+ **Upgrading to 1.5.x** (latest: `1.5.2`):
198
+
199
+ - **If** you relied on lines starting with `#` being treated as comments:
200
+ → pass `comment_regexp: /\A#/` explicitly — 1.5.0 changed the default to `nil`.
201
+
202
+ ---
203
+
204
+ ## Series 1.3 → 1.4
205
+
206
+ **Coming from any 1.3 version:**
207
+ [1.3.0]
208
+
209
+ **Upgrading to 1.4.x** (latest: `1.4.2`): you can upgrade all the way — no code changes needed.
210
+
211
+ ---
212
+
213
+ ## Series 1.2 → 1.3
214
+
215
+ **Coming from any 1.2 version:**
216
+ [1.2.0, 1.2.3, 1.2.4, 1.2.5, 1.2.6, 1.2.7, 1.2.8]
217
+
218
+ **Upgrading to 1.3.x** (latest: `1.3.0`):
219
+
220
+ - **If** you use `key_mapping:`:
221
+ → switch hash values to symbols (or update downstream reads to use string keys) — 1.3.0 stopped silently coercing values to symbols.
222
+
223
+ ---
224
+
225
+ ## Series 1.1 → 1.2
226
+
227
+ **Coming from any 1.1 version:**
228
+ [1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5]
229
+
230
+ **Upgrading to 1.2.x** (latest: `1.2.8`):
231
+
232
+ - **If** your CSV files have duplicate header names:
233
+ → rename the duplicates, or be ready to rescue `SmarterCSV::DuplicateHeaders` — 1.2.0 added default validation that each header appears only once and raises this exception when it doesn't.
234
+
235
+ ---
236
+
237
+ ## Series 1.0 → 1.1
238
+
239
+ **Coming from any 1.0 version:**
240
+ [1.0.0.pre1, 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4, 1.0.5, 1.0.6, 1.0.7, 1.0.8, 1.0.9, 1.0.10, 1.0.11, 1.0.12, 1.0.14, 1.0.15, 1.0.16, 1.0.17, 1.0.18, 1.0.19]
241
+
242
+ **Upgrading to 1.1.x** (latest: `1.1.5`):
243
+
244
+ - **If** you set `headers_in_file: false`:
245
+ → also provide `user_provided_headers:` — 1.1.0 now raises an error if you set the former without the latter.
246
+
247
+ ---
248
+
249
+ ---
250
+
251
+ Questions? Open an issue: <https://github.com/tilo/smarter_csv/issues>.
data/docs/.nojekyll ADDED
File without changes
@@ -0,0 +1,175 @@
1
+ {
2
+ "latest": "1.17",
3
+ "latest_release": "1.17.2",
4
+ "path": {
5
+ "1.0": {
6
+ "to": "1.1",
7
+ "latest_release": "1.0.19",
8
+ "actions": [
9
+ {
10
+ "if": "you set <code>headers_in_file: false</code>",
11
+ "then": "also provide <code>user_provided_headers:</code> &mdash; 1.1.0 now raises an error if you set the former without the latter."
12
+ }
13
+ ]
14
+ },
15
+ "1.1": {
16
+ "to": "1.2",
17
+ "latest_release": "1.1.5",
18
+ "actions": [
19
+ {
20
+ "if": "your CSV files have duplicate header names",
21
+ "then": "rename the duplicates, or be ready to rescue <code>SmarterCSV::DuplicateHeaders</code> &mdash; 1.2.0 added default validation that each header appears only once and raises this exception when it doesn't."
22
+ }
23
+ ]
24
+ },
25
+ "1.2": {
26
+ "to": "1.3",
27
+ "latest_release": "1.2.8",
28
+ "actions": [
29
+ {
30
+ "if": "you use <code>key_mapping:</code>",
31
+ "then": "switch hash values to symbols (or update downstream reads to use string keys) &mdash; 1.3.0 stopped silently coercing values to symbols."
32
+ }
33
+ ]
34
+ },
35
+ "1.3": {
36
+ "to": "1.4",
37
+ "latest_release": "1.3.0",
38
+ "actions": []
39
+ },
40
+ "1.4": {
41
+ "to": "1.5",
42
+ "latest_release": "1.4.2",
43
+ "actions": [
44
+ {
45
+ "if": "you relied on lines starting with <code>#</code> being treated as comments",
46
+ "then": "pass <code>comment_regexp: /\\A#/</code> explicitly &mdash; 1.5.0 changed the default to <code>nil</code>."
47
+ }
48
+ ]
49
+ },
50
+ "1.5": {
51
+ "to": "1.6",
52
+ "latest_release": "1.5.2",
53
+ "actions": [
54
+ {
55
+ "if": "you rescue an exception when <code>key_mapping:</code> has an unused key",
56
+ "then": "remove that rescue clause &mdash; 1.6.1 changed this from an exception to a warning."
57
+ }
58
+ ]
59
+ },
60
+ "1.6": {
61
+ "to": "1.7",
62
+ "latest_release": "1.6.1",
63
+ "actions": []
64
+ },
65
+ "1.7": {
66
+ "to": "1.8",
67
+ "latest_release": "1.7.4",
68
+ "actions": [
69
+ {
70
+ "if": "you accept CSV files from users or other external sources where the column separator might not be a comma (e.g. locale-specific exports using <code>;</code> or tab), or where a file might have only one column",
71
+ "then": "wrap your <code>SmarterCSV.process</code> calls in <code>rescue SmarterCSV::NoColSepDetected</code> &mdash; 1.8.0 made <code>col_sep: :auto</code> and <code>row_sep: :auto</code> the new defaults, but in rare cases it raises when separators could not be found."
72
+ }
73
+ ]
74
+ },
75
+ "1.8": {
76
+ "to": "1.9",
77
+ "latest_release": "1.8.5",
78
+ "actions": [
79
+ {
80
+ "if": "you rescue <code>SmarterCSV::MissingHeaders</code>",
81
+ "then": "rename it to <code>SmarterCSV::MissingKeys</code> &mdash; 1.9.0 renamed the error."
82
+ },
83
+ {
84
+ "if": "you use <code>key_mapping:</code> and want to allow some mapped headers to be missing",
85
+ "then": "pass <code>silence_missing_keys: true</code> &mdash; 1.9.0 now raises <code>MissingKeys</code> for unmapped headers (this makes them optional)."
86
+ }
87
+ ]
88
+ },
89
+ "1.9": {
90
+ "to": "1.10",
91
+ "latest_release": "1.9.3",
92
+ "actions": [
93
+ {
94
+ "if": "you use <code>user_provided_headers:</code>",
95
+ "then": "write the list in the exact final form you want (all symbols <em>or</em> all strings) &mdash; 1.10.0 stopped applying additional transformations. <code>strings_as_keys:</code> is ignored alongside it."
96
+ },
97
+ {
98
+ "if": "your <code>user_provided_headers:</code> list contains duplicate entries",
99
+ "then": "remove the duplicates &mdash; 1.10.0 raises <code>SmarterCSV::DuplicateHeaders</code>."
100
+ },
101
+ {
102
+ "if": "you depended on duplicate-header detection failing fast",
103
+ "then": "pass <code>duplicate_header_suffix: nil</code> explicitly &mdash; 1.10.0 changed the default to <code>''</code> (it auto-disambiguates duplicates as <code>name</code>, <code>name2</code>, ...)."
104
+ }
105
+ ]
106
+ },
107
+ "1.10": {
108
+ "to": "1.11",
109
+ "latest_release": "1.10.3",
110
+ "actions": []
111
+ },
112
+ "1.11": {
113
+ "to": "1.12",
114
+ "latest_release": "1.11.2",
115
+ "actions": [
116
+ {
117
+ "if": "you call <code>SmarterCSV.process</code> and need to inspect headers / warnings / errors after parsing",
118
+ "then": "switch to using <code>reader = SmarterCSV::Reader.new(file, options); reader.process</code>.<br>Version 1.11 class-level accessors <code>SmarterCSV.headers</code> / <code>SmarterCSV.raw_header</code> are gone in 1.12.0 &mdash; if you used those, see the next question."
119
+ },
120
+ {
121
+ "if": "you call <code>SmarterCSV.raw_headers</code> or <code>SmarterCSV.headers</code>",
122
+ "then": "switch to instantiating <code>SmarterCSV::Reader</code> and reading <code>reader.raw_headers</code> / <code>reader.headers</code> &mdash; 1.12.0 moved these off the class-level API."
123
+ }
124
+ ]
125
+ },
126
+ "1.12": {
127
+ "to": "1.13",
128
+ "latest_release": "1.12.1",
129
+ "actions": [
130
+ {
131
+ "if": "your CSV rows can have more columns than the header AND your code expects only header-listed keys",
132
+ "then": "filter out the new auto-generated <code>:column_N</code> keys, or pass <code>strict: true</code> to raise on extras &mdash; 1.13.0 keeps extra columns instead of dropping them silently."
133
+ },
134
+ {
135
+ "if": "any of your input files might have unbalanced quotes",
136
+ "then": "wrap calls in <code>rescue SmarterCSV::MalformedCSV</code> &mdash; 1.13.0 now raises instead of producing garbled output."
137
+ },
138
+ {
139
+ "if": "you pass <code>user_provided_headers:</code> AND your file has a header line that should be skipped",
140
+ "then": "also pass <code>headers_in_file: true</code> explicitly &mdash; 1.13.0 made <code>user_provided_headers:</code> imply <code>headers_in_file: false</code> by default."
141
+ }
142
+ ]
143
+ },
144
+ "1.13": {
145
+ "to": "1.14",
146
+ "latest_release": "1.13.1",
147
+ "actions": []
148
+ },
149
+ "1.14": {
150
+ "to": "1.15",
151
+ "latest_release": "1.14.4",
152
+ "actions": [
153
+ {
154
+ "if": "your Ruby version is 2.5 or older",
155
+ "then": "upgrade Ruby to 2.6 or newer &mdash; 1.15.0 dropped support for Ruby 2.5.<br><br>The migration is small: Ruby 2.5 reached end-of-life in March 2021 (no more security fixes anywhere), and Ruby 2.5 &rarr; 2.6 is API-compatible for nearly all code. Update your <code>.ruby-version</code> or the <code>ruby</code> line in your <code>Gemfile</code>, run <code>bundle install</code>, and you're done. Most users jump straight to a current Ruby (3.x)."
156
+ }
157
+ ]
158
+ },
159
+ "1.15": {
160
+ "to": "1.16",
161
+ "latest_release": "1.15.3",
162
+ "actions": [
163
+ {
164
+ "if": "your CSV files contain stray <code>\"</code> characters in the middle of unquoted fields",
165
+ "then": "verify the output is now correct &mdash; 1.16.0 treats them as literal (RFC 4180). Output gets more correct for almost everyone; the temporary escape hatch <code>quote_boundary: :legacy</code> exists if your downstream code depended on the previously-corrupted output (not recommended for new code)."
166
+ }
167
+ ]
168
+ },
169
+ "1.16": {
170
+ "to": "1.17",
171
+ "latest_release": "1.16.6",
172
+ "actions": []
173
+ }
174
+ }
175
+ }