bridgetown-core 0.13.0 → 0.15.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -1
  3. data/bin/bridgetown +9 -48
  4. data/bridgetown-core.gemspec +6 -2
  5. data/lib/bridgetown-core.rb +13 -3
  6. data/lib/bridgetown-core/cleaner.rb +1 -0
  7. data/lib/bridgetown-core/commands/apply.rb +73 -0
  8. data/lib/bridgetown-core/commands/base.rb +45 -0
  9. data/lib/bridgetown-core/commands/build.rb +91 -86
  10. data/lib/bridgetown-core/commands/clean.rb +30 -29
  11. data/lib/bridgetown-core/commands/concerns/actions.rb +123 -0
  12. data/lib/bridgetown-core/commands/concerns/build_options.rb +76 -0
  13. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +18 -0
  14. data/lib/bridgetown-core/commands/concerns/summarizable.rb +13 -0
  15. data/lib/bridgetown-core/commands/console.rb +46 -39
  16. data/lib/bridgetown-core/commands/doctor.rb +126 -127
  17. data/lib/bridgetown-core/commands/new.rb +120 -158
  18. data/lib/bridgetown-core/commands/plugins.rb +206 -0
  19. data/lib/bridgetown-core/commands/registrations.rb +16 -0
  20. data/lib/bridgetown-core/commands/serve.rb +214 -215
  21. data/lib/bridgetown-core/{convertible.rb → concerns/convertible.rb} +3 -6
  22. data/lib/bridgetown-core/concerns/site/configurable.rb +153 -0
  23. data/lib/bridgetown-core/concerns/site/content.rb +111 -0
  24. data/lib/bridgetown-core/concerns/site/extensible.rb +56 -0
  25. data/lib/bridgetown-core/concerns/site/processable.rb +74 -0
  26. data/lib/bridgetown-core/concerns/site/renderable.rb +49 -0
  27. data/lib/bridgetown-core/concerns/site/writable.rb +31 -0
  28. data/lib/bridgetown-core/configuration.rb +2 -9
  29. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +0 -3
  30. data/lib/bridgetown-core/document.rb +1 -1
  31. data/lib/bridgetown-core/drops/page_drop.rb +1 -1
  32. data/lib/bridgetown-core/drops/site_drop.rb +1 -1
  33. data/lib/bridgetown-core/excerpt.rb +4 -1
  34. data/lib/bridgetown-core/external.rb +17 -21
  35. data/lib/bridgetown-core/filters.rb +10 -0
  36. data/lib/bridgetown-core/generators/prototype_generator.rb +3 -1
  37. data/lib/bridgetown-core/hooks.rb +62 -62
  38. data/lib/bridgetown-core/layout.rb +10 -4
  39. data/lib/bridgetown-core/liquid_renderer.rb +1 -0
  40. data/lib/bridgetown-core/liquid_renderer/file.rb +1 -4
  41. data/lib/bridgetown-core/liquid_renderer/file_system.rb +3 -1
  42. data/lib/bridgetown-core/page.rb +11 -19
  43. data/lib/bridgetown-core/plugin.rb +2 -0
  44. data/lib/bridgetown-core/plugin_manager.rb +88 -21
  45. data/lib/bridgetown-core/reader.rb +5 -0
  46. data/lib/bridgetown-core/readers/data_reader.rb +5 -2
  47. data/lib/bridgetown-core/readers/layout_reader.rb +9 -2
  48. data/lib/bridgetown-core/readers/plugin_content_reader.rb +48 -0
  49. data/lib/bridgetown-core/renderer.rb +38 -28
  50. data/lib/bridgetown-core/site.rb +20 -463
  51. data/lib/bridgetown-core/tags/include.rb +12 -0
  52. data/lib/bridgetown-core/tags/render_content.rb +29 -16
  53. data/lib/bridgetown-core/tags/with.rb +15 -0
  54. data/lib/bridgetown-core/utils.rb +45 -27
  55. data/lib/bridgetown-core/utils/ruby_exec.rb +1 -4
  56. data/lib/bridgetown-core/version.rb +2 -2
  57. data/lib/bridgetown-core/watcher.rb +21 -10
  58. data/lib/site_template/Gemfile.erb +19 -0
  59. data/lib/site_template/package.json +1 -0
  60. data/lib/site_template/plugins/{.keep → builders/.keep} +0 -0
  61. data/lib/site_template/plugins/site_builder.rb +4 -0
  62. data/lib/site_template/src/_components/footer.html +3 -0
  63. data/lib/site_template/src/_components/head.html +9 -0
  64. data/lib/site_template/src/{_includes → _components}/navbar.html +1 -0
  65. data/lib/site_template/src/_layouts/default.html +3 -3
  66. data/lib/site_template/src/posts.md +15 -0
  67. data/lib/site_template/start.js +1 -1
  68. data/lib/site_template/webpack.config.js +3 -3
  69. metadata +90 -18
  70. data/lib/bridgetown-core/command.rb +0 -106
  71. data/lib/bridgetown-core/commands/help.rb +0 -34
  72. data/lib/site_template/src/_components/.keep +0 -0
  73. data/lib/site_template/src/_includes/footer.html +0 -3
  74. 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