bridgetown-core 0.14.1 → 0.15.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -1
  3. data/bin/bridgetown +9 -23
  4. data/bridgetown-core.gemspec +2 -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 +95 -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 +46 -38
  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 +214 -215
  20. data/lib/bridgetown-core/generators/prototype_generator.rb +2 -0
  21. data/lib/bridgetown-core/liquid_renderer.rb +1 -0
  22. data/lib/bridgetown-core/liquid_renderer/file_system.rb +3 -1
  23. data/lib/bridgetown-core/plugin_manager.rb +4 -4
  24. data/lib/bridgetown-core/renderer.rb +28 -15
  25. data/lib/bridgetown-core/tags/include.rb +12 -0
  26. data/lib/bridgetown-core/tags/render_content.rb +27 -16
  27. data/lib/bridgetown-core/tags/with.rb +15 -0
  28. data/lib/bridgetown-core/version.rb +2 -2
  29. data/lib/bridgetown-core/watcher.rb +17 -10
  30. data/lib/site_template/Gemfile.erb +19 -0
  31. data/lib/site_template/src/_components/footer.html +3 -0
  32. data/lib/site_template/src/_components/head.html +9 -0
  33. data/lib/site_template/src/{_includes → _components}/navbar.html +0 -0
  34. data/lib/site_template/src/_layouts/default.html +3 -3
  35. data/lib/site_template/start.js +1 -1
  36. metadata +39 -19
  37. data/lib/bridgetown-core/command.rb +0 -112
  38. data/lib/bridgetown-core/commands/help.rb +0 -34
  39. data/lib/site_template/src/_components/.keep +0 -0
  40. data/lib/site_template/src/_includes/footer.html +0 -3
  41. 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,261 @@
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
+
33
+ def self.banner
34
+ "bridgetown serve [options]"
35
+ end
36
+ summary "Serve your site locally using WEBrick"
60
37
 
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"
38
+ class << self
39
+ attr_accessor :loaded_config
40
+ end
64
41
 
65
- process_with_graceful_fail(cmd, config, Build, Serve)
66
- end
67
- end
42
+ DIRECTORY_INDEX = %w(
43
+ index.htm
44
+ index.html
45
+ index.rhtml
46
+ index.xht
47
+ index.xhtml
48
+ index.cgi
49
+ index.xml
50
+ index.json
51
+ ).freeze
52
+
53
+ def serve
54
+ @mutex = Mutex.new
55
+ @run_cond = ConditionVariable.new
56
+ @running = false
57
+
58
+ no_watch = options["watch"] == false
59
+
60
+ options = Thor::CoreExt::HashWithIndifferentAccess.new(self.options)
61
+
62
+ options["serving"] = true
63
+ options["watch"] = true unless no_watch
64
+
65
+ # TODO: this prints the configuration file log message out-of-order
66
+ self.class.loaded_config = configuration_with_overrides(options)
67
+ if Bridgetown.environment == "development"
68
+ self.class.loaded_config["url"] = default_url(self.class.loaded_config)
68
69
  end
69
70
 
70
- #
71
-
72
- def process(config)
73
- destination = config["destination"]
74
- setup(destination)
75
-
76
- start_up_webrick(config, destination)
77
- end
71
+ invoke(Build, [], options)
72
+ start_server
73
+ end
78
74
 
79
- def shutdown
80
- @server.shutdown if running?
81
- end
75
+ protected
82
76
 
83
- private
77
+ def start_server
78
+ config = self.class.loaded_config
79
+ destination = config["destination"]
80
+ setup(destination)
84
81
 
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.
82
+ start_up_webrick(config, destination)
83
+ end
88
84
 
89
- def setup(destination)
90
- require_relative "serve/servlet"
85
+ def setup(destination)
86
+ require_relative "serve/servlet"
91
87
 
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
88
+ FileUtils.mkdir_p(destination)
89
+ if File.exist?(File.join(destination, "404.html"))
90
+ WEBrick::HTTPResponse.class_eval do
91
+ def create_error_page
92
+ @header["Content-Type"] = "text/html; charset=UTF-8"
93
+ @body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
99
94
  end
100
95
  end
101
96
  end
97
+ end
102
98
 
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
99
+ def webrick_opts(opts)
100
+ opts = {
101
+ BridgetownOptions: opts,
102
+ DoNotReverseLookup: true,
103
+ MimeTypes: mime_types,
104
+ DocumentRoot: opts["destination"],
105
+ StartCallback: start_callback(opts["detach"]),
106
+ StopCallback: stop_callback(opts["detach"]),
107
+ BindAddress: opts["host"],
108
+ Port: opts["port"],
109
+ DirectoryIndex: DIRECTORY_INDEX,
110
+ }
111
+
112
+ opts[:DirectoryIndex] = [] if opts[:BridgetownOptions]["show_dir_listing"]
113
+
114
+ enable_ssl(opts)
115
+ enable_logging(opts)
116
+ opts
117
+ end
122
118
 
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)
119
+ def start_up_webrick(opts, destination)
120
+ @server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
121
+ @server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
126
122
 
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
123
+ Bridgetown.logger.info "Server address:", server_address(@server, opts)
124
+ launch_browser @server, opts if opts["open_url"]
125
+ boot_or_detach @server, opts
126
+ end
131
127
 
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
128
+ def shutdown
129
+ @server.shutdown if running?
130
+ end
141
131
 
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
132
+ def default_url(config)
133
+ format_url(
134
+ config["ssl_cert"] && config["ssl_key"],
135
+ config["host"] == "127.0.0.1" ? "localhost" : config["host"],
136
+ config["port"]
137
+ )
138
+ end
150
139
 
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
140
+ def format_url(ssl_enabled, address, port, baseurl = nil)
141
+ format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
142
+ prefix: ssl_enabled ? "https" : "http",
143
+ address: address,
144
+ port: port,
145
+ baseurl: baseurl ? "#{baseurl}/" : "")
146
+ end
158
147
 
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
148
+ # Recreate NondisclosureName under utf-8 circumstance
149
+ def file_handler_opts
150
+ WEBrick::Config::FileHandler.merge(
151
+ FancyIndexing: true,
152
+ NondisclosureName: [
153
+ ".ht*", "~*",
154
+ ]
155
+ )
156
+ end
166
157
 
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?
158
+ def server_address(server, options = {})
159
+ format_url(
160
+ server.config[:SSLEnable],
161
+ server.config[:BindAddress],
162
+ server.config[:Port],
163
+ options["baseurl"]
164
+ )
165
+ end
172
166
 
173
- Bridgetown.logger.error "Refusing to launch browser; " \
174
- "Platform launcher unknown."
175
- end
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?
176
172
 
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
173
+ Bridgetown.logger.error "Refusing to launch browser; " \
174
+ "Platform launcher unknown."
175
+ end
185
176
 
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
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
194
184
  end
195
- end
196
185
 
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)
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
202
194
  end
195
+ end
203
196
 
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
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)
202
+ end
203
+
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
226
225
  end
227
- opts[:SSLEnable] = true
228
226
  end
227
+ opts[:SSLEnable] = true
228
+ end
229
229
 
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
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
238
237
  end
239
238
  end
240
239
  end
240
+ end
241
241
 
242
- def stop_callback(detached)
243
- unless detached
244
- proc do
245
- mutex.synchronize do
246
- @running = false
247
- @run_cond.broadcast
248
- end
242
+ def stop_callback(detached)
243
+ unless detached
244
+ proc do
245
+ @mutex.synchronize do
246
+ @running = false
247
+ @run_cond.broadcast
249
248
  end
250
249
  end
251
250
  end
251
+ end
252
252
 
253
- def mime_types
254
- file = File.expand_path("../mime.types", __dir__)
255
- WEBrick::HTTPUtils.load_mime_types(file)
256
- end
253
+ def mime_types
254
+ file = File.expand_path("../mime.types", __dir__)
255
+ WEBrick::HTTPUtils.load_mime_types(file)
256
+ end
257
257
 
258
- def read_file(source_dir, file_path)
259
- File.read(Bridgetown.sanitized_path(source_dir, file_path))
260
- end
258
+ def read_file(source_dir, file_path)
259
+ File.read(Bridgetown.sanitized_path(source_dir, file_path))
261
260
  end
262
261
  end
263
262
  end