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
1 change: 0 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
- macos

ruby:
- "3.2"
- "3.3"
- "3.4"

Expand Down
26 changes: 9 additions & 17 deletions bake/utopia/project.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2020-2025, by Samuel Williams.
# Copyright, 2020-2026, by Samuel Williams.

def initialize(context)
super
Expand Down Expand Up @@ -35,7 +35,7 @@ def update
# @parameter port [Integer] The port to bind to.
# @parameter bind [String] The URL to bind to, e.g. `http://localhost:80`.
def serve(port: nil, bind: nil)
config_path = File.expand_path("../../template/config.ru", __dir__)
config_path = File.expand_path("../../template/config/serve.rb", __dir__)
preload_path = File.expand_path("../../template/preload.rb", __dir__)

options = []
Expand All @@ -55,22 +55,15 @@ def serve(port: nil, bind: nil)
# @parameter output_path [String] The output path for the static site.
# @parameter force [Boolean] Remove the output directory before generating the static content.
def static(output_path: "docs", force: true)
require "rackula/command"

config_path = File.expand_path("../../template/config.ru", __dir__)
application_path = File.expand_path("../../template/config/application.rb", __dir__)
public_path = File.expand_path("../../public", __dir__)

arguments = []

if force
arguments << "--force"
end

Rackula::Command::Top["generate", *arguments,
"--config", config_path,
"--public", public_path,
"--output-path", output_path
].call
context["utopia:static:generate"].call(
output_path: output_path,
application_path: application_path,
public_path: public_path,
force: force,
)

FileUtils.touch File.expand_path(".nojekyll", output_path)
end
Expand All @@ -94,4 +87,3 @@ def description(root: context.root)
end
end
end

3 changes: 1 addition & 2 deletions gems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@

group :test do
gem "sus"
gem "sus-fixtures-protocol-http", "~> 0.1"
gem "covered"
gem "decode"

gem "rubocop"
gem "rubocop-md"
gem "rubocop-socketry"

gem "rack-test"

gem "bake-test"
end
17 changes: 9 additions & 8 deletions lib/utopia/project.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2020-2025, by Samuel Williams.
# Copyright, 2020-2026, by Samuel Williams.

require "utopia/project/version"

require "variant"

require "utopia/application"
require "utopia/content"
require "utopia/controller"
require "utopia/exceptions"
require "utopia/localization"
require "utopia/redirection"
require "utopia/static"

require_relative "project/base"
require_relative "project/import_map"
Expand All @@ -23,19 +29,16 @@ module Project
# The root directory for static assets.
PUBLIC_ROOT = File.expand_path("public", SITE_ROOT)

# Appends a project application to the rack builder.
# Appends a project application to the protocol HTTP middleware builder.
#
# @parameter builder [Rack::Builder]
# @parameter builder [Protocol::HTTP::Middleware::Builder]
# @parameter root [String] The file-system root path of the project/gem.
# @parameter locales [Array(String)] an array of locales to support, e.g. `['en', 'ja']`.
def self.call(builder, root = Dir.pwd, locales: nil)
if UTOPIA.production?
# Handle exceptions in production with a error page and send an email notification:
builder.use Utopia::Exceptions::Handler
builder.use Utopia::Exceptions::Mailer
else
# We want to propate exceptions up when running tests:
builder.use Rack::ShowExceptions unless UTOPIA.testing?
end

# We serve static files from the project root:
Expand All @@ -46,7 +49,6 @@ def self.call(builder, root = Dir.pwd, locales: nil)
builder.use Utopia::Redirection::Rewrite, {
"/" => "/index"
}

builder.use Utopia::Redirection::DirectoryIndex

builder.use Utopia::Redirection::Errors, {
Expand All @@ -67,7 +69,6 @@ def self.call(builder, root = Dir.pwd, locales: nil)
# 'gallery' => Utopia::Gallery::Tags.new
}

builder.run lambda {|env| [404, {}, []]}
end
end
end
5 changes: 2 additions & 3 deletions lib/utopia/project/guides.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ def to_a
# @parameter name [String] The guide name.
# @returns [Guide | Nil]
def [](name)
to_a.find { |guide| guide.name == name }
to_a.find{|guide| guide.name == name}
end

# Get the related guides (previous and next) for the given guide.
# @parameter guide [Guide] The current guide.
# @returns [Array(Guide | Nil, Guide | Nil)] A two-element array containing the previous and next guides.
def related(guide)
index = to_a.index { |g| g.name == guide.name }
index = to_a.index{|g| g.name == guide.name}
return [nil, nil] unless index

previous_guide = index > 0 ? to_a[index - 1] : nil
Expand All @@ -63,4 +63,3 @@ def related(guide)
end
end
end

6 changes: 3 additions & 3 deletions pages/_header.xnode
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
path = path + "index"
end

if link = links(path.dirname, name: path.last, locale: localization.current_locale, indices: true).first
if link = links(path.dirname, name: path.last, locale: localization&.locale, indices: true).first
if replace = link[:replace]&.to_sym and base = controller[:base]
?> &rsaquo; #{link.to_href(content: base.public_send(replace))}<?r
else
Expand All @@ -30,11 +30,11 @@
?> &rsaquo; <a href="/guides/#{guide.name}/index">#{guide.title}</a> <?r
end

if localization.localized?
if localization&.localized?
?> &bull; (<?r
localization.all_locales.each.with_index do |locale, index|
?>#{index.zero? ? '' : ' '}<a href="#{localization.localized_path(page_path, locale)}">#{locale}</a><?r
end
?>)<?r
end
?></header>
?></header>
2 changes: 1 addition & 1 deletion pages/_page.xnode
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<link rel="icon" type="image/png" href="/_static/icon.png" />
<link rel="stylesheet" href="/_static/site.css" type="text/css" media="screen" />

#{Utopia::Project::IMPORT_MAP.relative_to(request.env["REQUEST_PATH"]).to_html}
#{Utopia::Project::IMPORT_MAP.relative_to(request.request_path).to_html}
<script type="module" src="/_static/application.js"></script>
</head>
<body>
Expand Down
1 change: 1 addition & 0 deletions releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- Don't render empty signature block when there are only examples.
- Use protocol HTTP middleware for serving and testing project documentation.

## v0.40.0

Expand Down
7 changes: 0 additions & 7 deletions template/config.ru

This file was deleted.

12 changes: 12 additions & 0 deletions template/config/application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2026, by Samuel Williams.

require_relative "environment"

require "utopia/project"

Application = Utopia::Application.build do |builder|
Utopia::Project.call(builder)
end
8 changes: 8 additions & 0 deletions template/config/environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2026, by Samuel Williams.

require "utopia/setup"

UTOPIA ||= Utopia.setup(File.expand_path("..", __dir__))
8 changes: 8 additions & 0 deletions template/config/serve.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2026, by Samuel Williams.

require "utopia/application"

run Utopia::Application.load(File.expand_path("application.rb", __dir__))
37 changes: 11 additions & 26 deletions test/utopia/project/serve.rb
Original file line number Diff line number Diff line change
@@ -1,52 +1,37 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2020-2025, by Samuel Williams.
# Copyright, 2020-2026, by Samuel Williams.

require "utopia/project"

require "rack/builder"
require "rack/test"
require "protocol/http/middleware/builder"
require "sus/fixtures/protocol/http/middleware_context"

describe Utopia::Project do
include Rack::Test::Methods
include Sus::Fixtures::Protocol::HTTP::MiddlewareContext

let(:template_root) {File.expand_path("../../../template", __dir__)}

let(:rackup_path) {File.expand_path("config.ru", template_root)}
let(:rackup_directory) {File.dirname(rackup_path)}
let(:configuration_path) {File.expand_path("config/serve.rb", template_root)}

let(:app) do
inner_app = Rack::Builder.parse_file(rackup_path)

# Middleware to set REQUEST_PATH from PATH_INFO
lambda do |env|
env["REQUEST_PATH"] ||= env["PATH_INFO"]
inner_app.call(env)
end
let(:middleware) do
Protocol::HTTP::Middleware.load(configuration_path)
end

it "has root page" do
get "/index"

expect(last_response.body).to be(:include?, "Project")
expect(client.get("/index").read).to be(:include?, "Project")
end

it "has guide page" do
get "/guides/getting-started/index"

expect(last_response.body).to be(:include?, "Getting Started")
expect(client.get("/guides/getting-started/index").read).to be(:include?, "Getting Started")
end

it "has source code index" do
get "/source/index"

expect(last_response.body).to be(:include?, "module Utopia")
expect(client.get("/source/index").read).to be(:include?, "module Utopia")
end

it "has source code file" do
get "/source/Utopia/Project/Base/index"

expect(last_response.body).to be(:include?, "def initialize")
expect(client.get("/source/Utopia/Project/Base/index").read).to be(:include?, "def initialize")
end
end
5 changes: 2 additions & 3 deletions utopia-project.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ Gem::Specification.new do |spec|

spec.files = Dir.glob(["{bake,context,lib,pages,public,template}/**/*", "*.md"], File::FNM_DOTMATCH, base: __dir__)

spec.required_ruby_version = ">= 3.2"
spec.required_ruby_version = ">= 3.3"

spec.add_dependency "decode", "~> 0.26"
spec.add_dependency "falcon"
spec.add_dependency "markly", "~> 0.15"
spec.add_dependency "rackula", "~> 1.3"
spec.add_dependency "thread-local"
spec.add_dependency "utopia", "~> 2.32"
spec.add_dependency "utopia", "~> 3.0"
end
Loading