bridgetown-core 0.14.1 → 0.15.0

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -1
  3. data/bin/bridgetown +9 -23
  4. data/bridgetown-core.gemspec +3 -1
  5. data/lib/bridgetown-core.rb +9 -2
  6. data/lib/bridgetown-core/commands/apply.rb +73 -0
  7. data/lib/bridgetown-core/commands/base.rb +45 -0
  8. data/lib/bridgetown-core/commands/build.rb +91 -86
  9. data/lib/bridgetown-core/commands/clean.rb +30 -29
  10. data/lib/bridgetown-core/commands/concerns/actions.rb +128 -0
  11. data/lib/bridgetown-core/commands/concerns/build_options.rb +76 -0
  12. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +18 -0
  13. data/lib/bridgetown-core/commands/concerns/summarizable.rb +13 -0
  14. data/lib/bridgetown-core/commands/console.rb +57 -39
  15. data/lib/bridgetown-core/commands/doctor.rb +126 -126
  16. data/lib/bridgetown-core/commands/new.rb +120 -155
  17. data/lib/bridgetown-core/commands/plugins.rb +167 -130
  18. data/lib/bridgetown-core/commands/registrations.rb +16 -0
  19. data/lib/bridgetown-core/commands/serve.rb +219 -215
  20. data/lib/bridgetown-core/concerns/convertible.rb +1 -4
  21. data/lib/bridgetown-core/concerns/site/renderable.rb +1 -2
  22. data/lib/bridgetown-core/drops/document_drop.rb +9 -1
  23. data/lib/bridgetown-core/drops/page_drop.rb +1 -1
  24. data/lib/bridgetown-core/excerpt.rb +4 -1
  25. data/lib/bridgetown-core/generators/prototype_generator.rb +2 -0
  26. data/lib/bridgetown-core/liquid_renderer.rb +1 -0
  27. data/lib/bridgetown-core/liquid_renderer/file.rb +1 -4
  28. data/lib/bridgetown-core/liquid_renderer/file_system.rb +3 -1
  29. data/lib/bridgetown-core/page.rb +3 -18
  30. data/lib/bridgetown-core/plugin_manager.rb +31 -17
  31. data/lib/bridgetown-core/renderer.rb +31 -18
  32. data/lib/bridgetown-core/tags/include.rb +14 -0
  33. data/lib/bridgetown-core/tags/render_content.rb +39 -16
  34. data/lib/bridgetown-core/tags/with.rb +15 -0
  35. data/lib/bridgetown-core/utils.rb +44 -0
  36. data/lib/bridgetown-core/version.rb +2 -2
  37. data/lib/bridgetown-core/watcher.rb +17 -10
  38. data/lib/site_template/Gemfile.erb +19 -0
  39. data/lib/site_template/bridgetown.config.yml +5 -3
  40. data/lib/site_template/package.json +1 -0
  41. data/lib/site_template/src/_components/footer.liquid +3 -0
  42. data/lib/site_template/src/_components/head.liquid +9 -0
  43. data/lib/site_template/src/{_includes/navbar.html → _components/navbar.liquid} +0 -0
  44. data/lib/site_template/src/_layouts/default.html +3 -3
  45. data/lib/site_template/start.js +1 -1
  46. data/lib/site_template/webpack.config.js +3 -3
  47. metadata +53 -19
  48. data/lib/bridgetown-core/command.rb +0 -112
  49. data/lib/bridgetown-core/commands/help.rb +0 -34
  50. data/lib/site_template/src/_components/.keep +0 -0
  51. data/lib/site_template/src/_includes/footer.html +0 -3
  52. data/lib/site_template/src/_includes/head.html +0 -9
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Commands
5
+ module Registrations
6
+ def self.registrations
7
+ @registrations || []
8
+ end
9
+
10
+ def self.register(&block)
11
+ @registrations ||= []
12
+ @registrations.push(block)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,262 +2,266 @@
2
2
 
3
3
  module Bridgetown
4
4
  module Commands
5
- class Serve < Command
6
- # Similar to the pattern in Utils::ThreadEvent except we are maintaining the
7
- # state of @running instead of just signaling an event. We have to maintain this
8
- # state since Serve is just called via class methods instead of an instance
9
- # being created each time.
10
- @mutex = Mutex.new
11
- @run_cond = ConditionVariable.new
12
- @running = false
5
+ class Serve < Thor::Group
6
+ extend BuildOptions
7
+ extend Summarizable
8
+ include ConfigurationOverridable
13
9
 
14
- class << self
15
- COMMAND_OPTIONS = {
16
- "ssl_cert" => ["--ssl-cert [CERT]", "X.509 (SSL) certificate."],
17
- "host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
18
- "open_url" => ["-o", "--open-url", "Launch your site in a browser"],
19
- "detach" => ["-B", "--detach",
20
- "Run the server in the background",],
21
- "ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
22
- "port" => ["-P", "--port [PORT]", "Port to listen on"],
23
- "show_dir_listing" => ["--show-dir-listing",
24
- "Show a directory listing instead of loading" \
25
- " your index file.",],
26
- "skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
27
- "Skips the initial site build which occurs before" \
28
- " the server is started.",],
29
- }.freeze
30
-
31
- DIRECTORY_INDEX = %w(
32
- index.htm
33
- index.html
34
- index.rhtml
35
- index.xht
36
- index.xhtml
37
- index.cgi
38
- index.xml
39
- index.json
40
- ).freeze
41
-
42
- attr_reader :mutex, :run_cond, :running
43
- alias_method :running?, :running
44
-
45
- def init_with_program(prog)
46
- prog.command(:serve) do |cmd|
47
- cmd.description "Serve your site locally"
48
- cmd.syntax "serve [options]"
49
- cmd.alias :server
50
- cmd.alias :s
51
-
52
- add_build_options(cmd)
53
- COMMAND_OPTIONS.each do |key, val|
54
- cmd.option key, *val
55
- end
10
+ Registrations.register do
11
+ register(Serve, "serve", "serve", Serve.summary)
12
+ end
56
13
 
57
- cmd.action do |_, opts|
58
- opts["serving"] = true
59
- opts["watch"] = true unless opts.key?("watch")
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 :open_url,
17
+ aliases: "-o",
18
+ type: :boolean,
19
+ desc: "Launch your site in a browser"
20
+ class_option :detach,
21
+ aliases: "-B",
22
+ type: :boolean,
23
+ desc: "Run the server in the background"
24
+ class_option :ssl_cert, desc: "X.509 (SSL) certificate."
25
+ class_option :ssl_key, desc: "X.509 (SSL) Private Key."
26
+ class_option :show_dir_listing,
27
+ type: :boolean,
28
+ desc: "Show a directory listing instead of loading your index file."
29
+ class_option :skip_initial_build,
30
+ type: :boolean,
31
+ desc: "Skips the initial site build which occurs before the server is started."
32
+ class_option :watch,
33
+ type: :boolean,
34
+ aliases: "-w",
35
+ default: true,
36
+ desc: "Watch for changes and rebuild"
37
+
38
+ def self.banner
39
+ "bridgetown serve [options]"
40
+ end
41
+ summary "Serve your site locally using WEBrick"
60
42
 
61
- # TODO: this prints the configuration file log message out-of-order
62
- config = configuration_from_options(opts)
63
- config["url"] = default_url(config) if Bridgetown.environment == "development"
43
+ class << self
44
+ attr_accessor :loaded_config
45
+ end
64
46
 
65
- process_with_graceful_fail(cmd, config, Build, Serve)
66
- end
67
- end
47
+ DIRECTORY_INDEX = %w(
48
+ index.htm
49
+ index.html
50
+ index.rhtml
51
+ index.xht
52
+ index.xhtml
53
+ index.cgi
54
+ index.xml
55
+ index.json
56
+ ).freeze
57
+
58
+ def serve
59
+ @mutex = Mutex.new
60
+ @run_cond = ConditionVariable.new
61
+ @running = false
62
+
63
+ no_watch = options["watch"] == false
64
+
65
+ options = Thor::CoreExt::HashWithIndifferentAccess.new(self.options)
66
+
67
+ options["serving"] = true
68
+ options["watch"] = true unless no_watch
69
+
70
+ # TODO: this prints the configuration file log message out-of-order
71
+ self.class.loaded_config = configuration_with_overrides(options)
72
+ if Bridgetown.environment == "development"
73
+ self.class.loaded_config["url"] = default_url(self.class.loaded_config)
68
74
  end
69
75
 
70
- #
71
-
72
- def process(config)
73
- destination = config["destination"]
74
- setup(destination)
75
-
76
- start_up_webrick(config, destination)
77
- end
76
+ invoke(Build, [], options)
77
+ start_server
78
+ end
78
79
 
79
- def shutdown
80
- @server.shutdown if running?
81
- end
80
+ protected
82
81
 
83
- private
82
+ def start_server
83
+ config = self.class.loaded_config
84
+ destination = config["destination"]
85
+ setup(destination)
84
86
 
85
- # Do a base pre-setup of WEBRick so that everything is in place
86
- # when we get ready to party, checking for an setting up an error page
87
- # and making sure our destination exists.
87
+ start_up_webrick(config, destination)
88
+ end
88
89
 
89
- def setup(destination)
90
- require_relative "serve/servlet"
90
+ def setup(destination)
91
+ require_relative "serve/servlet"
91
92
 
92
- FileUtils.mkdir_p(destination)
93
- if File.exist?(File.join(destination, "404.html"))
94
- WEBrick::HTTPResponse.class_eval do
95
- def create_error_page
96
- @header["Content-Type"] = "text/html; charset=UTF-8"
97
- @body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
98
- end
93
+ FileUtils.mkdir_p(destination)
94
+ if File.exist?(File.join(destination, "404.html"))
95
+ WEBrick::HTTPResponse.class_eval do
96
+ def create_error_page
97
+ @header["Content-Type"] = "text/html; charset=UTF-8"
98
+ @body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
99
99
  end
100
100
  end
101
101
  end
102
+ end
102
103
 
103
- def webrick_opts(opts)
104
- opts = {
105
- BridgetownOptions: opts,
106
- DoNotReverseLookup: true,
107
- MimeTypes: mime_types,
108
- DocumentRoot: opts["destination"],
109
- StartCallback: start_callback(opts["detach"]),
110
- StopCallback: stop_callback(opts["detach"]),
111
- BindAddress: opts["host"],
112
- Port: opts["port"],
113
- DirectoryIndex: DIRECTORY_INDEX,
114
- }
115
-
116
- opts[:DirectoryIndex] = [] if opts[:BridgetownOptions]["show_dir_listing"]
117
-
118
- enable_ssl(opts)
119
- enable_logging(opts)
120
- opts
121
- end
104
+ def webrick_opts(opts)
105
+ opts = {
106
+ BridgetownOptions: opts,
107
+ DoNotReverseLookup: true,
108
+ MimeTypes: mime_types,
109
+ DocumentRoot: opts["destination"],
110
+ StartCallback: start_callback(opts["detach"]),
111
+ StopCallback: stop_callback(opts["detach"]),
112
+ BindAddress: opts["host"],
113
+ Port: opts["port"],
114
+ DirectoryIndex: DIRECTORY_INDEX,
115
+ }
116
+
117
+ opts[:DirectoryIndex] = [] if opts[:BridgetownOptions]["show_dir_listing"]
118
+
119
+ enable_ssl(opts)
120
+ enable_logging(opts)
121
+ opts
122
+ end
122
123
 
123
- def start_up_webrick(opts, destination)
124
- @server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
125
- @server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
124
+ def start_up_webrick(opts, destination)
125
+ @server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
126
+ @server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
126
127
 
127
- Bridgetown.logger.info "Server address:", server_address(@server, opts)
128
- launch_browser @server, opts if opts["open_url"]
129
- boot_or_detach @server, opts
130
- end
128
+ Bridgetown.logger.info "Server address:", server_address(@server, opts)
129
+ launch_browser @server, opts if opts["open_url"]
130
+ boot_or_detach @server, opts
131
+ end
131
132
 
132
- # Recreate NondisclosureName under utf-8 circumstance
133
- def file_handler_opts
134
- WEBrick::Config::FileHandler.merge(
135
- FancyIndexing: true,
136
- NondisclosureName: [
137
- ".ht*", "~*",
138
- ]
139
- )
140
- end
133
+ def shutdown
134
+ @server.shutdown if running?
135
+ end
141
136
 
142
- def server_address(server, options = {})
143
- format_url(
144
- server.config[:SSLEnable],
145
- server.config[:BindAddress],
146
- server.config[:Port],
147
- options["baseurl"]
148
- )
149
- end
137
+ def default_url(config)
138
+ format_url(
139
+ config["ssl_cert"] && config["ssl_key"],
140
+ config["host"] == "127.0.0.1" ? "localhost" : config["host"],
141
+ config["port"]
142
+ )
143
+ end
150
144
 
151
- def format_url(ssl_enabled, address, port, baseurl = nil)
152
- format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
153
- prefix: ssl_enabled ? "https" : "http",
154
- address: address,
155
- port: port,
156
- baseurl: baseurl ? "#{baseurl}/" : "")
157
- end
145
+ def format_url(ssl_enabled, address, port, baseurl = nil)
146
+ format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
147
+ prefix: ssl_enabled ? "https" : "http",
148
+ address: address,
149
+ port: port,
150
+ baseurl: baseurl ? "#{baseurl}/" : "")
151
+ end
158
152
 
159
- def default_url(config)
160
- format_url(
161
- config["ssl_cert"] && config["ssl_key"],
162
- config["host"] == "127.0.0.1" ? "localhost" : config["host"],
163
- config["port"]
164
- )
165
- end
153
+ # Recreate NondisclosureName under utf-8 circumstance
154
+ def file_handler_opts
155
+ WEBrick::Config::FileHandler.merge(
156
+ FancyIndexing: true,
157
+ NondisclosureName: [
158
+ ".ht*", "~*",
159
+ ]
160
+ )
161
+ end
166
162
 
167
- def launch_browser(server, opts)
168
- address = server_address(server, opts)
169
- return system "start", address if Utils::Platforms.windows?
170
- return system "xdg-open", address if Utils::Platforms.linux?
171
- return system "open", address if Utils::Platforms.osx?
163
+ def server_address(server, options = {})
164
+ format_url(
165
+ server.config[:SSLEnable],
166
+ server.config[:BindAddress],
167
+ server.config[:Port],
168
+ options["baseurl"]
169
+ )
170
+ end
172
171
 
173
- Bridgetown.logger.error "Refusing to launch browser; " \
174
- "Platform launcher unknown."
175
- end
172
+ def launch_browser(server, opts)
173
+ address = server_address(server, opts)
174
+ return system "start", address if Utils::Platforms.windows?
175
+ return system "xdg-open", address if Utils::Platforms.linux?
176
+ return system "open", address if Utils::Platforms.osx?
176
177
 
177
- # Keep in our area with a thread or detach the server as requested
178
- # by the user. This method determines what we do based on what you
179
- # ask us to do.
180
- def boot_or_detach(server, opts)
181
- if opts["detach"]
182
- pid = Process.fork do
183
- server.start
184
- end
178
+ Bridgetown.logger.error "Refusing to launch browser; " \
179
+ "Platform launcher unknown."
180
+ end
185
181
 
186
- Process.detach(pid)
187
- Bridgetown.logger.info "Server detached with pid '#{pid}'.", \
188
- "Run `pkill -f bridgetown' or `kill -9 #{pid}'" \
189
- " to stop the server."
190
- else
191
- t = Thread.new { server.start }
192
- trap("INT") { server.shutdown }
193
- t.join
182
+ # Keep in our area with a thread or detach the server as requested
183
+ # by the user. This method determines what we do based on what you
184
+ # ask us to do.
185
+ def boot_or_detach(server, opts)
186
+ if opts["detach"]
187
+ pid = Process.fork do
188
+ server.start
194
189
  end
195
- end
196
190
 
197
- # Make the stack verbose if the user requests it.
198
- def enable_logging(opts)
199
- opts[:AccessLog] = []
200
- level = WEBrick::Log.const_get(opts[:BridgetownOptions]["verbose"] ? :DEBUG : :WARN)
201
- opts[:Logger] = WEBrick::Log.new($stdout, level)
191
+ Process.detach(pid)
192
+ Bridgetown.logger.info "Server detached with pid '#{pid}'.", \
193
+ "Run `pkill -f bridgetown' or `kill -9 #{pid}'" \
194
+ " to stop the server."
195
+ else
196
+ t = Thread.new { server.start }
197
+ trap("INT") { server.shutdown }
198
+ t.join
202
199
  end
200
+ end
203
201
 
204
- # Add SSL to the stack if the user triggers --enable-ssl and they
205
- # provide both types of certificates commonly needed. Raise if they
206
- # forget to add one of the certificates.
207
- def enable_ssl(opts)
208
- cert, key, src =
209
- opts[:BridgetownOptions].values_at("ssl_cert", "ssl_key", "source")
210
-
211
- return if cert.nil? && key.nil?
212
- raise "Missing --ssl_cert or --ssl_key. Both are required." unless cert && key
213
-
214
- require "openssl"
215
- require "webrick/https"
216
-
217
- opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(read_file(src, cert))
218
- begin
219
- opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(read_file(src, key))
220
- rescue StandardError
221
- if defined?(OpenSSL::PKey::EC)
222
- opts[:SSLPrivateKey] = OpenSSL::PKey::EC.new(read_file(src, key))
223
- else
224
- raise
225
- end
202
+ # Make the stack verbose if the user requests it.
203
+ def enable_logging(opts)
204
+ opts[:AccessLog] = []
205
+ level = WEBrick::Log.const_get(opts[:BridgetownOptions]["verbose"] ? :DEBUG : :WARN)
206
+ opts[:Logger] = WEBrick::Log.new($stdout, level)
207
+ end
208
+
209
+ # Add SSL to the stack if the user triggers --enable-ssl and they
210
+ # provide both types of certificates commonly needed. Raise if they
211
+ # forget to add one of the certificates.
212
+ def enable_ssl(opts)
213
+ cert, key, src =
214
+ opts[:BridgetownOptions].values_at("ssl_cert", "ssl_key", "source")
215
+
216
+ return if cert.nil? && key.nil?
217
+ raise "Missing --ssl_cert or --ssl_key. Both are required." unless cert && key
218
+
219
+ require "openssl"
220
+ require "webrick/https"
221
+
222
+ opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(read_file(src, cert))
223
+ begin
224
+ opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(read_file(src, key))
225
+ rescue StandardError
226
+ if defined?(OpenSSL::PKey::EC)
227
+ opts[:SSLPrivateKey] = OpenSSL::PKey::EC.new(read_file(src, key))
228
+ else
229
+ raise
226
230
  end
227
- opts[:SSLEnable] = true
228
231
  end
232
+ opts[:SSLEnable] = true
233
+ end
229
234
 
230
- def start_callback(detached)
231
- unless detached
232
- proc do
233
- mutex.synchronize do
234
- @running = true
235
- Bridgetown.logger.info("Server running…", "press ctrl-c to stop.")
236
- @run_cond.broadcast
237
- end
235
+ def start_callback(detached)
236
+ unless detached
237
+ proc do
238
+ @mutex.synchronize do
239
+ @running = true
240
+ Bridgetown.logger.info("Server running…", "press ctrl-c to stop.")
241
+ @run_cond.broadcast
238
242
  end
239
243
  end
240
244
  end
245
+ end
241
246
 
242
- def stop_callback(detached)
243
- unless detached
244
- proc do
245
- mutex.synchronize do
246
- @running = false
247
- @run_cond.broadcast
248
- end
247
+ def stop_callback(detached)
248
+ unless detached
249
+ proc do
250
+ @mutex.synchronize do
251
+ @running = false
252
+ @run_cond.broadcast
249
253
  end
250
254
  end
251
255
  end
256
+ end
252
257
 
253
- def mime_types
254
- file = File.expand_path("../mime.types", __dir__)
255
- WEBrick::HTTPUtils.load_mime_types(file)
256
- end
258
+ def mime_types
259
+ file = File.expand_path("../mime.types", __dir__)
260
+ WEBrick::HTTPUtils.load_mime_types(file)
261
+ end
257
262
 
258
- def read_file(source_dir, file_path)
259
- File.read(Bridgetown.sanitized_path(source_dir, file_path))
260
- end
263
+ def read_file(source_dir, file_path)
264
+ File.read(Bridgetown.sanitized_path(source_dir, file_path))
261
265
  end
262
266
  end
263
267
  end