bridgetown-core 0.14.0 → 0.15.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
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 -13
  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