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
10 changes: 10 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ jobs:
rails: '~> 8.0.0'
- ruby: '3.4'
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
Expand All @@ -39,6 +48,7 @@ jobs:
- name: Set Rails version
run: |
echo "RAILS_VERSION=${{ matrix.rails }}" >> $GITHUB_ENV
echo "RUBY_VERSION=${{ matrix.ruby }}" >> $GITHUB_ENV
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RUBY_VERSION is exported to $GITHUB_ENV here, but the workflow doesn’t reference it later (matrix values are used directly). Consider removing this line to avoid unused configuration, or use it in subsequent steps if it’s intended for tooling.

Suggested change
echo "RUBY_VERSION=${{ matrix.ruby }}" >> $GITHUB_ENV

Copilot uses AI. Check for mistakes.
- name: Install dependencies
run: |
bundle install --jobs 4 --retry 3
Expand Down
3 changes: 1 addition & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
plugins:
- rubocop-rspec
- rubocop-rake
- rubocop-rbs_inline
- rubocop-factory_bot

AllCops:
Expand All @@ -27,5 +26,5 @@ RSpec/ExampleLength:
Metrics/ClassLength:
Max: 150

Metrics/MethodLength:
Metrics/MethodLength:
Max: 20
9 changes: 9 additions & 0 deletions .rubocop_rbs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# RuboCop configuration for Ruby 3.3+ with RBS Inline support
inherit_from: .rubocop.yml

plugins:
- rubocop-rbs_inline

Comment on lines +2 to +6
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In .rubocop_rbs.yml, defining plugins: will override the plugins: list inherited from .rubocop.yml unless you explicitly merge. That can cause inherited cop configuration (e.g., RSpec/*) to become “unrecognized cop” when running with this config. Include the full plugin list here (rspec/rake/factory_bot + rbs_inline) or add an inherit_mode merge for plugins so all required plugins remain enabled.

Copilot uses AI. Check for mistakes.
# ========= RBS ===========
Style/RbsInline/MissingTypeAnnotation:
EnforcedStyle: method_type_signature
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.4.5
4.0.0
11 changes: 8 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

source 'https://rubygems.org'

Expand All @@ -22,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
Comment on lines +34 to +38
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RUBY_VERSION >= '3.3.0' compares strings lexicographically, which can give incorrect results for versions like 3.10.0. Use Gem::Version comparisons (or a helper constant) for reliable version gating.

Copilot uses AI. Check for mistakes.
end
25 changes: 21 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
# frozen_string_literal: true
# rbs_inline: enabled

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 for Ruby 3.3+
rubocop_config = if RUBY_VERSION >= '3.3.0'
'.rubocop_rbs.yml'
else
'.rubocop.yml'
end
Comment on lines +12 to +16
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RUBY_VERSION >= '3.3.0' check here is a lexicographic string comparison and can misbehave for versions like 3.10.0. Prefer Gem::Version comparisons for this gate.

Copilot uses AI. Check for mistakes.

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 = %i[spec rubocop]

if RUBY_VERSION >= '3.3.0'
require 'steep/rake_task'
Steep::RakeTask.new
default_tasks << :steep
end
Comment on lines +25 to +29
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ruby-version gate for enabling Steep uses RUBY_VERSION >= '3.3.0' (string comparison). Use Gem::Version comparisons so the condition stays correct across all future Ruby version formats.

Copilot uses AI. Check for mistakes.

task default: default_tasks
1 change: 1 addition & 0 deletions Steepfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

# D = Steep::Diagnostic
target :lib do
Expand Down
1 change: 1 addition & 0 deletions bin/console
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
# rbs_inline: enabled

require 'bundler/setup'
require 'structured_params'
Expand Down
14 changes: 14 additions & 0 deletions bin/rubocop
Original file line number Diff line number Diff line change
@@ -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)
10 changes: 3 additions & 7 deletions lib/structured_params/params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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)
Expand All @@ -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)

Expand Down
1 change: 1 addition & 0 deletions lib/structured_params/type/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions spec/errors_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

require 'spec_helper'

Expand Down
1 change: 1 addition & 0 deletions spec/factories/address_parameters.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

class AddressParameter < StructuredParams::Params
attribute :postal_code, :string
Expand Down
1 change: 1 addition & 0 deletions spec/factories/hobby_parameters.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

class HobbyParameter < StructuredParams::Params
attribute :name, :string
Expand Down
1 change: 1 addition & 0 deletions spec/factories/user_parameters.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

class UserParameter < StructuredParams::Params
attribute :name, :string
Expand Down
1 change: 1 addition & 0 deletions spec/params_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

require 'spec_helper'

Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

require 'structured_params'
require 'rspec-parameterized'
Expand Down
2 changes: 2 additions & 0 deletions spec/type/array_spec.rb
Original file line number Diff line number Diff line change
@@ -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
#: () -> String
def self.name
'DummyModel'
end
Expand Down
2 changes: 2 additions & 0 deletions spec/type/object_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

require 'spec_helper'

Expand All @@ -7,6 +8,7 @@

let(:dummy_model_class) do
Class.new(StructuredParams::Params) do
#: () -> String
def self.name
'DummyModel'
end
Expand Down
3 changes: 2 additions & 1 deletion structured_params.gemspec
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true
# rbs_inline: enabled

require_relative 'lib/structured_params/version'

Expand All @@ -12,7 +13,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',
Expand Down