bridgetown-core 0.12.0 → 0.15.0.beta1

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