rbcsv 0.1.6 → 0.1.7

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/DEVELOPMENT.md CHANGED
@@ -1,24 +1,65 @@
1
- # 開発ガイド
1
+ # RbCsv 開発ガイド
2
2
 
3
- このドキュメントでは、rbcsvの開発環境のセットアップ、ビルド方法、リリース手順について説明します。
3
+ このドキュメントでは、rbcsvの開発環境のセットアップ、ビルド方法、テスト手順、リリース手順について詳しく説明します。
4
4
 
5
5
  ## 必要な環境
6
6
 
7
- - Ruby 3.0以降
8
- - Rust(最新の安定版を推奨)
9
- - Bundler gem
10
- - Git
7
+ - **Ruby**: 3.2.0以降(gemspec要件)
8
+ - **Rust**: 最新の安定版を推奨(MSRV: 1.75+)
9
+ - **Bundler**: gem管理
10
+ - **Git**: バージョン管理
11
+ - **RubyGems**: 3.3.11以降
12
+
13
+ ### システム要件
14
+
15
+ - **macOS**: Apple Silicon (arm64) / Intel (x86_64)
16
+ - **Linux**: x86_64 / aarch64
17
+ - **Windows**: x86_64(実験的サポート)
18
+
19
+ ## プロジェクト構成
20
+
21
+ ```
22
+ r_csv/
23
+ ├── lib/
24
+ │ ├── rbcsv.rb # メインのRubyエントリーポイント
25
+ │ └── rbcsv/
26
+ │ ├── version.rb # バージョン定義
27
+ │ └── rbcsv.bundle # コンパイル済みネイティブ拡張(生成される)
28
+ ├── ext/
29
+ │ └── rbcsv/
30
+ │ ├── src/
31
+ │ │ ├── lib.rs # Rust拡張のエントリーポイント、Magnus初期化
32
+ │ │ ├── parser.rs # CSV解析コア、CsvParseOptions定義
33
+ │ │ ├── ruby_api.rs # Ruby APIバインディング、オプション処理
34
+ │ │ └── error.rs # エラーハンドリング
35
+ │ ├── Cargo.toml # Rust依存関係(Magnus 0.8.1使用)
36
+ │ └── extconf.rb # Ruby拡張ビルド設定
37
+ ├── spec/
38
+ │ ├── rbcsv_spec.rb # メインのRubyテスト
39
+ │ └── spec_helper.rb # テスト設定
40
+ ├── docs/ # ドキュメント
41
+ ├── target/ # Rustビルド出力(git無視)
42
+ ├── tmp/ # Ruby拡張ビルド中間ファイル(git無視)
43
+ ├── *.gem # ビルド済みgemファイル
44
+ ├── rbcsv.gemspec # Gem仕様
45
+ ├── Rakefile # ビルドタスク(rb_sys使用)
46
+ ├── Gemfile # Ruby依存関係
47
+ ├── Cargo.toml # ワークスペース設定
48
+ ├── CHANGELOG.md # 変更履歴
49
+ ├── README.md # 使用法ガイド
50
+ └── DEVELOPMENT.md # このファイル
51
+ ```
11
52
 
12
53
  ## 開発環境のセットアップ
13
54
 
14
55
  ### 1. リポジトリのクローン
15
56
 
16
57
  ```bash
17
- git clone <repository-url>
18
- cd r_csv
58
+ git clone https://github.com/fs0414/rbcsv.git
59
+ cd rbcsv
19
60
  ```
20
61
 
21
- ### 2. 依存関係のインストール
62
+ ### 2. Ruby依存関係のインストール
22
63
 
23
64
  ```bash
24
65
  bundle install
@@ -27,221 +68,424 @@ bundle install
27
68
  ### 3. ネイティブ拡張のビルド
28
69
 
29
70
  ```bash
71
+ # 推奨方法(rb_sys使用)
30
72
  rake compile
73
+
74
+ # 代替方法(開発時)
75
+ bundle exec rake compile
31
76
  ```
32
77
 
33
- ### 4. テストの実行
78
+ ### 4. 動作確認
34
79
 
35
- #### Rubyテスト
36
80
  ```bash
37
- bundle exec rspec
81
+ # 基本的な動作確認
82
+ ruby -I lib -e "require 'rbcsv'; p RbCsv.parse('a,b\n1,2', {})"
83
+ # 期待される出力: [["a", "b"], ["1", "2"]]
84
+
85
+ # オプション付きテスト
86
+ ruby -I lib -e "require 'rbcsv'; p RbCsv.parse(' a , b \n 1 , 2 ', {trim: true})"
87
+ # 期待される出力: [["a", "b"], ["1", "2"]]
38
88
  ```
39
89
 
40
- #### Rustテスト
90
+ ## ビルドプロセス
91
+
92
+ ### 自動ビルド(推奨)
93
+
94
+ ```bash
95
+ # 全体ビルド(コンパイル、テスト、リント)
96
+ rake
97
+
98
+ # 拡張のみコンパイル
99
+ rake compile
100
+
101
+ # クリーンビルド
102
+ rake clean
103
+ rake compile
104
+ ```
105
+
106
+ ### 手動ビルド手順
107
+
41
108
  ```bash
109
+ # 1. 前回のビルドをクリーン
110
+ rm -rf lib/rbcsv/rbcsv.bundle tmp/ target/
111
+
112
+ # 2. Rust拡張のコンパイル
42
113
  cd ext/rbcsv
43
- cargo test
114
+ cargo build --release
44
115
  cd ../..
116
+
117
+ # 3. バンドルファイルのコピー(macOSの場合)
118
+ cp target/release/librbcsv.dylib lib/rbcsv/rbcsv.bundle
119
+
120
+ # Linuxの場合
121
+ # cp target/release/librbcsv.so lib/rbcsv/rbcsv.bundle
45
122
  ```
46
123
 
47
- ### 5. 動作確認テスト
124
+ ### ビルドのトラブルシューティング
125
+
126
+ #### ABIバージョンの不一致
48
127
 
49
128
  ```bash
50
- ruby -I lib -e "require 'rbcsv'; p RbCsv.parse('a,b\n1,2')"
129
+ # エラー例: "incompatible ABI version"
130
+ rm -rf lib/rbcsv/rbcsv.bundle tmp/ target/
131
+ bundle exec rake compile
51
132
  ```
52
133
 
53
- 期待される出力: `[["a", "b"], ["1", "2"]]`
134
+ #### Rust/Cargoの問題
54
135
 
55
- ## プロジェクト構成
136
+ ```bash
137
+ # Rust依存関係の更新
138
+ cd ext/rbcsv
139
+ cargo update
140
+ cargo clean
141
+ cargo build --release
142
+ cd ../..
143
+ ```
144
+
145
+ #### Magnus APIエラー
56
146
 
147
+ ```bash
148
+ # 最新のMagnus 0.8.1では、ReprValueトレイトの明示的インポートが必要
149
+ # ruby_api.rs で以下が含まれていることを確認:
150
+ use magnus::{value::ReprValue};
57
151
  ```
58
- r_csv/
59
- ├── lib/
60
- │ ├── rbcsv.rb # メインのRubyモジュール
61
- │ └── rbcsv/
62
- │ ├── version.rb # バージョン定義
63
- │ └── rbcsv.bundle # コンパイル済みネイティブ拡張
64
- ├── ext/
65
- │ └── rbcsv/
66
- │ ├── src/
67
- │ │ └── lib.rs # Rust実装
68
- │ ├── Cargo.toml # Rust依存関係
69
- │ └── extconf.rb # Ruby拡張の設定
70
- ├── spec/ # Rubyテスト
71
- ├── rbcsv.gemspec # Gem仕様
72
- ├── Rakefile # ビルドタスク
73
- └── DEVELOPMENT.md # このファイル
152
+
153
+ ## テスト手順
154
+
155
+ ### Ruby統合テスト
156
+
157
+ ```bash
158
+ # 全テスト実行
159
+ bundle exec rspec
160
+
161
+ # 特定のテストファイル
162
+ bundle exec rspec spec/rbcsv_spec.rb
163
+
164
+ # 詳細出力
165
+ bundle exec rspec --format documentation
74
166
  ```
75
167
 
76
- ## ビルドプロセス
168
+ ### Rustユニットテスト
169
+
170
+ ```bash
171
+ # 全Rustテスト
172
+ cd ext/rbcsv
173
+ cargo test
77
174
 
78
- このプロジェクトは、`rb_sys`クレートとRubyの拡張メカニズムを通じてコンパイルされるRustベースのネイティブ拡張を使用しています。
175
+ # 詳細出力
176
+ cargo test -- --nocapture
79
177
 
80
- ### 手動ビルド手順
178
+ # 特定のテスト
179
+ cargo test test_parse_basic
180
+ cd ../..
181
+ ```
81
182
 
82
- 1. **前回のビルドをクリーン**(必要に応じて):
83
- ```bash
84
- rm -rf lib/rbcsv/rbcsv.bundle tmp/
85
- ```
183
+ ### パフォーマンステスト
86
184
 
87
- 2. **拡張のコンパイル**:
88
- ```bash
89
- rake compile
90
- ```
185
+ ```bash
186
+ # ベンチマーク実行
187
+ ruby benchmark.rb
91
188
 
92
- 3. **代替ビルド方法**(rakeが失敗する場合):
93
- ```bash
94
- cd ext/rbcsv
95
- cargo build --release
96
- cp ../../target/release/librbcsv.dylib ../../lib/rbcsv/rbcsv.bundle
97
- cd ../..
98
- ```
189
+ # カスタムテストファイルでのテスト
190
+ ruby test.rb
191
+ ```
99
192
 
100
- ### ビルドのトラブルシューティング
193
+ ### コードスタイルチェック
101
194
 
102
- #### ABIバージョンの不一致
103
- 「incompatible ABI version」エラーが発生した場合:
195
+ ```bash
196
+ # Rubyコード(RuboCop)
197
+ bundle exec rubocop
198
+
199
+ # Rustコード
200
+ cd ext/rbcsv
201
+ cargo fmt --check
202
+ cargo clippy -- -D warnings
203
+ cd ../..
204
+ ```
205
+
206
+ ## API設計
207
+
208
+ ### 現在のAPI(v0.1.6+)
209
+
210
+ ```ruby
211
+ # 統一されたオプションベースAPI
212
+ RbCsv.parse(csv_string, options = {})
213
+ RbCsv.read(file_path, options = {})
214
+
215
+ # 利用可能なオプション
216
+ options = {
217
+ trim: true/false # 空白文字の除去(デフォルト: false)
218
+ # 将来の拡張:
219
+ # headers: true/false
220
+ # delimiter: ','
221
+ }
222
+ ```
104
223
 
105
- 1. ビルドと実行で同じRubyバージョンを使用していることを確認
106
- 2. クリーンして再ビルド:
107
- ```bash
108
- rm -rf lib/rbcsv/rbcsv.bundle tmp/
109
- rake compile
110
- ```
224
+ ### 実装アーキテクチャ
111
225
 
112
- #### Rubyバージョンの競合
113
- 開発版Ruby(3.5.0devなど)を使用する場合、プリコンパイル済みのgemは動作しません。必ずソースから再ビルドしてください。
226
+ 1. **parser.rs**: CsvParseOptionsと核となるCSV解析機能
227
+ 2. **ruby_api.rs**: Rubyハッシュオプションの処理とMagnus API
228
+ 3. **lib.rs**: Magnus初期化と関数登録
229
+ 4. **error.rs**: エラーハンドリングとRuby例外の変換
114
230
 
115
231
  ## リリース手順
116
232
 
117
- ### 1. バージョンの更新
233
+ ### 1. 準備フェーズ
234
+
235
+ ```bash
236
+ # 開発状況の確認
237
+ git status
238
+ git log --oneline -10
239
+
240
+ # 全テストの実行
241
+ rake clean
242
+ rake
243
+
244
+ # コードスタイルチェック
245
+ bundle exec rubocop
246
+ cd ext/rbcsv && cargo clippy && cd ../..
247
+ ```
248
+
249
+ ### 2. バージョン更新
250
+
251
+ ```bash
252
+ # lib/rbcsv/version.rb を編集
253
+ vim lib/rbcsv/version.rb
254
+ ```
118
255
 
119
- `lib/rbcsv/version.rb`を編集:
120
256
  ```ruby
121
257
  module RbCsv
122
- VERSION = "x.y.z" # バージョン番号を更新
258
+ VERSION = "x.y.z" # セマンティックバージョニング
123
259
  end
124
260
  ```
125
261
 
126
- ### 2. CHANGELOG.mdの更新
262
+ ### 3. CHANGELOG.md の更新
127
263
 
128
- リリース用の新しいセクションを追加:
129
264
  ```markdown
130
265
  ## [x.y.z] - YYYY-MM-DD
131
266
 
132
- - **修正**: バグ修正の説明
133
- - **追加**: 新機能の説明
134
- - **変更**: 変更点の説明
135
- - **削除**: 削除された機能の説明
267
+ ### 追加
268
+ - 新機能の説明
269
+
270
+ ### 変更
271
+ - 既存機能の変更点
272
+
273
+ ### 修正
274
+ - バグ修正の説明
275
+
276
+ ### 削除
277
+ - 削除された機能(非互換性のある変更)
278
+
279
+ ### セキュリティ
280
+ - セキュリティ関連の修正
136
281
  ```
137
282
 
138
- ### 3. ビルドとテスト
283
+ ### 4. ビルドとテスト
139
284
 
140
285
  ```bash
141
- # クリーンビルド
142
- rm -rf lib/rbcsv/rbcsv.bundle tmp/
143
-
144
- # 拡張の再ビルド
286
+ # フルクリーンビルド
287
+ rake clean
288
+ bundle install
145
289
  rake compile
146
290
 
147
- # 機能テスト
148
- ruby -I lib -e "require 'rbcsv'; p RbCsv.parse('a,b\n1,2')"
291
+ # 統合テスト
292
+ rake spec
149
293
 
150
- # テストスイートの実行
151
- bundle exec rspec
294
+ # 動作確認
295
+ ruby -I lib -e "require 'rbcsv'; puts RbCsv::VERSION"
296
+ ruby -I lib -e "require 'rbcsv'; p RbCsv.parse('a,b\n1,2', {})"
152
297
  ```
153
298
 
154
- ### 4. Gemのビルド
299
+ ### 5. Gemビルド
155
300
 
156
301
  ```bash
302
+ # Gemファイル生成
157
303
  gem build rbcsv.gemspec
158
- ```
159
304
 
160
- これにより、現在のディレクトリに`rbcsv-x.y.z.gem`が作成されます。
305
+ # 生成確認
306
+ ls -la rbcsv-*.gem
307
+ ```
161
308
 
162
- ### 5. 変更のコミット
309
+ ### 6. 変更のコミット
163
310
 
164
311
  ```bash
165
312
  git add -A
166
- git commit -m "Release vx.y.z
313
+ git commit -m "Release v${VERSION}
167
314
 
168
- - 主な変更点の簡潔な説明
169
- - 重要な改善や修正のリスト"
315
+ 主な変更:
316
+ - 変更点1の説明
317
+ - 変更点2の説明
318
+ - バグ修正やパフォーマンス改善"
170
319
  ```
171
320
 
172
- ### 6. Gitタグの作成
321
+ ### 7. タグ作成とプッシュ
173
322
 
174
323
  ```bash
175
- git tag vx.y.z
324
+ VERSION=$(ruby -I lib -e "require 'rbcsv/version'; puts RbCsv::VERSION")
325
+ git tag "v${VERSION}"
326
+ git push origin main
327
+ git push origin "v${VERSION}"
176
328
  ```
177
329
 
178
- ### 7. リポジトリへのプッシュ
330
+ ### 8. Gem公開(オプション)
179
331
 
180
332
  ```bash
181
- git push origin main
182
- git push origin vx.y.z
333
+ # RubyGems.orgへの公開
334
+ gem push rbcsv-${VERSION}.gem
335
+
336
+ # 公開確認
337
+ gem list rbcsv --remote
183
338
  ```
184
339
 
185
- ### 8. Gemの公開(オプション)
340
+ ## 開発のベストプラクティス
341
+
342
+ ### コードスタイル
186
343
 
187
- RubyGems.orgに公開する場合:
344
+ #### Ruby
345
+ - 標準的なRuby Style Guideに従う
346
+ - RuboCop設定を使用(`.rubocop.yml`)
347
+ - frozen_string_literalを有効化
188
348
 
349
+ #### Rust
189
350
  ```bash
190
- gem push rbcsv-x.y.z.gem
351
+ # フォーマット
352
+ cargo fmt
353
+
354
+ # リント
355
+ cargo clippy -- -D warnings
356
+
357
+ # ドキュメント生成
358
+ cargo doc --open
191
359
  ```
192
360
 
193
- **注意**: RubyGems.orgの適切な認証情報が設定されていることを確認してください。
361
+ ### テスト戦略
194
362
 
195
- ## 開発のヒント
363
+ 1. **単体テスト**: 各Rustモジュールに対するcargo test
364
+ 2. **統合テスト**: Ruby APIレベルでのRSpecテスト
365
+ 3. **パフォーマンステスト**: 大きなCSVファイルでのベンチマーク
366
+ 4. **エッジケーステスト**: 不正なCSV、空ファイル、エンコーディング問題
196
367
 
197
- ### コードスタイル
368
+ ### デバッグ
369
+
370
+ #### Rust側のデバッグ
198
371
 
199
- - 標準的なRubyとRustのフォーマット規約に従う
200
- - Rustコードのフォーマットには`cargo fmt`を使用
201
- - 適切なRubyリンティングツールを使用
372
+ ```rust
373
+ // 開発ビルドでのみ有効
374
+ #[cfg(debug_assertions)]
375
+ eprintln!("Debug: {:?}", variable);
202
376
 
203
- ### テスト
377
+ // ログ出力(log crateを使用)
378
+ log::debug!("Debug information: {:?}", data);
379
+ ```
204
380
 
205
- - 新機能のテストを`spec/`に追加
206
- - Rustユニットテストを`ext/rbcsv/src/lib.rs`に追加
207
- - コミット前にすべてのテストが通ることを確認
381
+ #### Ruby側のデバッグ
208
382
 
209
- ### デバッグ
383
+ ```ruby
384
+ # 詳細エラー情報
385
+ begin
386
+ RbCsv.parse(invalid_csv, {})
387
+ rescue => e
388
+ puts "Error: #{e.class} - #{e.message}"
389
+ puts e.backtrace
390
+ end
391
+ ```
210
392
 
211
- Rustコードにデバッグ出力を追加する(開発ビルド用):
393
+ ## よくある問題と解決策
212
394
 
213
- ```rust
214
- #[cfg(not(test))]
215
- eprintln!("デバッグ情報: {:?}", variable);
395
+ ### ビルド関連
396
+
397
+ **問題**: "incompatible ABI version"
398
+ ```bash
399
+ # 解決策: クリーンして同じRubyバージョンで再ビルド
400
+ rm -rf lib/rbcsv/rbcsv.bundle tmp/
401
+ bundle exec rake compile
402
+ ```
403
+
404
+ **問題**: Rustコンパイルエラー
405
+ ```bash
406
+ # 解決策: Rust依存関係の更新
407
+ cd ext/rbcsv
408
+ cargo update
409
+ cargo clean
410
+ cargo build --release
411
+ cd ../..
216
412
  ```
217
413
 
218
- これはテスト以外のビルドでのみ出力され、本番環境には影響しません。
414
+ ### 実行時問題
415
+
416
+ **問題**: 空配列が返される
417
+ - **原因**: CSVリーダーの`has_headers`設定
418
+ - **解決策**: 最新バージョン(v0.1.4+)を使用
219
419
 
220
- ## よくある問題
420
+ **問題**: 日本語CSV文字化け
421
+ - **原因**: エンコーディング問題
422
+ - **解決策**: UTF-8での保存を確認、またはエンコーディング変換
221
423
 
222
- ### 拡張が読み込めない
424
+ ### パフォーマンス問題
223
425
 
224
- 1. 正しいRubyバージョン用に拡張がビルドされているか確認
225
- 2. 拡張ファイルの存在を確認: `lib/rbcsv/rbcsv.bundle`
226
- 3. 再ビルドを試す: `rake compile`
426
+ **問題**: 大きなファイルでメモリ不足
427
+ - **解決策**: ストリーミング処理の実装を検討(将来の機能)
227
428
 
228
- ### 空配列が返される
429
+ **問題**: 予想より遅い処理速度
430
+ - **チェック項目**:
431
+ - ファイルI/O vs メモリ処理
432
+ - trimオプションの使用
433
+ - デバッグビルド vs リリースビルド
229
434
 
230
- これはv0.1.4で修正された既知の問題です。CSVリーダーで`has_headers(false)`設定を使用した最新バージョンを使用していることを確認してください。
435
+ ## コントリビューションガイドライン
231
436
 
232
- ### ビルドの失敗
437
+ ### 開発フロー
233
438
 
234
- 1. Rustがインストールされ、最新であることを確認
235
- 2. Ruby開発ヘッダーが利用可能であることを確認
236
- 3. ビルドキャッシュをクリア: `rm -rf tmp/`
439
+ 1. **Issue作成**: バグ報告や機能要求
440
+ 2. **フォーク**: 個人リポジトリへのフォーク
441
+ 3. **ブランチ作成**: `feature/new-feature` または `fix/bug-name`
442
+ 4. **開発**: コードの実装とテスト追加
443
+ 5. **テスト**: 全テストの実行と確認
444
+ 6. **プルリクエスト**: 説明と変更内容の詳細
237
445
 
238
- ## コントリビューション
446
+ ### コミットメッセージ
239
447
 
240
- 1. リポジトリをフォーク
241
- 2. 機能ブランチを作成
242
- 3. 変更を実施
243
- 4. 新機能のテストを追加
244
- 5. すべてのテストが通ることを確認
245
- 6. プルリクエストを送信
448
+ ```
449
+ [種類] 簡潔な説明(50文字以内)
450
+
451
+ 詳細な説明(必要に応じて):
452
+ - 変更の理由
453
+ - 実装方法
454
+ - 影響範囲
455
+
456
+ 関連Issue: #123
457
+ ```
246
458
 
247
- コードは既存のスタイルに従い、適切なテストを含めてください。
459
+ 種類の例:
460
+ - `feat`: 新機能
461
+ - `fix`: バグ修正
462
+ - `docs`: ドキュメント
463
+ - `style`: コードスタイル
464
+ - `refactor`: リファクタリング
465
+ - `test`: テスト追加
466
+ - `chore`: その他(依存関係更新など)
467
+
468
+ ## ロードマップ
469
+
470
+ ### 短期目標(v0.2.x)
471
+ - [ ] カスタム区切り文字サポート
472
+ - [ ] ヘッダー行処理
473
+ - [ ] エラーハンドリングの改善
474
+
475
+ ### 中期目標(v0.3.x)
476
+ - [ ] ストリーミング処理
477
+ - [ ] 非同期処理サポート
478
+ - [ ] Windows完全サポート
479
+
480
+ ### 長期目標(v1.0.x)
481
+ - [ ] 安定したAPI
482
+ - [ ] 包括的なドキュメント
483
+ - [ ] パフォーマンス最適化完了
484
+
485
+ ## 参考リンク
486
+
487
+ - [Magnus Documentation](https://docs.rs/magnus/)
488
+ - [rb_sys Documentation](https://docs.rs/rb_sys/)
489
+ - [Ruby Extension Guide](https://docs.ruby-lang.org/en/master/extension_rdoc.html)
490
+ - [Cargo Book](https://doc.rust-lang.org/cargo/)
491
+ - [RubyGems Guides](https://guides.rubygems.org/)
data/ext/rbcsv/Cargo.toml CHANGED
@@ -11,5 +11,9 @@ crate-type = ["cdylib"]
11
11
 
12
12
  [dependencies]
13
13
  csv = "1.3.1"
14
- magnus = { version = "0.6.2" }
15
- rb-sys = { version = "0.9", features = ["link-ruby"] }
14
+ magnus = { version = "0.8.1" }
15
+ # rb-sys = { version = "0.9", features = ["link-ruby"] }
16
+ log = "0.4"
17
+
18
+ [dev-dependencies]
19
+ env_logger = "0.10"