bridgetown-core 1.2.0 → 1.3.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bridgetown-core.gemspec +21 -22
- data/lib/bridgetown-core/collection.rb +1 -1
- data/lib/bridgetown-core/commands/new.rb +2 -0
- data/lib/bridgetown-core/configuration/configuration_dsl.rb +1 -1
- data/lib/bridgetown-core/configurations/purgecss.rb +1 -1
- data/lib/bridgetown-core/errors.rb +10 -1
- data/lib/bridgetown-core/rack/boot.rb +13 -1
- data/lib/bridgetown-core/rack/routes.rb +40 -6
- data/lib/bridgetown-core/readers/layout_reader.rb +2 -2
- data/lib/bridgetown-core/utils/loaders_manager.rb +4 -0
- data/lib/bridgetown-core/utils.rb +18 -0
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/bridgetown-core/watcher.rb +1 -1
- data/lib/bridgetown-core.rb +12 -0
- data/lib/roda/plugins/bridgetown_server.rb +140 -0
- data/lib/site_template/Gemfile.erb +6 -3
- data/lib/site_template/server/roda_app.rb +4 -2
- data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
- metadata +10 -27
- data/lib/bridgetown-core/commands/serve/servlet.rb +0 -68
- data/lib/bridgetown-core/commands/serve.rb +0 -253
- data/lib/bridgetown-core/rack/roda.rb +0 -157
- data/lib/roda/plugins/bridgetown_boot.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9176399e9b750178476e2d57edb346989426407d5d40e8958c5be3901626f77f
|
4
|
+
data.tar.gz: a5130e5511c64acba6e6ee619a7529b49415e1c25b3e056cf4e709c4d78361da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 849bff55f1997483ce24f67536daec7bdd53ff016d7e4ab8937b0184892680eb59f159d3a3d26c22fbc63ef63486ddd1b793943cd21fead6c281f0d2d9698f69
|
7
|
+
data.tar.gz: e5c317edb3ae4e232cd2a56c885b44af5375d7daeff71f385e620d402cbe57c68cf32fdc6eb13508bb92e3e8dff254cf53e59f56790631692eee092c6eaa0463
|
data/bridgetown-core.gemspec
CHANGED
@@ -31,26 +31,25 @@ Gem::Specification.new do |s|
|
|
31
31
|
|
32
32
|
s.required_ruby_version = ">= 2.7.0"
|
33
33
|
|
34
|
-
s.add_runtime_dependency("activemodel",
|
35
|
-
s.add_runtime_dependency("activesupport",
|
36
|
-
s.add_runtime_dependency("addressable",
|
37
|
-
s.add_runtime_dependency("amazing_print",
|
38
|
-
s.add_runtime_dependency("colorator",
|
39
|
-
s.add_runtime_dependency("erubi",
|
40
|
-
s.add_runtime_dependency("faraday",
|
41
|
-
s.add_runtime_dependency("
|
42
|
-
s.add_runtime_dependency("hash_with_dot_access",
|
43
|
-
s.add_runtime_dependency("i18n",
|
44
|
-
s.add_runtime_dependency("kramdown",
|
45
|
-
s.add_runtime_dependency("kramdown-parser-gfm",
|
46
|
-
s.add_runtime_dependency("liquid",
|
47
|
-
s.add_runtime_dependency("listen",
|
48
|
-
s.add_runtime_dependency("rake",
|
49
|
-
s.add_runtime_dependency("roda",
|
50
|
-
s.add_runtime_dependency("rouge",
|
51
|
-
s.add_runtime_dependency("serbea",
|
52
|
-
s.add_runtime_dependency("thor",
|
53
|
-
s.add_runtime_dependency("tilt",
|
54
|
-
s.add_runtime_dependency("
|
55
|
-
s.add_runtime_dependency("zeitwerk", "~> 2.5")
|
34
|
+
s.add_runtime_dependency("activemodel", [">= 6.0", "< 8.0"])
|
35
|
+
s.add_runtime_dependency("activesupport", [">= 6.0", "< 8.0"])
|
36
|
+
s.add_runtime_dependency("addressable", "~> 2.4")
|
37
|
+
s.add_runtime_dependency("amazing_print", "~> 1.2")
|
38
|
+
s.add_runtime_dependency("colorator", "~> 1.0")
|
39
|
+
s.add_runtime_dependency("erubi", "~> 1.9")
|
40
|
+
s.add_runtime_dependency("faraday", "~> 2.0")
|
41
|
+
s.add_runtime_dependency("faraday-follow_redirects", "~> 0.3")
|
42
|
+
s.add_runtime_dependency("hash_with_dot_access", "~> 1.2")
|
43
|
+
s.add_runtime_dependency("i18n", "~> 1.0")
|
44
|
+
s.add_runtime_dependency("kramdown", "~> 2.1")
|
45
|
+
s.add_runtime_dependency("kramdown-parser-gfm", "~> 1.0")
|
46
|
+
s.add_runtime_dependency("liquid", "~> 5.0")
|
47
|
+
s.add_runtime_dependency("listen", "~> 3.0")
|
48
|
+
s.add_runtime_dependency("rake", ">= 13.0")
|
49
|
+
s.add_runtime_dependency("roda", "~> 3.46")
|
50
|
+
s.add_runtime_dependency("rouge", "~> 3.0")
|
51
|
+
s.add_runtime_dependency("serbea", "~> 1.0")
|
52
|
+
s.add_runtime_dependency("thor", "~> 1.1")
|
53
|
+
s.add_runtime_dependency("tilt", "~> 2.0")
|
54
|
+
s.add_runtime_dependency("zeitwerk", "~> 2.5")
|
56
55
|
end
|
@@ -282,7 +282,7 @@ module Bridgetown
|
|
282
282
|
if model_is_multi_locale?(model, model_relative_path)
|
283
283
|
# If the model specifies a locales key, use that to determine the
|
284
284
|
# the locale of each resource, otherwise fall back to `site.config.available_locales`
|
285
|
-
locales = model.locales || site.config.available_locales
|
285
|
+
locales = model.attributes[:locales] || site.config.available_locales
|
286
286
|
|
287
287
|
locales.each do |locale|
|
288
288
|
model.locale = locale.to_sym
|
@@ -80,6 +80,8 @@ module Bridgetown
|
|
80
80
|
after_install new_site_path, args.join(" "), options
|
81
81
|
rescue ArgumentError => e
|
82
82
|
say_status :alert, e.message, :red
|
83
|
+
ensure
|
84
|
+
self.class.created_site_dir = nil # reset afterwards, otherwise hanging tmp dirs in test
|
83
85
|
end
|
84
86
|
|
85
87
|
protected
|
@@ -49,7 +49,7 @@ module Bridgetown
|
|
49
49
|
priority: Bridgetown::Hooks::DEFAULT_PRIORITY,
|
50
50
|
&block
|
51
51
|
)
|
52
|
-
Bridgetown::Hooks.register_one(owner, event, priority: priority, &block)
|
52
|
+
Bridgetown::Hooks.register_one(owner, event, priority: priority, reloadable: false, &block)
|
53
53
|
end
|
54
54
|
|
55
55
|
def source_manifest(**kwargs)
|
@@ -31,7 +31,7 @@ create_builder "purgecss.rb" do
|
|
31
31
|
manifest = JSON.parse(File.read(manifest_file))
|
32
32
|
|
33
33
|
if Bridgetown::Utils.frontend_bundler_type == :esbuild
|
34
|
-
css_file = manifest["styles/index.css"].split("/").last
|
34
|
+
css_file = (manifest["styles/index.css"] || manifest["styles/index.scss"]).split("/").last
|
35
35
|
css_path = ["output", "_bridgetown", "static", css_file].join("/")
|
36
36
|
else
|
37
37
|
css_file = manifest["main.css"].split("/").last
|
@@ -15,10 +15,13 @@ module Bridgetown
|
|
15
15
|
InvalidURLError = Class.new(FatalException)
|
16
16
|
InvalidConfigurationError = Class.new(FatalException)
|
17
17
|
|
18
|
-
def self.print_build_error(exc, trace: false, logger: Bridgetown.logger)
|
18
|
+
def self.print_build_error(exc, trace: false, logger: Bridgetown.logger, server: false) # rubocop:disable Metrics
|
19
19
|
logger.error "Exception raised:", exc.class.to_s.bold
|
20
20
|
logger.error exc.message.reset_ansi
|
21
21
|
|
22
|
+
build_errors_file = Bridgetown.build_errors_path if !server && Bridgetown::Current.site
|
23
|
+
build_errors_data = "#{exc.class}: #{exc.message}"
|
24
|
+
|
22
25
|
trace_args = ["-t", "--trace"]
|
23
26
|
print_trace_msg = true
|
24
27
|
traces = if trace || ARGV.find { |arg| trace_args.include?(arg) }
|
@@ -29,6 +32,12 @@ module Bridgetown
|
|
29
32
|
end
|
30
33
|
traces.each_with_index do |backtrace_line, index|
|
31
34
|
logger.error "#{index + 1}:", backtrace_line.reset_ansi
|
35
|
+
build_errors_data << "\n#{backtrace_line}" if index < 2
|
36
|
+
end
|
37
|
+
|
38
|
+
if build_errors_file
|
39
|
+
FileUtils.mkdir_p(File.dirname(build_errors_file))
|
40
|
+
File.write(build_errors_file, build_errors_data, mode: "w")
|
32
41
|
end
|
33
42
|
|
34
43
|
return unless print_trace_msg
|
@@ -8,12 +8,22 @@ require "roda/plugins/public"
|
|
8
8
|
Bridgetown::Current.preloaded_configuration ||= Bridgetown.configuration
|
9
9
|
|
10
10
|
require_relative "logger"
|
11
|
-
require_relative "roda"
|
12
11
|
require_relative "routes"
|
13
12
|
require_relative "static_indexes"
|
14
13
|
|
15
14
|
module Bridgetown
|
16
15
|
module Rack
|
16
|
+
class Roda < ::Roda
|
17
|
+
def self.inherited(klass)
|
18
|
+
Bridgetown::Deprecator.deprecation_message(
|
19
|
+
"The `Bridgetown::Rack::Roda' class will be removed in favor of using the " \
|
20
|
+
"`bridgetown_server' plugin in a future version"
|
21
|
+
)
|
22
|
+
super
|
23
|
+
klass.plugin :bridgetown_server
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
17
27
|
class << self
|
18
28
|
# @return [Bridgetown::Utils::LoadersManager]
|
19
29
|
attr_accessor :loaders_manager
|
@@ -56,6 +66,8 @@ module Bridgetown
|
|
56
66
|
loader.reload
|
57
67
|
loader.eager_load
|
58
68
|
Bridgetown::Rack::Routes.reload_subclasses
|
69
|
+
rescue SyntaxError => e
|
70
|
+
Bridgetown::Errors.print_build_error(e)
|
59
71
|
end.start
|
60
72
|
end
|
61
73
|
end
|
@@ -20,6 +20,37 @@ module Bridgetown
|
|
20
20
|
}.freeze
|
21
21
|
|
22
22
|
class << self
|
23
|
+
# rubocop:disable Bridgetown/NoPutsAllowed, Metrics/MethodLength
|
24
|
+
def print_routes
|
25
|
+
# TODO: this needs to be fully documented
|
26
|
+
routes = begin
|
27
|
+
JSON.parse(
|
28
|
+
File.read(
|
29
|
+
File.join(Bridgetown::Current.preloaded_configuration.root_dir, ".routes.json")
|
30
|
+
)
|
31
|
+
)
|
32
|
+
rescue StandardError
|
33
|
+
[]
|
34
|
+
end
|
35
|
+
puts
|
36
|
+
puts "Routes:"
|
37
|
+
puts "======="
|
38
|
+
if routes.blank?
|
39
|
+
puts "No routes found. Have you commented all of your routes?"
|
40
|
+
puts "Documentation: https://github.com/jeremyevans/roda-route_list#basic-usage-"
|
41
|
+
end
|
42
|
+
|
43
|
+
routes.each do |route|
|
44
|
+
puts [
|
45
|
+
route["methods"]&.join("|") || "GET",
|
46
|
+
route["path"],
|
47
|
+
route["file"] ? "\n File: #{route["file"]}" : nil,
|
48
|
+
].compact.join(" ")
|
49
|
+
end
|
50
|
+
puts
|
51
|
+
end
|
52
|
+
# rubocop:enable Bridgetown/NoPutsAllowed, Metrics/MethodLength
|
53
|
+
|
23
54
|
# @return [Hash<String, Class(Routes)>]
|
24
55
|
attr_accessor :tracked_subclasses
|
25
56
|
|
@@ -80,7 +111,7 @@ module Bridgetown
|
|
80
111
|
# Initialize a new Routes instance and execute the route as part of the
|
81
112
|
# Roda app request cycle
|
82
113
|
#
|
83
|
-
# @param roda_app [
|
114
|
+
# @param roda_app [Roda]
|
84
115
|
def merge(roda_app)
|
85
116
|
return unless router_block
|
86
117
|
|
@@ -90,7 +121,7 @@ module Bridgetown
|
|
90
121
|
# Start the Roda app request cycle. There are two different code paths
|
91
122
|
# depending on if there's a site `base_path` configured
|
92
123
|
#
|
93
|
-
# @param roda_app [
|
124
|
+
# @param roda_app [Roda]
|
94
125
|
# @return [void]
|
95
126
|
def start!(roda_app)
|
96
127
|
if Bridgetown::Current.preloaded_configuration.base_path == "/"
|
@@ -112,7 +143,7 @@ module Bridgetown
|
|
112
143
|
# run through all the Routes blocks. If the file-based router plugin
|
113
144
|
# is available, kick off that request process next.
|
114
145
|
#
|
115
|
-
# @param roda_app [
|
146
|
+
# @param roda_app [Roda]
|
116
147
|
# @return [void]
|
117
148
|
def load_all_routes(roda_app)
|
118
149
|
roda_app.request.public
|
@@ -127,11 +158,12 @@ module Bridgetown
|
|
127
158
|
end
|
128
159
|
end
|
129
160
|
|
130
|
-
# @param app [
|
131
|
-
def setup_live_reload(app) # rubocop:disable Metrics
|
161
|
+
# @param app [Roda]
|
162
|
+
def setup_live_reload(app) # rubocop:disable Metrics
|
132
163
|
sleep_interval = 0.2
|
133
164
|
file_to_check = File.join(Bridgetown::Current.preloaded_configuration.destination,
|
134
165
|
"index.html")
|
166
|
+
errors_file = Bridgetown.build_errors_path
|
135
167
|
|
136
168
|
app.request.get "_bridgetown/live_reload" do
|
137
169
|
app.response["Content-Type"] = "text/event-stream"
|
@@ -146,6 +178,8 @@ module Bridgetown
|
|
146
178
|
if @_mod < new_mod
|
147
179
|
out << "data: reloaded!\n\n"
|
148
180
|
break
|
181
|
+
elsif File.exist?(errors_file)
|
182
|
+
out << "event: builderror\ndata: #{File.read(errors_file).to_json}\n\n"
|
149
183
|
else
|
150
184
|
out << "data: #{new_mod}\n\n"
|
151
185
|
end
|
@@ -157,7 +191,7 @@ module Bridgetown
|
|
157
191
|
end
|
158
192
|
end
|
159
193
|
|
160
|
-
# @param roda_app [
|
194
|
+
# @param roda_app [Roda]
|
161
195
|
def initialize(roda_app)
|
162
196
|
@_roda_app = roda_app
|
163
197
|
end
|
@@ -11,13 +11,13 @@ module Bridgetown
|
|
11
11
|
|
12
12
|
def read
|
13
13
|
layout_entries.each do |layout_file|
|
14
|
-
@layouts[layout_name(layout_file)] =
|
14
|
+
@layouts[layout_name(layout_file)] =
|
15
15
|
Layout.new(site, layout_directory, layout_file)
|
16
16
|
end
|
17
17
|
|
18
18
|
site.config.source_manifests.filter_map(&:layouts).each do |plugin_layouts|
|
19
19
|
layout_entries(plugin_layouts).each do |layout_file|
|
20
|
-
@layouts[layout_name(layout_file)] ||=
|
20
|
+
@layouts[layout_name(layout_file)] ||=
|
21
21
|
Layout.new(site, plugin_layouts, layout_file, from_plugin: true)
|
22
22
|
end
|
23
23
|
end
|
@@ -13,6 +13,8 @@ module Bridgetown
|
|
13
13
|
@config = config
|
14
14
|
@loaders = {}
|
15
15
|
@root_dir = config.root_dir
|
16
|
+
|
17
|
+
FileUtils.rm_f(Bridgetown.build_errors_path)
|
16
18
|
end
|
17
19
|
|
18
20
|
def unload_loaders
|
@@ -75,6 +77,8 @@ module Bridgetown
|
|
75
77
|
end
|
76
78
|
|
77
79
|
def reload_loaders
|
80
|
+
FileUtils.rm_f(Bridgetown.build_errors_path)
|
81
|
+
|
78
82
|
@loaders.each do |load_path, loader|
|
79
83
|
next unless reloading_enabled?(load_path)
|
80
84
|
|
@@ -466,6 +466,7 @@ module Bridgetown
|
|
466
466
|
function startReloadConnection() {
|
467
467
|
const evtSource = new EventSource("#{site.base_path(strip_slash_only: true)}/_bridgetown/live_reload")
|
468
468
|
evtSource.onmessage = event => {
|
469
|
+
if (document.querySelector("#bridgetown-build-error")) document.querySelector("#bridgetown-build-error").close()
|
469
470
|
if (event.data == "reloaded!") {
|
470
471
|
location.reload()
|
471
472
|
} else {
|
@@ -477,6 +478,23 @@ module Bridgetown
|
|
477
478
|
}
|
478
479
|
}
|
479
480
|
}
|
481
|
+
evtSource.addEventListener("builderror", event => {
|
482
|
+
let dialog = document.querySelector("#bridgetown-build-error")
|
483
|
+
if (!dialog) {
|
484
|
+
dialog = document.createElement("dialog")
|
485
|
+
dialog.id = "bridgetown-build-error"
|
486
|
+
dialog.style.borderColor = "red"
|
487
|
+
dialog.style.fontSize = "110%"
|
488
|
+
dialog.innerHTML = `
|
489
|
+
<p style="color:red">There was an error when building the site:</p>
|
490
|
+
<output><pre></pre></output>
|
491
|
+
<p><small>Check your Bridgetown logs for further details.</small></p>
|
492
|
+
`
|
493
|
+
document.body.appendChild(dialog)
|
494
|
+
dialog.showModal()
|
495
|
+
}
|
496
|
+
dialog.querySelector("pre").textContent = JSON.parse(event.data)
|
497
|
+
})
|
480
498
|
evtSource.onerror = event => {
|
481
499
|
if (evtSource.readyState === 2) {
|
482
500
|
// reconnect with new object
|
@@ -106,7 +106,7 @@ module Bridgetown
|
|
106
106
|
end
|
107
107
|
Bridgetown.logger.info "Done! 🎉", "#{"Completed".bold.green} in less than " \
|
108
108
|
"#{(Time.now - time).ceil(2)} seconds."
|
109
|
-
rescue StandardError => e
|
109
|
+
rescue StandardError, SyntaxError => e
|
110
110
|
Bridgetown::Errors.print_build_error(e, trace: options[:trace])
|
111
111
|
end
|
112
112
|
Bridgetown.logger.info ""
|
data/lib/bridgetown-core.rb
CHANGED
@@ -377,6 +377,18 @@ module Bridgetown
|
|
377
377
|
File.join(base_directory, clean_path)
|
378
378
|
end
|
379
379
|
end
|
380
|
+
|
381
|
+
# When there's a build error, error details will be logged to a file which the dev server
|
382
|
+
# can read and pass along to the browser.
|
383
|
+
#
|
384
|
+
# @return [String] the path to the cached errors file
|
385
|
+
def build_errors_path
|
386
|
+
File.join(
|
387
|
+
(Bridgetown::Current.site&.config || Bridgetown::Current.preloaded_configuration).root_dir,
|
388
|
+
".bridgetown-cache",
|
389
|
+
"build_errors.txt"
|
390
|
+
)
|
391
|
+
end
|
380
392
|
end
|
381
393
|
end
|
382
394
|
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Roda
|
4
|
+
module RodaPlugins
|
5
|
+
module BridgetownServer
|
6
|
+
SiteContext = Struct.new(:registers) # for use by Liquid-esque URL helpers
|
7
|
+
|
8
|
+
def self.load_dependencies(app) # rubocop:disable Metrics
|
9
|
+
unless Bridgetown::Current.preloaded_configuration
|
10
|
+
raise "You must supply a preloaded configuration before loading the Bridgetown Roda " \
|
11
|
+
"plugin"
|
12
|
+
end
|
13
|
+
|
14
|
+
app.plugin :initializers
|
15
|
+
app.plugin :method_override
|
16
|
+
app.plugin :all_verbs
|
17
|
+
app.plugin :hooks
|
18
|
+
app.plugin :common_logger, Bridgetown::Rack::Logger.new($stdout), method: :info
|
19
|
+
app.plugin :json
|
20
|
+
app.plugin :json_parser
|
21
|
+
app.plugin :indifferent_params
|
22
|
+
app.plugin :cookies
|
23
|
+
app.plugin :streaming
|
24
|
+
app.plugin :public, root: Bridgetown::Current.preloaded_configuration.destination
|
25
|
+
app.plugin :not_found do
|
26
|
+
output_folder = Bridgetown::Current.preloaded_configuration.destination
|
27
|
+
File.read(File.join(output_folder, "404.html"))
|
28
|
+
rescue Errno::ENOENT
|
29
|
+
"404 Not Found"
|
30
|
+
end
|
31
|
+
app.plugin :exception_page
|
32
|
+
app.plugin :error_handler do |e|
|
33
|
+
Bridgetown::Errors.print_build_error(
|
34
|
+
e, logger: Bridgetown::LogAdapter.new(self.class.opts[:common_logger]), server: true
|
35
|
+
)
|
36
|
+
next exception_page(e) if ENV.fetch("RACK_ENV", nil) == "development"
|
37
|
+
|
38
|
+
output_folder = Bridgetown::Current.preloaded_configuration.destination
|
39
|
+
File.read(File.join(output_folder, "500.html"))
|
40
|
+
rescue Errno::ENOENT
|
41
|
+
"500 Internal Server Error"
|
42
|
+
end
|
43
|
+
|
44
|
+
ExceptionPage.class_eval do # rubocop:disable Metrics/BlockLength
|
45
|
+
def self.css
|
46
|
+
<<~CSS
|
47
|
+
html * { padding:0; margin:0; }
|
48
|
+
body * { padding:10px 20px; }
|
49
|
+
body * * { padding:0; }
|
50
|
+
body { font-family: -apple-system, sans-serif; font-size: 90%; }
|
51
|
+
body>div { border-bottom:1px solid #ddd; }
|
52
|
+
code { font-family: ui-monospace, monospace; }
|
53
|
+
h1 { font-weight: bold; margin-block-end: .8em; }
|
54
|
+
h2 { margin-block-end:.8em; }
|
55
|
+
h2 span { font-size:80%; color:#f7f7db; font-weight:normal; }
|
56
|
+
h3 { margin:1em 0 .5em 0; }
|
57
|
+
h4 { margin:0 0 .5em 0; font-weight: normal; }
|
58
|
+
table {
|
59
|
+
border:1px solid #ccc; border-collapse: collapse; background:white; }
|
60
|
+
tbody td, tbody th { vertical-align:top; padding:2px 3px; }
|
61
|
+
thead th {
|
62
|
+
padding:1px 6px 1px 3px; background:#fefefe; text-align:left;
|
63
|
+
font-weight:normal; font-size:11px; border:1px solid #ddd; }
|
64
|
+
tbody th { text-align:right; opacity: 0.7; padding-right:.5em; }
|
65
|
+
table.vars { margin:5px 0 2px 40px; }
|
66
|
+
table.vars td, table.req td { font-family: ui-monospace, monospace; }
|
67
|
+
table td.code { width:100%;}
|
68
|
+
table td.code div { overflow:hidden; }
|
69
|
+
table.source th { color:#666; }
|
70
|
+
table.source td {
|
71
|
+
font-family: ui-monospace, monospace; white-space:pre; border-bottom:1px solid #eee; }
|
72
|
+
ul.traceback { list-style-type:none; }
|
73
|
+
ul.traceback li.frame { margin-bottom:1em; }
|
74
|
+
div.context { margin: 10px 0; }
|
75
|
+
div.context ol {
|
76
|
+
padding-left:30px; margin:0 10px; list-style-position: inside; }
|
77
|
+
div.context ol li {
|
78
|
+
font-family: ui-monospace, monospace; white-space:pre; color:#666; cursor:pointer; }
|
79
|
+
div.context ol.context-line li { color:black; background-color:#f7f7db; }
|
80
|
+
div.context ol.context-line li span { float: right; }
|
81
|
+
div.commands { margin-left: 40px; }
|
82
|
+
div.commands a { color:black; text-decoration:none; }
|
83
|
+
#summary { background: #1D453C; color: white; }
|
84
|
+
#summary h2 { font-weight: normal; color: white; }
|
85
|
+
#summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
|
86
|
+
#summary ul#quicklinks li { float: left; padding: 0 1em; }
|
87
|
+
#summary ul#quicklinks>li+li { border-left: 1px #666 solid; }
|
88
|
+
#summary a { color: #f47c3c; }
|
89
|
+
#explanation { background:#eee; }
|
90
|
+
#traceback { background: white; }
|
91
|
+
#requestinfo { background:#f6f6f6; padding-left:120px; }
|
92
|
+
#summary table { border:none; background:transparent; }
|
93
|
+
#requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
|
94
|
+
#requestinfo h3 { margin-bottom:-1em; }
|
95
|
+
.error { background: #ffc; }
|
96
|
+
.specific { color:#cc3300; font-weight:bold; }
|
97
|
+
CSS
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
app.before do
|
102
|
+
if self.class.opts[:bridgetown_site]
|
103
|
+
# The site had previously been initialized via the bridgetown_ssr plugin
|
104
|
+
Bridgetown::Current.sites[self.class.opts[:bridgetown_site].label] =
|
105
|
+
self.class.opts[:bridgetown_site]
|
106
|
+
@context ||= SiteContext.new({ site: self.class.opts[:bridgetown_site] })
|
107
|
+
end
|
108
|
+
Bridgetown::Current.preloaded_configuration ||=
|
109
|
+
self.class.opts[:bridgetown_preloaded_config]
|
110
|
+
|
111
|
+
request.root do
|
112
|
+
output_folder = Bridgetown::Current.preloaded_configuration.destination
|
113
|
+
File.read(File.join(output_folder, "index.html"))
|
114
|
+
rescue StandardError
|
115
|
+
response.status = 500
|
116
|
+
"<p>ERROR: cannot find <code>index.html</code> in the output folder.</p>"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
Roda::RodaRequest.alias_method :_previous_roda_cookies, :cookies
|
122
|
+
|
123
|
+
module RequestMethods
|
124
|
+
# Monkeypatch Roda/Rack's Request object so it returns a hash which allows for
|
125
|
+
# indifferent access
|
126
|
+
def cookies
|
127
|
+
# TODO: maybe replace with a simpler hash that offers an overloaded `[]` method
|
128
|
+
_previous_roda_cookies.with_indifferent_access
|
129
|
+
end
|
130
|
+
|
131
|
+
# Starts up the Bridgetown routing system
|
132
|
+
def bridgetown
|
133
|
+
Bridgetown::Rack::Routes.start!(scope)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
register_plugin :bridgetown_server, BridgetownServer
|
139
|
+
end
|
140
|
+
end
|
@@ -24,10 +24,13 @@ gem "bridgetown", "~> <%= Bridgetown::VERSION %>"
|
|
24
24
|
# Uncomment to add file-based dynamic routing to your project:
|
25
25
|
# gem "bridgetown-routes", "~> <%= Bridgetown::VERSION %>"
|
26
26
|
|
27
|
+
# Puma is the Rack-compatible web server used by Bridgetown
|
28
|
+
# (you can optionally limit this to the "development" group)
|
29
|
+
gem "puma", "< 7"
|
30
|
+
|
27
31
|
# Uncomment to use the Inspectors API to manipulate the output
|
28
32
|
# of your HTML or XML resources:
|
29
33
|
# gem "nokogiri", "~> 1.13"
|
30
34
|
|
31
|
-
#
|
32
|
-
#
|
33
|
-
gem "puma", "~> 5.6"
|
35
|
+
# Or for faster parsing of HTML-only resources via Inspectors, use Nokolexbor:
|
36
|
+
# gem "nokolexbor", "~> 0.4"
|
@@ -2,9 +2,11 @@
|
|
2
2
|
# on the concept of a routing tree. Bridgetown uses it for its development
|
3
3
|
# server, but you can also run it in production for fast, dynamic applications.
|
4
4
|
#
|
5
|
-
# Learn more at:
|
5
|
+
# Learn more at: https://www.bridgetownrb.com/docs/routes
|
6
|
+
|
7
|
+
class RodaApp < Roda
|
8
|
+
plugin :bridgetown_server
|
6
9
|
|
7
|
-
class RodaApp < Bridgetown::Rack::Roda
|
8
10
|
# Some Roda configuration is handled in the `config/initializers.rb` file.
|
9
11
|
# But you can also add additional Roda configuration here if needed.
|
10
12
|
|
@@ -5,7 +5,7 @@ date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>
|
|
5
5
|
categories: updates
|
6
6
|
---
|
7
7
|
|
8
|
-
You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `bridgetown
|
8
|
+
You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `bin/bridgetown start`, which launches a web server and auto-regenerates your site when a file is updated.
|
9
9
|
|
10
10
|
Bridgetown requires blog post files to be named according to the following format:
|
11
11
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bridgetown-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bridgetown Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01
|
11
|
+
date: 2023-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -112,28 +112,28 @@ dependencies:
|
|
112
112
|
requirements:
|
113
113
|
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: '
|
115
|
+
version: '2.0'
|
116
116
|
type: :runtime
|
117
117
|
prerelease: false
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
119
119
|
requirements:
|
120
120
|
- - "~>"
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: '
|
122
|
+
version: '2.0'
|
123
123
|
- !ruby/object:Gem::Dependency
|
124
|
-
name:
|
124
|
+
name: faraday-follow_redirects
|
125
125
|
requirement: !ruby/object:Gem::Requirement
|
126
126
|
requirements:
|
127
127
|
- - "~>"
|
128
128
|
- !ruby/object:Gem::Version
|
129
|
-
version: '
|
129
|
+
version: '0.3'
|
130
130
|
type: :runtime
|
131
131
|
prerelease: false
|
132
132
|
version_requirements: !ruby/object:Gem::Requirement
|
133
133
|
requirements:
|
134
134
|
- - "~>"
|
135
135
|
- !ruby/object:Gem::Version
|
136
|
-
version: '
|
136
|
+
version: '0.3'
|
137
137
|
- !ruby/object:Gem::Dependency
|
138
138
|
name: hash_with_dot_access
|
139
139
|
requirement: !ruby/object:Gem::Requirement
|
@@ -302,20 +302,6 @@ dependencies:
|
|
302
302
|
- - "~>"
|
303
303
|
- !ruby/object:Gem::Version
|
304
304
|
version: '2.0'
|
305
|
-
- !ruby/object:Gem::Dependency
|
306
|
-
name: webrick
|
307
|
-
requirement: !ruby/object:Gem::Requirement
|
308
|
-
requirements:
|
309
|
-
- - "~>"
|
310
|
-
- !ruby/object:Gem::Version
|
311
|
-
version: '1.7'
|
312
|
-
type: :runtime
|
313
|
-
prerelease: false
|
314
|
-
version_requirements: !ruby/object:Gem::Requirement
|
315
|
-
requirements:
|
316
|
-
- - "~>"
|
317
|
-
- !ruby/object:Gem::Version
|
318
|
-
version: '1.7'
|
319
305
|
- !ruby/object:Gem::Dependency
|
320
306
|
name: zeitwerk
|
321
307
|
requirement: !ruby/object:Gem::Requirement
|
@@ -368,8 +354,6 @@ files:
|
|
368
354
|
- lib/bridgetown-core/commands/new.rb
|
369
355
|
- lib/bridgetown-core/commands/plugins.rb
|
370
356
|
- lib/bridgetown-core/commands/registrations.rb
|
371
|
-
- lib/bridgetown-core/commands/serve.rb
|
372
|
-
- lib/bridgetown-core/commands/serve/servlet.rb
|
373
357
|
- lib/bridgetown-core/commands/start.rb
|
374
358
|
- lib/bridgetown-core/commands/webpack.rb
|
375
359
|
- lib/bridgetown-core/commands/webpack/enable-postcss.rb
|
@@ -487,7 +471,6 @@ files:
|
|
487
471
|
- lib/bridgetown-core/plugin_manager.rb
|
488
472
|
- lib/bridgetown-core/rack/boot.rb
|
489
473
|
- lib/bridgetown-core/rack/logger.rb
|
490
|
-
- lib/bridgetown-core/rack/roda.rb
|
491
474
|
- lib/bridgetown-core/rack/routes.rb
|
492
475
|
- lib/bridgetown-core/rack/static_indexes.rb
|
493
476
|
- lib/bridgetown-core/reader.rb
|
@@ -529,7 +512,7 @@ files:
|
|
529
512
|
- lib/bridgetown-core/version.rb
|
530
513
|
- lib/bridgetown-core/watcher.rb
|
531
514
|
- lib/bridgetown-core/yaml_parser.rb
|
532
|
-
- lib/roda/plugins/
|
515
|
+
- lib/roda/plugins/bridgetown_server.rb
|
533
516
|
- lib/roda/plugins/bridgetown_ssr.rb
|
534
517
|
- lib/roda/plugins/initializers.rb
|
535
518
|
- lib/roda/plugins/method_override.rb
|
@@ -601,9 +584,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
601
584
|
version: 2.7.0
|
602
585
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
603
586
|
requirements:
|
604
|
-
- - "
|
587
|
+
- - ">"
|
605
588
|
- !ruby/object:Gem::Version
|
606
|
-
version:
|
589
|
+
version: 1.3.1
|
607
590
|
requirements: []
|
608
591
|
rubygems_version: 3.1.4
|
609
592
|
signing_key:
|
@@ -1,68 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "webrick"
|
4
|
-
|
5
|
-
module Bridgetown
|
6
|
-
module Commands
|
7
|
-
class Serve
|
8
|
-
class Servlet < WEBrick::HTTPServlet::FileHandler
|
9
|
-
DEFAULTS = {
|
10
|
-
"Cache-Control" => "private, max-age=0, proxy-revalidate, " \
|
11
|
-
"no-store, no-cache, must-revalidate",
|
12
|
-
}.freeze
|
13
|
-
|
14
|
-
def initialize(server, root, callbacks)
|
15
|
-
# So we can access them easily.
|
16
|
-
@bridgetown_opts = server.config[:BridgetownOptions]
|
17
|
-
set_defaults
|
18
|
-
super
|
19
|
-
end
|
20
|
-
|
21
|
-
def search_index_file(req, res)
|
22
|
-
super ||
|
23
|
-
search_file(req, res, ".html") ||
|
24
|
-
search_file(req, res, ".xhtml")
|
25
|
-
end
|
26
|
-
|
27
|
-
# Add the ability to tap file.html the same way that Nginx does on our
|
28
|
-
# Docker images (or on GitHub Pages.) The difference is that we might end
|
29
|
-
# up with a different preference on which comes first.
|
30
|
-
|
31
|
-
def search_file(req, res, basename)
|
32
|
-
# /file.* > /file/index.html > /file.html
|
33
|
-
super ||
|
34
|
-
super(req, res, "#{basename}.html") ||
|
35
|
-
super(req, res, "#{basename}.xhtml")
|
36
|
-
end
|
37
|
-
|
38
|
-
# rubocop:disable Naming/MethodName
|
39
|
-
def do_GET(req, res)
|
40
|
-
rtn = super
|
41
|
-
|
42
|
-
validate_and_ensure_charset(req, res)
|
43
|
-
res.header.merge!(@headers)
|
44
|
-
rtn
|
45
|
-
end
|
46
|
-
# rubocop:enable Naming/MethodName
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def validate_and_ensure_charset(_req, res)
|
51
|
-
key = res.header.keys.grep(%r!content-type!i).first
|
52
|
-
typ = res.header[key]
|
53
|
-
|
54
|
-
return if %r!;\s*charset=!.match?(typ)
|
55
|
-
|
56
|
-
res.header[key] = "#{typ}; charset=#{@bridgetown_opts["encoding"]}"
|
57
|
-
end
|
58
|
-
|
59
|
-
def set_defaults
|
60
|
-
hash_ = @bridgetown_opts.fetch("webrick", {}).fetch("headers", {})
|
61
|
-
DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|
|
62
|
-
hash[key] = val unless hash.key?(key)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,253 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Bridgetown
|
4
|
-
module Commands
|
5
|
-
class Serve < Thor::Group
|
6
|
-
extend BuildOptions
|
7
|
-
extend Summarizable
|
8
|
-
include ConfigurationOverridable
|
9
|
-
|
10
|
-
Registrations.register do
|
11
|
-
register(Serve, "serve", "serve", Serve.summary)
|
12
|
-
end
|
13
|
-
|
14
|
-
class_option :host, aliases: "-H", desc: "Host to bind to"
|
15
|
-
class_option :port, aliases: "-P", desc: "Port to listen on"
|
16
|
-
class_option :detach,
|
17
|
-
aliases: "-B",
|
18
|
-
type: :boolean,
|
19
|
-
desc: "Run the server in the background"
|
20
|
-
class_option :ssl_cert, desc: "X.509 (SSL) certificate."
|
21
|
-
class_option :ssl_key, desc: "X.509 (SSL) Private Key."
|
22
|
-
class_option :show_dir_listing,
|
23
|
-
type: :boolean,
|
24
|
-
desc: "Show a directory listing instead of loading your index file."
|
25
|
-
class_option :skip_initial_build,
|
26
|
-
type: :boolean,
|
27
|
-
desc: "Skips the initial site build which occurs before the server is started."
|
28
|
-
class_option :watch,
|
29
|
-
type: :boolean,
|
30
|
-
aliases: "-w",
|
31
|
-
default: true,
|
32
|
-
desc: "Watch for changes and rebuild"
|
33
|
-
|
34
|
-
def self.banner
|
35
|
-
"bridgetown serve [options]"
|
36
|
-
end
|
37
|
-
summary "DEPRECATED (Serve your site locally using WEBrick)"
|
38
|
-
|
39
|
-
DIRECTORY_INDEX = %w(
|
40
|
-
index.htm
|
41
|
-
index.html
|
42
|
-
index.rhtml
|
43
|
-
index.xht
|
44
|
-
index.xhtml
|
45
|
-
index.cgi
|
46
|
-
index.xml
|
47
|
-
index.json
|
48
|
-
).freeze
|
49
|
-
|
50
|
-
def serve
|
51
|
-
Bridgetown::Deprecator.deprecation_message(
|
52
|
-
"WEBrick (serve) will be removed in favor of Puma (start) in the next Bridgetown release"
|
53
|
-
)
|
54
|
-
|
55
|
-
@mutex = Mutex.new
|
56
|
-
@run_cond = ConditionVariable.new
|
57
|
-
@running = false
|
58
|
-
|
59
|
-
no_watch = options["watch"] == false
|
60
|
-
|
61
|
-
options = Thor::CoreExt::HashWithIndifferentAccess.new(self.options)
|
62
|
-
options["serving"] = true
|
63
|
-
options["watch"] = true unless no_watch
|
64
|
-
|
65
|
-
config = configuration_with_overrides(options, Bridgetown::Current.preloaded_configuration)
|
66
|
-
if Bridgetown.environment == "development"
|
67
|
-
default_url(config).tap do |url|
|
68
|
-
options["url"] = url
|
69
|
-
config.url = url
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
invoke(Build, [], options)
|
74
|
-
start_server
|
75
|
-
end
|
76
|
-
|
77
|
-
protected
|
78
|
-
|
79
|
-
def start_server
|
80
|
-
destination = Bridgetown::Current.preloaded_configuration.destination
|
81
|
-
setup(destination)
|
82
|
-
|
83
|
-
start_up_webrick(destination)
|
84
|
-
end
|
85
|
-
|
86
|
-
def setup(destination)
|
87
|
-
require_relative "serve/servlet"
|
88
|
-
|
89
|
-
FileUtils.mkdir_p(destination)
|
90
|
-
return unless File.exist?(File.join(destination, "404.html"))
|
91
|
-
|
92
|
-
WEBrick::HTTPResponse.class_eval do
|
93
|
-
def create_error_page
|
94
|
-
@header["Content-Type"] = "text/html; charset=UTF-8"
|
95
|
-
@body = File.read(File.join(@config[:DocumentRoot], "404.html"))
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def webrick_opts(opts)
|
101
|
-
opts = {
|
102
|
-
BridgetownOptions: opts,
|
103
|
-
DoNotReverseLookup: true,
|
104
|
-
MimeTypes: mime_types,
|
105
|
-
DocumentRoot: opts["destination"],
|
106
|
-
StartCallback: start_callback(opts["detach"]),
|
107
|
-
StopCallback: stop_callback(opts["detach"]),
|
108
|
-
BindAddress: opts["host"],
|
109
|
-
Port: opts["port"],
|
110
|
-
DirectoryIndex: DIRECTORY_INDEX,
|
111
|
-
}
|
112
|
-
|
113
|
-
opts[:DirectoryIndex] = [] if opts[:BridgetownOptions]["show_dir_listing"]
|
114
|
-
|
115
|
-
enable_ssl(opts)
|
116
|
-
enable_logging(opts)
|
117
|
-
opts
|
118
|
-
end
|
119
|
-
|
120
|
-
def start_up_webrick(destination)
|
121
|
-
opts = Bridgetown::Current.preloaded_configuration
|
122
|
-
@server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
|
123
|
-
@server.mount(opts["base_path"].to_s, Servlet, destination, file_handler_opts)
|
124
|
-
|
125
|
-
Bridgetown.logger.info "Server address:", server_address(@server, opts)
|
126
|
-
launch_browser @server, opts if opts["open_url"]
|
127
|
-
boot_or_detach @server, opts
|
128
|
-
end
|
129
|
-
|
130
|
-
def shutdown
|
131
|
-
@server.shutdown if running?
|
132
|
-
end
|
133
|
-
|
134
|
-
def default_url(config)
|
135
|
-
format_url(
|
136
|
-
config["ssl_cert"] && config["ssl_key"],
|
137
|
-
config["host"] == "127.0.0.1" ? "localhost" : config["host"],
|
138
|
-
config["port"]
|
139
|
-
)
|
140
|
-
end
|
141
|
-
|
142
|
-
def format_url(ssl_enabled, address, port, baseurl = nil)
|
143
|
-
format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
|
144
|
-
prefix: ssl_enabled ? "https" : "http",
|
145
|
-
address: address,
|
146
|
-
port: port,
|
147
|
-
baseurl: baseurl ? "#{baseurl}/" : "")
|
148
|
-
end
|
149
|
-
|
150
|
-
# Recreate NondisclosureName under utf-8 circumstance
|
151
|
-
def file_handler_opts
|
152
|
-
WEBrick::Config::FileHandler.merge(
|
153
|
-
FancyIndexing: true,
|
154
|
-
NondisclosureName: [
|
155
|
-
".ht*", "~*",
|
156
|
-
]
|
157
|
-
)
|
158
|
-
end
|
159
|
-
|
160
|
-
def server_address(server, options = {})
|
161
|
-
format_url(
|
162
|
-
server.config[:SSLEnable],
|
163
|
-
server.config[:BindAddress],
|
164
|
-
server.config[:Port],
|
165
|
-
options["baseurl"]
|
166
|
-
)
|
167
|
-
end
|
168
|
-
|
169
|
-
# Keep in our area with a thread or detach the server as requested
|
170
|
-
# by the user. This method determines what we do based on what you
|
171
|
-
# ask us to do.
|
172
|
-
def boot_or_detach(server, opts)
|
173
|
-
if opts["detach"]
|
174
|
-
pid = Process.fork do
|
175
|
-
server.start
|
176
|
-
end
|
177
|
-
|
178
|
-
Process.detach(pid)
|
179
|
-
Bridgetown.logger.info "Server detached with pid '#{pid}'.", \
|
180
|
-
"Run `pkill -f bridgetown' or `kill -9 #{pid}' " \
|
181
|
-
"to stop the server."
|
182
|
-
else
|
183
|
-
t = Thread.new { server.start }
|
184
|
-
trap("INT") { server.shutdown }
|
185
|
-
t.join
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
# Make the stack verbose if the user requests it.
|
190
|
-
def enable_logging(opts)
|
191
|
-
opts[:AccessLog] = []
|
192
|
-
level = WEBrick::Log.const_get(opts[:BridgetownOptions]["verbose"] ? :DEBUG : :WARN)
|
193
|
-
opts[:Logger] = WEBrick::Log.new($stdout, level)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Add SSL to the stack if the user triggers --enable-ssl and they
|
197
|
-
# provide both types of certificates commonly needed. Raise if they
|
198
|
-
# forget to add one of the certificates.
|
199
|
-
def enable_ssl(opts)
|
200
|
-
cert, key, src =
|
201
|
-
opts[:BridgetownOptions].values_at("ssl_cert", "ssl_key", "source")
|
202
|
-
|
203
|
-
return if cert.nil? && key.nil?
|
204
|
-
raise "Missing --ssl_cert or --ssl_key. Both are required." unless cert && key
|
205
|
-
|
206
|
-
require "openssl"
|
207
|
-
require "webrick/https"
|
208
|
-
|
209
|
-
opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(read_file(src, cert))
|
210
|
-
begin
|
211
|
-
opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(read_file(src, key))
|
212
|
-
rescue StandardError
|
213
|
-
raise unless defined?(OpenSSL::PKey::EC)
|
214
|
-
|
215
|
-
opts[:SSLPrivateKey] = OpenSSL::PKey::EC.new(read_file(src, key))
|
216
|
-
end
|
217
|
-
opts[:SSLEnable] = true
|
218
|
-
end
|
219
|
-
|
220
|
-
def start_callback(detached)
|
221
|
-
return if detached
|
222
|
-
|
223
|
-
proc do
|
224
|
-
@mutex.synchronize do
|
225
|
-
@running = true
|
226
|
-
Bridgetown.logger.info("Server running…", "press ctrl-c to stop.")
|
227
|
-
@run_cond.broadcast
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
def stop_callback(detached)
|
233
|
-
return if detached
|
234
|
-
|
235
|
-
proc do
|
236
|
-
@mutex.synchronize do
|
237
|
-
@running = false
|
238
|
-
@run_cond.broadcast
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
def mime_types
|
244
|
-
file = File.expand_path("../mime.types", __dir__)
|
245
|
-
WEBrick::HTTPUtils.load_mime_types(file)
|
246
|
-
end
|
247
|
-
|
248
|
-
def read_file(source_dir, file_path)
|
249
|
-
File.read(Bridgetown.sanitized_path(source_dir, file_path))
|
250
|
-
end
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
@@ -1,157 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
unless Bridgetown::Current.preloaded_configuration
|
4
|
-
raise "You must supply a preloaded configuration before loading Bridgetown's Roda superclass"
|
5
|
-
end
|
6
|
-
|
7
|
-
module Bridgetown
|
8
|
-
module Rack
|
9
|
-
class Roda < ::Roda
|
10
|
-
class << self
|
11
|
-
def inherited(klass)
|
12
|
-
super
|
13
|
-
klass.plugin :initializers
|
14
|
-
end
|
15
|
-
|
16
|
-
# rubocop:disable Bridgetown/NoPutsAllowed
|
17
|
-
def print_routes
|
18
|
-
# TODO: this needs to be fully documented
|
19
|
-
routes = begin
|
20
|
-
JSON.parse(
|
21
|
-
File.read(
|
22
|
-
File.join(Bridgetown::Current.preloaded_configuration.root_dir, ".routes.json")
|
23
|
-
)
|
24
|
-
)
|
25
|
-
rescue StandardError
|
26
|
-
[]
|
27
|
-
end
|
28
|
-
puts
|
29
|
-
puts "Routes:"
|
30
|
-
puts "======="
|
31
|
-
if routes.blank?
|
32
|
-
puts "No routes found. Have you commented all of your routes?"
|
33
|
-
puts "Documentation: https://github.com/jeremyevans/roda-route_list#basic-usage-"
|
34
|
-
end
|
35
|
-
|
36
|
-
routes.each do |route|
|
37
|
-
puts [
|
38
|
-
route["methods"]&.join("|") || "GET",
|
39
|
-
route["path"],
|
40
|
-
route["file"] ? "\n File: #{route["file"]}" : nil,
|
41
|
-
].compact.join(" ")
|
42
|
-
end
|
43
|
-
puts
|
44
|
-
end
|
45
|
-
# rubocop:enable Bridgetown/NoPutsAllowed
|
46
|
-
end
|
47
|
-
|
48
|
-
SiteContext = Struct.new(:registers) # for use by Liquid-esque URL helpers
|
49
|
-
|
50
|
-
plugin :method_override
|
51
|
-
plugin :all_verbs
|
52
|
-
plugin :hooks
|
53
|
-
plugin :common_logger, Bridgetown::Rack::Logger.new($stdout), method: :info
|
54
|
-
plugin :json
|
55
|
-
plugin :json_parser
|
56
|
-
plugin :indifferent_params
|
57
|
-
plugin :cookies
|
58
|
-
plugin :streaming
|
59
|
-
plugin :bridgetown_boot
|
60
|
-
plugin :public, root: Bridgetown::Current.preloaded_configuration.destination
|
61
|
-
plugin :not_found do
|
62
|
-
output_folder = Bridgetown::Current.preloaded_configuration.destination
|
63
|
-
File.read(File.join(output_folder, "404.html"))
|
64
|
-
rescue Errno::ENOENT
|
65
|
-
"404 Not Found"
|
66
|
-
end
|
67
|
-
plugin :exception_page
|
68
|
-
plugin :error_handler do |e|
|
69
|
-
Bridgetown::Errors.print_build_error(
|
70
|
-
e, logger: Bridgetown::LogAdapter.new(self.class.opts[:common_logger])
|
71
|
-
)
|
72
|
-
next exception_page(e) if ENV.fetch("RACK_ENV", nil) == "development"
|
73
|
-
|
74
|
-
output_folder = Bridgetown::Current.preloaded_configuration.destination
|
75
|
-
File.read(File.join(output_folder, "500.html"))
|
76
|
-
rescue Errno::ENOENT
|
77
|
-
"500 Internal Server Error"
|
78
|
-
end
|
79
|
-
|
80
|
-
::Roda::RodaPlugins::ExceptionPage.class_eval do
|
81
|
-
def self.css
|
82
|
-
<<~CSS
|
83
|
-
html * { padding:0; margin:0; }
|
84
|
-
body * { padding:10px 20px; }
|
85
|
-
body * * { padding:0; }
|
86
|
-
body { font-family: -apple-system, sans-serif; font-size: 90%; }
|
87
|
-
body>div { border-bottom:1px solid #ddd; }
|
88
|
-
code { font-family: ui-monospace, monospace; }
|
89
|
-
h1 { font-weight: bold; margin-block-end: .8em; }
|
90
|
-
h2 { margin-block-end:.8em; }
|
91
|
-
h2 span { font-size:80%; color:#f7f7db; font-weight:normal; }
|
92
|
-
h3 { margin:1em 0 .5em 0; }
|
93
|
-
h4 { margin:0 0 .5em 0; font-weight: normal; }
|
94
|
-
table {
|
95
|
-
border:1px solid #ccc; border-collapse: collapse; background:white; }
|
96
|
-
tbody td, tbody th { vertical-align:top; padding:2px 3px; }
|
97
|
-
thead th {
|
98
|
-
padding:1px 6px 1px 3px; background:#fefefe; text-align:left;
|
99
|
-
font-weight:normal; font-size:11px; border:1px solid #ddd; }
|
100
|
-
tbody th { text-align:right; opacity: 0.7; padding-right:.5em; }
|
101
|
-
table.vars { margin:5px 0 2px 40px; }
|
102
|
-
table.vars td, table.req td { font-family: ui-monospace, monospace; }
|
103
|
-
table td.code { width:100%;}
|
104
|
-
table td.code div { overflow:hidden; }
|
105
|
-
table.source th { color:#666; }
|
106
|
-
table.source td {
|
107
|
-
font-family: ui-monospace, monospace; white-space:pre; border-bottom:1px solid #eee; }
|
108
|
-
ul.traceback { list-style-type:none; }
|
109
|
-
ul.traceback li.frame { margin-bottom:1em; }
|
110
|
-
div.context { margin: 10px 0; }
|
111
|
-
div.context ol {
|
112
|
-
padding-left:30px; margin:0 10px; list-style-position: inside; }
|
113
|
-
div.context ol li {
|
114
|
-
font-family: ui-monospace, monospace; white-space:pre; color:#666; cursor:pointer; }
|
115
|
-
div.context ol.context-line li { color:black; background-color:#f7f7db; }
|
116
|
-
div.context ol.context-line li span { float: right; }
|
117
|
-
div.commands { margin-left: 40px; }
|
118
|
-
div.commands a { color:black; text-decoration:none; }
|
119
|
-
#summary { background: #1D453C; color: white; }
|
120
|
-
#summary h2 { font-weight: normal; color: white; }
|
121
|
-
#summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
|
122
|
-
#summary ul#quicklinks li { float: left; padding: 0 1em; }
|
123
|
-
#summary ul#quicklinks>li+li { border-left: 1px #666 solid; }
|
124
|
-
#summary a { color: #f47c3c; }
|
125
|
-
#explanation { background:#eee; }
|
126
|
-
#traceback { background: white; }
|
127
|
-
#requestinfo { background:#f6f6f6; padding-left:120px; }
|
128
|
-
#summary table { border:none; background:transparent; }
|
129
|
-
#requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
|
130
|
-
#requestinfo h3 { margin-bottom:-1em; }
|
131
|
-
.error { background: #ffc; }
|
132
|
-
.specific { color:#cc3300; font-weight:bold; }
|
133
|
-
CSS
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
before do
|
138
|
-
if self.class.opts[:bridgetown_site]
|
139
|
-
# The site had previously been initialized via the bridgetown_ssr plugin
|
140
|
-
Bridgetown::Current.sites[self.class.opts[:bridgetown_site].label] =
|
141
|
-
self.class.opts[:bridgetown_site]
|
142
|
-
@context ||= SiteContext.new({ site: self.class.opts[:bridgetown_site] })
|
143
|
-
end
|
144
|
-
Bridgetown::Current.preloaded_configuration ||=
|
145
|
-
self.class.opts[:bridgetown_preloaded_config]
|
146
|
-
|
147
|
-
request.root do
|
148
|
-
output_folder = Bridgetown::Current.preloaded_configuration.destination
|
149
|
-
File.read(File.join(output_folder, "index.html"))
|
150
|
-
rescue StandardError
|
151
|
-
response.status = 500
|
152
|
-
"<p>ERROR: cannot find <code>index.html</code> in the output folder.</p>"
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Roda
|
4
|
-
module RodaPlugins
|
5
|
-
module BridgetownBoot
|
6
|
-
Roda::RodaRequest.alias_method :_previous_roda_cookies, :cookies
|
7
|
-
|
8
|
-
module RequestMethods
|
9
|
-
# Monkeypatch Roda/Rack's Request object so it returns a hash which allows for
|
10
|
-
# indifferent access
|
11
|
-
def cookies
|
12
|
-
# TODO: maybe replace with a simpler hash that offers an overloaded `[]` method
|
13
|
-
_previous_roda_cookies.with_indifferent_access
|
14
|
-
end
|
15
|
-
|
16
|
-
# Starts up the Bridgetown routing system
|
17
|
-
def bridgetown
|
18
|
-
Bridgetown::Rack::Routes.start!(scope)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
register_plugin :bridgetown_boot, BridgetownBoot
|
24
|
-
end
|
25
|
-
end
|