## Motivation and Context
The gemspec already declares `required_ruby_version >= 2.7.0`, but the conformance Rake task used `Hash#except` to drop
the `:port` option before handing the remaining options to `Conformance::ClientRunner`. `Hash#except` was only added in Ruby 3.0,
so running `rake conformance` on Ruby 2.7 aborted before any scenario ran, raising `NoMethodError: undefined method except for {}:Hash`.
CI missed this because no job runs `rake conformance` on Ruby 2.7: the conformance workflow runs only on Ruby 4.0,
while the Ruby 2.7.0 matrix entry runs `rake test` alone.
## How Has This Been Tested?
Replace `options.except(:port)` with `options.reject { |key, _| key == :port }`, which has been available since well
before Ruby 2.7 and returns an equivalent Hash without mutating the original. `rake conformance` now runs the full suite on Ruby 2.7,
and its baseline still passes on current Ruby, verified on Ruby 4.0.
## Breaking Changes
None.
59 lines
1.7 KiB
Ruby
59 lines
1.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "bundler/gem_tasks"
|
|
require "rake/testtask"
|
|
|
|
Rake::TestTask.new(:test) do |t|
|
|
t.ruby_opts = ["-W0", "-W:deprecated"]
|
|
t.libs << "test"
|
|
t.libs << "lib"
|
|
t.test_files = FileList["test/**/*_test.rb"]
|
|
end
|
|
|
|
require "rubocop/rake_task"
|
|
|
|
RuboCop::RakeTask.new
|
|
|
|
task default: [:rubocop, :test, :conformance]
|
|
|
|
desc "Run MCP conformance tests (PORT, SCENARIO, SPEC_VERSION, VERBOSE)"
|
|
task :conformance do |t|
|
|
next unless npx_available?(t.name)
|
|
|
|
require_relative "conformance/server_runner"
|
|
require_relative "conformance/client_runner"
|
|
|
|
options = {}
|
|
options[:port] = Integer(ENV["PORT"]) if ENV["PORT"]
|
|
options[:scenario] = ENV["SCENARIO"] if ENV["SCENARIO"]
|
|
options[:spec_version] = ENV["SPEC_VERSION"] if ENV["SPEC_VERSION"]
|
|
options[:verbose] = true if ENV["VERBOSE"]
|
|
|
|
Conformance::ServerRunner.new(**options).run
|
|
Conformance::ClientRunner.new(**options.reject { |key, _value| key == :port }).run
|
|
end
|
|
|
|
desc "List available conformance scenarios"
|
|
task :conformance_list do |t|
|
|
next unless npx_available?(t.name)
|
|
|
|
system("npx", "--yes", "@modelcontextprotocol/conformance", "list", "--server")
|
|
system("npx", "--yes", "@modelcontextprotocol/conformance", "list", "--client")
|
|
end
|
|
|
|
desc "Start the conformance server (PORT)"
|
|
task :conformance_server do
|
|
require_relative "conformance/server"
|
|
|
|
options = {}
|
|
options[:port] = Integer(ENV["PORT"]) if ENV["PORT"]
|
|
|
|
Conformance::Server.new(**options).start
|
|
end
|
|
|
|
def npx_available?(task_name)
|
|
return true if system("which", "npx", out: File::NULL, err: File::NULL)
|
|
|
|
warn("Skipping #{task_name}: npx is not installed. Install Node.js to run this task: https://nodejs.org/")
|
|
false
|
|
end
|