rbcsv 0.1.8 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6081f5083fa0f62ff08812aed7b6ff8fe47fbbc2a2170fc3d5ff3a4c6ef21661
4
- data.tar.gz: a73748f6fefbf4a8fced9bf15f1f5db5ae3b4ef4fc11512e0f30a4ceb09b2e3f
3
+ metadata.gz: c08a56224baf175930ae9bdd61da9e29464dfb35f0336f5fcd234073d96d8200
4
+ data.tar.gz: f77af48e7ea72618f2e7b6476e87a78cd50f5641391f31fa571b5914d622ad5d
5
5
  SHA512:
6
- metadata.gz: f2bc15f8586443f6be96a47525688312938141f5d509fe1365b0c83c6e4776c2624678e4e2bdabb926b319875218d03e6e519e317acb42ab7749861197e72a8e
7
- data.tar.gz: c0e37e6c24bae12583a538f79b9a0bba74d9b7ce06b16198c9b8764de1a2dd87cbcd1ca0681f580b65220d2a9c532c98fe7cc6fe04ad72cd6fb5a403ead1024a
6
+ metadata.gz: f22832f042dbc8e1ccbed9bef74b05ba314484dc781d7fb3901d00d4f8bac85ebf9d2e68f2e4ec25669643b1a18dc831925ec5088e1a58e365705c313730ac99
7
+ data.tar.gz: cd35bf0419a08e31409210b759a584df0f3f851780530b1bdad724edaa58e357919833aab1097c256119be18ea8513a2381413ecb41ccf8efd11c07057b168f6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2025-10-04
4
+
5
+ ### Added
6
+ - **Type-aware CSV parsing**: New methods for automatic type conversion
7
+ - `parse_typed` and `parse_typed!` for string parsing with type detection
8
+ - `read_typed` and `read_typed!` for file reading with type detection
9
+ - Automatically converts numeric strings to Integer or Float types
10
+ - Preserves strings for non-numeric values
11
+ - **Performance benchmarks**: Comprehensive benchmark suite
12
+ - 2.4-3.8x faster than Ruby's standard CSV library for parse operations
13
+ - ~140x faster for type conversion compared to manual Ruby conversion
14
+ - Added benchmark results to README
15
+
16
+ ### Changed
17
+ - Improved README with cleaner, more concise documentation
18
+ - Added author information and contribution guidelines
19
+ - Updated API reference section for better clarity
20
+
21
+ ### Technical
22
+ - Added `CsvValue` enum for type-safe value handling
23
+ - Implemented efficient type detection algorithm (Integer → Float → String)
24
+ - Added comprehensive tests for type conversion functionality
25
+
3
26
  ## [0.1.8] - 2025-01-28
4
27
 
5
28
  ### Added
data/Cargo.lock CHANGED
@@ -276,7 +276,7 @@ checksum = "08f8d2924cf136a1315e2b4c7460a39f62ef11ee5d522df9b2750fab55b868b6"
276
276
 
277
277
  [[package]]
278
278
  name = "rbcsv"
279
- version = "0.1.0"
279
+ version = "0.2.0"
280
280
  dependencies = [
281
281
  "csv",
282
282
  "env_logger",
data/DEVELOPMENT.md CHANGED
@@ -85,6 +85,62 @@ puts File.read('/tmp/test_output.csv')
85
85
  # Alice,25,Tokyo
86
86
  # Bob,30,Osaka
87
87
 
88
+ #### CSV 型認識機能
89
+
90
+ ```bash
91
+ # 基本的な型認識パース
92
+ ruby -I lib -e "
93
+ require 'rbcsv'
94
+ csv_data = 'name,age,score\nAlice,25,85.5\nBob,30,92'
95
+ result = RbCsv.parse_typed(csv_data)
96
+ p result
97
+ puts \"Age type: #{result[1][1].class}\"
98
+ puts \"Score type: #{result[1][2].class}\"
99
+ "
100
+ # 期待される出力:
101
+ # [["name", "age", "score"], ["Alice", 25, 85.5], ["Bob", 30, 92]]
102
+ # Age type: Integer
103
+ # Score type: Float
104
+
105
+ # trim機能付き型認識パース
106
+ ruby -I lib -e "
107
+ require 'rbcsv'
108
+ csv_data = ' name , age , score \n Alice , 25 , 85.5 '
109
+ result = RbCsv.parse_typed!(csv_data)
110
+ p result
111
+ puts \"Age type: #{result[1][1].class}\"
112
+ "
113
+ # 期待される出力:
114
+ # [["name", "age", "score"], ["Alice", 25, 85.5]]
115
+ # Age type: Integer
116
+
117
+ # 型認識ファイル読み込み
118
+ ruby -I lib -e "
119
+ require 'rbcsv'
120
+ result = RbCsv.read_typed('spec/fixtures/test.csv')
121
+ p result[1] # 2行目のデータ
122
+ puts \"Age type: #{result[1][1].class}\"
123
+ "
124
+ # 期待される出力: ["Alice", 25, "Tokyo"] (ageが数値型)
125
+
126
+ # 型認識の詳細テスト
127
+ ruby -I lib -e "
128
+ require 'rbcsv'
129
+ test_data = 'type,value\ninteger,123\nfloat,45.6\nscientific,1.23e-4\nstring,hello\nempty,'
130
+ result = RbCsv.parse_typed(test_data)
131
+ result.each_with_index do |row, i|
132
+ next if i == 0 # ヘッダーをスキップ
133
+ value = row[1]
134
+ puts \"#{row[0]}: #{value.inspect} (#{value.class})\"
135
+ end
136
+ "
137
+ # 期待される出力:
138
+ # integer: 123 (Integer)
139
+ # float: 45.6 (Float)
140
+ # scientific: 0.000123 (Float)
141
+ # string: "hello" (String)
142
+ # empty: "" (String)
143
+
88
144
  # 書き込み→読み込みの往復テスト
89
145
  ruby -I lib -e "
90
146
  require 'rbcsv'
@@ -235,10 +291,10 @@ cd ../..
235
291
 
236
292
  ```bash
237
293
  # ベンチマーク実行
238
- ruby benchmark.rb
294
+ ruby examples/benchmarks/benchmark.rb
239
295
 
240
296
  # カスタムテストファイルでのテスト
241
- ruby test.rb
297
+ ruby examples/basic/basic_usage.rb
242
298
  ```
243
299
 
244
300
  ### コードスタイルチェック
@@ -260,16 +316,37 @@ cd ../..
260
316
 
261
317
  ```ruby
262
318
  # 関数ベースAPI(`!`サフィックスでtrim機能分離)
263
- RbCsv.parse(csv_string) # 通常のパース
264
- RbCsv.parse!(csv_string) # trim機能付きパース
265
- RbCsv.read(file_path) # 通常のファイル読み込み
266
- RbCsv.read!(file_path) # trim機能付きファイル読み込み
319
+
320
+ # 文字列専用パース(従来型)
321
+ RbCsv.parse(csv_string) # 通常のパース(すべて文字列)
322
+ RbCsv.parse!(csv_string) # trim機能付きパース(すべて文字列)
323
+
324
+ # 型認識パース(新機能 v0.1.8+)
325
+ RbCsv.parse_typed(csv_string) # 数値を数値型として返す
326
+ RbCsv.parse_typed!(csv_string) # trim + 数値を数値型として返す
327
+
328
+ # ファイル読み込み
329
+ RbCsv.read(file_path) # 通常のファイル読み込み(すべて文字列)
330
+ RbCsv.read!(file_path) # trim機能付きファイル読み込み(すべて文字列)
331
+ RbCsv.read_typed(file_path) # 型認識ファイル読み込み
332
+ RbCsv.read_typed!(file_path) # trim + 型認識ファイル読み込み
333
+
334
+ # ファイル書き込み
267
335
  RbCsv.write(file_path, data) # CSVファイル書き込み
268
336
 
269
337
  # データ形式
270
- data = [
338
+ # 従来型(すべて文字列)
339
+ string_data = [
271
340
  ["header1", "header2", "header3"], # ヘッダー行
272
- ["value1", "value2", "value3"], # データ行
341
+ ["value1", "value2", "value3"], # データ行(すべて文字列)
342
+ # ...
343
+ ]
344
+
345
+ # 型認識版(数値は数値型)
346
+ typed_data = [
347
+ ["name", "age", "score"], # ヘッダー行(文字列)
348
+ ["Alice", 25, 85.5], # データ行(文字列, 整数, 浮動小数点)
349
+ ["Bob", 30, 92], # データ行(文字列, 整数, 整数)
273
350
  # ...
274
351
  ]
275
352
  ```
@@ -288,12 +365,36 @@ RbCsv.parse!(csv_string) # trim版
288
365
  RbCsv.write(file_path, data) # 新機能
289
366
  ```
290
367
 
368
+ #### v0.1.8+(型認識機能追加)
369
+ ```ruby
370
+ RbCsv.parse_typed(csv_string) # 数値型自動変換
371
+ RbCsv.parse_typed!(csv_string) # trim + 数値型自動変換
372
+ RbCsv.read_typed(file_path) # ファイル読み込み + 数値型自動変換
373
+ RbCsv.read_typed!(file_path) # trim + ファイル読み込み + 数値型自動変換
374
+ ```
375
+
291
376
  ### 実装アーキテクチャ
292
377
 
293
378
  1. **parser.rs**: CSV解析・書き込みコア機能、エラーハンドリング
294
- 2. **ruby_api.rs**: Ruby API関数、Magnus バインディング
295
- 3. **lib.rs**: Magnus初期化と関数登録
296
- 4. **error.rs**: 包括的なエラーハンドリングとRuby例外変換
379
+ 2. **value.rs**: CSV値の型定義(CsvValue enum)と型変換ロジック
380
+ 3. **ruby_api.rs**: Ruby API関数、Magnus バインディング
381
+ 4. **lib.rs**: Magnus初期化と関数登録
382
+ 5. **error.rs**: 包括的なエラーハンドリングとRuby例外変換
383
+
384
+ #### モジュール詳細
385
+
386
+ **parser.rs**
387
+ - 文字列専用関数: `parse_csv_core`, `parse_csv_file`, `write_csv_file`
388
+ - 型認識関数: `parse_csv_typed`, `parse_csv_file_typed`
389
+
390
+ **value.rs**
391
+ - `CsvValue` enum: Integer(i64), Float(f64), String(String)
392
+ - 型変換メソッド: `from_str`, `from_str_trimmed`, `to_ruby`
393
+ - 優先順位: 整数 → 浮動小数点 → 文字列
394
+
395
+ **ruby_api.rs**
396
+ - 文字列版: `parse`, `parse_trim`, `read`, `read_trim`, `write`
397
+ - 型認識版: `parse_typed`, `parse_typed_trim`, `read_typed`, `read_typed_trim`
297
398
 
298
399
  ### 開発時の重要な注意点
299
400
 
@@ -455,9 +556,18 @@ cargo doc --open
455
556
  ### テスト戦略
456
557
 
457
558
  1. **単体テスト**: 各Rustモジュールに対するcargo test
559
+ - `value.rs`: 型変換ロジックの単体テスト
560
+ - `parser.rs`: CSV解析・型認識機能の単体テスト
458
561
  2. **統合テスト**: Ruby APIレベルでのRSpecテスト
562
+ - 基本的なCSV処理機能
563
+ - 型認識機能(parse_typed, read_typed系)
564
+ - エラーハンドリング
459
565
  3. **パフォーマンステスト**: 大きなCSVファイルでのベンチマーク
460
566
  4. **エッジケーステスト**: 不正なCSV、空ファイル、エンコーディング問題
567
+ 5. **型認識テスト**: 数値文字列の正確な型変換
568
+ - 整数、浮動小数点、科学記法
569
+ - 混在型のCSVデータ
570
+ - trim機能との組み合わせ
461
571
 
462
572
  ### デバッグ
463
573
 
data/README.md CHANGED
@@ -1,27 +1,23 @@
1
1
  # RbCsv
2
2
 
3
- A fast CSV processing library for Ruby, built with Rust for high performance. RbCsv provides simple, efficient methods for parsing CSV strings, reading CSV files, and writing CSV data to files.
3
+ Fast CSV library for Ruby powered by Rust.
4
4
 
5
5
  ## Installation
6
6
 
7
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
7
+ Add this line to your Gemfile:
8
8
 
9
- Install the gem and add to the application's Gemfile by executing:
10
-
11
- ```bash
12
- bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
9
+ ```ruby
10
+ gem 'rbcsv'
13
11
  ```
14
12
 
15
- If bundler is not being used to manage dependencies, install the gem by executing:
13
+ Or install directly:
16
14
 
17
15
  ```bash
18
- gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
16
+ gem install rbcsv
19
17
  ```
20
18
 
21
19
  ## Usage
22
20
 
23
- ### Parsing CSV strings
24
-
25
21
  ```ruby
26
22
  require 'rbcsv'
27
23
 
@@ -30,75 +26,101 @@ csv_data = "name,age,city\nAlice,25,Tokyo\nBob,30,Osaka"
30
26
  result = RbCsv.parse(csv_data)
31
27
  # => [["name", "age", "city"], ["Alice", "25", "Tokyo"], ["Bob", "30", "Osaka"]]
32
28
 
33
- # Parse CSV with automatic whitespace trimming
34
- csv_with_spaces = " name , age , city \n Alice , 25 , Tokyo "
35
- result = RbCsv.parse!(csv_with_spaces)
36
- # => [["name", "age", "city"], ["Alice", "25", "Tokyo"]]
37
- ```
38
-
39
- ### Reading CSV files
29
+ # Parse with whitespace trimming
30
+ result = RbCsv.parse!(" name , age \n Alice , 25 ")
31
+ # => [["name", "age"], ["Alice", "25"]]
40
32
 
41
- ```ruby
42
- # Read CSV file
33
+ # Read from file
43
34
  result = RbCsv.read("data.csv")
44
- # => [["name", "age", "city"], ["Alice", "25", "Tokyo"], ["Bob", "30", "Osaka"]]
45
-
46
- # Read CSV file with automatic whitespace trimming
47
- result = RbCsv.read!("data_with_spaces.csv")
48
- # => [["name", "age", "city"], ["Alice", "25", "Tokyo"], ["Bob", "30", "Osaka"]]
49
- ```
50
-
51
- ### Writing CSV files
52
35
 
53
- ```ruby
54
- # Prepare data
55
- data = [
56
- ["name", "age", "city"],
57
- ["Alice", "25", "Tokyo"],
58
- ["Bob", "30", "Osaka"]
59
- ]
60
-
61
- # Write CSV data to file
36
+ # Write to file
37
+ data = [["name", "age"], ["Alice", "25"], ["Bob", "30"]]
62
38
  RbCsv.write("output.csv", data)
63
- # Creates a file with:
64
- # name,age,city
65
- # Alice,25,Tokyo
66
- # Bob,30,Osaka
67
- ```
68
-
69
- ### Error Handling
70
-
71
- RbCsv provides detailed error messages for various scenarios:
72
-
73
- ```ruby
74
- # Empty data
75
- RbCsv.write("output.csv", [])
76
- # => RuntimeError: Invalid Data Error: CSV data is empty
77
-
78
- # Inconsistent field count
79
- data = [["name", "age"], ["Alice", "25", "Tokyo"]] # 3 fields in second row
80
- RbCsv.write("output.csv", data)
81
- # => RuntimeError: Invalid Data Error: Field count mismatch at line 2: expected 2 fields, got 3 fields
82
39
 
83
- # File not found
84
- RbCsv.read("nonexistent.csv")
85
- # => RuntimeError: IO Error: File not found: nonexistent.csv
40
+ # Type-aware parsing (converts numbers automatically)
41
+ result = RbCsv.parse_typed("name,age,score\nAlice,25,85.5")
42
+ # => [["name", "age", "score"], ["Alice", 25, 85.5]]
86
43
  ```
87
44
 
88
- ## Development
89
-
90
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
45
+ ## API Reference
46
+
47
+ ### Basic Methods
48
+ - `RbCsv.parse(string)` - Parse CSV string
49
+ - `RbCsv.parse!(string)` - Parse with trimming
50
+ - `RbCsv.read(filepath)` - Read CSV file
51
+ - `RbCsv.read!(filepath)` - Read with trimming
52
+ - `RbCsv.write(filepath, data)` - Write CSV file
53
+
54
+ ### Type-aware Methods
55
+ - `RbCsv.parse_typed(string)` - Parse with type conversion
56
+ - `RbCsv.parse_typed!(string)` - Parse with trimming and type conversion
57
+ - `RbCsv.read_typed(filepath)` - Read with type conversion
58
+ - `RbCsv.read_typed!(filepath)` - Read with trimming and type conversion
59
+
60
+ ## Benchmark
61
+
62
+ Currently, we achieve 2.4 to 3.8 times faster processing for parse operations, with even greater speed improvements for type conversion.
63
+
64
+ Compared to casting to arbitrary forms using Ruby methods, parse_typed with pre-defined type conversion delivers approximately 140 times faster results.
65
+
66
+ *exec data 2025/10/04*
67
+ ```sh
68
+ % ruby examples/benchmarks/benchmark.rb
69
+
70
+ file: bench.csv
71
+ file size: 16457 bytes
72
+ recode: 100
73
+ 🚀 parse (1000 times)
74
+ --------------------------------------------------
75
+ user system total real
76
+ Ruby CSV.parse 0.258438 0.002993 0.261431 ( 0.261500)
77
+ Ruby CSV.parse (headers: true) 0.329098 0.001348 0.330446 ( 0.330398)
78
+ RbCsv.parse 0.085052 0.000358 0.085410 ( 0.085403)
79
+ RbCsv.parse! (with trim) 0.112470 0.000246 0.112716 ( 0.112703)
80
+ RbCsv.parse_typed 0.096728 0.000512 0.097240 ( 0.097227)
81
+ RbCsv.parse_typed! (typed + trim) 0.128616 0.000478 0.129094 ( 0.129075)
82
+
83
+ 📁 read (1000 times)
84
+ --------------------------------------------------
85
+ user system total real
86
+ Ruby CSV.read 0.273029 0.030768 0.303797 ( 0.398752)
87
+ Ruby CSV.read (headers: true) 0.360198 0.027133 0.387331 ( 0.478200)
88
+ RbCsv.read 0.088287 0.021659 0.109946 ( 0.169075)
89
+ RbCsv.read! (with trim) 0.119157 0.016301 0.135458 ( 0.149894)
90
+ RbCsv.read_typed 0.105971 0.016317 0.122288 ( 0.136625)
91
+ RbCsv.read_typed! (typed + trim) 0.137821 0.017739 0.155560 ( 0.174861)
92
+
93
+ ✏️ write (1000 times)
94
+ --------------------------------------------------
95
+ user system total real
96
+ Ruby CSV.open (write) 0.409897 0.355344 0.765241 ( 1.894642)
97
+ RbCsv.write 0.097875 0.505652 0.603527 ( 1.595586)
98
+
99
+ test data createing
100
+ ccreated: large_sample.csv (831947 bytes)
101
+ size: 831947 bytes
102
+
103
+ 🔢 parse_typed (1000 times )
104
+ --------------------------------------------------
105
+ user system total real
106
+ Manual conversion (CSV) 6.093143 0.011365 6.104508 ( 6.104026)
107
+ Manual conversion (RbCsv) 6.217609 0.023237 6.240846 ( 6.287587)
108
+ Automatic conversion (RbCsv typed) 0.000041 0.000001 0.000042 ( 0.000041)
109
+ ```
91
110
 
92
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
93
111
 
94
112
  ## Contributing
95
113
 
96
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/r_csv. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/r_csv/blob/master/CODE_OF_CONDUCT.md).
114
+ Found a bug or have a suggestion? Please open an issue on [GitHub](https://github.com/fujitanisora/r_csv/issues).
97
115
 
98
- ## License
116
+ Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
117
+
118
+ ## Author
99
119
 
100
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
120
+ **Fujitani Sora**
121
+ 📧 fujitanisora0414@gmail.com
122
+ 🐙 [@fujitanisora](https://github.com/fujitanisora)
101
123
 
102
- ## Code of Conduct
124
+ ## License
103
125
 
104
- Everyone interacting in the RCsv project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/r_csv/blob/master/CODE_OF_CONDUCT.md).
126
+ MIT License. See [LICENSE](https://opensource.org/licenses/MIT) for details.
@@ -0,0 +1,124 @@
1
+ # Gem Version Upgrade Execution Guide for AI Agent
2
+
3
+ ## Purpose
4
+ This document provides step-by-step instructions for AI agents to automatically upgrade and release a new version of the rbcsv gem.
5
+
6
+ ## Prerequisites Check
7
+ 1. Verify current directory is project root: `/Users/fujitanisora/dev/oss/r_csv`
8
+ 2. Ensure git repository is clean: `git status` should show no uncommitted changes
9
+ 3. Confirm on main branch: `git branch --show-current` should return `main`
10
+
11
+ ## Step-by-Step Instructions
12
+
13
+ ### 1. Update Version Number
14
+ **File:** `lib/rbcsv/version.rb`
15
+ **Action:** Increment version following semantic versioning (MAJOR.MINOR.PATCH)
16
+ - PATCH: Bug fixes only (0.1.4 � 0.1.5)
17
+ - MINOR: New features, backward compatible (0.1.4 � 0.2.0)
18
+ - MAJOR: Breaking changes (0.1.4 � 1.0.0)
19
+
20
+ ### 2. Update CHANGELOG.md
21
+ **File:** `CHANGELOG.md`
22
+ **Action:** Add new version section at the top with:
23
+ ```markdown
24
+ ## [VERSION] - YYYY-MM-DD
25
+ ### Added
26
+ - New features
27
+
28
+ ### Changed
29
+ - Modified features
30
+
31
+ ### Fixed
32
+ - Bug fixes
33
+
34
+ ### Removed
35
+ - Deprecated features
36
+ ```
37
+
38
+ ### 3. Run Tests
39
+ **Commands:**
40
+ ```bash
41
+ # Run Rust tests
42
+ cd ext/rbcsv && cargo test && cd ../..
43
+
44
+ # Run Ruby tests
45
+ bundle exec rspec
46
+
47
+ # Run linter
48
+ bundle exec rubocop
49
+ ```
50
+ **Verify:** All tests must pass before proceeding
51
+
52
+ ### 4. Build Rust Extension
53
+ **Commands:**
54
+ ```bash
55
+ cd ext/rbcsv
56
+ cargo build --release
57
+ cd ../..
58
+ bundle exec rake compile
59
+ ```
60
+ **Verify:** Build completes without errors
61
+
62
+ ### 5. Build Gem
63
+ **Command:** `gem build rbcsv.gemspec`
64
+ **Verify:** New .gem file created (e.g., rbcsv-0.1.5.gem)
65
+
66
+ ### 6. Test Local Installation
67
+ **Commands:**
68
+ ```bash
69
+ # Install locally
70
+ gem install ./rbcsv-*.gem
71
+
72
+ # Test in IRB
73
+ ruby -e "require 'rbcsv'; puts RbCsv::VERSION; puts RbCsv.parse('a,b\n1,2').inspect"
74
+ ```
75
+ **Verify:** Version matches and basic functionality works
76
+
77
+ ### 7. Create Git Commit
78
+ **Commands:**
79
+ ```bash
80
+ git add -A
81
+ git commit -m "Release version X.Y.Z
82
+
83
+ - [List key changes here]
84
+ "
85
+ git tag -a vX.Y.Z -m "Version X.Y.Z"
86
+ ```
87
+
88
+ ### 8. Push to Repository
89
+ **Commands:**
90
+ ```bash
91
+ git push origin main
92
+ git push origin --tags
93
+ ```
94
+
95
+ ### 9. Publish to RubyGems (Optional)
96
+ **Command:** `gem push rbcsv-X.Y.Z.gem`
97
+ **Note:** Requires RubyGems.org credentials
98
+
99
+ ## Validation Checklist
100
+ - [ ] Version updated in version.rb
101
+ - [ ] CHANGELOG.md updated with release notes
102
+ - [ ] All tests passing (Rust and Ruby)
103
+ - [ ] Gem builds successfully
104
+ - [ ] Local installation works
105
+ - [ ] Git commit and tag created
106
+ - [ ] Changes pushed to repository
107
+
108
+ ## Rollback Instructions
109
+ If any step fails:
110
+ 1. `git reset --hard HEAD~1` (if committed)
111
+ 2. `git tag -d vX.Y.Z` (if tagged)
112
+ 3. Delete generated .gem file
113
+ 4. Fix issues and restart process
114
+
115
+ ## Error Handling
116
+ - If tests fail: Fix bugs before proceeding
117
+ - If build fails: Check Rust/Ruby environment setup
118
+ - If gem push fails: Verify RubyGems credentials
119
+
120
+ ## Success Confirmation
121
+ After completion, verify:
122
+ 1. New version tag visible on GitHub
123
+ 2. Gem file exists in project root
124
+ 3. Version accessible via: `ruby -e "require 'rbcsv'; puts RbCsv::VERSION"`