bridgetown-core 0.12.0 → 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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -1
  3. data/bin/bridgetown +9 -48
  4. data/bridgetown-core.gemspec +10 -5
  5. data/lib/bridgetown-core.rb +20 -4
  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 +95 -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 -38
  16. data/lib/bridgetown-core/commands/doctor.rb +125 -135
  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 -217
  21. data/lib/bridgetown-core/{convertible.rb → concerns/convertible.rb} +2 -2
  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 +50 -0
  27. data/lib/bridgetown-core/concerns/site/writable.rb +31 -0
  28. data/lib/bridgetown-core/configuration.rb +98 -108
  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/bridgetown_drop.rb +6 -1
  32. data/lib/bridgetown-core/drops/site_drop.rb +1 -2
  33. data/lib/bridgetown-core/external.rb +17 -21
  34. data/lib/bridgetown-core/filters.rb +10 -0
  35. data/lib/bridgetown-core/generators/prototype_generator.rb +3 -1
  36. data/lib/bridgetown-core/hooks.rb +62 -62
  37. data/lib/bridgetown-core/layout.rb +10 -4
  38. data/lib/bridgetown-core/liquid_renderer.rb +2 -0
  39. data/lib/bridgetown-core/liquid_renderer/file_system.rb +5 -1
  40. data/lib/bridgetown-core/page.rb +9 -2
  41. data/lib/bridgetown-core/plugin.rb +2 -0
  42. data/lib/bridgetown-core/plugin_manager.rb +68 -14
  43. data/lib/bridgetown-core/reader.rb +5 -0
  44. data/lib/bridgetown-core/readers/data_reader.rb +15 -2
  45. data/lib/bridgetown-core/readers/layout_reader.rb +9 -2
  46. data/lib/bridgetown-core/readers/plugin_content_reader.rb +48 -0
  47. data/lib/bridgetown-core/renderer.rb +51 -32
  48. data/lib/bridgetown-core/site.rb +20 -449
  49. data/lib/bridgetown-core/static_file.rb +1 -5
  50. data/lib/bridgetown-core/tags/include.rb +12 -0
  51. data/lib/bridgetown-core/tags/render_content.rb +27 -16
  52. data/lib/bridgetown-core/tags/with.rb +15 -0
  53. data/lib/bridgetown-core/utils.rb +2 -27
  54. data/lib/bridgetown-core/utils/ruby_exec.rb +66 -0
  55. data/lib/bridgetown-core/version.rb +2 -2
  56. data/lib/bridgetown-core/watcher.rb +21 -10
  57. data/lib/site_template/Gemfile.erb +19 -0
  58. data/lib/site_template/plugins/{.keep → builders/.keep} +0 -0
  59. data/lib/site_template/plugins/site_builder.rb +4 -0
  60. data/lib/site_template/src/_components/footer.html +3 -0
  61. data/lib/site_template/src/_components/head.html +9 -0
  62. data/lib/site_template/src/{_includes → _components}/navbar.html +1 -0
  63. data/lib/site_template/src/_layouts/default.html +3 -3
  64. data/lib/site_template/src/{_components/.keep → favicon.ico} +0 -0
  65. data/lib/site_template/src/posts.md +15 -0
  66. data/lib/site_template/start.js +1 -1
  67. metadata +107 -19
  68. data/lib/bridgetown-core/command.rb +0 -106
  69. data/lib/bridgetown-core/commands/help.rb +0 -34
  70. data/lib/site_template/src/_includes/footer.html +0 -3
  71. data/lib/site_template/src/_includes/head.html +0 -9
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Site::Writable
5
+ # Remove orphaned files and empty directories in destination.
6
+ #
7
+ # Returns nothing.
8
+ def cleanup
9
+ @cleaner.cleanup!
10
+ end
11
+
12
+ # Write static files, pages, and posts.
13
+ #
14
+ # Returns nothing.
15
+ def write
16
+ each_site_file do |item|
17
+ item.write(dest) if regenerator.regenerate?(item)
18
+ end
19
+ regenerator.write_metadata
20
+ Bridgetown::Hooks.trigger :site, :post_write, self
21
+ end
22
+
23
+ def each_site_file
24
+ %w(pages static_files docs_to_write).each do |type|
25
+ send(type).each do |item|
26
+ yield item
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,66 +1,70 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- class Configuration < Hash
4
+ # TODO: refactor this whole object! Already had to fix obscure
5
+ # bugs just making minor changes, and all the indirection is
6
+ # quite hard to decipher. -JW
7
+ class Configuration < ActiveSupport::HashWithIndifferentAccess
5
8
  # Default options. Overridden by values in bridgetown.config.yml.
6
9
  # Strings rather than symbols are used for compatibility with YAML.
7
10
  DEFAULTS = {
8
11
  # Where things are
9
- "root_dir" => Dir.pwd,
10
- "plugins_dir" => "plugins",
11
- "source" => File.join(Dir.pwd, "src"),
12
- "destination" => File.join(Dir.pwd, "output"),
13
- "collections_dir" => "",
14
- "cache_dir" => ".bridgetown-cache",
15
- "layouts_dir" => "_layouts",
16
- "data_dir" => "_data",
17
- "components_dir" => "_components",
18
- "includes_dir" => "_includes",
19
- "collections" => {},
12
+ "root_dir" => Dir.pwd,
13
+ "plugins_dir" => "plugins",
14
+ "source" => File.join(Dir.pwd, "src"),
15
+ "destination" => File.join(Dir.pwd, "output"),
16
+ "collections_dir" => "",
17
+ "cache_dir" => ".bridgetown-cache",
18
+ "layouts_dir" => "_layouts",
19
+ "data_dir" => "_data",
20
+ "components_dir" => "_components",
21
+ "includes_dir" => "_includes",
22
+ "collections" => {},
20
23
 
21
24
  # Handling Reading
22
- "include" => [".htaccess", "_redirects", ".well-known"],
23
- "exclude" => [],
24
- "keep_files" => [".git", ".svn", "_bridgetown"],
25
- "encoding" => "utf-8",
26
- "markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
27
- "strict_front_matter" => false,
28
- "slugify_categories" => true,
25
+ "include" => [".htaccess", "_redirects", ".well-known"],
26
+ "exclude" => [],
27
+ "keep_files" => [".git", ".svn", "_bridgetown"],
28
+ "encoding" => "utf-8",
29
+ "markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
30
+ "strict_front_matter" => false,
31
+ "slugify_categories" => true,
29
32
 
30
33
  # Filtering Content
31
- "limit_posts" => 0,
32
- "future" => false,
33
- "unpublished" => false,
34
+ "limit_posts" => 0,
35
+ "future" => false,
36
+ "unpublished" => false,
37
+ "ruby_in_front_matter" => true, # requires BRIDGETOWN_RUBY_IN_FRONT_MATTER == "true"
34
38
 
35
39
  # Conversion
36
- "markdown" => "kramdown",
37
- "highlighter" => "rouge",
38
- "lsi" => false,
39
- "excerpt_separator" => "\n\n",
40
- "incremental" => false,
40
+ "markdown" => "kramdown",
41
+ "highlighter" => "rouge",
42
+ "lsi" => false,
43
+ "excerpt_separator" => "\n\n",
44
+ "incremental" => false,
41
45
 
42
46
  # Serving
43
- "detach" => false, # default to not detaching the server
44
- "port" => "4000",
45
- "host" => "127.0.0.1",
46
- "baseurl" => nil, # this mounts at /, i.e. no subdirectory
47
- "show_dir_listing" => false,
47
+ "detach" => false, # default to not detaching the server
48
+ "port" => "4000",
49
+ "host" => "127.0.0.1",
50
+ "baseurl" => nil, # this mounts at /, i.e. no subdirectory
51
+ "show_dir_listing" => false,
48
52
 
49
53
  # Output Configuration
50
- "permalink" => "date",
51
- "timezone" => nil, # use the local timezone
54
+ "permalink" => "date",
55
+ "timezone" => nil, # use the local timezone
52
56
 
53
- "quiet" => false,
54
- "verbose" => false,
55
- "defaults" => [],
57
+ "quiet" => false,
58
+ "verbose" => false,
59
+ "defaults" => [],
56
60
 
57
- "liquid" => {
61
+ "liquid" => {
58
62
  "error_mode" => "warn",
59
63
  "strict_filters" => false,
60
64
  "strict_variables" => false,
61
65
  },
62
66
 
63
- "kramdown" => {
67
+ "kramdown" => {
64
68
  "auto_ids" => true,
65
69
  "toc_levels" => (1..6).to_a,
66
70
  "entity_output" => "as_char",
@@ -87,18 +91,14 @@ module Bridgetown
87
91
  #
88
92
  # Returns a Configuration filled with defaults.
89
93
  def from(user_config)
90
- Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
91
- .add_default_collections.add_default_excludes
94
+ Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config])
95
+ .merge_environment_specific_options!
96
+ .add_default_collections
97
+ .add_default_excludes
98
+ .check_include_exclude
92
99
  end
93
100
  end
94
101
 
95
- # Public: Turn all keys into string
96
- #
97
- # Return a copy of the hash where all its keys are strings
98
- def stringify_keys
99
- each_with_object({}) { |(k, v), hsh| hsh[k.to_s] = v }
100
- end
101
-
102
102
  def get_config_value_with_override(config_key, override)
103
103
  override[config_key] || self[config_key] || DEFAULTS[config_key]
104
104
  end
@@ -178,31 +178,6 @@ module Bridgetown
178
178
  Array(config_files)
179
179
  end
180
180
 
181
- # Public: Read configuration and return merged Hash
182
- #
183
- # file - the path to the YAML file to be read in
184
- #
185
- # Returns this configuration, overridden by the values in the file
186
- def read_config_file(file)
187
- file = File.expand_path(file)
188
- next_config = safe_load_file(file)
189
-
190
- unless next_config.is_a?(Hash)
191
- raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
192
- end
193
-
194
- Bridgetown.logger.info "Configuration file:", file
195
- next_config
196
- rescue SystemCallError
197
- if @default_config_file ||= nil
198
- Bridgetown.logger.warn "Configuration file:", "none"
199
- {}
200
- else
201
- Bridgetown.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
202
- raise LoadError, "The Configuration file '#{file}' could not be found."
203
- end
204
- end
205
-
206
181
  # Public: Read in a list of configuration files and merge with this hash
207
182
  #
208
183
  # files - the list of configuration file paths
@@ -210,14 +185,14 @@ module Bridgetown
210
185
  # Returns the full configuration, with the defaults overridden by the values in the
211
186
  # configuration files
212
187
  def read_config_files(files)
213
- configuration = clone
188
+ config = self
214
189
 
215
190
  begin
216
191
  files.each do |config_file|
217
192
  next if config_file.nil? || config_file.empty?
218
193
 
219
194
  new_config = read_config_file(config_file)
220
- configuration = Utils.deep_merge_hashes(configuration, new_config)
195
+ config = Utils.deep_merge_hashes(self, new_config)
221
196
  end
222
197
  rescue ArgumentError => e
223
198
  Bridgetown.logger.warn "WARNING:", "Error reading configuration. Using defaults" \
@@ -225,52 +200,64 @@ module Bridgetown
225
200
  warn e
226
201
  end
227
202
 
228
- configuration.validate.add_default_collections
203
+ config
229
204
  end
230
205
 
231
- # Public: Split a CSV string into an array containing its values
206
+ # Public: Read configuration and return merged Hash
232
207
  #
233
- # csv - the string of comma-separated values
208
+ # file - the path to the YAML file to be read in
234
209
  #
235
- # Returns an array of the values contained in the CSV
236
- def csv_to_array(csv)
237
- csv.split(",").map(&:strip)
238
- end
210
+ # Returns this configuration, overridden by the values in the file
211
+ def read_config_file(file)
212
+ file = File.expand_path(file)
213
+ next_config = safe_load_file(file)
239
214
 
240
- # Public: Ensure the proper options are set in the configuration
241
- #
242
- # Returns the configuration Hash
243
- def validate
244
- config = clone
215
+ unless next_config.is_a?(Hash)
216
+ raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
217
+ end
245
218
 
246
- check_include_exclude(config)
219
+ Bridgetown.logger.info "Configuration file:", file
220
+ next_config
221
+ rescue SystemCallError
222
+ if @default_config_file ||= nil
223
+ Bridgetown.logger.warn "Configuration file:", "none"
224
+ {}
225
+ else
226
+ Bridgetown.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
227
+ raise LoadError, "The Configuration file '#{file}' could not be found."
228
+ end
229
+ end
247
230
 
248
- config
231
+ # Merge in environment-specific options, if present
232
+ def merge_environment_specific_options!
233
+ self[Bridgetown.environment]&.each_key do |k|
234
+ self[k] = self[Bridgetown.environment][k]
235
+ end
236
+ delete(Bridgetown.environment)
237
+ self
249
238
  end
250
239
 
251
240
  def add_default_collections
252
- config = clone
253
-
254
241
  # It defaults to `{}`, so this is only if someone sets it to null manually.
255
- return config if config["collections"].nil?
242
+ return self if self["collections"].nil?
256
243
 
257
244
  # Ensure we have a hash.
258
- if config["collections"].is_a?(Array)
259
- config["collections"] = config["collections"].each_with_object({}) do |collection, hash|
245
+ if self["collections"].is_a?(Array)
246
+ self["collections"] = self["collections"].each_with_object({}) do |collection, hash|
260
247
  hash[collection] = {}
261
248
  end
262
249
  end
263
250
 
264
- config["collections"] = Utils.deep_merge_hashes(
265
- { "posts" => {} }, config["collections"]
251
+ self["collections"] = Utils.deep_merge_hashes(
252
+ { "posts" => {} }, self["collections"]
266
253
  ).tap do |collections|
267
254
  collections["posts"]["output"] = true
268
- if config["permalink"]
269
- collections["posts"]["permalink"] ||= style_to_permalink(config["permalink"])
255
+ if self["permalink"]
256
+ collections["posts"]["permalink"] ||= style_to_permalink(self["permalink"])
270
257
  end
271
258
  end
272
259
 
273
- config
260
+ self
274
261
  end
275
262
 
276
263
  DEFAULT_EXCLUDES = %w(
@@ -281,14 +268,16 @@ module Bridgetown
281
268
  ).freeze
282
269
 
283
270
  def add_default_excludes
284
- config = clone
285
- return config if config["exclude"].nil?
271
+ return self if self["exclude"].nil?
286
272
 
287
- config["exclude"].concat(DEFAULT_EXCLUDES).uniq!
288
- config
273
+ self["exclude"].concat(DEFAULT_EXCLUDES).uniq!
274
+ self
289
275
  end
290
276
 
291
- private
277
+ def should_execute_inline_ruby?
278
+ ENV["BRIDGETOWN_RUBY_IN_FRONT_MATTER"] == "true" &&
279
+ self["ruby_in_front_matter"]
280
+ end
292
281
 
293
282
  # rubocop:disable Metrics/CyclomaticComplexity #
294
283
  def style_to_permalink(permalink_style)
@@ -311,14 +300,15 @@ module Bridgetown
311
300
  end
312
301
  # rubocop:enable Metrics/CyclomaticComplexity #
313
302
 
314
- def check_include_exclude(config)
303
+ def check_include_exclude
315
304
  %w(include exclude).each do |option|
316
- next unless config.key?(option)
317
- next if config[option].is_a?(Array)
305
+ next unless key?(option)
306
+ next if self[option].is_a?(Array)
318
307
 
319
308
  raise Bridgetown::Errors::InvalidConfigurationError,
320
- "'#{option}' should be set as an array, but was: #{config[option].inspect}."
309
+ "'#{option}' should be set as an array, but was: #{self[option].inspect}."
321
310
  end
311
+ self
322
312
  end
323
313
  end
324
314
  end
@@ -11,8 +11,6 @@ module Kramdown
11
11
  attr_reader :options, :parser
12
12
 
13
13
  # The implementation is basically the core logic in +Kramdown::Document#initialize+
14
- #
15
- # rubocop:disable Naming/MemoizedInstanceVariableName
16
14
  def setup(options)
17
15
  @cache ||= {}
18
16
 
@@ -36,7 +34,6 @@ module Kramdown
36
34
  end
37
35
  end
38
36
  end
39
- # rubocop:enable Naming/MemoizedInstanceVariableName
40
37
 
41
38
  private
42
39
 
@@ -59,7 +59,7 @@ module Bridgetown
59
59
  # Returns a Hash containing the data. An empty hash is returned if
60
60
  # no data was read.
61
61
  def data
62
- @data ||= {}
62
+ @data ||= ActiveSupport::HashWithIndifferentAccess.new
63
63
  end
64
64
 
65
65
  # Merge some data in with this document's data.
@@ -13,13 +13,18 @@ module Bridgetown
13
13
  Bridgetown::VERSION
14
14
  end
15
15
 
16
+ def code_name
17
+ Bridgetown::CODE_NAME
18
+ end
19
+
16
20
  def environment
17
- Bridgetown.env
21
+ Bridgetown.environment
18
22
  end
19
23
 
20
24
  def to_h
21
25
  @to_h ||= {
22
26
  "version" => version,
27
+ "code_name" => code_name,
23
28
  "environment" => environment,
24
29
  }
25
30
  end
@@ -7,7 +7,7 @@ module Bridgetown
7
7
 
8
8
  mutable false
9
9
 
10
- def_delegator :@obj, :site_data, :data
10
+ def_delegator :@obj, :data
11
11
  def_delegators :@obj, :time, :pages, :static_files, :tags, :categories
12
12
 
13
13
  private def_delegator :@obj, :config, :fallback_data
@@ -50,7 +50,6 @@ module Bridgetown
50
50
  @documents ||= @obj.documents
51
51
  end
52
52
 
53
- # TODO: provide a way to set BRIDGETOWN_ENV-specific metadata
54
53
  def metadata
55
54
  @site_metadata ||= @obj.data["site_metadata"]
56
55
  end
@@ -10,13 +10,11 @@ module Bridgetown
10
10
  #
11
11
  def require_if_present(names)
12
12
  Array(names).each do |name|
13
- begin
14
- require name
15
- rescue LoadError
16
- Bridgetown.logger.debug "Couldn't load #{name}. Skipping."
17
- yield(name, version_constraint(name)) if block_given?
18
- false
19
- end
13
+ require name
14
+ rescue LoadError
15
+ Bridgetown.logger.debug "Couldn't load #{name}. Skipping."
16
+ yield(name, version_constraint(name)) if block_given?
17
+ false
20
18
  end
21
19
  end
22
20
 
@@ -38,23 +36,21 @@ module Bridgetown
38
36
  #
39
37
  def require_with_graceful_fail(names)
40
38
  Array(names).each do |name|
41
- begin
42
- Bridgetown.logger.debug "Requiring:", name.to_s
43
- require name
44
- rescue LoadError => e
45
- Bridgetown.logger.error "Dependency Error:", <<~MSG
46
- Yikes! It looks like you don't have #{name} or one of its dependencies installed.
47
- In order to use Bridgetown as currently configured, you'll need to install this gem.
39
+ Bridgetown.logger.debug "Requiring:", name.to_s
40
+ require name
41
+ rescue LoadError => e
42
+ Bridgetown.logger.error "Dependency Error:", <<~MSG
43
+ Yikes! It looks like you don't have #{name} or one of its dependencies installed.
44
+ In order to use Bridgetown as currently configured, you'll need to install this gem.
48
45
 
49
- If you've run Bridgetown with `bundle exec`, ensure that you have included the #{name}
50
- gem in your Gemfile as well.
46
+ If you've run Bridgetown with `bundle exec`, ensure that you have included the #{name}
47
+ gem in your Gemfile as well.
51
48
 
52
- The full error message from Ruby is: '#{e.message}'
49
+ The full error message from Ruby is: '#{e.message}'
53
50
 
54
- If you run into trouble, you can find helpful resources at https://bridgetownrb.com/help/!
55
- MSG
56
- raise Bridgetown::Errors::MissingDependencyException, name
57
- end
51
+ If you run into trouble, you can find helpful resources at https://www.bridgetownrb.com/docs/community/
52
+ MSG
53
+ raise Bridgetown::Errors::MissingDependencyException, name
58
54
  end
59
55
  end
60
56
  end