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 +4 -4
- data/CHANGELOG.md +23 -0
- data/Cargo.lock +1 -1
- data/DEVELOPMENT.md +121 -11
- data/README.md +89 -67
- data/docs/exe_upgrade_version.md +124 -0
- data/docs/release_process_v0.1.8.md +298 -0
- data/docs/special_character_bug_fix.md +257 -0
- data/docs/write_functionality_implementation.md +197 -0
- data/examples/README.md +221 -0
- data/{test.rb → examples/basic/basic_usage.rb} +2 -1
- data/{test_fixed.rb → examples/basic/test_fixed.rb} +1 -1
- data/examples/benchmarks/benchmark.rb +372 -0
- data/{output_comparison.rb → examples/benchmarks/output_comparison.rb} +41 -26
- data/examples/benchmarks/sample.csv +1001 -0
- data/examples/features/test_typed_functionality.rb +109 -0
- data/{test_write_functionality.rb → examples/features/test_write_functionality.rb} +1 -1
- data/ext/rbcsv/Cargo.toml +1 -1
- data/ext/rbcsv/src/error.rs +2 -2
- data/ext/rbcsv/src/lib.rs +8 -1
- data/ext/rbcsv/src/parser.rs +74 -15
- data/ext/rbcsv/src/ruby_api.rs +101 -2
- data/ext/rbcsv/src/value.rs +87 -0
- data/lib/rbcsv/version.rb +1 -1
- metadata +16 -8
- data/benchmark.rb +0 -190
- /data/{quick_test.rb → examples/basic/quick_test.rb} +0 -0
- /data/{test_install.rb → examples/basic/test_install.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c08a56224baf175930ae9bdd61da9e29464dfb35f0336f5fcd234073d96d8200
|
|
4
|
+
data.tar.gz: f77af48e7ea72618f2e7b6476e87a78cd50f5641391f31fa571b5914d622ad5d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
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
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
RbCsv.
|
|
266
|
-
RbCsv.
|
|
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
|
-
|
|
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. **
|
|
295
|
-
3. **
|
|
296
|
-
4. **
|
|
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
|
-
|
|
3
|
+
Fast CSV library for Ruby powered by Rust.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Add this line to your Gemfile:
|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
13
|
+
Or install directly:
|
|
16
14
|
|
|
17
15
|
```bash
|
|
18
|
-
gem install
|
|
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
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
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
|
-
|
|
54
|
-
|
|
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
|
-
#
|
|
84
|
-
RbCsv.
|
|
85
|
-
# =>
|
|
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
|
-
##
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
114
|
+
Found a bug or have a suggestion? Please open an issue on [GitHub](https://github.com/fujitanisora/r_csv/issues).
|
|
97
115
|
|
|
98
|
-
|
|
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
|
-
|
|
120
|
+
**Fujitani Sora**
|
|
121
|
+
📧 fujitanisora0414@gmail.com
|
|
122
|
+
🐙 [@fujitanisora](https://github.com/fujitanisora)
|
|
101
123
|
|
|
102
|
-
##
|
|
124
|
+
## License
|
|
103
125
|
|
|
104
|
-
|
|
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"`
|