diff --git a/.gitignore b/.gitignore index 9053d965..de8444e5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ /spec/reports/ /tmp/ Gemfile.lock +docs/_site/ +docs/.jekyll-cache/ +docs/.jekyll-metadata +docs/_data/versions.yml diff --git a/AGENTS.md b/AGENTS.md index 8af6c4d7..5d344624 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,6 +17,7 @@ This is the official Ruby SDK for the Model Context Protocol (MCP), implementing - `rake rubocop` - Run linter - `rake` - Run tests and linting (default task) - `bundle exec rake conformance` - Run the MCP conformance suite (see conformance/README.md) +- `bundle exec rake docs:preview` - Serve the documentation site locally at http://localhost:4000 (PORT to override) - `ruby -I lib -I test test/path/to/specific_test.rb` - Run single test file - `gem build mcp.gemspec` - Build the gem diff --git a/Rakefile b/Rakefile index 36da72c2..c795e565 100644 --- a/Rakefile +++ b/Rakefile @@ -51,6 +51,42 @@ task :conformance_server do Conformance::Server.new(**options).start end +namespace :docs do + desc "Serve the documentation site locally at http://localhost:4000 (PORT)" + task :preview do + docs_dir = File.expand_path("docs", __dir__) + generate_docs_versions_data(docs_dir) + + env = { + "BUNDLE_GEMFILE" => File.join(docs_dir, "Gemfile"), + "RUBYOPT" => "-r#{File.join(docs_dir, "_preview", "taint_shim.rb")}", + } + port = ENV.fetch("PORT", "4000") + + Bundler.with_unbundled_env do + system(env, "bundle", "install", "--quiet", chdir: docs_dir, exception: true) + system(env, "bundle", "exec", "jekyll", "serve", "--port", port, chdir: docs_dir, exception: true) + rescue Interrupt + # Ctrl-C is the way to stop the preview, not an error. + end + end +end + +# Mirrors bin/generate-gh-pages.sh: the released site receives `_data/versions.yml` from +# the version tags at deploy time, and the preview generates the same data so the nav footer +# shows the released-gem version line. +def generate_docs_versions_data(docs_dir) + versions = %x(git tag --list).split("\n").filter_map { |tag| + tag[/\A[^0-9]*(\d+\.\d+\.\d+(?:-[a-zA-Z0-9.-]+)?)\z/, 1] + }.sort_by { |version| + Gem::Version.new(version) + }.reverse + return if versions.empty? + + mkdir_p(File.join(docs_dir, "_data")) + File.write(File.join(docs_dir, "_data", "versions.yml"), versions.map { |version| "- #{version}\n" }.join) +end + def npx_available?(task_name) return true if system("which", "npx", out: File::NULL, err: File::NULL) diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 00000000..eb295d0b --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# Dependencies for the local docs preview (`rake docs:preview`), kept out of the gem's own Gemfile: +# github-pages mirrors the GitHub Pages runtime that builds the released site +# (jekyll-remote-theme, jekyll-redirect-from, and the Jekyll version Pages actually runs). +source "https://rubygems.org" + +gem "github-pages", group: :jekyll_plugins +gem "webrick" + +# Former default gems that the Jekyll version pinned by github-pages still requires on Ruby 4.0. +gem "base64" +gem "bigdecimal" +gem "csv" +gem "logger" diff --git a/docs/_preview/taint_shim.rb b/docs/_preview/taint_shim.rb new file mode 100644 index 00000000..9d43470b --- /dev/null +++ b/docs/_preview/taint_shim.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Liquid 4.0.3 (pinned by github-pages) still calls the taint API that Ruby 3.2 removed. +# Restore it as a no-op for the local docs preview only; `rake docs:preview` loads +# this file via `RUBYOPT`, so nothing outside the preview process is affected. +class Object + def tainted? + false + end + + def taint + self + end + + def untaint + self + end +end