Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,21 @@ jobs:
echo "" >> temp_changelog.md

# Prepend to existing CHANGELOG (skip the header)
if [ -f CHANGELOG.md ]; then
tail -n +3 CHANGELOG.md >> temp_changelog.md
if [ -f structured_params/CHANGELOG.md ]; then
tail -n +3 structured_params/CHANGELOG.md >> temp_changelog.md
fi

# Add header back
echo "# Changelog" > CHANGELOG.md
echo "" >> CHANGELOG.md
cat temp_changelog.md >> CHANGELOG.md
echo "# Changelog" > structured_params/CHANGELOG.md
echo "" >> structured_params/CHANGELOG.md
cat temp_changelog.md >> structured_params/CHANGELOG.md

# Clean up temporary file
rm -f temp_changelog.md

- name: Commit CHANGELOG update
run: |
git add CHANGELOG.md
git add structured_params/CHANGELOG.md
if git diff --staged --quiet; then
echo "No CHANGELOG changes to commit"
else
Expand All @@ -85,8 +85,11 @@ jobs:
bundler-cache: true

- name: Build gem
working-directory: structured_params
Comment thread
Syati marked this conversation as resolved.
Resolved
run: |
gem build structured_params.gemspec

- name: Publish to RubyGems
uses: rubygems/release-gem@v1
with:
working-directory: structured_params
4 changes: 2 additions & 2 deletions .github/workflows/tagging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ jobs:
- name: Update version file
run: |
VERSION="${{ steps.extract_version.outputs.version }}"
sed -i "s/VERSION = '[^']*'/VERSION = '$VERSION'/" lib/structured_params/version.rb
sed -i "s/VERSION = '[^']*'/VERSION = '$VERSION'/" structured_params/lib/structured_params/version.rb

- name: Commit version update
run: |
git add lib/structured_params/version.rb
git add structured_params/lib/structured_params/version.rb
if git diff --staged --quiet; then
echo "No version changes to commit"
else
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Gemfile.lock
/.config
/coverage/
/InstalledFiles
/pkg/
pkg/
/spec/reports/
/spec/examples.txt
/test/tmp/
Expand Down
10 changes: 9 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ plugins:

AllCops:
NewCops: enable
# Both gemspecs require Ruby >= 3.2.0; RuboCop cannot infer it from a gemspec in a subdirectory.
TargetRubyVersion: 3.2

Style/OneClassPerFile:
Exclude:
- spec/support/test_classes/**/*
- '**/spec/support/test_classes/**/*'

# RuboCop's default excludes match spec/ at the repository root only.
Style/Documentation:
Exclude:
- '**/spec/**/*'
- '**/test/**/*'

Layout/LeadingCommentSpace:
Enabled: false
Expand Down
4 changes: 2 additions & 2 deletions .rubocop_rbs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Style/RbsInline/MissingTypeAnnotation:
- '**/spec/**/*'
Style/RbsInline/UntypedInstanceVariable:
Exclude:
- 'lib/structured_params/params.rb'
- 'lib/structured_params.rb'
- 'structured_params/lib/structured_params/params.rb'
- 'structured_params/lib/structured_params.rb'
- 'structured_params-openapi/lib/structured_params/openapi/configuration.rb'
- 'structured_params-openapi/lib/structured_params/openapi/registry.rb'

Expand Down
37 changes: 19 additions & 18 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
## プロジェクト概要

- `structured_params` は Rails 向けの型付きパラメータ/フォームオブジェクト用 gem です。
- コア実装は `lib/structured_params/` 配下にあります。
- このリポジトリには 2 つの gem があり、それぞれ独自のフォルダを持ちます。コア gem は `structured_params/`、OpenAPI drift check は `structured_params-openapi/` です。
- コア実装は `structured_params/lib/structured_params/` 配下にあります。
- テストは RSpec、Lint は RuboCop、型検査は Steep を使います。
- RBS シグネチャは `rbs-inline` から生成されます。

## 主要ディレクトリ

- `structured_params-openapi/`: OpenAPI drift check の別 gem(`structured_params-openapi`)。
独自の `lib/`・`sig/`・`spec/`・`docs/` と gemspec を持ちます。コアとは同じリポジトリで管理し、
テストは `cd structured_params-openapi && bundle exec rspec` で実行します。
- `structured_params/`: コア gem。`lib/`・`sig/`・`spec/`・`docs/`・`structured_params.gemspec`・`CHANGELOG.md` を持ちます。
- `structured_params-openapi/`: OpenAPI drift check の別 gem。同じ構成の独自の `lib/`・`sig/`・`spec/`・`docs/` と gemspec を持ちます。
- リポジトリ直下: `README.md`、`Gemfile`、`Rakefile`、`Steepfile`、`lefthook.yml`、RuboCop 設定など、両方の gem に共通のもの。

- `lib/structured_params.rb`: エントリーポイント
- `lib/structured_params/params.rb`: コアの `Params` 実装
- `lib/structured_params/type/`: `array` / `object` 型ハンドラ
- `spec/`: RSpec テスト
- `docs/`: 利用者向けドキュメント
- `sig/`: `rbs-inline` により生成された RBS
- `structured_params/lib/structured_params.rb`: エントリーポイント
- `structured_params/lib/structured_params/params.rb`: コアの `Params` 実装
- `structured_params/lib/structured_params/type/`: `array` / `object` 型ハンドラ
- `structured_params/spec/`: RSpec テスト
- `structured_params/docs/`: 利用者向けドキュメント
- `structured_params/sig/`: `rbs-inline` により生成された RBS

## セットアップと実行

Expand All @@ -33,7 +34,7 @@ bin/setup
通常の確認:

```bash
bundle exec rspec
bundle exec rake spec # 両方の gem の spec(各 gem のフォルダで bundle exec rspec でも可)
bundle exec rubocop
bundle exec steep check
```
Expand All @@ -43,13 +44,13 @@ Ruby 3.2 系では `steep` や `.rubocop_rbs.yml` 前提のチェックが使え
個別実行例:

```bash
bundle exec rspec spec/params_spec.rb
bundle exec rubocop lib/structured_params/params.rb
(cd structured_params && bundle exec rspec spec/params_spec.rb)
bundle exec rubocop structured_params/lib/structured_params/params.rb
```

## 変更時のルール

- `sig/**/*.rbs` は手編集しないでください。必要なら `bundle exec rbs-inline --output=sig lib/**/*.rb` で再生成します。
- `sig/**/*.rbs` は手編集しないでください。必要なら各 gem のフォルダ(`structured_params/` など)で `bundle exec rbs-inline --output=sig lib` を実行して再生成します。
- Ruby メソッドの型注釈は `rbs-inline` の `method_type_signature` スタイルを使ってください。
- インスタンス変数の型注釈は `# @rbs` コメントを使ってください。
- 既存の公開 API を変える場合は、README と `docs/` の整合も確認してください。
Expand All @@ -58,16 +59,16 @@ bundle exec rubocop lib/structured_params/params.rb
## テスト方針

- 振る舞い変更には RSpec を追加または更新してください。
- 既存 spec のスタイルに合わせ、必要に応じて `spec/factories/` と `spec/support/` を再利用してください。
- 既存 spec のスタイルに合わせ、必要に応じて `structured_params/spec/factories/` と `structured_params/spec/support/` を再利用してください。
- 修正が型やシリアライズ、permit 生成に関わる場合は、関連 spec を広めに実行してください。

## コミット前チェック

`lefthook.yml` によりコミット前に以下が走ります。

- `bundle exec rbs-inline --output=sig lib/**/*.rb`(`structured_params-openapi/` でも同様)
- 各 gem のフォルダでの `bundle exec rbs-inline --output=sig lib`(`structured_params/` と `structured_params-openapi/`)
- `bundle exec rubocop`
- `bundle exec rspec`(`structured_params-openapi/` でも実行)
- 各 gem のフォルダでの `bundle exec rspec`(`structured_params/` と `structured_params-openapi/`)
- `bundle exec steep check`

フックで失敗しない状態まで揃えてから完了扱いにしてください。
Expand All @@ -81,4 +82,4 @@ bundle exec rubocop lib/structured_params/params.rb
- エラーフォーマットやバリデーション挙動の変更
- Rails / Ruby サポート範囲の変更

利用者向け概要は `README.md`、詳細仕様は `docs/*.md`、日本語 README が必要なら `README_ja.md` も更新します。
利用者向け概要は `README.md`、詳細仕様は `structured_params/docs/*.md`、日本語 README が必要なら `README_ja.md` も更新します。
61 changes: 36 additions & 25 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ bin/setup
### Running Tests

```bash
# Run all tests
# Run the specs of every gem (from the repository root)
bundle exec rake spec

# The repository holds two gems, each in its own folder:
# structured_params/ the core gem
# structured_params-openapi/ the OpenAPI drift check gem
cd structured_params

# Run all tests of the gem
bundle exec rspec

# Run specific test file
Expand Down Expand Up @@ -62,15 +70,15 @@ Automatically regenerate signatures on file changes:
./bin/dev
```

This command uses `fswatch` to monitor the `lib/` directory and automatically runs `rbs-inline` when files change.
This command uses `fswatch` to monitor the `lib/` directory of each gem and automatically runs `rbs-inline` when files change.

### Manual Generation

Generate all signatures manually:

```bash
# Generate for all lib files
bundle exec rbs-inline --output=sig lib/**/*.rb
# Generate for all lib files (run inside each gem folder, e.g. structured_params/)
cd structured_params && bundle exec rbs-inline --output=sig lib
```

### Automatic Generation (Git Hooks)
Expand All @@ -88,7 +96,7 @@ The git hook configuration is in `lefthook.yml`:
prepare-commit-msg:
commands:
rbs-inline:
run: bundle exec rbs-inline --output=sig lib/**/*.rb
run: (cd structured_params && bundle exec rbs-inline --output=sig lib) && ...
```

## Coding Style
Expand Down Expand Up @@ -167,32 +175,35 @@ You can test against different Rails versions using the `RAILS_VERSION` environm

```bash
# Test with Rails 7.2
RAILS_VERSION="~> 7.2.0" bundle update && bundle exec rspec
RAILS_VERSION="~> 7.2.0" bundle update && bundle exec rake spec

# Test with Rails 8.0
RAILS_VERSION="~> 8.0.0" bundle update && bundle exec rspec
RAILS_VERSION="~> 8.0.0" bundle update && bundle exec rake spec
```

## Project Structure

```
structured_params/
├── lib/
│ ├── structured_params.rb # Main entry point
│ ├── structured_params/
│ │ ├── params.rb # Core Params class
│ │ ├── errors.rb # Enhanced error handling
│ │ ├── version.rb # Version constant
│ │ └── type/
│ │ ├── array.rb # Array type handler
│ │ └── object.rb # Object type handler
├── sig/ # Auto-generated RBS files
│ └── generated/ # DO NOT EDIT
├── spec/ # RSpec tests
│ ├── factories/ # Test parameter classes
│ ├── support/ # Test helpers
│ └── *_spec.rb # Test files
└── docs/ # Documentation
. # repository root: README, Gemfile, Rakefile, Steepfile, lefthook.yml, RuboCop config
├── structured_params/ # core gem
│ ├── structured_params.gemspec
│ ├── CHANGELOG.md
│ ├── lib/
│ │ ├── structured_params.rb # Main entry point
│ │ └── structured_params/
│ │ ├── params.rb # Core Params class
│ │ ├── errors.rb # Enhanced error handling
│ │ ├── version.rb # Version constant
│ │ └── type/
│ │ ├── array.rb # Array type handler
│ │ └── object.rb # Object type handler
│ ├── sig/ # Auto-generated RBS files (DO NOT EDIT)
│ ├── spec/ # RSpec tests
│ │ ├── factories/ # Test parameter classes
│ │ ├── support/ # Test helpers
│ │ └── *_spec.rb # Test files
│ └── docs/ # Documentation
└── structured_params-openapi/ # OpenAPI drift check gem (same layout)
```

## Submitting Changes
Expand All @@ -202,7 +213,7 @@ structured_params/
1. **Fork the repository** and create your branch from `main`
2. **Write tests** for your changes
3. **Update documentation** if needed (README, docs/, inline comments)
4. **Ensure all tests pass**: `bundle exec rspec`
4. **Ensure all tests pass**: `bundle exec rake spec`
5. **Ensure code quality**: `bundle exec rubocop`
6. **Ensure type safety** (Ruby 3.3+): `bundle exec steep check`
7. **RBS signatures will be auto-generated** by git hooks
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

source 'https://rubygems.org'

gemspec
gemspec path: 'structured_params'
gemspec path: 'structured_params-openapi'

# Allow testing different Rails versions via environment variable
Expand Down
3 changes: 2 additions & 1 deletion Procfile.dev
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
rbs-inline: fswatch -0 lib | xargs -0 -n1 bundle exec rbs-inline --output=sig
rbs-inline: sh -c 'cd structured_params && fswatch -0 lib | xargs -0 -n1 bundle exec rbs-inline --output=sig'
rbs-inline-openapi: sh -c 'cd structured_params-openapi && fswatch -0 lib | xargs -0 -n1 bundle exec rbs-inline --output=sig'
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ bundle exec rake structured_params:openapi:drift_check

## Documentation

- **[Installation and Setup](docs/installation.md)** - Getting started with StructuredParams
- **[Basic Usage](docs/basic-usage.md)** - Parameter classes, nested objects, and arrays
- **[Validation](docs/validation.md)** - Using ActiveModel validations with nested structures
- **[Installation and Setup](structured_params/docs/installation.md)** - Getting started with StructuredParams
- **[Basic Usage](structured_params/docs/basic-usage.md)** - Parameter classes, nested objects, and arrays
- **[Validation](structured_params/docs/validation.md)** - Using ActiveModel validations with nested structures
- **[OpenAPI Drift Check](structured_params-openapi/docs/drift-check.md)** - Detect differences between request schemas and Params classes (`structured_params-openapi` gem)
- **[Strong Parameters](docs/strong-parameters.md)** - Automatic permit list generation
- **[Error Handling](docs/error-handling.md)** - Flat and structured error formats
- **[Serialization](docs/serialization.md)** - Converting parameters to hashes and JSON
- **[Form Objects](docs/form-objects.md)** - Form object pattern with Rails views
- **[Strong Parameters](structured_params/docs/strong-parameters.md)** - Automatic permit list generation
- **[Error Handling](structured_params/docs/error-handling.md)** - Flat and structured error formats
- **[Serialization](structured_params/docs/serialization.md)** - Converting parameters to hashes and JSON
- **[Form Objects](structured_params/docs/form-objects.md)** - Form object pattern with Rails views

## Contributing

Expand Down
14 changes: 7 additions & 7 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ bundle exec rake structured_params:openapi:drift_check

## ドキュメント

- **[インストールとセットアップ](docs/installation.md)** - StructuredParams の始め方
- **[基本的な使い方](docs/basic-usage.md)** - パラメータクラス、ネストオブジェクト、配列
- **[バリデーション](docs/validation.md)** - ネスト構造での ActiveModel バリデーション
- **[インストールとセットアップ](structured_params/docs/installation.md)** - StructuredParams の始め方
- **[基本的な使い方](structured_params/docs/basic-usage.md)** - パラメータクラス、ネストオブジェクト、配列
- **[バリデーション](structured_params/docs/validation.md)** - ネスト構造での ActiveModel バリデーション
- **[OpenAPI Drift Check](structured_params-openapi/docs/drift-check_ja.md)** - OpenAPI schema と Params class の乖離検出(`structured_params-openapi` gem)
- **[Strong Parameters](docs/strong-parameters.md)** - permit リストの自動生成
- **[エラーハンドリング](docs/error-handling.md)** - フラット形式と構造化形式のエラー
- **[シリアライゼーション](docs/serialization.md)** - パラメータのハッシュと JSON 変換
- **[フォームオブジェクト](docs/form-objects.md)** - Rails ビューとのフォームオブジェクトパターン
- **[Strong Parameters](structured_params/docs/strong-parameters.md)** - permit リストの自動生成
- **[エラーハンドリング](structured_params/docs/error-handling.md)** - フラット形式と構造化形式のエラー
- **[シリアライゼーション](structured_params/docs/serialization.md)** - パラメータのハッシュと JSON 変換
- **[フォームオブジェクト](structured_params/docs/form-objects.md)** - Rails ビューとのフォームオブジェクトパターン

## コントリビューション

Expand Down
24 changes: 13 additions & 11 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
# frozen_string_literal: true
# rbs_inline: enabled

require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
require 'rubocop/rake_task'

RSpec::Core::RakeTask.new(:spec)
# The repository holds two gems, each in its own directory with its own spec suite and its
# own Rakefile for `build`/`install`/`release` (run those from the gem's directory).
GEM_DIRS = %w[structured_params structured_params-openapi].freeze #: Array[String]

require 'rubocop/rake_task'
GEM_DIRS.each do |gem_dir|
desc "Run the #{gem_dir} specs"
task "spec:#{gem_dir}" do
Dir.chdir(gem_dir) { sh 'bundle exec rspec' }
end
end

desc 'Run the specs of every gem'
task spec: GEM_DIRS.map { |gem_dir| "spec:#{gem_dir}" }

# Use RBS Inline configuration for Ruby 3.3+
rubocop_config = if RUBY_VERSION >= '3.3.0'
Expand All @@ -28,11 +37,4 @@ if RUBY_VERSION >= '3.3.0'
default_tasks << :steep
end

# The OpenAPI plugin lives in its own gem directory with its own spec suite.
desc 'Run the structured_params-openapi specs'
task :spec_openapi do
Dir.chdir('structured_params-openapi') { sh 'bundle exec rspec' }
end
default_tasks << :spec_openapi

task default: default_tasks
Loading
Loading