Add a rake docs:preview task serving the docs site locally
## Motivation and Context The documentation site under `docs/` had no development command: previewing a change meant hand-assembling a Jekyll environment, since the site only builds for real when a release publishes it through `bin/generate-gh-pages.sh` and the GitHub Pages runtime. `rake docs:preview` now builds and serves the site at http://localhost:4000 (override with `PORT`), with watch-based rebuilds on edit. The preview dependencies live in their own `docs/Gemfile` rather than the gem's Gemfile: `github-pages` mirrors the runtime that builds the released site (jekyll-remote-theme, jekyll-redirect-from, and the Jekyll version Pages actually runs), which keeps the preview faithful but is far too heavy to impose on the gem itself. The task subshells into that bundle with `Bundler.with_unbundled_env`, the same delegation shape the conformance tasks use for npx. Two support pieces keep the pinned toolchain running on current Ruby. `docs/_preview/taint_shim.rb` restores the taint API as no-ops: Liquid 4.0.3 calls `obj.tainted?` on every variable render, ahead of its own lax-mode check (`liquid/variable.rb:124`), so on Ruby 3.2 and later, where the taint API was removed, the first layout render dies with NoMethodError, while on Ruby 3.1 and earlier the methods still exist as deprecated no-ops and the shim is inert. The shim is loaded only into the preview process via RUBYOPT. The former default gems the pinned Jekyll expects are listed in the docs Gemfile. The task also regenerates `docs/_data/versions.yml` from the version tags, mirroring what `bin/generate-gh-pages.sh` produces at deploy time, so the nav footer shows the released-gem version line exactly as it does on the published site. Build products and the generated data file are ignored. ## How Has This Been Tested? By running the task on a spare port and verifying the served pages, the footer's version line, and that a SIGINT stops it cleanly with exit 0; `git status` stays clean while it runs (all build products ignored). Verified on both Ruby 3.1.5 (shim inert) and Ruby 4.0.6, where a shimless build reproduces the NoMethodError and the task runs green with the shim. RuboCop and the full suite are green. ## Breaking Changes None. The task and its Gemfile are development-only additions; the gem and its dependencies are untouched.
This commit is contained in:
parent
3b79c8e58a
commit
636e494068
5 changed files with 74 additions and 0 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -9,3 +9,7 @@
|
||||||
/spec/reports/
|
/spec/reports/
|
||||||
/tmp/
|
/tmp/
|
||||||
Gemfile.lock
|
Gemfile.lock
|
||||||
|
docs/_site/
|
||||||
|
docs/.jekyll-cache/
|
||||||
|
docs/.jekyll-metadata
|
||||||
|
docs/_data/versions.yml
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ This is the official Ruby SDK for the Model Context Protocol (MCP), implementing
|
||||||
- `rake rubocop` - Run linter
|
- `rake rubocop` - Run linter
|
||||||
- `rake` - Run tests and linting (default task)
|
- `rake` - Run tests and linting (default task)
|
||||||
- `bundle exec rake conformance` - Run the MCP conformance suite (see conformance/README.md)
|
- `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
|
- `ruby -I lib -I test test/path/to/specific_test.rb` - Run single test file
|
||||||
- `gem build mcp.gemspec` - Build the gem
|
- `gem build mcp.gemspec` - Build the gem
|
||||||
|
|
||||||
|
|
|
||||||
36
Rakefile
36
Rakefile
|
|
@ -51,6 +51,42 @@ task :conformance_server do
|
||||||
Conformance::Server.new(**options).start
|
Conformance::Server.new(**options).start
|
||||||
end
|
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)
|
def npx_available?(task_name)
|
||||||
return true if system("which", "npx", out: File::NULL, err: File::NULL)
|
return true if system("which", "npx", out: File::NULL, err: File::NULL)
|
||||||
|
|
||||||
|
|
|
||||||
15
docs/Gemfile
Normal file
15
docs/Gemfile
Normal file
|
|
@ -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"
|
||||||
18
docs/_preview/taint_shim.rb
Normal file
18
docs/_preview/taint_shim.rb
Normal file
|
|
@ -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
|
||||||
Loading…
Reference in a new issue