From fea4657641973cc9002c74e24b8194d6d18f48eb Mon Sep 17 00:00:00 2001 From: mizuki-y Date: Mon, 22 Sep 2025 22:12:08 +0900 Subject: [PATCH 1/8] Update Ruby and Rails versions in main.yml for compatibility with Ruby 3.4 and Rails 8.1.0.beta1 --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c36d729..ea50b79 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,6 +28,8 @@ jobs: rails: '~> 8.0.0' - ruby: '3.4' rails: '~> 8.0.0' + - ruby: '3.4' + rails: '8.1.0.beta1' steps: - uses: actions/checkout@v5 From cebe082cd4ca8a1e50c15ec2037e844439c9c441 Mon Sep 17 00:00:00 2001 From: mizuki-y Date: Sat, 17 Jan 2026 16:51:17 +0900 Subject: [PATCH 2/8] Adjust RuboCop configuration to remove space before Metrics/MethodLength key --- .rubocop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index 1a7561a..3cba502 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -27,5 +27,5 @@ RSpec/ExampleLength: Metrics/ClassLength: Max: 150 - Metrics/MethodLength: +Metrics/MethodLength: Max: 20 From e484a82234cb802db8ca21ca233dec1d264d07bc Mon Sep 17 00:00:00 2001 From: mizuki-y Date: Sun, 1 Mar 2026 02:29:39 +0900 Subject: [PATCH 3/8] Update Ruby version to 4.0.0 and adjust compatibility in main.yml and gemspec --- .github/workflows/main.yml | 4 ++-- .ruby-version | 2 +- structured_params.gemspec | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ea50b79..2974fae 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,8 +28,8 @@ jobs: rails: '~> 8.0.0' - ruby: '3.4' rails: '~> 8.0.0' - - ruby: '3.4' - rails: '8.1.0.beta1' + - ruby: '4.0' + rails: '~> 8.0.0' steps: - uses: actions/checkout@v5 diff --git a/.ruby-version b/.ruby-version index 4f5e697..fcdb2e1 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.4.5 +4.0.0 diff --git a/structured_params.gemspec b/structured_params.gemspec index 5a3672a..389d1db 100644 --- a/structured_params.gemspec +++ b/structured_params.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |spec| spec.description = '' spec.homepage = 'https://github.com/Syati/structured_params' spec.license = 'MIT' - spec.required_ruby_version = '>= 3.0.0' + spec.required_ruby_version = '>= 3.2.0' spec.require_paths = ['lib'] spec.files = Dir[ 'LICENSE.txt', From 62259df8fbad9049189dcddcf8c1256b2ca13039 Mon Sep 17 00:00:00 2001 From: mizuki-y Date: Sun, 1 Mar 2026 02:46:47 +0900 Subject: [PATCH 4/8] Add RBS configuration for missing type annotations and enable rbs_inline in Gemfile --- .rubocop.yml | 4 ++++ Gemfile | 1 + 2 files changed, 5 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 3cba502..2e5724b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -29,3 +29,7 @@ Metrics/ClassLength: Metrics/MethodLength: Max: 20 + +# ========= RBS =========== +Style/RbsInline/MissingTypeAnnotation: + EnforcedStyle: method_type_signature diff --git a/Gemfile b/Gemfile index 417ccdd..97ab9d5 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled source 'https://rubygems.org' From d10151d71ab2ee22f6c8f5d6ce79b4b43c86983d Mon Sep 17 00:00:00 2001 From: mizuki-y Date: Sun, 1 Mar 2026 02:47:08 +0900 Subject: [PATCH 5/8] Enable RBS inline for type annotations across multiple files --- Rakefile | 1 + Steepfile | 1 + bin/console | 1 + lib/structured_params/params.rb | 10 +++------- lib/structured_params/type/object.rb | 1 + spec/errors_spec.rb | 1 + spec/factories/address_parameters.rb | 1 + spec/factories/hobby_parameters.rb | 1 + spec/factories/user_parameters.rb | 1 + spec/params_spec.rb | 1 + spec/spec_helper.rb | 1 + spec/type/array_spec.rb | 2 ++ spec/type/object_spec.rb | 2 ++ structured_params.gemspec | 1 + 14 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Rakefile b/Rakefile index 0e0b70f..a9ab362 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled require 'bundler/gem_tasks' require 'rspec/core/rake_task' diff --git a/Steepfile b/Steepfile index 6309f26..8eb0ac3 100644 --- a/Steepfile +++ b/Steepfile @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled # D = Steep::Diagnostic target :lib do diff --git a/bin/console b/bin/console index fef4850..4fdf31d 100755 --- a/bin/console +++ b/bin/console @@ -1,5 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true +# rbs_inline: enabled require 'bundler/setup' require 'structured_params' diff --git a/lib/structured_params/params.rb b/lib/structured_params/params.rb index 834e9f1..c8e8b7e 100644 --- a/lib/structured_params/params.rb +++ b/lib/structured_params/params.rb @@ -18,7 +18,7 @@ class Params # @rbs @errors: ::StructuredParams::Errors? class << self - # @rbs self.@structured_attributes: Hash[Symbol, singleton(::StructuredParams::Params)]? + # @rbs @structured_attributes: Hash[Symbol, singleton(::StructuredParams::Params)]? # Generate permitted parameter structure for Strong Parameters #: () -> Array[untyped] @@ -128,9 +128,7 @@ def validate_structured_parameters end # Validate structured arrays - # @rbs attr_name: Symbol - # @rbs array_value: Array[untyped] - # @rbs return: void + #: (Symbol, Array[untyped]) -> void def validate_structured_array(attr_name, array_value) array_value.each_with_index do |item, index| next if item.valid?(validation_context) @@ -141,9 +139,7 @@ def validate_structured_array(attr_name, array_value) end # Validate structured objects - # @rbs attr_name: Symbol - # @rbs object_value: ::StructuredParams::Params - # @rbs return: void + #: (Symbol, StructuredParams::Params) -> void def validate_structured_object(attr_name, object_value) return if object_value.valid?(validation_context) diff --git a/lib/structured_params/type/object.rb b/lib/structured_params/type/object.rb index b1d22d4..645f313 100644 --- a/lib/structured_params/type/object.rb +++ b/lib/structured_params/type/object.rb @@ -10,6 +10,7 @@ class Object < ActiveModel::Type::Value # Get permitted parameter names for use with Strong Parameters # @rbs! # def permit_attribute_names: () -> ::Array[untyped] + delegate :permit_attribute_names, to: :value_class #: (value_class: singleton(StructuredParams::Params), **untyped) -> void diff --git a/spec/errors_spec.rb b/spec/errors_spec.rb index a23d234..52640ef 100644 --- a/spec/errors_spec.rb +++ b/spec/errors_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled require 'spec_helper' diff --git a/spec/factories/address_parameters.rb b/spec/factories/address_parameters.rb index c7e3127..6cbf531 100644 --- a/spec/factories/address_parameters.rb +++ b/spec/factories/address_parameters.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled class AddressParameter < StructuredParams::Params attribute :postal_code, :string diff --git a/spec/factories/hobby_parameters.rb b/spec/factories/hobby_parameters.rb index f9c4c3f..4385f5b 100644 --- a/spec/factories/hobby_parameters.rb +++ b/spec/factories/hobby_parameters.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled class HobbyParameter < StructuredParams::Params attribute :name, :string diff --git a/spec/factories/user_parameters.rb b/spec/factories/user_parameters.rb index 5d27d1f..c234127 100644 --- a/spec/factories/user_parameters.rb +++ b/spec/factories/user_parameters.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled class UserParameter < StructuredParams::Params attribute :name, :string diff --git a/spec/params_spec.rb b/spec/params_spec.rb index b45cd98..fd06cc3 100644 --- a/spec/params_spec.rb +++ b/spec/params_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled require 'spec_helper' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7b65c79..4ef9364 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled require 'structured_params' require 'rspec-parameterized' diff --git a/spec/type/array_spec.rb b/spec/type/array_spec.rb index 6cd731a..fc573fb 100644 --- a/spec/type/array_spec.rb +++ b/spec/type/array_spec.rb @@ -1,10 +1,12 @@ # frozen_string_literal: true +# rbs_inline: enabled require 'spec_helper' RSpec.describe StructuredParams::Type::Array do let(:dummy_model_class) do Class.new(StructuredParams::Params) do + #: () -> void def self.name 'DummyModel' end diff --git a/spec/type/object_spec.rb b/spec/type/object_spec.rb index 42dde0f..7720ad4 100644 --- a/spec/type/object_spec.rb +++ b/spec/type/object_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled require 'spec_helper' @@ -7,6 +8,7 @@ let(:dummy_model_class) do Class.new(StructuredParams::Params) do + #: () -> void def self.name 'DummyModel' end diff --git a/structured_params.gemspec b/structured_params.gemspec index 389d1db..82b241c 100644 --- a/structured_params.gemspec +++ b/structured_params.gemspec @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rbs_inline: enabled require_relative 'lib/structured_params/version' From 402bab5bfcdfca8358dfc5d6a807f4e135c93503 Mon Sep 17 00:00:00 2001 From: mizuki-y Date: Sun, 1 Mar 2026 02:54:08 +0900 Subject: [PATCH 6/8] Refactor RuboCop and RBS configuration for Ruby 3.3+ support --- .github/workflows/main.yml | 8 ++++++++ .rubocop.yml | 7 +------ .rubocop_rbs.yml | 11 +++++++++++ Gemfile | 10 +++++++--- Rakefile | 24 ++++++++++++++++++++---- 5 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 .rubocop_rbs.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2974fae..cbb753b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,6 +30,13 @@ jobs: rails: '~> 8.0.0' - ruby: '4.0' rails: '~> 8.0.0' + - ruby: '3.3' + rails: '~> 8.1.0' + - ruby: '3.4' + rails: '~> 8.1.0' + - ruby: '4.0' + rails: '~> 8.1.0' + steps: - uses: actions/checkout@v5 @@ -41,6 +48,7 @@ jobs: - name: Set Rails version run: | echo "RAILS_VERSION=${{ matrix.rails }}" >> $GITHUB_ENV + echo "RUBY_VERSION=${{ matrix.ruby }}" >> $GITHUB_ENV - name: Install dependencies run: | bundle install --jobs 4 --retry 3 diff --git a/.rubocop.yml b/.rubocop.yml index 2e5724b..9af088a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,6 @@ -plugins: +require: - rubocop-rspec - rubocop-rake - - rubocop-rbs_inline - rubocop-factory_bot AllCops: @@ -29,7 +28,3 @@ Metrics/ClassLength: Metrics/MethodLength: Max: 20 - -# ========= RBS =========== -Style/RbsInline/MissingTypeAnnotation: - EnforcedStyle: method_type_signature diff --git a/.rubocop_rbs.yml b/.rubocop_rbs.yml new file mode 100644 index 0000000..30da18f --- /dev/null +++ b/.rubocop_rbs.yml @@ -0,0 +1,11 @@ +# RuboCop configuration for Ruby 3.3+ with RBS Inline support +# This file should be loaded only when Ruby version is 3.3 or higher + +inherit_from: .rubocop.yml + +require: + - rubocop-rbs_inline + +# ========= RBS =========== +Style/RbsInline/MissingTypeAnnotation: + EnforcedStyle: method_type_signature diff --git a/Gemfile b/Gemfile index 97ab9d5..f27bc04 100644 --- a/Gemfile +++ b/Gemfile @@ -23,13 +23,17 @@ group :development, :test do gem 'factory_bot' gem 'lefthook', require: false gem 'rake', '~> 13.0' - gem 'rbs-inline', require: false gem 'rspec', '~> 3.0' gem 'rspec-parameterized' gem 'rubocop' gem 'rubocop-factory_bot', require: false gem 'rubocop-rake', require: false - gem 'rubocop-rbs_inline', require: false gem 'rubocop-rspec', require: false - gem 'steep', require: false + + # rbs-inline requires Ruby 3.3+ + if RUBY_VERSION >= '3.3.0' + gem 'rbs-inline', require: false + gem 'rubocop-rbs_inline', require: false + gem 'steep', require: false + end end diff --git a/Rakefile b/Rakefile index a9ab362..1bfe060 100644 --- a/Rakefile +++ b/Rakefile @@ -3,13 +3,29 @@ require 'bundler/gem_tasks' require 'rspec/core/rake_task' -require 'steep/rake_task' RSpec::Core::RakeTask.new(:spec) require 'rubocop/rake_task' -RuboCop::RakeTask.new -Steep::RakeTask.new +# Use RBS Inline configuration only for Ruby 3.3+ +rubocop_config = if RUBY_VERSION >= '3.3.0' + '.rubocop_rbs.yml' + else + '.rubocop.yml' + end -task default: %i[spec rubocop steep] +RuboCop::RakeTask.new do |task| + task.options = ['--config', rubocop_config] +end + +# Steep is only available for Ruby 3.3+ +default_tasks = [:spec, :rubocop] + +if RUBY_VERSION >= '3.3.0' + require 'steep/rake_task' + Steep::RakeTask.new + default_tasks << :steep +end + +task default: default_tasks From a1087781f2ab073ad67ecb0084619d4348bb6de7 Mon Sep 17 00:00:00 2001 From: mizuki-y Date: Sun, 1 Mar 2026 02:57:05 +0900 Subject: [PATCH 7/8] Update type annotations in dummy model classes to return String --- spec/type/array_spec.rb | 2 +- spec/type/object_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/type/array_spec.rb b/spec/type/array_spec.rb index fc573fb..a31473d 100644 --- a/spec/type/array_spec.rb +++ b/spec/type/array_spec.rb @@ -6,7 +6,7 @@ RSpec.describe StructuredParams::Type::Array do let(:dummy_model_class) do Class.new(StructuredParams::Params) do - #: () -> void + #: () -> String def self.name 'DummyModel' end diff --git a/spec/type/object_spec.rb b/spec/type/object_spec.rb index 7720ad4..694546b 100644 --- a/spec/type/object_spec.rb +++ b/spec/type/object_spec.rb @@ -8,7 +8,7 @@ let(:dummy_model_class) do Class.new(StructuredParams::Params) do - #: () -> void + #: () -> String def self.name 'DummyModel' end From d629feb90b0645f19c6d1d6edf07173c20f40df8 Mon Sep 17 00:00:00 2001 From: mizuki-y Date: Sun, 1 Mar 2026 03:07:37 +0900 Subject: [PATCH 8/8] Refactor RuboCop configuration to support RBS Inline and Ruby version checks --- .rubocop.yml | 2 +- .rubocop_rbs.yml | 4 +--- Rakefile | 4 ++-- bin/rubocop | 14 ++++++++++++++ 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100755 bin/rubocop diff --git a/.rubocop.yml b/.rubocop.yml index 9af088a..f7a8af6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,4 +1,4 @@ -require: +plugins: - rubocop-rspec - rubocop-rake - rubocop-factory_bot diff --git a/.rubocop_rbs.yml b/.rubocop_rbs.yml index 30da18f..a81a9f5 100644 --- a/.rubocop_rbs.yml +++ b/.rubocop_rbs.yml @@ -1,9 +1,7 @@ # RuboCop configuration for Ruby 3.3+ with RBS Inline support -# This file should be loaded only when Ruby version is 3.3 or higher - inherit_from: .rubocop.yml -require: +plugins: - rubocop-rbs_inline # ========= RBS =========== diff --git a/Rakefile b/Rakefile index 1bfe060..af5a5d4 100644 --- a/Rakefile +++ b/Rakefile @@ -8,7 +8,7 @@ RSpec::Core::RakeTask.new(:spec) require 'rubocop/rake_task' -# Use RBS Inline configuration only for Ruby 3.3+ +# Use RBS Inline configuration for Ruby 3.3+ rubocop_config = if RUBY_VERSION >= '3.3.0' '.rubocop_rbs.yml' else @@ -20,7 +20,7 @@ RuboCop::RakeTask.new do |task| end # Steep is only available for Ruby 3.3+ -default_tasks = [:spec, :rubocop] +default_tasks = %i[spec rubocop] if RUBY_VERSION >= '3.3.0' require 'steep/rake_task' diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 0000000..0ae32c8 --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# rbs_inline: enabled + +# Wrapper script for rubocop that automatically uses the correct config file +# based on Ruby version + +config_file = if RUBY_VERSION >= '3.3.0' && File.exist?('.rubocop_rbs.yml') + '.rubocop_rbs.yml' + else + '.rubocop.yml' + end + +exec('bundle', 'exec', 'rubocop', '--config', config_file, *ARGV)